diff options
Diffstat (limited to 'src')
351 files changed, 22165 insertions, 2652 deletions
diff --git a/src/.cvsignore b/src/.hgignore index 282522db0..282522db0 100644 --- a/src/.cvsignore +++ b/src/.hgignore diff --git a/src/Makefile.am b/src/Makefile.am index 67fbc38b8..0d5621593 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,4 +30,5 @@ SUBDIRS = \ libfaad \ libflac \ libmusepack \ - post + post \ + combined diff --git a/src/audio_out/.cvsignore b/src/audio_out/.hgignore index 7d926a554..7d926a554 100644 --- a/src/audio_out/.cvsignore +++ b/src/audio_out/.hgignore diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 445622765..d52f700f3 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -94,7 +94,7 @@ xineplug_ao_out_oss_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c -xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) +xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_ao_out_alsa_la_CFLAGS = $(VISIBILITY_FLAG) $(ALSA_CFLAGS) xineplug_ao_out_alsa_la_LDFLAGS = -avoid-version -module @@ -104,6 +104,7 @@ xineplug_ao_out_esd_la_CFLAGS = $(VISIBILITY_FLAG) $(ESD_CFLAGS) xineplug_ao_out_esd_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c +xineplug_ao_out_sun_la_LIBADD = $(XINE_LIB) xineplug_ao_out_sun_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module @@ -113,7 +114,7 @@ xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module #xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module xineplug_ao_out_arts_la_SOURCES = audio_arts_out.c -xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) +xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) $(XINE_LIB) xineplug_ao_out_arts_la_CFLAGS = $(VISIBILITY_FLAG) $(ARTS_CFLAGS) xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module @@ -140,7 +141,7 @@ xineplug_ao_out_pulseaudio_la_LDFLAGS = -avoid-version -module xineplug_ao_out_directx2_la_SOURCES = audio_directx2_out.c xineplug_ao_out_directx2_la_CPPFLAGS = $(DIRECTX_CPPFLAGS) -xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(THREAD_LIBS) +xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(PTHREAD_LIBS) xineplug_ao_out_directx2_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_directx2_la_LDFLAGS = -avoid-version -module diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index da8b87fc5..3651d21da 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -26,7 +26,7 @@ * (c) 2001 James Courtier-Dutton <James@superbug.demon.co.uk> * * - * $Id: audio_alsa_out.c,v 1.165 2006/09/08 20:40:34 miguelfreitas Exp $ + * $Id: audio_alsa_out.c,v 1.168 2007/02/25 22:33:25 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -162,7 +162,6 @@ static int my_snd_mixer_wait(snd_mixer_t *mixer, int timeout) { static void *ao_alsa_handle_event_thread(void *data) { alsa_driver_t *this = (alsa_driver_t *) data; - this->mixer.running = 1; do { if(my_snd_mixer_wait(this->mixer.handle, 333) > 0) { @@ -665,6 +664,15 @@ static int ao_alsa_delay (ao_driver_t *this_gen) { printf("audio_alsa_out:delay:ENTERED\n"); #endif err=snd_pcm_delay( this->audio_fd, &delay ); + + int state = snd_pcm_state(this->audio_fd); + + /* check for idle states, which need to be handled as delay=0 */ + if(state == SND_PCM_STATE_PREPARED || state == SND_PCM_STATE_PAUSED || + state == SND_PCM_STATE_OPEN || SND_PCM_STATE_XRUN) { + return 0; + } + #ifdef LOG_DEBUG printf("audio_alsa_out:delay:delay all=%ld err=%d\n",delay, err); gettimeofday(&now, 0); @@ -1292,6 +1300,8 @@ static void ao_alsa_mixer_init(ao_driver_t *this_gen) { if (send_events && found) { pthread_attr_t pth_attrs; struct sched_param pth_params; + + this->mixer.running = 1; pthread_attr_init(&pth_attrs); @@ -1321,7 +1331,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da char *pcm_device; snd_pcm_hw_params_t *params; /* for usability reasons, keep this in sync with audio_oss_out.c */ - static char *speaker_arrangement[] = {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1", + static const char *speaker_arrangement[] = {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1", "Surround 3.0", "Surround 4.0", "Surround 4.1", "Surround 5.0", "Surround 5.1", "Surround 6.0", "Surround 6.1", "Surround 7.1", "Pass Through", NULL}; #define MONO 0 @@ -1504,6 +1514,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da this->capabilities |= AO_CAP_FLOAT32; xprintf(class->xine, XINE_VERBOSITY_LOG, _("32bit ")); } + if (0 == (this->capabilities & (AO_CAP_FLOAT32 | AO_CAP_24BITS | AO_CAP_16BITS | AO_CAP_8BITS))) { + xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, + "\naudio_alsa_out: no supported PCM format found\n"); + snd_pcm_close(this->audio_fd); + free(this); + return NULL; + } if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 1))) { this->capabilities |= AO_CAP_MODE_MONO; xprintf(class->xine, XINE_VERBOSITY_LOG, _("mono ")); diff --git a/src/audio_out/audio_coreaudio_out.c b/src/audio_out/audio_coreaudio_out.c index 80cab6d71..22f53c0ef 100644 --- a/src/audio_out/audio_coreaudio_out.c +++ b/src/audio_out/audio_coreaudio_out.c @@ -265,7 +265,9 @@ static int ao_coreaudio_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate format.mSampleRate = rate; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger +#ifdef WORDS_BIGENDIAN | kLinearPCMFormatFlagIsBigEndian +#endif | kLinearPCMFormatFlagIsPacked; format.mBitsPerChannel = this->bits_per_sample; format.mChannelsPerFrame = this->num_channels; diff --git a/src/audio_out/audio_fusionsound_out.c b/src/audio_out/audio_fusionsound_out.c index 1a6f44972..71a17f6e6 100644 --- a/src/audio_out/audio_fusionsound_out.c +++ b/src/audio_out/audio_fusionsound_out.c @@ -262,6 +262,12 @@ static uint32_t ao_fusionsound_get_capabilities(ao_driver_t *ao_driver) { static void ao_fusionsound_exit(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; + if (this->playback) + this->playback->Release (this->playback); + + if (this->stream) + this->stream->Release (this->stream); + if (this->sound) this->sound->Release (this->sound); diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index 366fa250c..793b47650 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_oss_out.c,v 1.117 2006/07/16 16:18:09 dsalt Exp $ + * $Id: audio_oss_out.c,v 1.120 2007/03/17 06:59:31 dgp85 Exp $ * * 20-8-2001 First implementation of Audio sync and Audio driver separation. * Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk @@ -48,20 +48,19 @@ #include <fcntl.h> #include <math.h> #include <unistd.h> -#if defined(__OpenBSD__) -# include <soundcard.h> -#elif defined (__FreeBSD__) -# if __FreeBSD__ < 4 -# include <machine/soundcard.h> -# else -# include <sys/soundcard.h> -# endif -#else -# include <sys/soundcard.h> -#endif #include <sys/ioctl.h> #include <inttypes.h> +#ifdef HAVE_SYS_SOUNDCARD_H +# include <sys/soundcard.h> +#endif +#ifdef HAVE_MACHINE_SOUNDCARD_H +# include <sys/soundcard.h> +#endif +#ifdef HAVE_SOUNDCARD_H +# include <soundcard.h> +#endif + #define LOG_MODULE "audio_oss_out" #define LOG_VERBOSE /* @@ -75,9 +74,18 @@ #include <sys/time.h> +#ifndef SNDCTL_DSP_SETFMT +/* Deprecated OSS API */ +#define SNDCTL_DSP_SETFMT SOUND_PCM_SETFMT +#endif + +#ifndef SNDCTL_DSP_SPEED +/* Deprecated OSS API */ +#define SNDCTL_DSP_SPEED SOUND_PCM_WRITE_RATE +#endif + #ifndef AFMT_S16_NE -# if defined(sparc) || defined(__sparc__) || defined(PPC) -/* Big endian machines */ +# ifdef WORDS_BIGENDIAN # define AFMT_S16_NE AFMT_S16_BE # else # define AFMT_S16_NE AFMT_S16_LE @@ -515,7 +523,7 @@ static int ao_oss_get_property (ao_driver_t *this_gen, int property) { if(!this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -554,7 +562,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(!this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -583,7 +591,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v = 0; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -789,9 +797,9 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da */ arg = AFMT_S16_NE; - status = ioctl(audio_fd, SOUND_PCM_SETFMT, &arg); + status = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg); arg = 44100; - status = ioctl(audio_fd, SOUND_PCM_WRITE_RATE, &arg); + status = ioctl(audio_fd, SNDCTL_DSP_SPEED, &arg); /* * find out which sync method to use @@ -903,12 +911,12 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da this->capabilities = 0; arg = AFMT_U8; - if( ioctl(audio_fd, SOUND_PCM_SETFMT, &arg) != -1 && arg == AFMT_U8) + if( ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) != -1 && arg == AFMT_U8) this->capabilities |= AO_CAP_8BITS; /* switch back to 16bits, because some soundcards otherwise do not report all their capabilities */ arg = AFMT_S16_NE; - if (ioctl(audio_fd, SOUND_PCM_SETFMT, &arg) == -1 || arg != AFMT_S16_NE) { + if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) == -1 || arg != AFMT_S16_NE) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: switching the soundcard to 16 bits mode failed\n"); free(this); close(audio_fd); diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 2cef1992d..9e6089730 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2006 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.5 2006/11/10 12:10:54 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.17 2007/04/01 00:32:29 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -40,12 +40,9 @@ #include <math.h> #include <unistd.h> #include <inttypes.h> -#include <assert.h> #include <pthread.h> #include <pulse/pulseaudio.h> -#include <pulse/error.h> -#include <pulse/mainloop.h> #include "xine_internal.h" #include "xineutils.h" @@ -57,78 +54,146 @@ /* CHECKME: should this be conditional on autotools? */ extern const char *__progname; -typedef struct pulse_driver_s { +typedef struct { + audio_driver_class_t driver_class; + xine_t *xine; - ao_driver_t ao_driver; + pthread_mutex_t pa_mutex; /*< Mutex controlling PulseAudio access. */ + struct pa_context *context; /*< Pulseaudio connection context */ + struct pa_threaded_mainloop *mainloop; /*< Main event loop object */ +} pulse_class_t; - xine_t *xine; +typedef struct pulse_driver_s { + ao_driver_t ao_driver; + xine_t *xine; - /** The host to connect to */ - char *host; + pulse_class_t *pa_class; - /** The sink to connect to */ - char *sink; + char *host; /*< The host to connect to */ + char *sink; /*< The sink to connect to */ + struct pa_stream *stream; /*< Pulseaudio playback stream object */ - /** Pulseaudio playback stream object */ - struct pa_stream *stream; + pa_volume_t swvolume; + pa_cvolume cvolume; - /** Pulseaudio connection context */ - struct pa_context *context; + int capabilities; + int mode; - /** Main event loop object */ - struct pa_mainloop *mainloop; + int32_t sample_rate; + uint32_t num_channels; + uint32_t bits_per_sample; + uint32_t bytes_per_frame; - pa_volume_t swvolume; - pa_cvolume cvolume; + uint32_t frames_written; - int capabilities; - int mode; +} pulse_driver_t; - int32_t sample_rate; - uint32_t num_channels; - uint32_t bits_per_sample; - uint32_t bytes_per_frame; +/** + * @brief Callback function called when a stream operation succeed + * @param stream Stream which operation has succeeded + * @param success The success value for the operation (ignored) + * @param this_Gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_stream_success_callback(pa_stream *const stream, const int success, + void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; - uint32_t frames_written; + _x_assert(stream); _x_assert(this); + _x_assert(stream == this->stream); - pthread_mutex_t lock; + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); +} -} pulse_driver_t; +/** + * @brief Callback function called when the state of the context is changed + * @param ctx Context which operation has succeeded + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_context_status_callback(pa_context *const ctx, void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; -typedef struct { - audio_driver_class_t driver_class; + _x_assert(ctx); _x_assert(this); + _x_assert(ctx == this->pa_class->context); - xine_t *xine; -} pulse_class_t; + switch (pa_context_get_state(ctx)) { + case PA_CONTEXT_READY: + case PA_CONTEXT_TERMINATED: + case PA_CONTEXT_FAILED: + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); + break; + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + } +} + +/** + * @brief Callback function called when a context operation succeed + * @param ctx Context which operation has succeeded + * @param success The success value for the operation (ignored) + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_context_success_callback(pa_context *const ctx, const int success, + void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; -/** Make sure that the connection context doesn't starve to death */ -static void keep_alive(pulse_driver_t *this) { - assert(this->context && this->mainloop); + _x_assert(ctx); _x_assert(this); + _x_assert(ctx == this->pa_class->context); - while (pa_mainloop_iterate(this->mainloop, 0, NULL) > 0); + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); } -/** Wait until no further actions are pending on the connection context */ -static void wait_for_completion(pulse_driver_t *this) { - assert(this->context && this->mainloop); +/** + * @brief Callback function called when the information on the + * context's sink is retrieved. + * @param ctx Context which operation has succeeded + * @param info Structure containing the sink's information + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + * + * This function saves the volume field of the passed structure to the + * @c cvolume variable of the output instance. + */ +static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_input_info *const info, + const int is_last, void *const userdata) { + + pulse_driver_t *const this = (pulse_driver_t *) userdata; - while (pa_context_is_pending(this->context)) { - int r = pa_mainloop_iterate(this->mainloop, 1, NULL); - assert(r >= 0); + if (is_last < 0) { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", + pa_strerror(pa_context_errno(this->pa_class->context))); + return; } + + if (!info) + return; + + this->cvolume = info->volume; + + __xine_pa_context_success_callback(ctx, 0, this); } -/** Wait until the specified operation completes */ -static void wait_for_operation(pulse_driver_t *this, struct pa_operation *o) { - assert(o && this->context && this->mainloop); +static int wait_for_operation(pulse_driver_t *this, pa_operation *o) +{ + _x_assert(this && o && this->pa_class->mainloop); - while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) { - int r = pa_mainloop_iterate(this->mainloop, 1, NULL); - assert(r >= 0); - } + pa_threaded_mainloop_lock(this->pa_class->mainloop); + + while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(this->pa_class->mainloop); + + pa_threaded_mainloop_unlock(this->pa_class->mainloop); - pa_operation_unref(o); + return 0; } /* @@ -140,6 +205,7 @@ static int ao_pulse_open(ao_driver_t *this_gen, pulse_driver_t *this = (pulse_driver_t *) this_gen; struct pa_sample_spec ss; struct pa_buffer_attr a; + pa_stream_state_t streamstate; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); @@ -171,68 +237,85 @@ static int ao_pulse_open(ao_driver_t *this_gen, ss.format = PA_SAMPLE_U8; break; case 16: -#ifdef WORDS_BIGENDIAN - ss.format = PA_SAMPLE_S16BE; -#else - ss.format = PA_SAMPLE_S16LE; -#endif + ss.format = PA_SAMPLE_S16NE; break; case 32: - ss.format = PA_SAMPLE_FLOAT32; + ss.format = PA_SAMPLE_FLOAT32NE; break; } - pthread_mutex_lock(&this->lock); - if (!pa_sample_spec_valid(&ss)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid sample spec\n"); goto fail; } - this->mainloop = pa_mainloop_new(); - assert(this->mainloop); + pthread_mutex_lock(&this->pa_class->pa_mutex); + if ( this->pa_class->context && pa_context_get_state(this->pa_class->context) > PA_CONTEXT_READY ) { + pa_context_unref(this->pa_class->context); + this->pa_class->context = NULL; + } + + if ( this->pa_class->context == NULL ) { + this->pa_class->context = pa_context_new(pa_threaded_mainloop_get_api(this->pa_class->mainloop), + __progname); + } + + pa_context_ref(this->pa_class->context); + + if ( pa_context_get_state(this->pa_class->context) == PA_CONTEXT_UNCONNECTED ) { + int ret; - this->context = pa_context_new(pa_mainloop_get_api(this->mainloop), __progname); - assert(this->context); + pa_threaded_mainloop_lock(this->pa_class->mainloop); + ret = pa_context_connect(this->pa_class->context, this->host, 1, NULL); + if ( ret < 0 ) + goto fail; - pa_context_connect(this->context, this->host, 1, NULL); + pa_context_set_state_callback(this->pa_class->context, __xine_pa_context_status_callback, this); - wait_for_completion(this); + pa_threaded_mainloop_wait(this->pa_class->mainloop); + pa_threaded_mainloop_unlock(this->pa_class->mainloop); + } - if (pa_context_get_state(this->context) != PA_CONTEXT_READY) { + if (pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->context))); + pa_strerror(pa_context_errno(this->pa_class->context))); goto fail; } - this->stream = pa_stream_new(this->context, "audio stream", &ss, NULL); - assert(this->stream); + this->stream = pa_stream_new(this->pa_class->context, "audio stream", &ss, NULL); + _x_assert(this->stream); a.maxlength = pa_bytes_per_second(&ss)*1; a.tlength = a.maxlength*9/10; a.prebuf = a.tlength/2; a.minreq = a.tlength/10; - pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); pa_stream_connect_playback(this->stream, this->sink, &a, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, - &this->cvolume, NULL); + NULL, NULL); - wait_for_completion(this); + do { + xine_usec_sleep (100); - if (pa_stream_get_state(this->stream) != PA_STREAM_READY) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->context))); + streamstate = pa_stream_get_state(this->stream); + } while (streamstate < PA_STREAM_READY); + + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + if (streamstate != PA_STREAM_READY) { + xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n", + pa_strerror(pa_context_errno(this->pa_class->context))); goto fail; } - pthread_mutex_unlock(&this->lock); - this->frames_written = 0; + this->ao_driver.set_property(this, AO_PROP_PCM_VOL, 100); + return this->sample_rate; fail: - pthread_mutex_unlock(&this->lock); + pa_threaded_mainloop_unlock(this->pa_class->mainloop); + pthread_mutex_unlock(&this->pa_class->pa_mutex); this_gen->close(this_gen); return 0; } @@ -262,22 +345,16 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, int size = num_frames * this->bytes_per_frame; int ret = 0; - assert(this->stream && this->context); - - pthread_mutex_lock(&this->lock); - - if (pa_stream_get_state(this->stream) == PA_STREAM_READY) { + if ( !this->stream || !this->pa_class->context) + return -1; + switch( pa_stream_get_state(this->stream) ) { + case PA_STREAM_READY: while (size > 0) { size_t l; - keep_alive(this); - while (!(l = pa_stream_writable_size(this->stream))) { - pthread_mutex_unlock(&this->lock); xine_usec_sleep (10000); - pthread_mutex_lock(&this->lock); - keep_alive(this); } if (l > size) @@ -286,16 +363,15 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE); data = (int16_t *) ((uint8_t*) data + l); size -= l; - - wait_for_completion(this); } this->frames_written += num_frames; if (pa_stream_get_state(this->stream) == PA_STREAM_READY) ret = 1; + + break; } - pthread_mutex_unlock(&this->lock); return ret; } @@ -307,20 +383,25 @@ static int ao_pulse_delay (ao_driver_t *this_gen) pa_usec_t latency = 0; int delay_frames; - pthread_mutex_lock(&this->lock); + if ( ! this->stream ) return this->frames_written; - for (;;) { - if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) - break; + pthread_mutex_lock(&this->pa_class->pa_mutex); - if (pa_context_errno(this->context) != PA_ERR_NODATA) { - /* error */ - } - keep_alive(this); - } + if (pa_stream_get_latency(this->stream, &latency, NULL) < 0) { + pa_context_unref(this->pa_class->context); + this->pa_class->context = NULL; - pthread_mutex_unlock(&this->lock); + pa_stream_disconnect(this->stream); + pa_stream_unref(this->stream); + this->stream = NULL; + + pthread_mutex_unlock(&this->pa_class->pa_mutex); + return 0; + } + + pthread_mutex_unlock(&this->pa_class->pa_mutex); + /* convert latency (us) to frame units. */ delay_frames = (int)(latency * this->sample_rate / 1000000); @@ -334,26 +415,19 @@ static void ao_pulse_close(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; - pthread_mutex_lock(&this->lock); if (this->stream) { + pthread_mutex_lock(&this->pa_class->pa_mutex); + if (pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this, pa_stream_drain(this->stream, NULL, NULL)); + wait_for_operation(this, pa_stream_drain(this->stream, __xine_pa_stream_success_callback, this)); pa_stream_disconnect(this->stream); pa_stream_unref(this->stream); this->stream = NULL; - } - if (this->context) { - pa_context_disconnect(this->context); - pa_context_unref(this->context); - this->context = NULL; - } + pa_context_unref(this->pa_class->context); - if (this->mainloop) { - pa_mainloop_free(this->mainloop); - this->mainloop = NULL; + pthread_mutex_unlock(&this->pa_class->pa_mutex); } - pthread_mutex_unlock(&this->lock); } static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) { @@ -368,101 +442,124 @@ static void ao_pulse_exit(ao_driver_t *this_gen) free (this); } -/** A callback function that is called when the - * pa_context_get_sink_input_info() operation completes. Saves the - * volume field of the specified structure to the global variable volume. */ -static void info_func(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) { - - pulse_driver_t *this = (pulse_driver_t *) userdata; - if (is_last < 0) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", - pa_strerror(pa_context_errno(this->context))); - return; - } - - if (!i) - return; - - this->cvolume = i->volume; -} - - static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { pulse_driver_t *this = (pulse_driver_t *) this_gen; + int result = 0; + + if ( ! this->stream || ! this->pa_class->context ) + return 0; + pthread_mutex_lock(&this->pa_class->pa_mutex); + switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - pthread_mutex_lock(&this->lock); - if( this->stream && this->context ) - wait_for_operation(this, - pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), info_func, this)); - pthread_mutex_unlock(&this->lock); - return (int) (pa_sw_volume_to_linear(this->swvolume)*100); + { + pa_operation *o = pa_context_get_sink_input_info(this->pa_class->context, + pa_stream_get_index(this->stream), + __xine_pa_sink_info_callback, this); + if ( ! o ) return 0; + wait_for_operation(this, o); + + result = (pa_sw_volume_to_linear(this->swvolume)*100); + } break; + case AO_PROP_MUTE_VOL: + result = pa_cvolume_is_muted(&this->cvolume); break; } - return 0; + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + return result; } static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value) { pulse_driver_t *this = (pulse_driver_t *) this_gen; + int result = ~value; + + if ( ! this->stream || ! this->pa_class->context ) + return result; + + pthread_mutex_lock(&this->pa_class->pa_mutex); switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - pthread_mutex_lock(&this->lock); this->swvolume = pa_sw_volume_from_linear((double)value/100.0); - if( this->stream && this->context ) { - pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); - wait_for_operation(this, - pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), - &this->cvolume, NULL, NULL)); - } - pthread_mutex_unlock(&this->lock); + pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); + wait_for_operation(this, + pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), + &this->cvolume, __xine_pa_context_success_callback, this)); + + result = value; break; + case AO_PROP_MUTE_VOL: + if ( value ) + pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels); + else + pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); + + wait_for_operation(this, + pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), + &this->cvolume, __xine_pa_context_success_callback, this)); + + result = value; break; } - return 0; + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + return result; } static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { pulse_driver_t *this = (pulse_driver_t *) this_gen; - pthread_mutex_lock(&this->lock); + if ( ! this->stream ) return 0; + switch (cmd) { case AO_CTRL_PLAY_PAUSE: - assert(this->stream && this->context ); + _x_assert(this->stream && this->pa_class->context ); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this,pa_stream_cork(this->stream, 1, NULL, NULL)); + wait_for_operation(this,pa_stream_cork(this->stream, 1, __xine_pa_stream_success_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + break; case AO_CTRL_PLAY_RESUME: - assert(this->stream && this->context); + _x_assert(this->stream && this->pa_class->context); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) { struct pa_operation *o2, *o1; - o1 = pa_stream_prebuf(this->stream, NULL, NULL); - o2 = pa_stream_cork(this->stream, 0, NULL, NULL); - assert(o1 && o2); - wait_for_operation(this,o1); - wait_for_operation(this,o2); - wait_for_completion(this); + o1 = pa_stream_prebuf(this->stream, __xine_pa_stream_success_callback, this); + _x_assert(o1); wait_for_operation(this, o1); + + o2 = pa_stream_cork(this->stream, 0, __xine_pa_stream_success_callback, this); + _x_assert(o2); wait_for_operation(this,o2); } + pthread_mutex_unlock(&this->pa_class->pa_mutex); + break; case AO_CTRL_FLUSH_BUFFERS: - assert(this->stream && this->context); + _x_assert(this->stream && this->pa_class->context); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this,pa_stream_flush(this->stream, NULL, NULL)); + wait_for_operation(this,pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + this->frames_written = 0; + break; } - pthread_mutex_unlock(&this->lock); return 0; } @@ -470,7 +567,6 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { pulse_class_t *class = (pulse_class_t *) class_gen; pulse_driver_t *this; - char hn[128]; char *device; lprintf ("audio_pulse_out: open_plugin called\n"); @@ -490,7 +586,8 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da AO_CAP_16BITS | AO_CAP_FLOAT32; this->sample_rate = 0; - this->swvolume = PA_VOLUME_NORM; + this->host = NULL; + this->sink = NULL; this->ao_driver.get_capabilities = ao_pulse_get_capabilities; this->ao_driver.get_property = ao_pulse_get_property; @@ -514,35 +611,27 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da 10, NULL, NULL); - if (device && strlen(device)) { - int i = strcspn(device, ":"); - if (i >= sizeof(hn)) - i = sizeof(hn)-1; - - if (i > 0) { - strncpy(this->host = hn, device, i); - hn[i] = 0; - } - - if (device[i] == ':') - this->sink = device+i+1; + if (device && *device) { + char *sep = strchr(device, ':'); + if ( sep ) { + this->host = strndup(device, sep-device); + this->sink = strdup(&sep[1]); + } else + this->host = strdup(device); } xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", this->host ? this->host : "(null)", this->sink ? this->sink : "(null)"); - pthread_mutex_init (&this->lock, NULL); - - /* test pulseaudio connection */ - if( this->ao_driver.open(&this->ao_driver, 16, 44100, AO_CAP_MODE_STEREO) != 0 ) { - this->ao_driver.close(&this->ao_driver); - } else { - free(this); - xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); - return NULL; - } + this->pa_class = class; return &this->ao_driver; + + fail: + pthread_mutex_unlock(&this->pa_class->pa_mutex); + free(this); + xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); + return NULL; } /* @@ -561,6 +650,15 @@ static void dispose_class (audio_driver_class_t *this_gen) { pulse_class_t *this = (pulse_class_t *) this_gen; + pthread_mutex_lock(&this->pa_mutex); + + if ( this->context ) + pa_context_unref(this->context); + + pa_threaded_mainloop_stop(this->mainloop); + pa_threaded_mainloop_free(this->mainloop); + + pthread_mutex_destroy(&this->pa_mutex); free (this); } @@ -581,6 +679,18 @@ static void *init_class (xine_t *xine, void *data) { this->xine = xine; + pthread_mutex_init(&this->pa_mutex, NULL); + pthread_mutex_lock(&this->pa_mutex); + + this->mainloop = pa_threaded_mainloop_new(); + _x_assert(this->mainloop); + + pa_threaded_mainloop_start(this->mainloop); + + this->context = NULL; + + pthread_mutex_unlock(&this->pa_mutex); + return this; } @@ -598,3 +708,4 @@ const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; + diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c index 95e38d811..93361d2f3 100644 --- a/src/audio_out/audio_sun_out.c +++ b/src/audio_out/audio_sun_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_sun_out.c,v 1.45 2006/07/16 16:18:09 dsalt Exp $ + * $Id: audio_sun_out.c,v 1.47 2007/03/10 00:55:14 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -41,13 +41,20 @@ #ifdef __svr4__ #include <stropts.h> #endif +#include <sys/param.h> + +#if (defined(BSD) && BSD >= 199306) +typedef unsigned uint_t; +#endif #include "xine_internal.h" #include "xineutils.h" #include "audio_out.h" +#ifdef __svr4__ #define CS4231_WORKAROUND 1 /* enable workaround for audiocs play.samples bug */ #define SW_SAMPLE_COUNT 1 +#endif #ifndef AUDIO_CHANNELS_MONO @@ -89,7 +96,9 @@ typedef struct sun_driver_s { uint32_t num_channels; int bytes_per_frame; +#ifdef __svr4__ uint32_t frames_in_buffer; /* number of frames writen to audio hardware */ +#endif enum { RTSC_UNKNOWN = 0, @@ -114,12 +123,14 @@ typedef struct sun_driver_s { unsigned buf_len; #endif +#ifdef __svr4__ #if SW_SAMPLE_COUNT struct timeval tv0; uint_t sample0; #endif uint_t last_samplecnt; +#endif } sun_driver_t; @@ -129,6 +140,7 @@ typedef struct sun_driver_s { */ static int realtime_samplecounter_available(xine_t *xine, char *dev) { +#ifdef __svr4__ int fd = -1; audio_info_t info; int rtsc_ok = RTSC_DISABLED; @@ -247,6 +259,9 @@ error: } return rtsc_ok; +#else + return RTSC_ENABLED; +#endif } @@ -430,7 +445,9 @@ static int ao_sun_open(ao_driver_t *this_gen, this->mode = mode; this->input_sample_rate = rate; +#ifdef __svr4__ this->frames_in_buffer = 0; +#endif /* * open audio device @@ -462,6 +479,9 @@ static int ao_sun_open(ao_driver_t *this_gen, info.play.sample_rate = this->input_sample_rate; info.play.eof = 0; info.play.samples = 0; +#ifndef __svr4__ + info.blocksize = 1024; +#endif this->convert_u8_s8 = 0; @@ -523,7 +543,9 @@ static int ao_sun_open(ao_driver_t *this_gen, return 0; } +#ifdef __svr4__ this->last_samplecnt = 0; +#endif this->output_sample_rate = info.play.sample_rate; this->num_channels = info.play.channels; @@ -564,6 +586,7 @@ static int ao_sun_delay(ao_driver_t *this_gen) sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; +#ifdef __svr4__ if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0 && (this->frames_in_buffer == 0 || info.play.samples > 0)) { @@ -610,6 +633,10 @@ static int ao_sun_delay(ao_driver_t *this_gen) } #endif } +#else + if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0) + return info.play.seek / this->bytes_per_frame; +#endif return NOT_REAL_TIME; } @@ -718,7 +745,9 @@ static int ao_sun_write(ao_driver_t *this_gen, if (num_written > 0) { int buffered_samples; +#ifdef __svr4__ this->frames_in_buffer += num_written / this->bytes_per_frame; +#endif /* * Avoid storing too much data in the sound driver's buffers. @@ -862,6 +891,9 @@ static int ao_sun_ctrl(ao_driver_t *this_gen, int cmd, ...) { this->frames_in_buffer = 0; this->last_samplecnt = 0; #endif +#ifdef __NetBSD__ + ioctl(this->audio_fd, AUDIO_FLUSH); +#endif break; } @@ -888,9 +920,10 @@ static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const v audiodev = getenv("AUDIODEV"); /* This config entry is security critical, is it really necessary? */ - devname = config->register_string(config, + devname = config->register_filename(config, "audio.device.sun_audio_device", audiodev && *audiodev ? audiodev : "/dev/audio", + XINE_CONFIG_STRING_IS_DEVICE_NAME, _("Sun audio device name"), _("Specifies the file name for the Sun audio device " "to be used.\nThis setting is security critical, " @@ -945,7 +978,10 @@ static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const v */ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_8BITS - | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL; + | AO_CAP_16BITS | AO_CAP_PCM_VOL; +#ifdef __svr4__ + this->capabilities |= AO_CAP_MUTE_VOL; +#endif /* * get initial mixer volume diff --git a/src/demuxers/.cvsignore b/src/combined/.hgignore index 7d926a554..7d926a554 100644 --- a/src/demuxers/.cvsignore +++ b/src/combined/.hgignore diff --git a/src/combined/Makefile.am b/src/combined/Makefile.am new file mode 100644 index 000000000..0d27f71c0 --- /dev/null +++ b/src/combined/Makefile.am @@ -0,0 +1,12 @@ +include $(top_srcdir)/misc/Makefile.common + +if HAVE_WAVPACK +xineplug_wavpack = xineplug_wavpack.la +endif + +xineplug_LTLIBRARIES = $(xineplug_wavpack) + +xineplug_wavpack_la_SOURCES = demux_wavpack.c decoder_wavpack.c combined_wavpack.c combined_wavpack.h +xineplug_wavpack_la_CFLAGS = $(VISIBILITY_FLAG) $(WAVPACK_CFLAGS) -I$(srcdir)/../demuxers +xineplug_wavpack_la_LIBADD = $(XINE_LIB) $(WAVPACK_LIBS) +xineplug_wavpack_la_LDFLAGS = $(xineplug_ldflags) diff --git a/src/combined/combined_wavpack.c b/src/combined/combined_wavpack.c new file mode 100644 index 000000000..7a334b15c --- /dev/null +++ b/src/combined/combined_wavpack.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> + * + * $Id: combined_wavpack.c,v 1.3 2007/03/17 07:34:02 dgp85 Exp $ + */ + +#include "xine_internal.h" +#include "combined_wavpack.h" + +static const demuxer_info_t demux_info_wv = { + 0 /* priority */ +}; + +static uint32_t audio_types[] = { + BUF_AUDIO_WAVPACK, 0 + }; + +static const decoder_info_t decoder_info_wv = { + audio_types, /* supported types */ + 7 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_DEMUX, 26, "wavpack", XINE_VERSION_CODE, &demux_info_wv, demux_wv_init_plugin }, + { PLUGIN_AUDIO_DECODER, 15, "wavpackdec", XINE_VERSION_CODE, &decoder_info_wv, decoder_wavpack_init_plugin }, + { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } +}; diff --git a/src/combined/combined_wavpack.h b/src/combined/combined_wavpack.h new file mode 100644 index 000000000..b7bf32acb --- /dev/null +++ b/src/combined/combined_wavpack.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> + * + * $Id: combined_wavpack.h,v 1.3 2007/03/17 07:34:02 dgp85 Exp $ + */ + +#include "os_types.h" + +typedef struct { + uint32_t idcode; /* This should always be the string "wvpk" */ + uint32_t block_size; /* Size of the rest of the frame */ + uint16_t wv_version; /* Version of the wavpack, 0x0403 should be latest */ + uint8_t track; /* Unused, has to be 0 */ + uint8_t index; /* Unused, has to be 0 */ + uint32_t file_samples; /* (uint32_t)-1 if unknown, else the total number + of samples for the file */ + uint32_t samples_index; /* Index of the first sample in block, from the + start of the file */ + uint32_t samples_count; /* Count of samples in the current frame */ + uint32_t flags; /* Misc flags */ + uint32_t decoded_crc32; /* CRC32 of the decoded data */ +} __attribute__((packed)) wvheader_t; + +#ifdef WORDS_BIGENDIAN +static const uint32_t wvpk_signature = ('k' + ('p' << 8) + ('v' << 16) + ('w' << 24)); +#else +static const uint32_t wvpk_signature = ('w' + ('v' << 8) + ('p' << 16) + ('k' << 24)); +#endif + +void *demux_wv_init_plugin (xine_t *const xine, void *const data); +void *decoder_wavpack_init_plugin (xine_t *xine, void *data); diff --git a/src/combined/decoder_wavpack.c b/src/combined/decoder_wavpack.c new file mode 100644 index 000000000..ec14dfbf5 --- /dev/null +++ b/src/combined/decoder_wavpack.c @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> + * + * $Id: decoder_wavpack.c,v 1.14 2007/03/29 19:45:33 dgp85 Exp $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#define LOG_MODULE "decode_wavpack" +#define LOG_VERBOSE + +#include "xine_internal.h" +#include "attributes.h" +#include "bswap.h" + +#include <wavpack/wavpack.h> +#include "combined_wavpack.h" + +typedef struct { + audio_decoder_class_t decoder_class; +} wavpack_class_t; + +typedef struct { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + uint8_t *buf; + size_t buf_size; + size_t buf_pos; + + int sample_rate; + uint16_t bits_per_sample:6; + uint16_t channels:4; + + uint16_t output_open:1; + +} wavpack_decoder_t; + +/* Wrapper functions for Wavpack */ +static int32_t xine_buffer_read_bytes(void *const this_gen, void *const data, + int32_t bcount) { + wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; + + if ( bcount <= 0 ) + return 0; + + if ( bcount > (this->buf_size - this->buf_pos) ) + bcount = (this->buf_size - this->buf_pos); + + xine_fast_memcpy(data, this->buf + this->buf_pos, bcount); + this->buf_pos += bcount; + + return bcount; +} + +static uint32_t xine_buffer_get_pos(void *const this_gen) { + wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; + return this->buf_pos; +} + +static int xine_buffer_set_pos_rel(void *const this_gen, const int32_t delta, + const int mode) { + wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; + + switch(mode) { + case SEEK_SET: + if ( delta < 0 || delta > this->buf_size ) + return -1; + + this->buf_pos = delta; + return 0; + case SEEK_CUR: + if ( (this->buf_pos+delta) < 0 || (this->buf_pos+delta) > this->buf_size ) + return -1; + + this->buf_pos += delta; + return 0; + case SEEK_END: + if ( delta < 0 || delta > this->buf_size ) + return -1; + + this->buf_pos = this->buf_size - delta; + + return 0; + } +} + +static int xine_buffer_set_pos_abs(void *const this_gen, const uint32_t pos) { + return xine_buffer_set_pos_rel(this_gen, pos, SEEK_SET); +} + +static int xine_buffer_push_back_byte(void *const this_gen, const int c) { + if ( ! xine_buffer_set_pos_rel(this_gen, -1, SEEK_CUR) ) + return EOF; + return c; +} + +static uint32_t xine_buffer_get_length(void *const this_gen) { + wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; + return this->buf_size; +} + +static int xine_buffer_can_seek(void *const this_gen) { + return 1; +} + +static int32_t xine_buffer_write_bytes(__attr_unused void *const id, + __attr_unused void *const data, + __attr_unused const int32_t bcount) { + lprintf("xine_buffer_write_bytes: access is read-only.\n"); + return 0; +} + +/* Wavpack plugin functions */ +static void wavpack_reset (audio_decoder_t *const this_gen) +{ + wavpack_decoder_t *const this = (wavpack_decoder_t *) this_gen; + + this->buf_pos = 0; +} + +static void wavpack_discontinuity (audio_decoder_t *const this_gen) +{ + /* wavpack_decoder_t *this = (wavpack_decoder_t *) this_gen; */ + + lprintf("Discontinuity!\n"); +} + +static void wavpack_decode_data (audio_decoder_t *const this_gen, buf_element_t *const buf) +{ + wavpack_decoder_t *const this = (wavpack_decoder_t *) this_gen; + + /* We are getting the stream header, open up the audio + * device, and collect information about the stream + */ + if (buf->decoder_flags & BUF_FLAG_STDHEADER) + { + int mode = AO_CAP_MODE_MONO; + + this->sample_rate = buf->decoder_info[1]; + _x_assert(buf->decoder_info[2] <= 32); + this->bits_per_sample = buf->decoder_info[2]; + _x_assert(buf->decoder_info[3] <= 8); + this->channels = buf->decoder_info[3]; + + mode = _x_ao_channels2mode(this->channels); + + _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, + "WavPack"); + + if (!this->output_open) + { + this->output_open = this->stream->audio_out->open ( + this->stream->audio_out, + this->stream, + this->bits_per_sample, + this->sample_rate, + mode) ? 1 : 0; + } + this->buf_pos = 0; + } else if (this->output_open) { + /* This isn't a header frame and we have opened the output device */ + + /* What we have buffered so far, and what is coming in + * is larger than our buffer + */ + if (this->buf_pos + buf->size > this->buf_size) + { + this->buf_size += 2 * buf->size; + this->buf = realloc (this->buf, this->buf_size); + lprintf("reallocating buffer to %zd\n", this->buf_size); + } + + xine_fast_memcpy (&this->buf[this->buf_pos], buf->content, buf->size); + this->buf_pos += buf->size; + + if ( buf->decoder_flags & BUF_FLAG_FRAME_END ) { + static WavpackStreamReader wavpack_buffer_reader = { + .read_bytes = xine_buffer_read_bytes, + .get_pos = xine_buffer_get_pos, + .set_pos_abs = xine_buffer_set_pos_abs, + .set_pos_rel = xine_buffer_set_pos_rel, + .push_back_byte = xine_buffer_push_back_byte, + .get_length = xine_buffer_get_length, + .can_seek = xine_buffer_can_seek, + .write_bytes = xine_buffer_write_bytes + }; + + WavpackContext *ctx = NULL; + /* Current version of wavpack (4.40) does not write more than this */ + char error[256] = { 0, }; + int32_t samples_left; uint32_t samples_total; + const wvheader_t *header = (const wvheader_t*)this->buf; + + this->buf_pos = 0; + + if ( le2me_32(header->samples_count) == 0 ) return; + + ctx = WavpackOpenFileInputEx(&wavpack_buffer_reader, this, NULL, error, OPEN_STREAMING, 0); + if ( ! ctx ) { + lprintf("unable to open the stream: %s\n", error); + this->buf_pos = 0; + return; + } + + samples_left = samples_total = header->samples_count; + while ( samples_left > 0 ) { + uint32_t buf_samples, decoded_count; + audio_buffer_t *audio_buffer = this->stream->audio_out->get_buffer(this->stream->audio_out); + int32_t *decoded; + int i; + + buf_samples = audio_buffer->mem_size / (this->channels * (this->bits_per_sample/8)); + if ( buf_samples > samples_left ) buf_samples = samples_left; + + decoded = alloca(buf_samples * this->channels * sizeof(int32_t)); + + decoded_count = WavpackUnpackSamples(ctx, decoded, buf_samples); + if ( decoded_count == 0 && *error ) { + lprintf("Error during decode: %s\n", error); + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, NULL); + break; + } + + if ( decoded_count == 0 ) { + lprintf("Finished decoding, but still %d samples left?\n", samples_left); + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, NULL); + break; + } + + lprintf("Decoded %d samples\n", buf_samples); + + samples_left -= decoded_count; + + audio_buffer->num_frames = decoded_count; + audio_buffer->vpts = 0; /* TODO: Fix the pts calculation */ + // audio_buffer->vpts = (buf->pts * (samples_total-samples_left)) / samples_total; + lprintf("Audio buffer with pts %"PRId64"\n", audio_buffer->vpts); + + switch(this->bits_per_sample) { + case 8: { + int8_t *data8 = (int8_t*)audio_buffer->mem; + for(i = 0; i < decoded_count*this->channels; i++) + data8[i] = decoded[i]; + } + break; + case 16: { + int16_t *data16 = (int16_t*)audio_buffer->mem; + for(i = 0; i < decoded_count*this->channels; i++) + data16[i] = decoded[i]; + } + } + + this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); + } + + WavpackCloseFile(ctx); + this->buf_pos = 0; + } + } +} + +static void wavpack_dispose (audio_decoder_t *this_gen) { + wavpack_decoder_t *this = (wavpack_decoder_t *) this_gen; + + if (this->output_open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + free(this->buf); + + free (this_gen); +} + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + wavpack_decoder_t * const this = (wavpack_decoder_t *) xine_xmalloc (sizeof (wavpack_decoder_t)); + + this->audio_decoder.decode_data = wavpack_decode_data; + this->audio_decoder.reset = wavpack_reset; + this->audio_decoder.discontinuity = wavpack_discontinuity; + this->audio_decoder.dispose = wavpack_dispose; + this->stream = stream; + + this->buf = NULL; + this->buf_size = 0; + + return (audio_decoder_t *) this; +} + +/* + * wavpack plugin class + */ + +static char *get_identifier (audio_decoder_class_t *this) { + return "wavpackdec"; +} + +static char *get_description (audio_decoder_class_t *this) { + return "wavpack audio decoder plugin"; +} + +static void dispose_class (audio_decoder_class_t *this) { + free (this); +} + +void *decoder_wavpack_init_plugin (xine_t *xine, void *data) { + wavpack_class_t *this; + + this = (wavpack_class_t *) xine_xmalloc (sizeof (wavpack_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.get_identifier = get_identifier; + this->decoder_class.get_description = get_description; + this->decoder_class.dispose = dispose_class; + + return this; +} diff --git a/src/combined/demux_wavpack.c b/src/combined/demux_wavpack.c new file mode 100644 index 000000000..6a0e33e19 --- /dev/null +++ b/src/combined/demux_wavpack.c @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2006-2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> + * + * $Id: demux_wavpack.c,v 1.11 2007/03/17 07:34:02 dgp85 Exp $ + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#define LOG_MODULE "demux_wavpack" +#define LOG_VERBOSE + +#include "xine_internal.h" +#include "xineutils.h" +#include "demux.h" +#include "bswap.h" +#include "attributes.h" + +#include <wavpack/wavpack.h> +#include "combined_wavpack.h" + +typedef struct { + demux_plugin_t demux_plugin; + + xine_stream_t *stream; + fifo_buffer_t *audio_fifo; + input_plugin_t *input; + int status; + + uint32_t current_sample; + uint32_t samples; + uint32_t samplerate; + uint16_t bits_per_sample:6; + uint16_t channels:4; +} demux_wv_t; + +typedef struct { + demux_class_t demux_class; +} demux_wv_class_t; + +static int32_t xine_input_read_bytes(void *const this_gen, void *const data, + const int32_t bcount) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return this->read(this, data, bcount); +} + +static uint32_t xine_input_get_pos(void *const this_gen) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return this->get_current_pos(this); +} + +static int xine_input_set_pos_abs(void *const this_gen, const uint32_t pos) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return this->seek(this, pos, SEEK_SET); +} + +static int xine_input_set_pos_rel(void *const this_gen, const int32_t delta, + const int mode) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return this->seek(this, delta, mode); +} + +static int xine_input_push_back_byte(void *const this_gen, const int c) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + if ( this->seek(this, -1, SEEK_CUR) ) { + return c; + } else { + lprintf("xine_input_push_back_byte: unable to seek.\n"); + return EOF; + } +} + +static uint32_t xine_input_get_length(void *const this_gen) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return this->get_length(this); +} + +static int xine_input_can_seek(void *const this_gen) { + input_plugin_t *const this = (input_plugin_t*)this_gen; + return INPUT_IS_SEEKABLE(this); +} + +static int32_t xine_input_write_bytes(__attr_unused void *const id, + __attr_unused void *const data, + __attr_unused const int32_t bcount) { + lprintf("xine_input_write_bytes: acces is read-only.\n"); + return 0; +} + +static WavpackStreamReader wavpack_input_reader = { + .read_bytes = xine_input_read_bytes, + .get_pos = xine_input_get_pos, + .set_pos_abs = xine_input_set_pos_abs, + .set_pos_rel = xine_input_set_pos_rel, + .push_back_byte = xine_input_push_back_byte, + .get_length = xine_input_get_length, + .can_seek = xine_input_can_seek, + .write_bytes = xine_input_write_bytes +}; + +static int open_wv_file(demux_wv_t *const this) { + WavpackContext *ctx = NULL; + char error[256]; /* Current version of wavpack (4.31) does not write more than this */ + wvheader_t header; + uint32_t tmp; + + /* Right now we don't support non-seekable streams */ + if (! INPUT_IS_SEEKABLE(this->input) ) { + lprintf("open_wv_file: non-seekable inputs aren't supported yet.\n"); + return 0; + } + + /* Read the file header */ + if (_x_demux_read_header(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t)) + return 0; + + /* Validate header, we currently support only Wavpack 4 */ + if ( header.idcode != wvpk_signature || (le2me_16(header.wv_version) >> 8) != 4 ) + return 0; + + /* Rewind */ + this->input->seek(this->input, 0, SEEK_SET); + + ctx = WavpackOpenFileInputEx(&wavpack_input_reader, this->input, NULL, error, 0, 0); + if ( ! ctx ) { + lprintf("xine_open_wavpack_input: unable to open the stream: %s\n", error); + return 0; + } + + this->current_sample = 0; + this->samples = WavpackGetNumSamples(ctx); + lprintf("number of samples: %u\n", this->samples); + this->samplerate = WavpackGetSampleRate(ctx); + lprintf("samplerate: %u Hz\n", this->samplerate); + + tmp = WavpackGetBitsPerSample(ctx); _x_assert(tmp <= 32); + lprintf("bits_per_sample: %u\n", tmp); + this->bits_per_sample = tmp; + + tmp = WavpackGetNumChannels(ctx); _x_assert(tmp <= 8); + lprintf("channels: %u\n", tmp); + this->channels = tmp; + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, + wvpk_signature); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, + this->channels); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, + this->samplerate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, + this->bits_per_sample); + + WavpackCloseFile(ctx); + this->input->seek(this->input, SEEK_SET, 0); + + return 1; +} + +static int demux_wv_send_chunk(demux_plugin_t *const this_gen) { + demux_wv_t *const this = (demux_wv_t *) this_gen; + uint32_t bytes_to_read; uint8_t header_sent = 0; + wvheader_t header; + + lprintf("new frame\n"); + + /* Check if we've finished */ + if (this->current_sample >= this->samples) { + lprintf("all frames read\n"); + this->status = DEMUX_FINISHED; + return this->status; + } + + lprintf("current sample: %u\n", this->current_sample); + + do { + if ( this->input->read(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t) ) { + this->status = DEMUX_FINISHED; + return this->status; + } + + /* The size of the block is «of course» minus 8, and + it also includes the size of the header. + */ + bytes_to_read = le2me_32(header.block_size) + 8 - sizeof(wvheader_t); + + lprintf("demux_wavpack: going to read %u bytes.\n", bytes_to_read); + + while(bytes_to_read) { + off_t bytes_read = 0, bytes_to_read_now, offset = 0; + buf_element_t *buf = NULL; + int64_t input_time_guess; + + /* Get a buffer */ + buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); + buf->type = BUF_AUDIO_WAVPACK; + buf->decoder_flags = 0; + + /* Set normalised position */ + buf->extra_info->input_normpos = + (int) ((double) this->input->get_current_pos(this->input) * 65535 / + this->input->get_length(this->input)); + + buf->pts = (((this->current_sample) / this->samplerate))*90000; + lprintf("Sending buffer with PTS %"PRId64"\n", buf->pts); + + /* Set time */ + input_time_guess = this->samples; + input_time_guess /= this->samplerate; + input_time_guess *= 1000; + input_time_guess *= buf->extra_info->input_normpos; + input_time_guess /= 65535; + buf->extra_info->input_time = input_time_guess; + + bytes_to_read_now = ( bytes_to_read > buf->max_size ) ? buf->max_size : bytes_to_read; + if ( ! header_sent ) { + bytes_to_read_now -= (offset = sizeof(wvheader_t)); + + header_sent = 1; + xine_fast_memcpy(buf->content, &header, sizeof(wvheader_t)); + } + + bytes_read = this->input->read(this->input, &buf->content[offset], bytes_to_read_now); + + buf->size = offset + bytes_read; + + bytes_to_read -= bytes_read; + + if ( bytes_to_read <= 0 && (le2me_32(header.flags) & FINAL_BLOCK) == FINAL_BLOCK) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + + this->audio_fifo->put(this->audio_fifo, buf); + } + } while ( (le2me_32(header.flags) & FINAL_BLOCK) != FINAL_BLOCK ); + + this->current_sample += le2me_32(header.samples_count); + + return this->status; +} + +static void demux_wv_send_headers(demux_plugin_t *const this_gen) { + demux_wv_t *const this = (demux_wv_t *) this_gen; + buf_element_t *buf; + + this->audio_fifo = this->stream->audio_fifo; + + this->status = DEMUX_OK; + + /* Send start buffers */ + _x_demux_control_start(this->stream); + + /* Send header to decoder */ + if (this->audio_fifo) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + + buf->type = BUF_AUDIO_WAVPACK; + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + buf->decoder_info[0] = this->input->get_length(this->input); + buf->decoder_info[1] = this->samplerate; + buf->decoder_info[2] = this->bits_per_sample; + buf->decoder_info[3] = this->channels; + + buf->size = 0; + + this->audio_fifo->put (this->audio_fifo, buf); + } +} + +static int demux_wv_seek (demux_plugin_t *this_gen, + off_t start_pos, int start_time, int playing) { + demux_wv_t *const this = (demux_wv_t *) this_gen; + + /* If thread is not running, initialize demuxer */ + if( !playing ) { + + /* send new pts */ + _x_demux_control_newpts(this->stream, 0, 0); + + this->status = DEMUX_OK; + + } + + return this->status; +} + +static void demux_wv_dispose (demux_plugin_t *const this_gen) { + demux_wv_t *const this = (demux_wv_t *) this_gen; + + free(this); +} + +static int demux_wv_get_status (demux_plugin_t *const this_gen) { + const demux_wv_t *const this = (const demux_wv_t *) this_gen; + + return this->status; +} + +static int demux_wv_get_stream_length (demux_plugin_t *const this_gen) { + const demux_wv_t *const this = (demux_wv_t *) this_gen; + + return (this->samples*1000) / this->samplerate; +} + +static uint32_t demux_wv_get_capabilities(demux_plugin_t *const this_gen) { + return DEMUX_CAP_NOCAP; +} + +static int demux_wv_get_optional_data(demux_plugin_t *const this_gen, + void *data, const int data_type) { + return DEMUX_OPTIONAL_UNSUPPORTED; +} + +static demux_plugin_t *open_plugin (demux_class_t *const class_gen, + xine_stream_t *const stream, + input_plugin_t *const input) { + demux_wv_t *const this = xine_xmalloc (sizeof (demux_wv_t)); + this->stream = stream; + this->input = input; + + this->demux_plugin.send_headers = demux_wv_send_headers; + this->demux_plugin.send_chunk = demux_wv_send_chunk; + this->demux_plugin.seek = demux_wv_seek; + this->demux_plugin.dispose = demux_wv_dispose; + this->demux_plugin.get_status = demux_wv_get_status; + this->demux_plugin.get_stream_length = demux_wv_get_stream_length; + this->demux_plugin.get_capabilities = demux_wv_get_capabilities; + this->demux_plugin.get_optional_data = demux_wv_get_optional_data; + this->demux_plugin.demux_class = class_gen; + + this->status = DEMUX_FINISHED; + switch (stream->content_detection_method) { + + case METHOD_BY_EXTENSION: { + const char *const mrl = input->get_mrl (input); + const char *const extensions = class_gen->get_extensions (class_gen); + + if (!_x_demux_check_extension (mrl, extensions)) { + free (this); + return NULL; + } + } + /* Falling through is intended */ + + case METHOD_BY_CONTENT: + case METHOD_EXPLICIT: + + if (!open_wv_file(this)) { + free (this); + return NULL; + } + + break; + + default: + free (this); + return NULL; + } + + return &this->demux_plugin; +} + +static const char *get_description (demux_class_t *const this_gen) { + return "Wavpack demux plugin"; +} + +static const char *get_identifier (demux_class_t *const this_gen) { + return "Wavpack"; +} + +static const char *get_extensions (demux_class_t *const this_gen) { + return "wv"; +} + +static const char *get_mimetypes (demux_class_t *const this_gen) { + return NULL; +} + +static void class_dispose (demux_class_t *const this_gen) { + demux_wv_class_t *const this = (demux_wv_class_t *) this_gen; + + free (this); +} + +void *demux_wv_init_plugin (xine_t *const xine, void *const data) { + demux_wv_class_t *const this = xine_xmalloc (sizeof (demux_wv_class_t)); + + this->demux_class.open_plugin = open_plugin; + this->demux_class.get_description = get_description; + this->demux_class.get_identifier = get_identifier; + this->demux_class.get_mimetypes = get_mimetypes; + this->demux_class.get_extensions = get_extensions; + this->demux_class.dispose = class_dispose; + + return this; +} diff --git a/src/dxr3/.cvsignore b/src/demuxers/.hgignore index 7d926a554..7d926a554 100644 --- a/src/dxr3/.cvsignore +++ b/src/demuxers/.hgignore diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am index 4523afc27..8a931c2d6 100644 --- a/src/demuxers/Makefile.am +++ b/src/demuxers/Makefile.am @@ -1,12 +1,7 @@ include $(top_srcdir)/misc/Makefile.common -AM_CFLAGS = $(VORBIS_CFLAGS) $(THEORA_CFLAGS) $(SPEEX_CFLAGS) \ - $(LIBMODPLUG_CFLAGS) $(VISIBILITY_FLAG) -AM_CPPFLAGS = $(ZLIB_CPPFLAGS) - -libdir = $(XINE_PLUGINDIR) - -# Sensing of OGG/VORBIS, ZLIB and ASF is broken in cvscompile.sh. +AM_CFLAGS = $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) if HAVE_VORBIS ogg_module = xineplug_dmx_ogg.la @@ -29,7 +24,7 @@ endif # --------- # All of xine demuxer plugins should be named like the scheme "xineplug_dmx_" -lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(mng_module) $(image_module) \ +xineplug_LTLIBRARIES = $(ogg_module) $(asf_module) $(mng_module) $(image_module) \ xineplug_dmx_games.la \ xineplug_dmx_audio.la \ xineplug_dmx_mpeg_ts.la \ @@ -52,65 +47,53 @@ lib_LTLIBRARIES = $(ogg_module) $(asf_module) $(mng_module) $(image_module) \ xineplug_dmx_flv.la xineplug_dmx_ogg_la_SOURCES = demux_ogg.c -xineplug_dmx_ogg_la_LIBADD = $(VORBIS_LIBS) $(SPEEX_LIBS) $(THEORA_LIBS) $(OGG_LIBS) $(XINE_LIB) -xineplug_dmx_ogg_la_LDFLAGS = -avoid-version -module +xineplug_dmx_ogg_la_LIBADD = $(VORBIS_LIBS) $(SPEEX_LIBS) $(THEORA_LIBS) $(OGG_LIBS) $(XINE_LIB) +xineplug_dmx_ogg_la_CFLAGS = $(AM_CFLAGS) $(VORBIS_CFLAGS) $(SPEEX_CFLAGS) $(THEORA_CFLAGS) $(OGG_CFLAGS) xineplug_dmx_avi_la_SOURCES = demux_avi.c xineplug_dmx_avi_la_LIBADD = $(XINE_LIB) -xineplug_dmx_avi_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_block_la_SOURCES = demux_mpeg_block.c xineplug_dmx_mpeg_block_la_LIBADD = $(XINE_LIB) -xineplug_dmx_mpeg_block_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_la_SOURCES = demux_mpeg.c xineplug_dmx_mpeg_la_LIBADD = $(XINE_LIB) -xineplug_dmx_mpeg_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_elem_la_SOURCES = demux_elem.c xineplug_dmx_mpeg_elem_la_LIBADD = $(XINE_LIB) -xineplug_dmx_mpeg_elem_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_pes_la_SOURCES = demux_mpeg_pes.c xineplug_dmx_mpeg_pes_la_LIBADD = $(XINE_LIB) -xineplug_dmx_mpeg_pes_la_LDFLAGS = -avoid-version -module xineplug_dmx_mpeg_ts_la_SOURCES = demux_ts.c xineplug_dmx_mpeg_ts_la_LIBADD = $(XINE_LIB) -xineplug_dmx_mpeg_ts_la_LDFLAGS = -avoid-version -module xineplug_dmx_qt_la_SOURCES = demux_qt.c xineplug_dmx_qt_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) -xineplug_dmx_qt_la_LDFLAGS = -avoid-version -module +xineplug_dmx_qt_la_CPPFLAGS = $(ZLIB_CPPFLAGS) xineplug_dmx_asf_la_SOURCES = demux_asf.c asfheader.c xineplug_dmx_asf_la_LIBADD = $(XINE_LIB) -xineplug_dmx_asf_la_CFLAGS = -fno-strict-aliasing -xineplug_dmx_asf_la_LDFLAGS = -avoid-version -module +xineplug_dmx_asf_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing xineplug_dmx_fli_la_SOURCES = demux_fli.c xineplug_dmx_fli_la_LIBADD = $(XINE_LIB) -xineplug_dmx_fli_la_LDFLAGS = -avoid-version -module xineplug_dmx_yuv4mpeg2_la_SOURCES = demux_yuv4mpeg2.c xineplug_dmx_yuv4mpeg2_la_LIBADD = $(XINE_LIB) -xineplug_dmx_yuv4mpeg2_la_LDFLAGS = -avoid-version -module xineplug_dmx_real_la_SOURCES = demux_real.c xineplug_dmx_real_la_LIBADD = $(XINE_LIB) -xineplug_dmx_real_la_LDFLAGS = -avoid-version -module xineplug_dmx_rawdv_la_SOURCES = demux_rawdv.c xineplug_dmx_rawdv_la_LIBADD = $(XINE_LIB) -xineplug_dmx_rawdv_la_LDFLAGS = -avoid-version -module xineplug_dmx_mng_la_SOURCES = demux_mng.c xineplug_dmx_mng_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(MNG_LIBS) -xineplug_dmx_mng_la_LDFLAGS = -avoid-version -module +xineplug_dmx_mng_la_CPPFLAGS = $(ZLIB_CPPFLAGS) xineplug_dmx_pva_la_SOURCES = demux_pva.c xineplug_dmx_pva_la_LIBADD = $(XINE_LIB) -xineplug_dmx_pva_la_LDFLAGS = -avoid-version -module xineplug_dmx_games_la_SOURCES = group_games.c demux_eawve.c \ demux_idcin.c demux_ipmovie.c demux_roq.c \ @@ -125,38 +108,33 @@ xineplug_dmx_audio_la_SOURCES = group_audio.c demux_aud.c demux_aiff.c \ demux_realaudio.c demux_snd.c demux_voc.c \ demux_vox.c demux_wav.c demux_ac3.c id3.c \ demux_aac.c demux_mod.c demux_flac.c \ - demux_mpc.c demux_dts.c demux_shn.c + demux_mpc.c demux_dts.c demux_shn.c \ + demux_tta.c xineplug_dmx_audio_la_LIBADD = $(XINE_LIB) $(LIBMODPLUG_LIBS) -xineplug_dmx_audio_la_LDFLAGS = -avoid-version -module +xineplug_dmx_audio_la_CFLAGS = $(AM_CFLAGS) $(LIBMODPLUG_CFLAGS) xineplug_dmx_yuv_frames_la_SOURCES = demux_yuv_frames.c xineplug_dmx_yuv_frames_la_LIBADD = $(XINE_LIB) -xineplug_dmx_yuv_frames_la_LDFLAGS = -avoid-version -module xineplug_dmx_slave_la_SOURCES = demux_slave.c xineplug_dmx_slave_la_LIBADD = $(XINE_LIB) -xineplug_dmx_slave_la_LDFLAGS = -avoid-version -module xineplug_dmx_image_la_SOURCES = demux_image.c xineplug_dmx_image_la_LIBADD = $(XINE_LIB) -xineplug_dmx_image_la_LDFLAGS = -avoid-version -module xineplug_dmx_nsv_la_SOURCES = demux_nsv.c xineplug_dmx_nsv_la_LIBADD = $(XINE_LIB) -xineplug_dmx_nsv_la_LDFLAGS = -avoid-version -module xineplug_dmx_matroska_la_SOURCES = demux_matroska.c ebml.c xineplug_dmx_matroska_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) -xineplug_dmx_matroska_la_CFLAGS = -fno-strict-aliasing -xineplug_dmx_matroska_la_LDFLAGS = -avoid-version -module +xineplug_dmx_matroska_la_CPPFLAGS = $(ZLIB_CPPFLAGS) +xineplug_dmx_matroska_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing xineplug_dmx_iff_la_SOURCES = demux_iff.c xineplug_dmx_iff_la_LIBADD = $(XINE_LIB) -xineplug_dmx_iff_la_LDFLAGS = -avoid-version -module xineplug_dmx_flv_la_SOURCES = demux_flv.c xineplug_dmx_flv_la_LIBADD = $(XINE_LIB) -xineplug_dmx_flv_la_LDFLAGS = -avoid-version -module -include_HEADERS = demux.h +xineinclude_HEADERS = demux.h noinst_HEADERS = asfheader.h qtpalette.h group_games.h group_audio.h id3.h ebml.h matroska.h iff.h flacutils.h diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h index 0ce33b090..157519a87 100644 --- a/src/demuxers/demux.h +++ b/src/demuxers/demux.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux.h,v 1.39 2005/02/06 15:26:00 tmattern Exp $ + * $Id: demux.h,v 1.40 2007/01/19 00:26:39 dgp85 Exp $ */ #ifndef HAVE_DEMUX_H @@ -58,19 +58,19 @@ struct demux_class_s { /* * return human readable (verbose = 1 line) description for this plugin */ - char* (*get_description) (demux_class_t *this); + const char* (*get_description) (demux_class_t *this); /* * return human readable identifier for this plugin */ - char* (*get_identifier) (demux_class_t *this); + const char* (*get_identifier) (demux_class_t *this); /* * return MIME types supported for this plugin */ - char* (*get_mimetypes) (demux_class_t *this); + const char* (*get_mimetypes) (demux_class_t *this); /* * return ' ' seperated list of file extensions this @@ -79,7 +79,7 @@ struct demux_class_s { * file selection dialogs) */ - char* (*get_extensions) (demux_class_t *this); + const char* (*get_extensions) (demux_class_t *this); /* * close down, free all resources diff --git a/src/demuxers/demux_4xm.c b/src/demuxers/demux_4xm.c index c6d2d3f0e..56360542c 100644 --- a/src/demuxers/demux_4xm.c +++ b/src/demuxers/demux_4xm.c @@ -23,7 +23,7 @@ * For more information on the 4xm file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_4xm.c,v 1.15 2004/06/13 21:28:52 miguelfreitas Exp $ + * $Id: demux_4xm.c,v 1.16 2007/01/19 00:26:39 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -493,7 +493,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -523,19 +523,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "4X Technologies (4xm) demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "4X Technologies"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "4xm"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_aac.c b/src/demuxers/demux_aac.c index b9e4c4084..ab71e8382 100644 --- a/src/demuxers/demux_aac.c +++ b/src/demuxers/demux_aac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2005 the xine project + * Copyright (C) 2001-2007 the xine project * * This file is part of xine, a free video player. * @@ -21,7 +21,7 @@ * This demuxer detects ADIF and ADTS headers in AAC files. * Then it shovels buffer-sized chunks over to the AAC decoder. * - * $Id: demux_aac.c,v 1.12 2006/11/14 21:51:32 dsalt Exp $ + * $Id: demux_aac.c,v 1.17 2007/03/03 01:41:16 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -48,6 +48,8 @@ #include "bswap.h" #include "group_audio.h" +#include "id3.h" + typedef struct { demux_plugin_t demux_plugin; @@ -57,7 +59,6 @@ typedef struct { input_plugin_t *input; int status; - off_t data_start; off_t data_size; int seek_flag; /* this is set when a seek just occurred */ @@ -72,11 +73,30 @@ static int open_aac_file(demux_aac_t *this) { int i; uint8_t peak[MAX_PREVIEW_SIZE]; uint16_t syncword = 0; + uint32_t id3size = 0; + off_t data_start = 0; - /* Check for an ADIF header - should be at the start of the file */ - if (_x_demux_read_header(this->input, peak, 4) != 4) + _x_assert(MAX_PREVIEW_SIZE > 10); + + /* Get enough data to be able to check the size of ID3 tag */ + if (_x_demux_read_header(this->input, peak, 10) != 10) return 0; + /* Check if there's an ID3v2 tag at the start */ + if ( id3v2_istag(peak) ) { + id3size = id3v2_tagsize(&peak[6]); + + this->input->seek(this->input, 4, SEEK_SET); + + id3v2_parse_tag(this->input, this->stream, peak); + + lprintf("ID3v2 tag encountered, skipping %u bytes.\n", id3size); + } + + if ( this->input->read(this->input, peak, 4) != 4 ) + return 0; + + /* Check for an ADIF header - should be at the start of the file */ if ((peak[0] == 'A') && (peak[1] == 'D') && (peak[2] == 'I') && (peak[3] == 'F')) { lprintf("found ADIF header\n"); @@ -84,13 +104,20 @@ static int open_aac_file(demux_aac_t *this) { } /* Look for an ADTS header - might not be at the start of the file */ - if (_x_demux_read_header(this->input, peak, MAX_PREVIEW_SIZE) != - MAX_PREVIEW_SIZE) + if ( id3size != 0 && this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE ) { + lprintf("Getting a buffer of size %u starting from %u\n", MAX_PREVIEW_SIZE, id3size); + + this->input->seek(this->input, id3size, SEEK_SET); + if ( this->input->read(this->input, peak, MAX_PREVIEW_SIZE) != MAX_PREVIEW_SIZE ) + return 0; + this->input->seek(this->input, 0, SEEK_SET); + } else if (_x_demux_read_header(this->input, peak, MAX_PREVIEW_SIZE) != + MAX_PREVIEW_SIZE) return 0; for (i=0; i<MAX_PREVIEW_SIZE; i++) { if ((syncword & 0xfff6) == 0xfff0) { - this->data_start = i - 2; + data_start = i - 2; lprintf("found ADTS header at offset %d\n", i-2); break; } @@ -99,27 +126,27 @@ static int open_aac_file(demux_aac_t *this) { } /* Look for second ADTS header to confirm it's really aac */ - if (this->data_start + 5 < MAX_PREVIEW_SIZE) { - int frame_size = ((peak[this->data_start+3] & 0x03) << 11) | - (peak[this->data_start+4] << 3) | - ((peak[this->data_start+5] & 0xe0) >> 5); + if (data_start + 5 < MAX_PREVIEW_SIZE) { + int frame_size = ((peak[data_start+3] & 0x03) << 11) | + (peak[data_start+4] << 3) | + ((peak[data_start+5] & 0xe0) >> 5); lprintf("first frame size %d\n", frame_size); if ((frame_size > 0) && - (this->data_start+frame_size < MAX_PREVIEW_SIZE-1) && + (data_start+frame_size < MAX_PREVIEW_SIZE-1) && /* first 28 bits must be identical */ - (peak[this->data_start ] ==peak[this->data_start+frame_size ]) && - (peak[this->data_start+1] ==peak[this->data_start+frame_size+1]) && - (peak[this->data_start+2] ==peak[this->data_start+frame_size+2]) && - (peak[this->data_start+3]>>4==peak[this->data_start+frame_size+3]>>4)) + (peak[data_start ] ==peak[data_start+frame_size ]) && + (peak[data_start+1] ==peak[data_start+frame_size+1]) && + (peak[data_start+2] ==peak[data_start+frame_size+2]) && + (peak[data_start+3]>>4==peak[data_start+frame_size+3]>>4)) { lprintf("found second ADTS header\n"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - this->input->seek(this->input, this->data_start, SEEK_SET); + this->input->seek(this->input, data_start+id3size, SEEK_SET); return 1; } } @@ -255,7 +282,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -283,19 +310,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "ADIF/ADTS AAC demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "AAC"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "aac"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_ac3.c b/src/demuxers/demux_ac3.c index fa2dddfed..7f3dadeb7 100644 --- a/src/demuxers/demux_ac3.c +++ b/src/demuxers/demux_ac3.c @@ -23,7 +23,7 @@ * This demuxer detects raw AC3 data in a file and shovels AC3 data * directly to the AC3 decoder. * - * $Id: demux_ac3.c,v 1.19 2005/06/04 20:32:08 jstembridge Exp $ + * $Id: demux_ac3.c,v 1.21 2007/03/19 16:42:32 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -51,7 +51,6 @@ #include "group_audio.h" #define DATA_TAG 0x61746164 -#define PEAK_SIZE 7056 /* 3 raw cd frames */ typedef struct { demux_plugin_t demux_plugin; @@ -129,31 +128,29 @@ static const struct frmsize_s frmsizecod_tbl[64] = static int open_ac3_file(demux_ac3_t *this) { int i; int offset = 0; - int peak_size = 0; + size_t peak_size = 0; int spdif_mode = 0; uint32_t syncword = 0; uint32_t blocksize; - uint8_t peak[PEAK_SIZE]; + uint8_t *peak; - lprintf("open_ac3_file\n"); - - /* block based demuxer (i.e. cdda) will only allow reads in block - * sized pieces */ blocksize = this->input->get_blocksize(this->input); - if (blocksize && INPUT_IS_SEEKABLE(this->input)) { - int read; - + if (blocksize) { this->input->seek(this->input, 0, SEEK_SET); - while (peak_size < PEAK_SIZE) { - read = this->input->read(this->input, &peak[peak_size], blocksize); - if (read) - peak_size += read; - else - break; - } + buf_element_t *buf = this->input->read_block(this->input, + this->audio_fifo, + blocksize); this->input->seek(this->input, 0, SEEK_SET); + + if (!buf) + return 0; + + peak = alloca(peak_size = buf->size); + xine_fast_memcpy(peak, buf->content, peak_size); + + buf->free_buffer(buf); } else { - peak_size = MAX_PREVIEW_SIZE; + peak = alloca(peak_size = MAX_PREVIEW_SIZE); if (_x_demux_read_header(this->input, peak, peak_size) != peak_size) return 0; @@ -163,10 +160,7 @@ static int open_ac3_file(demux_ac3_t *this) { /* Check for wav header, as we'll handle AC3 with a wav header shoved * on the front for CD burning */ - if ((peak[0] == 'R') && (peak[1] == 'I') && (peak[2] == 'F') && - (peak[3] == 'F') && (peak[8] == 'W') && (peak[9] == 'A') && - (peak[10] == 'V') && (peak[11] == 'E') && (peak[12] == 'f') && - (peak[13] == 'm') && (peak[14] == 't') && (peak[15] == ' ')) { + if ( memcmp(peak, "RIFF", 4) == 0 || memcmp(&peak[8], "WAVEfmt ", 8) == 0 ) { /* Check this looks like a cd audio wav */ unsigned int audio_type; xine_waveformatex *wave = (xine_waveformatex *) &peak[20]; @@ -441,7 +435,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -471,19 +465,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Raw AC3 demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "AC3"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "ac3"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index 253827454..f88c58572 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -21,7 +21,7 @@ /* * AIFF File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_aiff.c,v 1.40 2004/12/15 21:03:02 mroi Exp $ + * $Id: demux_aiff.c,v 1.41 2007/01/19 00:26:40 dgp85 Exp $ * */ @@ -359,7 +359,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -389,19 +389,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "AIFF file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "AIFF"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "aif aiff"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/x-aiff: aif, aiff: AIFF audio;" "audio/aiff: aif, aiff: AIFF audio;" "audio/x-pn-aiff: aif, aiff: AIFF audio;"; diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index ba31d6e51..65838138f 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_asf.c,v 1.188 2006/11/29 21:26:52 dgp85 Exp $ + * $Id: demux_asf.c,v 1.194 2007/03/09 23:18:19 dgp85 Exp $ * * demultiplexer for asf streams * @@ -38,6 +38,9 @@ #include <unistd.h> #include <string.h> #include <stdlib.h> +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif #define LOG_MODULE "demux_asf" #define LOG_VERBOSE @@ -408,7 +411,9 @@ static int asf_read_header (demux_asf_t *this) { this->length = 0; /* compute average byterate (needed for seeking) */ - if (this->length) + if (this->asf_header->file->max_bitrate) + this->rate = this->asf_header->file->max_bitrate >> 3; + else if (this->length) this->rate = (int64_t) this->input->get_length(this->input) * 1000 / this->length; _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->asf_header->file->max_bitrate); @@ -639,15 +644,15 @@ static void check_newpts (demux_asf_t *this, int64_t pts, int video, int frame_e #ifdef LOG if (pts) { if (video) { - printf ("demux_asf: VIDEO: pts = %8lld, diff = %8lld\n", pts, pts - this->last_pts[video]); + printf ("demux_asf: VIDEO: pts = %8"PRId64", diff = %8"PRId64"\n", pts, pts - this->last_pts[video]); } else { - printf ("demux_asf: AUDIO: pts = %8lld, diff = %8lld\n", pts, pts - this->last_pts[video]); + printf ("demux_asf: AUDIO: pts = %8"PRId64", diff = %8"PRId64"\n", pts, pts - this->last_pts[video]); } } #endif if (pts && (this->send_newpts || (this->last_pts[video] && abs(diff) > WRAP_THRESHOLD))) { - lprintf ("sending newpts %lld (video = %d diff = %lld)\n", pts, video, diff); + lprintf ("sending newpts %"PRId64" (video = %d diff = %"PRId64")\n", pts, video, diff); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); @@ -674,7 +679,7 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *str int bufsize; int package_done; - lprintf ("pts=%lld, off=%d, len=%d, total=%d\n", + lprintf ("pts=%"PRId64", off=%d, len=%d, total=%d\n", timestamp * 90, frag_offset, frag_len, stream->payload_size); if (frag_offset == 0) { @@ -758,7 +763,7 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_demux_stream_t *strea printf("asf_send_buffer seq=%d frag_offset=%d frag_len=%d\n", seq, frag_offset, frag_len ); */ - lprintf ("asf_send_buffer_defrag: timestamp=%lld, pts=%lld\n", timestamp, timestamp * 90); + lprintf ("asf_send_buffer_defrag: timestamp=%"PRId64", pts=%"PRId64"\n", timestamp, timestamp * 90); if (frag_offset == 0) { /* new packet */ @@ -864,11 +869,11 @@ static int asf_parse_packet_align(demux_asf_t *this) { /* check packet_count */ packet_num = (packet_pos - this->first_packet_pos) / this->packet_size; - lprintf("packet_num=%lld, packet_count=%lld\n", packet_num, this->packet_count); + lprintf("packet_num=%"PRId64", packet_count=%"PRId64"\n", packet_num, this->packet_count); if (packet_num >= this->packet_count) { /* end of payload data */ current_pos = this->input->get_current_pos (this->input); - lprintf("end of payload data, current_pos=%lld\n", current_pos); + lprintf("end of payload data, current_pos=%"PRId64"\n", current_pos); { /* check new asf header */ if (get_guid(this) == GUID_ASF_HEADER) { @@ -998,7 +1003,7 @@ static int asf_parse_packet_payload_header(demux_asf_t *this, uint32_t p_hdr_siz timestamp = get_le32(this); p_hdr_size += 4; duration = get_le16(this); p_hdr_size += 2; - lprintf ("timestamp=%lld, duration=%lld\n", timestamp, duration); + lprintf ("timestamp=%"PRId64", duration=%"PRId64"\n", timestamp, duration); if ((this->packet_len_flags >> 5) & 3) { /* absolute data size */ @@ -1354,7 +1359,6 @@ static int demux_asf_parse_http_references( demux_asf_t *this) { int buf_used = 0; int len; char *href = NULL; - char *mrl; int free_href = 0; /* read file to memory. @@ -1379,7 +1383,7 @@ static int demux_asf_parse_http_references( demux_asf_t *this) { ptr = buf; if (!strncmp(ptr, "[Reference]", 11)) { - mrl = this->input->get_mrl(this->input); + const char *const mrl = this->input->get_mrl(this->input); if (!strncmp(mrl, "http", 4)) { /* never trust a ms server, reopen the same mrl with the mms input plugin * some servers are badly configured and return a incorrect reference. @@ -1789,11 +1793,7 @@ static int demux_asf_seek (demux_plugin_t *this_gen, int i, state; int64_t ts; - start_time /= 1000; - start_pos = (off_t) ( (double) start_pos / 65535 * - this->input->get_length (this->input) ); - - lprintf ("demux_asf_seek: start_pos=%lld, start_time=%d\n", + lprintf ("demux_asf_seek: start_pos=%"PRId64", start_time=%d\n", start_pos, start_time); this->status = DEMUX_OK; @@ -1824,6 +1824,10 @@ static int demux_asf_seek (demux_plugin_t *this_gen, _x_demux_flush_engine(this->stream); + start_time /= 1000; + start_pos = (off_t) ( (double) start_pos / 65535 * + this->input->get_length (this->input) ); + if ( (!start_pos) && (start_time)) start_pos = start_time * this->rate; @@ -1910,13 +1914,13 @@ static int demux_asf_seek (demux_plugin_t *this_gen, } state = 1; /* search an audio packet with pts < this->keyframe_pts */ - lprintf ("demux_asf_seek: keyframe found at %lld, timestamp = %lld\n", start_pos, ts); + lprintf ("demux_asf_seek: keyframe found at %"PRId64", timestamp = %"PRId64"\n", start_pos, ts); check_newpts (this, ts * 90, 1, 0); } } else if (state == 1) { if ((this->audio_stream != -1 && stream_id == this->asf_header->streams[this->audio_stream]->stream_number) && ts && (ts <= this->keyframe_ts)) { - lprintf ("demux_asf_seek: audio packet found at %lld, ts = %lld\n", start_pos, ts); + lprintf ("demux_asf_seek: audio packet found at %"PRId64", ts = %"PRId64"\n", start_pos, ts); state = 5; /* end */ break; @@ -1927,7 +1931,7 @@ static int demux_asf_seek (demux_plugin_t *this_gen, this->keyframe_ts = ts; state = 5; /* end */ - lprintf ("demux_asf_seek: audio packet found at %lld, timestamp = %lld\n", start_pos, ts); + lprintf ("demux_asf_seek: audio packet found at %"PRId64", timestamp = %"PRId64"\n", start_pos, ts); check_newpts (this, ts * 90, 0, 0); } } @@ -1941,7 +1945,7 @@ static int demux_asf_seek (demux_plugin_t *this_gen, } else { this->input->seek (this->input, start_pos + this->packet_size, SEEK_SET); } - lprintf ("demux_asf_seek: keyframe_found=%d, keyframe_ts=%lld\n", + lprintf ("demux_asf_seek: keyframe_found=%d, keyframe_ts=%"PRId64"\n", this->keyframe_found, this->keyframe_ts); if (this->video_stream >= 0) { this->streams[this->video_stream].resync = 1; @@ -1951,6 +1955,22 @@ static int demux_asf_seek (demux_plugin_t *this_gen, this->streams[this->audio_stream].resync = 1; this->streams[this->audio_stream].skip = 1; } + } else if (!playing && this->input->seek_time != NULL) { + if (start_pos && !start_time) + start_time = this->length * start_pos / 65535; + + this->input->seek_time (this->input, start_time, SEEK_SET); + + this->keyframe_ts = 0; + this->keyframe_found = 0; /* means next keyframe */ + if (this->video_stream >= 0) { + this->streams[this->video_stream].resync = 1; + this->streams[this->video_stream].skip = 1; + } + if (this->audio_stream >= 0) { + this->streams[this->audio_stream].resync = 0; + this->streams[this->audio_stream].skip = 0; + } } else { /* "streaming" mode */ this->keyframe_ts = 0; @@ -2034,15 +2054,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, break; case METHOD_BY_EXTENSION: { - char *ending, *mrl; - - mrl = input->get_mrl (input); - - /* - * check extension - */ - - ending = strrchr (mrl, '.'); + const char *const mrl = input->get_mrl (input); + const char *const ending = strrchr (mrl, '.'); if (!ending) return NULL; @@ -2105,20 +2118,20 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "ASF demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "ASF"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { /* asx, wvx, wax are metafile or playlist */ return "asf wmv wma asx wvx wax"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/x-ms-asf: asf: ASF stream;" "video/x-ms-wmv: wmv: Windows Media Video;" diff --git a/src/demuxers/demux_aud.c b/src/demuxers/demux_aud.c index 5ebf25e13..ea57a6939 100644 --- a/src/demuxers/demux_aud.c +++ b/src/demuxers/demux_aud.c @@ -34,7 +34,7 @@ * data. This makes seeking conceptually impossible. Upshot: Random * seeking is not supported. * - * $Id: demux_aud.c,v 1.19 2004/06/13 21:28:52 miguelfreitas Exp $ + * $Id: demux_aud.c,v 1.20 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -292,7 +292,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str case METHOD_BY_CONTENT: /* no reliable detection */ case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -320,19 +320,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Westwood Studios AUD file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Westwood Studios AUD"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "aud"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index 4f4cbc428..fe324c2f4 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_avi.c,v 1.228 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_avi.c,v 1.232 2007/03/29 19:24:18 dgp85 Exp $ * * demultiplexer for avi streams * @@ -194,8 +194,8 @@ typedef struct{ uint32_t audio_posb; /* Audio position: byte within chunk */ + int wavex_len; xine_waveformatex *wavex; - int wavex_len; audio_index_t audio_idx; @@ -251,28 +251,27 @@ typedef struct demux_avi_s { input_plugin_t *input; int status; - avi_t *avi; - - int no_audio; - uint32_t video_step; uint32_t AVI_errno; - idx_grow_t idx_grow; - - int streaming; - int last_index_entry_type; - int has_index; - /* seeking args backup */ - int seek_request; - off_t seek_start_pos; int seek_start_time; + off_t seek_start_pos; + + avi_t *avi; + + idx_grow_t idx_grow; + + uint8_t no_audio:1; + + uint8_t streaming:1; + uint8_t has_index:1; + + uint8_t seek_request:1; /* discontinuity detection (only at seek) */ - int send_newpts; - int buf_flag_seek; - + uint8_t buf_flag_seek:1; + uint8_t send_newpts:1; } demux_avi_t ; typedef struct { @@ -1392,7 +1391,7 @@ static avi_t *AVI_init(demux_avi_t *this) { AVI->video_posf = 0; AVI->video_posb = 0; - lprintf("done, pos=%lld, AVI->movi_start=%" PRIdMAX "\n", this->input->get_current_pos(this->input), (intmax_t)AVI->movi_start); + lprintf("done, pos=%"PRId64", AVI->movi_start=%" PRIdMAX "\n", this->input->get_current_pos(this->input), (intmax_t)AVI->movi_start); return AVI; } @@ -2259,7 +2258,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -2316,19 +2315,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str * demux avi class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "AVI/RIFF demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "AVI"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "avi"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/msvideo: avi: AVI video;" "video/x-msvideo: avi: AVI video;"; } diff --git a/src/demuxers/demux_cdda.c b/src/demuxers/demux_cdda.c index 3790ee6b9..d92a8ba23 100644 --- a/src/demuxers/demux_cdda.c +++ b/src/demuxers/demux_cdda.c @@ -24,7 +24,7 @@ * linear PCM "decoder" (which in turn sends them directly to the audio * output target; this is a really fancy CD-playing architecture). * - * $Id: demux_cdda.c,v 1.19 2004/06/13 21:28:52 miguelfreitas Exp $ + * $Id: demux_cdda.c,v 1.20 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -227,19 +227,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "CD Digital Audio demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "CDDA"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return NULL; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_dts.c b/src/demuxers/demux_dts.c index 16f14211d..7baeae377 100644 --- a/src/demuxers/demux_dts.c +++ b/src/demuxers/demux_dts.c @@ -19,7 +19,7 @@ * * Raw DTS Demuxer by James Stembridge (jstembridge@gmail.com) * - * $Id: demux_dts.c,v 1.6 2005/06/04 20:32:08 jstembridge Exp $ + * $Id: demux_dts.c,v 1.8 2007/03/19 16:42:32 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -47,7 +47,6 @@ #include "group_audio.h" #define DATA_TAG 0x61746164 -#define PEAK_SIZE 7056 /* 3 raw cd frames */ typedef struct { demux_plugin_t demux_plugin; @@ -79,29 +78,29 @@ static const int dts_sample_rates[] = static int open_dts_file(demux_dts_t *this) { int i, offset = 0; uint32_t syncword = 0; - int peak_size = 0; + size_t peak_size = 0; uint32_t blocksize; - uint8_t peak[PEAK_SIZE]; + uint8_t *peak; lprintf("open_dts_file\n"); - /* block based demuxer (i.e. cdda) will only allow reads in block - * sized pieces */ blocksize = this->input->get_blocksize(this->input); - if (blocksize && INPUT_IS_SEEKABLE(this->input)) { - int read; - + if (blocksize) { this->input->seek(this->input, 0, SEEK_SET); - while (peak_size < PEAK_SIZE) { - read = this->input->read(this->input, &peak[peak_size], blocksize); - if (read) - peak_size += read; - else - break; - } + buf_element_t *buf = this->input->read_block(this->input, + this->audio_fifo, + blocksize); this->input->seek(this->input, 0, SEEK_SET); + + if (!buf) + return 0; + + peak = alloca(peak_size = buf->size); + xine_fast_memcpy(peak, buf->content, peak_size); + + buf->free_buffer(buf); } else { - peak_size = MAX_PREVIEW_SIZE; + peak = alloca(peak_size = MAX_PREVIEW_SIZE); if (_x_demux_read_header(this->input, peak, peak_size) != peak_size) return 0; @@ -111,10 +110,7 @@ static int open_dts_file(demux_dts_t *this) { /* Check for wav header, as we'll handle DTS with a wav header shoved * on the front for CD burning */ - if ((peak[0] == 'R') && (peak[1] == 'I') && (peak[2] == 'F') && - (peak[3] == 'F') && (peak[8] == 'W') && (peak[9] == 'A') && - (peak[10] == 'V') && (peak[11] == 'E') && (peak[12] == 'f') && - (peak[13] == 'm') && (peak[14] == 't') && (peak[15] == ' ')) { + if ( memcmp(peak, "RIFF", 4) == 0 || memcmp(&peak[8], "WAVEfmt ", 8) == 0 ) { /* Check this looks like a cd audio wav */ unsigned int audio_type; xine_waveformatex *wave = (xine_waveformatex *) &peak[20]; @@ -368,7 +364,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -396,19 +392,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Raw DTS demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "DTS"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "dts"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_eawve.c b/src/demuxers/demux_eawve.c index 7d7cc922a..67c087208 100644 --- a/src/demuxers/demux_eawve.c +++ b/src/demuxers/demux_eawve.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_eawve.c,v 1.28 2004/06/13 21:28:52 miguelfreitas Exp $ + * $Id: demux_eawve.c,v 1.29 2007/01/19 00:26:40 dgp85 Exp $ * * demux_eawve.c, Demuxer plugin for Electronic Arts' WVE file format * @@ -370,7 +370,7 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -400,19 +400,19 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre return &this->demux_plugin; } -static char *get_description(demux_class_t *this_gen){ +static const char *get_description(demux_class_t *this_gen){ return "Electronics Arts WVE format demux plugin"; } -static char *get_identifier(demux_class_t *this_gen){ +static const char *get_identifier(demux_class_t *this_gen){ return "EA WVE"; } -static char *get_extensions(demux_class_t *this_gen){ +static const char *get_extensions(demux_class_t *this_gen){ return "wve"; } -static char *get_mimetypes(demux_class_t *this_gen){ +static const char *get_mimetypes(demux_class_t *this_gen){ return NULL; } diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c index 2645992bc..be86b32ed 100644 --- a/src/demuxers/demux_elem.c +++ b/src/demuxers/demux_elem.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_elem.c,v 1.89 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_elem.c,v 1.91 2007/02/20 00:34:55 dgp85 Exp $ * * demultiplexer for elementary mpeg streams */ @@ -73,7 +73,7 @@ static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) { buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); blocksize = (this->blocksize ? this->blocksize : buf->max_size); done = this->input->read(this->input, buf->mem, blocksize); - lprintf ("read size = %lld\n", done); + lprintf ("read size = %"PRId64"\n", done); if (done <= 0) { buf->free_buffer (buf); @@ -160,7 +160,7 @@ static int demux_mpeg_elem_seek (demux_plugin_t *this_gen, this->status = DEMUX_FINISHED; return this->status; } - lprintf ("seeking to %lld\n", start_pos); + lprintf ("seeking to %"PRId64"\n", start_pos); } /* @@ -225,7 +225,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -261,19 +261,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Elementary MPEG stream demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEG_ELEM"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mpv"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c index f4a27c22b..d3cedc0e1 100644 --- a/src/demuxers/demux_film.c +++ b/src/demuxers/demux_film.c @@ -21,7 +21,7 @@ * For more information on the FILM file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_film.c,v 1.81 2006/11/19 16:07:50 dgp85 Exp $ + * $Id: demux_film.c,v 1.82 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -874,7 +874,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -904,19 +904,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "FILM (CPK) demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "FILM (CPK)"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "cpk cak film"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c index bd5c19350..f52da4d03 100644 --- a/src/demuxers/demux_flac.c +++ b/src/demuxers/demux_flac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2004 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -23,7 +23,7 @@ * For more information on the FLAC file format, visit: * http://flac.sourceforge.net/ * - * $Id: demux_flac.c,v 1.12 2006/11/09 23:51:29 dgp85 Exp $ + * $Id: demux_flac.c,v 1.17 2007/03/29 16:52:23 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -49,6 +49,7 @@ #include "bswap.h" #include "group_audio.h" +#include "id3.h" #include "flacutils.h" typedef struct { @@ -66,10 +67,10 @@ typedef struct { off_t data_start; off_t data_size; - unsigned char streaminfo[sizeof(xine_waveformatex) + FLAC_STREAMINFO_SIZE]; flac_seekpoint_t *seekpoints; int seekpoint_count; + unsigned char streaminfo[sizeof(xine_waveformatex) + FLAC_STREAMINFO_SIZE]; } demux_flac_t; typedef struct { @@ -81,7 +82,7 @@ typedef struct { * It returns 1 if flac file was opened successfully. */ static int open_flac_file(demux_flac_t *flac) { - unsigned char preamble[4]; + unsigned char preamble[10]; unsigned int block_length; unsigned char buffer[FLAC_SEEKPOINT_SIZE]; unsigned char *streaminfo = flac->streaminfo + sizeof(xine_waveformatex); @@ -89,26 +90,19 @@ static int open_flac_file(demux_flac_t *flac) { flac->seekpoints = NULL; - /* fetch the file signature */ - if (_x_demux_read_header(flac->input, preamble, 4) != 4) + /* fetch the file signature, get enough bytes so that id3 can also + be skipped and/or parsed */ + if (_x_demux_read_header(flac->input, preamble, 10) != 10) return 0; - /* validate signature */ - if ((preamble[0] != 'f') || - (preamble[1] != 'L') || - (preamble[2] != 'a') || - (preamble[3] != 'C')) { - + /* Unfortunately some FLAC files have an ID3 flag prefixed on them + * before the actual FLAC headers... these are barely legal, but + * users use them and want them working, so check and skip the ID3 + * tag if present. + */ + if ( id3v2_istag(preamble) ) { uint32_t id3size; - /* Unfortunately some FLAC files have an ID3 flag prefixed on them - * before the actual FLAC headers... these are barely legal, but - * users use them and want them working, so check and skip the ID3 - * tag if present. - */ - if ( preamble[0] != 'I' || preamble[1] != 'D' || preamble[2] != '3' ) - return 0; - /* First 3 bytes are the ID3 signature as above, then comes two bytes * encoding the major and minor version of ID3 used, that we can ignore * as long as we don't try to read the metadata; after those there's a @@ -117,24 +111,22 @@ static int open_flac_file(demux_flac_t *flac) { * is encoded as four bytes.. but only 7 out of 8 bits of every byte is * used... don't ask. */ - flac->input->seek(flac->input, 6, SEEK_SET); - if ( flac->input->read(flac->input, preamble, 4) != 4 ) - return 0; + id3size = id3v2_tagsize(&preamble[6]); - id3size = (preamble[0] << 7*3) + (preamble[1] << 7*2) + (preamble[2] << 7) + preamble[3]; - - flac->input->seek(flac->input, id3size, SEEK_CUR); + id3v2_parse_tag(flac->input, flac->stream, preamble); + + flac->input->seek(flac->input, id3size, SEEK_SET); if ( flac->input->read(flac->input, preamble, 4) != 4 ) return 0; - - if ( preamble[0] != 'f' || preamble[1] != 'L' || preamble[2] != 'a' || preamble[3] != 'C' ) - return 0; - - } else - /* file is qualified; skip over the signature bytes in the stream */ + } else flac->input->seek(flac->input, 4, SEEK_SET); + /* validate signature */ + if ((preamble[0] != 'f') || (preamble[1] != 'L') || + (preamble[2] != 'a') || (preamble[3] != 'C')) + return 0; + /* loop through the metadata blocks; use a do-while construct since there * will always be 1 metadata block */ do { @@ -166,7 +158,7 @@ static int open_flac_file(demux_flac_t *flac) { flac->bits_per_sample = ((flac->sample_rate >> 4) & 0x1F) + 1; flac->sample_rate >>= 12; flac->total_samples = BE_64(&streaminfo[10]) & UINT64_C(0x0FFFFFFFFF); /* 36 bits */ - lprintf ("%d Hz, %d bits, %d channels, %lld total samples\n", + lprintf ("%d Hz, %d bits, %d channels, %"PRId64" total samples\n", flac->sample_rate, flac->bits_per_sample, flac->channels, flac->total_samples); break; @@ -193,15 +185,15 @@ static int open_flac_file(demux_flac_t *flac) { if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE) return 0; flac->seekpoints[i].sample_number = BE_64(&buffer[0]); - lprintf (" %d: sample %lld, ", i, flac->seekpoints[i].sample_number); + lprintf (" %d: sample %"PRId64", ", i, flac->seekpoints[i].sample_number); flac->seekpoints[i].offset = BE_64(&buffer[8]); flac->seekpoints[i].size = BE_16(&buffer[16]); - lprintf ("@ 0x%llX, size = %d bytes, ", + lprintf ("@ 0x%"PRIX64", size = %d bytes, ", flac->seekpoints[i].offset, flac->seekpoints[i].size); flac->seekpoints[i].pts = flac->seekpoints[i].sample_number; flac->seekpoints[i].pts *= 90000; flac->seekpoints[i].pts /= flac->sample_rate; - lprintf ("pts = %lld\n", flac->seekpoints[i].pts); + lprintf ("pts = %"PRId64"\n", flac->seekpoints[i].pts); } break; @@ -524,7 +516,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -554,19 +546,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Free Lossless Audio Codec (flac) demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "FLAC"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "flac"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c index e17e47258..c9cc26cf1 100644 --- a/src/demuxers/demux_fli.c +++ b/src/demuxers/demux_fli.c @@ -24,7 +24,7 @@ * avoid while programming a FLI decoder, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_fli.c,v 1.59 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_fli.c,v 1.60 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -324,7 +324,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -354,19 +354,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Autodesk Animator FLI/FLC demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "FLI/FLC"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "fli flc"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/x-flic: fli,flc: Autodesk FLIC files;"; } diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c index 57f83e002..0588b408e 100644 --- a/src/demuxers/demux_flv.c +++ b/src/demuxers/demux_flv.c @@ -20,11 +20,13 @@ /* * Flash Video (.flv) File Demuxer - * by Mike Melanson (melanson@pcisys.net) + * by Mike Melanson (melanson@pcisys.net) and + * Claudio Ciccani (klan@directfb.org) + * * For more information on the FLV file format, visit: * http://download.macromedia.com/pub/flash/flash_file_format_specification.pdf * - * $Id: demux_flv.c,v 1.9 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_flv.c,v 1.21 2007/03/17 11:29:43 klan Exp $ */ #ifdef HAVE_CONFIG_H @@ -42,7 +44,6 @@ /* #define LOG */ - #include "xine_internal.h" #include "xineutils.h" #include "compat.h" @@ -51,103 +52,448 @@ #include "group_games.h" typedef struct { + unsigned int pts; + unsigned int offset; +} flv_index_entry_t; + +typedef struct { demux_plugin_t demux_plugin; + xine_t *xine; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; - unsigned int video_type; - unsigned int audio_type; - - off_t data_start; - off_t data_size; - - unsigned char bih[sizeof(xine_bmiheader)]; - xine_waveformatex wave; - + unsigned char flags; + off_t start; /* in bytes */ + off_t size; /* in bytes */ + + unsigned char got_video; + unsigned char got_audio; + + unsigned int length; /* in ms */ + int width; + int height; + double framerate; + + flv_index_entry_t *index; + int num_indices; + + unsigned int cur_pts; + + int64_t last_pts[2]; + int send_newpts; + int buf_flag_seek; } demux_flv_t ; typedef struct { demux_class_t demux_class; } demux_flv_class_t; + +#define FLV_FLAG_HAS_VIDEO 0x01 +#define FLV_FLAG_HAS_AUDIO 0x04 + +#define FLV_TAG_TYPE_AUDIO 0x08 +#define FLV_TAG_TYPE_VIDEO 0x09 +#define FLV_TAG_TYPE_SCRIPT 0x12 + +#define FLV_SOUND_FORMAT_PCM_BE 0x00 +#define FLV_SOUND_FORMAT_ADPCM 0x01 +#define FLV_SOUND_FORMAT_MP3 0x02 +#define FLV_SOUND_FORMAT_PCM_LE 0x03 +#define FLV_SOUND_FORMAT_NELLY8 0x05 /* Nellymoser 8KHz */ +#define FLV_SOUND_FORMAT_NELLY 0x06 /* Nellymoser */ + +#define FLV_VIDEO_FORMAT_FLV1 0x02 /* Sorenson H.263 */ +#define FLV_VIDEO_FORMAT_SCREEN 0x03 +#define FLV_VIDEO_FORMAT_VP6 0x04 /* On2 VP6 */ +#define FLV_VIDEO_FORMAT_VP6A 0x05 /* On2 VP6 with alphachannel */ +#define FLV_VIDEO_FORMAT_SCREEN2 0x06 + +#define FLV_DATA_TYPE_NUMBER 0x00 +#define FLV_DATA_TYPE_BOOL 0x01 +#define FLV_DATA_TYPE_STRING 0x02 +#define FLV_DATA_TYPE_OBJECT 0x03 +#define FLC_DATA_TYPE_CLIP 0x04 +#define FLV_DATA_TYPE_REFERENCE 0x07 +#define FLV_DATA_TYPE_ECMARRAY 0x08 +#define FLV_DATA_TYPE_ENDOBJECT 0x09 +#define FLV_DATA_TYPE_ARRAY 0x0a +#define FLV_DATA_TYPE_DATE 0x0b +#define FLV_DATA_TYPE_LONGSTRING 0x0c + + +/* redefine abs as macro to handle 64-bit diffs. + i guess llabs may not be available everywhere */ +#define abs(x) ( ((x)<0) ? -(x) : (x) ) + +#define WRAP_THRESHOLD 220000 +#define PTS_AUDIO 0 +#define PTS_VIDEO 1 + +static void check_newpts(demux_flv_t *this, int64_t pts, int video) { + int64_t diff; + + diff = pts - this->last_pts[video]; + lprintf ("check_newpts %"PRId64"\n", pts); + + if (pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD))) { + lprintf ("diff=%"PRId64"\n", diff); + + if (this->buf_flag_seek) { + _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); + this->buf_flag_seek = 0; + } else { + _x_demux_control_newpts(this->stream, pts, 0); + } + this->send_newpts = 0; + this->last_pts[1-video] = 0; + } + + if (pts) + this->last_pts[video] = pts; +} + /* returns 1 if the FLV file was opened successfully, 0 otherwise */ static int open_flv_file(demux_flv_t *this) { + unsigned char buffer[9]; - unsigned char buffer[4]; - off_t first_offset; - - if (_x_demux_read_header(this->input, buffer, 4) != 4) + if (_x_demux_read_header(this->input, buffer, 9) != 9) return 0; if ((buffer[0] != 'F') || (buffer[1] != 'L') || (buffer[2] != 'V')) return 0; + + if (buffer[3] != 0x01) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("unsupported FLV version (%d).\n"), buffer[3]); + return 0; + } - this->video_type = this->audio_type = 0; - if (buffer[3] & 0x1) - this->video_type = BUF_VIDEO_FLV1; -/* buffer[3] * 0x4 indicates audio, possibly always MP3; deal with - that later */ - - /* file is qualified at this point; position to start of first packet */ - this->input->seek(this->input, 5, SEEK_SET); - if (this->input->read(this->input, buffer, 4) != 4) + this->flags = buffer[4]; + if ((this->flags & (FLV_FLAG_HAS_VIDEO | FLV_FLAG_HAS_AUDIO)) == 0) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("neither video nor audio stream in this file.\n")); return 0; + } - first_offset = BE_32(buffer); - this->input->seek(this->input, first_offset, SEEK_SET); + this->start = BE_32(&buffer[5]); + this->size = this->input->get_length(this->input); + + if (INPUT_IS_SEEKABLE(this->input)) + this->input->seek(this->input, this->start, SEEK_SET); + else if (this->start > 9) + this->input->seek(this->input, this->start-9, SEEK_CUR); + lprintf(" qualified FLV file, repositioned @ offset 0x%" PRIxMAX "\n", - (intmax_t)first_offset); + (intmax_t)this->start); return 1; } -static int demux_flv_send_chunk(demux_plugin_t *this_gen) { - - demux_flv_t *this = (demux_flv_t *) this_gen; - buf_element_t *buf = NULL; - unsigned int remaining_bytes; - unsigned char chunk_type, sub_type; - int64_t pts; - - unsigned char buffer[12]; +#define BE_F64(buf) ({\ + union { uint64_t q; double d; } _tmp;\ + _tmp.q = BE_64(buf);\ + _tmp.d;\ +})\ + +static int parse_flv_var(demux_flv_t *this, + unsigned char *buf, int size, char *key, int keylen) { + unsigned char *tmp = buf; + unsigned char *end = buf + size; + char *str; + unsigned char type; + int len, num; + + if (size < 1) + return 0; + + type = *tmp++; + + switch (type) { + case FLV_DATA_TYPE_NUMBER: + lprintf(" got number (%f)\n", BE_F64(tmp)); + if (key) { + double val = BE_F64(tmp); + if (keylen == 8 && !strncmp(key, "duration", 8)) { + this->length = val * 1000.0; + } + else if (keylen == 5 && !strncmp(key, "width", 5)) { + this->width = val; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); + } + else if (keylen == 6 && !strncmp(key, "height", 6)) { + this->height = val; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); + } + else if (keylen == 9 && !strncmp(key, "framerate", 9)) { + this->framerate = val; + } + else if (keylen == 13 && !strncmp(key, "videodatarate", 13)) { + _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, val*1000.0); + } + } + tmp += 8; + break; + case FLV_DATA_TYPE_BOOL: + lprintf(" got bool (%d)\n", *tmp); + tmp++; + break; + case FLV_DATA_TYPE_STRING: + lprintf(" got string (%s)\n", tmp+2); + len = BE_16(tmp); + tmp += len + 2; + break; + case FLV_DATA_TYPE_OBJECT: + while ((len = BE_16(tmp)) && tmp < end) { + lprintf(" got object var (%s)\n", tmp+2); + str = tmp + 2; + tmp += len + 2; + len = parse_flv_var(this, tmp, end-tmp, str, len); + tmp += len; + } + if (*tmp++ != FLV_DATA_TYPE_ENDOBJECT) + return 0; + break; + case FLV_DATA_TYPE_ECMARRAY: + lprintf(" got EMCA array (%d indices)\n", BE_32(tmp)); + num = BE_32(tmp); + tmp += 4; + while (num-- && tmp < end) { + lprintf(" got array key (%s)\n", tmp+2); + len = BE_16(tmp); + str = tmp + 2; + tmp += len + 2; + len = parse_flv_var(this, tmp, end-tmp, str, len); + tmp += len; + } + break; + case FLV_DATA_TYPE_ARRAY: + lprintf(" got array (%d indices)\n", BE_32(tmp)); + num = BE_32(tmp); + tmp += 4; + if (key && keylen == 5 && !strncmp(key, "times", 5)) { + if (this->index) + free (this->index); + this->index = xine_xmalloc(num*sizeof(flv_index_entry_t)); + this->num_indices = num; + for (num = 0; num < this->num_indices && tmp < end; num++) { + if (*tmp++ == FLV_DATA_TYPE_NUMBER) { + lprintf(" got number (%f)\n", BE_F64(tmp)); + this->index[num].pts = BE_F64(tmp) * 1000.0; + tmp += 8; + } + } + break; + } + if (key && keylen == 13 && !strncmp(key, "filepositions", 13)) { + if (this->index && this->num_indices == num) { + for (num = 0; num < this->num_indices && tmp < end; num++) { + if (*tmp++ == FLV_DATA_TYPE_NUMBER) { + lprintf(" got number (%f)\n", BE_F64(tmp)); + this->index[num].offset = BE_F64(tmp); + tmp += 8; + } + } + break; + } + } + while (num-- && tmp < end) { + len = parse_flv_var(this, tmp, end-tmp, NULL, 0); + tmp += len; + } + break; + case FLV_DATA_TYPE_DATE: + lprintf(" got date (%"PRId64", %d)\n", BE_64(tmp), BE_16(tmp+8)); + tmp += 10; + break; + default: + lprintf(" got type %d\n", type); + break; + } + + return (tmp - buf); +} - lprintf (" sending FLV chunk...\n"); - this->input->seek(this->input, 4, SEEK_CUR); - if (this->input->read(this->input, buffer, 12) != 12) { +static void parse_flv_script(demux_flv_t *this, int size) { + unsigned char *buf = xine_xmalloc(size); + unsigned char *tmp = buf; + unsigned char *end = buf + size; + int len; + + if (this->input->read(this->input, buf, size ) != size) { this->status = DEMUX_FINISHED; - return this->status; + free(buf); + return; } - chunk_type = buffer[0]; - remaining_bytes = BE_32(&buffer[0]); - remaining_bytes &= 0x00FFFFFF; - pts = BE_32(&buffer[3]); - pts &= 0x00FFFFFF; - sub_type = buffer[11]; - - /* Flash timestamps are in milliseconds; multiply by 90 to get xine pts */ - pts *= 90; - - lprintf (" chunk_type = %X, 0x%X -1 bytes, pts %lld, sub-type = %X\n", - chunk_type, remaining_bytes, pts, sub_type); - - /* only handle the chunk right now if chunk type is 9 and lower nibble - * of sub-type is 2 */ - if ((chunk_type != 9) || ((sub_type & 0x0F) != 2)) { - this->input->seek(this->input, remaining_bytes - 1, SEEK_CUR); - } else { - /* send the chunk off to the video demuxer */ - remaining_bytes--; /* sub-type byte does not count */ + while (tmp < end) { + len = parse_flv_var(this, tmp, end-tmp, NULL, 0); + if (len < 1) + break; + tmp += len; + } + + free(buf); +} + +static int read_flv_packet(demux_flv_t *this) { + fifo_buffer_t *fifo = NULL; + buf_element_t *buf = NULL; + unsigned char buffer[12]; + unsigned char tag_type; + unsigned int remaining_bytes; + unsigned int buf_type = 0; + unsigned int buf_flags = 0; + unsigned int pts; + + while (1) { + lprintf (" reading FLV tag...\n"); + this->input->seek(this->input, 4, SEEK_CUR); + if (this->input->read(this->input, buffer, 11) != 11) { + this->status = DEMUX_FINISHED; + return this->status; + } + + tag_type = buffer[0]; + remaining_bytes = BE_24(&buffer[1]); + pts = BE_24(&buffer[4]) | (buffer[7] << 24); + + lprintf(" tag_type = 0x%02X, 0x%X bytes, pts %u\n", + tag_type, remaining_bytes, pts/90); + + switch (tag_type) { + case FLV_TAG_TYPE_AUDIO: + lprintf(" got audio tag..\n"); + if (this->input->read(this->input, buffer, 1) != 1) { + this->status = DEMUX_FINISHED; + return this->status; + } + remaining_bytes--; + + switch (buffer[0] >> 4) { + case FLV_SOUND_FORMAT_PCM_BE: + buf_type = BUF_AUDIO_LPCM_BE; + break; + case FLV_SOUND_FORMAT_ADPCM: + buf_type = BUF_AUDIO_FLVADPCM; + break; + case FLV_SOUND_FORMAT_MP3: + buf_type = BUF_AUDIO_MPEG; + break; + case FLV_SOUND_FORMAT_PCM_LE: + buf_type = BUF_AUDIO_LPCM_LE; + break; + default: + lprintf(" unsupported audio format (%d)...\n", buffer[0] >> 4); + buf_type = BUF_AUDIO_UNKNOWN; + break; + } + + fifo = this->audio_fifo; + if (!this->got_audio) { + /* send init info to audio decoder */ + buf = fifo->buffer_pool_alloc(fifo); + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + buf->decoder_info[0] = 0; + buf->decoder_info[1] = 44100 >> (3 - ((buffer[0] >> 2) & 3)); /* samplerate */ + buf->decoder_info[2] = (buffer[0] & 2) ? 16 : 8; /* bits per sample */ + buf->decoder_info[3] = (buffer[0] & 1) + 1; /* channels */ + buf->size = 0; /* no extra data */ + buf->type = buf_type; + + fifo->put(fifo, buf); + + this->got_audio = 1; + } + break; + + case FLV_TAG_TYPE_VIDEO: + lprintf(" got video tag..\n"); + if (this->input->read(this->input, buffer, 1) != 1) { + this->status = DEMUX_FINISHED; + return this->status; + } + remaining_bytes--; + + if ((buffer[0] >> 4) == 0x01) + buf_flags = BUF_FLAG_KEYFRAME; + + switch (buffer[0] & 0x0F) { + case FLV_VIDEO_FORMAT_FLV1: + buf_type = BUF_VIDEO_FLV1; + break; + case FLV_VIDEO_FORMAT_VP6: + buf_type = BUF_VIDEO_VP6F; + /* VP6 extra header */ + this->input->read(this->input, buffer, 1 ); + remaining_bytes--; + break; + case FLV_VIDEO_FORMAT_VP6A: + buf_type = BUF_VIDEO_VP6F; + /* VP6A extra header */ + this->input->read(this->input, buffer, 4); + remaining_bytes -= 4; + break; + default: + lprintf(" unsupported video format (%d)...\n", buffer[0] & 0x0F); + buf_type = BUF_VIDEO_UNKNOWN; + break; + } + + fifo = this->video_fifo; + if (!this->got_video) { + xine_bmiheader *bih; + /* send init info to video decoder; send the bitmapinfo header to the decoder + * primarily as a formality since there is no real data inside */ + buf = fifo->buffer_pool_alloc(fifo); + buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | + BUF_FLAG_FRAMERATE | BUF_FLAG_FRAME_END; + buf->decoder_info[0] = this->framerate ? (90000.0/this->framerate) : 0; + bih = (xine_bmiheader *) buf->content; + memset(bih, 0, sizeof(xine_bmiheader)); + bih->biSize = sizeof(xine_bmiheader); + bih->biWidth = this->width; + bih->biHeight = this->height; + buf->size = sizeof(xine_bmiheader); + buf->type = buf_type; + if (buf_type == BUF_VIDEO_VP6F) { + *((unsigned char *)buf->content+buf->size) = buffer[0]; + bih->biSize++; + buf->size++; + } + + fifo->put(fifo, buf); + + this->got_video = 1; + } + break; + + case FLV_TAG_TYPE_SCRIPT: + lprintf(" got script tag...\n"); + parse_flv_script(this, remaining_bytes); + continue; + + default: + lprintf(" skipping packet...\n"); + this->input->seek(this->input, remaining_bytes, SEEK_CUR); + continue; + } + while (remaining_bytes) { - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->type = BUF_VIDEO_FLV1; - if( this->input->get_length (this->input) ) - buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * - 65535 / this->input->get_length (this->input) ); + buf = fifo->buffer_pool_alloc(fifo); + buf->type = buf_type; + buf->pts = (int64_t) pts * 90; + check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO)); + + buf->extra_info->input_time = pts; + if (this->input->get_length(this->input)) { + buf->extra_info->input_normpos = + (int)((double)this->input->get_current_pos(this->input) * 65535.0 / this->size); + } if (remaining_bytes > buf->max_size) buf->size = buf->max_size; @@ -155,28 +501,120 @@ static int demux_flv_send_chunk(demux_plugin_t *this_gen) { buf->size = remaining_bytes; remaining_bytes -= buf->size; + buf->decoder_flags = buf_flags; if (!remaining_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; - if (this->input->read(this->input, buf->content, buf->size) != - buf->size) { + if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } - buf->pts = pts; - buf->extra_info->input_time = buf->pts / 90; - this->video_fifo->put(this->video_fifo, buf); + fifo->put(fifo, buf); } + + this->cur_pts = pts; + break; } - + return this->status; } +static void seek_flv_file(demux_flv_t *this, int seek_pts) { + unsigned char buffer[16]; + unsigned int pts = this->cur_pts; + int len = 0; + int next_tag = 0; + int do_rewind = (seek_pts < this->cur_pts); + + lprintf(" seeking %s to %d...\n", + do_rewind ? "backward" : "forward", seek_pts); + + if (seek_pts == 0) { + this->input->seek(this->input, this->start, SEEK_SET); + this->cur_pts = 0; + return; + } + + if (this->index) { + int i; + + if (do_rewind) { + for (i = this->num_indices-1; i > 0; i--) { + if (this->index[i-1].pts < seek_pts) + break; + } + } + else { + for (i = 0; i < (this->num_indices-1); i++) { + if (this->index[i+1].pts > seek_pts) + break; + } + } + + if (this->index[i].offset >= this->start+4) { + lprintf(" seeking to index entry %d (pts:%u, offset:%u).\n", + i, this->index[i].pts, this->index[i].offset); + + this->input->seek(this->input, this->index[i].offset-4, SEEK_SET); + this->cur_pts = this->index[i].pts; + return; + } + } + + while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) { + unsigned char tag_type; + int data_size; + int ptag_size; + + if (next_tag) + this->input->seek(this->input, next_tag, SEEK_CUR); + + len = this->input->read(this->input, buffer, 16); + if (len != 16) { + len = (len < 0) ? 0 : len; + break; + } + + ptag_size = BE_32(&buffer[0]); + tag_type = buffer[4]; + data_size = BE_24(&buffer[5]); + pts = BE_24(&buffer[8]) | (buffer[11] << 24); + + if (do_rewind) { + if (!ptag_size) break; /* beginning of movie */ + next_tag = -(ptag_size + 16 + 4); + } + else { + next_tag = data_size - 1; + } + + if (this->flags & FLV_FLAG_HAS_VIDEO) { + /* sync to video key frame */ + if (tag_type != FLV_TAG_TYPE_VIDEO || (buffer[15] >> 4) != 0x01) + continue; + lprintf(" video keyframe found at %d...\n", pts); + } + this->cur_pts = pts; + } + + /* seek back to the beginning of the tag */ + this->input->seek(this->input, -len, SEEK_CUR); + + lprintf( " seeked to %d.\n", pts); +} + + +static int demux_flv_send_chunk(demux_plugin_t *this_gen) { + demux_flv_t *this = (demux_flv_t *) this_gen; + + return read_flv_packet(this); +} + static void demux_flv_send_headers(demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; - buf_element_t *buf; + int i; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; @@ -185,24 +623,23 @@ static void demux_flv_send_headers(demux_plugin_t *this_gen) { /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, - (this->video_type ? 1 : 0)); + (this->flags & FLV_FLAG_HAS_VIDEO) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, - (this->audio_type ? 1 : 0)); + (this->flags & FLV_FLAG_HAS_AUDIO) ? 1 : 0); /* send start buffers */ _x_demux_control_start(this->stream); - /* send init info to decoders; send the bitmapinfo header to the decoder - * primarily as a formality since there is no real data inside */ - buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); - buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| - BUF_FLAG_FRAME_END; - buf->decoder_info[0] = 7470; /* initial duration */ - memcpy(buf->content, this->bih, sizeof(xine_bmiheader)); - buf->size = sizeof(xine_bmiheader); - buf->type = BUF_VIDEO_FLV1; - this->video_fifo->put (this->video_fifo, buf); - + /* find first audio/video packets and send headers */ + for (i = 0; i < 20; i++) { + if (read_flv_packet(this) != DEMUX_OK) + break; + if (((this->flags & FLV_FLAG_HAS_VIDEO) && this->got_video) && + ((this->flags & FLV_FLAG_HAS_AUDIO) && this->got_audio)) { + lprintf(" headers sent...\n"); + break; + } + } } static int demux_flv_seek (demux_plugin_t *this_gen, @@ -210,10 +647,21 @@ static int demux_flv_seek (demux_plugin_t *this_gen, demux_flv_t *this = (demux_flv_t *) this_gen; - /* if thread is not running, initialize demuxer */ - if( !playing ) { - this->status = DEMUX_OK; - } + this->status = DEMUX_OK; + + if (INPUT_IS_SEEKABLE(this->input)) { + if (start_pos && !start_time) + start_time = (int64_t) this->length * start_pos / 65535; + + if (!this->length || start_time < this->length) { + seek_flv_file(this, start_time); + + if (playing) { + this->buf_flag_seek = 1; + _x_demux_flush_engine(this->stream); + } + } + } return this->status; } @@ -221,6 +669,8 @@ static int demux_flv_seek (demux_plugin_t *this_gen, static void demux_flv_dispose (demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; + if (this->index) + free(this->index); free(this); } @@ -231,9 +681,9 @@ static int demux_flv_get_status (demux_plugin_t *this_gen) { } static int demux_flv_get_stream_length (demux_plugin_t *this_gen) { -/* demux_flv_t *this = (demux_flv_t *) this_gen;*/ + demux_flv_t *this = (demux_flv_t *) this_gen; - return 0; + return this->length; } static uint32_t demux_flv_get_capabilities(demux_plugin_t *this_gen) { @@ -247,10 +697,10 @@ static int demux_flv_get_optional_data(demux_plugin_t *this_gen, static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { + demux_flv_t *this; - demux_flv_t *this; - - this = xine_xmalloc (sizeof (demux_flv_t)); + this = xine_xmalloc(sizeof (demux_flv_t)); + this->xine = stream->xine; this->stream = stream; this->input = input; @@ -267,52 +717,43 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { + case METHOD_BY_EXTENSION: + if (!_x_demux_check_extension(input->get_mrl(input), "flv")) { + free (this); + return NULL; + } + + /* falling through is intended */ + case METHOD_BY_CONTENT: + case METHOD_EXPLICIT: + if (!open_flv_file(this)) { + free (this); + return NULL; + } + break; - case METHOD_BY_EXTENSION: { - char *extensions, *mrl; - - mrl = input->get_mrl (input); - extensions = class_gen->get_extensions (class_gen); - - if (!_x_demux_check_extension (mrl, extensions)) { - free (this); - return NULL; - } - } - /* falling through is intended */ - - case METHOD_BY_CONTENT: - case METHOD_EXPLICIT: - - if (!open_flv_file(this)) { + default: free (this); return NULL; - } - - break; - - default: - free (this); - return NULL; } return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Flash Video file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "FLV"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "flv"; } -static char *get_mimetypes (demux_class_t *this_gen) { - return NULL; +static const char *get_mimetypes (demux_class_t *this_gen) { + return "video/x-flv: flv: Flash video;"; } static void class_dispose (demux_class_t *this_gen) { diff --git a/src/demuxers/demux_idcin.c b/src/demuxers/demux_idcin.c index a778d4c6f..461771425 100644 --- a/src/demuxers/demux_idcin.c +++ b/src/demuxers/demux_idcin.c @@ -65,7 +65,7 @@ * - if any bytes exceed 63, do not shift the bytes at all before * transmitting them to the video decoder * - * $Id: demux_idcin.c,v 1.53 2005/11/21 10:28:18 valtri Exp $ + * $Id: demux_idcin.c,v 1.55 2007/02/20 00:34:55 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -222,7 +222,7 @@ static int demux_idcin_send_chunk(demux_plugin_t *this_gen) { if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; - lprintf("sending video buf with %d bytes, %lld pts\n", buf->size, buf->pts); + lprintf("sending video buf with %d bytes, %"PRId64" pts\n", buf->size, buf->pts); this->video_fifo->put(this->video_fifo, buf); } @@ -263,7 +263,7 @@ static int demux_idcin_send_chunk(demux_plugin_t *this_gen) { if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; - lprintf("sending audio buf with %d bytes, %lld pts\n", buf->size, buf->pts); + lprintf("sending audio buf with %d bytes, %"PRId64" pts\n", buf->size, buf->pts); this->audio_fifo->put(this->audio_fifo, buf); } } @@ -493,7 +493,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -524,19 +524,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Id Quake II Cinematic file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Id CIN"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "cin"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c index 213ac4c99..cc4df0c85 100644 --- a/src/demuxers/demux_iff.c +++ b/src/demuxers/demux_iff.c @@ -36,7 +36,7 @@ * * ANIM (Animations) * - Animation works fine, without seeking. * - * $Id: demux_iff.c,v 1.17 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_iff.c,v 1.19 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -827,7 +827,8 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) { } } else { for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) { - zw_16 = BE_16(&pointer16_from[k++]); + zw_16 = BE_16(&pointer16_from[k]); + k++; zw_rescale = zw_16; zw_rescale *= this->audio_volume_left; zw_rescale /= max_volume; @@ -856,7 +857,8 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) { } } else { for (j = 1; j < (buf->size / 2); j += this->audio_channels) { - zw_16 = BE_16(&pointer16_from[k++]); + zw_16 = BE_16(&pointer16_from[k]); + k++; zw_rescale = zw_16; zw_rescale *= this->audio_volume_left; zw_rescale /= max_volume; @@ -1253,7 +1255,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -1283,19 +1285,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "IFF demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "IFF"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "iff svx 8svx 16sv ilbm ham ham6 ham8 anim anim3 anim5 anim7 anim8"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/x-8svx: 8svx: IFF-8SVX Audio;" "audio/8svx: 8svx: IFF-8SVX Audio;" "audio/x-16sv: 16sv: IFF-16SV Audio;" diff --git a/src/demuxers/demux_image.c b/src/demuxers/demux_image.c index 727d80a29..d799c2324 100644 --- a/src/demuxers/demux_image.c +++ b/src/demuxers/demux_image.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_image.c,v 1.25 2006/08/13 23:51:33 miguelfreitas Exp $ + * $Id: demux_image.c,v 1.26 2007/01/19 00:26:40 dgp85 Exp $ * * image dummy demultiplexer */ @@ -177,7 +177,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -225,19 +225,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, * image demuxer class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "image demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "imagedmx"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "png gif jpg jpeg"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c index 20c1c3118..6fe185b1a 100644 --- a/src/demuxers/demux_ipmovie.c +++ b/src/demuxers/demux_ipmovie.c @@ -23,7 +23,7 @@ * For more information regarding the Interplay MVE file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_ipmovie.c,v 1.25 2004/06/13 21:28:53 miguelfreitas Exp $ + * $Id: demux_ipmovie.c,v 1.27 2007/02/20 00:34:55 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -326,7 +326,7 @@ static int process_ipmovie_chunk(demux_ipmovie_t *this) { audio_pts *= this->audio_frame_count; audio_pts /= this->wave.nSamplesPerSec; - lprintf("sending audio frame with pts %lld (%d audio frames)\n", + lprintf("sending audio frame with pts %"PRId64" (%d audio frames)\n", audio_pts, this->audio_frame_count); if(this->audio_fifo) { @@ -432,7 +432,7 @@ static int process_ipmovie_chunk(demux_ipmovie_t *this) { lprintf("set video data\n"); current_file_pos = this->input->get_current_pos(this->input); - lprintf("sending video data with pts %lld\n", + lprintf("sending video data with pts %"PRId64"\n", this->video_pts); /* send off any new palette data */ @@ -693,7 +693,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -723,19 +723,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Interplay MVE Movie demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Interplay MVE"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mve mv8"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index bcc5f52ea..2bd8f3540 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2005 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_matroska.c,v 1.49 2006/11/14 14:17:31 dgp85 Exp $ + * $Id: demux_matroska.c,v 1.53 2007/03/12 16:27:21 dgp85 Exp $ * * demultiplexer for matroska streams * @@ -362,6 +362,140 @@ static int parse_audio_track (demux_matroska_t *this, matroska_audio_track_t *at } +static int parse_content_compression (demux_matroska_t *this, matroska_track_t *track) { + ebml_parser_t *ebml = this->ebml; + int next_level = 6; + + while (next_level == 6) { + ebml_elem_t elem; + uint64_t val; + + if (!ebml_read_elem_head(ebml, &elem)) + return 0; + + switch (elem.id) { + case MATROSKA_ID_CE_COMPALGO: + lprintf("ContentCompAlgo\n"); + if (!ebml_read_uint(ebml, &elem, &val)) + return 0; + switch (val) + { + case MATROSKA_COMPRESS_ZLIB: + case MATROSKA_COMPRESS_BZLIB: + case MATROSKA_COMPRESS_LZO1X: + case MATROSKA_COMPRESS_HEADER_STRIP: + track->compress_algo = val; + break; + default: + track->compress_algo = MATROSKA_COMPRESS_UNKNOWN; + break; + } + break; + case MATROSKA_ID_CE_COMPSETTINGS: + lprintf("ContentCompSettings (UNSUPPORTED)\n"); + if (!ebml_skip(ebml, &elem)) + return 0; + break; + default: + lprintf("Unhandled ID: 0x%x\n", elem.id); + if (!ebml_skip(ebml, &elem)) + return 0; + } + next_level = ebml_get_next_level(ebml, &elem); + } + return 1; +} + + +static int parse_content_encoding (demux_matroska_t *this, matroska_track_t *track) { + ebml_parser_t *ebml = this->ebml; + int next_level = 5; + + while (next_level == 5) { + ebml_elem_t elem; + uint64_t val; + + if (!ebml_read_elem_head(ebml, &elem)) + return 0; + + switch (elem.id) { + case MATROSKA_ID_CE_ORDER: + lprintf("ContentEncodingOrder\n"); + if (!ebml_read_uint(ebml, &elem, &val)) + return 0; + if (val != 0) { // multiple content encoding isn't supported + lprintf(" warning: a non-zero encoding order is UNSUPPORTED\n"); + return 0; + } + break; + case MATROSKA_ID_CE_SCOPE: + lprintf("ContentEncodingScope\n"); + if (!ebml_read_uint(ebml, &elem, &val)) + return 0; + if (val != 1) { // 1 (all frame contents) is the only supported option + lprintf(" warning: UNSUPPORTED encoding scope (%" PRId64 ")\n", val); + return 0; + } + break; + case MATROSKA_ID_CE_TYPE: + lprintf("ContentEncodingType\n"); + if (!ebml_read_uint(ebml, &elem, &val)) + return 0; + if (val != 0) // only compression (0) is supported + return 0; + break; + case MATROSKA_ID_CE_COMPRESSION: + lprintf("ContentCompression\n"); + if (!ebml_read_master (ebml, &elem)) + return 0; + if ((elem.len > 0) && !parse_content_compression(this, track)) + return 0; + break; + case MATROSKA_ID_CE_ENCRYPTION: + lprintf("ContentEncryption (UNSUPPORTED)\n"); + if (!ebml_skip(ebml, &elem)) + return 0; + break; + default: + lprintf("Unhandled ID: 0x%x\n", elem.id); + if (!ebml_skip(ebml, &elem)) + return 0; + } + next_level = ebml_get_next_level(ebml, &elem); + } + return 1; +} + + +static int parse_content_encodings (demux_matroska_t *this, matroska_track_t *track) { + ebml_parser_t *ebml = this->ebml; + int next_level = 4; + + while (next_level == 4) { + ebml_elem_t elem; + + if (!ebml_read_elem_head(ebml, &elem)) + return 0; + + switch (elem.id) { + case MATROSKA_ID_CONTENTENCODING: + lprintf("ContentEncoding\n"); + if (!ebml_read_master (ebml, &elem)) + return 0; + if ((elem.len > 0) && !parse_content_encoding(this, track)) + return 0; + break; + default: + lprintf("Unhandled ID: 0x%x\n", elem.id); + if (!ebml_skip(ebml, &elem)) + return 0; + } + next_level = ebml_get_next_level(ebml, &elem); + } + return 1; +} + + static void init_codec_video(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; @@ -937,45 +1071,67 @@ static void handle_vobsub (demux_plugin_t *this_gen, matroska_track_t *track, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; buf_element_t *buf; - z_stream zstream; - uint8_t *dest; - int old_data_len, result; - - old_data_len = data_len; - zstream.zalloc = (alloc_func) 0; - zstream.zfree = (free_func) 0; - zstream.opaque = (voidpf) 0; - if (inflateInit (&zstream) != Z_OK) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_matroska: VobSub: zlib inflateInit failed.\n"); - return; - } - zstream.next_in = (Bytef *)data; - zstream.avail_in = data_len; - dest = (uint8_t *)malloc(data_len); - zstream.avail_out = data_len; - do { - data_len += 4000; - dest = (uint8_t *)realloc(dest, data_len); - zstream.next_out = (Bytef *)(dest + zstream.total_out); - result = inflate (&zstream, Z_NO_FLUSH); - if ((result != Z_OK) && (result != Z_STREAM_END)) { + if (track->compress_algo == MATROSKA_COMPRESS_ZLIB || + track->compress_algo == MATROSKA_COMPRESS_UNKNOWN) { + z_stream zstream; + uint8_t *dest; + int old_data_len, result; + + old_data_len = data_len; + zstream.zalloc = (alloc_func) 0; + zstream.zfree = (free_func) 0; + zstream.opaque = (voidpf) 0; + if (inflateInit (&zstream) != Z_OK) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_matroska: VobSub: zlib decompression failed.\n"); - free(dest); - inflateEnd(&zstream); + "demux_matroska: VobSub: zlib inflateInit failed.\n"); return; } - zstream.avail_out += 4000; - } while ((zstream.avail_out == 4000) && - (zstream.avail_in != 0) && (result != Z_STREAM_END)); - - data_len = zstream.total_out; - inflateEnd(&zstream); - - lprintf("VobSub: decompression for track %d from %d to %d\n", - (int)track->track_num, old_data_len, data_len); + zstream.next_in = (Bytef *)data; + zstream.avail_in = data_len; + + dest = (uint8_t *)malloc(data_len); + zstream.avail_out = data_len; + do { + data_len += 4000; + dest = (uint8_t *)realloc(dest, data_len); + zstream.next_out = (Bytef *)(dest + zstream.total_out); + result = inflate (&zstream, Z_NO_FLUSH); + if ((result != Z_OK) && (result != Z_STREAM_END)) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "demux_matroska: VobSub: zlib decompression failed for track %d (result = %d).\n", + (int)track->track_num, result); + free(dest); + inflateEnd(&zstream); + + if (result == Z_DATA_ERROR && track->compress_algo == MATROSKA_COMPRESS_UNKNOWN) { + track->compress_algo = MATROSKA_COMPRESS_NONE; + data_len = old_data_len; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "demux_matroska: VobSub: falling back to uncompressed mode.\n"); + break; + } + return; + } + zstream.avail_out += 4000; + } while ((zstream.avail_out == 4000) && + (zstream.avail_in != 0) && (result != Z_STREAM_END)); + + if (track->compress_algo != MATROSKA_COMPRESS_NONE) { + data_len = zstream.total_out; + inflateEnd(&zstream); + + data = dest; + track->compress_algo = MATROSKA_COMPRESS_ZLIB; + lprintf("VobSub: decompression for track %d from %d to %d\n", + (int)track->track_num, old_data_len, data_len); + } + } + else + { + lprintf("VobSub: track %d isn't compressed (%d bytes)\n", + (int)track->track_num, data_len); + } buf = track->fifo->buffer_pool_alloc(track->fifo); @@ -986,8 +1142,8 @@ static void handle_vobsub (demux_plugin_t *this_gen, matroska_track_t *track, buf->decoder_info[2] = SPU_DVD_SUBTYPE_VOBSUB_PACKAGE; buf->type = track->buf_type; - xine_fast_memcpy(buf->content, dest, data_len); - + xine_fast_memcpy(buf->content, data, data_len); + buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; @@ -1000,7 +1156,8 @@ static void handle_vobsub (demux_plugin_t *this_gen, matroska_track_t *track, buf->free_buffer(buf); } - free(dest); + if (track->compress_algo == MATROSKA_COMPRESS_ZLIB) + free(data); } static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { @@ -1100,7 +1257,16 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { if (!ebml_read_uint(ebml, &elem, &val)) return 0; track->default_duration = val; - lprintf("Default Duration: %lld\n", track->default_duration); + lprintf("Default Duration: %"PRIu64"\n", track->default_duration); + } + break; + + case MATROSKA_ID_CONTENTENCODINGS: { + lprintf("ContentEncodings\n"); + if (!ebml_read_master (ebml, &elem)) + return 0; + if ((elem.len > 0) && !parse_content_encodings(this, track)) + return 0; } break; @@ -1230,6 +1396,10 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_DTS)) { + lprintf("MATROSKA_CODEC_ID_A_DTS\n"); + track->buf_type = BUF_AUDIO_DTS; + init_codec = init_codec_audio; + } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_VORBIS)) { lprintf("MATROSKA_CODEC_ID_A_VORBIS\n"); @@ -1289,6 +1459,14 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { track->buf_type = BUF_SPU_DVD; track->handle_content = handle_vobsub; init_codec = init_codec_vobsub; + + /* Enable autodetection of the zlib compression, unless it was + * explicitely set. Most vobsubs are compressed with zlib but + * are not declared as such. + */ + if (track->compress_algo == MATROSKA_COMPRESS_NONE) { + track->compress_algo = MATROSKA_COMPRESS_UNKNOWN; + } } else { lprintf("unknown codec\n"); } @@ -1339,12 +1517,17 @@ static int parse_tracks(demux_matroska_t *this) { switch (elem.id) { case MATROSKA_ID_TR_ENTRY: { + matroska_track_t *track; + /* alloc and initialize a track with 0 */ - this->tracks[this->num_tracks] = xine_xmalloc(sizeof(matroska_track_t)); + track = xine_xmalloc(sizeof(matroska_track_t)); + track->compress_algo = MATROSKA_COMPRESS_NONE; + this->tracks[this->num_tracks] = track; + lprintf("TrackEntry\n"); if (!ebml_read_master (ebml, &elem)) return 0; - if ((elem.len > 0) && !parse_track_entry(this, this->tracks[this->num_tracks])) + if ((elem.len > 0) && !parse_track_entry(this, track)) return 0; this->num_tracks++; } @@ -2623,13 +2806,11 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *mrl = input->get_mrl(input); - char *extensions; + const char *const mrl = input->get_mrl(input); + const char *const extensions = class_gen->get_extensions (class_gen);; lprintf ("stage by extension %s\n", mrl); - extensions = class_gen->get_extensions (class_gen); - if (!_x_demux_check_extension (mrl, extensions)) return NULL; @@ -2687,22 +2868,22 @@ error: * demux matroska class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "matroska demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "matroska"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mkv"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/mkv: mkv: matroska;"; } diff --git a/src/demuxers/demux_mng.c b/src/demuxers/demux_mng.c index 7f7b5bd84..e2ab1e4ea 100644 --- a/src/demuxers/demux_mng.c +++ b/src/demuxers/demux_mng.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_mng.c,v 1.28 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_mng.c,v 1.29 2007/01/19 00:26:40 dgp85 Exp $ * * demux_mng.c, Demuxer plugin for Multiple-image Network Graphics format * @@ -288,7 +288,7 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl(input); extensions = class_gen->get_extensions (class_gen); @@ -336,19 +336,19 @@ static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stre return &this->demux_plugin; } -static char *get_description(demux_class_t *this_gen){ +static const char *get_description(demux_class_t *this_gen){ return "Multiple-image Network Graphics demux plugin"; } -static char *get_identifier(demux_class_t *this_gen){ +static const char *get_identifier(demux_class_t *this_gen){ return "MNG"; } -static char *get_extensions(demux_class_t *this_gen){ +static const char *get_extensions(demux_class_t *this_gen){ return "png mng"; } -static char *get_mimetypes(demux_class_t *this_gen){ +static const char *get_mimetypes(demux_class_t *this_gen){ return "image/png: png: PNG image;" "image/x-png: png: PNG image;" "video/mng: mng: MNG animation;" diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c index 185ef5c97..37e066b13 100644 --- a/src/demuxers/demux_mod.c +++ b/src/demuxers/demux_mod.c @@ -50,6 +50,7 @@ #include "demux.h" #include "group_audio.h" #include "modplug.h" +#include "bswap.h" #define MOD_SAMPLERATE 44100 #define MOD_BITS 16 @@ -89,6 +90,43 @@ typedef struct { demux_class_t demux_class; } demux_mod_class_t; +#define FOURCC_32(a, b, c, d) (d + (c<<8) + (b<<16) + (a<<24)) + +/** + * @brief Probes if the given file can be demuxed using modplug or not + * @retval 0 The file is not a valid modplug file (or the probe isn't complete yet) + * @retval 1 The file has been identified as a valid modplug file + * @todo Just Protracker files are detected right now. + */ +static int probe_mod_file(demux_mod_t *this) { + /* We need the value present at offset 1080, of size 4 */ + union { + uint8_t buffer[1080+4]; /* The raw buffer */ + uint32_t values[(1080+4)/sizeof(uint32_t)]; + } header; + + if (_x_demux_read_header(this->input, header.buffer, 1080+4) != 1080+4) + return 0; + + /* Magic numbers taken from GNU file's magic description */ + switch( ABE_32(header.values + (1080/sizeof(uint32_t))) ) { + case FOURCC_32('M', '.', 'K', '.'): /* 4-channel Protracker module sound data */ + case FOURCC_32('M', '!', 'K', '!'): /* 4-channel Protracker module sound data */ + case FOURCC_32('F', 'L', 'T', '4'): /* 4-channel Startracker module sound data */ + case FOURCC_32('F', 'L', 'T', '8'): /* 8-channel Startracker module sound data */ + case FOURCC_32('4', 'C', 'H', 'N'): /* 4-channel Fasttracker module sound data */ + case FOURCC_32('6', 'C', 'H', 'N'): /* 6-channel Fasttracker module sound data */ + case FOURCC_32('8', 'C', 'H', 'N'): /* 8-channel Fasttracker module sound data */ + case FOURCC_32('C', 'D', '8', '1'): /* 8-channel Octalyser module sound data */ + case FOURCC_32('O', 'K', 'T', 'A'): /* 8-channel Oktalyzer module sound data */ + case FOURCC_32('1', '6', 'C', 'N'): /* 16-channel Taketracker module sound data */ + case FOURCC_32('3', '2', 'C', 'N'): /* 32-channel Taketracker module sound data */ + return 1; + } + + return 0; +} + /* returns 1 if the MOD file was opened successfully, 0 otherwise */ static int open_mod_file(demux_mod_t *this) { int total_read; @@ -289,7 +327,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str case METHOD_EXPLICIT: case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -306,6 +344,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_CONTENT: + if (probe_mod_file(this) && open_mod_file(this)) + break; + default: free (this); return NULL; @@ -314,19 +355,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "ModPlug Amiga MOD Music file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "mod"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mod it stm s3m 669 amf med mdl xm"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_mpc.c b/src/demuxers/demux_mpc.c index ab2ef511d..e1a3f28b9 100644 --- a/src/demuxers/demux_mpc.c +++ b/src/demuxers/demux_mpc.c @@ -24,7 +24,7 @@ * APE tag reading * Seeking?? * - * $Id: demux_mpc.c,v 1.3 2005/03/06 11:41:00 jstembridge Exp $ + * $Id: demux_mpc.c,v 1.5 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -119,11 +119,11 @@ static int open_mpc_file(demux_mpc_t *this) { } } - /* Validate signature - We only support SV7 at the moment */ + /* Validate signature - We only support SV 7.x at the moment */ if ((this->header[0] != 'M') || (this->header[1] != 'P') || (this->header[2] != '+') || - (this->header[3] != 0x07)) + ((this->header[3]&0x0f) != 0x07)) return 0; /* Get frame count */ @@ -344,7 +344,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -374,19 +374,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Musepack demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Musepack"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mpc mp+"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c index 61d7cc3ca..c9d49efa2 100644 --- a/src/demuxers/demux_mpeg.c +++ b/src/demuxers/demux_mpeg.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_mpeg.c,v 1.150 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_mpeg.c,v 1.152 2007/02/20 00:34:55 dgp85 Exp $ * * demultiplexer for mpeg 1/2 program streams * reads streams of variable blocksizes @@ -310,7 +310,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU SVCD PACK (pts: %lld, spu id: %d) put on FIFO\n", + lprintf ("SPU SVCD PACK (pts: %"PRId64", spu id: %d) put on FIFO\n", buf->pts, spu_id); return; @@ -1199,7 +1199,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str } case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -1222,19 +1222,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "MPEG program stream demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEG"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mpg mpeg"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/mpeg: mpeg, mpg, mpe: MPEG animation;" "video/x-mpeg: mpeg, mpg, mpe: MPEG animation;"; } diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c index ef17ac948..7083d33d9 100644 --- a/src/demuxers/demux_mpeg_block.c +++ b/src/demuxers/demux_mpeg_block.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg_block.c,v 1.217 2006/10/16 22:18:24 valtri Exp $ + * $Id: demux_mpeg_block.c,v 1.220 2007/02/20 00:34:55 dgp85 Exp $ * * demultiplexer for mpeg 1/2 program streams * used with fixed blocksize devices (like dvd/vcd) @@ -458,7 +458,7 @@ static int32_t parse_program_stream_pack_header(demux_mpeg_block_t *this, uint8_ this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) ); */ - lprintf ("SCR=%lld\n", this->scr); + lprintf ("SCR=%"PRId64"\n", this->scr); /* mux_rate */ @@ -525,7 +525,7 @@ static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_ this->last_begin_time = buf->extra_info->input_time; } - lprintf ("NAV packet, start pts = %lld, end_pts = %lld\n", + lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n", start_pts, end_pts); if (this->nav_last_end_pts != start_pts && !this->preview_mode) { @@ -664,7 +664,7 @@ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_eleme this->pts |= p[12] << 7 ; this->pts |= (p[13] & 0xFE) >> 1 ; - lprintf ("pts = %lld\n", this->pts); + lprintf ("pts = %"PRId64"\n", this->pts); } else this->pts = 0; @@ -731,7 +731,7 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU SVCD PACK (%lld, %d) put on fifo\n", this->pts, spu_id); + lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return -1; } @@ -749,7 +749,7 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU CVD PACK (%lld, %d) put on fifo\n", this->pts, spu_id); + lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return -1; } @@ -1146,7 +1146,7 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) { count ++; /* - printf ("demux_mpeg_block: stream_id %02x, pos: %lld, pts: %d, cur_rate = %d, overall rate : %d\n", + printf ("demux_mpeg_block: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n", stream_id, pos, pts, cur_rate, rate); */ } @@ -1456,9 +1456,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *ending, *mrl; + char *ending; - mrl = input->get_mrl (input); + const char *const mrl = input->get_mrl (input); if(!strncmp(mrl, "vcd:", 4)) { this->blocksize = 2324; @@ -1516,19 +1516,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "DVD/VOB demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEG_BLOCK"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "vob"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index cb9732e53..c5769e3e3 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpeg_pes.c,v 1.37 2006/10/16 22:18:24 valtri Exp $ + * $Id: demux_mpeg_pes.c,v 1.43 2007/03/29 17:11:36 dgp85 Exp $ * * demultiplexer for mpeg 2 PES (Packetized Elementary Streams) * reads streams of variable blocksizes @@ -81,20 +81,23 @@ typedef struct demux_mpeg_pes_s { int64_t nav_last_end_pts; int64_t nav_last_start_pts; int64_t last_pts[2]; - int send_newpts; - int preview_mode; - int buf_flag_seek; int64_t scr; uint32_t packet_len; + uint32_t stream_id; + int64_t pts; int64_t dts; - uint32_t stream_id; - int32_t mpeg1; - int32_t wait_for_program_stream_pack_header; + uint8_t send_newpts:1; + uint8_t buf_flag_seek:1; + uint8_t preview_mode:1; + uint8_t mpeg1:1; + uint8_t wait_for_program_stream_pack_header:1; + uint8_t mpeg12_h264_detected:2; + + int last_begin_time; int64_t last_cell_time; off_t last_cell_pos; - int last_begin_time; uint8_t preview_data[ MAX_PREVIEW_SIZE ]; off_t preview_size, preview_done; @@ -417,6 +420,9 @@ static int32_t parse_padding_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_elem done += i; } + /* trigger detection of MPEG 1/2 respectively H.264 content */ + this->mpeg12_h264_detected = 0; + buf->free_buffer(buf); return this->packet_len + 6; } @@ -572,7 +578,7 @@ static int32_t parse_program_stream_pack_header(demux_mpeg_pes_t *this, uint8_t this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) ); */ - lprintf ("SCR=%lld\n", this->scr); + lprintf ("SCR=%"PRId64"\n", this->scr); /* mux_rate */ @@ -649,7 +655,7 @@ static int32_t parse_private_stream_2(demux_mpeg_pes_t *this, uint8_t *p, buf_el this->last_begin_time = buf->extra_info->input_time; } - lprintf ("NAV packet, start pts = %lld, end_pts = %lld\n", + lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n", start_pts, end_pts); if (this->nav_last_end_pts != start_pts && !this->preview_mode) { @@ -795,7 +801,7 @@ static int32_t parse_pes_for_pts(demux_mpeg_pes_t *this, uint8_t *p, buf_element this->pts |= (int64_t) p[12] << 7 ; this->pts |= (int64_t) (p[13] & 0xFE) >> 1 ; - lprintf ("pts = %lld\n", this->pts); + lprintf ("pts = %"PRId64"\n", this->pts); } else this->pts = 0; @@ -862,7 +868,7 @@ static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_el check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU SVCD PACK (%lld, %d) put on fifo\n", this->pts, spu_id); + lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return this->packet_len + result; } @@ -880,7 +886,7 @@ static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_el check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU CVD PACK (%lld, %d) put on fifo\n", this->pts, spu_id); + lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return this->packet_len + result; } @@ -1062,21 +1068,102 @@ static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_elemen uint32_t todo_length=0; uint32_t i; uint32_t chunk_length; + int buf_type = BUF_VIDEO_MPEG; + int payload_size; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; - buf->content = p; + buf->content = p; + payload_size = buf->max_size - result; + if (payload_size > this->packet_len) + payload_size = this->packet_len; + + /* H.264 broadcasts via DVB-S use standard video PES packets, + so there is no way other than scanning the video data to + detect whether BUF_VIDEO_H264 needs to be used. + For performance reasons, this is not a general scanner for + H.264 content, as this kind of data format is likely to be + used only by VDR and VDR will ensure that an AUD-NAL unit + will be at the beginning of the PES packet's payload. + To minimize false hits, the whole payload is scanned for + MPEG 1/2 start codes, so there is only a little chance left + that a MPEG 1/2 slice 9 start code will be considered as a + H.264 access unit delimiter (should only happen after a seek). + + Meaning of bit 0 and 1 of mpeg12_h264_detected: + Bit 0: H.264 access unit delimiter seen + Bit 1: H.264 AUD seen again or MPEG 1/2 start code seen + + For performance reasons, the scanner is only active until + a H.264 AUD has been seen a second time or a MPEG 1/2 start + code has been seen. The scanner get's activated initially + (e. g. when opening the stream), after seeking or when VDR + sends a padding packet. + Until the scanner is convinced of it's decision by setting + bit 1, the default behaviour is to assume MPEG 1/2 unless + an AUD has been found at the beginning of the payload. + */ + if (this->mpeg12_h264_detected < 2) { + uint8_t *pp = p + 2, *pp_limit = p + payload_size - 1; + while (0 < pp && pp < pp_limit) { + if (pp[0] == 0x01 && pp[-1] == 0x00 && pp[-2] == 0x00) { + if (pp[1] >= 0x80) { /* MPEG 1/2 start code */ + this->mpeg12_h264_detected = 2; + break; + } else { + int nal_type_code = pp[1] & 0x1f; + if (nal_type_code == 9 && pp == (p + 2)) { /* access unit delimiter */ + if (this->mpeg12_h264_detected == 1) { + this->mpeg12_h264_detected = 3; + break; + } + this->mpeg12_h264_detected = 1; + } + } + } + pp++; + pp = memchr(pp, 0x01, pp_limit - pp); + } + lprintf("%s%c\n", (this->mpeg12_h264_detected & 1) ? "H.264" : "MPEG1/2", (this->mpeg12_h264_detected & 2) ? '!' : '?'); + } - if (this->packet_len <= (buf->max_size - 6)) { - buf->size = this->packet_len; + /* when an H.264 AUD is seen, we first need to tell the decoder that the + previous frame was complete. + */ + if (this->mpeg12_h264_detected & 1) { + buf_type = BUF_VIDEO_H264; + int nal_type_code = -1; + if (payload_size >= 4 && p[2] == 0x01 && p[1] == 0x00 && p[0] == 0x00) + nal_type_code = p[3] & 0x1f; + if (nal_type_code == 9) { /* access unit delimiter */ + buf_element_t *b = this->video_fifo->buffer_pool_alloc (this->video_fifo); + b->content = b->mem; + b->size = 0; + b->pts = 0; + b->type = buf_type; + b->decoder_flags = BUF_FLAG_FRAME_END; + this->video_fifo->put (this->video_fifo, b); + } + } + + if (this->packet_len <= (buf->max_size - result)) { + buf->size = this->packet_len; + /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We + need to detect this to inform the decoder that the current frame is complete. + */ + if (this->mpeg12_h264_detected & 1) { + uint8_t *t = buf->content + buf->size; + if (buf->size >=4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */ + buf->decoder_flags = BUF_FLAG_FRAME_END; + } } else { - buf->size = buf->max_size - result; - todo_length = this->packet_len - buf->size; + buf->size = buf->max_size - result; + todo_length = this->packet_len - buf->size; } - buf->type = BUF_VIDEO_MPEG; + buf->type = buf_type; buf->pts = this->pts; buf->decoder_info[0] = this->pts - this->dts; if( !this->preview_mode ) @@ -1098,10 +1185,20 @@ static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_elemen } buf->content = buf->mem; buf->size = chunk_length; - buf->type = BUF_VIDEO_MPEG; + buf->type = buf_type; buf->pts = 0; - this->video_fifo->put (this->video_fifo, buf); todo_length -= chunk_length; + + /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We + need to detect this to inform the decoder that the current frame is complete. + */ + if ((this->mpeg12_h264_detected & 1) && todo_length <= 0) { + uint8_t *t = buf->content + buf->size; + if (buf->size >= 4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */ + buf->decoder_flags = BUF_FLAG_FRAME_END; + } + + this->video_fifo->put (this->video_fifo, buf); } lprintf ("MPEG Video PACK put on fifo\n"); @@ -1283,7 +1380,7 @@ static int demux_mpeg_pes_estimate_rate (demux_mpeg_pes_t *this) { count ++; /* - printf ("demux_mpeg_pes: stream_id %02x, pos: %lld, pts: %d, cur_rate = %d, overall rate : %d\n", + printf ("demux_mpeg_pes: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n", stream_id, pos, pts, cur_rate, rate); */ } @@ -1426,6 +1523,8 @@ static int demux_mpeg_pes_seek (demux_plugin_t *this_gen, } else { this->buf_flag_seek = 1; this->nav_last_end_pts = this->nav_last_start_pts = 0; + /* trigger detection of MPEG 1/2 respectively H.264 content */ + this->mpeg12_h264_detected = 0; _x_demux_flush_engine(this->stream); } @@ -1500,7 +1599,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->status = DEMUX_FINISHED; /* Don't start demuxing stream until we see a program_stream_pack_header */ /* We need to system header in order to identify is the stream is mpeg1 or mpeg2. */ - this->wait_for_program_stream_pack_header=1; + this->wait_for_program_stream_pack_header = 1; + /* trigger detection of MPEG 1/2 respectively H.264 content */ + this->mpeg12_h264_detected = 0; this->preview_size = 0; @@ -1594,11 +1695,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *ending, *mrl; - - mrl = input->get_mrl (input); - - ending = strrchr(mrl, '.'); + const char *const mrl = input->get_mrl (input); + const char *const ending = strrchr(mrl, '.'); if (!ending) { free (this->scratch_base); @@ -1630,19 +1728,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "mpeg pes demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEG_PES"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "pes"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c index 13724026c..31b2d33ff 100644 --- a/src/demuxers/demux_mpgaudio.c +++ b/src/demuxers/demux_mpgaudio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2003 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_mpgaudio.c,v 1.145 2006/09/03 02:03:21 dgp85 Exp $ + * $Id: demux_mpgaudio.c,v 1.156 2007/03/29 16:32:12 dgp85 Exp $ * * demultiplexer for mpeg audio (i.e. mp3) streams * @@ -79,28 +79,16 @@ /* mp3 frame struct */ typedef struct { /* header */ - uint16_t frame_sync; - uint8_t mpeg25_bit; - uint8_t lsf_bit; - uint8_t layer; - uint8_t protection_bit; - uint8_t bitrate_idx; - uint8_t freq_idx; - uint8_t padding_bit; - uint8_t private_bit; - uint8_t channel_mode; - uint8_t mode_extension; - uint8_t copyright; - uint8_t original; - uint8_t emphasis; - - uint8_t version_idx; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */ - int bitrate; /* in bit per second */ - int freq; /* in Hz */ - int samples; /* samples per frame */ - int padding; /* padding bytes (0, 1 or 4)*/ - int size; /* in bytes */ - double duration; /* in xine pts */ + double duration; + uint32_t size; /* in bytes */ + uint32_t bitrate; /* in bit per second */ + uint16_t freq; /* in Hz */ + + uint8_t layer; + + uint8_t version_idx:2; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */ + uint8_t lsf_bit:1; + uint8_t channel_mode:3; } mpg_audio_frame_t; /* Xing Vbr Header struct */ @@ -163,61 +151,72 @@ typedef struct { } demux_mpgaudio_class_t; -/* bitrate table[mpeg version][layer][bitrate index] - * values stored in kbps - */ -const int mp3_bitrates[3][3][16] = { - { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,} }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} } -}; - -/* frequency table[mpeg version][frequence index] (in KHz) */ -static int mp3_freqs[3][3] = { - { 44100, 48000, 32000 }, - { 22050, 24000, 16000 }, - { 11025, 12000, 8000 } -}; - -/* samples per frame table[mpeg version][layer] */ -static int mp3_samples[3][3] = { - { 384, 1152, 1152 }, - { 384, 1152, 576 }, - { 384, 1152, 576 } -}; - -/* samples per frame table[layer][padding bit] */ -static int mp3_paddings[3][2] = { - { 0, 4 }, - { 0, 1 }, - { 0, 1 } -}; - /* * Parse a mp3 frame * return 1 on success */ -static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { - uint32_t head; +static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *const buf) { + /* bitrate table[mpeg version][layer][bitrate index] + * values stored in kbps + */ + static const uint16_t mp3_bitrates[3][3][16] = { + { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,} }, + { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} }, + { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} } + }; + + /* frequency table[mpeg version][frequence index] (in KHz) */ + static const uint16_t mp3_freqs[3][3] = { + { 44100, 48000, 32000 }, + { 22050, 24000, 16000 }, + { 11025, 12000, 8000 } + }; + + /* samples per frame table[mpeg version][layer] */ + static const uint16_t mp3_samples[3][3] = { + { 384, 1152, 1152 }, + { 384, 1152, 576 }, + { 384, 1152, 576 } + }; + + struct { + uint16_t mpeg25_bit:1; + uint16_t bitrate_idx:4; + uint16_t freq_idx:3; + uint16_t padding_bit:1; + uint16_t channel_mode:3; + +#if 0 /* Unused */ + uint16_t protection_bit:1; + uint16_t private_bit:1; + uint16_t mode_extension:3; + uint16_t copyright:1; + uint16_t original:1; +#endif - head = BE_32(buf); +#if defined(OPT_STRICT) + uint16_t emphasis:3; +#endif + } frame_header; + + const uint32_t head = BE_32(buf); + const uint16_t frame_sync = head >> 21; lprintf("header: %08X\n", head); - frame->frame_sync = head >> 21; - if (frame->frame_sync != 0x7ff) { + if (frame_sync != 0x7ff) { lprintf("invalid frame sync\n"); return 0; } - frame->mpeg25_bit = (head >> 20) & 0x1; + frame_header.mpeg25_bit = (head >> 20) & 0x1; frame->lsf_bit = (head >> 19) & 0x1; - if (!frame->mpeg25_bit) { + if (!frame_header.mpeg25_bit) { if (frame->lsf_bit) { lprintf("reserved mpeg25 lsf combination\n"); return 0; @@ -236,54 +235,60 @@ static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { return 0; } - frame->protection_bit = (head >> 16) & 0x1; - frame->bitrate_idx = (head >> 12) & 0xf; - if ((frame->bitrate_idx == 0) || (frame->bitrate_idx == 15)) { + frame_header.bitrate_idx = (head >> 12) & 0xf; + if ((frame_header.bitrate_idx == 0) || (frame_header.bitrate_idx == 15)) { lprintf("invalid bitrate index\n"); return 0; } - frame->freq_idx = (head >> 10) & 0x3; - if (frame->freq_idx == 3) { + frame_header.freq_idx = (head >> 10) & 0x3; + if (frame_header.freq_idx == 3) { lprintf("invalid frequence index\n"); return 0; } - frame->padding_bit = (head >> 9) & 0x1; - frame->private_bit = (head >> 8) & 0x1; - frame->channel_mode = (head >> 6) & 0x3; - frame->mode_extension = (head >> 4) & 0x3; - frame->copyright = (head >> 3) & 0x1; - frame->original = (head >> 2) & 0x1; - frame->emphasis = head & 0x3; + frame_header.padding_bit = (head >> 9) & 0x1; + frame_header.channel_mode = (head >> 6) & 0x3; + +#if 0 /* Unused */ + frame_header.protection_bit = (head >> 16) & 0x1; + frame_header.private_bit = (head >> 8) & 0x1; + frame_header.mode_extension = (head >> 4) & 0x3; + frame_header.copyright = (head >> 3) & 0x1; + frame_header.original = (head >> 2) & 0x1; +#endif #if defined(OPT_STRICT) + frame_header.emphasis = head & 0x3; + /* * ISO/IEC 11172-3 says this is a reserved emphasis value, but * streams exist which use it anyway. Since the value is not important * to the decoder proper, we allow it unless OPT_STRICT is defined. */ - if (frame->emphasis == 2) { + if (frame_header.emphasis == 2) { lprintf("reserved emphasis\n"); return 0; } #endif - frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame->bitrate_idx] * 1000; - frame->freq = mp3_freqs[frame->version_idx][frame->freq_idx]; - frame->samples = mp3_samples[frame->version_idx][frame->layer - 1]; - frame->padding = mp3_paddings[frame->layer - 1][frame->padding_bit]; + { + const uint16_t samples = mp3_samples[frame->version_idx][frame->layer - 1]; + frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame_header.bitrate_idx] * 1000; + frame->freq = mp3_freqs[frame->version_idx][frame_header.freq_idx]; - frame->size = frame->samples * (frame->bitrate / 8); - frame->size /= frame->freq; - frame->size += frame->padding; + frame->size = samples * (frame->bitrate / 8); + frame->size /= frame->freq; + /* Padding: only if padding_bit is set; 4 bytes for Layer 1 and 1 byte for others */ + frame->size += ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 ); - frame->duration = 1000.0f * (double)frame->samples / (double)frame->freq; + frame->duration = 1000.0f * (double)samples / (double)frame->freq; + } lprintf("mpeg %d, layer %d\n", frame->version_idx + 1, frame->layer); lprintf("bitrate: %d bps, samplerate: %d Hz\n", frame->bitrate, frame->freq); lprintf("length: %d bytes, %f ms\n", frame->size, frame->duration); - lprintf("padding: %d bytes\n", frame->padding); + lprintf("padding: %d bytes\n", ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 )); return 1; } @@ -294,7 +299,9 @@ static int parse_frame_header(mpg_audio_frame_t *frame, uint8_t *buf) { static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame, uint8_t *buf, int bufsize) { +#ifdef LOG int i; +#endif uint8_t *ptr = buf; xing_header_t *xing; @@ -338,14 +345,12 @@ static xing_header_t* parse_xing_header(mpg_audio_frame_t *frame, lprintf("toc found\n"); if (ptr >= (buf + bufsize - XING_TOC_LENGTH)) return 0; - for (i = 0; i < XING_TOC_LENGTH; i++) { - xing->toc[i] = *(ptr + i); + memcpy(xing->toc, ptr, XING_TOC_LENGTH); #ifdef LOG - printf("%d ", xing->toc[i]); -#endif + for (i = 0; i < XING_TOC_LENGTH; i++) { + lprintf("%d ", xing->toc[i]); } -#ifdef LOG - printf("\n"); + lprintf("\n"); #endif ptr += XING_TOC_LENGTH; } @@ -437,7 +442,7 @@ static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame, for (i = 0; i <= vbri->toc_entries; i++) { toc_stream_size += vbri->toc[i]; } - lprintf("stream size from toc: %lld\n", toc_stream_size); + lprintf("stream size from toc: %"PRId64"\n", toc_stream_size); } return vbri; @@ -460,7 +465,7 @@ static int parse_frame_payload(demux_mpgaudio_t *this, uint64_t pts = 0; frame_pos = this->input->get_current_pos(this->input) - 4; - lprintf("frame_pos = %lld\n", frame_pos); + lprintf("frame_pos = %"PRId64"\n", frame_pos); buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); @@ -510,7 +515,7 @@ static int parse_frame_payload(demux_mpgaudio_t *this, buf->decoder_flags = decoder_flags|BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); - lprintf("send buffer: pts=%lld\n", pts); + lprintf("send buffer: pts=%"PRId64"\n", pts); this->cur_time += this->cur_frame.duration; return 1; } @@ -606,39 +611,14 @@ static int demux_mpgaudio_next (demux_mpgaudio_t *this, int decoder_flags, int s return parse_frame_payload(this, header_buf, decoder_flags); - } else if ((BE_32(header_buf)) == ID3V22_TAG) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.2 tag\n"); - if (!id3v22_parse_tag(this->input, this->stream, header_buf)) { + } else if ( id3v2_istag(header_buf) ) { + if (!id3v2_parse_tag(this->input, this->stream, header_buf)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.2 tag parsing error\n"); + LOG_MODULE ": ID3V2 tag parsing error\n"); bytes = 1; /* resync */ } else { bytes = 4; } - - } else if ((BE_32(header_buf)) == ID3V23_TAG) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.3 tag\n"); - if (!id3v23_parse_tag(this->input, this->stream, header_buf)) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.3 tag parsing error\n"); - bytes = 1; /* resync */ - } else { - bytes = 4; - } - - } else if ((BE_32(header_buf)) == ID3V24_TAG) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.4 tag\n"); - if (!id3v24_parse_tag(this->input, this->stream, header_buf)) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "demux_mpgaudio: ID3V2.4 tag parsing error\n"); - bytes = 1; /* resync */ - } else { - bytes = 4; - } - } else { /* skip */ bytes = 1; @@ -718,10 +698,7 @@ static int detect_mpgaudio_file(input_plugin_t *input) { * flac files can contain id3v2 tags */ uint8_t *ptr = &buf[6]; - uint32_t tag_size = ((uint32_t)ptr[0] << 21) + - ((uint32_t)ptr[1] << 14) + - ((uint32_t)ptr[2] << 7) + - (uint32_t)ptr[3]; + uint32_t tag_size = id3v2_tagsize(ptr); lprintf("try to skip id3v2 tag (%d bytes)\n", tag_size); if ((10 + tag_size) >= preview_len) { lprintf("cannot skip id3v2 tag\n"); @@ -823,9 +800,9 @@ static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->br); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->br); - lprintf("frame_start: %lld, frame_end: %lld\n", + lprintf("frame_start: %"PRId64", frame_end: %"PRId64"\n", this->mpg_frame_start, this->mpg_frame_end); - lprintf("stream size: %lld, mp3 size: %lld\n", + lprintf("stream size: %"PRId64", mp3 size: %"PRId64"\n", this->input->get_length(this->input), this->mpg_size); lprintf("stream_length: %d ms\n", this->stream_length); @@ -939,7 +916,7 @@ static int demux_mpgaudio_seek (demux_plugin_t *this_gen, /* Convert position seek to time seek */ if (!start_time) { start_time = (int)((double)start_pos * (double)this->stream_length / 65535.0f); - lprintf("position seek: start_pos=%lld => start_time=%d\n", start_pos, start_time); + lprintf("position seek: start_pos=%"PRId64" => start_time=%d\n", start_pos, start_time); } if (start_time < 0) @@ -951,14 +928,14 @@ static int demux_mpgaudio_seek (demux_plugin_t *this_gen, if (this->xing_header && (this->xing_header->flags & (XING_TOC_FLAG | XING_BYTES_FLAG))) { seek_pos += xing_get_seek_point(this->xing_header, start_time, this->stream_length); - lprintf("time seek: xing: time=%d, pos=%lld\n", start_time, seek_pos); + lprintf("time seek: xing: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } else if (this->vbri_header) { seek_pos += vbri_get_seek_point(this->vbri_header, start_time, this->stream_length); - lprintf("time seek: vbri: time=%d, pos=%lld\n", start_time, seek_pos); + lprintf("time seek: vbri: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } else { /* cbr */ seek_pos += ((double)start_time / 1000.0) * ((double)this->br / 8.0); - lprintf("time seek: cbr: time=%d, pos=%lld\n", start_time, seek_pos); + lprintf("time seek: cbr: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } } /* assume seeking is always perfect... */ @@ -1016,8 +993,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *mrl = input->get_mrl(input); - char *extensions = class_gen->get_extensions (class_gen); + const char *const mrl = input->get_mrl(input); + const char *const extensions = class_gen->get_extensions (class_gen); lprintf ("stage by extension %s\n", mrl); @@ -1058,15 +1035,15 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str * demux mpegaudio class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "MPEG audio demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEGAUDIO"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { demux_mpgaudio_class_t *this = (demux_mpgaudio_class_t *) this_gen; if( _x_decoder_available(this->xine, BUF_AUDIO_MPEG) ) @@ -1075,7 +1052,7 @@ static char *get_extensions (demux_class_t *this_gen) { return ""; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { demux_mpgaudio_class_t *this = (demux_mpgaudio_class_t *) this_gen; if( _x_decoder_available(this->xine, BUF_AUDIO_MPEG) ) @@ -1085,7 +1062,7 @@ static char *get_mimetypes (demux_class_t *this_gen) { "audio/x-mpeg3: mp3: MPEG audio;" "audio/mpeg: mpa,abs,mpega: MPEG audio;" "audio/x-mpeg: mpa,abs,mpega: MPEG audio;" - "x-mpegurl: mp3: MPEG audio;" + "audio/x-mpegurl: mp3: MPEG audio;" "audio/mpegurl: mp3: MPEG audio;" "audio/mp3: mp3: MPEG audio;" "audio/x-mp3: mp3: MPEG audio;"; diff --git a/src/demuxers/demux_nsf.c b/src/demuxers/demux_nsf.c index dae756d8d..7408274d5 100644 --- a/src/demuxers/demux_nsf.c +++ b/src/demuxers/demux_nsf.c @@ -30,7 +30,7 @@ * For more information regarding the NSF format, visit: * http://www.tripoint.org/kevtris/nes/nsfspec.txt * - * $Id: demux_nsf.c,v 1.22 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_nsf.c,v 1.24 2007/03/29 17:03:06 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -71,12 +71,14 @@ typedef struct { input_plugin_t *input; int status; - char *title; - char *artist; - char *copyright; int total_songs; int current_song; int new_song; /* indicates song change */ + + char *title; + char *artist; + char *copyright; + off_t filesize; int64_t current_pts; @@ -322,7 +324,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -352,19 +354,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "NES Music file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "NSF"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "nsf"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_nsv.c b/src/demuxers/demux_nsv.c index 6f71a6264..6d43b247c 100644 --- a/src/demuxers/demux_nsv.c +++ b/src/demuxers/demux_nsv.c @@ -23,7 +23,7 @@ * For more information regarding the NSV file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_nsv.c,v 1.24 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_nsv.c,v 1.25 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -615,7 +615,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -645,19 +645,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Nullsoft Video demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Nullsoft NSV"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "nsv"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c index 3ea07306b..f868018af 100644 --- a/src/demuxers/demux_ogg.c +++ b/src/demuxers/demux_ogg.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_ogg.c,v 1.171 2006/11/10 14:53:23 dgp85 Exp $ + * $Id: demux_ogg.c,v 1.177 2007/03/29 19:38:51 dgp85 Exp $ * * demultiplexer for ogg streams * @@ -126,17 +126,20 @@ typedef struct demux_ogg_s { input_plugin_t *input; int status; + int frame_duration; + #ifdef HAVE_THEORA theora_info t_info; theora_comment t_comment; #endif - int frame_duration; - ogg_sync_state oy; ogg_page og; int64_t start_pts; + int64_t last_pts[2]; + + int time_length; int num_streams; stream_info_t *si[MAX_STREAMS]; /* stream info */ @@ -148,16 +151,14 @@ typedef struct demux_ogg_s { off_t avg_bitrate; - int64_t last_pts[2]; - int send_newpts; - int buf_flag_seek; - int keyframe_needed; - int ignore_keyframes; - int time_length; - char *title; chapter_info_t *chapter_info; xine_event_queue_t *event_queue; + + uint8_t send_newpts:1; + uint8_t buf_flag_seek:1; + uint8_t keyframe_needed:1; + uint8_t ignore_keyframes:1; } demux_ogg_t ; typedef struct { @@ -536,7 +537,11 @@ static void update_chapter_display (demux_ogg_t *this, int stream_num, ogg_packe if (chapter >= 0) { char t_title[256]; - snprintf(t_title, sizeof (t_title), "%s / %s", this->title, this->chapter_info->entries[chapter].name); + if (this->title) { + snprintf(t_title, sizeof (t_title), "%s / %s", this->title, this->chapter_info->entries[chapter].name); + } else { + snprintf(t_title, sizeof (t_title), "%s", this->chapter_info->entries[chapter].name); + } title = t_title; } else { title = this->title; @@ -714,7 +719,7 @@ static void send_ogg_buf (demux_ogg_t *this, buf->size = 12 + op->bytes + 1; - lprintf ("CMML stream %d (bytes=%ld): PTS %lld: %s\n", + lprintf ("CMML stream %d (bytes=%ld): PTS %"PRId64": %s\n", stream_num, op->bytes, buf->pts, str); this->video_fifo->put (this->video_fifo, buf); @@ -1861,9 +1866,7 @@ static int format_lang_string (demux_ogg_t * this, uint32_t buf_mask, uint32_t b for (stream_num=0; stream_num<this->num_streams; stream_num++) { if ((this->si[stream_num]->buf_types & buf_mask) == buf_type) { if (this->si[stream_num]->language) { - strncpy (str, this->si[stream_num]->language, XINE_LANG_MAX); - str[XINE_LANG_MAX - 1] = '\0'; - if (strlen(this->si[stream_num]->language) >= XINE_LANG_MAX) + if (snprintf (str, XINE_LANG_MAX, "%s", this->si[stream_num]->language) >= XINE_LANG_MAX) /* the string got truncated */ str[XINE_LANG_MAX - 2] = str[XINE_LANG_MAX - 3] = str[XINE_LANG_MAX - 4] = '.'; /* TODO: provide long version in XINE_META_INFO_FULL_LANG */ @@ -1926,7 +1929,7 @@ static int detect_ogg_content (int detection_method, demux_class_t *class_gen, } case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -1988,7 +1991,7 @@ static int detect_anx_content (int detection_method, demux_class_t *class_gen, #undef ANNODEX_SIGNATURE_SEARCH case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -2099,19 +2102,19 @@ static demux_plugin_t *ogg_open_plugin (demux_class_t *class_gen, * Annodex demuxer class */ -static char *anx_get_description (demux_class_t *this_gen) { +static const char *anx_get_description (demux_class_t *this_gen) { return "Annodex demux plugin"; } -static char *anx_get_identifier (demux_class_t *this_gen) { +static const char *anx_get_identifier (demux_class_t *this_gen) { return "Annodex"; } -static char *anx_get_extensions (demux_class_t *this_gen) { +static const char *anx_get_extensions (demux_class_t *this_gen) { return "anx axa axv"; } -static char *anx_get_mimetypes (demux_class_t *this_gen) { +static const char *anx_get_mimetypes (demux_class_t *this_gen) { return "application/x-annodex: ogg: Annodex media;"; } @@ -2140,22 +2143,23 @@ static void *anx_init_class (xine_t *xine, void *data) { * ogg demuxer class */ -static char *ogg_get_description (demux_class_t *this_gen) { +static const char *ogg_get_description (demux_class_t *this_gen) { return "OGG demux plugin"; } -static char *ogg_get_identifier (demux_class_t *this_gen) { +static const char *ogg_get_identifier (demux_class_t *this_gen) { return "OGG"; } -static char *ogg_get_extensions (demux_class_t *this_gen) { +static const char *ogg_get_extensions (demux_class_t *this_gen) { return "ogg ogm spx"; } -static char *ogg_get_mimetypes (demux_class_t *this_gen) { +static const char *ogg_get_mimetypes (demux_class_t *this_gen) { return "audio/x-ogg: ogg: OggVorbis Audio;" "audio/x-speex: ogg: Speex Audio;" - "application/x-ogg: ogg: OggVorbis Audio;"; + "application/x-ogg: ogg: Ogg Stream;" + "application/ogg: ogg: Ogg Stream;"; } static void ogg_class_dispose (demux_class_t *this_gen) { diff --git a/src/demuxers/demux_pva.c b/src/demuxers/demux_pva.c index 44e5112c6..55b1f7644 100644 --- a/src/demuxers/demux_pva.c +++ b/src/demuxers/demux_pva.c @@ -23,7 +23,7 @@ * For more information regarding the PVA file format, refer to this PDF: * http://www.technotrend.de/download/av_format_v1.pdf * - * $Id: demux_pva.c,v 1.24 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_pva.c,v 1.25 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -451,7 +451,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -480,19 +480,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "TechnoTrend PVA demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "TechnoTrend PVA"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "pva"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index b4646b3e5..4144f3049 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -30,7 +30,7 @@ * build_frame_table * free_qt_info * - * $Id: demux_qt.c,v 1.212 2006/11/11 12:23:44 molivier Exp $ + * $Id: demux_qt.c,v 1.214 2007/01/19 01:05:24 dgp85 Exp $ * */ @@ -2993,11 +2993,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *ending, *mrl; - - mrl = input->get_mrl (input); - - ending = strrchr(mrl, '.'); + const char *const mrl = input->get_mrl (input); + const char *const ending = strrchr(mrl, '.'); if (!ending) { free (this); @@ -3041,19 +3038,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Apple Quicktime (MOV) and MPEG-4 demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MOV/MPEG-4"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mov qt mp4 m4a m4b"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "video/quicktime: mov,qt: Quicktime animation;" "video/x-quicktime: mov,qt: Quicktime animation;" "audio/x-m4a: m4a,m4b: MPEG-4 audio;" diff --git a/src/demuxers/demux_rawdv.c b/src/demuxers/demux_rawdv.c index 6c7d672e8..7a4cbaec9 100644 --- a/src/demuxers/demux_rawdv.c +++ b/src/demuxers/demux_rawdv.c @@ -19,7 +19,7 @@ */ /* - * $Id: demux_rawdv.c,v 1.29 2006/08/08 03:15:02 miguelfreitas Exp $ + * $Id: demux_rawdv.c,v 1.30 2007/01/19 00:26:40 dgp85 Exp $ * * demultiplexer for raw dv streams */ @@ -385,7 +385,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -413,19 +413,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Raw DV Video stream"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "raw_dv"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "dv dif"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 7441c8619..11b0dbf38 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -31,7 +31,7 @@ * * Based on FFmpeg's libav/rm.c. * - * $Id: demux_real.c,v 1.109 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_real.c,v 1.113 2007/02/20 00:34:56 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -181,7 +181,7 @@ static void real_parse_index(demux_real_t *this) { real_index_entry_t **index; while(next_index_chunk) { - lprintf("reading index chunk at %llX\n", next_index_chunk); + lprintf("reading index chunk at %"PRIX64"\n", next_index_chunk); /* Seek to index chunk */ this->input->seek(this->input, next_index_chunk, SEEK_SET); @@ -401,9 +401,9 @@ static void real_parse_headers (demux_real_t *this) { this->avg_bitrate = BE_32(&chunk_buffer[6]); lprintf("PROP: duration: %d ms\n", this->duration); - lprintf("PROP: index start: %llX\n", this->index_start); - lprintf("PROP: data start: %llX\n", this->data_start); - lprintf("PROP: average bit rate: %lld\n", this->avg_bitrate); + lprintf("PROP: index start: %"PRIX64"\n", this->index_start); + lprintf("PROP: data start: %"PRIX64"\n", this->data_start); + lprintf("PROP: average bit rate: %"PRId64"\n", this->avg_bitrate); if (this->avg_bitrate<1) this->avg_bitrate = 1; @@ -854,12 +854,12 @@ static void check_newpts (demux_real_t *this, int64_t pts, int video, int previe int64_t diff; diff = pts - this->last_pts[video]; - lprintf ("check_newpts %lld\n", pts); + lprintf ("check_newpts %"PRId64"\n", pts); if (!preview && pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { - lprintf ("diff=%lld\n", diff); + lprintf ("diff=%"PRId64"\n", diff); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); @@ -1012,7 +1012,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) { size--; } - lprintf ("packet of stream %d, 0x%X bytes @ %llX, pts = %lld%s\n", + lprintf ("packet of stream %d, 0x%X bytes @ %"PRIX64", pts = %"PRId64"%s\n", stream, size, offset, pts, keyframe ? ", keyframe" : ""); if (this->video_stream && (stream == this->video_stream->mdpr->stream_number)) { @@ -1409,12 +1409,15 @@ static int demux_real_seek (demux_plugin_t *this_gen, real_index_entry_t *index, *other_index = NULL; int i = 0, entries; - start_pos = (off_t) ( (double) start_pos / 65535 * - this->input->get_length (this->input) ); + lprintf("seek start_pos=%d, start_time=%d, playing=%d\n", + (int)start_pos, start_time, playing); if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) && ((this->audio_stream && this->audio_stream->index) || (this->video_stream && this->video_stream->index))) { + + start_pos = (off_t) ( (double) start_pos / 65535 * + this->input->get_length (this->input) ); /* video index has priority over audio index */ if(this->video_stream && this->video_stream->index) { @@ -1453,6 +1456,13 @@ static int demux_real_seek (demux_plugin_t *this_gen, _x_demux_flush_engine(this->stream); } } + else if (!playing && this->input->seek_time != NULL) { + /* RTSP supports only time based seek */ + if (start_pos && !start_time) + start_time = (int64_t) this->duration * start_pos / 65535; + + this->input->seek_time(this->input, start_time, SEEK_SET); + } this->send_newpts = 1; this->old_seqnum = -1; @@ -1555,7 +1565,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -1608,19 +1618,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "RealMedia file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Real"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "rm rmvb ram"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/x-pn-realaudio: ra, rm, ram: Real Media file;" "audio/x-pn-realaudio-plugin: rpm: Real Media plugin file;" "audio/x-real-audio: ra, rm, ram: Real Media file;" diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c index d1de83015..bf8de0dad 100644 --- a/src/demuxers/demux_realaudio.c +++ b/src/demuxers/demux_realaudio.c @@ -22,7 +22,7 @@ * RealAudio File Demuxer by Mike Melanson (melanson@pcisys.net) * improved by James Stembridge (jstembridge@users.sourceforge.net) * - * $Id: demux_realaudio.c,v 1.32 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_realaudio.c,v 1.34 2007/03/29 17:00:32 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -57,16 +57,15 @@ typedef struct { unsigned int fourcc; unsigned int audio_type; + unsigned short block_align; + + uint8_t seek_flag:1; /* this is set when a seek just occurred */ + off_t data_start; off_t data_size; - unsigned short block_align; - unsigned int bytes_per_sec; - unsigned char *header; unsigned int header_size; - - int seek_flag; /* this is set when a seek just occurred */ } demux_ra_t; typedef struct { @@ -316,10 +315,7 @@ static int demux_ra_get_status (demux_plugin_t *this_gen) { static int demux_ra_get_stream_length (demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; - if(this->bytes_per_sec) - return (int)((int64_t) this->data_size * 1000 / this->bytes_per_sec); - else - return 0; + return 0; } static uint32_t demux_ra_get_capabilities(demux_plugin_t *this_gen) { @@ -355,7 +351,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -385,19 +381,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "RealAudio file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "RA"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "ra"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/x-realaudio: ra: RealAudio File;"; } diff --git a/src/demuxers/demux_roq.c b/src/demuxers/demux_roq.c index ed261d728..0e7c93b97 100644 --- a/src/demuxers/demux_roq.c +++ b/src/demuxers/demux_roq.c @@ -23,7 +23,7 @@ * For more information regarding the RoQ file format, visit: * http://www.csse.monash.edu.au/~timf/ * - * $Id: demux_roq.c,v 1.53 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_roq.c,v 1.54 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -432,7 +432,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -462,19 +462,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Id RoQ file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "RoQ"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "roq"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_shn.c b/src/demuxers/demux_shn.c index 8e3602634..3db568aab 100644 --- a/src/demuxers/demux_shn.c +++ b/src/demuxers/demux_shn.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_shn.c,v 1.2 2006/09/28 22:27:52 dgp85 Exp $ + * $Id: demux_shn.c,v 1.4 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -67,8 +67,8 @@ static int open_shn_file(demux_shn_t *this) { if (_x_demux_read_header(this->input, peak, 4) != 4) return 0; - if ((peak[0] != 'a') && (peak[1] != 'j') && - (peak[2] != 'k') && (peak[3] != 'g')) { + if ((peak[0] != 'a') || (peak[1] != 'j') || + (peak[2] != 'k') || (peak[3] != 'g')) { return 0; } @@ -202,7 +202,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -230,19 +230,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Shorten demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "Shorten"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "shn"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_slave.c b/src/demuxers/demux_slave.c index 306b14ed4..a00ad0661 100644 --- a/src/demuxers/demux_slave.c +++ b/src/demuxers/demux_slave.c @@ -21,7 +21,7 @@ */ /* - * $Id: demux_slave.c,v 1.21 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_slave.c,v 1.23 2007/01/19 01:05:24 dgp85 Exp $ * * demuxer for slave "protocol" * master xine must be started with XINE_PARAM_BROADCASTER_PORT set, that is, @@ -338,9 +338,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *mrl; - - mrl = input->get_mrl (input); + const char *const mrl = input->get_mrl (input); if(!strncmp(mrl, "slave://", 8)) break; @@ -393,19 +391,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return ""; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "slave"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return ""; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_smjpeg.c b/src/demuxers/demux_smjpeg.c index afe28328d..9c86314c5 100644 --- a/src/demuxers/demux_smjpeg.c +++ b/src/demuxers/demux_smjpeg.c @@ -23,7 +23,7 @@ * For more information on the SMJPEG file format, visit: * http://www.lokigames.com/development/smjpeg.php3 * - * $Id: demux_smjpeg.c,v 1.50 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_smjpeg.c,v 1.51 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -421,7 +421,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -451,19 +451,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "SMJPEG file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "SMJPEG"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mjpg"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_snd.c b/src/demuxers/demux_snd.c index c1925bc71..99415890a 100644 --- a/src/demuxers/demux_snd.c +++ b/src/demuxers/demux_snd.c @@ -21,7 +21,7 @@ /* * SND/AU File Demuxer by Mike Melanson (melanson@pcisys.net) * - * $Id: demux_snd.c,v 1.40 2004/10/18 18:20:32 miguelfreitas Exp $ + * $Id: demux_snd.c,v 1.41 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -339,7 +339,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -369,19 +369,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "SND/AU file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "SND/AU"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "snd au"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/basic: snd,au: ULAW (Sun) audio;" "audio/x-basic: snd,au: ULAW (Sun) audio;" "audio/x-pn-au: snd,au: ULAW (Sun) audio;"; diff --git a/src/demuxers/demux_str.c b/src/demuxers/demux_str.c index ddb800260..90dbf2117 100644 --- a/src/demuxers/demux_str.c +++ b/src/demuxers/demux_str.c @@ -24,7 +24,7 @@ * This demuxer handles either raw STR files (which are just a concatenation * of raw compact disc sectors) or STR files with RIFF headers. * - * $Id: demux_str.c,v 1.25 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_str.c,v 1.26 2007/01/19 00:26:40 dgp85 Exp $ */ /* @@ -576,7 +576,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -605,20 +605,20 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Sony Playstation STR file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "PSX STR"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { /* also .mov, but we don't want to hijack that extension */ return "str iki ik2 dps dat xa xa1 xa2 xas xap"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index ef68cb698..aea0c8ca1 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_ts.c,v 1.123 2006/08/08 03:58:15 miguelfreitas Exp $ + * $Id: demux_ts.c,v 1.129 2007/04/02 10:46:08 dgp85 Exp $ * * Demultiplexer for MPEG2 Transport Streams. * @@ -254,7 +254,7 @@ typedef struct { } demux_ts_media; /* DVBSUB */ -#define MAX_NO_SPU_LANGS 16 +#define MAX_SPU_LANGS 16 typedef struct { spu_dvb_descriptor_t desc; @@ -262,6 +262,14 @@ typedef struct { int media_index; } demux_ts_spu_lang; +/* Audio Channels */ +#define MAX_AUDIO_TRACKS 16 + +typedef struct { + int pid; + int media_index; + char lang[4]; +} demux_ts_audio_track; typedef struct { /* @@ -299,10 +307,10 @@ typedef struct { unsigned int pid; unsigned int pid_count; unsigned int videoPid; - unsigned int audioPid; unsigned int videoMedia; - unsigned int audioMedia; - char audioLang[4]; + + demux_ts_audio_track audio_tracks[MAX_AUDIO_TRACKS]; + int audio_tracks_count; int send_end_buffers; int64_t last_pts[2]; @@ -319,8 +327,8 @@ typedef struct { /* DVBSUB */ unsigned int spu_pid; unsigned int spu_media; - demux_ts_spu_lang spu_langs[MAX_NO_SPU_LANGS]; - int no_spu_langs; + demux_ts_spu_lang spu_langs[MAX_SPU_LANGS]; + int spu_langs_count; int current_spu_channel; /* dvb */ @@ -457,7 +465,7 @@ static void demux_ts_update_spu_channel(demux_ts_t *this) buf->size = 0; if (this->current_spu_channel >= 0 - && this->current_spu_channel < this->no_spu_langs) + && this->current_spu_channel < this->spu_langs_count) { demux_ts_spu_lang *lang = &this->spu_langs[this->current_spu_channel]; @@ -627,7 +635,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, /* force PMT reparsing when pmt_pid changes */ if (this->pmt_pid[program_count] != pmt_pid) { this->pmt_pid[program_count] = pmt_pid; - this->audioPid = INVALID_PID; + this->audio_tracks_count = 0; this->videoPid = INVALID_PID; this->spu_pid = INVALID_PID; } @@ -737,7 +745,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, (p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */ m->content = p; m->size = packet_len; - m->type = BUF_AUDIO_A52; + m->type |= BUF_AUDIO_A52; return 1; } else if (m->descriptor_tag == 0x06 @@ -761,7 +769,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->content = p+4; m->size = packet_len - 4; - m->type = BUF_AUDIO_A52 + track; + m->type |= BUF_AUDIO_A52 + track; return 1; } else if ((p[0]&0xf0) == 0xa0) { @@ -777,7 +785,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->content = p+pcm_offset; m->size = packet_len-pcm_offset; - m->type = BUF_AUDIO_LPCM_BE + track; + m->type |= BUF_AUDIO_LPCM_BE + track; return 1; } @@ -818,16 +826,16 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, case ISO_11172_AUDIO: case ISO_13818_AUDIO: lprintf ("demux_ts: found MPEG audio track.\n"); - m->type = BUF_AUDIO_MPEG + track; + m->type |= BUF_AUDIO_MPEG + track; break; case ISO_13818_PART7_AUDIO: case ISO_14496_PART3_AUDIO: lprintf ("demux_ts: found AAC audio track.\n"); - m->type = BUF_AUDIO_AAC + track; + m->type |= BUF_AUDIO_AAC + track; break; default: lprintf ("demux_ts: unknown audio type: %d, defaulting to MPEG.\n", m->descriptor_tag); - m->type = BUF_AUDIO_MPEG + track; + m->type |= BUF_AUDIO_MPEG + track; break; } return 1; @@ -1212,7 +1220,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num /* * Extract the elementary streams. */ - this->no_spu_langs = 0; + this->spu_langs_count = 0; while (section_length > 0) { unsigned int stream_info_length; @@ -1248,15 +1256,26 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num case ISO_13818_AUDIO: case ISO_13818_PART7_AUDIO: case ISO_14496_PART3_AUDIO: - if (this->audioPid == INVALID_PID) { + if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { + int i, found = 0; + for(i = 0; i < this->audio_tracks_count; i++) { + if(this->audio_tracks[i].pid == pid) { + found = 1; + break; + } + } + if(!found) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT audio pid 0x%.4x\n", pid); + printf ("demux_ts: PMT audio pid 0x%.4x\n", pid); #endif - demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo,stream[0]); - this->audioPid = pid; - this->audioMedia = this->media_num; - demux_ts_get_lang_desc(this, this->audioLang, + demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo,stream[0]); + this->audio_tracks[this->audio_tracks_count].pid = pid; + this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; + this->media[this->media_num].type = this->audio_tracks_count; + demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang, stream + 5, stream_info_length); + this->audio_tracks_count++; + } } break; case ISO_13818_PRIVATE: @@ -1275,30 +1294,31 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num break; case ISO_13818_PES_PRIVATE: for (i = 5; i < coded_length; i += stream[i+1] + 2) { - if ((stream[i] == 0x6a) && (this->audioPid == INVALID_PID)) { + if ((stream[i] == 0x6a) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { uint32_t format_identifier=0; + int i, found = 0; + for(i = 0; i < this->audio_tracks_count; i++) { + if(this->audio_tracks[i].pid == pid) { + found = 1; + break; + } + } + if(!found) { #ifdef TS_PMT_LOG - printf ("demux_ts: PMT AC3 audio pid 0x%.4x\n", pid); + printf ("demux_ts: PMT AC3 audio pid 0x%.4x\n", pid); #endif - demux_ts_get_reg_desc(this, &format_identifier, - stream + 5, stream_info_length); - if (format_identifier == 0x41432d33) /* AC-3 */ - demux_ts_pes_new(this, this->media_num, pid, - this->audio_fifo, 0x81); - else if((stream[i+1]>1) && (stream[i+2] & 0x80 ) && (stream[3] & 0x40)) /* AC3 Full Service */ - demux_ts_pes_new(this, this->media_num, pid, - this->audio_fifo, 0x81); - else - demux_ts_pes_new(this, this->media_num, pid, - this->audio_fifo,stream[0]); - - this->audioPid = pid; - this->audioMedia = this->media_num; - demux_ts_get_lang_desc(this, this->audioLang, - stream + 5, stream_info_length); + demux_ts_pes_new(this, this->media_num, pid, + this->audio_fifo, 0x81); + + this->audio_tracks[this->audio_tracks_count].pid = pid; + this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; + this->media[this->media_num].type = this->audio_tracks_count; + demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang, + stream + 5, stream_info_length); + this->audio_tracks_count++; break; + } } - /* Teletext */ else if (stream[i] == 0x56) { @@ -1318,13 +1338,13 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num int pos; for (pos = i + 2; pos + 8 <= i + 2 + stream[i + 1] - && this->no_spu_langs < MAX_NO_SPU_LANGS; + && this->spu_langs_count < MAX_SPU_LANGS; pos += 8) { - int no = this->no_spu_langs; + int no = this->spu_langs_count; demux_ts_spu_lang *lang = &this->spu_langs[no]; - this->no_spu_langs++; + this->spu_langs_count++; memcpy(lang->desc.lang, &stream[pos], 3); lang->desc.lang[3] = 0; @@ -1356,18 +1376,29 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num * if is does, we tag this as an audio stream. * FIXME: This will need expanding if we ever see a DTS or other media format here. */ - if (this->audioPid == INVALID_PID && (stream[0] >= 0x80) ) { - uint32_t format_identifier=0; - demux_ts_get_reg_desc(this, &format_identifier, - stream + 5, stream_info_length); - /* If no format identifier, assume A52 */ - if ((format_identifier == 0x41432d33) || (format_identifier == 0)) { - demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]); - this->audioPid = pid; - this->audioMedia = this->media_num; - demux_ts_get_lang_desc(this, this->audioLang, - stream + 5, stream_info_length); - break; + if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) { + int i, found = 0; + for(i = 0; i < this->audio_tracks_count; i++) { + if(this->audio_tracks[i].pid == pid) { + found = 1; + break; + } + } + if(!found) { + uint32_t format_identifier=0; + demux_ts_get_reg_desc(this, &format_identifier, + stream + 5, stream_info_length); + /* If no format identifier, assume A52 */ + if ((format_identifier == 0x41432d33) || (format_identifier == 0)) { + demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]); + this->audio_tracks[this->audio_tracks_count].pid = pid; + this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; + this->media[this->media_num].type = this->audio_tracks_count; + demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang, + stream + 5, stream_info_length); + this->audio_tracks_count++; + break; + } } } else { #ifdef TS_PMT_LOG @@ -1612,6 +1643,16 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, return PCR; } +/* check if an apid is in the list of known apids */ +static int apid_check(demux_ts_t*this, unsigned int pid) { + int i; + for(i=0; i<this->audio_tracks_count; i++) { + if(this->audio_tracks[i].pid == pid) + return i; + } + return -1; +} + /* transport stream packet layer */ static void demux_ts_parse_packet (demux_ts_t*this) { @@ -1753,15 +1794,27 @@ static void demux_ts_parse_packet (demux_ts_t*this) { demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, pes_stream_id); } } else if ( (pes_stream_id >= AUDIO_STREAM_S) && (pes_stream_id <= AUDIO_STREAM_E) ) { - if ( this->audioPid == INVALID_PID) { - - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_ts: auto-detected audio pid 0x%.4x\n", pid); - - this->audioPid = pid; - this->audioMedia = this->media_num; - demux_ts_pes_new(this, this->media_num++, pid, this->audio_fifo, pes_stream_id); - } + if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { + int i, found = 0; + for(i = 0; i < this->audio_tracks_count; i++) { + if(this->audio_tracks[i].pid == pid) { + found = 1; + break; + } + } + if(!found) { +#ifdef TS_PMT_LOG + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_ts: auto-detected audio pid 0x%.4x\n", pid); +#endif + this->audio_tracks[this->audio_tracks_count].pid = pid; + this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; + this->media[this->media_num].type = this->audio_tracks_count; + demux_ts_pes_new(this, this->media_num++, pid, + this->audio_fifo,pes_stream_id); + this->audio_tracks_count++; + } + } } } @@ -1775,6 +1828,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) { /* * Do the demuxing in descending order of packet frequency! */ + int index; if (pid == this->videoPid) { #ifdef TS_LOG printf ("demux_ts: Video pid: 0x%.4x\n", pid); @@ -1785,12 +1839,13 @@ static void demux_ts_parse_packet (demux_ts_t*this) { data_len); return; } - else if (pid == this->audioPid) { + else if ((index = apid_check(this, pid)) > -1) { #ifdef TS_LOG printf ("demux_ts: Audio pid: 0x%.4x\n", pid); #endif - check_newpts(this, this->media[this->audioMedia].pts, PTS_AUDIO); - demux_ts_buffer_pes (this, originalPkt+data_offset, this->audioMedia, + check_newpts(this, this->media[this->audio_tracks[index].media_index].pts, PTS_AUDIO); + demux_ts_buffer_pes (this, originalPkt+data_offset, + this->audio_tracks[index].media_index, payload_unit_start_indicator, continuity_counter, data_len); return; @@ -1830,12 +1885,12 @@ static void demux_ts_event_handler (demux_ts_t *this) { case XINE_EVENT_PIDS_CHANGE: this->videoPid = INVALID_PID; - this->audioPid = INVALID_PID; + this->audio_tracks_count = 0; this->media_num = 0; this->send_newpts = 1; this->spu_pid = INVALID_PID; this->spu_media = 0; - this->no_spu_langs= 0; + this->spu_langs_count= 0; _x_demux_control_start (this->stream); break; @@ -1909,7 +1964,7 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) { */ this->videoPid = INVALID_PID; - this->audioPid = INVALID_PID; + this->audio_tracks_count = 0; this->media_num= 0; _x_demux_control_start (this->stream); @@ -1927,7 +1982,7 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) { /* DVBSUB */ this->spu_pid = INVALID_PID; - this->no_spu_langs = 0; + this->spu_langs_count = 0; this->current_spu_channel = this->stream->spu_channel; /* FIXME ? */ @@ -2005,6 +2060,8 @@ static int demux_ts_get_optional_data(demux_plugin_t *this_gen, { demux_ts_t *this = (demux_ts_t *) this_gen; char *str = data; + int channel = *((int *)data); + int track_num; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) @@ -2013,22 +2070,24 @@ static int demux_ts_get_optional_data(demux_plugin_t *this_gen, switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: - if (this->audioLang[0]) - { - strcpy(str, this->audioLang); - } + if ((channel >= 0) && (channel < this->audio_tracks_count)) { + if(this->audio_tracks[channel].lang) + strcpy(str, this->audio_tracks[channel].lang); + else + sprintf(str, "%3i", _x_get_audio_channel(this->stream)); + } else { - sprintf(str, "%3i", _x_get_audio_channel(this->stream)); + snprintf(str, XINE_LANG_MAX, "%3i", _x_get_audio_channel(this->stream)); } return DEMUX_OPTIONAL_SUCCESS; case DEMUX_OPTIONAL_DATA_SPULANG: if (this->current_spu_channel >= 0 - && this->current_spu_channel < this->no_spu_langs) + && this->current_spu_channel < this->spu_langs_count) { memcpy(str, this->spu_langs[this->current_spu_channel].desc.lang, 3); - str[4] = 0; + str[3] = 0; } else if (this->current_spu_channel == -1) { @@ -2036,7 +2095,7 @@ static int demux_ts_get_optional_data(demux_plugin_t *this_gen, } else { - sprintf(str, "%3i", this->current_spu_channel); + snprintf(str, XINE_LANG_MAX, "%3i", this->current_spu_channel); } return DEMUX_OPTIONAL_SUCCESS; @@ -2089,12 +2148,10 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, break; case METHOD_BY_EXTENSION: { - char *extensions, *mrl; - - mrl = input->get_mrl (input); + const char *const mrl = input->get_mrl (input); /* check extension */ - extensions = class_gen->get_extensions (class_gen); + const char *const extensions = class_gen->get_extensions (class_gen); if (_x_demux_check_extension (mrl, extensions)) break; @@ -2163,7 +2220,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->pcrPid = INVALID_PID; this->scrambled_npids = 0; this->videoPid = INVALID_PID; - this->audioPid = INVALID_PID; + this->audio_tracks_count = 0; this->rate = 16000; /* FIXME */ @@ -2177,7 +2234,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, /* DVBSUB */ this->spu_pid = INVALID_PID; - this->no_spu_langs = 0; + this->spu_langs_count = 0; this->current_spu_channel = this->stream->spu_channel; /* dvb */ @@ -2190,19 +2247,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, * ts demuxer class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "MPEG Transport Stream demuxer"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "MPEG_TS"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "ts m2t trp"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c new file mode 100644 index 000000000..2e4808b9c --- /dev/null +++ b/src/demuxers/demux_tta.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2006 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * True Audio demuxer by Diego Pettenò <flameeyes@gentoo.org> + * Inspired by tta libavformat demuxer by Alex Beregszaszi + * + * $Id: demux_tta.c,v 1.4 2007/03/29 16:46:23 dgp85 Exp $ + */ + +#define LOG_MODULE "demux_tta" +#define LOG_VERBOSE + +#include "xine_internal.h" +#include "xineutils.h" +#include "demux.h" +#include "buffer.h" +#include "bswap.h" +#include "group_audio.h" + +typedef struct { + demux_plugin_t demux_plugin; + + xine_stream_t *stream; + fifo_buffer_t *video_fifo; + fifo_buffer_t *audio_fifo; + input_plugin_t *input; + + uint32_t *seektable; + uint32_t totalframes; + uint32_t currentframe; + + int status; + + union { + struct tta_header { + uint32_t signature; /* TTA1 */ + uint16_t flags; /* Skipped */ + uint16_t channels; + uint16_t bits_per_sample; + uint32_t samplerate; + uint32_t data_length; + uint32_t crc32; + } __attribute__((__packed__)) tta; + uint8_t buffer[22]; /* This is the size of the header */ + } header; +} demux_tta_t; + +typedef struct { + demux_class_t demux_class; +} demux_tta_class_t; + +#define FOURCC_32(a, b, c, d) (d + (c<<8) + (b<<16) + (a<<24)) + +static int open_tta_file(demux_tta_t *this) { + uint8_t peek[4]; + uint32_t framelen; + + if (_x_demux_read_header(this->input, peek, 4) != 4) + return 0; + + if ( BE_32(peek) != FOURCC_32('T', 'T', 'A', '1') ) + return 0; + + if ( this->input->read(this->input, this->header.buffer, sizeof(this->header)) != sizeof(this->header) ) + return 0; + + framelen = 1.04489795918367346939 * le2me_32(this->header.tta.samplerate); + this->totalframes = le2me_32(this->header.tta.data_length) / framelen + ((le2me_32(this->header.tta.data_length) % framelen) ? 1 : 0); + this->currentframe = 0; + + if(this->totalframes >= UINT_MAX/sizeof(uint32_t)) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, _("demux_tta: total frames count too high\n")); + return 0; + } + + this->seektable = xine_xmalloc(sizeof(uint32_t)*this->totalframes); + this->input->read(this->input, this->seektable, sizeof(uint32_t)*this->totalframes); + + /* Skip the CRC32 */ + this->input->seek(this->input, 4, SEEK_CUR); + + return 1; +} + +static int demux_tta_send_chunk(demux_plugin_t *this_gen) { + demux_tta_t *this = (demux_tta_t *) this_gen; + uint32_t bytes_to_read; + + if ( this->currentframe > this->totalframes ) { + this->status = DEMUX_FINISHED; + return this->status; + } + + bytes_to_read = le2me_32(this->seektable[this->currentframe]); + + while(bytes_to_read) { + off_t bytes_read = 0; + buf_element_t *buf = NULL; + + /* Get a buffer */ + buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); + buf->type = BUF_AUDIO_TTA; + buf->pts = 0; + buf->extra_info->total_time = this->totalframes; + buf->decoder_flags = 0; + + /* Set normalised position */ + buf->extra_info->input_normpos = + (int) ((double) this->currentframe * 65535 / this->totalframes); + + /* Set time */ + /* buf->extra_info->input_time = this->current_sample / this->samplerate; */ + + bytes_read = this->input->read(this->input, buf->content, ( bytes_to_read > buf->max_size ) ? buf->max_size : bytes_to_read); + + buf->size = bytes_read; + + bytes_to_read -= bytes_read; + + if ( bytes_to_read <= 0 ) + buf->decoder_flags |= BUF_FLAG_FRAME_END; + + this->audio_fifo->put(this->audio_fifo, buf); + } + + this->currentframe++; + + return this->status; +} + +static void demux_tta_send_headers(demux_plugin_t *this_gen) { + demux_tta_t *this = (demux_tta_t *) this_gen; + buf_element_t *buf; + + this->audio_fifo = this->stream->audio_fifo; + + this->status = DEMUX_OK; + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, + le2me_16(this->header.tta.channels)); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, + le2me_32(this->header.tta.samplerate)); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, + le2me_16(this->header.tta.bits_per_sample)); + + /* send start buffers */ + _x_demux_control_start(this->stream); + + /* send init info to decoders */ + if (this->audio_fifo) { + xine_waveformatex wave; + + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_TTA; + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + buf->decoder_info[0] = 0; + buf->decoder_info[1] = le2me_32(this->header.tta.samplerate); + buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample); + buf->decoder_info[3] = le2me_16(this->header.tta.channels); + + buf->size = sizeof(xine_waveformatex) + sizeof(this->header) + sizeof(uint32_t)*this->totalframes; + memcpy(buf->content+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header)); + memcpy(buf->content+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes); + + wave.cbSize = buf->size - sizeof(xine_waveformatex); + memcpy(buf->content, &wave, sizeof(wave)); + + this->audio_fifo->put (this->audio_fifo, buf); + } +} + +static int demux_tta_seek (demux_plugin_t *this_gen, + off_t start_pos, int start_time, int playing) { + demux_tta_t *this = (demux_tta_t *) this_gen; + + /* if thread is not running, initialize demuxer */ + if( !playing ) { + + /* send new pts */ + _x_demux_control_newpts(this->stream, 0, 0); + + this->status = DEMUX_OK; + } + + return this->status; +} + +static void demux_tta_dispose (demux_plugin_t *this_gen) { + demux_tta_t *this = (demux_tta_t *) this_gen; + + free(this); +} + +static int demux_tta_get_status (demux_plugin_t *this_gen) { + demux_tta_t *this = (demux_tta_t *) this_gen; + + return this->status; +} + +static int demux_tta_get_stream_length (demux_plugin_t *this_gen) { +// demux_tta_t *this = (demux_tta_t *) this_gen; + + return 0; +} + +static uint32_t demux_tta_get_capabilities(demux_plugin_t *this_gen) { + return DEMUX_CAP_NOCAP; +} + +static int demux_tta_get_optional_data(demux_plugin_t *this_gen, + void *data, int data_type) { + return DEMUX_OPTIONAL_UNSUPPORTED; +} + +static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, + input_plugin_t *input) { + + demux_tta_t *this; + + this = xine_xmalloc (sizeof (demux_tta_t)); + this->stream = stream; + this->input = input; + + this->demux_plugin.send_headers = demux_tta_send_headers; + this->demux_plugin.send_chunk = demux_tta_send_chunk; + this->demux_plugin.seek = demux_tta_seek; + this->demux_plugin.dispose = demux_tta_dispose; + this->demux_plugin.get_status = demux_tta_get_status; + this->demux_plugin.get_stream_length = demux_tta_get_stream_length; + this->demux_plugin.get_capabilities = demux_tta_get_capabilities; + this->demux_plugin.get_optional_data = demux_tta_get_optional_data; + this->demux_plugin.demux_class = class_gen; + + this->status = DEMUX_FINISHED; + + this->seektable = NULL; + + switch (stream->content_detection_method) { + + case METHOD_BY_EXTENSION: { + const char *extensions, *mrl; + + mrl = input->get_mrl (input); + extensions = class_gen->get_extensions (class_gen); + + if (!_x_demux_check_extension (mrl, extensions)) { + free (this); + return NULL; + } + } + /* Falling through is intended */ + + case METHOD_BY_CONTENT: + case METHOD_EXPLICIT: + if (!open_tta_file(this)) { + free (this); + return NULL; + } + break; + + default: + free (this); + return NULL; + } + + return &this->demux_plugin; +} + +static const char *get_description (demux_class_t *this_gen) { + return "True Audio demux plugin"; +} + +static const char *get_identifier (demux_class_t *this_gen) { + return "True Audio"; +} + +static const char *get_extensions (demux_class_t *this_gen) { + return "tta"; +} + +static const char *get_mimetypes (demux_class_t *this_gen) { + return NULL; +} + +static void class_dispose (demux_class_t *this_gen) { + demux_tta_class_t *this = (demux_tta_class_t *) this_gen; + + free (this); +} + +void *demux_tta_init_plugin (xine_t *xine, void *data) { + demux_tta_class_t *this; + + this = xine_xmalloc (sizeof (demux_tta_class_t)); + + this->demux_class.open_plugin = open_plugin; + this->demux_class.get_description = get_description; + this->demux_class.get_identifier = get_identifier; + this->demux_class.get_mimetypes = get_mimetypes; + this->demux_class.get_extensions = get_extensions; + this->demux_class.dispose = class_dispose; + + return this; +} diff --git a/src/demuxers/demux_vmd.c b/src/demuxers/demux_vmd.c index fb7174031..e2b68fbb1 100644 --- a/src/demuxers/demux_vmd.c +++ b/src/demuxers/demux_vmd.c @@ -28,7 +28,7 @@ * checking the first 2 bytes, which are 0x2E 0x03 in a Sierra VMD file. * There is a 1/65536 chance of a false positive using this method. * - * $Id: demux_vmd.c,v 1.3 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_vmd.c,v 1.4 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -442,7 +442,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -472,19 +472,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Sierra VMD file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "VMD"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "vmd"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_voc.c b/src/demuxers/demux_voc.c index cfd67a9e6..1c1675b92 100644 --- a/src/demuxers/demux_voc.c +++ b/src/demuxers/demux_voc.c @@ -25,7 +25,7 @@ * It will only play that block if it is PCM data. More variations will be * supported as they are encountered. * - * $Id: demux_voc.c,v 1.40 2005/12/24 00:08:42 tmmm Exp $ + * $Id: demux_voc.c,v 1.41 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -317,7 +317,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -347,19 +347,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "VOC file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "VOC"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "voc"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_vox.c b/src/demuxers/demux_vox.c index 53e8d2399..c772e4978 100644 --- a/src/demuxers/demux_vox.c +++ b/src/demuxers/demux_vox.c @@ -22,7 +22,7 @@ * VOX Demuxer by Mike Melanson (melanson@pcisys.net) * This a demuxer for .vox files containing raw Dialogic ADPCM data. * - * $Id: demux_vox.c,v 1.13 2004/06/13 21:28:54 miguelfreitas Exp $ + * $Id: demux_vox.c,v 1.14 2007/01/19 00:26:40 dgp85 Exp $ * */ @@ -192,7 +192,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str case METHOD_BY_CONTENT: case METHOD_EXPLICIT: case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -225,19 +225,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Dialogic VOX file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "VOX"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "vox"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_vqa.c b/src/demuxers/demux_vqa.c index 41209ce75..56fbde7d1 100644 --- a/src/demuxers/demux_vqa.c +++ b/src/demuxers/demux_vqa.c @@ -29,7 +29,7 @@ * block needs information from the previous audio block in order to be * decoded, thus making random seeking difficult. * - * $Id: demux_vqa.c,v 1.41 2004/06/13 21:28:55 miguelfreitas Exp $ + * $Id: demux_vqa.c,v 1.42 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -355,7 +355,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -385,19 +385,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Westwood Studios VQA file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "VQA"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "vqa"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index e23f43aa5..1e46d8526 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -22,7 +22,7 @@ * MS WAV File Demuxer by Mike Melanson (melanson@pcisys.net) * based on WAV specs that are available far and wide * - * $Id: demux_wav.c,v 1.63 2005/06/04 20:29:16 jstembridge Exp $ + * $Id: demux_wav.c,v 1.65 2007/03/17 20:57:04 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -86,18 +86,7 @@ static int open_wav_file(demux_wav_t *this) { if (_x_demux_read_header(this->input, signature, WAV_SIGNATURE_SIZE) != WAV_SIGNATURE_SIZE) return 0; - if ((signature[0] != 'R') || - (signature[1] != 'I') || - (signature[2] != 'F') || - (signature[3] != 'F') || - (signature[8] != 'W') || - (signature[9] != 'A') || - (signature[10] != 'V') || - (signature[11] != 'E') || - (signature[12] != 'f') || - (signature[13] != 'm') || - (signature[14] != 't') || - (signature[15] != ' ')) + if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVEfmt ", 8) ) return 0; /* file is qualified; skip over the header bytes in the stream */ @@ -108,7 +97,7 @@ static int open_wav_file(demux_wav_t *this) { (unsigned char *)&this->wave_size, 4) != 4) return 0; this->wave_size = le2me_32(this->wave_size); - this->wave = (xine_waveformatex *) malloc( this->wave_size ); + this->wave = xine_xmalloc( this->wave_size ); if (this->input->read(this->input, (void *)this->wave, this->wave_size) != this->wave_size) { @@ -365,7 +354,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -404,19 +393,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "WAV file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "WAV"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "wav"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return "audio/x-wav: wav: WAV audio;" "audio/wav: wav: WAV audio;" "audio/x-pn-wav: wav: WAV audio;" diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c index a41637ba1..fa1cfb17d 100644 --- a/src/demuxers/demux_wc3movie.c +++ b/src/demuxers/demux_wc3movie.c @@ -24,7 +24,7 @@ * For more information on the MVE file format, visit: * http://www.pcisys.net/~melanson/codecs/ * - * $Id: demux_wc3movie.c,v 1.53 2005/07/26 22:10:40 tmattern Exp $ + * $Id: demux_wc3movie.c,v 1.54 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -688,7 +688,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -718,19 +718,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "Wing Commander III Movie (MVE) demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "WC3 Movie"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "mve"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_yuv4mpeg2.c b/src/demuxers/demux_yuv4mpeg2.c index 126370453..4e0bb1069 100644 --- a/src/demuxers/demux_yuv4mpeg2.c +++ b/src/demuxers/demux_yuv4mpeg2.c @@ -24,7 +24,7 @@ * tools, visit: * http://mjpeg.sourceforge.net/ * - * $Id: demux_yuv4mpeg2.c,v 1.43 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_yuv4mpeg2.c,v 1.44 2007/01/19 00:26:40 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -424,7 +424,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *extensions, *mrl; + const char *extensions, *mrl; mrl = input->get_mrl (input); extensions = class_gen->get_extensions (class_gen); @@ -454,19 +454,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str return &this->demux_plugin; } -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "YUV4MPEG2 file demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "YUV4MPEG2"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return "y4m"; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/demux_yuv_frames.c b/src/demuxers/demux_yuv_frames.c index 06115a4d3..3866f0437 100644 --- a/src/demuxers/demux_yuv_frames.c +++ b/src/demuxers/demux_yuv_frames.c @@ -20,7 +20,7 @@ */ /* - * $Id: demux_yuv_frames.c,v 1.22 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: demux_yuv_frames.c,v 1.24 2007/01/19 01:05:24 dgp85 Exp $ * * dummy demultiplexer for raw yuv frames (delivered by v4l) */ @@ -185,9 +185,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, break; case METHOD_BY_EXTENSION: { - char *mrl; - - mrl = input->get_mrl (input); + const char *const mrl = input->get_mrl (input); if (strncmp (mrl, "v4l:/", 5)) return NULL; @@ -232,19 +230,19 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, * demuxer class */ -static char *get_description (demux_class_t *this_gen) { +static const char *get_description (demux_class_t *this_gen) { return "YUV frames dummy demux plugin"; } -static char *get_identifier (demux_class_t *this_gen) { +static const char *get_identifier (demux_class_t *this_gen) { return "YUV_FRAMES"; } -static char *get_extensions (demux_class_t *this_gen) { +static const char *get_extensions (demux_class_t *this_gen) { return NULL; } -static char *get_mimetypes (demux_class_t *this_gen) { +static const char *get_mimetypes (demux_class_t *this_gen) { return NULL; } diff --git a/src/demuxers/group_audio.c b/src/demuxers/group_audio.c index 7139ee5b9..b8f0e1ed4 100644 --- a/src/demuxers/group_audio.c +++ b/src/demuxers/group_audio.c @@ -19,7 +19,7 @@ * * This file contains plugin entries for several demuxers used in games * - * $Id: group_audio.c,v 1.24 2006/07/10 22:08:13 dgp85 Exp $ + * $Id: group_audio.c,v 1.26 2007/03/03 02:06:09 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -36,7 +36,7 @@ */ static const demuxer_info_t demux_info_aac = { - 0 /* priority */ + -1 /* priority */ }; static const demuxer_info_t demux_info_ac3 = { @@ -87,6 +87,10 @@ static const demuxer_info_t demux_info_snd = { 10 /* priority */ }; +static const demuxer_info_t demux_info_tta = { + 10 /* priority */ +}; + static const demuxer_info_t demux_info_voc = { 10 /* priority */ }; @@ -120,6 +124,7 @@ const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_DEMUX, 26, "realaudio", XINE_VERSION_CODE, &demux_info_realaudio, demux_realaudio_init_plugin }, { PLUGIN_DEMUX, 26, "shn", XINE_VERSION_CODE, &demux_info_shn, demux_shn_init_plugin }, { PLUGIN_DEMUX, 26, "snd", XINE_VERSION_CODE, &demux_info_snd, demux_snd_init_plugin }, + { PLUGIN_DEMUX, 26, "tta", XINE_VERSION_CODE, &demux_info_tta, demux_tta_init_plugin }, { PLUGIN_DEMUX, 26, "voc", XINE_VERSION_CODE, &demux_info_voc, demux_voc_init_plugin }, { PLUGIN_DEMUX, 26, "vox", XINE_VERSION_CODE, &demux_info_vox, demux_vox_init_plugin }, { PLUGIN_DEMUX, 26, "wav", XINE_VERSION_CODE, &demux_info_wav, demux_wav_init_plugin }, diff --git a/src/demuxers/group_audio.h b/src/demuxers/group_audio.h index fba22cffa..7f1fccc5e 100644 --- a/src/demuxers/group_audio.h +++ b/src/demuxers/group_audio.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: group_audio.h,v 1.8 2005/05/29 19:20:48 jstembridge Exp $ + * $Id: group_audio.h,v 1.9 2006/12/26 16:59:55 dgp85 Exp $ */ #ifndef HAVE_GROUP_AUDIO_H @@ -38,6 +38,7 @@ void *demux_nsf_init_plugin (xine_t *xine, void *data); void *demux_realaudio_init_plugin (xine_t *xine, void *data); void *demux_shn_init_plugin (xine_t *xine, void *data); void *demux_snd_init_plugin (xine_t *xine, void *data); +void *demux_tta_init_plugin (xine_t *xine, void *data); void *demux_voc_init_plugin (xine_t *xine, void *data); void *demux_vox_init_plugin (xine_t *xine, void *data); void *demux_wav_init_plugin (xine_t *xine, void *data); diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c index ffa022a59..b707166b6 100644 --- a/src/demuxers/id3.c +++ b/src/demuxers/id3.c @@ -29,7 +29,7 @@ * * ID3v2 specs: http://www.id3.org/ * - * $Id: id3.c,v 1.12 2006/04/05 22:12:18 valtri Exp $ + * $Id: id3.c,v 1.13 2007/03/03 00:58:52 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -878,3 +878,33 @@ int id3v24_parse_tag(input_plugin_t *input, return 0; } } + +int id3v2_parse_tag(input_plugin_t *input, + xine_stream_t *stream, + int8_t *mp3_frame_header) { + _x_assert(mp3_frame_header[0] == 'I' && mp3_frame_header[1] == 'D' && mp3_frame_header[2] == '3'); + + int result = 0; + + switch(mp3_frame_header[3]) { + case 2: + xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.2 tag\n"); + result = id3v22_parse_tag(input, stream, mp3_frame_header); + break; + + case 3: + xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.3 tag\n"); + result = id3v23_parse_tag(input, stream, mp3_frame_header); + break; + + case 4: + xprintf(stream->xine, XINE_VERBOSITY_LOG, "ID3V2.3 tag\n"); + result = id3v24_parse_tag(input, stream, mp3_frame_header); + break; + + default: + xprintf(stream->xine, XINE_VERBOSITY_LOG, "Unknown ID3v2 version: 0x%02x.\n", mp3_frame_header[3]); + } + + return result; +} diff --git a/src/demuxers/id3.h b/src/demuxers/id3.h index 2d8970ea7..9d08f6817 100644 --- a/src/demuxers/id3.h +++ b/src/demuxers/id3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2003 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -21,7 +21,7 @@ * * Supported versions: v1, v1.1, v2.2, v2.3, v2.4 * - * $Id: id3.h,v 1.4 2005/09/15 18:45:15 tmattern Exp $ + * $Id: id3.h,v 1.6 2007/03/03 01:41:16 dgp85 Exp $ */ #ifndef ID3_H @@ -38,6 +38,7 @@ #define ID3V24_TAG FOURCC_TAG('I', 'D', '3', 4) /* id3 v2.4 header tag */ #define ID3V24_FOOTER_TAG FOURCC_TAG('3', 'D', 'I', 0) /* id3 v2.4 footer tag */ + /* * ID3 v2.2 */ @@ -164,4 +165,24 @@ int id3v24_parse_tag(input_plugin_t *input, xine_stream_t *stream, int8_t *mp3_frame_header); +/* Generic function that switch between the three above */ +int id3v2_parse_tag(input_plugin_t *input, + xine_stream_t *stream, + int8_t *mp3_frame_header); + +static inline int id3v2_istag(uint8_t *ptr) { + return + (ptr[0] == 'I') && + (ptr[1] == 'D') && + (ptr[2] == '3'); +} + +static inline uint32_t id3v2_tagsize(uint8_t *ptr) { + return + ((uint32_t)ptr[0] << 21) + + ((uint32_t)ptr[1] << 14) + + ((uint32_t)ptr[2] << 7) + + (uint32_t)ptr[3]; +} + #endif /* ID3_H */ diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h index 926d6d0a6..3bfdbdc0c 100644 --- a/src/demuxers/matroska.h +++ b/src/demuxers/matroska.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2003 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: matroska.h,v 1.10 2006/11/14 07:09:46 molivier Exp $ + * $Id: matroska.h,v 1.11 2007/01/07 12:33:50 molivier Exp $ * */ #ifndef MATROSKA_H @@ -224,6 +224,7 @@ struct matroska_track_s { uint8_t *codec_private; uint32_t codec_private_len; int default_flag; + uint32_t compress_algo; uint32_t buf_type; fifo_buffer_t *fifo; @@ -305,4 +306,12 @@ struct matroska_track_s { #define MATROSKA_TRACK_SUBTITLE 0x11 #define MATROSKA_TRACK_CONTROL 0x20 +/* compression algorithms */ +#define MATROSKA_COMPRESS_ZLIB 0x00 +#define MATROSKA_COMPRESS_BZLIB 0x01 +#define MATROSKA_COMPRESS_LZO1X 0x02 +#define MATROSKA_COMPRESS_HEADER_STRIP 0x03 +#define MATROSKA_COMPRESS_UNKNOWN 0xFFFFFFFE /* Xine internal type */ +#define MATROSKA_COMPRESS_NONE 0xFFFFFFFF /* Xine internal type */ + #endif /* MATROSKA_H */ diff --git a/src/input/.cvsignore b/src/dxr3/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/.cvsignore +++ b/src/dxr3/.hgignore diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index f364a375e..8bf9c9427 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -22,7 +22,7 @@ endif lib_LTLIBRARIES = $(dxr3_modules) xineplug_decode_dxr3_video_la_SOURCES = dxr3_decode_video.c -xineplug_decode_dxr3_video_la_LIBADD = $(XINE_LIB) +xineplug_decode_dxr3_video_la_LIBADD = $(XINE_LIB) xineplug_decode_dxr3_video_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_decode_dxr3_video_la_LDFLAGS = -avoid-version -module @@ -44,7 +44,7 @@ xineplug_vo_out_dxr3_la_SOURCES = \ dxr3_scr.c \ video_out_dxr3.c -xineplug_vo_out_dxr3_la_LIBADD = $(link_fame) $(link_rte) $(link_x_libs) $(XINE_LIB) +xineplug_vo_out_dxr3_la_LIBADD = $(link_fame) $(link_rte) $(link_x_libs) $(XINE_LIB) $(DYNAMIC_LD_LIBS) -lm xineplug_vo_out_dxr3_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c index 6fe2ff397..cba47aad4 100644 --- a/src/dxr3/dxr3_mpeg_encoders.c +++ b/src/dxr3/dxr3_mpeg_encoders.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_mpeg_encoders.c,v 1.24 2005/11/28 12:24:57 valtri Exp $ + * $Id: dxr3_mpeg_encoders.c,v 1.25 2007/03/10 17:25:13 dgp85 Exp $ */ /* mpeg encoders for the dxr3 video out plugin. @@ -44,6 +44,7 @@ #include <fcntl.h> #include <errno.h> #include <math.h> +#include <unistd.h> #define LOG_MODULE "dxr3_mpeg_encoder" /* #define LOG_VERBOSE */ diff --git a/src/input/libdvdnav/.cvsignore b/src/input/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/libdvdnav/.cvsignore +++ b/src/input/.hgignore diff --git a/src/input/Makefile.am b/src/input/Makefile.am index c0924f829..68adf84be 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -77,17 +77,17 @@ xineplug_inp_file_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_file_la_LDFLAGS = -avoid-version -module xineplug_inp_dvd_la_SOURCES = input_dvd.c media_helper.c -xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(THREAD_LIBS) +xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) xineplug_inp_dvd_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_dvd_la_LDFLAGS = -avoid-version -module xineplug_inp_net_la_SOURCES = input_net.c net_buf_ctrl.c -xineplug_inp_net_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_net_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) xineplug_inp_net_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_net_la_LDFLAGS = -avoid-version -module xineplug_inp_mms_la_SOURCES = input_mms.c net_buf_ctrl.c mms.c mmsh.c http_helper.c ../demuxers/asfheader.c -xineplug_inp_mms_la_LIBADD = $(XINE_LIB) @LIBICONV@ $(THREAD_LIBS) +xineplug_inp_mms_la_LIBADD = $(XINE_LIB) @LIBICONV@ $(PTHREAD_LIBS) xineplug_inp_mms_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_mms_la_LDFLAGS = -avoid-version -module @@ -97,32 +97,32 @@ xineplug_inp_vcdo_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_vcdo_la_LDFLAGS = -avoid-version -module xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c net_buf_ctrl.c -xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_inp_stdin_fifo_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_stdin_fifo_la_LDFLAGS = -avoid-version -module xineplug_inp_rtp_la_SOURCES = input_rtp.c net_buf_ctrl.c -xineplug_inp_rtp_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_rtp_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) xineplug_inp_rtp_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_rtp_la_LDFLAGS = -avoid-version -module xineplug_inp_http_la_SOURCES = input_http.c net_buf_ctrl.c http_helper.c -xineplug_inp_http_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_http_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) xineplug_inp_http_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_http_la_LDFLAGS = -avoid-version -module xineplug_inp_pnm_la_SOURCES = input_pnm.c net_buf_ctrl.c pnm.c -xineplug_inp_pnm_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_pnm_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_inp_pnm_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_pnm_la_LDFLAGS = -avoid-version -module xineplug_inp_dvb_la_SOURCES = input_dvb.c net_buf_ctrl.c -xineplug_inp_dvb_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_dvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_inp_dvb_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_dvb_la_LDFLAGS = -avoid-version -module xineplug_inp_rtsp_la_SOURCES = input_rtsp.c net_buf_ctrl.c -xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) libreal/libreal.la librtsp/librtsp.la +xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) libreal/libreal.la librtsp/librtsp.la xineplug_inp_rtsp_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_rtsp_la_LDFLAGS = -avoid-version -module @@ -137,7 +137,7 @@ xineplug_inp_v4l_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_v4l_la_LDFLAGS = -avoid-version -module xineplug_inp_gnome_vfs_la_SOURCES = input_gnome_vfs.c net_buf_ctrl.c -xineplug_inp_gnome_vfs_la_LIBADD = $(GNOME_VFS_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_inp_gnome_vfs_la_LIBADD = $(GNOME_VFS_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_inp_gnome_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_gnome_vfs_la_LDFLAGS = -avoid-version -module @@ -147,10 +147,10 @@ xineplug_inp_smb_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_smb_la_LDFLAGS = -avoid-version -module xineplug_inp_pvr_la_SOURCES = input_pvr.c -xineplug_inp_pvr_la_LIBADD = $(XINE_LIB) +xineplug_inp_pvr_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_inp_pvr_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_inp_pvr_la_LDFLAGS = -avoid-version -module -include_HEADERS = input_plugin.h +xineinclude_HEADERS = input_plugin.h noinst_HEADERS = net_buf_ctrl.h mms.h mmsh.h pnm.h media_helper.h videodev2.h http_helper.h diff --git a/src/input/dvb/.cvsignore b/src/input/dvb/.hgignore index 282522db0..282522db0 100644 --- a/src/input/dvb/.cvsignore +++ b/src/input/dvb/.hgignore diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c index f51ffc646..d21c8e4db 100644 --- a/src/input/input_cdda.c +++ b/src/input/input_cdda.c @@ -20,7 +20,7 @@ * Compact Disc Digital Audio (CDDA) Input Plugin * by Mike Melanson (melanson@pcisys.net) * - * $Id: input_cdda.c,v 1.90 2006/08/11 21:40:02 dsalt Exp $ + * $Id: input_cdda.c,v 1.94 2007/03/10 00:48:59 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -86,6 +86,7 @@ #define CD_FRAMES_PER_SECOND 75 #define CD_RAW_FRAME_SIZE 2352 #define CD_LEADOUT_TRACK 0xAA +#define CD_BLOCK_OFFSET 150 typedef struct _cdrom_toc_entry { int track_mode; @@ -613,14 +614,20 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f return 0; } -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) #include <sys/cdio.h> +#include <sys/scsiio.h> static int read_cdrom_toc(int fd, cdrom_toc *toc) { struct ioc_toc_header tochdr; +#if defined(__FreeBSD__) struct ioc_read_toc_single_entry tocentry; +#elif defined(__NetBSD__) + struct ioc_read_toc_entry tocentry; + struct cd_toc_entry data; +#endif int i; /* fetch the table of contents */ @@ -646,13 +653,26 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { memset(&tocentry, 0, sizeof(tocentry)); +#if defined(__FreeBSD__) tocentry.track = i; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) { perror("CDIOREADTOCENTRY"); return -1; } +#elif defined(__NetBSD__) + memset(&data, 0, sizeof(data)); + tocentry.data_len = sizeof(data); + tocentry.data = &data; + tocentry.starting_track = i; + tocentry.address_format = CD_MSF_FORMAT; + if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { + perror("CDIOREADTOCENTRYS"); + return -1; + } +#endif +#if defined(__FreeBSD__) toc->toc_entries[i-1].track_mode = (tocentry.entry.control & 0x04) ? 1 : 0; toc->toc_entries[i-1].first_frame_minute = tocentry.entry.addr.msf.minute; toc->toc_entries[i-1].first_frame_second = tocentry.entry.addr.msf.second; @@ -661,18 +681,41 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.entry.addr.msf.frame; +#elif defined(__NetBSD__) + toc->toc_entries[i-1].track_mode = (tocentry.data->control & 0x04) ? 1 : 0; + toc->toc_entries[i-1].first_frame_minute = tocentry.data->addr.msf.minute; + toc->toc_entries[i-1].first_frame_second = tocentry.data->addr.msf.second; + toc->toc_entries[i-1].first_frame_frame = tocentry.data->addr.msf.frame; + toc->toc_entries[i-1].first_frame = + (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + + (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) + + tocentry.data->addr.msf.frame - CD_BLOCK_OFFSET; +#endif } /* fetch the leadout as well */ memset(&tocentry, 0, sizeof(tocentry)); +#if defined(__FreeBSD__) tocentry.track = CD_LEADOUT_TRACK; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) { perror("CDIOREADTOCENTRY"); return -1; } +#elif defined(__NetBSD__) + memset(&data, 0, sizeof(data)); + tocentry.data_len = sizeof(data); + tocentry.data = &data; + tocentry.starting_track = CD_LEADOUT_TRACK; + tocentry.address_format = CD_MSF_FORMAT; + if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { + perror("CDIOREADTOCENTRYS"); + return -1; + } +#endif +#if defined(__FreeBSD__) toc->leadout_track.track_mode = (tocentry.entry.control & 0x04) ? 1 : 0; toc->leadout_track.first_frame_minute = tocentry.entry.addr.msf.minute; toc->leadout_track.first_frame_second = tocentry.entry.addr.msf.second; @@ -681,6 +724,16 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) { (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.entry.addr.msf.frame; +#elif defined(__NetBSD__) + toc->leadout_track.track_mode = (tocentry.data->control & 0x04) ? 1 : 0; + toc->leadout_track.first_frame_minute = tocentry.data->addr.msf.minute; + toc->leadout_track.first_frame_second = tocentry.data->addr.msf.second; + toc->leadout_track.first_frame_frame = tocentry.data->addr.msf.frame; + toc->leadout_track.first_frame = + (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + + (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) + + tocentry.data->addr.msf.frame - CD_BLOCK_OFFSET; +#endif return 0; } @@ -689,12 +742,12 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f unsigned char *data) { int fd = this_gen->fd; -#if __FreeBSD_version < 501106 - struct ioc_read_audio cdda; -#endif while( num_frames ) { +#if defined(__FreeBSD__) #if __FreeBSD_version < 501106 + struct ioc_read_audio cdda; + cdda.address_format = CD_MSF_FORMAT; cdda.address.msf.minute = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; cdda.address.msf.second = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; @@ -712,6 +765,33 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f perror("CDIOCREADAUDIO"); return -1; } +#elif defined(__NetBSD__) + scsireq_t req; + int nblocks = 1; + + memset(&req, 0, sizeof(req)); + req.cmd[0] = 0xbe; + req.cmd[1] = 0; + req.cmd[2] = (frame >> 24) & 0xff; + req.cmd[3] = (frame >> 16) & 0xff; + req.cmd[4] = (frame >> 8) & 0xff; + req.cmd[5] = (frame >> 0) & 0xff; + req.cmd[6] = (nblocks >> 16) & 0xff; + req.cmd[7] = (nblocks >> 8) & 0xff; + req.cmd[8] = (nblocks >> 0) & 0xff; + req.cmd[9] = 0x78; + req.cmdlen = 10; + + req.datalen = nblocks * CD_RAW_FRAME_SIZE; + req.databuf = data; + req.timeout = 10000; + req.flags = SCCMD_READ; + + if(ioctl(fd, SCIOCCOMMAND, &req) < 0) { + perror("SCIOCCOMMAND"); + return -1; + } +#endif data += CD_RAW_FRAME_SIZE; frame++; @@ -2270,7 +2350,7 @@ static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) { return CD_RAW_FRAME_SIZE; } -static char* cdda_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* cdda_plugin_get_mrl (input_plugin_t *this_gen) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; return this->mrl; @@ -2623,7 +2703,7 @@ static const char *cdda_class_get_identifier (input_class_t *this_gen) { return "cdda"; } -static char *cdda_class_get_description (input_class_t *this_gen) { +static const char *cdda_class_get_description (input_class_t *this_gen) { return _("CD Digital Audio (aka. CDDA)"); } @@ -2675,8 +2755,8 @@ static void *init_plugin (xine_t *xine, void *data) { this->mrls_allocated_entries = 0; this->ip = NULL; - this->cdda_device = config->register_string(config, "media.audio_cd.device", - DEFAULT_CDDA_DEVICE, + this->cdda_device = config->register_filename(config, "media.audio_cd.device", + DEFAULT_CDDA_DEVICE, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for CD audio"), _("The path to the device, usually a " "CD or DVD drive, which you intend to use " @@ -2704,8 +2784,8 @@ static void *init_plugin (xine_t *xine, void *data) { "title and track information from."), XINE_CONFIG_SECURITY, port_changed_cb, (void *) this); - config->register_string(config, "media.audio_cd.cddb_cachedir", - (_cdda_cddb_get_default_location()), + config->register_filename(config, "media.audio_cd.cddb_cachedir", + (_cdda_cddb_get_default_location()), XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("CDDB cache directory"), _("The replies from the CDDB server will be " "cached in this directory.\nThis setting is security critical, because files " "with uncontrollable names will be created in this directory. Be sure to use " diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 8d06cb61e..39507ac15 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -2651,7 +2651,7 @@ static void dvb_plugin_dispose (input_plugin_t *this_gen) { free (this); } -static char* dvb_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* dvb_plugin_get_mrl (input_plugin_t *this_gen) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; return this->mrl; @@ -3085,7 +3085,7 @@ static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen, * dvb input plugin class stuff */ -static char *dvb_class_get_description (input_class_t *this_gen) { +static const char *dvb_class_get_description (input_class_t *this_gen) { return _("DVB (Digital TV) input plugin"); } @@ -3183,15 +3183,14 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen, } if (lastchannel_enable.num_value){ - if (lastchannel.num_value>-1) /* plugin has been used before - channel is valid */ - sprintf(foobuffer,"dvb://%s",channels[lastchannel.num_value].name); - else /* set a reasonable default - the first channel */ - sprintf(foobuffer,"dvb://%s",channels[lastchannel_enable.num_value].name); - if(class->autoplaylist[0]) - free(class->autoplaylist[0]); - class->autoplaylist[0]=xine_xmalloc(128); - _x_assert(class->autoplaylist[0] != NULL); - class->autoplaylist[0]=strdup(foobuffer); + if (lastchannel.num_value > -1 && lastchannel.num_value < num_channels) + /* plugin has been used before - channel is valid */ + sprintf (foobuffer, "dvb://%s", channels[lastchannel.num_value].name); + else + /* set a reasonable default - the first channel */ + sprintf (foobuffer, "dvb://%s", num_channels ? channels[0].name : "0"); + free(class->autoplaylist[0]); + class->autoplaylist[0]=strdup(foobuffer); } free(tmpbuffer); diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index 26eb67e24..944ae88bd 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_dvd.c,v 1.211 2006/10/29 19:39:39 hadess Exp $ + * $Id: input_dvd.c,v 1.216 2007/02/20 01:04:07 dgp85 Exp $ * */ @@ -930,7 +930,7 @@ static uint32_t dvd_plugin_get_blocksize (input_plugin_t *this_gen) { return DVD_BLOCK_SIZE; } -static char* dvd_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* dvd_plugin_get_mrl (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; trace_print("Called\n"); @@ -1278,7 +1278,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen, if(this && this->stream && this->dvdnav) { if(!(dvdnav_is_domain_vts(this->dvdnav))) { - sprintf(data, "%s", "menu"); + strcpy(data, "menu"); if (channel <= 0) return INPUT_OPTIONAL_SUCCESS; else @@ -1297,11 +1297,11 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen, sprintf(data, " %c%c", lang >> 8, lang & 0xff); /* TODO: provide long version in XINE_META_INFO_FULL_LANG */ else - sprintf(data, " %c%c", '?', '?'); + strcpy(data, " ??"); return INPUT_OPTIONAL_SUCCESS; } else { if (channel == -1) { - sprintf(data, "%s", "none"); + strcpy(data, "none"); return INPUT_OPTIONAL_SUCCESS; } } @@ -1680,7 +1680,7 @@ static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_st return &this->input_plugin; } -static char *dvd_class_get_description (input_class_t *this_gen) { +static const char *dvd_class_get_description (input_class_t *this_gen) { trace_print("Called\n"); return "DVD Navigator"; @@ -1749,9 +1749,9 @@ static void *init_class (xine_t *xine, void *data) { dvd_input_class_t *this; config_values_t *config = xine->config; void *dvdcss; - static char *skip_modes[] = {"skip program", "skip part", "skip title", NULL}; - static char *seek_modes[] = {"seek in program chain", "seek in program", NULL}; - static char *play_single_chapter_modes[] = {"entire dvd", "one chapter", NULL}; + static const char *skip_modes[] = {"skip program", "skip part", "skip title", NULL}; + static const char *seek_modes[] = {"seek in program chain", "seek in program", NULL}; + static const char *play_single_chapter_modes[] = {"entire dvd", "one chapter", NULL}; trace_print("Called\n"); #ifdef INPUT_DEBUG @@ -1779,9 +1779,9 @@ static void *init_class (xine_t *xine, void *data) { this->ip = NULL; - this->dvd_device = config->register_string(config, + this->dvd_device = config->register_filename(config, "media.dvd.device", - DVD_PATH, + DVD_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for DVD playback"), _("The path to the device, usually a " "DVD drive, which you intend to use for playing DVDs."), @@ -1795,12 +1795,13 @@ static void *init_class (xine_t *xine, void *data) { { /* we have found libdvdcss, enable the specific config options */ char *raw_device; - static char *decrypt_modes[] = { "key", "disc", "title", NULL }; + static const char *decrypt_modes[] = { "key", "disc", "title", NULL }; char *css_cache_default, *css_cache; int mode; - raw_device = config->register_string(config, "media.dvd.raw_device", - RDVD_PATH, _("raw device set up for DVD access"), + raw_device = config->register_filename(config, "media.dvd.raw_device", + RDVD_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME, + _("raw device set up for DVD access"), _("If this points to a raw device connected to your " "DVD device, xine will use the raw device for playback. " "This has the advantage of being slightly faster and " @@ -1822,7 +1823,7 @@ static void *init_class (xine_t *xine, void *data) { css_cache_default = (char *)malloc(strlen(xine_get_homedir()) + 10); sprintf(css_cache_default, "%s/.dvdcss/", xine_get_homedir()); - css_cache = config->register_string(config, "media.dvd.css_cache_path", css_cache_default, + css_cache = config->register_filename(config, "media.dvd.css_cache_path", css_cache_default, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("path to the title key cache"), _("Since cracking the copy protection of scrambled DVDs can " "be quite time consuming, libdvdcss will cache the cracked " diff --git a/src/input/input_file.c b/src/input/input_file.c index 93d208c4e..fd2b0e733 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_file.c,v 1.117 2006/10/01 20:14:43 dgp85 Exp $ + * $Id: input_file.c,v 1.122 2007/03/29 19:47:17 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -66,8 +66,8 @@ typedef struct { xine_t *xine; config_values_t *config; - int show_hidden_files; char *origin_path; + int show_hidden_files; int mrls_allocated_entries; xine_mrl_t **mrls; @@ -280,11 +280,6 @@ static off_t file_plugin_get_length (input_plugin_t *this_gen) { } static uint32_t file_plugin_get_blocksize (input_plugin_t *this_gen) { - file_input_plugin_t *this = (file_input_plugin_t *) this_gen; -#if 0 && defined(HAVE_MMAP) - if ( check_mmap_file(this) ) - return this->mmap_len; -#endif return 0; } @@ -299,7 +294,7 @@ static int is_a_dir(char *filepathname) { return (S_ISDIR(pstat.st_mode)); } -static char* file_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* file_plugin_get_mrl (input_plugin_t *this_gen) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; return this->mrl; @@ -659,7 +654,7 @@ static off_t get_file_size(char *filepathname, char *origin) { return pstat.st_size; } -static char *file_class_get_description (input_class_t *this_gen) { +static const char *file_class_get_description (input_class_t *this_gen) { return _("file input plugin"); } @@ -1027,8 +1022,8 @@ static void *init_plugin (xine_t *xine, void *data) { if(getcwd(current_dir, sizeof(current_dir)) == NULL) strcpy(current_dir, "."); - this->origin_path = config->register_string(config, "media.files.origin_path", - current_dir, + this->origin_path = config->register_filename(config, "media.files.origin_path", + current_dir, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("file browsing start location"), _("The browser to select the file to play will " "start at this location."), diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c index 3ada09d19..b9f516931 100644 --- a/src/input/input_gnome_vfs.c +++ b/src/input/input_gnome_vfs.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_gnome_vfs.c,v 1.32 2006/09/08 06:20:37 tmattern Exp $ + * $Id: input_gnome_vfs.c,v 1.34 2007/01/19 01:05:25 dgp85 Exp $ */ @@ -204,7 +204,7 @@ gnomevfs_plugin_get_blocksize (input_plugin_t *this_gen) return 32 * 1024; } -static char* +static const char* gnomevfs_plugin_get_mrl (input_plugin_t *this_gen) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; @@ -212,7 +212,7 @@ gnomevfs_plugin_get_mrl (input_plugin_t *this_gen) return this->mrl; } -static char +static const char *gnomevfs_klass_get_description (input_class_t *this_gen) { return _("gnome-vfs input plugin as shipped with xine"); diff --git a/src/input/input_http.c b/src/input/input_http.c index 0ba143091..3adbc836b 100644 --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -19,7 +19,7 @@ * * input plugin for http network streams * - * $Id: input_http.c,v 1.124 2006/11/30 10:54:18 dgp85 Exp $ + * $Id: input_http.c,v 1.129 2007/03/17 16:47:16 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -335,12 +335,9 @@ static int http_plugin_read_metainf (http_input_plugin_t *this) { /* prepares the event */ radio = _x_meta_info_get(this->stream, XINE_META_INFO_ALBUM); if (radio) { - int len = strlen(radio); - strncpy(data.str, radio, sizeof(data.str)); - strncat(data.str, " - ", sizeof(data.str) - len); - strncat(data.str, songtitle, sizeof(data.str) - len - 3); + snprintf (data.str, sizeof(data.str), "%s - %s", radio, songtitle); } else { - strncpy(data.str, songtitle, sizeof(data.str)); + strncpy(data.str, songtitle, sizeof(data.str)-1); } data.str[sizeof(data.str) - 1] = '\0'; data.str_len = strlen(data.str) + 1; @@ -366,7 +363,7 @@ static off_t http_plugin_read_int (http_input_plugin_t *this, int read_bytes = 0; int nlen; - lprintf("total=%lld\n", total); + lprintf("total=%"PRId64"\n", total); while (total) { nlen = total; if (this->shoutcast_mode && @@ -418,7 +415,7 @@ static off_t http_plugin_read (input_plugin_t *this_gen, else n = nlen; - lprintf ("%lld bytes from preview (which has %lld bytes)\n", n, this->preview_size); + lprintf ("%"PRId64" bytes from preview (which has %"PRId64" bytes)\n", n, this->preview_size); memcpy (buf, &this->preview[this->curpos], n); num_bytes += n; @@ -577,7 +574,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin return this->curpos; } -static char* http_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* http_plugin_get_mrl (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; return this->mrl; @@ -766,13 +763,11 @@ static int http_plugin_open (input_plugin_t *this_gen ) { } snprintf(this->buf + buflen, BUFSIZE - buflen, - "User-Agent: xine/%s\015\012", VERSION); - buflen = strlen(this->buf); - strncat (this->buf, "Accept: */*\015\012", BUFSIZE - buflen); - buflen = strlen(this->buf); - strncat (this->buf, "Icy-MetaData: 1\015\012", BUFSIZE - buflen); - buflen = strlen(this->buf); - strncat (this->buf, "\015\012", BUFSIZE - buflen); + "User-Agent: xine/%s\015\012" + "Accept: */*\015\012" + "Icy-MetaData: 1\015\012" + "\015\012", + VERSION); buflen = strlen(this->buf); if (_x_io_tcp_write (this->stream, this->fh, this->buf, buflen) != buflen) { _x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL); @@ -809,18 +804,20 @@ static int http_plugin_open (input_plugin_t *this_gen ) { if (linenum == 1) { int httpver, httpsub; - char httpstatus[51]; - - if (sscanf(this->buf, "HTTP/%d.%d %d %50[^\015\012]", &httpver, &httpsub, - &httpcode, httpstatus) != 4) { - - /* icecast 1 ? */ - if (sscanf(this->buf, "ICY %d %50[^\015\012]", &httpcode, httpstatus) != 2) { + char httpstatus[51] = { 0, }; + + if ( + (sscanf(this->buf, "HTTP/%d.%d %d %50[^\015\012]", &httpver, &httpsub, + &httpcode, httpstatus) != 4) && + (sscanf(this->buf, "HTTP/%d.%d %d", &httpver, &httpsub, + &httpcode) != 3) && + (sscanf(this->buf, "ICY %d %50[^\015\012]", /* icecast 1 ? */ + &httpcode, httpstatus) != 2) + ) { _x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "invalid http answer", NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: invalid http answer\n")); return -6; - } } if (httpcode >= 300 && httpcode < 400) { @@ -947,7 +944,7 @@ static int http_plugin_open (input_plugin_t *this_gen ) { return -12; } - lprintf("preview_size=%lld\n", this->preview_size); + lprintf("preview_size=%"PRId64"\n", this->preview_size); this->curpos = 0; return 1; @@ -995,7 +992,7 @@ static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_str return &this->input_plugin; } -static char *http_class_get_description (input_class_t *this_gen) { +static const char *http_class_get_description (input_class_t *this_gen) { return _("http input plugin"); } diff --git a/src/input/input_mms.c b/src/input/input_mms.c index d4f6cb940..05c0b168b 100644 --- a/src/input/input_mms.c +++ b/src/input/input_mms.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_mms.c,v 1.64 2006/10/23 21:18:18 hadess Exp $ + * $Id: input_mms.c,v 1.70 2007/02/20 00:51:39 dgp85 Exp $ * * mms input plugin based on work from major mms */ @@ -56,18 +56,18 @@ #define PROTOCOL_MMSH 2 /* network bandwidth */ -const uint32_t mms_bandwidths[]={14400,19200,28800,33600,34430,57600, - 115200,262200,393216,524300,1544000,10485800}; +static const uint32_t mms_bandwidths[]={14400,19200,28800,33600,34430,57600, + 115200,262200,393216,524300,1544000,10485800}; -const char * mms_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", - "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", - "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", - "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", - "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", - "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; +static const char * mms_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", + "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", + "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", + "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", + "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", + "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; /* connection methods */ -const char *mms_protocol_strs[]={"auto", "TCP", "HTTP", NULL}; +static const char *mms_protocol_strs[]={"auto", "TCP", "HTTP", NULL}; typedef struct { input_plugin_t input_plugin; @@ -102,7 +102,7 @@ static off_t mms_plugin_read (input_plugin_t *this_gen, mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t n = 0; - lprintf ("mms_plugin_read: %lld bytes ...\n", len); + lprintf ("mms_plugin_read: %"PRId64" bytes ...\n", len); switch (this->protocol) { case PROTOCOL_MMST: @@ -122,7 +122,7 @@ static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); int total_bytes; - lprintf ("mms_plugin_read_block: %lld bytes...\n", todo); + lprintf ("mms_plugin_read_block: %"PRId64" bytes...\n", todo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -144,7 +144,7 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin off_t dest = 0; off_t curpos = 0; - lprintf ("mms_plugin_seek: %lld offset, %d origin...\n", offset, origin); + lprintf ("mms_plugin_seek: %"PRId64" offset, %d origin...\n", offset, origin); switch (this->protocol) { @@ -201,6 +201,28 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin return curpos; } +static off_t mms_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + off_t curpos = 0; + + lprintf ("seek_time %d msec, origin %d\n", time_offset, origin); + + switch (this->protocol) { + case PROTOCOL_MMST: + if (origin == SEEK_SET) + mms_set_start_time (this->mms, time_offset); + curpos = mms_get_current_pos (this->mms); + break; + case PROTOCOL_MMSH: + if (origin == SEEK_SET) + mmsh_set_start_time (this->mmsh, time_offset); + curpos = mmsh_get_current_pos (this->mmsh); + break; + } + + return curpos; +} + static off_t mms_plugin_get_length (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t length = 0; @@ -217,7 +239,7 @@ static off_t mms_plugin_get_length (input_plugin_t *this_gen) { break; } - lprintf ("length is %lld\n", length); + lprintf ("length is %"PRId64"\n", length); return length; @@ -270,7 +292,7 @@ static void mms_plugin_dispose (input_plugin_t *this_gen) { free (this); } -static char* mms_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* mms_plugin_get_mrl (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; return this->mrl; @@ -400,6 +422,7 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre this->input_plugin.read = mms_plugin_read; this->input_plugin.read_block = mms_plugin_read_block; this->input_plugin.seek = mms_plugin_seek; + this->input_plugin.seek_time = mms_plugin_seek_time; this->input_plugin.get_current_pos = mms_plugin_get_current_pos; this->input_plugin.get_length = mms_plugin_get_length; this->input_plugin.get_blocksize = mms_plugin_get_blocksize; @@ -416,7 +439,7 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre * mms input plugin class stuff */ -static char *mms_class_get_description (input_class_t *this_gen) { +static const char *mms_class_get_description (input_class_t *this_gen) { return _("mms streaming input plugin"); } @@ -452,7 +475,7 @@ static void *init_class (xine_t *xine, void *data) { this->input_class.eject_media = NULL; xine->config->register_enum(xine->config, "media.network.bandwidth", 10, - (char **)mms_bandwidth_strs, + mms_bandwidth_strs, _("network bandwidth"), _("Specify the bandwidth of your internet connection here. " "This will be used when streaming servers offer different versions " @@ -462,7 +485,7 @@ static void *init_class (xine_t *xine, void *data) { this->protocol = xine->config->register_enum(xine->config, "media.network.mms_protocol", 0, - (char **)mms_protocol_strs, + mms_protocol_strs, _("MMS protocol"), _("Select the protocol to encapsulate MMS.\nTCP is better but you may need HTTP behind a firewall."), 20, diff --git a/src/input/input_net.c b/src/input/input_net.c index 19326c301..0ce2e1340 100644 --- a/src/input/input_net.c +++ b/src/input/input_net.c @@ -20,7 +20,7 @@ * Read from a tcp network stream over a lan (put a tweaked mp1e encoder the * other end and you can watch tv anywhere in the house ..) * - * $Id: input_net.c,v 1.68 2006/07/10 22:08:15 dgp85 Exp $ + * $Id: input_net.c,v 1.70 2007/01/19 01:05:25 dgp85 Exp $ * * how to set up mp1e for use with this plugin: * @@ -367,7 +367,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin } -static char* net_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* net_plugin_get_mrl (input_plugin_t *this_gen) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->mrl; @@ -506,7 +506,7 @@ static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stre * net plugin class */ -static char *net_class_get_description (input_class_t *this_gen) { +static const char *net_class_get_description (input_class_t *this_gen) { return _("net input plugin as shipped with xine"); } diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h index 2e9f0dca6..370dc6a71 100644 --- a/src/input/input_plugin.h +++ b/src/input/input_plugin.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_plugin.h,v 1.60 2005/10/14 21:02:16 miguelfreitas Exp $ + * $Id: input_plugin.h,v 1.64 2007/01/19 01:05:25 dgp85 Exp $ */ #ifndef HAVE_INPUT_PLUGIN_H @@ -60,7 +60,7 @@ struct input_class_s { * return human readable (verbose = 1 line) description for * this plugin class */ - char* (*get_description) (input_class_t *this); + const char* (*get_description) (input_class_t *this); /* * ls function, optional: may be NULL @@ -201,7 +201,7 @@ struct input_plugin_s { /* * return current MRL */ - char * (*get_mrl) (input_plugin_t *this); + const char * (*get_mrl) (input_plugin_t *this); /* @@ -297,6 +297,7 @@ struct input_plugin_s { #define INPUT_CAP_RIP_FORBIDDEN 0x00000100 + #define INPUT_IS_SEEKABLE(input) (((input)->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) #define INPUT_OPTIONAL_UNSUPPORTED 0 diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c index 26fdd350e..e1413b0f7 100644 --- a/src/input/input_pnm.c +++ b/src/input/input_pnm.c @@ -80,7 +80,7 @@ static off_t pnm_plugin_read (input_plugin_t *this_gen, pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; off_t n; - lprintf ("pnm_plugin_read: %lld bytes ...\n", len); + lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len); nbc_check_buffers (this->nbc); @@ -96,7 +96,7 @@ static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); int total_bytes; - lprintf ("pnm_plugin_read_block: %lld bytes...\n", todo); + lprintf ("pnm_plugin_read_block: %"PRId64" bytes...\n", todo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -156,7 +156,7 @@ static off_t pnm_plugin_get_current_pos (input_plugin_t *this_gen){ pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; /* - printf ("current pos is %lld\n", this->curpos); + printf ("current pos is %"PRId64"\n", this->curpos); */ return this->curpos; @@ -181,7 +181,7 @@ static void pnm_plugin_dispose (input_plugin_t *this_gen) { free (this); } -static char* pnm_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* pnm_plugin_get_mrl (input_plugin_t *this_gen) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; return this->mrl; @@ -258,7 +258,7 @@ static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stre * pnm input plugin class stuff */ -static char *pnm_class_get_description (input_class_t *this_gen) { +static const char *pnm_class_get_description (input_class_t *this_gen) { return _("pnm streaming input plugin"); } diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c index 1461d0f9e..bcf93af2b 100644 --- a/src/input/input_pvr.c +++ b/src/input/input_pvr.c @@ -38,7 +38,7 @@ * usage: * xine pvr:/<prefix_to_tmp_files>\!<prefix_to_saved_files>\!<max_page_age> * - * $Id: input_pvr.c,v 1.62 2006/07/10 22:08:15 dgp85 Exp $ + * $Id: input_pvr.c,v 1.65 2007/01/19 01:05:25 dgp85 Exp $ */ /************************************************************************** @@ -1317,7 +1317,7 @@ static uint32_t pvr_plugin_get_blocksize (input_plugin_t *this_gen) { return PVR_BLOCK_SIZE; } -static char* pvr_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* pvr_plugin_get_mrl (input_plugin_t *this_gen) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; return this->mrl; @@ -1524,7 +1524,7 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre * plugin class functions */ -static char *pvr_class_get_description (input_class_t *this_gen) { +static const char *pvr_class_get_description (input_class_t *this_gen) { return _("WinTV-PVR 250/350 input plugin"); } @@ -1548,9 +1548,9 @@ static void *init_plugin (xine_t *xine, void *data) { this->xine = xine; this->config = xine->config; - this->devname = this->config->register_string(this->config, + this->devname = this->config->register_filename(this->config, "media.wintv_pvr.device", - PVR_DEVICE, + PVR_DEVICE, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for WinTV-PVR 250/350 (pvr plugin)"), _("The path to the device of your WinTV card."), 10, NULL, diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c index b23ecb895..d4ba804c6 100644 --- a/src/input/input_rtp.c +++ b/src/input/input_rtp.c @@ -174,7 +174,10 @@ static int host_connect_attempt(struct in_addr ia, int port, const char *interface, xine_t *xine) { int s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - struct sockaddr_in sin; + union { + struct sockaddr_in in; + struct sockaddr sa; + } saddr; int optval; int multicast = 0; /* boolean, assume unicast */ @@ -183,12 +186,12 @@ static int host_connect_attempt(struct in_addr ia, int port, return -1; } - sin.sin_family = AF_INET; - sin.sin_addr = ia; - sin.sin_port = htons(port); + saddr.in.sin_family = AF_INET; + saddr.in.sin_addr = ia; + saddr.in.sin_port = htons(port); /* Is it a multicast address? */ - if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe) { + if ((ntohl(saddr.in.sin_addr.s_addr) >> 28) == 0xe) { LOG_MSG(xine, _("IP address specified is multicast\n")); multicast = 1; /* boolean true */ } @@ -205,14 +208,14 @@ static int host_connect_attempt(struct in_addr ia, int port, /* If multicast we allow multiple readers to open the same address */ if (multicast) { if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - &sin, sizeof(sin))) < 0) { + &saddr.in, sizeof(saddr.in))) < 0) { LOG_MSG(xine, _("setsockopt(SO_REUSEADDR): %s.\n"), strerror(errno)); return -1; } } /* datagram socket */ - if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) { + if (bind(s, &saddr.sa, sizeof(saddr.in))) { LOG_MSG(xine, _("bind(): %s.\n"), strerror(errno)); return -1; } @@ -240,7 +243,7 @@ static int host_connect_attempt(struct in_addr ia, int port, } /* struct ip_mreq mreq; */ - mreq.imr_multiaddr.s_addr = sin.sin_addr.s_addr; + mreq.imr_multiaddr.s_addr = saddr.in.sin_addr.s_addr; if (interface == NULL) { mreq.imr_interface.s_addr = htonl(INADDR_ANY); } @@ -559,7 +562,7 @@ static uint32_t rtp_plugin_get_blocksize (input_plugin_t *this_gen) { /* * */ -static char* rtp_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* rtp_plugin_get_mrl (input_plugin_t *this_gen) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; return this->mrl; @@ -739,7 +742,7 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen, * net plugin class */ -static char *rtp_class_get_description (input_class_t *this_gen) { +static const char *rtp_class_get_description (input_class_t *this_gen) { return _("RTP and UDP input plugin as shipped with xine"); } diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c index 0256edc8d..693e8af66 100644 --- a/src/input/input_rtsp.c +++ b/src/input/input_rtsp.c @@ -81,7 +81,7 @@ static off_t rtsp_plugin_read (input_plugin_t *this_gen, rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; off_t n; - lprintf ("rtsp_plugin_read: %lld bytes ...\n", len); + lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len); nbc_check_buffers (this->nbc); @@ -97,7 +97,7 @@ static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen, buf_element_t *buf = fifo->buffer_pool_alloc (fifo); int total_bytes; - lprintf ("rtsp_plugin_read_block: %lld bytes...\n", todo); + lprintf ("rtsp_plugin_read_block: %"PRId64" bytes...\n", todo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; @@ -118,7 +118,7 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; - lprintf ("seek %lld bytes, origin %d\n", offset, origin); + lprintf ("seek %"PRId64" bytes, origin %d\n", offset, origin); /* only realtive forward-seeking is implemented */ @@ -134,6 +134,18 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi return this->curpos; } +static off_t rtsp_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { + + rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; + + lprintf ("seek_time %d msec, origin %d\n", time_offset, origin); + + if (origin == SEEK_SET) + rtsp_session_set_start_time (this->rtsp, time_offset); + + return this->curpos; +} + static off_t rtsp_plugin_get_length (input_plugin_t *this_gen) { /* @@ -156,7 +168,7 @@ static off_t rtsp_plugin_get_current_pos (input_plugin_t *this_gen){ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; /* - printf ("current pos is %lld\n", this->curpos); + printf ("current pos is %"PRId64"\n", this->curpos); */ return this->curpos; @@ -184,7 +196,7 @@ static void rtsp_plugin_dispose (input_plugin_t *this_gen) { free (this); } -static char* rtsp_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* rtsp_plugin_get_mrl (input_plugin_t *this_gen) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; return this->public_mrl; @@ -212,7 +224,7 @@ static int rtsp_plugin_open (input_plugin_t *this_gen) { lprintf ("trying to open '%s'\n", this->mrl); - rtsp = rtsp_session_start(this->stream,this->mrl); + rtsp = rtsp_session_start(this->stream, this->mrl); if (!rtsp) { lprintf ("returning null.\n"); @@ -226,22 +238,19 @@ static int rtsp_plugin_open (input_plugin_t *this_gen) { } static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, - const char *data) { + const char *mrl) { /* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */ rtsp_input_plugin_t *this; - char *mrl = strdup(data); - if (strncasecmp (mrl, "rtsp://", 6)) { - free (mrl); + if (strncasecmp (mrl, "rtsp://", 6)) return NULL; - } this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t)); this->stream = stream; this->rtsp = NULL; - this->mrl = mrl; + this->mrl = strdup (mrl); /* since we handle only real streams yet, we can savely add * an .rm extention to force handling by demux_real. */ @@ -255,6 +264,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str this->input_plugin.read = rtsp_plugin_read; this->input_plugin.read_block = rtsp_plugin_read_block; this->input_plugin.seek = rtsp_plugin_seek; + this->input_plugin.seek_time = rtsp_plugin_seek_time; this->input_plugin.get_current_pos = rtsp_plugin_get_current_pos; this->input_plugin.get_length = rtsp_plugin_get_length; this->input_plugin.get_blocksize = rtsp_plugin_get_blocksize; @@ -270,7 +280,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str * rtsp input plugin class stuff */ -static char *rtsp_class_get_description (input_class_t *this_gen) { +static const char *rtsp_class_get_description (input_class_t *this_gen) { return _("rtsp streaming input plugin"); } diff --git a/src/input/input_smb.c b/src/input/input_smb.c index 21b45fa73..1b1f15565 100644 --- a/src/input/input_smb.c +++ b/src/input/input_smb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_smb.c,v 1.15 2006/07/10 22:08:16 dgp85 Exp $ + * $Id: input_smb.c,v 1.16 2007/01/26 17:06:05 dgp85 Exp $ */ @@ -148,6 +148,10 @@ smb_plugin_get_mrl (input_plugin_t *this_gen) return this->mrl; } +static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) { + return 0; +} + static char *smb_class_get_description (input_class_t *this_gen) { @@ -485,7 +489,7 @@ smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, this->input_plugin.seek = smb_plugin_seek; this->input_plugin.get_current_pos = smb_plugin_get_current_pos; this->input_plugin.get_length = smb_plugin_get_length; - this->input_plugin.get_blocksize = NULL; + this->input_plugin.get_blocksize = smb_plugin_get_blocksize; this->input_plugin.get_mrl = smb_plugin_get_mrl; this->input_plugin.get_optional_data = smb_plugin_get_optional_data; diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c index 3780a1cef..939f56f25 100644 --- a/src/input/input_stdin_fifo.c +++ b/src/input/input_stdin_fifo.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_stdin_fifo.c,v 1.67 2006/07/10 22:08:16 dgp85 Exp $ + * $Id: input_stdin_fifo.c,v 1.70 2007/02/20 00:34:56 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -86,14 +86,14 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen, stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; off_t n, total; - lprintf ("reading %lld bytes...\n", len); + lprintf ("reading %"PRId64" bytes...\n", len); total=0; if (this->curpos < this->preview_size) { n = this->preview_size - this->curpos; if (n > (len - total)) n = len - total; - lprintf ("%lld bytes from preview (which has %lld bytes)\n", n, this->preview_size); + lprintf ("%"PRId64" bytes from preview (which has %"PRId64" bytes)\n", n, this->preview_size); memcpy (&buf[total], &this->preview[this->curpos], n); this->curpos += n; @@ -103,7 +103,7 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen, if( (len-total) > 0 ) { n = _x_io_file_read (this->stream, this->fh, &buf[total], len - total); - lprintf ("got %lld bytes (%lld/%lld bytes read)\n", n,total,len); + lprintf ("got %"PRId64" bytes (%"PRId64"/%"PRId64" bytes read)\n", n,total,len); if (n < 0) { _x_message(this->stream, XINE_MSG_READ_ERROR, NULL); @@ -143,7 +143,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; - lprintf ("seek %lld offset, %d origin...\n", offset, origin); + lprintf ("seek %"PRId64" offset, %d origin...\n", offset, origin); if ((origin == SEEK_CUR) && (offset >= 0)) { @@ -202,7 +202,7 @@ static off_t stdin_plugin_get_current_pos (input_plugin_t *this_gen){ return this->curpos; } -static char* stdin_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* stdin_plugin_get_mrl (input_plugin_t *this_gen) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; return this->mrl; @@ -346,7 +346,7 @@ static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen, * stdin input plugin class stuff */ -static char *stdin_class_get_description (input_class_t *this_gen) { +static const char *stdin_class_get_description (input_class_t *this_gen) { return _("stdin streaming input plugin"); } diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index 1dfde167f..17c4223a2 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -1628,7 +1628,7 @@ static void v4l_plugin_dispose (input_plugin_t *this_gen) { * * Get the current MRL used by the plugin. */ -static char* v4l_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* v4l_plugin_get_mrl (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; return this->mrl; @@ -1907,8 +1907,8 @@ static void *init_video_class (xine_t *xine, void *data) this->input_class.dispose = v4l_class_dispose; this->input_class.eject_media = NULL; - config->register_string (config, "media.video4linux.video_device", - VIDEO_DEV, + config->register_filename (config, "media.video4linux.video_device", + VIDEO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("v4l video device"), _("The path to your Video4Linux video device."), 10, NULL, NULL); @@ -1933,8 +1933,8 @@ static void *init_radio_class (xine_t *xine, void *data) this->input_class.dispose = v4l_class_dispose; this->input_class.eject_media = NULL; - config->register_string (config, "media.video4linux.radio_device", - RADIO_DEV, + config->register_filename (config, "media.video4linux.radio_device", + RADIO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("v4l radio device"), _("The path to your Video4Linux radio device."), 10, NULL, NULL); diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c index 0103027bf..bcd50ecc1 100644 --- a/src/input/input_vcd.c +++ b/src/input/input_vcd.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: input_vcd.c,v 1.85 2006/07/10 22:08:16 dgp85 Exp $ + * $Id: input_vcd.c,v 1.89 2007/03/16 16:32:58 dgp85 Exp $ * */ @@ -25,7 +25,6 @@ #include "config.h" #endif -#include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> @@ -34,6 +33,7 @@ #include <fcntl.h> #include <sys/ioctl.h> #include <string.h> +#include <netinet/in.h> #ifdef HAVE_LINUX_CDROM_H # include <linux/cdrom.h> #endif @@ -813,7 +813,7 @@ static void vcd_plugin_dispose (input_plugin_t *this_gen ) { free (this); } -static char* vcd_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* vcd_plugin_get_mrl (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; return this->mrl; @@ -919,7 +919,7 @@ static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stre * vcd input plugin class stuff */ -static char *vcd_class_get_description (input_class_t *this_gen) { +static const char *vcd_class_get_description (input_class_t *this_gen) { return _("Video CD input plugin"); } @@ -1094,7 +1094,7 @@ static void *init_class (xine_t *xine, void *data) { this->input_class.dispose = vcd_class_dispose; this->input_class.eject_media = vcd_class_eject_media; - this->device = config->register_string (config, "media.vcd.device", CDROM, + this->device = config->register_filename (config, "media.vcd.device", CDROM, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for VCD playback"), _("The path to the device, usually a CD or DVD drive, " "you intend to play your VideoCDs with."), diff --git a/src/input/libreal/.cvsignore b/src/input/libdvdnav/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/libreal/.cvsignore +++ b/src/input/libdvdnav/.hgignore diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am index 2aadb3588..412828261 100644 --- a/src/input/libdvdnav/Makefile.am +++ b/src/input/libdvdnav/Makefile.am @@ -22,7 +22,7 @@ libdvdnav_la_SOURCES = \ dvd_reader.c \ dvd_input.c \ dvd_udf.c -libdvdnav_la_LIBADD = $(THREAD_LIBS) +libdvdnav_la_LIBADD = $(PTHREAD_LIBS) libdvdnav_la_CFLAGS = $(VISIBILITY_FLAG) libdvdnav_la_LDFLAGS = -avoid-version -module diff --git a/src/input/libdvdnav/bswap.h b/src/input/libdvdnav/bswap.h index 7d7acd556..c1fc7a045 100644 --- a/src/input/libdvdnav/bswap.h +++ b/src/input/libdvdnav/bswap.h @@ -41,6 +41,12 @@ #define B2N_32(x) x = bswap_32(x) #define B2N_64(x) x = bswap_64(x) +#elif defined(__APPLE__) +#include <libkern/OSByteOrder.h> +#define B2N_16(x) x = OSSwapBigToHostInt16(x) +#define B2N_32(x) x = OSSwapBigToHostInt32(x) +#define B2N_64(x) x = OSSwapBigToHostInt64(x) + #elif defined(__NetBSD__) #include <sys/endian.h> #define B2N_16(x) BE16TOH(x) diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch index 6afca3a98..202474fef 100644 --- a/src/input/libdvdnav/diff_against_cvs.patch +++ b/src/input/libdvdnav/diff_against_cvs.patch @@ -263,6 +263,19 @@ diff -u -p -u -r1.3 bswap.h #include <byteswap.h> #define B2N_16(x) x = bswap_16(x) #define B2N_32(x) x = bswap_32(x) +@@ -41,6 +41,12 @@ + #define B2N_32(x) x = bswap_32(x) + #define B2N_64(x) x = bswap_64(x) + ++#elif defined(__APPLE__) ++#include <libkern/OSByteOrder.h> ++#define B2N_16(x) x = OSSwapBigToHostInt16(x) ++#define B2N_32(x) x = OSSwapBigToHostInt32(x) ++#define B2N_64(x) x = OSSwapBigToHostInt64(x) ++ + #elif defined(__NetBSD__) + #include <sys/endian.h> + #define B2N_16(x) BE16TOH(x) Index: src/input/libdvdnav/dvd_reader.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_reader.c,v diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c index e71d6ca42..7ecd8f1ba 100644 --- a/src/input/libdvdnav/dvd_reader.c +++ b/src/input/libdvdnav/dvd_reader.c @@ -603,10 +603,12 @@ static int findDirFile( const char *path, const char *file, char *filename ) sprintf( filename, "%s%s%s", path, ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ), ent->d_name ); + closedir (dir); return 0; } } + closedir (dir); return -1; } diff --git a/src/input/libdvdnav/remap.c b/src/input/libdvdnav/remap.c index 86cf3a4ad..f2049ac06 100644 --- a/src/input/libdvdnav/remap.c +++ b/src/input/libdvdnav/remap.c @@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: remap.c,v 1.5 2006/09/17 13:01:08 valtri Exp $ + * $Id: remap.c,v 1.6 2006/12/08 16:26:10 mshopf Exp $ */ #include <stdlib.h> @@ -193,10 +193,7 @@ remap_t* remap_loadmap( char *title) { /* Build the map filename */ home = getenv("HOME"); assert(home); - strncpy(fname, home, sizeof(fname)); - strncat(fname, "/.dvdnav/", sizeof(fname)); - strncat(fname, title, sizeof(fname)); - strncat(fname, ".map", sizeof(fname)); + snprintf (fname, sizeof(fname), "%s/.dvdnav/%s.map", home, title); /* Open the map file */ fp = fopen( fname, "r"); diff --git a/src/input/librtsp/.cvsignore b/src/input/libreal/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/librtsp/.cvsignore +++ b/src/input/libreal/.hgignore diff --git a/src/input/libreal/asmrp.c b/src/input/libreal/asmrp.c index 5fd5ae798..8afc19df6 100644 --- a/src/input/libreal/asmrp.c +++ b/src/input/libreal/asmrp.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: asmrp.c,v 1.9 2006/11/29 19:43:01 dgp85 Exp $ + * $Id: asmrp.c,v 1.10 2006/12/25 15:39:31 dgp85 Exp $ * * a parser for real's asm rules * @@ -417,7 +417,9 @@ static int asmrp_operand (asmrp_t *p) { i = asmrp_find_id (p, p->str); if (i<0) { - lprintf ("error: unknown identifier %s\n", p->str); + printf ("error: unknown identifier %s\n", p->str); + ret = 0; + break; } ret = p->sym_tab[i].v; diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c index 270fd16e4..dc0c001bd 100644 --- a/src/input/libreal/real.c +++ b/src/input/libreal/real.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: real.c,v 1.24 2006/11/29 19:43:01 dgp85 Exp $ + * $Id: real.c,v 1.26 2007/01/19 01:19:06 dgp85 Exp $ * * special functions for real streams. * adopted from joschkas real tools. @@ -289,18 +289,15 @@ static void calc_response (char *result, char *field) { static void calc_response_string (char *result, char *challenge) { - char field[128]; + char field[128] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; char zres[20]; int i; - /* initialize our field */ - BE_32C (field, 0x01234567); - BE_32C ((field+4), 0x89ABCDEF); - BE_32C ((field+8), 0xFEDCBA98); - BE_32C ((field+12), 0x76543210); - BE_32C ((field+16), 0x00000000); - BE_32C ((field+20), 0x00000000); - /* calculate response */ call_hash(field, challenge, 64); calc_response(zres,field); @@ -715,10 +712,6 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid rtsp_schedule_field(rtsp_session, subscribe); rtsp_request_setparameter(rtsp_session,NULL); - /* and finally send a play request */ - rtsp_schedule_field(rtsp_session, "Range: npt=0-"); - rtsp_request_play(rtsp_session,NULL); - xine_buffer_free(subscribe); xine_buffer_free(buf); return h; diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c index e77781253..019237243 100644 --- a/src/input/libreal/sdpplin.c +++ b/src/input/libreal/sdpplin.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: sdpplin.c,v 1.6 2006/06/20 01:07:58 dgp85 Exp $ + * $Id: sdpplin.c,v 1.8 2006/12/25 16:21:56 dgp85 Exp $ * * sdp/sdpplin parser. * @@ -71,8 +71,9 @@ static char *b64_decode(const char *in, char *out, int *size) int c = in[i+j]; if (dtable[c] & 0x80) { - printf("Illegal character '%c' in input.\n", c); - exit(1); + fprintf(stderr, "Illegal character '%c' in input.\n", c); + *size = 0; + return NULL; } a[i] = (char) c; b[i] = (char) dtable[c]; @@ -200,11 +201,13 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) { if(filter(*data,"a=OpaqueData:buffer;",&buf)) { decoded = b64_decode(buf, decoded, &(desc->mlti_data_size)); - desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size); - memcpy(desc->mlti_data, decoded, desc->mlti_data_size); - handled=1; - *data=nl(*data); - lprintf("mlti_data_size: %i\n", desc->mlti_data_size); + if ( decoded != NULL ) { + desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size); + memcpy(desc->mlti_data, decoded, desc->mlti_data_size); + handled=1; + *data=nl(*data); + lprintf("mlti_data_size: %i\n", desc->mlti_data_size); + } } if(filter(*data,"a=ASMRuleBook:string;",&buf)) { @@ -239,11 +242,17 @@ sdpplin_t *sdpplin_parse(char *data) { int handled; int len; + desc->stream = NULL; + while (data && *data) { handled=0; if (filter(data, "m=", &buf)) { + if ( ! desc->stream ) { + fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping."); + continue; + } stream=sdpplin_parse_stream(&data); lprintf("got data for stream id %u\n", stream->stream_id); desc->stream[stream->stream_id]=stream; @@ -252,30 +261,38 @@ sdpplin_t *sdpplin_parse(char *data) { if(filter(data,"a=Title:buffer;",&buf)) { decoded=b64_decode(buf, decoded, &len); - desc->title=strdup(decoded); - handled=1; - data=nl(data); + if ( decoded != NULL ) { + desc->title=strdup(decoded); + handled=1; + data=nl(data); + } } if(filter(data,"a=Author:buffer;",&buf)) { decoded=b64_decode(buf, decoded, &len); - desc->author=strdup(decoded); - handled=1; - data=nl(data); + if ( decoded != NULL ) { + desc->author=strdup(decoded); + handled=1; + data=nl(data); + } } if(filter(data,"a=Copyright:buffer;",&buf)) { decoded=b64_decode(buf, decoded, &len); - desc->copyright=strdup(decoded); - handled=1; - data=nl(data); + if ( decoded != NULL ) { + desc->copyright=strdup(decoded); + handled=1; + data=nl(data); + } } if(filter(data,"a=Abstract:buffer;",&buf)) { decoded=b64_decode(buf, decoded, &len); - desc->abstract=strdup(decoded); - handled=1; - data=nl(data); + if ( decoded != NULL ) { + desc->abstract=strdup(decoded); + handled=1; + data=nl(data); + } } if(filter(data,"a=StreamCount:integer;",&buf)) { diff --git a/src/input/vcd/.cvsignore b/src/input/librtsp/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/vcd/.cvsignore +++ b/src/input/librtsp/.hgignore diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c index 6f06693a9..66de10584 100644 --- a/src/input/librtsp/rtsp_session.c +++ b/src/input/librtsp/rtsp_session.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: rtsp_session.c,v 1.16 2004/04/24 16:55:42 miguelfreitas Exp $ + * $Id: rtsp_session.c,v 1.19 2006/12/22 18:08:10 klan Exp $ * * high level interface to rtsp servers. */ @@ -53,24 +53,49 @@ struct rtsp_session_s { rtsp_t *s; /* receive buffer */ - uint8_t *recv; + uint8_t *recv; int recv_size; int recv_read; /* header buffer */ uint8_t header[HEADER_SIZE]; int header_len; - int header_read; + int header_left; + int playing; + int start_time; }; +/* network bandwidth */ +const uint32_t rtsp_bandwidths[]={14400,19200,28800,33600,34430,57600, + 115200,262200,393216,524300,1544000,10485800}; + +const char *rtsp_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", + "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", + "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", + "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", + "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", + "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; + + rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) { - rtsp_session_t *rtsp_session = malloc(sizeof(rtsp_session_t)); + rtsp_session_t *rtsp_session = xine_xmalloc(sizeof(rtsp_session_t)); + xine_t *xine = stream->xine; char *server; char *mrl_line=strdup(mrl); rmff_header_t *h; - uint32_t bandwidth=10485800; + int bandwidth_id; + uint32_t bandwidth; + + bandwidth_id = xine->config->register_enum(xine->config, "media.network.bandwidth", 10, + (char **)rtsp_bandwidth_strs, + _("network bandwidth"), + _("Specify the bandwidth of your internet connection here. " + "This will be used when streaming servers offer different versions " + "with different bandwidth requirements of the same stream."), + 0, NULL, NULL); + bandwidth = rtsp_bandwidths[bandwidth_id]; rtsp_session->recv = xine_buffer_init(BUF_SIZE); @@ -123,7 +148,8 @@ connect: } } - rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,1024); + rtsp_session->header_left = + rtsp_session->header_len = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE); xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len); rtsp_session->recv_size = rtsp_session->header_len; @@ -144,16 +170,48 @@ connect: return rtsp_session; } +void rtsp_session_set_start_time (rtsp_session_t *this, int start_time) { + + if (start_time >= 0) + this->start_time = start_time; +} + +static void rtsp_session_play (rtsp_session_t *this) { + + char buf[256]; + + snprintf (buf, sizeof(buf), "Range: npt=%d.%03d-", + this->start_time/1000, this->start_time%1000); + + rtsp_schedule_field (this->s, buf); + rtsp_request_play (this->s,NULL); +} + int rtsp_session_read (rtsp_session_t *this, char *data, int len) { - int to_copy=len; + int to_copy; char *dest=data; char *source=this->recv + this->recv_read; int fill=this->recv_size - this->recv_read; - if (len < 0) return 0; + if (len < 0) + return 0; + + if (this->header_left) { + if (len > this->header_left) + len = this->header_left; + + this->header_left -= len; + } + + to_copy = len; while (to_copy > fill) { + if (!this->playing) { + rtsp_session_play (this); + this->playing = 1; + } + memcpy(dest, source, fill); to_copy -= fill; dest += fill; diff --git a/src/input/librtsp/rtsp_session.h b/src/input/librtsp/rtsp_session.h index 140d09a0a..649842e7a 100644 --- a/src/input/librtsp/rtsp_session.h +++ b/src/input/librtsp/rtsp_session.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: rtsp_session.h,v 1.6 2003/12/09 00:02:31 f1rmb Exp $ + * $Id: rtsp_session.h,v 1.7 2006/12/18 21:31:47 klan Exp $ * * high level interface to rtsp servers. */ @@ -29,6 +29,8 @@ typedef struct rtsp_session_s rtsp_session_t; rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl); +void rtsp_session_set_start_time(rtsp_session_t *this, int start_time); + int rtsp_session_read(rtsp_session_t *session, char *data, int len); int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize); diff --git a/src/input/mms.c b/src/input/mms.c index 86317a1ee..74087f7c5 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mms.c,v 1.63 2006/09/16 08:13:51 tmattern Exp $ + * $Id: mms.c,v 1.65 2007/02/20 00:34:56 dgp85 Exp $ * * MMS over TCP protocol * based on work from major mms @@ -144,9 +144,19 @@ struct mms_s { int eos; uint8_t live_flag; + + uint8_t playing; + double start_time; }; +#define D2Q(d) ({\ + union { double db; long long qw; } _tmp;\ + _tmp.db = d;\ + _tmp.qw;\ +})\ + + static void mms_buffer_init (mms_buffer_t *mms_buffer, char *buffer) { mms_buffer->buffer = (uint8_t*)buffer; mms_buffer->pos = 0; @@ -179,6 +189,20 @@ static void mms_buffer_put_32 (mms_buffer_t *mms_buffer, uint32_t value) { mms_buffer->pos += 4; } +static void mms_buffer_put_64 (mms_buffer_t *mms_buffer, uint64_t value) { + + mms_buffer->buffer[mms_buffer->pos] = value & 0xff; + mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 2] = (value >> 16) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 3] = (value >> 24) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 4] = (value >> 32) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 5] = (value >> 40) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 6] = (value >> 48) & 0xff; + mms_buffer->buffer[mms_buffer->pos + 7] = (value >> 56) & 0xff; + + mms_buffer->pos += 8; +} + static void print_command (char *data, int len) { @@ -361,7 +385,7 @@ static int get_packet_header (mms_t *this, mms_packet_header_t *header) { return packet_type; error: - lprintf("read error, len=%d\n", len); + lprintf("read error, len=%zd\n", len); return MMS_PACKET_ERR; } @@ -839,11 +863,13 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) { report_progress (stream, 80); /* command 0x07 */ + /* moved to mms_read() */ +#if 0 { mms_buffer_t command_buffer; mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_32 (&command_buffer, 0x00000000); /* 64 byte float timestamp */ - mms_buffer_put_32 (&command_buffer, 0x00000000); + mms_buffer_put_32 (&command_buffer, 0x00000000); mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ @@ -857,6 +883,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) { goto fail; } } +#endif report_progress (stream, 100); @@ -1052,9 +1079,33 @@ int mms_read (mms_t *this, char *data, int len) { this->asf_header_read += n; total += n; this->current_pos += n; + + if (this->asf_header_read == this->asf_header_len) + break; } else { int n, bytes_left ; + + if (!this->playing) { + /* send command 0x07 with initial timestamp */ + mms_buffer_t command_buffer; + mms_buffer_init(&command_buffer, this->scmd_body); + mms_buffer_put_64 (&command_buffer, D2Q(this->start_time)); /* 64 byte float timestamp */ + mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ + mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ + mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ + mms_buffer_put_8 (&command_buffer, 0xFF); + mms_buffer_put_8 (&command_buffer, 0xFF); + mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ + mms_buffer_put_32 (&command_buffer, ASF_MEDIA_PACKET_ID_TYPE); /* asf media packet id type */ + if (!send_command (this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { + xprintf (this->stream->xine, XINE_VERBOSITY_LOG, + "libmms: failed to send command 0x07\n"); + this->eos = 1; + break; + } + this->playing = 1; + } bytes_left = this->buf_size - this->buf_read; if (bytes_left == 0) { @@ -1111,3 +1162,9 @@ uint32_t mms_get_length (mms_t *this) { off_t mms_get_current_pos (mms_t *this) { return this->current_pos; } + +void mms_set_start_time (mms_t *this, int time_offset) { + if (time_offset >= 0) + this->start_time = (double) time_offset / 1000.0; +} + diff --git a/src/input/mms.h b/src/input/mms.h index f4b2928cd..310a6d0cc 100644 --- a/src/input/mms.h +++ b/src/input/mms.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mms.h,v 1.12 2006/06/20 01:46:41 dgp85 Exp $ + * $Id: mms.h,v 1.13 2007/01/03 15:09:42 klan Exp $ * * libmms public header */ @@ -41,5 +41,7 @@ size_t mms_peek_header (mms_t *this, char *data, size_t maxsize); off_t mms_get_current_pos (mms_t *this); +void mms_set_start_time (mms_t *this, int time_offset); + #endif diff --git a/src/input/mmsh.c b/src/input/mmsh.c index 889596cf7..30c16001d 100644 --- a/src/input/mmsh.c +++ b/src/input/mmsh.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mmsh.c,v 1.40 2006/11/11 00:05:22 dgp85 Exp $ + * $Id: mmsh.c,v 1.42 2007/01/11 16:20:55 klan Exp $ * * MMS over HTTP protocol * written by Thibaut Mattern @@ -99,7 +99,7 @@ "Pragma: no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=%u,max-duration=%u\r\n" \ CLIENTGUID \ "Pragma: xPlayStrm=1\r\n" \ - "Pragma: stream-switch-coun t=%d\r\n" \ + "Pragma: stream-switch-count=%d\r\n" \ "Pragma: stream-switch-entry=%s\r\n" /* ffff:1:0 ffff:2:0 */ \ "Connection: Close\r\n\r\n" @@ -180,9 +180,15 @@ struct mmsh_s { uint32_t asf_header_len; uint32_t asf_header_read; int seq_num; + + int video_stream; + int audio_stream; off_t current_pos; - int user_bandwitdh; + int user_bandwidth; + + int playing; + unsigned int start_time; }; static int send_command (mmsh_t *this, char *cmd) { @@ -382,7 +388,6 @@ static int get_header (mmsh_t *this) { lprintf("get_header\n"); this->asf_header_len = 0; - this->asf_header_read = 0; /* read chunk */ while (1) { @@ -514,13 +519,10 @@ static int mmsh_tcp_connect(mmsh_t *this) { return 0; } - +/* + * firts http request + */ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { - int i; - char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */ - int offset; - int audio_stream, video_stream; - /* * let the negotiations begin... */ @@ -532,30 +534,45 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { this->host, this->port, 1); if (!send_command (this, this->str)) - goto fail; + return 0; if (!get_answer (this)) - goto fail; + return 0; - get_header(this); /* FIXME: it returns 0 */ + get_header (this); /* FIXME: it returns 0 */ - if (!interp_header(this)) - goto fail; + if (!interp_header (this)) + return 0; - close(this->s); + close (this->s); report_progress (this->stream, 20); - asf_header_choose_streams (this->asf_header, bandwidth, &video_stream, &audio_stream); + asf_header_choose_streams (this->asf_header, bandwidth, + &this->video_stream, &this->audio_stream); - lprintf("audio stream %d, video stream %d\n", audio_stream, video_stream); + lprintf("audio stream %d, video stream %d\n", + this->audio_stream, this->video_stream); + + asf_header_disable_streams (this->asf_header, + this->video_stream, this->audio_stream); + + if (mmsh_tcp_connect(this)) + return 0; + + return 1; +} + +/* + * second http request + */ +static int mmsh_connect_int2(mmsh_t *this, int bandwidth) { + int i; + char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */ + int offset; /* second request */ lprintf("second http request\n"); - if (mmsh_tcp_connect(this)) { - goto fail; - } - /* stream selection string */ /* The same selection is done with mmst */ /* 0 means selected */ @@ -563,8 +580,8 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { offset = 0; for (i = 0; i < this->asf_header->stream_count; i++) { int size; - if ((i == audio_stream) || - (i == video_stream)) { + if ((i == this->audio_stream) || + (i == this->video_stream)) { size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:0 ", this->asf_header->streams[i]->stream_number); } else { @@ -573,14 +590,15 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:2 ", this->asf_header->streams[i]->stream_number); } - if (size < 0) goto fail; + if (size < 0) + return 0; offset += size; } switch (this->stream_type) { case MMSH_SEEKABLE: snprintf (this->str, SCRATCH_SIZE, mmsh_SeekableRequest, this->uri, - this->host, this->port, 0, 0, 0, 2, 0, + this->host, this->port, this->start_time, 0, 0, 2, 0, this->asf_header->stream_count, stream_selection); break; case MMSH_LIVE: @@ -591,25 +609,25 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { } if (!send_command (this, this->str)) - goto fail; + return 0; lprintf("before read \n"); if (!get_answer (this)) - goto fail; - - if (!get_header(this)) - goto fail; - - if (!interp_header(this)) - goto fail; + return 0; - asf_header_disable_streams (this->asf_header, video_stream, audio_stream); + if (!get_header (this)) + return 0; + +#if 0 + if (!interp_header (this)) + return 0; + + asf_header_disable_streams (this->asf_header, + this->video_stream, this->audio_stream); +#endif return 1; - -fail: - return 0; } mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) { @@ -630,7 +648,7 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) { this->buf_size = 0; this->buf_read = 0; this->current_pos = 0; - this->user_bandwitdh = bandwidth; + this->user_bandwidth = bandwidth; report_progress (stream, 0); @@ -650,7 +668,7 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) { report_progress (stream, 30); - if (!mmsh_connect_int(this, this->user_bandwitdh)) + if (!mmsh_connect_int(this, this->user_bandwidth)) goto fail; report_progress (stream, 100); @@ -709,8 +727,10 @@ static int get_media_packet (mmsh_t *this) { if (mmsh_tcp_connect(this)) return 0; - if (!mmsh_connect_int(this, this->user_bandwitdh)) + if (!mmsh_connect_int(this, this->user_bandwidth)) return 0; + + this->playing = 0; /* mmsh_connect_int reads the first data packet */ /* this->buf_size is set by mmsh_connect_int */ @@ -784,7 +804,7 @@ int mmsh_read (mmsh_t *this, char *data, int len) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left ; - bytes_left = this->asf_header_len - this->asf_header_read ; + bytes_left = this->asf_header_len - this->asf_header_read; if ((len-total) < bytes_left) n = len-total; @@ -796,9 +816,18 @@ int mmsh_read (mmsh_t *this, char *data, int len) { this->asf_header_read += n; total += n; this->current_pos += n; + + if (this->asf_header_read == this->asf_header_len) + break; } else { int n, bytes_left ; + + if (!this->playing) { + if (!mmsh_connect_int2 (this, this->user_bandwidth)) + break; + this->playing = 1; + } bytes_left = this->buf_size - this->buf_read; @@ -867,3 +896,8 @@ uint32_t mmsh_get_length (mmsh_t *this) { off_t mmsh_get_current_pos (mmsh_t *this) { return this->current_pos; } + +void mmsh_set_start_time (mmsh_t *this, int time_offset) { + if (time_offset >= 0) + this->start_time = time_offset; +} diff --git a/src/input/mmsh.h b/src/input/mmsh.h index 8aee808f0..1ded6295a 100644 --- a/src/input/mmsh.h +++ b/src/input/mmsh.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: mmsh.h,v 1.5 2006/06/20 01:46:41 dgp85 Exp $ + * $Id: mmsh.h,v 1.6 2007/01/09 20:51:00 klan Exp $ * * libmmsh public header */ @@ -31,7 +31,7 @@ typedef struct mmsh_s mmsh_t; char* mmsh_connect_common(int *s ,int *port, char *url, char **host, char **path, char **file); -mmsh_t* mmsh_connect (xine_stream_t *stream, const char *url_, int bandwidth); +mmsh_t* mmsh_connect (xine_stream_t *stream, const char *url_, int bandwidth); int mmsh_read (mmsh_t *this, char *data, int len); uint32_t mmsh_get_length (mmsh_t *this); @@ -41,4 +41,6 @@ size_t mmsh_peek_header (mmsh_t *this, char *data, size_t maxsize); off_t mmsh_get_current_pos (mmsh_t *this); +void mmsh_set_start_time (mmsh_t *this, int time_offset); + #endif diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c index 75743a070..86514cdea 100644 --- a/src/input/net_buf_ctrl.c +++ b/src/input/net_buf_ctrl.c @@ -149,7 +149,7 @@ static void nbc_compute_fifo_length(nbc_t *this, fifo_buffer_t *fifo, buf_element_t *buf, int action) { - int fifo_free, fifo_fill; + int fifo_free, fifo_fill, fifo_div; int64_t video_br, audio_br, diff; int has_video, has_audio; @@ -160,10 +160,13 @@ static void nbc_compute_fifo_length(nbc_t *this, fifo_free = fifo->buffer_pool_num_free; fifo_fill = fifo->fifo_size; + fifo_div = fifo_fill + fifo_free - 1; + if (fifo_div == 0) + fifo_div = 1; /* avoid a possible divide-by-zero */ if (fifo == this->video_fifo) { this->video_fifo_free = fifo_free; - this->video_fifo_fill = (100 * fifo_fill) / (fifo_fill + fifo_free - 1); + this->video_fifo_fill = (100 * fifo_fill) / fifo_div; this->video_fifo_size = fifo->fifo_data_size; if (buf->pts && (this->video_in_disc == 0)) { @@ -196,7 +199,7 @@ static void nbc_compute_fifo_length(nbc_t *this, } else { this->audio_fifo_free = fifo_free; - this->audio_fifo_fill = (100 * fifo_fill) / (fifo_fill + fifo_free - 1); + this->audio_fifo_fill = (100 * fifo_fill) / fifo_div; this->audio_fifo_size = fifo->fifo_data_size; if (buf->pts && (this->audio_in_disc == 0)) { diff --git a/src/input/vcd/libcdio/.cvsignore b/src/input/vcd/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/vcd/libcdio/.cvsignore +++ b/src/input/vcd/.hgignore diff --git a/src/input/vcd/Makefile.am b/src/input/vcd/Makefile.am index deb30e78f..98903aac8 100644 --- a/src/input/vcd/Makefile.am +++ b/src/input/vcd/Makefile.am @@ -18,7 +18,7 @@ xineplug_inp_vcd_la_LDFLAGS = -avoid-version -module if HAVE_VCDNAV xineplug_inp_vcd_la_LIBADD = $(XINE_LIB) $(LIBVCDINFO_LIBS) else -xineplug_inp_vcd_la_LIBADD = $(XINE_LIB) $(LIBVCD_LIBS) $(LIBVCDINFO_LIBS) +xineplug_inp_vcd_la_LIBADD = $(XINE_LIB) $(LIBVCD_LIBS) $(LIBVCDINFO_LIBS) -lm endif endif diff --git a/src/input/vcd/libvcd/.cvsignore b/src/input/vcd/libcdio/.hgignore index 7d926a554..7d926a554 100644 --- a/src/input/vcd/libvcd/.cvsignore +++ b/src/input/vcd/libcdio/.hgignore diff --git a/src/input/vcd/libcdio/MSWindows/.cvsignore b/src/input/vcd/libcdio/MSWindows/.hgignore index 282522db0..282522db0 100644 --- a/src/input/vcd/libcdio/MSWindows/.cvsignore +++ b/src/input/vcd/libcdio/MSWindows/.hgignore diff --git a/src/input/vcd/libcdio/cdio/.cvsignore b/src/input/vcd/libcdio/cdio/.hgignore index 282522db0..282522db0 100644 --- a/src/input/vcd/libcdio/cdio/.cvsignore +++ b/src/input/vcd/libcdio/cdio/.hgignore diff --git a/src/input/vcd/libcdio/image/.cvsignore b/src/input/vcd/libcdio/image/.hgignore index 282522db0..282522db0 100644 --- a/src/input/vcd/libcdio/image/.cvsignore +++ b/src/input/vcd/libcdio/image/.hgignore diff --git a/src/input/vcd/libcdio/iso9660_fs.c b/src/input/vcd/libcdio/iso9660_fs.c index 0a2de8fa1..fff12cd7c 100644 --- a/src/input/vcd/libcdio/iso9660_fs.c +++ b/src/input/vcd/libcdio/iso9660_fs.c @@ -1,5 +1,5 @@ /* - $Id: iso9660_fs.c,v 1.6 2006/09/28 08:19:14 dgp85 Exp $ + $Id: iso9660_fs.c,v 1.7 2006/12/08 16:26:10 mshopf Exp $ Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com> @@ -51,7 +51,7 @@ #include <stdio.h> -static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.6 2006/09/28 08:19:14 dgp85 Exp $"; +static const char _rcsid[] = "$Id: iso9660_fs.c,v 1.7 2006/12/08 16:26:10 mshopf Exp $"; /* Implementation of iso9660_t type */ struct _iso9660 { @@ -1200,9 +1200,7 @@ find_fs_lsn_recurse (CdIo *p_cdio, const char pathname[], lsn_t lsn) char _fullname[4096] = { 0, }; char *filename = (char *) statbuf->filename; - snprintf (_fullname, sizeof (_fullname), "%s%s", pathname, filename); - - strncat (_fullname, "/", sizeof (_fullname)); + snprintf (_fullname, sizeof (_fullname), "%s%s/", pathname, filename); if (statbuf->type == _STAT_DIR && strcmp ((char *) statbuf->filename, ".") diff --git a/src/liba52/.cvsignore b/src/input/vcd/libvcd/.hgignore index 7d926a554..7d926a554 100644 --- a/src/liba52/.cvsignore +++ b/src/input/vcd/libvcd/.hgignore diff --git a/src/input/vcd/libvcd/info.c b/src/input/vcd/libvcd/info.c index d178968a8..b01bd6eee 100644 --- a/src/input/vcd/libvcd/info.c +++ b/src/input/vcd/libvcd/info.c @@ -1,5 +1,5 @@ /* - $Id: info.c,v 1.7 2006/09/26 22:29:39 dgp85 Exp $ + $Id: info.c,v 1.8 2007/03/23 21:47:31 dsalt Exp $ Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com> @@ -59,7 +59,7 @@ #include <stddef.h> #include <errno.h> -static const char _rcsid[] = "$Id: info.c,v 1.7 2006/09/26 22:29:39 dgp85 Exp $"; +static const char _rcsid[] = "$Id: info.c,v 1.8 2007/03/23 21:47:31 dsalt Exp $"; #define BUF_COUNT 16 #define BUF_SIZE 80 @@ -1904,14 +1904,12 @@ vcdinfo_open(vcdinfo_obj_t **obj_p, char *source_name[], strlen (ISO_XA_MARKER_STRING)); } - if (!read_info(obj->img, &(obj->info), &(obj->vcd_type))) - return VCDINFO_OPEN_OTHER; - - if (vcdinfo_get_format_version (obj) == VCD_TYPE_INVALID) - return VCDINFO_OPEN_OTHER; - - if (!read_entries(obj->img, &(obj->entries))) + if (!read_info(obj->img, &(obj->info), &(obj->vcd_type)) || + vcdinfo_get_format_version (obj) == VCD_TYPE_INVALID || + !read_entries(obj->img, &(obj->entries))) { + free (obj); /* match 0.7.23's behaviour */ return VCDINFO_OPEN_OTHER; + } { size_t len = strlen(*source_name)+1; diff --git a/src/input/vcd/libvcd/libvcd/.cvsignore b/src/input/vcd/libvcd/libvcd/.hgignore index 282522db0..282522db0 100644 --- a/src/input/vcd/libvcd/libvcd/.cvsignore +++ b/src/input/vcd/libvcd/libvcd/.hgignore diff --git a/src/input/vcd/libvcd/vcd.c b/src/input/vcd/libvcd/vcd.c index e9618a7d7..0772149ec 100644 --- a/src/input/vcd/libvcd/vcd.c +++ b/src/input/vcd/libvcd/vcd.c @@ -1,5 +1,5 @@ /* - $Id: vcd.c,v 1.3 2005/01/01 02:43:59 rockyb Exp $ + $Id: vcd.c,v 1.4 2006/12/08 16:26:10 mshopf Exp $ Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org> @@ -49,7 +49,7 @@ #include "util.h" #include "vcd.h" -static const char _rcsid[] = "$Id: vcd.c,v 1.3 2005/01/01 02:43:59 rockyb Exp $"; +static const char _rcsid[] = "$Id: vcd.c,v 1.4 2006/12/08 16:26:10 mshopf Exp $"; static const char zero[CDIO_CD_FRAMESIZE_RAW] = { 0, }; @@ -1664,7 +1664,7 @@ _write_sequence (VcdObj *obj, int track_idx) track->info->ahdr[i].bitrate / 1024, _mode_str[track->info->ahdr[i].mode]); - strncat (buf2, buf, sizeof(buf)); + strncat (buf2, buf, sizeof(buf2) - strlen(buf2) - 1); } vcd_info ("writing track %d, %s, %s, %s...", track_idx + 2, diff --git a/src/input/vcd/vcdio.c b/src/input/vcd/vcdio.c index 7fee5a0db..387397cf4 100644 --- a/src/input/vcd/vcdio.c +++ b/src/input/vcd/vcdio.c @@ -1,5 +1,5 @@ /* - $Id: vcdio.c,v 1.7 2005/06/14 17:27:12 rockyb Exp $ + $Id: vcdio.c,v 1.9 2007/03/23 21:47:31 dsalt Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> @@ -103,9 +103,20 @@ vcdio_open(vcdplayer_t *p_vcdplayer, char *intended_vcd_device) } } - if ( vcdinfo_open(&p_vcdplayer->vcd, &intended_vcd_device, DRIVER_UNKNOWN, - NULL) != VCDINFO_OPEN_VCD) { - return false; + switch ( vcdinfo_open(&p_vcdplayer->vcd, &intended_vcd_device, + DRIVER_UNKNOWN, NULL)) + { + case VCDINFO_OPEN_ERROR: + /* Failed to open the device => return failure */ + return false; + + case VCDINFO_OPEN_VCD: + /* Opened the device, and it's a VCD => proceed */ + break; + + default: + /* Opened the device, but it's not a VCD => is closed, return failure */ + return false; } p_vcdinfo = p_vcdplayer->vcd; diff --git a/src/input/vcd/vcdplayer.c b/src/input/vcd/vcdplayer.c index 27f726e3c..502d736cc 100644 --- a/src/input/vcd/vcdplayer.c +++ b/src/input/vcd/vcdplayer.c @@ -1,5 +1,5 @@ /* - $Id: vcdplayer.c,v 1.19 2005/06/20 02:17:41 rockyb Exp $ + $Id: vcdplayer.c,v 1.20 2007/02/21 23:17:14 dgp85 Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> @@ -46,6 +46,12 @@ #include "vcdplayer.h" #include "vcdio.h" +/* This function is _not_ exported by libvcd, its usage should be avoided, most + * likely. + */ +void vcdinfo_get_seg_resolution(const vcdinfo_obj_t *p_vcdinfo, segnum_t i_seg, + /*out*/ uint16_t *max_x, /*out*/ uint16_t *max_y); + #define LOG_ERR(p_vcdplayer, s, args...) \ if (p_vcdplayer != NULL && p_vcdplayer->log_err != NULL) \ p_vcdplayer->log_err("%s: "s, __func__ , ##args) diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c index baa6b0d9a..920b5c1d8 100644 --- a/src/input/vcd/xineplug_inp_vcd.c +++ b/src/input/vcd/xineplug_inp_vcd.c @@ -1,5 +1,5 @@ /* - $Id: xineplug_inp_vcd.c,v 1.50 2006/07/10 22:08:29 dgp85 Exp $ + $Id: xineplug_inp_vcd.c,v 1.53 2007/02/08 02:40:23 dsalt Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> @@ -322,6 +322,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device) unsigned int n, i=0; unsigned int i_entries; vcdinfo_obj_t *p_vcdinfo; + int was_open; if (NULL == class) { LOG_MSG("%s", _("was passed a null class parameter")); @@ -331,7 +332,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device) vcdplayer = &(my_vcd.player); /* If VCD already open, we gotta close and stop it. */ - if (vcdplayer->b_opened) { + if ((was_open = vcdplayer->b_opened)) { vcd_close(class); } @@ -374,6 +375,8 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device) if (NULL == class->mrls) { LOG_ERR("Can't calloc %d MRL entries", class->num_mrls); class->num_mrls = 0; + if (!was_open) + vcdio_close(vcdplayer); return false; } @@ -445,6 +448,8 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device) class->mrl_track_offset, class->mrl_entry_offset, class->mrl_play_offset, class->mrl_segment_offset); + if (!was_open) + vcdio_close(vcdplayer); return true; } @@ -1290,7 +1295,7 @@ vcd_get_optional_data (input_plugin_t *this_gen, dbg_print(INPUT_DBG_EXT, "AUDIO CHANNEL = %d\n", channel); if (channel == (uint8_t)-1) { - sprintf(data, " %s", "auto"); + strcpy(data, "auto"); } else { const vcdinfo_obj_t *p_vcdinfo= my_vcd.player.vcd; unsigned int audio_type; @@ -1315,9 +1320,9 @@ vcd_get_optional_data (input_plugin_t *this_gen, channel = (int8_t) _x_get_spu_channel(my_vcd.stream); dbg_print(INPUT_DBG_EXT, "SPU CHANNEL = %d\n", channel); if (-1 == channel) { - sprintf(data, " %s", "auto"); + strcpy(data, "auto"); } else { - sprintf(data, " %1d", channel); + sprintf(data, "%1d", channel); } } @@ -1824,9 +1829,9 @@ _("The VCD play unit to use when none is specified in an MRL, e.g. " class->vcd_device = - strdup (config->register_string(config, + strdup (config->register_filename(config, "media.vcd.device", - "", + "", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("CD-ROM drive used for VCD when none given"), _("What to use if no drive specified. If the setting is empty, xine will scan for CD drives."), 20, diff --git a/src/libdts/.cvsignore b/src/liba52/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libdts/.cvsignore +++ b/src/liba52/.hgignore diff --git a/src/liba52/Makefile.am b/src/liba52/Makefile.am index 40532479f..f296a0ef3 100644 --- a/src/liba52/Makefile.am +++ b/src/liba52/Makefile.am @@ -26,7 +26,7 @@ xineplug_decode_a52_la_SOURCES = \ if EXTERNAL_A52DEC xineplug_decode_a52_la_LIBADD = $(XINE_LIB) -la52 -lm else -xineplug_decode_a52_la_LIBADD = $(XINE_LIB) +xineplug_decode_a52_la_LIBADD = $(XINE_LIB) -lm endif xineplug_decode_a52_la_CFLAGS = $(VISIBILITY_FLAG) diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c index 9c770fbbc..5435e9664 100644 --- a/src/liba52/xine_decoder.c +++ b/src/liba52/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.80 2006/07/10 22:08:29 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.81 2007/02/20 00:34:57 dgp85 Exp $ * * stuff needed to turn liba52 into a xine decoder plugin */ @@ -425,7 +425,7 @@ static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { uint16_t crc16; uint16_t crc16_result; - lprintf ("decode data %d bytes of type %08x, pts=%lld\n", + lprintf ("decode data %d bytes of type %08x, pts=%"PRId64"\n", buf->size, buf->type, buf->pts); lprintf ("decode data decoder_info=%d, %d\n",buf->decoder_info[1],buf->decoder_info[2]); diff --git a/src/libfaad/.cvsignore b/src/libdts/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libfaad/.cvsignore +++ b/src/libdts/.hgignore diff --git a/src/libdts/Makefile.am b/src/libdts/Makefile.am index c2d86e073..4cf54884f 100644 --- a/src/libdts/Makefile.am +++ b/src/libdts/Makefile.am @@ -21,9 +21,9 @@ xineplug_decode_dts_la_CFLAGS = $(LIBDTS_CFLAGS) $(VISIBILITY_FLAG) $(fnsa) xineplug_decode_dts_la_LDFLAGS = -avoid-version -module if EXTERNAL_LIBDTS -xineplug_decode_dts_la_LIBADD = $(XINE_LIB) $(LIBDTS_LIBS) +xineplug_decode_dts_la_LIBADD = $(XINE_LIB) $(LIBDTS_LIBS) -lm else -xineplug_decode_dts_la_LIBADD = $(XINE_LIB) +xineplug_decode_dts_la_LIBADD = $(XINE_LIB) -lm endif noinst_HEADERS = bitstream.h dts.h dts_internal.h tables.h tables_adpcm.h \ diff --git a/src/libdts/xine_decoder.c b/src/libdts/xine_decoder.c index a97ee1a9b..902d8c5b6 100644 --- a/src/libdts/xine_decoder.c +++ b/src/libdts/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.66 2006/07/10 22:08:29 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.67 2007/02/20 00:34:57 dgp85 Exp $ * * 04-09-2001 DTS passtrough (C) Joachim Koenig * 09-12-2001 DTS passthrough inprovements (C) James Courtier-Dutton @@ -201,7 +201,7 @@ static void dts_decode_frame (dts_decoder_t *this, int64_t pts, int preview_mode } #endif - lprintf("length=%d pts=%lld\n",this->ac5_pcm_length,audio_buffer->vpts); + lprintf("length=%d pts=%"PRId64"\n",this->ac5_pcm_length,audio_buffer->vpts); audio_buffer->num_frames = this->ac5_pcm_length; diff --git a/src/libffmpeg/.cvsignore b/src/libfaad/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libffmpeg/.cvsignore +++ b/src/libfaad/.hgignore diff --git a/src/libfaad/Makefile.am b/src/libfaad/Makefile.am index cef72a4ce..dcc57792a 100644 --- a/src/libfaad/Makefile.am +++ b/src/libfaad/Makefile.am @@ -55,7 +55,7 @@ xineplug_decode_faad_la_SOURCES = \ xine_decoder.c xineplug_decode_faad_la_LDFLAGS = -avoid-version -module -xineplug_decode_faad_la_LIBADD = $(XINE_LIB) +xineplug_decode_faad_la_LIBADD = -lm $(XINE_LIB) noinst_HEADERS = \ analysis.h \ diff --git a/src/libfaad/codebook/.cvsignore b/src/libfaad/codebook/.hgignore index 282522db0..282522db0 100644 --- a/src/libfaad/codebook/.cvsignore +++ b/src/libfaad/codebook/.hgignore diff --git a/src/libfaad/xine_decoder.c b/src/libfaad/xine_decoder.c index bf6e9183c..aa528a34d 100644 --- a/src/libfaad/xine_decoder.c +++ b/src/libfaad/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.48 2006/07/10 22:08:29 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.49 2007/02/20 00:34:57 dgp85 Exp $ * */ @@ -140,7 +140,7 @@ static int faad_open_dec( faad_decoder_t *this ) { _("libfaad: libfaad NeAACDecInit2 failed.\n")); this->faac_failed++; } else - lprintf( "NeAACDecInit2 returned rate=%ld channels=%d\n", + lprintf( "NeAACDecInit2 returned rate=%"PRId32" channels=%d\n", this->rate, this->num_channels ); } else { used = NeAACDecInit(this->faac_dec, this->buf, this->size, @@ -151,7 +151,7 @@ static int faad_open_dec( faad_decoder_t *this ) { _("libfaad: libfaad NeAACDecInit failed.\n")); this->faac_failed++; } else { - lprintf( "NeAACDecInit() returned rate=%ld channels=%d (used=%d)\n", + lprintf( "NeAACDecInit() returned rate=%"PRId32" channels=%d (used=%d)\n", this->rate, this->num_channels, used); this->size -= used; @@ -239,7 +239,7 @@ static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) { this->num_channels = this->faac_finfo.channels; this->rate = this->faac_finfo.samplerate; - lprintf("faacDecDecode() returned rate=%ld channels=%d used=%d\n", + lprintf("faacDecDecode() returned rate=%"PRId32" channels=%d used=%d\n", this->rate, this->num_channels, used); this->stream->audio_out->close (this->stream->audio_out, this->stream); diff --git a/src/libflac/.cvsignore b/src/libffmpeg/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libflac/.cvsignore +++ b/src/libffmpeg/.hgignore diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am index cf925bd3b..9ea37cd17 100644 --- a/src/libffmpeg/Makefile.am +++ b/src/libffmpeg/Makefile.am @@ -22,6 +22,9 @@ $(top_builddir)/contrib/ffmpeg/libpostproc/libpostproc.a: $(MAKE) -C $(top_builddir)/contrib/ffmpeg/ -f makefile.xine libpostproc/libpostproc.a endif +# ffmpeg_config.h is generated by configure +DISTCLEANFILES = ffmpeg_config.h + # this must always be included, even if the current machine has no DXR3... EXTRA_DIST = xine_encoder.c diff_to_ffmpeg_cvs.txt @@ -45,7 +48,7 @@ endif xineplug_decode_ff_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_decode_ff_la_LDFLAGS = -avoid-version -module @IMPURE_TEXT_LDFLAGS@ xineplug_decode_ff_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm $(ZLIB_LIBS) \ - $(link_ffmpeg) $(THREAD_LIBS) + $(link_ffmpeg) $(PTHREAD_LIBS) xineplug_decode_dvaudio_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) xineplug_decode_dvaudio_la_LDFLAGS = -avoid-version -module diff --git a/src/libffmpeg/audio_decoder.c b/src/libffmpeg/audio_decoder.c index c0a4503e2..7ab1f56b4 100644 --- a/src/libffmpeg/audio_decoder.c +++ b/src/libffmpeg/audio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_decoder.c,v 1.29 2006/10/13 21:41:30 dgp85 Exp $ + * $Id: audio_decoder.c,v 1.33 2007/01/28 18:38:33 miguelfreitas Exp $ * * xine audio decoder plugin using ffmpeg * @@ -25,6 +25,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" +#include "ffmpeg_config.h" #endif #include <stdlib.h> @@ -107,6 +108,8 @@ static const ff_codec_t ff_audio_lookup[] = { {BUF_AUDIO_TRUESPEECH, CODEC_ID_TRUESPEECH, "TrueSpeech (ffmpeg)"}, {BUF_AUDIO_TTA, CODEC_ID_TTA, "True Audio Lossless (ffmpeg)"}, {BUF_AUDIO_SMACKER, CODEC_ID_SMACKAUDIO, "Smacker (ffmpeg)"}, + {BUF_AUDIO_FLVADPCM, CODEC_ID_ADPCM_SWF, "Flash ADPCM (ffmpeg)"}, + {BUF_AUDIO_WAVPACK, CODEC_ID_WAVPACK, "WavPack (ffmpeg)"}, }; @@ -288,7 +291,8 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) offset = 0; while (this->size>0) { - bytes_consumed = avcodec_decode_audio (this->context, + decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; + bytes_consumed = avcodec_decode_audio2 (this->context, (int16_t *)this->decode_buffer, &decode_buffer_size, &this->buf[offset], @@ -441,37 +445,106 @@ void *init_audio_plugin (xine_t *xine, void *data) { } static uint32_t supported_audio_types[] = { + #ifdef CONFIG_WMAV1_DECODER BUF_AUDIO_WMAV1, + #endif + #ifdef CONFIG_WMAV2_DECODER BUF_AUDIO_WMAV2, + #endif + #ifdef CONFIG_RA_144_DECODER BUF_AUDIO_14_4, + #endif + #ifdef CONFIG_RA_288_DECODER BUF_AUDIO_28_8, - BUF_AUDIO_MULAW, - BUF_AUDIO_ALAW, + #endif + #ifdef CONFIG_MP3_DECODER + BUF_AUDIO_MPEG, + #endif + #ifdef CONFIG_ADPCM_MS_DECODER BUF_AUDIO_MSADPCM, + #endif + #ifdef CONFIG_ADPCM_IMA_QT_DECODER BUF_AUDIO_QTIMAADPCM, + #endif + #ifdef CONFIG_ADPCM_IMA_WAV_DECODER BUF_AUDIO_MSIMAADPCM, + #endif + #ifdef CONFIG_ADPCM_IMA_DK3_DECODER BUF_AUDIO_DK3ADPCM, + #endif + #ifdef CONFIG_ADPCM_IMA_DK4_DECODER BUF_AUDIO_DK4ADPCM, + #endif + #ifdef CONFIG_ADPCM_IMA_WS_DECODER + BUF_AUDIO_VQA_IMA, + #endif + #ifdef CONFIG_ADPCM_IMA_SMJPEG_DECODER + BUF_AUDIO_SMJPEG_IMA, + #endif + #ifdef CONFIG_ADPCM_XA_DECODER BUF_AUDIO_XA_ADPCM, + #endif + #ifdef CONFIG_ADPCM_4XM_DECODER + BUF_AUDIO_4X_ADPCM, + #endif + #ifdef CONFIG_ADPCM_EA_DECODER + BUF_AUDIO_EA_ADPCM, + #endif + #ifdef CONFIG_PCM_MULAW_DECODER + BUF_AUDIO_MULAW, + #endif + #ifdef CONFIG_PCM_ALAW_DECODER + BUF_AUDIO_ALAW, + #endif + #ifdef CONFIG_ROQ_DPCM_DECODER BUF_AUDIO_ROQ, + #endif + #ifdef CONFIG_INTERPLAY_DPCM_DECODER BUF_AUDIO_INTERPLAY, - BUF_AUDIO_VQA_IMA, - BUF_AUDIO_4X_ADPCM, + #endif + #ifdef CONFIG_MACE3_DECODER BUF_AUDIO_MAC3, + #endif + #ifdef CONFIG_MACE6_DECODER BUF_AUDIO_MAC6, + #endif + #ifdef CONFIG_XAN_DPCM_DECODER BUF_AUDIO_XAN_DPCM, + #endif + #ifdef CONFIG_VMDAUDIO_DECODER BUF_AUDIO_VMD, - BUF_AUDIO_EA_ADPCM, - BUF_AUDIO_SMJPEG_IMA, + #endif + #ifdef CONFIG_FLAC_DECODER BUF_AUDIO_FLAC, - BUF_AUDIO_ALAC, + #endif + #ifdef CONFIG_SHORTEN_DECODER BUF_AUDIO_SHORTEN, - BUF_AUDIO_MPEG, + #endif + #ifdef CONFIG_ALAC_DECODER + BUF_AUDIO_ALAC, + #endif + #ifdef CONFIG_QDM2_DECODER BUF_AUDIO_QDESIGN2, + #endif + #ifdef CONFIG_COOK_DECODER BUF_AUDIO_COOK, + #endif + #ifdef CONFIG_TRUESPEECH_DECODER BUF_AUDIO_TRUESPEECH, + #endif + #ifdef CONFIG_TTA_DECODER BUF_AUDIO_TTA, + #endif + #ifdef CONFIG_SMACKAUDIO_DECODER BUF_AUDIO_SMACKER, + #endif + #ifdef CONFIG_ADPCM_SWF_DECODER + BUF_AUDIO_FLVADPCM, + #endif + #ifdef CONFIG_WAVPACK_DECODER + BUF_AUDIO_WAVPACK, + #endif + 0 }; diff --git a/src/libffmpeg/dvaudio_decoder.c b/src/libffmpeg/dvaudio_decoder.c index 71e58417b..ff9a8435c 100644 --- a/src/libffmpeg/dvaudio_decoder.c +++ b/src/libffmpeg/dvaudio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dvaudio_decoder.c,v 1.11.2.1 2006/12/02 01:20:07 dgp85 Exp $ + * $Id: dvaudio_decoder.c,v 1.11 2006/07/10 22:08:29 dgp85 Exp $ * * dv audio decoder based on patch by Dan Dennedy <dan@dennedy.org> * @@ -91,6 +91,22 @@ typedef struct dvaudio_decoder_s { } dvaudio_decoder_t; + +enum dv_pack_type { + dv_header525 = 0x3f, /* see dv_write_pack for important details on */ + dv_header625 = 0xbf, /* these two packs */ + dv_timecode = 0x13, + dv_audio_source = 0x50, + dv_audio_control = 0x51, + dv_audio_recdate = 0x52, + dv_audio_rectime = 0x53, + dv_video_source = 0x60, + dv_video_control = 0x61, + dv_viedo_recdate = 0x62, + dv_video_rectime = 0x63, + dv_unknown_pack = 0xff, +}; + /* * This is the dumbest implementation of all -- it simply looks at * a fixed offset and if pack isn't there -- fails. We might want diff --git a/src/liblpcm/.cvsignore b/src/libffmpeg/libavcodec/.hgignore index 7d926a554..7d926a554 100644 --- a/src/liblpcm/.cvsignore +++ b/src/libffmpeg/libavcodec/.hgignore diff --git a/src/libmad/.cvsignore b/src/libffmpeg/libavcodec/alpha/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libmad/.cvsignore +++ b/src/libffmpeg/libavcodec/alpha/.hgignore diff --git a/src/libmpeg2/.cvsignore b/src/libffmpeg/libavcodec/armv4l/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libmpeg2/.cvsignore +++ b/src/libffmpeg/libavcodec/armv4l/.hgignore diff --git a/src/libffmpeg/libavcodec/armv4l/dsputil_arm_s.S b/src/libffmpeg/libavcodec/armv4l/dsputil_arm_s.S new file mode 100644 index 000000000..2a3ee9c50 --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/dsputil_arm_s.S @@ -0,0 +1,696 @@ +@ +@ ARMv4L optimized DSP utils +@ Copyright (c) 2004 AGAWA Koji <i (AT) atty (DOT) jp> +@ +@ This file is part of FFmpeg. +@ +@ FFmpeg is free software; you can redistribute it and/or +@ modify it under the terms of the GNU Lesser General Public +@ License as published by the Free Software Foundation; either +@ version 2.1 of the License, or (at your option) any later version. +@ +@ FFmpeg is distributed in the hope that it will be useful, +@ but WITHOUT ANY WARRANTY; without even the implied warranty of +@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@ Lesser General Public License for more details. +@ +@ You should have received a copy of the GNU Lesser General Public +@ License along with FFmpeg; if not, write to the Free Software +@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +@ + +.macro ADJ_ALIGN_QUADWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4 + mov \Rd0, \Rn0, lsr #(\shift * 8) + mov \Rd1, \Rn1, lsr #(\shift * 8) + mov \Rd2, \Rn2, lsr #(\shift * 8) + mov \Rd3, \Rn3, lsr #(\shift * 8) + orr \Rd0, \Rd0, \Rn1, lsl #(32 - \shift * 8) + orr \Rd1, \Rd1, \Rn2, lsl #(32 - \shift * 8) + orr \Rd2, \Rd2, \Rn3, lsl #(32 - \shift * 8) + orr \Rd3, \Rd3, \Rn4, lsl #(32 - \shift * 8) +.endm +.macro ADJ_ALIGN_DOUBLEWORD shift, R0, R1, R2 + mov \R0, \R0, lsr #(\shift * 8) + orr \R0, \R0, \R1, lsl #(32 - \shift * 8) + mov \R1, \R1, lsr #(\shift * 8) + orr \R1, \R1, \R2, lsl #(32 - \shift * 8) +.endm +.macro ADJ_ALIGN_DOUBLEWORD_D shift, Rdst0, Rdst1, Rsrc0, Rsrc1, Rsrc2 + mov \Rdst0, \Rsrc0, lsr #(\shift * 8) + mov \Rdst1, \Rsrc1, lsr #(\shift * 8) + orr \Rdst0, \Rdst0, \Rsrc1, lsl #(32 - (\shift * 8)) + orr \Rdst1, \Rdst1, \Rsrc2, lsl #(32 - (\shift * 8)) +.endm + +.macro RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask + @ Rd = (Rn | Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1) + @ Rmask = 0xFEFEFEFE + @ Rn = destroy + eor \Rd0, \Rn0, \Rm0 + eor \Rd1, \Rn1, \Rm1 + orr \Rn0, \Rn0, \Rm0 + orr \Rn1, \Rn1, \Rm1 + and \Rd0, \Rd0, \Rmask + and \Rd1, \Rd1, \Rmask + sub \Rd0, \Rn0, \Rd0, lsr #1 + sub \Rd1, \Rn1, \Rd1, lsr #1 +.endm + +.macro NO_RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask + @ Rd = (Rn & Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1) + @ Rmask = 0xFEFEFEFE + @ Rn = destroy + eor \Rd0, \Rn0, \Rm0 + eor \Rd1, \Rn1, \Rm1 + and \Rn0, \Rn0, \Rm0 + and \Rn1, \Rn1, \Rm1 + and \Rd0, \Rd0, \Rmask + and \Rd1, \Rd1, \Rmask + add \Rd0, \Rn0, \Rd0, lsr #1 + add \Rd1, \Rn1, \Rd1, lsr #1 +.endm + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels16_arm +put_pixels16_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11, lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + bic r1, r1, #3 + add r5, r5, r4, lsl #2 + ldrne pc, [r5] +1: + ldmia r1, {r4-r7} + add r1, r1, r2 + stmia r0, {r4-r7} + pld [r1] + subs r3, r3, #1 + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r11, pc} + .align 8 +2: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 1, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r11, pc} + .align 8 +3: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 2, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r11, pc} + .align 8 +4: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 3, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r11,pc} + .align 8 +5: + .word 1b + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_arm +put_pixels8_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r5,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + bic r1, r1, #3 + add r5, r5, r4, lsl #2 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 + subs r3, r3, #1 + pld [r1] + stmia r0, {r4-r5} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r5,pc} + .align 8 +2: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r5,pc} + .align 8 +3: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r5,pc} + .align 8 +4: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r5,pc} + .align 8 +5: + .word 1b + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_x2_arm +put_pixels8_x2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r10,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + pld [r1] + RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r10,pc} + .align 8 +2: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 + pld [r1] + RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r10,pc} + .align 8 +3: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 + pld [r1] + RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r10,pc} + .align 8 +4: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 + pld [r1] + RND_AVG32 r8, r9, r6, r7, r5, r10, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r10,pc} @@ update PC with LR content. + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + .align 8 + .global put_no_rnd_pixels8_x2_arm +put_no_rnd_pixels8_x2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r10,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r10,pc} + .align 8 +2: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r10,pc} + .align 8 +3: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r10,pc} + .align 8 +4: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r8, r9, r6, r7, r5, r10, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r10,pc} @@ update PC with LR content. + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_y2_arm +put_pixels8_y2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + mov r3, r3, lsr #1 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 +6: ldmia r1, {r6-r7} + add r1, r1, r2 + pld [r1] + RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + ldmia r1, {r4-r5} + add r1, r1, r2 + stmia r0, {r8-r9} + add r0, r0, r2 + pld [r1] + RND_AVG32 r8, r9, r6, r7, r4, r5, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +2: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +3: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +4: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + .align 8 + .global put_no_rnd_pixels8_y2_arm +put_no_rnd_pixels8_y2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + mov r3, r3, lsr #1 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 +6: ldmia r1, {r6-r7} + add r1, r1, r2 + pld [r1] + NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + ldmia r1, {r4-r5} + add r1, r1, r2 + stmia r0, {r8-r9} + add r0, r0, r2 + pld [r1] + NO_RND_AVG32 r8, r9, r6, r7, r4, r5, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +2: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +3: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +4: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- +.macro RND_XY2_IT align, rnd + @ l1= (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202) + @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2) +.if \align == 0 + ldmia r1, {r6-r8} +.elseif \align == 3 + ldmia r1, {r5-r7} +.else + ldmia r1, {r8-r10} +.endif + add r1, r1, r2 + pld [r1] +.if \align == 0 + ADJ_ALIGN_DOUBLEWORD_D 1, r4, r5, r6, r7, r8 +.elseif \align == 1 + ADJ_ALIGN_DOUBLEWORD_D 1, r4, r5, r8, r9, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r8, r9, r10 +.elseif \align == 2 + ADJ_ALIGN_DOUBLEWORD_D 2, r4, r5, r8, r9, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r8, r9, r10 +.elseif \align == 3 + ADJ_ALIGN_DOUBLEWORD_D 3, r4, r5, r5, r6, r7 +.endif + ldr r14, [r12, #0] @ 0x03030303 + tst r3, #1 + and r8, r4, r14 + and r9, r5, r14 + and r10, r6, r14 + and r11, r7, r14 +.if \rnd == 1 + ldreq r14, [r12, #16] @ 0x02020202 +.else + ldreq r14, [r12, #28] @ 0x01010101 +.endif + add r8, r8, r10 + add r9, r9, r11 + addeq r8, r8, r14 + addeq r9, r9, r14 + ldr r14, [r12, #20] @ 0xFCFCFCFC >> 2 + and r4, r14, r4, lsr #2 + and r5, r14, r5, lsr #2 + and r6, r14, r6, lsr #2 + and r7, r14, r7, lsr #2 + add r10, r4, r6 + add r11, r5, r7 +.endm + +.macro RND_XY2_EXPAND align, rnd + RND_XY2_IT \align, \rnd +6: stmfd sp!, {r8-r11} + RND_XY2_IT \align, \rnd + ldmfd sp!, {r4-r7} + add r4, r4, r8 + add r5, r5, r9 + add r6, r6, r10 + add r7, r7, r11 + ldr r14, [r12, #24] @ 0x0F0F0F0F + and r4, r14, r4, lsr #2 + and r5, r14, r5, lsr #2 + add r4, r4, r6 + add r5, r5, r7 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} +.endm + + .align 8 + .global put_pixels8_xy2_arm +put_pixels8_xy2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adrl r12, 5f + ands r4, r1, #3 + add r5, r12, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + RND_XY2_EXPAND 0, 1 + + .align 8 +2: + RND_XY2_EXPAND 1, 1 + + .align 8 +3: + RND_XY2_EXPAND 2, 1 + + .align 8 +4: + RND_XY2_EXPAND 3, 1 + +5: + .word 0x03030303 + .word 2b + .word 3b + .word 4b + .word 0x02020202 + .word 0xFCFCFCFC >> 2 + .word 0x0F0F0F0F + .word 0x01010101 + + .align 8 + .global put_no_rnd_pixels8_xy2_arm +put_no_rnd_pixels8_xy2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adrl r12, 5f + ands r4, r1, #3 + add r5, r12, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + RND_XY2_EXPAND 0, 0 + + .align 8 +2: + RND_XY2_EXPAND 1, 0 + + .align 8 +3: + RND_XY2_EXPAND 2, 0 + + .align 8 +4: + RND_XY2_EXPAND 3, 0 + +5: + .word 0x03030303 + .word 2b + .word 3b + .word 4b + .word 0x02020202 + .word 0xFCFCFCFC >> 2 + .word 0x0F0F0F0F + .word 0x01010101 diff --git a/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c b/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c new file mode 100644 index 000000000..d7401e760 --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c @@ -0,0 +1,188 @@ +/* + * iWMMXt optimized DSP utils + * Copyright (c) 2004 AGAWA Koji + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" + +#define DEF(x, y) x ## _no_rnd_ ## y ##_iwmmxt +#define SET_RND(regd) __asm__ __volatile__ ("mov r12, #1 \n\t tbcsth " #regd ", r12":::"r12"); +#define WAVG2B "wavg2b" +#include "dsputil_iwmmxt_rnd.h" +#undef DEF +#undef SET_RND +#undef WAVG2B + +#define DEF(x, y) x ## _ ## y ##_iwmmxt +#define SET_RND(regd) __asm__ __volatile__ ("mov r12, #2 \n\t tbcsth " #regd ", r12":::"r12"); +#define WAVG2B "wavg2br" +#include "dsputil_iwmmxt_rnd.h" +#undef DEF +#undef SET_RND +#undef WAVG2BR + +// need scheduling +#define OP(AVG) \ + asm volatile ( \ + /* alignment */ \ + "and r12, %[pixels], #7 \n\t" \ + "bic %[pixels], %[pixels], #7 \n\t" \ + "tmcr wcgr1, r12 \n\t" \ + \ + "wldrd wr0, [%[pixels]] \n\t" \ + "wldrd wr1, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "walignr1 wr4, wr0, wr1 \n\t" \ + \ + "1: \n\t" \ + \ + "wldrd wr2, [%[pixels]] \n\t" \ + "wldrd wr3, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "pld [%[pixels]] \n\t" \ + "walignr1 wr5, wr2, wr3 \n\t" \ + AVG " wr6, wr4, wr5 \n\t" \ + "wstrd wr6, [%[block]] \n\t" \ + "add %[block], %[block], %[line_size] \n\t" \ + \ + "wldrd wr0, [%[pixels]] \n\t" \ + "wldrd wr1, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "walignr1 wr4, wr0, wr1 \n\t" \ + "pld [%[pixels]] \n\t" \ + AVG " wr6, wr4, wr5 \n\t" \ + "wstrd wr6, [%[block]] \n\t" \ + "add %[block], %[block], %[line_size] \n\t" \ + \ + "subs %[h], %[h], #2 \n\t" \ + "bne 1b \n\t" \ + : [block]"+r"(block), [pixels]"+r"(pixels), [h]"+r"(h) \ + : [line_size]"r"(line_size) \ + : "memory", "r12"); +void put_pixels8_y2_iwmmxt(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + OP("wavg2br"); +} +void put_no_rnd_pixels8_y2_iwmmxt(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + OP("wavg2b"); +} +#undef OP + +void add_pixels_clamped_iwmmxt(const DCTELEM *block, uint8_t *pixels, int line_size) +{ + uint8_t *pixels2 = pixels + line_size; + + __asm__ __volatile__ ( + "mov r12, #4 \n\t" + "1: \n\t" + "pld [%[pixels], %[line_size2]] \n\t" + "pld [%[pixels2], %[line_size2]] \n\t" + "wldrd wr4, [%[pixels]] \n\t" + "wldrd wr5, [%[pixels2]] \n\t" + "pld [%[block], #32] \n\t" + "wunpckelub wr6, wr4 \n\t" + "wldrd wr0, [%[block]] \n\t" + "wunpckehub wr7, wr4 \n\t" + "wldrd wr1, [%[block], #8] \n\t" + "wunpckelub wr8, wr5 \n\t" + "wldrd wr2, [%[block], #16] \n\t" + "wunpckehub wr9, wr5 \n\t" + "wldrd wr3, [%[block], #24] \n\t" + "add %[block], %[block], #32 \n\t" + "waddhss wr10, wr0, wr6 \n\t" + "waddhss wr11, wr1, wr7 \n\t" + "waddhss wr12, wr2, wr8 \n\t" + "waddhss wr13, wr3, wr9 \n\t" + "wpackhus wr14, wr10, wr11 \n\t" + "wpackhus wr15, wr12, wr13 \n\t" + "wstrd wr14, [%[pixels]] \n\t" + "add %[pixels], %[pixels], %[line_size2] \n\t" + "subs r12, r12, #1 \n\t" + "wstrd wr15, [%[pixels2]] \n\t" + "add %[pixels2], %[pixels2], %[line_size2] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [pixels2]"+r"(pixels2) + : [line_size2]"r"(line_size << 1) + : "cc", "memory", "r12"); +} + +static void nop(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + return; +} + +int mm_flags; /* multimedia extension flags */ + +int mm_support(void) +{ + return 0; /* TODO, implement proper detection */ +} + +void dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx) +{ + mm_flags = mm_support(); + + if (avctx->dsp_mask) { + if (avctx->dsp_mask & FF_MM_FORCE) + mm_flags |= (avctx->dsp_mask & 0xffff); + else + mm_flags &= ~(avctx->dsp_mask & 0xffff); + } + + if (!(mm_flags & MM_IWMMXT)) return; + + c->add_pixels_clamped = add_pixels_clamped_iwmmxt; + + c->put_pixels_tab[0][0] = put_pixels16_iwmmxt; + c->put_pixels_tab[0][1] = put_pixels16_x2_iwmmxt; + c->put_pixels_tab[0][2] = put_pixels16_y2_iwmmxt; + c->put_pixels_tab[0][3] = put_pixels16_xy2_iwmmxt; + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_iwmmxt; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_iwmmxt; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_iwmmxt; + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_iwmmxt; + + c->put_pixels_tab[1][0] = put_pixels8_iwmmxt; + c->put_pixels_tab[1][1] = put_pixels8_x2_iwmmxt; + c->put_pixels_tab[1][2] = put_pixels8_y2_iwmmxt; + c->put_pixels_tab[1][3] = put_pixels8_xy2_iwmmxt; + c->put_no_rnd_pixels_tab[1][0] = put_pixels8_iwmmxt; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_iwmmxt; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_iwmmxt; + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_iwmmxt; + + c->avg_pixels_tab[0][0] = avg_pixels16_iwmmxt; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_iwmmxt; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_iwmmxt; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][0] = avg_pixels16_iwmmxt; + c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_iwmmxt; + + c->avg_pixels_tab[1][0] = avg_pixels8_iwmmxt; + c->avg_pixels_tab[1][1] = avg_pixels8_x2_iwmmxt; + c->avg_pixels_tab[1][2] = avg_pixels8_y2_iwmmxt; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_iwmmxt; + c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy2_iwmmxt; +} diff --git a/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h b/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h new file mode 100644 index 000000000..51ba61c47 --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h @@ -0,0 +1,1114 @@ +/* + * iWMMXt optimized DSP utils + * copyright (c) 2004 AGAWA Koji + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +void DEF(put, pixels8)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr4, [r4, #8] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr4, [r4, #8] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr0, [%[block]] \n\t" + "wldrd wr2, [r5] \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + WAVG2B" wr8, wr8, wr0 \n\t" + WAVG2B" wr10, wr10, wr2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(put, pixels16)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr2, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr4, [r4, #8] \n\t" + "walignr1 wr9, wr1, wr2 \n\t" + "wldrd wr5, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wstrd wr8, [%[block]] \n\t" + "walignr1 wr11, wr4, wr5 \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "wstrd wr11, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr2, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr4, [r4, #8] \n\t" + "walignr1 wr9, wr1, wr2 \n\t" + "wldrd wr5, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "wldrd wr0, [%[block]] \n\t" + "pld [r4] \n\t" + "wldrd wr1, [%[block], #8] \n\t" + "pld [r4, #32] \n\t" + "wldrd wr2, [r5] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wldrd wr3, [r5, #8] \n\t" + WAVG2B" wr8, wr8, wr0 \n\t" + WAVG2B" wr9, wr9, wr1 \n\t" + WAVG2B" wr10, wr10, wr2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "walignr1 wr11, wr4, wr5 \n\t" + WAVG2B" wr11, wr11, wr3 \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "wstrd wr11, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr6, wr14 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr2, [r5] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr15, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "walignr1 wr3, wr14, wr15 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr5, wr12 \n\t" + "wmoveq wr6, wr14 \n\t" + "wmoveq wr7, wr15 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr5, wr11, wr12 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "walignr2ne wr7, wr14, wr15 \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr1, wr1, wr5 \n\t" + "wstrd wr0, [%[block]] \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wstrd wr1, [%[block], #8] \n\t" + WAVG2B" wr3, wr3, wr7 \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr2, [r5] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr3, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr6, wr14 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "wldrd wr12, [r5] \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + WAVG2B" wr0, wr0, wr10 \n\t" + WAVG2B" wr2, wr2, wr12 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr2, [r5] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr15, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "walignr1 wr3, wr14, wr15 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr5, wr12 \n\t" + "wmoveq wr6, wr14 \n\t" + "wmoveq wr7, wr15 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr5, wr11, wr12 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "walignr2ne wr7, wr14, wr15 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr1, wr1, wr5 \n\t" + "wldrd wr12, [r5] \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wldrd wr13, [r5, #8] \n\t" + WAVG2B" wr3, wr3, wr7 \n\t" + WAVG2B" wr0, wr0, wr10 \n\t" + WAVG2B" wr1, wr1, wr11 \n\t" + WAVG2B" wr2, wr2, wr12 \n\t" + WAVG2B" wr3, wr3, wr13 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr1, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr2, [r5] \n\t" + "pld [%[block]] \n\t" + "wstrd wr3, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [%[block], #32] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + :"r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "cc", "memory", "r12"); +} + +void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "walignr1 wr5, wr11, wr12 \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "walignr1 wr5, wr11, wr12 \n\t" + "wldrd wr10, [%[block]] \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + WAVG2B" wr9, wr9, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "wldrd wr10, [%[block]] \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + WAVG2B" wr9, wr9, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "add r12, r12, #1 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "tmcr wcgr2, r12 \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "cmp r12, #8 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + /* alignment */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "tmcr wcgr2, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr7, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr6, wr7 \n\t" + "wunpckehub wr7, wr7 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr6, wr6, wr10 \n\t" + "waddhus wr7, wr7, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "add r12, r12, #1 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "tmcr wcgr2, r12 \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "cmp r12, #8 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wldrd wr12, [%[pixels]] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "subs %[h], %[h], #2 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + /* alignment */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "tmcr wcgr2, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr7, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr6, wr7 \n\t" + "wunpckehub wr7, wr7 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr6, wr6, wr10 \n\t" + "waddhus wr7, wr7, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wldrd wr13, [%[block], #8] \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + WAVG2B" wr9, wr9, wr13 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "pld [%[block]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "pld [%[block], #32] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wldrd wr13, [%[block], #8] \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + WAVG2B" wr9, wr9, wr13 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} diff --git a/src/libffmpeg/libavcodec/armv4l/mathops.h b/src/libffmpeg/libavcodec/armv4l/mathops.h new file mode 100644 index 000000000..7ddd0ec6e --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/mathops.h @@ -0,0 +1,49 @@ +/* + * simple math operations + * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef FRAC_BITS +# define MULL(a, b) \ + ({ int lo, hi;\ + asm("smull %0, %1, %2, %3 \n\t"\ + "mov %0, %0, lsr %4\n\t"\ + "add %1, %0, %1, lsl %5\n\t"\ + : "=&r"(lo), "=&r"(hi)\ + : "r"(b), "r"(a), "i"(FRAC_BITS), "i"(32-FRAC_BITS));\ + hi; }) +#endif + +#define MULH(a, b) \ + ({ int lo, hi;\ + asm ("smull %0, %1, %2, %3" : "=&r"(lo), "=&r"(hi) : "r"(b), "r"(a));\ + hi; }) + +#if defined(HAVE_ARMV5TE) + +/* signed 16x16 -> 32 multiply add accumulate */ +# define MAC16(rt, ra, rb) \ + asm ("smlabb %0, %2, %3, %0" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb)); +/* signed 16x16 -> 32 multiply */ +# define MUL16(ra, rb) \ + ({ int __rt; \ + asm ("smulbb %0, %1, %2" : "=r" (__rt) : "r" (ra), "r" (rb)); \ + __rt; }) + +#endif diff --git a/src/libffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c b/src/libffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c new file mode 100644 index 000000000..a8d09b8ce --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c @@ -0,0 +1,213 @@ +/* + * Optimization of some functions from mpegvideo.c for armv5te + * Copyright (c) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Some useful links for those who may be interested in optimizing code for ARM. + * ARM Architecture Reference Manual: http://www.arm.com/community/academy/resources.html + * Instructions timings and optimization guide for ARM9E: http://www.arm.com/pdfs/DDI0222B_9EJS_r1p2.pdf + */ + +#include "../dsputil.h" +#include "../mpegvideo.h" +#include "../avcodec.h" + + +#ifdef ENABLE_ARM_TESTS +/** + * h263 dequantizer supplementary function, it is performance critical and needs to + * have optimized implementations for each architecture. Is also used as a reference + * implementation in regression tests + */ +static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qadd, int count) +{ + int i, level; + for (i = 0; i < count; i++) { + level = block[i]; + if (level) { + if (level < 0) { + level = level * qmul - qadd; + } else { + level = level * qmul + qadd; + } + block[i] = level; + } + } +} +#endif + +/* GCC 3.1 or higher is required to support symbolic names in assembly code */ +#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) + +/** + * Special optimized version of dct_unquantize_h263_helper_c, it requires the block + * to be at least 8 bytes aligned, and may process more elements than requested. + * But it is guaranteed to never process more than 64 elements provided that + * xxcount argument is <= 64, so it is safe. This macro is optimized for a common + * distribution of values for nCoeffs (they are mostly multiple of 8 plus one or + * two extra elements). So this macro processes data as 8 elements per loop iteration + * and contains optional 2 elements processing in the end. + * + * Inner loop should take 6 cycles per element on arm926ej-s (Nokia 770) + */ +#define dct_unquantize_h263_special_helper_armv5te(xxblock, xxqmul, xxqadd, xxcount) \ +({ DCTELEM *xblock = xxblock; \ + int xqmul = xxqmul, xqadd = xxqadd, xcount = xxcount, xtmp; \ + int xdata1, xdata2; \ +__asm__ __volatile__( \ + "subs %[count], #2 \n\t" \ + "ble 2f \n\t" \ + "ldrd r4, [%[block], #0] \n\t" \ + "1: \n\t" \ + "ldrd r6, [%[block], #8] \n\t" \ +\ + "rsbs %[data1], %[zero], r4, asr #16 \n\t" \ + "addgt %[data1], %[qadd], #0 \n\t" \ + "rsblt %[data1], %[qadd], #0 \n\t" \ + "smlatbne %[data1], r4, %[qmul], %[data1] \n\t" \ +\ + "rsbs %[data2], %[zero], r5, asr #16 \n\t" \ + "addgt %[data2], %[qadd], #0 \n\t" \ + "rsblt %[data2], %[qadd], #0 \n\t" \ + "smlatbne %[data2], r5, %[qmul], %[data2] \n\t" \ +\ + "rsbs %[tmp], %[zero], r4, asl #16 \n\t" \ + "addgt %[tmp], %[qadd], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne r4, r4, %[qmul], %[tmp] \n\t" \ +\ + "rsbs %[tmp], %[zero], r5, asl #16 \n\t" \ + "addgt %[tmp], %[qadd], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne r5, r5, %[qmul], %[tmp] \n\t" \ +\ + "strh r4, [%[block]], #2 \n\t" \ + "strh %[data1], [%[block]], #2 \n\t" \ + "strh r5, [%[block]], #2 \n\t" \ + "strh %[data2], [%[block]], #2 \n\t" \ +\ + "rsbs %[data1], %[zero], r6, asr #16 \n\t" \ + "addgt %[data1], %[qadd], #0 \n\t" \ + "rsblt %[data1], %[qadd], #0 \n\t" \ + "smlatbne %[data1], r6, %[qmul], %[data1] \n\t" \ +\ + "rsbs %[data2], %[zero], r7, asr #16 \n\t" \ + "addgt %[data2], %[qadd], #0 \n\t" \ + "rsblt %[data2], %[qadd], #0 \n\t" \ + "smlatbne %[data2], r7, %[qmul], %[data2] \n\t" \ +\ + "rsbs %[tmp], %[zero], r6, asl #16 \n\t" \ + "addgt %[tmp], %[qadd], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne r6, r6, %[qmul], %[tmp] \n\t" \ +\ + "rsbs %[tmp], %[zero], r7, asl #16 \n\t" \ + "addgt %[tmp], %[qadd], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne r7, r7, %[qmul], %[tmp] \n\t" \ +\ + "strh r6, [%[block]], #2 \n\t" \ + "strh %[data1], [%[block]], #2 \n\t" \ + "strh r7, [%[block]], #2 \n\t" \ + "strh %[data2], [%[block]], #2 \n\t" \ +\ + "subs %[count], #8 \n\t" \ + "ldrgtd r4, [%[block], #0] \n\t" /* load data early to avoid load/use pipeline stall */ \ + "bgt 1b \n\t" \ +\ + "adds %[count], #2 \n\t" \ + "ble 3f \n\t" \ + "2: \n\t" \ + "ldrsh %[data1], [%[block], #0] \n\t" \ + "ldrsh %[data2], [%[block], #2] \n\t" \ + "mov %[tmp], %[qadd] \n\t" \ + "cmp %[data1], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne %[data1], %[data1], %[qmul], %[tmp] \n\t" \ + "mov %[tmp], %[qadd] \n\t" \ + "cmp %[data2], #0 \n\t" \ + "rsblt %[tmp], %[qadd], #0 \n\t" \ + "smlabbne %[data2], %[data2], %[qmul], %[tmp] \n\t" \ + "strh %[data1], [%[block]], #2 \n\t" \ + "strh %[data2], [%[block]], #2 \n\t" \ + "3: \n\t" \ + : [block] "+&r" (xblock), [count] "+&r" (xcount), [tmp] "=&r" (xtmp), \ + [data1] "=&r" (xdata1), [data2] "=&r" (xdata2) \ + : [qmul] "r" (xqmul), [qadd] "r" (xqadd), [zero] "r" (0) \ + : "r4", "r5", "r6", "r7", "cc", "memory" \ +); \ +}) + +static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int i, level, qmul, qadd; + int nCoeffs; + + assert(s->block_last_index[n]>=0); + + qmul = qscale << 1; + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level = block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + dct_unquantize_h263_special_helper_armv5te(block, qmul, qadd, nCoeffs + 1); + block[0] = level; +} + +static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int i, level, qmul, qadd; + int nCoeffs; + + assert(s->block_last_index[n]>=0); + + qadd = (qscale - 1) | 1; + qmul = qscale << 1; + + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + dct_unquantize_h263_special_helper_armv5te(block, qmul, qadd, nCoeffs + 1); +} + +#define HAVE_DCT_UNQUANTIZE_H263_ARMV5TE_OPTIMIZED + +#endif + +void MPV_common_init_armv5te(MpegEncContext *s) +{ +#ifdef HAVE_DCT_UNQUANTIZE_H263_ARMV5TE_OPTIMIZED + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te; +#endif +} diff --git a/src/libffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c b/src/libffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c new file mode 100644 index 000000000..1336ac5f8 --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c @@ -0,0 +1,119 @@ +/* + * copyright (c) 2004 AGAWA Koji + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" +#include "../mpegvideo.h" +#include "../avcodec.h" + +static void dct_unquantize_h263_intra_iwmmxt(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int level, qmul, qadd; + int nCoeffs; + DCTELEM *block_orig = block; + + assert(s->block_last_index[n]>=0); + + qmul = qscale << 1; + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level = block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + __asm__ __volatile__ ( +/* "movd %1, %%mm6 \n\t" //qmul */ +/* "packssdw %%mm6, %%mm6 \n\t" */ +/* "packssdw %%mm6, %%mm6 \n\t" */ + "tbcsth wr6, %[qmul] \n\t" +/* "movd %2, %%mm5 \n\t" //qadd */ +/* "packssdw %%mm5, %%mm5 \n\t" */ +/* "packssdw %%mm5, %%mm5 \n\t" */ + "tbcsth wr5, %[qadd] \n\t" + "wzero wr7 \n\t" /* "pxor %%mm7, %%mm7 \n\t" */ + "wzero wr4 \n\t" /* "pxor %%mm4, %%mm4 \n\t" */ + "wsubh wr7, wr5, wr7 \n\t" /* "psubw %%mm5, %%mm7 \n\t" */ + "1: \n\t" + "wldrd wr2, [%[block]] \n\t" /* "movq (%0, %3), %%mm0 \n\t" */ + "wldrd wr3, [%[block], #8] \n\t" /* "movq 8(%0, %3), %%mm1 \n\t" */ + "wmulsl wr0, wr6, wr2 \n\t" /* "pmullw %%mm6, %%mm0 \n\t" */ + "wmulsl wr1, wr6, wr3 \n\t" /* "pmullw %%mm6, %%mm1 \n\t" */ +/* "movq (%0, %3), %%mm2 \n\t" */ +/* "movq 8(%0, %3), %%mm3 \n\t" */ + "wcmpgtsh wr2, wr4, wr2 \n\t" /* "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 */ + "wcmpgtsh wr3, wr4, wr2 \n\t" /* "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 */ + "wxor wr0, wr2, wr0 \n\t" /* "pxor %%mm2, %%mm0 \n\t" */ + "wxor wr1, wr3, wr1 \n\t" /* "pxor %%mm3, %%mm1 \n\t" */ + "waddh wr0, wr7, wr0 \n\t" /* "paddw %%mm7, %%mm0 \n\t" */ + "waddh wr1, wr7, wr1 \n\t" /* "paddw %%mm7, %%mm1 \n\t" */ + "wxor wr2, wr0, wr2 \n\t" /* "pxor %%mm0, %%mm2 \n\t" */ + "wxor wr3, wr1, wr3 \n\t" /* "pxor %%mm1, %%mm3 \n\t" */ + "wcmpeqh wr0, wr7, wr0 \n\t" /* "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 */ + "wcmpeqh wr1, wr7, wr1 \n\t" /* "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 */ + "wandn wr0, wr2, wr0 \n\t" /* "pandn %%mm2, %%mm0 \n\t" */ + "wandn wr1, wr3, wr1 \n\t" /* "pandn %%mm3, %%mm1 \n\t" */ + "wstrd wr0, [%[block]] \n\t" /* "movq %%mm0, (%0, %3) \n\t" */ + "wstrd wr1, [%[block], #8] \n\t" /* "movq %%mm1, 8(%0, %3) \n\t" */ + "add %[block], %[block], #16 \n\t" /* "addl $16, %3 \n\t" */ + "subs %[i], %[i], #1 \n\t" + "bne 1b \n\t" /* "jng 1b \n\t" */ + :[block]"+r"(block) + :[i]"r"((nCoeffs + 8) / 8), [qmul]"r"(qmul), [qadd]"r"(qadd) + :"memory"); + + block_orig[0] = level; +} + +#if 0 +static void dct_unquantize_h263_inter_iwmmxt(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int nCoeffs; + + assert(s->block_last_index[n]>=0); + + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + ippiQuantInvInter_Compact_H263_16s_I(block, nCoeffs+1, qscale); +} +#endif + +void MPV_common_init_iwmmxt(MpegEncContext *s) +{ + if (!(mm_flags & MM_IWMMXT)) return; + + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_iwmmxt; +#if 0 + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_iwmmxt; +#endif +} diff --git a/src/libffmpeg/libavcodec/armv4l/simple_idct_armv5te.S b/src/libffmpeg/libavcodec/armv4l/simple_idct_armv5te.S new file mode 100644 index 000000000..28bee0643 --- /dev/null +++ b/src/libffmpeg/libavcodec/armv4l/simple_idct_armv5te.S @@ -0,0 +1,718 @@ +/* + * Simple IDCT + * + * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2006 Mans Rullgard <mru@inprovide.com> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define W1 22725 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W2 21407 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W3 19266 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W4 16383 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W5 12873 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W6 8867 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define W7 4520 /* cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 */ +#define ROW_SHIFT 11 +#define COL_SHIFT 20 + +#define W13 (W1 | (W3 << 16)) +#define W26 (W2 | (W6 << 16)) +#define W57 (W5 | (W7 << 16)) + + .text + .align +w13: .long W13 +w26: .long W26 +w57: .long W57 + + .align + .func idct_row_armv5te +idct_row_armv5te: + str lr, [sp, #-4]! + + ldrd v1, [a1, #8] + ldrd a3, [a1] /* a3 = row[1:0], a4 = row[3:2] */ + orrs v1, v1, v2 + cmpeq v1, a4 + cmpeq v1, a3, lsr #16 + beq row_dc_only + + mov v1, #(1<<(ROW_SHIFT-1)) + mov ip, #16384 + sub ip, ip, #1 /* ip = W4 */ + smlabb v1, ip, a3, v1 /* v1 = W4*row[0]+(1<<(RS-1)) */ + ldr ip, [pc, #(w26-.-8)] /* ip = W2 | (W6 << 16) */ + smultb a2, ip, a4 + smulbb lr, ip, a4 + add v2, v1, a2 + sub v3, v1, a2 + sub v4, v1, lr + add v1, v1, lr + + ldr ip, [pc, #(w13-.-8)] /* ip = W1 | (W3 << 16) */ + ldr lr, [pc, #(w57-.-8)] /* lr = W5 | (W7 << 16) */ + smulbt v5, ip, a3 + smultt v6, lr, a4 + smlatt v5, ip, a4, v5 + smultt a2, ip, a3 + smulbt v7, lr, a3 + sub v6, v6, a2 + smulbt a2, ip, a4 + smultt fp, lr, a3 + sub v7, v7, a2 + smulbt a2, lr, a4 + ldrd a3, [a1, #8] /* a3=row[5:4] a4=row[7:6] */ + sub fp, fp, a2 + + orrs a2, a3, a4 + beq 1f + + smlabt v5, lr, a3, v5 + smlabt v6, ip, a3, v6 + smlatt v5, lr, a4, v5 + smlabt v6, lr, a4, v6 + smlatt v7, lr, a3, v7 + smlatt fp, ip, a3, fp + smulbt a2, ip, a4 + smlatt v7, ip, a4, v7 + sub fp, fp, a2 + + ldr ip, [pc, #(w26-.-8)] /* ip = W2 | (W6 << 16) */ + mov a2, #16384 + sub a2, a2, #1 /* a2 = W4 */ + smulbb a2, a2, a3 /* a2 = W4*row[4] */ + smultb lr, ip, a4 /* lr = W6*row[6] */ + add v1, v1, a2 /* v1 += W4*row[4] */ + add v1, v1, lr /* v1 += W6*row[6] */ + add v4, v4, a2 /* v4 += W4*row[4] */ + sub v4, v4, lr /* v4 -= W6*row[6] */ + smulbb lr, ip, a4 /* lr = W2*row[6] */ + sub v2, v2, a2 /* v2 -= W4*row[4] */ + sub v2, v2, lr /* v2 -= W2*row[6] */ + sub v3, v3, a2 /* v3 -= W4*row[4] */ + add v3, v3, lr /* v3 += W2*row[6] */ + +1: add a2, v1, v5 + mov a3, a2, lsr #11 + bic a3, a3, #0x1f0000 + sub a2, v2, v6 + mov a2, a2, lsr #11 + add a3, a3, a2, lsl #16 + add a2, v3, v7 + mov a4, a2, lsr #11 + bic a4, a4, #0x1f0000 + add a2, v4, fp + mov a2, a2, lsr #11 + add a4, a4, a2, lsl #16 + strd a3, [a1] + + sub a2, v4, fp + mov a3, a2, lsr #11 + bic a3, a3, #0x1f0000 + sub a2, v3, v7 + mov a2, a2, lsr #11 + add a3, a3, a2, lsl #16 + add a2, v2, v6 + mov a4, a2, lsr #11 + bic a4, a4, #0x1f0000 + sub a2, v1, v5 + mov a2, a2, lsr #11 + add a4, a4, a2, lsl #16 + strd a3, [a1, #8] + + ldr pc, [sp], #4 + +row_dc_only: + orr a3, a3, a3, lsl #16 + bic a3, a3, #0xe000 + mov a3, a3, lsl #3 + mov a4, a3 + strd a3, [a1] + strd a3, [a1, #8] + + ldr pc, [sp], #4 + .endfunc + + .macro idct_col + ldr a4, [a1] /* a4 = col[1:0] */ + mov ip, #16384 + sub ip, ip, #1 /* ip = W4 */ +#if 0 + mov v1, #(1<<(COL_SHIFT-1)) + smlabt v2, ip, a4, v1 /* v2 = W4*col[1] + (1<<(COL_SHIFT-1)) */ + smlabb v1, ip, a4, v1 /* v1 = W4*col[0] + (1<<(COL_SHIFT-1)) */ + ldr a4, [a1, #(16*4)] +#else + mov v1, #((1<<(COL_SHIFT-1))/W4) /* this matches the C version */ + add v2, v1, a4, asr #16 + rsb v2, v2, v2, lsl #14 + mov a4, a4, lsl #16 + add v1, v1, a4, asr #16 + ldr a4, [a1, #(16*4)] + rsb v1, v1, v1, lsl #14 +#endif + + smulbb lr, ip, a4 + smulbt a3, ip, a4 + sub v3, v1, lr + sub v5, v1, lr + add v7, v1, lr + add v1, v1, lr + sub v4, v2, a3 + sub v6, v2, a3 + add fp, v2, a3 + ldr ip, [pc, #(w26-.-8)] + ldr a4, [a1, #(16*2)] + add v2, v2, a3 + + smulbb lr, ip, a4 + smultb a3, ip, a4 + add v1, v1, lr + sub v7, v7, lr + add v3, v3, a3 + sub v5, v5, a3 + smulbt lr, ip, a4 + smultt a3, ip, a4 + add v2, v2, lr + sub fp, fp, lr + add v4, v4, a3 + ldr a4, [a1, #(16*6)] + sub v6, v6, a3 + + smultb lr, ip, a4 + smulbb a3, ip, a4 + add v1, v1, lr + sub v7, v7, lr + sub v3, v3, a3 + add v5, v5, a3 + smultt lr, ip, a4 + smulbt a3, ip, a4 + add v2, v2, lr + sub fp, fp, lr + sub v4, v4, a3 + add v6, v6, a3 + + stmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp} + + ldr ip, [pc, #(w13-.-8)] + ldr a4, [a1, #(16*1)] + ldr lr, [pc, #(w57-.-8)] + smulbb v1, ip, a4 + smultb v3, ip, a4 + smulbb v5, lr, a4 + smultb v7, lr, a4 + smulbt v2, ip, a4 + smultt v4, ip, a4 + smulbt v6, lr, a4 + smultt fp, lr, a4 + rsb v4, v4, #0 + ldr a4, [a1, #(16*3)] + rsb v3, v3, #0 + + smlatb v1, ip, a4, v1 + smlatb v3, lr, a4, v3 + smulbb a3, ip, a4 + smulbb a2, lr, a4 + sub v5, v5, a3 + sub v7, v7, a2 + smlatt v2, ip, a4, v2 + smlatt v4, lr, a4, v4 + smulbt a3, ip, a4 + smulbt a2, lr, a4 + sub v6, v6, a3 + ldr a4, [a1, #(16*5)] + sub fp, fp, a2 + + smlabb v1, lr, a4, v1 + smlabb v3, ip, a4, v3 + smlatb v5, lr, a4, v5 + smlatb v7, ip, a4, v7 + smlabt v2, lr, a4, v2 + smlabt v4, ip, a4, v4 + smlatt v6, lr, a4, v6 + ldr a3, [a1, #(16*7)] + smlatt fp, ip, a4, fp + + smlatb v1, lr, a3, v1 + smlabb v3, lr, a3, v3 + smlatb v5, ip, a3, v5 + smulbb a4, ip, a3 + smlatt v2, lr, a3, v2 + sub v7, v7, a4 + smlabt v4, lr, a3, v4 + smulbt a4, ip, a3 + smlatt v6, ip, a3, v6 + sub fp, fp, a4 + .endm + + .align + .func idct_col_armv5te +idct_col_armv5te: + str lr, [sp, #-4]! + + idct_col + + ldmfd sp!, {a3, a4} + adds a2, a3, v1 + mov a2, a2, lsr #20 + orrmi a2, a2, #0xf000 + add ip, a4, v2 + mov ip, ip, asr #20 + orr a2, a2, ip, lsl #16 + str a2, [a1] + subs a3, a3, v1 + mov a2, a3, lsr #20 + orrmi a2, a2, #0xf000 + sub a4, a4, v2 + mov a4, a4, asr #20 + orr a2, a2, a4, lsl #16 + ldmfd sp!, {a3, a4} + str a2, [a1, #(16*7)] + + subs a2, a3, v3 + mov a2, a2, lsr #20 + orrmi a2, a2, #0xf000 + sub ip, a4, v4 + mov ip, ip, asr #20 + orr a2, a2, ip, lsl #16 + str a2, [a1, #(16*1)] + adds a3, a3, v3 + mov a2, a3, lsr #20 + orrmi a2, a2, #0xf000 + add a4, a4, v4 + mov a4, a4, asr #20 + orr a2, a2, a4, lsl #16 + ldmfd sp!, {a3, a4} + str a2, [a1, #(16*6)] + + adds a2, a3, v5 + mov a2, a2, lsr #20 + orrmi a2, a2, #0xf000 + add ip, a4, v6 + mov ip, ip, asr #20 + orr a2, a2, ip, lsl #16 + str a2, [a1, #(16*2)] + subs a3, a3, v5 + mov a2, a3, lsr #20 + orrmi a2, a2, #0xf000 + sub a4, a4, v6 + mov a4, a4, asr #20 + orr a2, a2, a4, lsl #16 + ldmfd sp!, {a3, a4} + str a2, [a1, #(16*5)] + + adds a2, a3, v7 + mov a2, a2, lsr #20 + orrmi a2, a2, #0xf000 + add ip, a4, fp + mov ip, ip, asr #20 + orr a2, a2, ip, lsl #16 + str a2, [a1, #(16*3)] + subs a3, a3, v7 + mov a2, a3, lsr #20 + orrmi a2, a2, #0xf000 + sub a4, a4, fp + mov a4, a4, asr #20 + orr a2, a2, a4, lsl #16 + str a2, [a1, #(16*4)] + + ldr pc, [sp], #4 + .endfunc + + .align + .func idct_col_put_armv5te +idct_col_put_armv5te: + str lr, [sp, #-4]! + + idct_col + + ldmfd sp!, {a3, a4} + ldr lr, [sp, #32] + add a2, a3, v1 + movs a2, a2, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add ip, a4, v2 + movs ip, ip, asr #20 + movmi ip, #0 + cmp ip, #255 + movgt ip, #255 + orr a2, a2, ip, lsl #8 + sub a3, a3, v1 + movs a3, a3, asr #20 + movmi a3, #0 + cmp a3, #255 + movgt a3, #255 + sub a4, a4, v2 + movs a4, a4, asr #20 + movmi a4, #0 + cmp a4, #255 + ldr v1, [sp, #28] + movgt a4, #255 + strh a2, [v1] + add a2, v1, #2 + str a2, [sp, #28] + orr a2, a3, a4, lsl #8 + rsb v2, lr, lr, lsl #3 + ldmfd sp!, {a3, a4} + strh a2, [v2, v1]! + + sub a2, a3, v3 + movs a2, a2, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + sub ip, a4, v4 + movs ip, ip, asr #20 + movmi ip, #0 + cmp ip, #255 + movgt ip, #255 + orr a2, a2, ip, lsl #8 + strh a2, [v1, lr]! + add a3, a3, v3 + movs a2, a3, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add a4, a4, v4 + movs a4, a4, asr #20 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a2, a4, lsl #8 + ldmfd sp!, {a3, a4} + strh a2, [v2, -lr]! + + add a2, a3, v5 + movs a2, a2, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add ip, a4, v6 + movs ip, ip, asr #20 + movmi ip, #0 + cmp ip, #255 + movgt ip, #255 + orr a2, a2, ip, lsl #8 + strh a2, [v1, lr]! + sub a3, a3, v5 + movs a2, a3, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + sub a4, a4, v6 + movs a4, a4, asr #20 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a2, a4, lsl #8 + ldmfd sp!, {a3, a4} + strh a2, [v2, -lr]! + + add a2, a3, v7 + movs a2, a2, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add ip, a4, fp + movs ip, ip, asr #20 + movmi ip, #0 + cmp ip, #255 + movgt ip, #255 + orr a2, a2, ip, lsl #8 + strh a2, [v1, lr] + sub a3, a3, v7 + movs a2, a3, asr #20 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + sub a4, a4, fp + movs a4, a4, asr #20 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a2, a4, lsl #8 + strh a2, [v2, -lr] + + ldr pc, [sp], #4 + .endfunc + + .align + .func idct_col_add_armv5te +idct_col_add_armv5te: + str lr, [sp, #-4]! + + idct_col + + ldr lr, [sp, #36] + + ldmfd sp!, {a3, a4} + ldrh ip, [lr] + add a2, a3, v1 + mov a2, a2, asr #20 + sub a3, a3, v1 + and v1, ip, #255 + adds a2, a2, v1 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add v1, a4, v2 + mov v1, v1, asr #20 + adds v1, v1, ip, lsr #8 + movmi v1, #0 + cmp v1, #255 + movgt v1, #255 + orr a2, a2, v1, lsl #8 + ldr v1, [sp, #32] + sub a4, a4, v2 + rsb v2, v1, v1, lsl #3 + ldrh ip, [v2, lr]! + strh a2, [lr] + mov a3, a3, asr #20 + and a2, ip, #255 + adds a3, a3, a2 + movmi a3, #0 + cmp a3, #255 + movgt a3, #255 + mov a4, a4, asr #20 + adds a4, a4, ip, lsr #8 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + add a2, lr, #2 + str a2, [sp, #28] + orr a2, a3, a4, lsl #8 + strh a2, [v2] + + ldmfd sp!, {a3, a4} + ldrh ip, [lr, v1]! + sub a2, a3, v3 + mov a2, a2, asr #20 + add a3, a3, v3 + and v3, ip, #255 + adds a2, a2, v3 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + sub v3, a4, v4 + mov v3, v3, asr #20 + adds v3, v3, ip, lsr #8 + movmi v3, #0 + cmp v3, #255 + movgt v3, #255 + orr a2, a2, v3, lsl #8 + add a4, a4, v4 + ldrh ip, [v2, -v1]! + strh a2, [lr] + mov a3, a3, asr #20 + and a2, ip, #255 + adds a3, a3, a2 + movmi a3, #0 + cmp a3, #255 + movgt a3, #255 + mov a4, a4, asr #20 + adds a4, a4, ip, lsr #8 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a3, a4, lsl #8 + strh a2, [v2] + + ldmfd sp!, {a3, a4} + ldrh ip, [lr, v1]! + add a2, a3, v5 + mov a2, a2, asr #20 + sub a3, a3, v5 + and v3, ip, #255 + adds a2, a2, v3 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add v3, a4, v6 + mov v3, v3, asr #20 + adds v3, v3, ip, lsr #8 + movmi v3, #0 + cmp v3, #255 + movgt v3, #255 + orr a2, a2, v3, lsl #8 + sub a4, a4, v6 + ldrh ip, [v2, -v1]! + strh a2, [lr] + mov a3, a3, asr #20 + and a2, ip, #255 + adds a3, a3, a2 + movmi a3, #0 + cmp a3, #255 + movgt a3, #255 + mov a4, a4, asr #20 + adds a4, a4, ip, lsr #8 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a3, a4, lsl #8 + strh a2, [v2] + + ldmfd sp!, {a3, a4} + ldrh ip, [lr, v1]! + add a2, a3, v7 + mov a2, a2, asr #20 + sub a3, a3, v7 + and v3, ip, #255 + adds a2, a2, v3 + movmi a2, #0 + cmp a2, #255 + movgt a2, #255 + add v3, a4, fp + mov v3, v3, asr #20 + adds v3, v3, ip, lsr #8 + movmi v3, #0 + cmp v3, #255 + movgt v3, #255 + orr a2, a2, v3, lsl #8 + sub a4, a4, fp + ldrh ip, [v2, -v1]! + strh a2, [lr] + mov a3, a3, asr #20 + and a2, ip, #255 + adds a3, a3, a2 + movmi a3, #0 + cmp a3, #255 + movgt a3, #255 + mov a4, a4, asr #20 + adds a4, a4, ip, lsr #8 + movmi a4, #0 + cmp a4, #255 + movgt a4, #255 + orr a2, a3, a4, lsl #8 + strh a2, [v2] + + ldr pc, [sp], #4 + .endfunc + + .align + .global simple_idct_armv5te + .func simple_idct_armv5te +simple_idct_armv5te: + stmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, lr} + + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + + sub a1, a1, #(16*7) + + bl idct_col_armv5te + add a1, a1, #4 + bl idct_col_armv5te + add a1, a1, #4 + bl idct_col_armv5te + add a1, a1, #4 + bl idct_col_armv5te + + ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} + .endfunc + + .align + .global simple_idct_add_armv5te + .func simple_idct_add_armv5te +simple_idct_add_armv5te: + stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} + + mov a1, a3 + + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + + sub a1, a1, #(16*7) + + bl idct_col_add_armv5te + add a1, a1, #4 + bl idct_col_add_armv5te + add a1, a1, #4 + bl idct_col_add_armv5te + add a1, a1, #4 + bl idct_col_add_armv5te + + add sp, sp, #8 + ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} + .endfunc + + .align + .global simple_idct_put_armv5te + .func simple_idct_put_armv5te +simple_idct_put_armv5te: + stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} + + mov a1, a3 + + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + add a1, a1, #16 + bl idct_row_armv5te + + sub a1, a1, #(16*7) + + bl idct_col_put_armv5te + add a1, a1, #4 + bl idct_col_put_armv5te + add a1, a1, #4 + bl idct_col_put_armv5te + add a1, a1, #4 + bl idct_col_put_armv5te + + add sp, sp, #8 + ldmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, pc} + .endfunc diff --git a/src/libffmpeg/libavcodec/bytestream.h b/src/libffmpeg/libavcodec/bytestream.h new file mode 100644 index 000000000..ae5438b49 --- /dev/null +++ b/src/libffmpeg/libavcodec/bytestream.h @@ -0,0 +1,89 @@ +/* + * Bytestream functions + * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_BYTESTREAM_H +#define FFMPEG_BYTESTREAM_H + +static av_always_inline unsigned int bytestream_get_le32(uint8_t **b) +{ + (*b) += 4; + return AV_RL32(*b - 4); +} + +static av_always_inline unsigned int bytestream_get_le16(uint8_t **b) +{ + (*b) += 2; + return AV_RL16(*b - 2); +} + +static av_always_inline unsigned int bytestream_get_byte(uint8_t **b) +{ + (*b)++; + return (*b)[-1]; +} + +static av_always_inline unsigned int bytestream_get_buffer(uint8_t **b, uint8_t *dst, unsigned int size) +{ + memcpy(dst, *b, size); + (*b) += size; + return size; +} + +static av_always_inline void bytestream_put_be32(uint8_t **b, const unsigned int value) +{ + *(*b)++ = value >> 24; + *(*b)++ = value >> 16; + *(*b)++ = value >> 8; + *(*b)++ = value; +}; + +static av_always_inline void bytestream_put_be16(uint8_t **b, const unsigned int value) +{ + *(*b)++ = value >> 8; + *(*b)++ = value; +} + +static av_always_inline void bytestream_put_le32(uint8_t **b, const unsigned int value) +{ + *(*b)++ = value; + *(*b)++ = value >> 8; + *(*b)++ = value >> 16; + *(*b)++ = value >> 24; +} + +static av_always_inline void bytestream_put_le16(uint8_t **b, const unsigned int value) +{ + *(*b)++ = value; + *(*b)++ = value >> 8; +} + +static av_always_inline void bytestream_put_byte(uint8_t **b, const unsigned int value) +{ + *(*b)++ = value; +} + +static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size) +{ + memcpy(*b, src, size); + (*b) += size; +} + +#endif /* FFMPEG_BYTESTREAM_H */ diff --git a/src/libffmpeg/libavcodec/eval.h b/src/libffmpeg/libavcodec/eval.h new file mode 100644 index 000000000..b52199cf4 --- /dev/null +++ b/src/libffmpeg/libavcodec/eval.h @@ -0,0 +1,84 @@ +/* + * simple arithmetic expression evaluator + * + * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file eval.h + * eval header. + */ + +#ifndef AVCODEC_EVAL_H +#define AVCODEC_EVAL_H + +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) +double ff_eval(char *s, double *const_value, const char **const_name, + double (**func1)(void *, double), const char **func1_name, + double (**func2)(void *, double, double), char **func2_name, + void *opaque); +#endif + +/** + * Parses and evaluates an expression. + * Note, this is significantly slower than ff_parse_eval() + * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)" + * @param func1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2 NULL terminated array of function pointers for functions which take 2 arguments + * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0} + * @param func1_name NULL terminated array of zero terminated strings of func1 identifers + * @param func2_name NULL terminated array of zero terminated strings of func2 identifers + * @param error pointer to a char* which is set to an error message if something goes wrong + * @param const_value a zero terminated array of values for the identifers from const_name + * @param opaque a pointer which will be passed to all functions from func1 and func2 + * @return the value of the expression + */ +double ff_eval2(char *s, double *const_value, const char **const_name, + double (**func1)(void *, double), const char **func1_name, + double (**func2)(void *, double, double), char **func2_name, + void *opaque, char **error); + +typedef struct ff_expr_s AVEvalExpr; + +/** + * Parses a expression. + * @param s expression as a zero terminated string for example "1+2^3+5*5+sin(2/3)" + * @param func1 NULL terminated array of function pointers for functions which take 1 argument + * @param func2 NULL terminated array of function pointers for functions which take 2 arguments + * @param const_name NULL terminated array of zero terminated strings of constant identifers for example {"PI", "E", 0} + * @param func1_name NULL terminated array of zero terminated strings of func1 identifers + * @param func2_name NULL terminated array of zero terminated strings of func2 identifers + * @param error pointer to a char* which is set to an error message if something goes wrong + * @return AVEvalExpr which must be freed with ff_eval_free by the user when its not needed anymore + * NULL if anything went wrong + */ +AVEvalExpr * ff_parse(char *s, const char **const_name, + double (**func1)(void *, double), const char **func1_name, + double (**func2)(void *, double, double), char **func2_name, + char **error); +/** + * Evaluates a previously parsed expression. + * @param const_value a zero terminated array of values for the identifers from ff_parse const_name + * @param opaque a pointer which will be passed to all functions from func1 and func2 + * @return the value of the expression + */ +double ff_parse_eval(AVEvalExpr * e, double *const_value, void *opaque); +void ff_eval_free(AVEvalExpr * e); + +#endif /* AVCODEC_EVAL_H */ diff --git a/src/libmpeg2new/.cvsignore b/src/libffmpeg/libavcodec/i386/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libmpeg2new/.cvsignore +++ b/src/libffmpeg/libavcodec/i386/.hgignore diff --git a/src/libffmpeg/libavcodec/i386/fft_3dn.c b/src/libffmpeg/libavcodec/i386/fft_3dn.c new file mode 100644 index 000000000..8087f1932 --- /dev/null +++ b/src/libffmpeg/libavcodec/i386/fft_3dn.c @@ -0,0 +1,125 @@ +/* + * FFT/MDCT transform with 3DNow! optimizations + * Copyright (c) 2006 Zuxy MENG Jie, Loren Merritt + * Based on fft_sse.c copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" + +static const int p1m1[2] __attribute__((aligned(8))) = + { 0, 1 << 31 }; + +static const int m1p1[2] __attribute__((aligned(8))) = + { 1 << 31, 0 }; + +void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + long i, j; + long nblocks, nloops; + FFTComplex *p, *cptr; + + asm volatile( + /* FEMMS is not a must here but recommended by AMD */ + "femms \n\t" + "movq %0, %%mm7 \n\t" + ::"m"(*(s->inverse ? m1p1 : p1m1)) + ); + + i = 8 << ln; + asm volatile( + "1: \n\t" + "sub $32, %0 \n\t" + "movq (%0,%1), %%mm0 \n\t" + "movq 16(%0,%1), %%mm1 \n\t" + "movq 8(%0,%1), %%mm2 \n\t" + "movq 24(%0,%1), %%mm3 \n\t" + "movq %%mm0, %%mm4 \n\t" + "movq %%mm1, %%mm5 \n\t" + "pfadd %%mm2, %%mm0 \n\t" + "pfadd %%mm3, %%mm1 \n\t" + "pfsub %%mm2, %%mm4 \n\t" + "pfsub %%mm3, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm5, %%mm6 \n\t" + "punpckhdq %%mm6, %%mm5 \n\t" + "movq %%mm4, %%mm3 \n\t" + "pxor %%mm7, %%mm5 \n\t" + "pfadd %%mm1, %%mm0 \n\t" + "pfadd %%mm5, %%mm4 \n\t" + "pfsub %%mm1, %%mm2 \n\t" + "pfsub %%mm5, %%mm3 \n\t" + "movq %%mm0, (%0,%1) \n\t" + "movq %%mm4, 8(%0,%1) \n\t" + "movq %%mm2, 16(%0,%1) \n\t" + "movq %%mm3, 24(%0,%1) \n\t" + "jg 1b \n\t" + :"+r"(i) + :"r"(z) + ); + /* pass 2 .. ln-1 */ + + nblocks = 1 << (ln-3); + nloops = 1 << 2; + cptr = s->exptab1; + do { + p = z; + j = nblocks; + do { + i = nloops*8; + asm volatile( + "1: \n\t" + "sub $16, %0 \n\t" + "movq (%1,%0), %%mm0 \n\t" + "movq 8(%1,%0), %%mm1 \n\t" + "movq (%2,%0), %%mm2 \n\t" + "movq 8(%2,%0), %%mm3 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm3, %%mm5 \n\t" + "punpckldq %%mm2, %%mm2 \n\t" + "punpckldq %%mm3, %%mm3 \n\t" + "punpckhdq %%mm4, %%mm4 \n\t" + "punpckhdq %%mm5, %%mm5 \n\t" + "pfmul (%3,%0,2), %%mm2 \n\t" // cre*re cim*re + "pfmul 8(%3,%0,2), %%mm3 \n\t" + "pfmul 16(%3,%0,2), %%mm4 \n\t" // -cim*im cre*im + "pfmul 24(%3,%0,2), %%mm5 \n\t" + "pfadd %%mm2, %%mm4 \n\t" // cre*re-cim*im cim*re+cre*im + "pfadd %%mm3, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "movq %%mm1, %%mm3 \n\t" + "pfadd %%mm4, %%mm0 \n\t" + "pfadd %%mm5, %%mm1 \n\t" + "pfsub %%mm4, %%mm2 \n\t" + "pfsub %%mm5, %%mm3 \n\t" + "movq %%mm0, (%1,%0) \n\t" + "movq %%mm1, 8(%1,%0) \n\t" + "movq %%mm2, (%2,%0) \n\t" + "movq %%mm3, 8(%2,%0) \n\t" + "jg 1b \n\t" + :"+r"(i) + :"r"(p), "r"(p + nloops), "r"(cptr) + ); + p += nloops*2; + } while (--j); + cptr += nloops*2; + nblocks >>= 1; + nloops <<= 1; + } while (nblocks != 0); + asm volatile("femms"); +} diff --git a/src/libffmpeg/libavcodec/i386/fft_3dn2.c b/src/libffmpeg/libavcodec/i386/fft_3dn2.c new file mode 100644 index 000000000..a4fe5f0b6 --- /dev/null +++ b/src/libffmpeg/libavcodec/i386/fft_3dn2.c @@ -0,0 +1,210 @@ +/* + * FFT/MDCT transform with Extended 3DNow! optimizations + * Copyright (c) 2006 Zuxy MENG Jie, Loren Merritt + * Based on fft_sse.c copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" + +static const int p1m1[2] __attribute__((aligned(8))) = + { 0, 1 << 31 }; + +static const int m1p1[2] __attribute__((aligned(8))) = + { 1 << 31, 0 }; + +void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + long i, j; + long nblocks, nloops; + FFTComplex *p, *cptr; + + asm volatile( + /* FEMMS is not a must here but recommended by AMD */ + "femms \n\t" + "movq %0, %%mm7 \n\t" + ::"m"(*(s->inverse ? m1p1 : p1m1)) + ); + + i = 8 << ln; + asm volatile( + "1: \n\t" + "sub $32, %0 \n\t" + "movq (%0,%1), %%mm0 \n\t" + "movq 16(%0,%1), %%mm1 \n\t" + "movq 8(%0,%1), %%mm2 \n\t" + "movq 24(%0,%1), %%mm3 \n\t" + "movq %%mm0, %%mm4 \n\t" + "movq %%mm1, %%mm5 \n\t" + "pfadd %%mm2, %%mm0 \n\t" + "pfadd %%mm3, %%mm1 \n\t" + "pfsub %%mm2, %%mm4 \n\t" + "pfsub %%mm3, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "pswapd %%mm5, %%mm5 \n\t" + "movq %%mm4, %%mm3 \n\t" + "pxor %%mm7, %%mm5 \n\t" + "pfadd %%mm1, %%mm0 \n\t" + "pfadd %%mm5, %%mm4 \n\t" + "pfsub %%mm1, %%mm2 \n\t" + "pfsub %%mm5, %%mm3 \n\t" + "movq %%mm0, (%0,%1) \n\t" + "movq %%mm4, 8(%0,%1) \n\t" + "movq %%mm2, 16(%0,%1) \n\t" + "movq %%mm3, 24(%0,%1) \n\t" + "jg 1b \n\t" + :"+r"(i) + :"r"(z) + ); + /* pass 2 .. ln-1 */ + + nblocks = 1 << (ln-3); + nloops = 1 << 2; + cptr = s->exptab1; + do { + p = z; + j = nblocks; + do { + i = nloops*8; + asm volatile( + "1: \n\t" + "sub $16, %0 \n\t" + "movq (%1,%0), %%mm0 \n\t" + "movq 8(%1,%0), %%mm1 \n\t" + "movq (%2,%0), %%mm2 \n\t" + "movq 8(%2,%0), %%mm3 \n\t" + "movq (%3,%0,2), %%mm4 \n\t" + "movq 8(%3,%0,2), %%mm5 \n\t" + "pswapd %%mm4, %%mm6 \n\t" // no need for cptr[2] & cptr[3] + "pswapd %%mm5, %%mm7 \n\t" + "pfmul %%mm2, %%mm4 \n\t" // cre*re cim*im + "pfmul %%mm3, %%mm5 \n\t" + "pfmul %%mm2, %%mm6 \n\t" // cim*re cre*im + "pfmul %%mm3, %%mm7 \n\t" + "pfpnacc %%mm6, %%mm4 \n\t" // cre*re-cim*im cim*re+cre*im + "pfpnacc %%mm7, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "movq %%mm1, %%mm3 \n\t" + "pfadd %%mm4, %%mm0 \n\t" + "pfadd %%mm5, %%mm1 \n\t" + "pfsub %%mm4, %%mm2 \n\t" + "pfsub %%mm5, %%mm3 \n\t" + "movq %%mm0, (%1,%0) \n\t" + "movq %%mm1, 8(%1,%0) \n\t" + "movq %%mm2, (%2,%0) \n\t" + "movq %%mm3, 8(%2,%0) \n\t" + "jg 1b \n\t" + :"+r"(i) + :"r"(p), "r"(p + nloops), "r"(cptr) + ); + p += nloops*2; + } while (--j); + cptr += nloops*2; + nblocks >>= 1; + nloops <<= 1; + } while (nblocks != 0); + asm volatile("femms"); +} + +void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp) +{ + long k, n8, n4, n2, n; + const uint16_t *revtab = s->fft.revtab; + const FFTSample *tcos = s->tcos; + const FFTSample *tsin = s->tsin; + const FFTSample *in1, *in2; + FFTComplex *z = (FFTComplex *)tmp; + + n = 1 << s->nbits; + n2 = n >> 1; + n4 = n >> 2; + n8 = n >> 3; + + /* pre rotation */ + in1 = input; + in2 = input + n2 - 1; + for(k = 0; k < n4; k++) { + // FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it + asm volatile( + "movd %0, %%mm0 \n\t" + "movd %2, %%mm1 \n\t" + "punpckldq %1, %%mm0 \n\t" + "punpckldq %3, %%mm1 \n\t" + "movq %%mm0, %%mm2 \n\t" + "pfmul %%mm1, %%mm0 \n\t" + "pswapd %%mm1, %%mm1 \n\t" + "pfmul %%mm1, %%mm2 \n\t" + "pfpnacc %%mm2, %%mm0 \n\t" + ::"m"(in2[-2*k]), "m"(in1[2*k]), + "m"(tcos[k]), "m"(tsin[k]) + ); + asm volatile( + "movq %%mm0, %0 \n\t" + :"=m"(z[revtab[k]]) + ); + } + + ff_fft_calc(&s->fft, z); + + /* post rotation + reordering */ + for(k = 0; k < n4; k++) { + asm volatile( + "movq %0, %%mm0 \n\t" + "movd %1, %%mm1 \n\t" + "punpckldq %2, %%mm1 \n\t" + "movq %%mm0, %%mm2 \n\t" + "pfmul %%mm1, %%mm0 \n\t" + "pswapd %%mm1, %%mm1 \n\t" + "pfmul %%mm1, %%mm2 \n\t" + "pfpnacc %%mm2, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + :"+m"(z[k]) + :"m"(tcos[k]), "m"(tsin[k]) + ); + } + + k = n-8; + asm volatile("movd %0, %%mm7" ::"r"(1<<31)); + asm volatile( + "1: \n\t" + "movq (%4,%0), %%mm0 \n\t" // z[n8+k] + "neg %0 \n\t" + "pswapd -8(%4,%0), %%mm1 \n\t" // z[n8-1-k] + "movq %%mm0, %%mm2 \n\t" + "pxor %%mm7, %%mm2 \n\t" + "punpckldq %%mm1, %%mm2 \n\t" + "pswapd %%mm2, %%mm3 \n\t" + "punpckhdq %%mm1, %%mm0 \n\t" + "pswapd %%mm0, %%mm4 \n\t" + "pxor %%mm7, %%mm0 \n\t" + "pxor %%mm7, %%mm4 \n\t" + "movq %%mm3, -8(%3,%0) \n\t" // output[n-2-2*k] = { z[n8-1-k].im, -z[n8+k].re } + "movq %%mm4, -8(%2,%0) \n\t" // output[n2-2-2*k]= { -z[n8-1-k].re, z[n8+k].im } + "neg %0 \n\t" + "movq %%mm0, (%1,%0) \n\t" // output[2*k] = { -z[n8+k].im, z[n8-1-k].re } + "movq %%mm2, (%2,%0) \n\t" // output[n2+2*k] = { -z[n8+k].re, z[n8-1-k].im } + "sub $8, %0 \n\t" + "jge 1b \n\t" + :"+r"(k) + :"r"(output), "r"(output+n2), "r"(output+n), "r"(z+n8) + :"memory" + ); + asm volatile("femms"); +} + diff --git a/src/libffmpeg/libavcodec/i386/mathops.h b/src/libffmpeg/libavcodec/i386/mathops.h new file mode 100644 index 000000000..3553a4025 --- /dev/null +++ b/src/libffmpeg/libavcodec/i386/mathops.h @@ -0,0 +1,41 @@ +/* + * simple math operations + * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef FRAC_BITS +# define MULL(ra, rb) \ + ({ int rt, dummy; asm (\ + "imull %3 \n\t"\ + "shrdl %4, %%edx, %%eax \n\t"\ + : "=a"(rt), "=d"(dummy)\ + : "a" (ra), "rm" (rb), "i"(FRAC_BITS));\ + rt; }) +#endif + +#define MULH(ra, rb) \ + ({ int rt, dummy;\ + asm ("imull %3\n\t" : "=d"(rt), "=a"(dummy): "a" (ra), "rm" (rb));\ + rt; }) + +#define MUL64(ra, rb) \ + ({ int64_t rt;\ + asm ("imull %2\n\t" : "=A"(rt) : "a" (ra), "g" (rb));\ + rt; }) + diff --git a/src/libmpeg2new/libmpeg2/.cvsignore b/src/libffmpeg/libavcodec/libpostproc/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libmpeg2new/libmpeg2/.cvsignore +++ b/src/libffmpeg/libavcodec/libpostproc/.hgignore diff --git a/src/libffmpeg/libavcodec/mathops.h b/src/libffmpeg/libavcodec/mathops.h new file mode 100644 index 000000000..c6ec70597 --- /dev/null +++ b/src/libffmpeg/libavcodec/mathops.h @@ -0,0 +1,69 @@ +/* + * simple math operations + * Copyright (c) 2001, 2002 Fabrice Bellard. + * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef MATHOPS_H +#define MATHOPS_H + +#ifdef ARCH_X86_32 + +#include "i386/mathops.h" + +#elif defined(ARCH_ARMV4L) + +#include "armv4l/mathops.h" + +#elif defined(ARCH_PPC) + +#include "ppc/mathops.h" + +#endif + +/* generic implementation */ + +#ifndef MULL +# define MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) +#endif + +#ifndef MULH +//gcc 3.4 creates an incredibly bloated mess out of this +//# define MULH(a,b) (((int64_t)(a) * (int64_t)(b))>>32) + +static av_always_inline int MULH(int a, int b){ + return ((int64_t)(a) * (int64_t)(b))>>32; +} +#endif + +#ifndef MUL64 +# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b)) +#endif + +/* signed 16x16 -> 32 multiply add accumulate */ +#ifndef MAC16 +# define MAC16(rt, ra, rb) rt += (ra) * (rb) +#endif + +/* signed 16x16 -> 32 multiply */ +#ifndef MUL16 +# define MUL16(ra, rb) ((ra) * (rb)) +#endif + +#endif //MATHOPS_H + diff --git a/src/libmusepack/.cvsignore b/src/libffmpeg/libavcodec/mlib/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libmusepack/.cvsignore +++ b/src/libffmpeg/libavcodec/mlib/.hgignore diff --git a/src/libffmpeg/libavcodec/opt.c b/src/libffmpeg/libavcodec/opt.c new file mode 100644 index 000000000..70babd587 --- /dev/null +++ b/src/libffmpeg/libavcodec/opt.c @@ -0,0 +1,381 @@ +/* + * AVOptions + * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file opt.c + * AVOptions + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#include "avcodec.h" +#include "opt.h" +#include "eval.h" + +//FIXME order them and do a bin search +static const AVOption *find_opt(void *v, const char *name, const char *unit){ + AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass + const AVOption *o= c->option; + + for(;o && o->name; o++){ + if(!strcmp(o->name, name) && (!unit || !strcmp(o->unit, unit)) ) + return o; + } + return NULL; +} + +const AVOption *av_next_option(void *obj, const AVOption *last){ + if(last && last[1].name) return ++last; + else if(last) return NULL; + else return (*(AVClass**)obj)->option; +} + +static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){ + const AVOption *o= find_opt(obj, name, NULL); + void *dst; + if(!o || o->offset<=0) + return NULL; + + if(o->max*den < num*intnum || o->min*den > num*intnum) { + av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name); + return NULL; + } + + dst= ((uint8_t*)obj) + o->offset; + + switch(o->type){ + case FF_OPT_TYPE_FLAGS: + case FF_OPT_TYPE_INT: *(int *)dst= lrintf(num/den)*intnum; break; + case FF_OPT_TYPE_INT64: *(int64_t *)dst= lrintf(num/den)*intnum; break; + case FF_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; + case FF_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; + case FF_OPT_TYPE_RATIONAL: + if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; + else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); + default: + return NULL; + } + return o; +} + +static const AVOption *set_all_opt(void *v, const char *unit, double d){ + AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass + const AVOption *o= c->option; + const AVOption *ret=NULL; + + for(;o && o->name; o++){ + if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){ + double tmp= d; + if(o->type == FF_OPT_TYPE_FLAGS) + tmp= av_get_int(v, o->name, NULL) | (int64_t)d; + + av_set_number(v, o->name, tmp, 1, 1); + ret= o; + } + } + return ret; +} + +static double const_values[]={ + M_PI, + M_E, + FF_QP2LAMBDA, + 0 +}; + +static const char *const_names[]={ + "PI", + "E", + "QP2LAMBDA", + 0 +}; + +const AVOption *av_set_string(void *obj, const char *name, const char *val){ + const AVOption *o= find_opt(obj, name, NULL); + if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ + return set_all_opt(obj, o->unit, o->default_val); + } + if(!o || !val || o->offset<=0) + return NULL; + if(o->type != FF_OPT_TYPE_STRING){ + for(;;){ + int i; + char buf[256]; + int cmd=0; + double d; + char *error = NULL; + + if(*val == '+' || *val == '-') + cmd= *(val++); + + for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) + buf[i]= val[i]; + buf[i]=0; + val+= i; + + d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error); + if(isnan(d)) { + const AVOption *o_named= find_opt(obj, buf, o->unit); + if(o_named && o_named->type == FF_OPT_TYPE_CONST) + d= o_named->default_val; + else if(!strcmp(buf, "default")) d= o->default_val; + else if(!strcmp(buf, "max" )) d= o->max; + else if(!strcmp(buf, "min" )) d= o->min; + else { + if (!error) + av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); + return NULL; + } + } + if(o->type == FF_OPT_TYPE_FLAGS){ + if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; + else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; + }else if(cmd=='-') + d= -d; + + av_set_number(obj, name, d, 1, 1); + if(!*val) + return o; + } + return NULL; + } + + memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); + return o; +} + +const AVOption *av_set_double(void *obj, const char *name, double n){ + return av_set_number(obj, name, n, 1, 1); +} + +const AVOption *av_set_q(void *obj, const char *name, AVRational n){ + return av_set_number(obj, name, n.num, n.den, 1); +} + +const AVOption *av_set_int(void *obj, const char *name, int64_t n){ + return av_set_number(obj, name, 1, 1, n); +} + +/** + * + * @param buf a buffer which is used for returning non string values as strings, can be NULL + * @param buf_len allocated length in bytes of buf + */ +const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){ + const AVOption *o= find_opt(obj, name, NULL); + void *dst; + if(!o || o->offset<=0) + return NULL; + if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) + return NULL; + + dst= ((uint8_t*)obj) + o->offset; + if(o_out) *o_out= o; + + if(o->type == FF_OPT_TYPE_STRING) + return dst; + + switch(o->type){ + case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; + case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; + case FF_OPT_TYPE_INT64: snprintf(buf, buf_len, "%"PRId64, *(int64_t*)dst);break; + case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; + case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; + case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; + default: return NULL; + } + return buf; +} + +static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum){ + const AVOption *o= find_opt(obj, name, NULL); + void *dst; + if(!o || o->offset<=0) + goto error; + + dst= ((uint8_t*)obj) + o->offset; + + if(o_out) *o_out= o; + + switch(o->type){ + case FF_OPT_TYPE_FLAGS: + case FF_OPT_TYPE_INT: *intnum= *(int *)dst;return 0; + case FF_OPT_TYPE_INT64: *intnum= *(int64_t*)dst;return 0; + case FF_OPT_TYPE_FLOAT: *num= *(float *)dst;return 0; + case FF_OPT_TYPE_DOUBLE: *num= *(double *)dst;return 0; + case FF_OPT_TYPE_RATIONAL: *intnum= ((AVRational*)dst)->num; + *den = ((AVRational*)dst)->den; + return 0; + } +error: + *den=*intnum=0; + return -1; +} + +double av_get_double(void *obj, const char *name, const AVOption **o_out){ + int64_t intnum=1; + double num=1; + int den=1; + + av_get_number(obj, name, o_out, &num, &den, &intnum); + return num*intnum/den; +} + +AVRational av_get_q(void *obj, const char *name, const AVOption **o_out){ + int64_t intnum=1; + double num=1; + int den=1; + + av_get_number(obj, name, o_out, &num, &den, &intnum); + if(num == 1.0 && (int)intnum == intnum) + return (AVRational){intnum, den}; + else + return av_d2q(num*intnum/den, 1<<24); +} + +int64_t av_get_int(void *obj, const char *name, const AVOption **o_out){ + int64_t intnum=1; + double num=1; + int den=1; + + av_get_number(obj, name, o_out, &num, &den, &intnum); + return num*intnum/den; +} + +static void opt_list(void *obj, void *av_log_obj, const char *unit) +{ + const AVOption *opt=NULL; + + while((opt= av_next_option(obj, opt))){ + if(!(opt->flags & (AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM))) + continue; + + /* Don't print CONST's on level one. + * Don't print anything but CONST's on level two. + * Only print items from the requested unit. + */ + if (!unit && opt->type==FF_OPT_TYPE_CONST) + continue; + else if (unit && opt->type!=FF_OPT_TYPE_CONST) + continue; + else if (unit && opt->type==FF_OPT_TYPE_CONST && strcmp(unit, opt->unit)) + continue; + else if (unit && opt->type == FF_OPT_TYPE_CONST) + av_log(av_log_obj, AV_LOG_INFO, " %-15s ", opt->name); + else + av_log(av_log_obj, AV_LOG_INFO, "-%-17s ", opt->name); + + switch( opt->type ) + { + case FF_OPT_TYPE_FLAGS: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<flags>" ); + break; + case FF_OPT_TYPE_INT: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int>" ); + break; + case FF_OPT_TYPE_INT64: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<int64>" ); + break; + case FF_OPT_TYPE_DOUBLE: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<double>" ); + break; + case FF_OPT_TYPE_FLOAT: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<float>" ); + break; + case FF_OPT_TYPE_STRING: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<string>" ); + break; + case FF_OPT_TYPE_RATIONAL: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" ); + break; + case FF_OPT_TYPE_CONST: + default: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); + break; + } + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); + + if(opt->help) + av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); + av_log(av_log_obj, AV_LOG_INFO, "\n"); + if (opt->unit && opt->type != FF_OPT_TYPE_CONST) { + opt_list(obj, av_log_obj, opt->unit); + } + } +} + +int av_opt_show(void *obj, void *av_log_obj){ + if(!obj) + return -1; + + av_log(av_log_obj, AV_LOG_INFO, "%s AVOptions:\n", (*(AVClass**)obj)->class_name); + + opt_list(obj, av_log_obj, NULL); + + return 0; +} + +/** Set the values of the AVCodecContext or AVFormatContext structure. + * They are set to the defaults specified in the according AVOption options + * array default_val field. + * + * @param s AVCodecContext or AVFormatContext for which the defaults will be set + */ +void av_opt_set_defaults(void *s) +{ + const AVOption *opt = NULL; + while ((opt = av_next_option(s, opt)) != NULL) { + switch(opt->type) { + case FF_OPT_TYPE_CONST: + /* Nothing to be done here */ + break; + case FF_OPT_TYPE_FLAGS: + case FF_OPT_TYPE_INT: { + int val; + val = opt->default_val; + av_set_int(s, opt->name, val); + } + break; + case FF_OPT_TYPE_FLOAT: { + double val; + val = opt->default_val; + av_set_double(s, opt->name, val); + } + break; + case FF_OPT_TYPE_RATIONAL: { + AVRational val; + val = av_d2q(opt->default_val, INT_MAX); + av_set_q(s, opt->name, val); + } + break; + case FF_OPT_TYPE_STRING: + /* Cannot set default for string as default_val is of type * double */ + break; + default: + av_log(s, AV_LOG_DEBUG, "AVOption type %d of option %s not implemented yet\n", opt->type, opt->name); + } + } +} + diff --git a/src/libffmpeg/libavcodec/parser.h b/src/libffmpeg/libavcodec/parser.h new file mode 100644 index 000000000..3496b341f --- /dev/null +++ b/src/libffmpeg/libavcodec/parser.h @@ -0,0 +1,63 @@ +/* + * AVCodecParser prototypes and definitions + * Copyright (c) 2003 Fabrice Bellard. + * Copyright (c) 2003 Michael Niedermayer. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_PARSER_H +#define FFMPEG_PARSER_H + +typedef struct ParseContext{ + uint8_t *buffer; + int index; + int last_index; + unsigned int buffer_size; + uint32_t state; ///< contains the last few bytes in MSB order + int frame_start_found; + int overread; ///< the number of bytes which where irreversibly read from the next frame + int overread_index; ///< the index into ParseContext.buffer of the overreaded bytes +} ParseContext; + +struct MpegEncContext; + +typedef struct ParseContext1{ + ParseContext pc; +/* XXX/FIXME PC1 vs. PC */ + /* MPEG2 specific */ + AVRational frame_rate; + int progressive_sequence; + int width, height; + + /* XXX: suppress that, needed by MPEG4 */ + struct MpegEncContext *enc; + int first_picture; +} ParseContext1; + +#define END_NOT_FOUND (-100) + +int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size); +int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, + int buf_size); +void ff_parse_close(AVCodecParserContext *s); +void ff_parse1_close(AVCodecParserContext *s); + +/* h263dec.c */ +int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); + +#endif /* !FFMPEG_PARSER_H */ diff --git a/src/libreal/.cvsignore b/src/libffmpeg/libavcodec/ppc/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libreal/.cvsignore +++ b/src/libffmpeg/libavcodec/ppc/.hgignore diff --git a/src/libffmpeg/libavcodec/ppc/float_altivec.c b/src/libffmpeg/libavcodec/ppc/float_altivec.c new file mode 100644 index 000000000..22c2de61a --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/float_altivec.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" + +#include "gcc_fixes.h" + +#include "dsputil_altivec.h" + +static void vector_fmul_altivec(float *dst, const float *src, int len) +{ + int i; + vector float d0, d1, s, zero = (vector float)vec_splat_u32(0); + for(i=0; i<len-7; i+=8) { + d0 = vec_ld(0, dst+i); + s = vec_ld(0, src+i); + d1 = vec_ld(16, dst+i); + d0 = vec_madd(d0, s, zero); + d1 = vec_madd(d1, vec_ld(16,src+i), zero); + vec_st(d0, 0, dst+i); + vec_st(d1, 16, dst+i); + } +} + +static void vector_fmul_reverse_altivec(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + vector float d, s0, s1, h0, l0, + s2, s3, zero = (vector float)vec_splat_u32(0); + src1 += len-4; + for(i=0; i<len-7; i+=8) { + s1 = vec_ld(0, src1-i); // [a,b,c,d] + s0 = vec_ld(0, src0+i); + l0 = vec_mergel(s1, s1); // [c,c,d,d] + s3 = vec_ld(-16, src1-i); + h0 = vec_mergeh(s1, s1); // [a,a,b,b] + s2 = vec_ld(16, src0+i); + s1 = vec_mergeh(vec_mergel(l0,h0), // [d,b,d,b] + vec_mergeh(l0,h0)); // [c,a,c,a] + // [d,c,b,a] + l0 = vec_mergel(s3, s3); + d = vec_madd(s0, s1, zero); + h0 = vec_mergeh(s3, s3); + vec_st(d, 0, dst+i); + s3 = vec_mergeh(vec_mergel(l0,h0), + vec_mergeh(l0,h0)); + d = vec_madd(s2, s3, zero); + vec_st(d, 16, dst+i); + } +} + +static void vector_fmul_add_add_altivec(float *dst, const float *src0, + const float *src1, const float *src2, + int src3, int len, int step) +{ + int i; + vector float d, s0, s1, s2, t0, t1, edges; + vector unsigned char align = vec_lvsr(0,dst), + mask = vec_lvsl(0, dst); + +#if 0 //FIXME: there is still something wrong + if (step == 2) { + int y; + vector float d0, d1, s3, t2; + vector unsigned int sel = + vec_mergeh(vec_splat_u32(-1), vec_splat_u32(0)); + t1 = vec_ld(16, dst); + for (i=0,y=0; i<len-3; i+=4,y+=8) { + + s0 = vec_ld(0,src0+i); + s1 = vec_ld(0,src1+i); + s2 = vec_ld(0,src2+i); + +// t0 = vec_ld(0, dst+y); //[x x x|a] +// t1 = vec_ld(16, dst+y); //[b c d|e] + t2 = vec_ld(31, dst+y); //[f g h|x] + + d = vec_madd(s0,s1,s2); // [A B C D] + + // [A A B B] + + // [C C D D] + + d0 = vec_perm(t0, t1, mask); // [a b c d] + + d0 = vec_sel(vec_mergeh(d, d), d0, sel); // [A b B d] + + edges = vec_perm(t1, t0, mask); + + t0 = vec_perm(edges, d0, align); // [x x x|A] + + t1 = vec_perm(d0, edges, align); // [b B d|e] + + vec_stl(t0, 0, dst+y); + + d1 = vec_perm(t1, t2, mask); // [e f g h] + + d1 = vec_sel(vec_mergel(d, d), d1, sel); // [C f D h] + + edges = vec_perm(t2, t1, mask); + + t1 = vec_perm(edges, d1, align); // [b B d|C] + + t2 = vec_perm(d1, edges, align); // [f D h|x] + + vec_stl(t1, 16, dst+y); + + t0 = t1; + + vec_stl(t2, 31, dst+y); + + t1 = t2; + } + } else + #endif + if (step == 1 && src3 == 0) + for (i=0; i<len-3; i+=4) { + t0 = vec_ld(0, dst+i); + t1 = vec_ld(15, dst+i); + s0 = vec_ld(0, src0+i); + s1 = vec_ld(0, src1+i); + s2 = vec_ld(0, src2+i); + edges = vec_perm(t1 ,t0, mask); + d = vec_madd(s0,s1,s2); + t1 = vec_perm(d, edges, align); + t0 = vec_perm(edges, d, align); + vec_st(t1, 15, dst+i); + vec_st(t0, 0, dst+i); + } + else + ff_vector_fmul_add_add_c(dst, src0, src1, src2, src3, len, step); +} + +void float_to_int16_altivec(int16_t *dst, const float *src, int len) +{ + int i; + vector float s0, s1; + vector signed int t0, t1; + vector signed short d0, d1, d; + vector unsigned char align; + if(((long)dst)&15) //FIXME + for(i=0; i<len-7; i+=8) { + s0 = vec_ld(0, src+i); + s1 = vec_ld(16, src+i); + t0 = vec_cts(s0, 0); + d0 = vec_ld(0, dst+i); + t1 = vec_cts(s1, 0); + d1 = vec_ld(15, dst+i); + d = vec_packs(t0,t1); + d1 = vec_perm(d1, d0, vec_lvsl(0,dst+i)); + align = vec_lvsr(0, dst+i); + d0 = vec_perm(d1, d, align); + d1 = vec_perm(d, d1, align); + vec_st(d0, 0, dst+i); + vec_st(d1,15, dst+i); + } + else + for(i=0; i<len-7; i+=8) { + s0 = vec_ld(0, src+i); + s1 = vec_ld(16, src+i); + t0 = vec_cts(s0, 0); + t1 = vec_cts(s1, 0); + d = vec_packs(t0,t1); + vec_st(d, 0, dst+i); + } +} + +void float_init_altivec(DSPContext* c, AVCodecContext *avctx) +{ + c->vector_fmul = vector_fmul_altivec; + c->vector_fmul_reverse = vector_fmul_reverse_altivec; + c->vector_fmul_add_add = vector_fmul_add_add_altivec; + if(!(avctx->flags & CODEC_FLAG_BITEXACT)) + c->float_to_int16 = float_to_int16_altivec; +} diff --git a/src/libffmpeg/libavcodec/ppc/h264_altivec.c b/src/libffmpeg/libavcodec/ppc/h264_altivec.c new file mode 100644 index 000000000..bac620e82 --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/h264_altivec.c @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" + +#include "gcc_fixes.h" + +#include "dsputil_altivec.h" +#include "types_altivec.h" + +#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s +#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s) + +#define OP_U8_ALTIVEC PUT_OP_U8_ALTIVEC +#define PREFIX_h264_chroma_mc8_altivec put_h264_chroma_mc8_altivec +#define PREFIX_h264_chroma_mc8_num altivec_put_h264_chroma_mc8_num +#define PREFIX_h264_qpel16_h_lowpass_altivec put_h264_qpel16_h_lowpass_altivec +#define PREFIX_h264_qpel16_h_lowpass_num altivec_put_h264_qpel16_h_lowpass_num +#define PREFIX_h264_qpel16_v_lowpass_altivec put_h264_qpel16_v_lowpass_altivec +#define PREFIX_h264_qpel16_v_lowpass_num altivec_put_h264_qpel16_v_lowpass_num +#define PREFIX_h264_qpel16_hv_lowpass_altivec put_h264_qpel16_hv_lowpass_altivec +#define PREFIX_h264_qpel16_hv_lowpass_num altivec_put_h264_qpel16_hv_lowpass_num +#include "h264_template_altivec.c" +#undef OP_U8_ALTIVEC +#undef PREFIX_h264_chroma_mc8_altivec +#undef PREFIX_h264_chroma_mc8_num +#undef PREFIX_h264_qpel16_h_lowpass_altivec +#undef PREFIX_h264_qpel16_h_lowpass_num +#undef PREFIX_h264_qpel16_v_lowpass_altivec +#undef PREFIX_h264_qpel16_v_lowpass_num +#undef PREFIX_h264_qpel16_hv_lowpass_altivec +#undef PREFIX_h264_qpel16_hv_lowpass_num + +#define OP_U8_ALTIVEC AVG_OP_U8_ALTIVEC +#define PREFIX_h264_chroma_mc8_altivec avg_h264_chroma_mc8_altivec +#define PREFIX_h264_chroma_mc8_num altivec_avg_h264_chroma_mc8_num +#define PREFIX_h264_qpel16_h_lowpass_altivec avg_h264_qpel16_h_lowpass_altivec +#define PREFIX_h264_qpel16_h_lowpass_num altivec_avg_h264_qpel16_h_lowpass_num +#define PREFIX_h264_qpel16_v_lowpass_altivec avg_h264_qpel16_v_lowpass_altivec +#define PREFIX_h264_qpel16_v_lowpass_num altivec_avg_h264_qpel16_v_lowpass_num +#define PREFIX_h264_qpel16_hv_lowpass_altivec avg_h264_qpel16_hv_lowpass_altivec +#define PREFIX_h264_qpel16_hv_lowpass_num altivec_avg_h264_qpel16_hv_lowpass_num +#include "h264_template_altivec.c" +#undef OP_U8_ALTIVEC +#undef PREFIX_h264_chroma_mc8_altivec +#undef PREFIX_h264_chroma_mc8_num +#undef PREFIX_h264_qpel16_h_lowpass_altivec +#undef PREFIX_h264_qpel16_h_lowpass_num +#undef PREFIX_h264_qpel16_v_lowpass_altivec +#undef PREFIX_h264_qpel16_v_lowpass_num +#undef PREFIX_h264_qpel16_hv_lowpass_altivec +#undef PREFIX_h264_qpel16_hv_lowpass_num + +#define H264_MC(OPNAME, SIZE, CODETYPE) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){ \ + DECLARE_ALIGNED_16(uint8_t, half[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, half[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, half[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, half[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(int16_t, tmp[SIZE*(SIZE+8)]);\ + OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfHV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(int16_t, tmp[SIZE*(SIZE+8)]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfH[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfHV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(int16_t, tmp[SIZE*(SIZE+8)]);\ + put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfHV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(int16_t, tmp[SIZE*(SIZE+8)]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\ + DECLARE_ALIGNED_16(uint8_t, halfV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(uint8_t, halfHV[SIZE*SIZE]);\ + DECLARE_ALIGNED_16(int16_t, tmp[SIZE*(SIZE+8)]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\ +}\ + +/* this code assume that stride % 16 == 0 */ +void put_no_rnd_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) { + signed int ABCD[4] __attribute__((aligned(16))) = + {((8 - x) * (8 - y)), + ((x) * (8 - y)), + ((8 - x) * (y)), + ((x) * (y))}; + register int i; + vector unsigned char fperm; + const vector signed int vABCD = vec_ld(0, ABCD); + const vector signed short vA = vec_splat((vector signed short)vABCD, 1); + const vector signed short vB = vec_splat((vector signed short)vABCD, 3); + const vector signed short vC = vec_splat((vector signed short)vABCD, 5); + const vector signed short vD = vec_splat((vector signed short)vABCD, 7); + const vector signed int vzero = vec_splat_s32(0); + const vector signed short v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4)); + const vector unsigned short v6us = vec_splat_u16(6); + register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; + register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; + + vector unsigned char vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; + vector unsigned char vsrc0uc, vsrc1uc; + vector signed short vsrc0ssH, vsrc1ssH; + vector unsigned char vsrcCuc, vsrc2uc, vsrc3uc; + vector signed short vsrc2ssH, vsrc3ssH, psum; + vector unsigned char vdst, ppsum, fsum; + + if (((unsigned long)dst) % 16 == 0) { + fperm = (vector unsigned char)AVV(0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F); + } else { + fperm = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F); + } + + vsrcAuc = vec_ld(0, src); + + if (loadSecond) + vsrcBuc = vec_ld(16, src); + vsrcperm0 = vec_lvsl(0, src); + vsrcperm1 = vec_lvsl(1, src); + + vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); + if (reallyBadAlign) + vsrc1uc = vsrcBuc; + else + vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); + + vsrc0ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc0uc); + vsrc1ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc1uc); + + if (!loadSecond) {// -> !reallyBadAlign + for (i = 0 ; i < h ; i++) { + + + vsrcCuc = vec_ld(stride + 0, src); + + vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); + + vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc2uc); + vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc3uc); + + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v28ss, psum); + psum = vec_sra(psum, v6us); + + vdst = vec_ld(0, dst); + ppsum = (vector unsigned char)vec_packsu(psum, psum); + fsum = vec_perm(vdst, ppsum, fperm); + + vec_st(fsum, 0, dst); + + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; + + dst += stride; + src += stride; + } + } else { + vector unsigned char vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrcDuc = vec_ld(stride + 16, src); + + vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + if (reallyBadAlign) + vsrc3uc = vsrcDuc; + else + vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); + + vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc2uc); + vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc3uc); + + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v28ss, psum); + psum = vec_sr(psum, v6us); + + vdst = vec_ld(0, dst); + ppsum = (vector unsigned char)vec_pack(psum, psum); + fsum = vec_perm(vdst, ppsum, fperm); + + vec_st(fsum, 0, dst); + + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; + + dst += stride; + src += stride; + } + } +} + +static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, + const uint8_t * src2, int dst_stride, + int src_stride1, int h) +{ + int i; + vector unsigned char a, b, d, tmp1, tmp2, mask, mask_, edges, align; + + mask_ = vec_lvsl(0, src2); + + for (i = 0; i < h; i++) { + + tmp1 = vec_ld(i * src_stride1, src1); + mask = vec_lvsl(i * src_stride1, src1); + tmp2 = vec_ld(i * src_stride1 + 15, src1); + + a = vec_perm(tmp1, tmp2, mask); + + tmp1 = vec_ld(i * 16, src2); + tmp2 = vec_ld(i * 16 + 15, src2); + + b = vec_perm(tmp1, tmp2, mask_); + + tmp1 = vec_ld(0, dst); + mask = vec_lvsl(0, dst); + tmp2 = vec_ld(15, dst); + + d = vec_avg(a, b); + + edges = vec_perm(tmp2, tmp1, mask); + + align = vec_lvsr(0, dst); + + tmp2 = vec_perm(d, edges, align); + tmp1 = vec_perm(edges, d, align); + + vec_st(tmp2, 15, dst); + vec_st(tmp1, 0 , dst); + + dst += dst_stride; + } +} + +static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, + const uint8_t * src2, int dst_stride, + int src_stride1, int h) +{ + int i; + vector unsigned char a, b, d, tmp1, tmp2, mask, mask_, edges, align; + + mask_ = vec_lvsl(0, src2); + + for (i = 0; i < h; i++) { + + tmp1 = vec_ld(i * src_stride1, src1); + mask = vec_lvsl(i * src_stride1, src1); + tmp2 = vec_ld(i * src_stride1 + 15, src1); + + a = vec_perm(tmp1, tmp2, mask); + + tmp1 = vec_ld(i * 16, src2); + tmp2 = vec_ld(i * 16 + 15, src2); + + b = vec_perm(tmp1, tmp2, mask_); + + tmp1 = vec_ld(0, dst); + mask = vec_lvsl(0, dst); + tmp2 = vec_ld(15, dst); + + d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b)); + + edges = vec_perm(tmp2, tmp1, mask); + + align = vec_lvsr(0, dst); + + tmp2 = vec_perm(d, edges, align); + tmp1 = vec_perm(edges, d, align); + + vec_st(tmp2, 15, dst); + vec_st(tmp1, 0 , dst); + + dst += dst_stride; + } +} + +/* Implemented but could be faster +#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h) +#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h) + */ + + H264_MC(put_, 16, altivec) + H264_MC(avg_, 16, altivec) + + +/**************************************************************************** + * IDCT transform: + ****************************************************************************/ + +#define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, d0, d1, d2, d3, d4, d5, d6, d7) {\ + /* a0 = SRC(0) + SRC(4); */ \ + vec_s16_t a0v = vec_add(s0, s4); \ + /* a2 = SRC(0) - SRC(4); */ \ + vec_s16_t a2v = vec_sub(s0, s4); \ + /* a4 = (SRC(2)>>1) - SRC(6); */ \ + vec_s16_t a4v = vec_sub(vec_sra(s2, onev), s6); \ + /* a6 = (SRC(6)>>1) + SRC(2); */ \ + vec_s16_t a6v = vec_add(vec_sra(s6, onev), s2); \ + /* b0 = a0 + a6; */ \ + vec_s16_t b0v = vec_add(a0v, a6v); \ + /* b2 = a2 + a4; */ \ + vec_s16_t b2v = vec_add(a2v, a4v); \ + /* b4 = a2 - a4; */ \ + vec_s16_t b4v = vec_sub(a2v, a4v); \ + /* b6 = a0 - a6; */ \ + vec_s16_t b6v = vec_sub(a0v, a6v); \ + /* a1 = SRC(5) - SRC(3) - SRC(7) - (SRC(7)>>1); */ \ + /* a1 = (SRC(5)-SRC(3)) - (SRC(7) + (SRC(7)>>1)); */ \ + vec_s16_t a1v = vec_sub( vec_sub(s5, s3), vec_add(s7, vec_sra(s7, onev)) ); \ + /* a3 = SRC(7) + SRC(1) - SRC(3) - (SRC(3)>>1); */ \ + /* a3 = (SRC(7)+SRC(1)) - (SRC(3) + (SRC(3)>>1)); */ \ + vec_s16_t a3v = vec_sub( vec_add(s7, s1), vec_add(s3, vec_sra(s3, onev)) );\ + /* a5 = SRC(7) - SRC(1) + SRC(5) + (SRC(5)>>1); */ \ + /* a5 = (SRC(7)-SRC(1)) + SRC(5) + (SRC(5)>>1); */ \ + vec_s16_t a5v = vec_add( vec_sub(s7, s1), vec_add(s5, vec_sra(s5, onev)) );\ + /* a7 = SRC(5)+SRC(3) + SRC(1) + (SRC(1)>>1); */ \ + vec_s16_t a7v = vec_add( vec_add(s5, s3), vec_add(s1, vec_sra(s1, onev)) );\ + /* b1 = (a7>>2) + a1; */ \ + vec_s16_t b1v = vec_add( vec_sra(a7v, twov), a1v); \ + /* b3 = a3 + (a5>>2); */ \ + vec_s16_t b3v = vec_add(a3v, vec_sra(a5v, twov)); \ + /* b5 = (a3>>2) - a5; */ \ + vec_s16_t b5v = vec_sub( vec_sra(a3v, twov), a5v); \ + /* b7 = a7 - (a1>>2); */ \ + vec_s16_t b7v = vec_sub( a7v, vec_sra(a1v, twov)); \ + /* DST(0, b0 + b7); */ \ + d0 = vec_add(b0v, b7v); \ + /* DST(1, b2 + b5); */ \ + d1 = vec_add(b2v, b5v); \ + /* DST(2, b4 + b3); */ \ + d2 = vec_add(b4v, b3v); \ + /* DST(3, b6 + b1); */ \ + d3 = vec_add(b6v, b1v); \ + /* DST(4, b6 - b1); */ \ + d4 = vec_sub(b6v, b1v); \ + /* DST(5, b4 - b3); */ \ + d5 = vec_sub(b4v, b3v); \ + /* DST(6, b2 - b5); */ \ + d6 = vec_sub(b2v, b5v); \ + /* DST(7, b0 - b7); */ \ + d7 = vec_sub(b0v, b7v); \ +} + +#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \ + /* unaligned load */ \ + vec_u8_t hv = vec_ld( 0, dest ); \ + vec_u8_t lv = vec_ld( 7, dest ); \ + vec_u8_t dstv = vec_perm( hv, lv, (vec_u8_t)perm_ldv ); \ + vec_s16_t idct_sh6 = vec_sra(idctv, sixv); \ + vec_u16_t dst16 = (vec_u16_t)vec_mergeh(zero_u8v, dstv); \ + vec_s16_t idstsum = vec_adds(idct_sh6, (vec_s16_t)dst16); \ + vec_u8_t idstsum8 = vec_packsu(zero_s16v, idstsum); \ + vec_u8_t edgehv; \ + /* unaligned store */ \ + vec_u8_t bodyv = vec_perm( idstsum8, idstsum8, perm_stv );\ + vec_u8_t edgelv = vec_perm( sel, zero_u8v, perm_stv ); \ + lv = vec_sel( lv, bodyv, edgelv ); \ + vec_st( lv, 7, dest ); \ + hv = vec_ld( 0, dest ); \ + edgehv = vec_perm( zero_u8v, sel, perm_stv ); \ + hv = vec_sel( hv, bodyv, edgehv ); \ + vec_st( hv, 0, dest ); \ + } + +void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) { + vec_s16_t s0, s1, s2, s3, s4, s5, s6, s7; + vec_s16_t d0, d1, d2, d3, d4, d5, d6, d7; + vec_s16_t idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7; + + vec_u8_t perm_ldv = vec_lvsl(0, dst); + vec_u8_t perm_stv = vec_lvsr(8, dst); + + const vec_u16_t onev = vec_splat_u16(1); + const vec_u16_t twov = vec_splat_u16(2); + const vec_u16_t sixv = vec_splat_u16(6); + + const vec_u8_t sel = (vec_u8_t) AVV(0,0,0,0,0,0,0,0, + -1,-1,-1,-1,-1,-1,-1,-1); + LOAD_ZERO; + + dct[0] += 32; // rounding for the >>6 at the end + + s0 = vec_ld(0x00, (int16_t*)dct); + s1 = vec_ld(0x10, (int16_t*)dct); + s2 = vec_ld(0x20, (int16_t*)dct); + s3 = vec_ld(0x30, (int16_t*)dct); + s4 = vec_ld(0x40, (int16_t*)dct); + s5 = vec_ld(0x50, (int16_t*)dct); + s6 = vec_ld(0x60, (int16_t*)dct); + s7 = vec_ld(0x70, (int16_t*)dct); + + IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, + d0, d1, d2, d3, d4, d5, d6, d7); + + TRANSPOSE8( d0, d1, d2, d3, d4, d5, d6, d7 ); + + IDCT8_1D_ALTIVEC(d0, d1, d2, d3, d4, d5, d6, d7, + idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7); + + ALTIVEC_STORE_SUM_CLIP(&dst[0*stride], idct0, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[1*stride], idct1, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[2*stride], idct2, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[3*stride], idct3, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[4*stride], idct4, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[5*stride], idct5, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[6*stride], idct6, perm_ldv, perm_stv, sel); + ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel); +} + +void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) { + +#ifdef HAVE_ALTIVEC + if (has_altivec()) { + c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; + c->put_no_rnd_h264_chroma_pixels_tab[0] = put_no_rnd_h264_chroma_mc8_altivec; + c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; + c->h264_idct8_add = ff_h264_idct8_add_altivec; + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 0, 16); +#undef dspfunc + + } else +#endif /* HAVE_ALTIVEC */ + { + // Non-AltiVec PPC optimisations + + // ... pending ... + } +} diff --git a/src/libffmpeg/libavcodec/ppc/h264_template_altivec.c b/src/libffmpeg/libavcodec/ppc/h264_template_altivec.c new file mode 100644 index 000000000..e8ad67f2f --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/h264_template_altivec.c @@ -0,0 +1,719 @@ +/* + * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* this code assume that stride % 16 == 0 */ +void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) { + POWERPC_PERF_DECLARE(PREFIX_h264_chroma_mc8_num, 1); + signed int ABCD[4] __attribute__((aligned(16))) = + {((8 - x) * (8 - y)), + ((x) * (8 - y)), + ((8 - x) * (y)), + ((x) * (y))}; + register int i; + vector unsigned char fperm; + const vector signed int vABCD = vec_ld(0, ABCD); + const vector signed short vA = vec_splat((vector signed short)vABCD, 1); + const vector signed short vB = vec_splat((vector signed short)vABCD, 3); + const vector signed short vC = vec_splat((vector signed short)vABCD, 5); + const vector signed short vD = vec_splat((vector signed short)vABCD, 7); + const vector signed int vzero = vec_splat_s32(0); + const vector signed short v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5)); + const vector unsigned short v6us = vec_splat_u16(6); + register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; + register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; + + vector unsigned char vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; + vector unsigned char vsrc0uc, vsrc1uc; + vector signed short vsrc0ssH, vsrc1ssH; + vector unsigned char vsrcCuc, vsrc2uc, vsrc3uc; + vector signed short vsrc2ssH, vsrc3ssH, psum; + vector unsigned char vdst, ppsum, vfdst, fsum; + + POWERPC_PERF_START_COUNT(PREFIX_h264_chroma_mc8_num, 1); + + if (((unsigned long)dst) % 16 == 0) { + fperm = (vector unsigned char)AVV(0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F); + } else { + fperm = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F); + } + + vsrcAuc = vec_ld(0, src); + + if (loadSecond) + vsrcBuc = vec_ld(16, src); + vsrcperm0 = vec_lvsl(0, src); + vsrcperm1 = vec_lvsl(1, src); + + vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); + if (reallyBadAlign) + vsrc1uc = vsrcBuc; + else + vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); + + vsrc0ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc0uc); + vsrc1ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc1uc); + + if (!loadSecond) {// -> !reallyBadAlign + for (i = 0 ; i < h ; i++) { + + + vsrcCuc = vec_ld(stride + 0, src); + + vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); + + vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc2uc); + vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc3uc); + + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v32ss, psum); + psum = vec_sra(psum, v6us); + + vdst = vec_ld(0, dst); + ppsum = (vector unsigned char)vec_packsu(psum, psum); + vfdst = vec_perm(vdst, ppsum, fperm); + + OP_U8_ALTIVEC(fsum, vfdst, vdst); + + vec_st(fsum, 0, dst); + + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; + + dst += stride; + src += stride; + } + } else { + vector unsigned char vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrcDuc = vec_ld(stride + 16, src); + + vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + if (reallyBadAlign) + vsrc3uc = vsrcDuc; + else + vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); + + vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc2uc); + vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, + (vector unsigned char)vsrc3uc); + + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v32ss, psum); + psum = vec_sr(psum, v6us); + + vdst = vec_ld(0, dst); + ppsum = (vector unsigned char)vec_pack(psum, psum); + vfdst = vec_perm(vdst, ppsum, fperm); + + OP_U8_ALTIVEC(fsum, vfdst, vdst); + + vec_st(fsum, 0, dst); + + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; + + dst += stride; + src += stride; + } + } + POWERPC_PERF_STOP_COUNT(PREFIX_h264_chroma_mc8_num, 1); +} + +/* this code assume stride % 16 == 0 */ +static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { + POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_h_lowpass_num, 1); + register int i; + + const vector signed int vzero = vec_splat_s32(0); + const vector unsigned char permM2 = vec_lvsl(-2, src); + const vector unsigned char permM1 = vec_lvsl(-1, src); + const vector unsigned char permP0 = vec_lvsl(+0, src); + const vector unsigned char permP1 = vec_lvsl(+1, src); + const vector unsigned char permP2 = vec_lvsl(+2, src); + const vector unsigned char permP3 = vec_lvsl(+3, src); + const vector signed short v5ss = vec_splat_s16(5); + const vector unsigned short v5us = vec_splat_u16(5); + const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vector signed short v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); + const vector unsigned char dstperm = vec_lvsr(0, dst); + const vector unsigned char neg1 = + (const vector unsigned char) vec_splat_s8(-1); + + const vector unsigned char dstmask = + vec_perm((const vector unsigned char)vzero, + neg1, dstperm); + + vector unsigned char srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; + + register int align = ((((unsigned long)src) - 2) % 16); + + vector signed short srcP0A, srcP0B, srcP1A, srcP1B, + srcP2A, srcP2B, srcP3A, srcP3B, + srcM1A, srcM1B, srcM2A, srcM2B, + sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, + pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, + psumA, psumB, sumA, sumB; + + vector unsigned char sum, dst1, dst2, vdst, fsum, + rsum, fdst1, fdst2; + + POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_h_lowpass_num, 1); + + for (i = 0 ; i < 16 ; i ++) { + vector unsigned char srcR1 = vec_ld(-2, src); + vector unsigned char srcR2 = vec_ld(14, src); + + switch (align) { + default: { + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = vec_perm(srcR1, srcR2, permP2); + srcP3 = vec_perm(srcR1, srcR2, permP3); + } break; + case 11: { + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = vec_perm(srcR1, srcR2, permP2); + srcP3 = srcR2; + } break; + case 12: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = srcR2; + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 13: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = srcR2; + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 14: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = srcR2; + srcP1 = vec_perm(srcR2, srcR3, permP1); + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 15: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = srcR2; + srcP0 = vec_perm(srcR2, srcR3, permP0); + srcP1 = vec_perm(srcR2, srcR3, permP1); + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + } + + srcP0A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP0); + srcP0B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP0); + srcP1A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP1); + srcP1B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP1); + + srcP2A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP2); + srcP2B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP2); + srcP3A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP3); + srcP3B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP3); + + srcM1A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM1); + srcM1B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM1); + srcM2A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM2); + srcM2B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM2); + + sum1A = vec_adds(srcP0A, srcP1A); + sum1B = vec_adds(srcP0B, srcP1B); + sum2A = vec_adds(srcM1A, srcP2A); + sum2B = vec_adds(srcM1B, srcP2B); + sum3A = vec_adds(srcM2A, srcP3A); + sum3B = vec_adds(srcM2B, srcP3B); + + pp1A = vec_mladd(sum1A, v20ss, v16ss); + pp1B = vec_mladd(sum1B, v20ss, v16ss); + + pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); + pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + + pp3A = vec_add(sum3A, pp1A); + pp3B = vec_add(sum3B, pp1B); + + psumA = vec_sub(pp3A, pp2A); + psumB = vec_sub(pp3B, pp2B); + + sumA = vec_sra(psumA, v5us); + sumB = vec_sra(psumB, v5us); + + sum = vec_packsu(sumA, sumB); + + dst1 = vec_ld(0, dst); + dst2 = vec_ld(16, dst); + vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + + OP_U8_ALTIVEC(fsum, sum, vdst); + + rsum = vec_perm(fsum, fsum, dstperm); + fdst1 = vec_sel(dst1, rsum, dstmask); + fdst2 = vec_sel(rsum, dst2, dstmask); + + vec_st(fdst1, 0, dst); + vec_st(fdst2, 16, dst); + + src += srcStride; + dst += dstStride; + } +POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_h_lowpass_num, 1); +} + +/* this code assume stride % 16 == 0 */ +static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { + POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_v_lowpass_num, 1); + + register int i; + + const vector signed int vzero = vec_splat_s32(0); + const vector unsigned char perm = vec_lvsl(0, src); + const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vector unsigned short v5us = vec_splat_u16(5); + const vector signed short v5ss = vec_splat_s16(5); + const vector signed short v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); + const vector unsigned char dstperm = vec_lvsr(0, dst); + const vector unsigned char neg1 = (const vector unsigned char)vec_splat_s8(-1); + const vector unsigned char dstmask = vec_perm((const vector unsigned char)vzero, neg1, dstperm); + + uint8_t *srcbis = src - (srcStride * 2); + + const vector unsigned char srcM2a = vec_ld(0, srcbis); + const vector unsigned char srcM2b = vec_ld(16, srcbis); + const vector unsigned char srcM2 = vec_perm(srcM2a, srcM2b, perm); +// srcbis += srcStride; + const vector unsigned char srcM1a = vec_ld(0, srcbis += srcStride); + const vector unsigned char srcM1b = vec_ld(16, srcbis); + const vector unsigned char srcM1 = vec_perm(srcM1a, srcM1b, perm); +// srcbis += srcStride; + const vector unsigned char srcP0a = vec_ld(0, srcbis += srcStride); + const vector unsigned char srcP0b = vec_ld(16, srcbis); + const vector unsigned char srcP0 = vec_perm(srcP0a, srcP0b, perm); +// srcbis += srcStride; + const vector unsigned char srcP1a = vec_ld(0, srcbis += srcStride); + const vector unsigned char srcP1b = vec_ld(16, srcbis); + const vector unsigned char srcP1 = vec_perm(srcP1a, srcP1b, perm); +// srcbis += srcStride; + const vector unsigned char srcP2a = vec_ld(0, srcbis += srcStride); + const vector unsigned char srcP2b = vec_ld(16, srcbis); + const vector unsigned char srcP2 = vec_perm(srcP2a, srcP2b, perm); +// srcbis += srcStride; + + vector signed short srcM2ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM2); + vector signed short srcM2ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM2); + vector signed short srcM1ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM1); + vector signed short srcM1ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM1); + vector signed short srcP0ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP0); + vector signed short srcP0ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP0); + vector signed short srcP1ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP1); + vector signed short srcP1ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP1); + vector signed short srcP2ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP2); + vector signed short srcP2ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP2); + + vector signed short pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, + psumA, psumB, sumA, sumB, + srcP3ssA, srcP3ssB, + sum1A, sum1B, sum2A, sum2B, sum3A, sum3B; + + vector unsigned char sum, dst1, dst2, vdst, fsum, rsum, fdst1, fdst2, + srcP3a, srcP3b, srcP3; + + POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_v_lowpass_num, 1); + + for (i = 0 ; i < 16 ; i++) { + srcP3a = vec_ld(0, srcbis += srcStride); + srcP3b = vec_ld(16, srcbis); + srcP3 = vec_perm(srcP3a, srcP3b, perm); + srcP3ssA = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP3); + srcP3ssB = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP3); +// srcbis += srcStride; + + sum1A = vec_adds(srcP0ssA, srcP1ssA); + sum1B = vec_adds(srcP0ssB, srcP1ssB); + sum2A = vec_adds(srcM1ssA, srcP2ssA); + sum2B = vec_adds(srcM1ssB, srcP2ssB); + sum3A = vec_adds(srcM2ssA, srcP3ssA); + sum3B = vec_adds(srcM2ssB, srcP3ssB); + + srcM2ssA = srcM1ssA; + srcM2ssB = srcM1ssB; + srcM1ssA = srcP0ssA; + srcM1ssB = srcP0ssB; + srcP0ssA = srcP1ssA; + srcP0ssB = srcP1ssB; + srcP1ssA = srcP2ssA; + srcP1ssB = srcP2ssB; + srcP2ssA = srcP3ssA; + srcP2ssB = srcP3ssB; + + pp1A = vec_mladd(sum1A, v20ss, v16ss); + pp1B = vec_mladd(sum1B, v20ss, v16ss); + + pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); + pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + + pp3A = vec_add(sum3A, pp1A); + pp3B = vec_add(sum3B, pp1B); + + psumA = vec_sub(pp3A, pp2A); + psumB = vec_sub(pp3B, pp2B); + + sumA = vec_sra(psumA, v5us); + sumB = vec_sra(psumB, v5us); + + sum = vec_packsu(sumA, sumB); + + dst1 = vec_ld(0, dst); + dst2 = vec_ld(16, dst); + vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + + OP_U8_ALTIVEC(fsum, sum, vdst); + + rsum = vec_perm(fsum, fsum, dstperm); + fdst1 = vec_sel(dst1, rsum, dstmask); + fdst2 = vec_sel(rsum, dst2, dstmask); + + vec_st(fdst1, 0, dst); + vec_st(fdst2, 16, dst); + + dst += dstStride; + } + POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_v_lowpass_num, 1); +} + +/* this code assume stride % 16 == 0 *and* tmp is properly aligned */ +static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) { + POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_hv_lowpass_num, 1); + register int i; + const vector signed int vzero = vec_splat_s32(0); + const vector unsigned char permM2 = vec_lvsl(-2, src); + const vector unsigned char permM1 = vec_lvsl(-1, src); + const vector unsigned char permP0 = vec_lvsl(+0, src); + const vector unsigned char permP1 = vec_lvsl(+1, src); + const vector unsigned char permP2 = vec_lvsl(+2, src); + const vector unsigned char permP3 = vec_lvsl(+3, src); + const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vector unsigned int v10ui = vec_splat_u32(10); + const vector signed short v5ss = vec_splat_s16(5); + const vector signed short v1ss = vec_splat_s16(1); + const vector signed int v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9)); + const vector unsigned int v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4)); + + register int align = ((((unsigned long)src) - 2) % 16); + + const vector unsigned char neg1 = (const vector unsigned char) + vec_splat_s8(-1); + + vector signed short srcP0A, srcP0B, srcP1A, srcP1B, + srcP2A, srcP2B, srcP3A, srcP3B, + srcM1A, srcM1B, srcM2A, srcM2B, + sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, + pp1A, pp1B, pp2A, pp2B, psumA, psumB; + + const vector unsigned char dstperm = vec_lvsr(0, dst); + + const vector unsigned char dstmask = vec_perm((const vector unsigned char)vzero, neg1, dstperm); + + const vector unsigned char mperm = (const vector unsigned char) + AVV(0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, + 0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F); + int16_t *tmpbis = tmp; + + vector signed short tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB, + tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB, + tmpP2ssA, tmpP2ssB; + + vector signed int pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo, + pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo, + pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo, + ssumAe, ssumAo, ssumBe, ssumBo; + vector unsigned char fsum, sumv, sum, dst1, dst2, vdst, + rsum, fdst1, fdst2; + vector signed short ssume, ssumo; + + POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_hv_lowpass_num, 1); + src -= (2 * srcStride); + for (i = 0 ; i < 21 ; i ++) { + vector unsigned char srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; + vector unsigned char srcR1 = vec_ld(-2, src); + vector unsigned char srcR2 = vec_ld(14, src); + + switch (align) { + default: { + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = vec_perm(srcR1, srcR2, permP2); + srcP3 = vec_perm(srcR1, srcR2, permP3); + } break; + case 11: { + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = vec_perm(srcR1, srcR2, permP2); + srcP3 = srcR2; + } break; + case 12: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = vec_perm(srcR1, srcR2, permP1); + srcP2 = srcR2; + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 13: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = vec_perm(srcR1, srcR2, permP0); + srcP1 = srcR2; + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 14: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = vec_perm(srcR1, srcR2, permM1); + srcP0 = srcR2; + srcP1 = vec_perm(srcR2, srcR3, permP1); + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + case 15: { + vector unsigned char srcR3 = vec_ld(30, src); + srcM2 = vec_perm(srcR1, srcR2, permM2); + srcM1 = srcR2; + srcP0 = vec_perm(srcR2, srcR3, permP0); + srcP1 = vec_perm(srcR2, srcR3, permP1); + srcP2 = vec_perm(srcR2, srcR3, permP2); + srcP3 = vec_perm(srcR2, srcR3, permP3); + } break; + } + + srcP0A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP0); + srcP0B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP0); + srcP1A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP1); + srcP1B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP1); + + srcP2A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP2); + srcP2B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP2); + srcP3A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcP3); + srcP3B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcP3); + + srcM1A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM1); + srcM1B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM1); + srcM2A = (vector signed short) + vec_mergeh((vector unsigned char)vzero, srcM2); + srcM2B = (vector signed short) + vec_mergel((vector unsigned char)vzero, srcM2); + + sum1A = vec_adds(srcP0A, srcP1A); + sum1B = vec_adds(srcP0B, srcP1B); + sum2A = vec_adds(srcM1A, srcP2A); + sum2B = vec_adds(srcM1B, srcP2B); + sum3A = vec_adds(srcM2A, srcP3A); + sum3B = vec_adds(srcM2B, srcP3B); + + pp1A = vec_mladd(sum1A, v20ss, sum3A); + pp1B = vec_mladd(sum1B, v20ss, sum3B); + + pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); + pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + + psumA = vec_sub(pp1A, pp2A); + psumB = vec_sub(pp1B, pp2B); + + vec_st(psumA, 0, tmp); + vec_st(psumB, 16, tmp); + + src += srcStride; + tmp += tmpStride; /* int16_t*, and stride is 16, so it's OK here */ + } + + tmpM2ssA = vec_ld(0, tmpbis); + tmpM2ssB = vec_ld(16, tmpbis); + tmpbis += tmpStride; + tmpM1ssA = vec_ld(0, tmpbis); + tmpM1ssB = vec_ld(16, tmpbis); + tmpbis += tmpStride; + tmpP0ssA = vec_ld(0, tmpbis); + tmpP0ssB = vec_ld(16, tmpbis); + tmpbis += tmpStride; + tmpP1ssA = vec_ld(0, tmpbis); + tmpP1ssB = vec_ld(16, tmpbis); + tmpbis += tmpStride; + tmpP2ssA = vec_ld(0, tmpbis); + tmpP2ssB = vec_ld(16, tmpbis); + tmpbis += tmpStride; + + for (i = 0 ; i < 16 ; i++) { + const vector signed short tmpP3ssA = vec_ld(0, tmpbis); + const vector signed short tmpP3ssB = vec_ld(16, tmpbis); + + const vector signed short sum1A = vec_adds(tmpP0ssA, tmpP1ssA); + const vector signed short sum1B = vec_adds(tmpP0ssB, tmpP1ssB); + const vector signed short sum2A = vec_adds(tmpM1ssA, tmpP2ssA); + const vector signed short sum2B = vec_adds(tmpM1ssB, tmpP2ssB); + const vector signed short sum3A = vec_adds(tmpM2ssA, tmpP3ssA); + const vector signed short sum3B = vec_adds(tmpM2ssB, tmpP3ssB); + + tmpbis += tmpStride; + + tmpM2ssA = tmpM1ssA; + tmpM2ssB = tmpM1ssB; + tmpM1ssA = tmpP0ssA; + tmpM1ssB = tmpP0ssB; + tmpP0ssA = tmpP1ssA; + tmpP0ssB = tmpP1ssB; + tmpP1ssA = tmpP2ssA; + tmpP1ssB = tmpP2ssB; + tmpP2ssA = tmpP3ssA; + tmpP2ssB = tmpP3ssB; + + pp1Ae = vec_mule(sum1A, v20ss); + pp1Ao = vec_mulo(sum1A, v20ss); + pp1Be = vec_mule(sum1B, v20ss); + pp1Bo = vec_mulo(sum1B, v20ss); + + pp2Ae = vec_mule(sum2A, v5ss); + pp2Ao = vec_mulo(sum2A, v5ss); + pp2Be = vec_mule(sum2B, v5ss); + pp2Bo = vec_mulo(sum2B, v5ss); + + pp3Ae = vec_sra((vector signed int)sum3A, v16ui); + pp3Ao = vec_mulo(sum3A, v1ss); + pp3Be = vec_sra((vector signed int)sum3B, v16ui); + pp3Bo = vec_mulo(sum3B, v1ss); + + pp1cAe = vec_add(pp1Ae, v512si); + pp1cAo = vec_add(pp1Ao, v512si); + pp1cBe = vec_add(pp1Be, v512si); + pp1cBo = vec_add(pp1Bo, v512si); + + pp32Ae = vec_sub(pp3Ae, pp2Ae); + pp32Ao = vec_sub(pp3Ao, pp2Ao); + pp32Be = vec_sub(pp3Be, pp2Be); + pp32Bo = vec_sub(pp3Bo, pp2Bo); + + sumAe = vec_add(pp1cAe, pp32Ae); + sumAo = vec_add(pp1cAo, pp32Ao); + sumBe = vec_add(pp1cBe, pp32Be); + sumBo = vec_add(pp1cBo, pp32Bo); + + ssumAe = vec_sra(sumAe, v10ui); + ssumAo = vec_sra(sumAo, v10ui); + ssumBe = vec_sra(sumBe, v10ui); + ssumBo = vec_sra(sumBo, v10ui); + + ssume = vec_packs(ssumAe, ssumBe); + ssumo = vec_packs(ssumAo, ssumBo); + + sumv = vec_packsu(ssume, ssumo); + sum = vec_perm(sumv, sumv, mperm); + + dst1 = vec_ld(0, dst); + dst2 = vec_ld(16, dst); + vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + + OP_U8_ALTIVEC(fsum, sum, vdst); + + rsum = vec_perm(fsum, fsum, dstperm); + fdst1 = vec_sel(dst1, rsum, dstmask); + fdst2 = vec_sel(rsum, dst2, dstmask); + + vec_st(fdst1, 0, dst); + vec_st(fdst2, 16, dst); + + dst += dstStride; + } + POWERPC_PERF_STOP_COUNT(PREFIX_h264_qpel16_hv_lowpass_num, 1); +} diff --git a/src/libffmpeg/libavcodec/ppc/mathops.h b/src/libffmpeg/libavcodec/ppc/mathops.h new file mode 100644 index 000000000..6af23f246 --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/mathops.h @@ -0,0 +1,33 @@ +/* + * simple math operations + * Copyright (c) 2001, 2002 Fabrice Bellard. + * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if defined(ARCH_POWERPC_405) +/* signed 16x16 -> 32 multiply add accumulate */ +# define MAC16(rt, ra, rb) \ + asm ("maclhw %0, %2, %3" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb)); + +/* signed 16x16 -> 32 multiply */ +# define MUL16(ra, rb) \ + ({ int __rt; + asm ("mullhw %0, %1, %2" : "=r" (__rt) : "r" (ra), "r" (rb)); + __rt; }) +#endif diff --git a/src/libffmpeg/libavcodec/ppc/snow_altivec.c b/src/libffmpeg/libavcodec/ppc/snow_altivec.c new file mode 100644 index 000000000..b15672ffe --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/snow_altivec.c @@ -0,0 +1,788 @@ +/* + * Altivec optimized snow DSP utils + * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * + */ + +#include "../dsputil.h" + +#include "gcc_fixes.h" +#include "dsputil_altivec.h" +#include "../snow.h" + +#undef NDEBUG +#include <assert.h> + + + +//FIXME remove this replication +#define slice_buffer_get_line(slice_buf, line_num) ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] : slice_buffer_load_line((slice_buf), (line_num))) + +static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) +{ + int offset; + DWTELEM * buffer; + +// av_log(NULL, AV_LOG_DEBUG, "Cache hit: %d\n", line); + + assert(buf->data_stack_top >= 0); +// assert(!buf->line[line]); + if (buf->line[line]) + return buf->line[line]; + + offset = buf->line_width * line; + buffer = buf->data_stack[buf->data_stack_top]; + buf->data_stack_top--; + buf->line[line] = buffer; + +// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_load_line: line: %d remaining: %d\n", line, buf->data_stack_top + 1); + + return buffer; +} + + +//altivec code + +void ff_snow_horizontal_compose97i_altivec(DWTELEM *b, int width) +{ + const int w2= (width+1)>>1; + DECLARE_ALIGNED_16(DWTELEM, temp[(width>>1)]); + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + vector signed int t1, t2, x, y, tmp1, tmp2; + vector signed int *vbuf, *vtmp; + vector unsigned char align; + + + + { // Lift 0 + DWTELEM * const ref = b + w2 - 1; + DWTELEM b_0 = b[0]; + vbuf = (vector signed int *)b; + + tmp1 = vec_ld (0, ref); + align = vec_lvsl (0, ref); + tmp2 = vec_ld (15, ref); + t1= vec_perm(tmp1, tmp2, align); + + i = 0; + + for (i=0; i<w_l-15; i+=16) { +#if 0 + b[i+0] = b[i+0] - ((3 * (ref[i+0] + ref[i+1]) + 4) >> 3); + b[i+1] = b[i+1] - ((3 * (ref[i+1] + ref[i+2]) + 4) >> 3); + b[i+2] = b[i+2] - ((3 * (ref[i+2] + ref[i+3]) + 4) >> 3); + b[i+3] = b[i+3] - ((3 * (ref[i+3] + ref[i+4]) + 4) >> 3); +#else + + tmp1 = vec_ld (0, ref+4+i); + tmp2 = vec_ld (15, ref+4+i); + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_add(vec_add(y,y),y); + + tmp1 = vec_ld (0, ref+8+i); + + y = vec_add(y, vec_splat_s32(4)); + y = vec_sra(y, vec_splat_u32(3)); + + tmp2 = vec_ld (15, ref+8+i); + + *vbuf = vec_sub(*vbuf, y); + + t1=t2; + + vbuf++; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_add(vec_add(y,y),y); + + tmp1 = vec_ld (0, ref+12+i); + + y = vec_add(y, vec_splat_s32(4)); + y = vec_sra(y, vec_splat_u32(3)); + + tmp2 = vec_ld (15, ref+12+i); + + *vbuf = vec_sub(*vbuf, y); + + t1=t2; + + vbuf++; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_add(vec_add(y,y),y); + + tmp1 = vec_ld (0, ref+16+i); + + y = vec_add(y, vec_splat_s32(4)); + y = vec_sra(y, vec_splat_u32(3)); + + tmp2 = vec_ld (15, ref+16+i); + + *vbuf = vec_sub(*vbuf, y); + + t1=t2; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_add(vec_add(y,y),y); + + vbuf++; + + y = vec_add(y, vec_splat_s32(4)); + y = vec_sra(y, vec_splat_u32(3)); + *vbuf = vec_sub(*vbuf, y); + + t1=t2; + + vbuf++; + +#endif + } + + snow_horizontal_compose_lift_lead_out(i, b, b, ref, width, w_l, 0, W_DM, W_DO, W_DS); + b[0] = b_0 - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); + } + + { // Lift 1 + DWTELEM * const dst = b+w2; + + i = 0; + for(; (((long)&dst[i]) & 0xF) && i<w_r; i++){ + dst[i] = dst[i] - (b[i] + b[i + 1]); + } + + align = vec_lvsl(0, b+i); + tmp1 = vec_ld(0, b+i); + vbuf = (vector signed int*) (dst + i); + tmp2 = vec_ld(15, b+i); + + t1 = vec_perm(tmp1, tmp2, align); + + for (; i<w_r-3; i+=4) { + +#if 0 + dst[i] = dst[i] - (b[i] + b[i + 1]); + dst[i+1] = dst[i+1] - (b[i+1] + b[i + 2]); + dst[i+2] = dst[i+2] - (b[i+2] + b[i + 3]); + dst[i+3] = dst[i+3] - (b[i+3] + b[i + 4]); +#else + + tmp1 = vec_ld(0, b+4+i); + tmp2 = vec_ld(15, b+4+i); + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1, vec_sld(t1,t2,4)); + *vbuf = vec_sub (*vbuf, y); + + vbuf++; + + t1 = t2; + +#endif + + } + + snow_horizontal_compose_lift_lead_out(i, dst, dst, b, width, w_r, 1, W_CM, W_CO, W_CS); + } + + { // Lift 2 + DWTELEM * const ref = b+w2 - 1; + DWTELEM b_0 = b[0]; + vbuf= (vector signed int *) b; + + tmp1 = vec_ld (0, ref); + align = vec_lvsl (0, ref); + tmp2 = vec_ld (15, ref); + t1= vec_perm(tmp1, tmp2, align); + + i = 0; + for (; i<w_l-15; i+=16) { +#if 0 + b[i] = b[i] - (((8 -(ref[i] + ref[i+1])) - (b[i] <<2)) >> 4); + b[i+1] = b[i+1] - (((8 -(ref[i+1] + ref[i+2])) - (b[i+1]<<2)) >> 4); + b[i+2] = b[i+2] - (((8 -(ref[i+2] + ref[i+3])) - (b[i+2]<<2)) >> 4); + b[i+3] = b[i+3] - (((8 -(ref[i+3] + ref[i+4])) - (b[i+3]<<2)) >> 4); +#else + tmp1 = vec_ld (0, ref+4+i); + tmp2 = vec_ld (15, ref+4+i); + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_sub(vec_splat_s32(8),y); + + tmp1 = vec_ld (0, ref+8+i); + + x = vec_sl(*vbuf,vec_splat_u32(2)); + y = vec_sra(vec_sub(y,x),vec_splat_u32(4)); + + tmp2 = vec_ld (15, ref+8+i); + + *vbuf = vec_sub( *vbuf, y); + + t1 = t2; + + vbuf++; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_sub(vec_splat_s32(8),y); + + tmp1 = vec_ld (0, ref+12+i); + + x = vec_sl(*vbuf,vec_splat_u32(2)); + y = vec_sra(vec_sub(y,x),vec_splat_u32(4)); + + tmp2 = vec_ld (15, ref+12+i); + + *vbuf = vec_sub( *vbuf, y); + + t1 = t2; + + vbuf++; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_sub(vec_splat_s32(8),y); + + tmp1 = vec_ld (0, ref+16+i); + + x = vec_sl(*vbuf,vec_splat_u32(2)); + y = vec_sra(vec_sub(y,x),vec_splat_u32(4)); + + tmp2 = vec_ld (15, ref+16+i); + + *vbuf = vec_sub( *vbuf, y); + + t1 = t2; + + vbuf++; + + t2 = vec_perm(tmp1, tmp2, align); + + y = vec_add(t1,vec_sld(t1,t2,4)); + y = vec_sub(vec_splat_s32(8),y); + + t1 = t2; + + x = vec_sl(*vbuf,vec_splat_u32(2)); + y = vec_sra(vec_sub(y,x),vec_splat_u32(4)); + *vbuf = vec_sub( *vbuf, y); + + vbuf++; + +#endif + } + + snow_horizontal_compose_liftS_lead_out(i, b, b, ref, width, w_l); + b[0] = b_0 - (((-2 * ref[1] + W_BO) - 4 * b_0) >> W_BS); + } + + { // Lift 3 + DWTELEM * const src = b+w2; + + vbuf = (vector signed int *)b; + vtmp = (vector signed int *)temp; + + i = 0; + align = vec_lvsl(0, src); + + for (; i<w_r-3; i+=4) { +#if 0 + temp[i] = src[i] - ((-3*(b[i] + b[i+1]))>>1); + temp[i+1] = src[i+1] - ((-3*(b[i+1] + b[i+2]))>>1); + temp[i+2] = src[i+2] - ((-3*(b[i+2] + b[i+3]))>>1); + temp[i+3] = src[i+3] - ((-3*(b[i+3] + b[i+4]))>>1); +#else + tmp1 = vec_ld(0,src+i); + t1 = vec_add(vbuf[0],vec_sld(vbuf[0],vbuf[1],4)); + tmp2 = vec_ld(15,src+i); + t1 = vec_sub(vec_splat_s32(0),t1); //bad! + t1 = vec_add(t1,vec_add(t1,t1)); + t2 = vec_perm(tmp1 ,tmp2 ,align); + t1 = vec_sra(t1,vec_splat_u32(1)); + vbuf++; + *vtmp = vec_sub(t2,t1); + vtmp++; + +#endif + + } + + snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -3, 0, 1); + } + + { + //Interleave + int a; + vector signed int *t = (vector signed int *)temp, + *v = (vector signed int *)b; + + snow_interleave_line_header(&i, width, b, temp); + + for (; (i & 0xE) != 0xE; i-=2){ + b[i+1] = temp[i>>1]; + b[i] = b[i>>1]; + } + for (i-=14; i>=0; i-=16){ + a=i/4; + + v[a+3]=vec_mergel(v[(a>>1)+1],t[(a>>1)+1]); + v[a+2]=vec_mergeh(v[(a>>1)+1],t[(a>>1)+1]); + v[a+1]=vec_mergel(v[a>>1],t[a>>1]); + v[a]=vec_mergeh(v[a>>1],t[a>>1]); + + } + + } +} + +void ff_snow_vertical_compose97i_altivec(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width) +{ + int i, w4 = width/4; + vector signed int *v0, *v1,*v2,*v3,*v4,*v5; + vector signed int t1, t2; + + v0=(vector signed int *)b0; + v1=(vector signed int *)b1; + v2=(vector signed int *)b2; + v3=(vector signed int *)b3; + v4=(vector signed int *)b4; + v5=(vector signed int *)b5; + + for (i=0; i< w4;i++) + { + + #if 0 + b4[i] -= (3*(b3[i] + b5[i])+4)>>3; + b3[i] -= ((b2[i] + b4[i])); + b2[i] += ((b1[i] + b3[i])+4*b2[i]+8)>>4; + b1[i] += (3*(b0[i] + b2[i]))>>1; + #else + t1 = vec_add(v3[i], v5[i]); + t2 = vec_add(t1, vec_add(t1,t1)); + t1 = vec_add(t2, vec_splat_s32(4)); + v4[i] = vec_sub(v4[i], vec_sra(t1,vec_splat_u32(3))); + + v3[i] = vec_sub(v3[i], vec_add(v2[i], v4[i])); + + t1 = vec_add(vec_splat_s32(8), vec_add(v1[i], v3[i])); + t2 = vec_sl(v2[i], vec_splat_u32(2)); + v2[i] = vec_add(v2[i], vec_sra(vec_add(t1,t2),vec_splat_u32(4))); + t1 = vec_add(v0[i], v2[i]); + t2 = vec_add(t1, vec_add(t1,t1)); + v1[i] = vec_add(v1[i], vec_sra(t2,vec_splat_u32(1))); + + #endif + } + + for(i*=4; i < width; i++) + { + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } +} + +#define LOAD_BLOCKS \ + tmp1 = vec_ld(0, &block[3][y*src_stride]);\ + align = vec_lvsl(0, &block[3][y*src_stride]);\ + tmp2 = vec_ld(15, &block[3][y*src_stride]);\ +\ + b3 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, &block[2][y*src_stride]);\ + align = vec_lvsl(0, &block[2][y*src_stride]);\ + tmp2 = vec_ld(15, &block[2][y*src_stride]);\ +\ + b2 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, &block[1][y*src_stride]);\ + align = vec_lvsl(0, &block[1][y*src_stride]);\ + tmp2 = vec_ld(15, &block[1][y*src_stride]);\ +\ + b1 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, &block[0][y*src_stride]);\ + align = vec_lvsl(0, &block[0][y*src_stride]);\ + tmp2 = vec_ld(15, &block[0][y*src_stride]);\ +\ + b0 = vec_perm(tmp1,tmp2,align); + +#define LOAD_OBMCS \ + tmp1 = vec_ld(0, obmc1);\ + align = vec_lvsl(0, obmc1);\ + tmp2 = vec_ld(15, obmc1);\ +\ + ob1 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, obmc2);\ + align = vec_lvsl(0, obmc2);\ + tmp2 = vec_ld(15, obmc2);\ +\ + ob2 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, obmc3);\ + align = vec_lvsl(0, obmc3);\ + tmp2 = vec_ld(15, obmc3);\ +\ + ob3 = vec_perm(tmp1,tmp2,align);\ +\ + tmp1 = vec_ld(0, obmc4);\ + align = vec_lvsl(0, obmc4);\ + tmp2 = vec_ld(15, obmc4);\ +\ + ob4 = vec_perm(tmp1,tmp2,align); + +/* interleave logic + * h1 <- [ a,b,a,b, a,b,a,b, a,b,a,b, a,b,a,b ] + * h2 <- [ c,d,c,d, c,d,c,d, c,d,c,d, c,d,c,d ] + * h <- [ a,b,c,d, a,b,c,d, a,b,c,d, a,b,c,d ] + */ + +#define STEPS_0_1\ + h1 = (vector unsigned short)\ + vec_mergeh(ob1, ob2);\ +\ + h2 = (vector unsigned short)\ + vec_mergeh(ob3, ob4);\ +\ + ih = (vector unsigned char)\ + vec_mergeh(h1,h2);\ +\ + l1 = (vector unsigned short) vec_mergeh(b3, b2);\ +\ + ih1 = (vector unsigned char) vec_mergel(h1, h2);\ +\ + l2 = (vector unsigned short) vec_mergeh(b1, b0);\ +\ + il = (vector unsigned char) vec_mergeh(l1, l2);\ +\ + v[0] = (vector signed int) vec_msum(ih, il, vec_splat_u32(0));\ +\ + il1 = (vector unsigned char) vec_mergel(l1, l2);\ +\ + v[1] = (vector signed int) vec_msum(ih1, il1, vec_splat_u32(0)); + +#define FINAL_STEP_SCALAR\ + for(x=0; x<b_w; x++)\ + if(add){\ + vbuf[x] += dst[x + src_x];\ + vbuf[x] = (vbuf[x] + (1<<(FRAC_BITS-1))) >> FRAC_BITS;\ + if(vbuf[x]&(~255)) vbuf[x]= ~(vbuf[x]>>31);\ + dst8[x + y*src_stride] = vbuf[x];\ + }else{\ + dst[x + src_x] -= vbuf[x];\ + } + +static void inner_add_yblock_bw_8_obmc_16_altivec(uint8_t *obmc, + const int obmc_stride, + uint8_t * * block, int b_w, + int b_h, int src_x, int src_y, + int src_stride, slice_buffer * sb, + int add, uint8_t * dst8) +{ + int y, x; + DWTELEM * dst; + vector unsigned short h1, h2, l1, l2; + vector unsigned char ih, il, ih1, il1, tmp1, tmp2, align; + vector unsigned char b0,b1,b2,b3; + vector unsigned char ob1,ob2,ob3,ob4; + + DECLARE_ALIGNED_16(int, vbuf[16]); + vector signed int *v = (vector signed int *)vbuf, *d; + + for(y=0; y<b_h; y++){ + //FIXME ugly missue of obmc_stride + + uint8_t *obmc1= obmc + y*obmc_stride; + uint8_t *obmc2= obmc1+ (obmc_stride>>1); + uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); + uint8_t *obmc4= obmc3+ (obmc_stride>>1); + + dst = slice_buffer_get_line(sb, src_y + y); + d = (vector signed int *)(dst + src_x); + +//FIXME i could avoid some loads! + + // load blocks + LOAD_BLOCKS + + // load obmcs + LOAD_OBMCS + + // steps 0 1 + STEPS_0_1 + + FINAL_STEP_SCALAR + + } + +} + +#define STEPS_2_3\ + h1 = (vector unsigned short) vec_mergel(ob1, ob2);\ +\ + h2 = (vector unsigned short) vec_mergel(ob3, ob4);\ +\ + ih = (vector unsigned char) vec_mergeh(h1,h2);\ +\ + l1 = (vector unsigned short) vec_mergel(b3, b2);\ +\ + l2 = (vector unsigned short) vec_mergel(b1, b0);\ +\ + ih1 = (vector unsigned char) vec_mergel(h1,h2);\ +\ + il = (vector unsigned char) vec_mergeh(l1,l2);\ +\ + v[2] = (vector signed int) vec_msum(ih, il, vec_splat_u32(0));\ +\ + il1 = (vector unsigned char) vec_mergel(l1,l2);\ +\ + v[3] = (vector signed int) vec_msum(ih1, il1, vec_splat_u32(0)); + + +static void inner_add_yblock_bw_16_obmc_32_altivec(uint8_t *obmc, + const int obmc_stride, + uint8_t * * block, int b_w, + int b_h, int src_x, int src_y, + int src_stride, slice_buffer * sb, + int add, uint8_t * dst8) +{ + int y, x; + DWTELEM * dst; + vector unsigned short h1, h2, l1, l2; + vector unsigned char ih, il, ih1, il1, tmp1, tmp2, align; + vector unsigned char b0,b1,b2,b3; + vector unsigned char ob1,ob2,ob3,ob4; + DECLARE_ALIGNED_16(int, vbuf[b_w]); + vector signed int *v = (vector signed int *)vbuf, *d; + + for(y=0; y<b_h; y++){ + //FIXME ugly missue of obmc_stride + + uint8_t *obmc1= obmc + y*obmc_stride; + uint8_t *obmc2= obmc1+ (obmc_stride>>1); + uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); + uint8_t *obmc4= obmc3+ (obmc_stride>>1); + + dst = slice_buffer_get_line(sb, src_y + y); + d = (vector signed int *)(dst + src_x); + + // load blocks + LOAD_BLOCKS + + // load obmcs + LOAD_OBMCS + + // steps 0 1 2 3 + STEPS_0_1 + + STEPS_2_3 + + FINAL_STEP_SCALAR + + } +} + +#define FINAL_STEP_VEC \ +\ + if(add)\ + {\ + for(x=0; x<b_w/4; x++)\ + {\ + v[x] = vec_add(v[x], d[x]);\ + v[x] = vec_sra(vec_add(v[x],\ + vec_sl( vec_splat_s32(1),\ + vec_splat_u32(7))),\ + vec_splat_u32(8));\ +\ + mask = (vector bool int) vec_sl((vector signed int)\ + vec_cmpeq(v[x],v[x]),vec_splat_u32(8));\ + mask = (vector bool int) vec_and(v[x],vec_nor(mask,mask));\ +\ + mask = (vector bool int)\ + vec_cmpeq((vector signed int)mask,\ + (vector signed int)vec_splat_u32(0));\ +\ + vs = vec_sra(v[x],vec_splat_u32(8));\ + vs = vec_sra(v[x],vec_splat_u32(8));\ + vs = vec_sra(v[x],vec_splat_u32(15));\ +\ + vs = vec_nor(vs,vs);\ +\ + v[x]= vec_sel(v[x],vs,mask);\ + }\ +\ + for(x=0; x<b_w; x++)\ + dst8[x + y*src_stride] = vbuf[x];\ +\ + }\ + else\ + for(x=0; x<b_w/4; x++)\ + d[x] = vec_sub(d[x], v[x]); + +static void inner_add_yblock_a_bw_8_obmc_16_altivec(uint8_t *obmc, + const int obmc_stride, + uint8_t * * block, int b_w, + int b_h, int src_x, int src_y, + int src_stride, slice_buffer * sb, + int add, uint8_t * dst8) +{ + int y, x; + DWTELEM * dst; + vector bool int mask; + vector signed int vs; + vector unsigned short h1, h2, l1, l2; + vector unsigned char ih, il, ih1, il1, tmp1, tmp2, align; + vector unsigned char b0,b1,b2,b3; + vector unsigned char ob1,ob2,ob3,ob4; + + DECLARE_ALIGNED_16(int, vbuf[16]); + vector signed int *v = (vector signed int *)vbuf, *d; + + for(y=0; y<b_h; y++){ + //FIXME ugly missue of obmc_stride + + uint8_t *obmc1= obmc + y*obmc_stride; + uint8_t *obmc2= obmc1+ (obmc_stride>>1); + uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); + uint8_t *obmc4= obmc3+ (obmc_stride>>1); + + dst = slice_buffer_get_line(sb, src_y + y); + d = (vector signed int *)(dst + src_x); + +//FIXME i could avoid some loads! + + // load blocks + LOAD_BLOCKS + + // load obmcs + LOAD_OBMCS + + // steps 0 1 + STEPS_0_1 + + FINAL_STEP_VEC + + } + +} + +static void inner_add_yblock_a_bw_16_obmc_32_altivec(uint8_t *obmc, + const int obmc_stride, + uint8_t * * block, int b_w, + int b_h, int src_x, int src_y, + int src_stride, slice_buffer * sb, + int add, uint8_t * dst8) +{ + int y, x; + DWTELEM * dst; + vector bool int mask; + vector signed int vs; + vector unsigned short h1, h2, l1, l2; + vector unsigned char ih, il, ih1, il1, tmp1, tmp2, align; + vector unsigned char b0,b1,b2,b3; + vector unsigned char ob1,ob2,ob3,ob4; + DECLARE_ALIGNED_16(int, vbuf[b_w]); + vector signed int *v = (vector signed int *)vbuf, *d; + + for(y=0; y<b_h; y++){ + //FIXME ugly missue of obmc_stride + + uint8_t *obmc1= obmc + y*obmc_stride; + uint8_t *obmc2= obmc1+ (obmc_stride>>1); + uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); + uint8_t *obmc4= obmc3+ (obmc_stride>>1); + + dst = slice_buffer_get_line(sb, src_y + y); + d = (vector signed int *)(dst + src_x); + + // load blocks + LOAD_BLOCKS + + // load obmcs + LOAD_OBMCS + + // steps 0 1 2 3 + STEPS_0_1 + + STEPS_2_3 + + FINAL_STEP_VEC + + } +} + + +void ff_snow_inner_add_yblock_altivec(uint8_t *obmc, const int obmc_stride, + uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, + slice_buffer * sb, int add, + uint8_t * dst8) +{ + if (src_x&15) { + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_altivec(obmc, obmc_stride, block, + b_w, b_h, src_x, src_y, + src_stride, sb, add, dst8); + else if (b_w == 8) + inner_add_yblock_bw_8_obmc_16_altivec(obmc, obmc_stride, block, + b_w, b_h, src_x, src_y, + src_stride, sb, add, dst8); + else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, + src_y, src_stride, sb, add, dst8); + } else { + if (b_w == 16) + inner_add_yblock_a_bw_16_obmc_32_altivec(obmc, obmc_stride, block, + b_w, b_h, src_x, src_y, + src_stride, sb, add, dst8); + else if (b_w == 8) + inner_add_yblock_a_bw_8_obmc_16_altivec(obmc, obmc_stride, block, + b_w, b_h, src_x, src_y, + src_stride, sb, add, dst8); + else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x, + src_y, src_stride, sb, add, dst8); + } +} + + +void snow_init_altivec(DSPContext* c, AVCodecContext *avctx) +{ + c->horizontal_compose97i = ff_snow_horizontal_compose97i_altivec; + c->vertical_compose97i = ff_snow_vertical_compose97i_altivec; + c->inner_add_yblock = ff_snow_inner_add_yblock_altivec; +} diff --git a/src/libffmpeg/libavcodec/ppc/types_altivec.h b/src/libffmpeg/libavcodec/ppc/types_altivec.h new file mode 100644 index 000000000..f29026e04 --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/types_altivec.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2006 Guillaume Poirier <gpoirier@mplayerhq.hu> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/*********************************************************************** + * Vector types + **********************************************************************/ +#define vec_u8_t vector unsigned char +#define vec_s8_t vector signed char +#define vec_u16_t vector unsigned short +#define vec_s16_t vector signed short +#define vec_u32_t vector unsigned int +#define vec_s32_t vector signed int + +/*********************************************************************** + * Null vector + **********************************************************************/ +#define LOAD_ZERO const vec_u8_t zerov = vec_splat_u8( 0 ) + +#define zero_u8v (vec_u8_t) zerov +#define zero_s8v (vec_s8_t) zerov +#define zero_u16v (vec_u16_t) zerov +#define zero_s16v (vec_s16_t) zerov +#define zero_u32v (vec_u32_t) zerov +#define zero_s32v (vec_s32_t) zerov diff --git a/src/libffmpeg/libavcodec/ppc/vc1dsp_altivec.c b/src/libffmpeg/libavcodec/ppc/vc1dsp_altivec.c new file mode 100644 index 000000000..114c9d41f --- /dev/null +++ b/src/libffmpeg/libavcodec/ppc/vc1dsp_altivec.c @@ -0,0 +1,338 @@ +/* + * VC-1 and WMV3 decoder - DSP functions AltiVec-optimized + * Copyright (c) 2006 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "../dsputil.h" + +#include "gcc_fixes.h" + +#include "dsputil_altivec.h" + +// main steps of 8x8 transform +#define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \ +do { \ + t0 = vec_sl(vec_add(s0, s4), vec_2); \ + t0 = vec_add(vec_sl(t0, vec_1), t0); \ + t0 = vec_add(t0, vec_rnd); \ + t1 = vec_sl(vec_sub(s0, s4), vec_2); \ + t1 = vec_add(vec_sl(t1, vec_1), t1); \ + t1 = vec_add(t1, vec_rnd); \ + t2 = vec_add(vec_sl(s6, vec_2), vec_sl(s6, vec_1)); \ + t2 = vec_add(t2, vec_sl(s2, vec_4)); \ + t3 = vec_add(vec_sl(s2, vec_2), vec_sl(s2, vec_1)); \ + t3 = vec_sub(t3, vec_sl(s6, vec_4)); \ + t4 = vec_add(t0, t2); \ + t5 = vec_add(t1, t3); \ + t6 = vec_sub(t1, t3); \ + t7 = vec_sub(t0, t2); \ +\ + t0 = vec_sl(vec_add(s1, s3), vec_4); \ + t0 = vec_add(t0, vec_sl(s5, vec_3)); \ + t0 = vec_add(t0, vec_sl(s7, vec_2)); \ + t0 = vec_add(t0, vec_sub(s5, s3)); \ +\ + t1 = vec_sl(vec_sub(s1, s5), vec_4); \ + t1 = vec_sub(t1, vec_sl(s7, vec_3)); \ + t1 = vec_sub(t1, vec_sl(s3, vec_2)); \ + t1 = vec_sub(t1, vec_add(s1, s7)); \ +\ + t2 = vec_sl(vec_sub(s7, s3), vec_4); \ + t2 = vec_add(t2, vec_sl(s1, vec_3)); \ + t2 = vec_add(t2, vec_sl(s5, vec_2)); \ + t2 = vec_add(t2, vec_sub(s1, s7)); \ +\ + t3 = vec_sl(vec_sub(s5, s7), vec_4); \ + t3 = vec_sub(t3, vec_sl(s3, vec_3)); \ + t3 = vec_add(t3, vec_sl(s1, vec_2)); \ + t3 = vec_sub(t3, vec_add(s3, s5)); \ +\ + s0 = vec_add(t4, t0); \ + s1 = vec_add(t5, t1); \ + s2 = vec_add(t6, t2); \ + s3 = vec_add(t7, t3); \ + s4 = vec_sub(t7, t3); \ + s5 = vec_sub(t6, t2); \ + s6 = vec_sub(t5, t1); \ + s7 = vec_sub(t4, t0); \ +}while(0) + +#define SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7) \ +do { \ + s0 = vec_sra(s0, vec_3); \ + s1 = vec_sra(s1, vec_3); \ + s2 = vec_sra(s2, vec_3); \ + s3 = vec_sra(s3, vec_3); \ + s4 = vec_sra(s4, vec_3); \ + s5 = vec_sra(s5, vec_3); \ + s6 = vec_sra(s6, vec_3); \ + s7 = vec_sra(s7, vec_3); \ +}while(0) + +#define SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7) \ +do { \ + s0 = vec_sra(s0, vec_7); \ + s1 = vec_sra(s1, vec_7); \ + s2 = vec_sra(s2, vec_7); \ + s3 = vec_sra(s3, vec_7); \ + s4 = vec_sra(vec_add(s4, vec_1s), vec_7); \ + s5 = vec_sra(vec_add(s5, vec_1s), vec_7); \ + s6 = vec_sra(vec_add(s6, vec_1s), vec_7); \ + s7 = vec_sra(vec_add(s7, vec_1s), vec_7); \ +}while(0) + +/* main steps of 4x4 transform */ +#define STEP4(s0, s1, s2, s3, vec_rnd) \ +do { \ + t1 = vec_add(vec_sl(s0, vec_4), s0); \ + t1 = vec_add(t1, vec_rnd); \ + t2 = vec_add(vec_sl(s2, vec_4), s2); \ + t0 = vec_add(t1, t2); \ + t1 = vec_sub(t1, t2); \ + t3 = vec_sl(vec_sub(s3, s1), vec_1); \ + t3 = vec_add(t3, vec_sl(t3, vec_2)); \ + t2 = vec_add(t3, vec_sl(s1, vec_5)); \ + t3 = vec_add(t3, vec_sl(s3, vec_3)); \ + t3 = vec_add(t3, vec_sl(s3, vec_2)); \ + s0 = vec_add(t0, t2); \ + s1 = vec_sub(t1, t3); \ + s2 = vec_add(t1, t3); \ + s3 = vec_sub(t0, t2); \ +}while (0) + +#define SHIFT_HOR4(s0, s1, s2, s3) \ + s0 = vec_sra(s0, vec_3); \ + s1 = vec_sra(s1, vec_3); \ + s2 = vec_sra(s2, vec_3); \ + s3 = vec_sra(s3, vec_3); + +#define SHIFT_VERT4(s0, s1, s2, s3) \ + s0 = vec_sra(s0, vec_7); \ + s1 = vec_sra(s1, vec_7); \ + s2 = vec_sra(s2, vec_7); \ + s3 = vec_sra(s3, vec_7); + +/** Do inverse transform on 8x8 block +*/ +static void vc1_inv_trans_8x8_altivec(DCTELEM block[64]) +{ + vector signed short src0, src1, src2, src3, src4, src5, src6, src7; + vector signed int s0, s1, s2, s3, s4, s5, s6, s7; + vector signed int s8, s9, sA, sB, sC, sD, sE, sF; + vector signed int t0, t1, t2, t3, t4, t5, t6, t7; + const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4)); + const vector unsigned int vec_7 = vec_splat_u32(7); + const vector unsigned int vec_5 = vec_splat_u32(5); + const vector unsigned int vec_4 = vec_splat_u32(4); + const vector signed int vec_4s = vec_splat_s32(4); + const vector unsigned int vec_3 = vec_splat_u32(3); + const vector unsigned int vec_2 = vec_splat_u32(2); + const vector signed int vec_1s = vec_splat_s32(1); + const vector unsigned int vec_1 = vec_splat_u32(1); + + + src0 = vec_ld( 0, block); + src1 = vec_ld( 16, block); + src2 = vec_ld( 32, block); + src3 = vec_ld( 48, block); + src4 = vec_ld( 64, block); + src5 = vec_ld( 80, block); + src6 = vec_ld( 96, block); + src7 = vec_ld(112, block); + + TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); + s0 = vec_unpackl(src0); + s1 = vec_unpackl(src1); + s2 = vec_unpackl(src2); + s3 = vec_unpackl(src3); + s4 = vec_unpackl(src4); + s5 = vec_unpackl(src5); + s6 = vec_unpackl(src6); + s7 = vec_unpackl(src7); + s8 = vec_unpackh(src0); + s9 = vec_unpackh(src1); + sA = vec_unpackh(src2); + sB = vec_unpackh(src3); + sC = vec_unpackh(src4); + sD = vec_unpackh(src5); + sE = vec_unpackh(src6); + sF = vec_unpackh(src7); + STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s); + SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7); + STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s); + SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF); + src0 = vec_pack(s8, s0); + src1 = vec_pack(s9, s1); + src2 = vec_pack(sA, s2); + src3 = vec_pack(sB, s3); + src4 = vec_pack(sC, s4); + src5 = vec_pack(sD, s5); + src6 = vec_pack(sE, s6); + src7 = vec_pack(sF, s7); + TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); + + s0 = vec_unpackl(src0); + s1 = vec_unpackl(src1); + s2 = vec_unpackl(src2); + s3 = vec_unpackl(src3); + s4 = vec_unpackl(src4); + s5 = vec_unpackl(src5); + s6 = vec_unpackl(src6); + s7 = vec_unpackl(src7); + s8 = vec_unpackh(src0); + s9 = vec_unpackh(src1); + sA = vec_unpackh(src2); + sB = vec_unpackh(src3); + sC = vec_unpackh(src4); + sD = vec_unpackh(src5); + sE = vec_unpackh(src6); + sF = vec_unpackh(src7); + STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_64); + SHIFT_VERT8(s0, s1, s2, s3, s4, s5, s6, s7); + STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_64); + SHIFT_VERT8(s8, s9, sA, sB, sC, sD, sE, sF); + src0 = vec_pack(s8, s0); + src1 = vec_pack(s9, s1); + src2 = vec_pack(sA, s2); + src3 = vec_pack(sB, s3); + src4 = vec_pack(sC, s4); + src5 = vec_pack(sD, s5); + src6 = vec_pack(sE, s6); + src7 = vec_pack(sF, s7); + + vec_st(src0, 0, block); + vec_st(src1, 16, block); + vec_st(src2, 32, block); + vec_st(src3, 48, block); + vec_st(src4, 64, block); + vec_st(src5, 80, block); + vec_st(src6, 96, block); + vec_st(src7,112, block); +} + +/** Do inverse transform on 8x4 part of block +*/ +static void vc1_inv_trans_8x4_altivec(DCTELEM block[64], int n) +{ + vector signed short src0, src1, src2, src3, src4, src5, src6, src7; + vector signed int s0, s1, s2, s3, s4, s5, s6, s7; + vector signed int s8, s9, sA, sB, sC, sD, sE, sF; + vector signed int t0, t1, t2, t3, t4, t5, t6, t7; + const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4)); + const vector unsigned int vec_7 = vec_splat_u32(7); + const vector unsigned int vec_5 = vec_splat_u32(5); + const vector unsigned int vec_4 = vec_splat_u32(4); + const vector signed int vec_4s = vec_splat_s32(4); + const vector unsigned int vec_3 = vec_splat_u32(3); + const vector unsigned int vec_2 = vec_splat_u32(2); + const vector unsigned int vec_1 = vec_splat_u32(1); + + src0 = vec_ld( 0, block); + src1 = vec_ld( 16, block); + src2 = vec_ld( 32, block); + src3 = vec_ld( 48, block); + src4 = vec_ld( 64, block); + src5 = vec_ld( 80, block); + src6 = vec_ld( 96, block); + src7 = vec_ld(112, block); + + TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); + s0 = vec_unpackl(src0); + s1 = vec_unpackl(src1); + s2 = vec_unpackl(src2); + s3 = vec_unpackl(src3); + s4 = vec_unpackl(src4); + s5 = vec_unpackl(src5); + s6 = vec_unpackl(src6); + s7 = vec_unpackl(src7); + s8 = vec_unpackh(src0); + s9 = vec_unpackh(src1); + sA = vec_unpackh(src2); + sB = vec_unpackh(src3); + sC = vec_unpackh(src4); + sD = vec_unpackh(src5); + sE = vec_unpackh(src6); + sF = vec_unpackh(src7); + STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_4s); + SHIFT_HOR8(s0, s1, s2, s3, s4, s5, s6, s7); + STEP8(s8, s9, sA, sB, sC, sD, sE, sF, vec_4s); + SHIFT_HOR8(s8, s9, sA, sB, sC, sD, sE, sF); + src0 = vec_pack(s8, s0); + src1 = vec_pack(s9, s1); + src2 = vec_pack(sA, s2); + src3 = vec_pack(sB, s3); + src4 = vec_pack(sC, s4); + src5 = vec_pack(sD, s5); + src6 = vec_pack(sE, s6); + src7 = vec_pack(sF, s7); + TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); + + if(!n){ // upper half of block + s0 = vec_unpackh(src0); + s1 = vec_unpackh(src1); + s2 = vec_unpackh(src2); + s3 = vec_unpackh(src3); + s8 = vec_unpackl(src0); + s9 = vec_unpackl(src1); + sA = vec_unpackl(src2); + sB = vec_unpackl(src3); + STEP4(s0, s1, s2, s3, vec_64); + SHIFT_VERT4(s0, s1, s2, s3); + STEP4(s8, s9, sA, sB, vec_64); + SHIFT_VERT4(s8, s9, sA, sB); + src0 = vec_pack(s0, s8); + src1 = vec_pack(s1, s9); + src2 = vec_pack(s2, sA); + src3 = vec_pack(s3, sB); + + vec_st(src0, 0, block); + vec_st(src1, 16, block); + vec_st(src2, 32, block); + vec_st(src3, 48, block); + } else { //lower half of block + s0 = vec_unpackh(src4); + s1 = vec_unpackh(src5); + s2 = vec_unpackh(src6); + s3 = vec_unpackh(src7); + s8 = vec_unpackl(src4); + s9 = vec_unpackl(src5); + sA = vec_unpackl(src6); + sB = vec_unpackl(src7); + STEP4(s0, s1, s2, s3, vec_64); + SHIFT_VERT4(s0, s1, s2, s3); + STEP4(s8, s9, sA, sB, vec_64); + SHIFT_VERT4(s8, s9, sA, sB); + src4 = vec_pack(s0, s8); + src5 = vec_pack(s1, s9); + src6 = vec_pack(s2, sA); + src7 = vec_pack(s3, sB); + + vec_st(src4, 64, block); + vec_st(src5, 80, block); + vec_st(src6, 96, block); + vec_st(src7,112, block); + } +} + + +void vc1dsp_init_altivec(DSPContext* dsp, AVCodecContext *avctx) { + dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_altivec; + dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec; +} diff --git a/src/libffmpeg/libavcodec/ratecontrol.h b/src/libffmpeg/libavcodec/ratecontrol.h new file mode 100644 index 000000000..c428923a5 --- /dev/null +++ b/src/libffmpeg/libavcodec/ratecontrol.h @@ -0,0 +1,103 @@ +/* + * Ratecontrol + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_RATECONTROL_H +#define AVCODEC_RATECONTROL_H + +/** + * @file ratecontrol.h + * ratecontrol header. + */ + +#include "eval.h" + +typedef struct Predictor{ + double coeff; + double count; + double decay; +} Predictor; + +typedef struct RateControlEntry{ + int pict_type; + float qscale; + int mv_bits; + int i_tex_bits; + int p_tex_bits; + int misc_bits; + int header_bits; + uint64_t expected_bits; + int new_pict_type; + float new_qscale; + int mc_mb_var_sum; + int mb_var_sum; + int i_count; + int skip_count; + int f_code; + int b_code; +}RateControlEntry; + +/** + * rate control context. + */ +typedef struct RateControlContext{ + FILE *stats_file; + int num_entries; ///< number of RateControlEntries + RateControlEntry *entry; + double buffer_index; ///< amount of bits in the video/audio buffer + Predictor pred[5]; + double short_term_qsum; ///< sum of recent qscales + double short_term_qcount; ///< count of recent qscales + double pass1_rc_eq_output_sum;///< sum of the output of the rc equation, this is used for normalization + double pass1_wanted_bits; ///< bits which should have been outputed by the pass1 code (including complexity init) + double last_qscale; + double last_qscale_for[5]; ///< last qscale for a specific pict type, used for max_diff & ipb factor stuff + int last_mc_mb_var_sum; + int last_mb_var_sum; + uint64_t i_cplx_sum[5]; + uint64_t p_cplx_sum[5]; + uint64_t mv_bits_sum[5]; + uint64_t qscale_sum[5]; + int frame_count[5]; + int last_non_b_pict_type; + + void *non_lavc_opaque; ///< context for non lavc rc code (for example xvid) + float dry_run_qscale; ///< for xvid rc + int last_picture_number; ///< for xvid rc + AVEvalExpr * rc_eq_eval; +}RateControlContext; + +struct MpegEncContext; + +/* rate control */ +int ff_rate_control_init(struct MpegEncContext *s); +float ff_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); +void ff_write_pass1_stats(struct MpegEncContext *s); +void ff_rate_control_uninit(struct MpegEncContext *s); +int ff_vbv_update(struct MpegEncContext *s, int frame_size); +void ff_get_2pass_fcode(struct MpegEncContext *s); + +int ff_xvid_rate_control_init(struct MpegEncContext *s); +void ff_xvid_rate_control_uninit(struct MpegEncContext *s); +float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); + +#endif /* AVCODEC_RATECONTROL_H */ + diff --git a/src/libspeex/.cvsignore b/src/libffmpeg/libavcodec/sparc/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libspeex/.cvsignore +++ b/src/libffmpeg/libavcodec/sparc/.hgignore diff --git a/src/libffmpeg/libavcodec/vorbis_data.c b/src/libffmpeg/libavcodec/vorbis_data.c new file mode 100644 index 000000000..5dc9c5f00 --- /dev/null +++ b/src/libffmpeg/libavcodec/vorbis_data.c @@ -0,0 +1,2155 @@ +/* + * copyright (c) 2005 Denes Balatoni ( dbalatoni programozo hu ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "vorbis.h" + +static const float vwin64[32] = { + 0.0009460463F, 0.0085006468F, 0.0235352254F, 0.0458950567F, + 0.0753351908F, 0.1115073077F, 0.1539457973F, 0.2020557475F, + 0.2551056759F, 0.3122276645F, 0.3724270287F, 0.4346027792F, + 0.4975789974F, 0.5601459521F, 0.6211085051F, 0.6793382689F, + 0.7338252629F, 0.7837245849F, 0.8283939355F, 0.8674186656F, + 0.9006222429F, 0.9280614787F, 0.9500073081F, 0.9669131782F, + 0.9793740220F, 0.9880792941F, 0.9937636139F, 0.9971582668F, + 0.9989462667F, 0.9997230082F, 0.9999638688F, 0.9999995525F, +}; + +static const float vwin128[64] = { + 0.0002365472F, 0.0021280687F, 0.0059065254F, 0.0115626550F, + 0.0190823442F, 0.0284463735F, 0.0396300935F, 0.0526030430F, + 0.0673285281F, 0.0837631763F, 0.1018564887F, 0.1215504095F, + 0.1427789367F, 0.1654677960F, 0.1895342001F, 0.2148867160F, + 0.2414252576F, 0.2690412240F, 0.2976177952F, 0.3270303960F, + 0.3571473350F, 0.3878306189F, 0.4189369387F, 0.4503188188F, + 0.4818259135F, 0.5133064334F, 0.5446086751F, 0.5755826278F, + 0.6060816248F, 0.6359640047F, 0.6650947483F, 0.6933470543F, + 0.7206038179F, 0.7467589810F, 0.7717187213F, 0.7954024542F, + 0.8177436264F, 0.8386902831F, 0.8582053981F, 0.8762669622F, + 0.8928678298F, 0.9080153310F, 0.9217306608F, 0.9340480615F, + 0.9450138200F, 0.9546851041F, 0.9631286621F, 0.9704194171F, + 0.9766389810F, 0.9818741197F, 0.9862151938F, 0.9897546035F, + 0.9925852598F, 0.9947991032F, 0.9964856900F, 0.9977308602F, + 0.9986155015F, 0.9992144193F, 0.9995953200F, 0.9998179155F, + 0.9999331503F, 0.9999825563F, 0.9999977357F, 0.9999999720F, +}; + +static const float vwin256[128] = { + 0.0000591390F, 0.0005321979F, 0.0014780301F, 0.0028960636F, + 0.0047854363F, 0.0071449926F, 0.0099732775F, 0.0132685298F, + 0.0170286741F, 0.0212513119F, 0.0259337111F, 0.0310727950F, + 0.0366651302F, 0.0427069140F, 0.0491939614F, 0.0561216907F, + 0.0634851102F, 0.0712788035F, 0.0794969160F, 0.0881331402F, + 0.0971807028F, 0.1066323515F, 0.1164803426F, 0.1267164297F, + 0.1373318534F, 0.1483173323F, 0.1596630553F, 0.1713586755F, + 0.1833933062F, 0.1957555184F, 0.2084333404F, 0.2214142599F, + 0.2346852280F, 0.2482326664F, 0.2620424757F, 0.2761000481F, + 0.2903902813F, 0.3048975959F, 0.3196059553F, 0.3344988887F, + 0.3495595160F, 0.3647705766F, 0.3801144597F, 0.3955732382F, + 0.4111287047F, 0.4267624093F, 0.4424557009F, 0.4581897696F, + 0.4739456913F, 0.4897044744F, 0.5054471075F, 0.5211546088F, + 0.5368080763F, 0.5523887395F, 0.5678780103F, 0.5832575361F, + 0.5985092508F, 0.6136154277F, 0.6285587300F, 0.6433222619F, + 0.6578896175F, 0.6722449294F, 0.6863729144F, 0.7002589187F, + 0.7138889597F, 0.7272497662F, 0.7403288154F, 0.7531143679F, + 0.7655954985F, 0.7777621249F, 0.7896050322F, 0.8011158947F, + 0.8122872932F, 0.8231127294F, 0.8335866365F, 0.8437043850F, + 0.8534622861F, 0.8628575905F, 0.8718884835F, 0.8805540765F, + 0.8888543947F, 0.8967903616F, 0.9043637797F, 0.9115773078F, + 0.9184344360F, 0.9249394562F, 0.9310974312F, 0.9369141608F, + 0.9423961446F, 0.9475505439F, 0.9523851406F, 0.9569082947F, + 0.9611289005F, 0.9650563408F, 0.9687004405F, 0.9720714191F, + 0.9751798427F, 0.9780365753F, 0.9806527301F, 0.9830396204F, + 0.9852087111F, 0.9871715701F, 0.9889398207F, 0.9905250941F, + 0.9919389832F, 0.9931929973F, 0.9942985174F, 0.9952667537F, + 0.9961087037F, 0.9968351119F, 0.9974564312F, 0.9979827858F, + 0.9984239359F, 0.9987892441F, 0.9990876435F, 0.9993276081F, + 0.9995171241F, 0.9996636648F, 0.9997741654F, 0.9998550016F, + 0.9999119692F, 0.9999502656F, 0.9999744742F, 0.9999885497F, + 0.9999958064F, 0.9999989077F, 0.9999998584F, 0.9999999983F, +}; + +static const float vwin512[256] = { + 0.0000147849F, 0.0001330607F, 0.0003695946F, 0.0007243509F, + 0.0011972759F, 0.0017882983F, 0.0024973285F, 0.0033242588F, + 0.0042689632F, 0.0053312973F, 0.0065110982F, 0.0078081841F, + 0.0092223540F, 0.0107533880F, 0.0124010466F, 0.0141650703F, + 0.0160451800F, 0.0180410758F, 0.0201524373F, 0.0223789233F, + 0.0247201710F, 0.0271757958F, 0.0297453914F, 0.0324285286F, + 0.0352247556F, 0.0381335972F, 0.0411545545F, 0.0442871045F, + 0.0475306997F, 0.0508847676F, 0.0543487103F, 0.0579219038F, + 0.0616036982F, 0.0653934164F, 0.0692903546F, 0.0732937809F, + 0.0774029356F, 0.0816170305F, 0.0859352485F, 0.0903567428F, + 0.0948806375F, 0.0995060259F, 0.1042319712F, 0.1090575056F, + 0.1139816300F, 0.1190033137F, 0.1241214941F, 0.1293350764F, + 0.1346429333F, 0.1400439046F, 0.1455367974F, 0.1511203852F, + 0.1567934083F, 0.1625545735F, 0.1684025537F, 0.1743359881F, + 0.1803534820F, 0.1864536069F, 0.1926349000F, 0.1988958650F, + 0.2052349715F, 0.2116506555F, 0.2181413191F, 0.2247053313F, + 0.2313410275F, 0.2380467105F, 0.2448206500F, 0.2516610835F, + 0.2585662164F, 0.2655342226F, 0.2725632448F, 0.2796513950F, + 0.2867967551F, 0.2939973773F, 0.3012512852F, 0.3085564739F, + 0.3159109111F, 0.3233125375F, 0.3307592680F, 0.3382489922F, + 0.3457795756F, 0.3533488602F, 0.3609546657F, 0.3685947904F, + 0.3762670121F, 0.3839690896F, 0.3916987634F, 0.3994537572F, + 0.4072317788F, 0.4150305215F, 0.4228476653F, 0.4306808783F, + 0.4385278181F, 0.4463861329F, 0.4542534630F, 0.4621274424F, + 0.4700057001F, 0.4778858615F, 0.4857655502F, 0.4936423891F, + 0.5015140023F, 0.5093780165F, 0.5172320626F, 0.5250737772F, + 0.5329008043F, 0.5407107971F, 0.5485014192F, 0.5562703465F, + 0.5640152688F, 0.5717338914F, 0.5794239366F, 0.5870831457F, + 0.5947092801F, 0.6023001235F, 0.6098534829F, 0.6173671907F, + 0.6248391059F, 0.6322671161F, 0.6396491384F, 0.6469831217F, + 0.6542670475F, 0.6614989319F, 0.6686768267F, 0.6757988210F, + 0.6828630426F, 0.6898676592F, 0.6968108799F, 0.7036909564F, + 0.7105061843F, 0.7172549043F, 0.7239355032F, 0.7305464154F, + 0.7370861235F, 0.7435531598F, 0.7499461068F, 0.7562635986F, + 0.7625043214F, 0.7686670148F, 0.7747504721F, 0.7807535410F, + 0.7866751247F, 0.7925141825F, 0.7982697296F, 0.8039408387F, + 0.8095266395F, 0.8150263196F, 0.8204391248F, 0.8257643590F, + 0.8310013848F, 0.8361496236F, 0.8412085555F, 0.8461777194F, + 0.8510567129F, 0.8558451924F, 0.8605428730F, 0.8651495278F, + 0.8696649882F, 0.8740891432F, 0.8784219392F, 0.8826633797F, + 0.8868135244F, 0.8908724888F, 0.8948404441F, 0.8987176157F, + 0.9025042831F, 0.9062007791F, 0.9098074886F, 0.9133248482F, + 0.9167533451F, 0.9200935163F, 0.9233459472F, 0.9265112712F, + 0.9295901680F, 0.9325833632F, 0.9354916263F, 0.9383157705F, + 0.9410566504F, 0.9437151618F, 0.9462922398F, 0.9487888576F, + 0.9512060252F, 0.9535447882F, 0.9558062262F, 0.9579914516F, + 0.9601016078F, 0.9621378683F, 0.9641014348F, 0.9659935361F, + 0.9678154261F, 0.9695683830F, 0.9712537071F, 0.9728727198F, + 0.9744267618F, 0.9759171916F, 0.9773453842F, 0.9787127293F, + 0.9800206298F, 0.9812705006F, 0.9824637665F, 0.9836018613F, + 0.9846862258F, 0.9857183066F, 0.9866995544F, 0.9876314227F, + 0.9885153662F, 0.9893528393F, 0.9901452948F, 0.9908941823F, + 0.9916009470F, 0.9922670279F, 0.9928938570F, 0.9934828574F, + 0.9940354423F, 0.9945530133F, 0.9950369595F, 0.9954886562F, + 0.9959094633F, 0.9963007242F, 0.9966637649F, 0.9969998925F, + 0.9973103939F, 0.9975965351F, 0.9978595598F, 0.9981006885F, + 0.9983211172F, 0.9985220166F, 0.9987045311F, 0.9988697776F, + 0.9990188449F, 0.9991527924F, 0.9992726499F, 0.9993794157F, + 0.9994740570F, 0.9995575079F, 0.9996306699F, 0.9996944099F, + 0.9997495605F, 0.9997969190F, 0.9998372465F, 0.9998712678F, + 0.9998996704F, 0.9999231041F, 0.9999421807F, 0.9999574732F, + 0.9999695157F, 0.9999788026F, 0.9999857885F, 0.9999908879F, + 0.9999944746F, 0.9999968817F, 0.9999984010F, 0.9999992833F, + 0.9999997377F, 0.9999999317F, 0.9999999911F, 0.9999999999F, +}; + +static const float vwin1024[512] = { + 0.0000036962F, 0.0000332659F, 0.0000924041F, 0.0001811086F, + 0.0002993761F, 0.0004472021F, 0.0006245811F, 0.0008315063F, + 0.0010679699F, 0.0013339631F, 0.0016294757F, 0.0019544965F, + 0.0023090133F, 0.0026930125F, 0.0031064797F, 0.0035493989F, + 0.0040217533F, 0.0045235250F, 0.0050546946F, 0.0056152418F, + 0.0062051451F, 0.0068243817F, 0.0074729278F, 0.0081507582F, + 0.0088578466F, 0.0095941655F, 0.0103596863F, 0.0111543789F, + 0.0119782122F, 0.0128311538F, 0.0137131701F, 0.0146242260F, + 0.0155642855F, 0.0165333111F, 0.0175312640F, 0.0185581042F, + 0.0196137903F, 0.0206982797F, 0.0218115284F, 0.0229534910F, + 0.0241241208F, 0.0253233698F, 0.0265511886F, 0.0278075263F, + 0.0290923308F, 0.0304055484F, 0.0317471241F, 0.0331170013F, + 0.0345151222F, 0.0359414274F, 0.0373958560F, 0.0388783456F, + 0.0403888325F, 0.0419272511F, 0.0434935347F, 0.0450876148F, + 0.0467094213F, 0.0483588828F, 0.0500359261F, 0.0517404765F, + 0.0534724575F, 0.0552317913F, 0.0570183983F, 0.0588321971F, + 0.0606731048F, 0.0625410369F, 0.0644359070F, 0.0663576272F, + 0.0683061077F, 0.0702812571F, 0.0722829821F, 0.0743111878F, + 0.0763657775F, 0.0784466526F, 0.0805537129F, 0.0826868561F, + 0.0848459782F, 0.0870309736F, 0.0892417345F, 0.0914781514F, + 0.0937401128F, 0.0960275056F, 0.0983402145F, 0.1006781223F, + 0.1030411101F, 0.1054290568F, 0.1078418397F, 0.1102793336F, + 0.1127414119F, 0.1152279457F, 0.1177388042F, 0.1202738544F, + 0.1228329618F, 0.1254159892F, 0.1280227980F, 0.1306532471F, + 0.1333071937F, 0.1359844927F, 0.1386849970F, 0.1414085575F, + 0.1441550230F, 0.1469242403F, 0.1497160539F, 0.1525303063F, + 0.1553668381F, 0.1582254875F, 0.1611060909F, 0.1640084822F, + 0.1669324936F, 0.1698779549F, 0.1728446939F, 0.1758325362F, + 0.1788413055F, 0.1818708232F, 0.1849209084F, 0.1879913785F, + 0.1910820485F, 0.1941927312F, 0.1973232376F, 0.2004733764F, + 0.2036429541F, 0.2068317752F, 0.2100396421F, 0.2132663552F, + 0.2165117125F, 0.2197755102F, 0.2230575422F, 0.2263576007F, + 0.2296754753F, 0.2330109540F, 0.2363638225F, 0.2397338646F, + 0.2431208619F, 0.2465245941F, 0.2499448389F, 0.2533813719F, + 0.2568339669F, 0.2603023956F, 0.2637864277F, 0.2672858312F, + 0.2708003718F, 0.2743298135F, 0.2778739186F, 0.2814324472F, + 0.2850051576F, 0.2885918065F, 0.2921921485F, 0.2958059366F, + 0.2994329219F, 0.3030728538F, 0.3067254799F, 0.3103905462F, + 0.3140677969F, 0.3177569747F, 0.3214578205F, 0.3251700736F, + 0.3288934718F, 0.3326277513F, 0.3363726468F, 0.3401278914F, + 0.3438932168F, 0.3476683533F, 0.3514530297F, 0.3552469734F, + 0.3590499106F, 0.3628615659F, 0.3666816630F, 0.3705099239F, + 0.3743460698F, 0.3781898204F, 0.3820408945F, 0.3858990095F, + 0.3897638820F, 0.3936352274F, 0.3975127601F, 0.4013961936F, + 0.4052852405F, 0.4091796123F, 0.4130790198F, 0.4169831732F, + 0.4208917815F, 0.4248045534F, 0.4287211965F, 0.4326414181F, + 0.4365649248F, 0.4404914225F, 0.4444206167F, 0.4483522125F, + 0.4522859146F, 0.4562214270F, 0.4601584538F, 0.4640966984F, + 0.4680358644F, 0.4719756548F, 0.4759157726F, 0.4798559209F, + 0.4837958024F, 0.4877351199F, 0.4916735765F, 0.4956108751F, + 0.4995467188F, 0.5034808109F, 0.5074128550F, 0.5113425550F, + 0.5152696149F, 0.5191937395F, 0.5231146336F, 0.5270320028F, + 0.5309455530F, 0.5348549910F, 0.5387600239F, 0.5426603597F, + 0.5465557070F, 0.5504457754F, 0.5543302752F, 0.5582089175F, + 0.5620814145F, 0.5659474793F, 0.5698068262F, 0.5736591704F, + 0.5775042283F, 0.5813417176F, 0.5851713571F, 0.5889928670F, + 0.5928059689F, 0.5966103856F, 0.6004058415F, 0.6041920626F, + 0.6079687761F, 0.6117357113F, 0.6154925986F, 0.6192391705F, + 0.6229751612F, 0.6267003064F, 0.6304143441F, 0.6341170137F, + 0.6378080569F, 0.6414872173F, 0.6451542405F, 0.6488088741F, + 0.6524508681F, 0.6560799742F, 0.6596959469F, 0.6632985424F, + 0.6668875197F, 0.6704626398F, 0.6740236662F, 0.6775703649F, + 0.6811025043F, 0.6846198554F, 0.6881221916F, 0.6916092892F, + 0.6950809269F, 0.6985368861F, 0.7019769510F, 0.7054009085F, + 0.7088085484F, 0.7121996632F, 0.7155740484F, 0.7189315023F, + 0.7222718263F, 0.7255948245F, 0.7289003043F, 0.7321880760F, + 0.7354579530F, 0.7387097518F, 0.7419432921F, 0.7451583966F, + 0.7483548915F, 0.7515326059F, 0.7546913723F, 0.7578310265F, + 0.7609514077F, 0.7640523581F, 0.7671337237F, 0.7701953535F, + 0.7732371001F, 0.7762588195F, 0.7792603711F, 0.7822416178F, + 0.7852024259F, 0.7881426654F, 0.7910622097F, 0.7939609356F, + 0.7968387237F, 0.7996954579F, 0.8025310261F, 0.8053453193F, + 0.8081382324F, 0.8109096638F, 0.8136595156F, 0.8163876936F, + 0.8190941071F, 0.8217786690F, 0.8244412960F, 0.8270819086F, + 0.8297004305F, 0.8322967896F, 0.8348709171F, 0.8374227481F, + 0.8399522213F, 0.8424592789F, 0.8449438672F, 0.8474059356F, + 0.8498454378F, 0.8522623306F, 0.8546565748F, 0.8570281348F, + 0.8593769787F, 0.8617030779F, 0.8640064080F, 0.8662869477F, + 0.8685446796F, 0.8707795899F, 0.8729916682F, 0.8751809079F, + 0.8773473059F, 0.8794908626F, 0.8816115819F, 0.8837094713F, + 0.8857845418F, 0.8878368079F, 0.8898662874F, 0.8918730019F, + 0.8938569760F, 0.8958182380F, 0.8977568194F, 0.8996727552F, + 0.9015660837F, 0.9034368465F, 0.9052850885F, 0.9071108577F, + 0.9089142057F, 0.9106951869F, 0.9124538591F, 0.9141902832F, + 0.9159045233F, 0.9175966464F, 0.9192667228F, 0.9209148257F, + 0.9225410313F, 0.9241454187F, 0.9257280701F, 0.9272890704F, + 0.9288285075F, 0.9303464720F, 0.9318430576F, 0.9333183603F, + 0.9347724792F, 0.9362055158F, 0.9376175745F, 0.9390087622F, + 0.9403791881F, 0.9417289644F, 0.9430582055F, 0.9443670283F, + 0.9456555521F, 0.9469238986F, 0.9481721917F, 0.9494005577F, + 0.9506091252F, 0.9517980248F, 0.9529673894F, 0.9541173540F, + 0.9552480557F, 0.9563596334F, 0.9574522282F, 0.9585259830F, + 0.9595810428F, 0.9606175542F, 0.9616356656F, 0.9626355274F, + 0.9636172915F, 0.9645811114F, 0.9655271425F, 0.9664555414F, + 0.9673664664F, 0.9682600774F, 0.9691365355F, 0.9699960034F, + 0.9708386448F, 0.9716646250F, 0.9724741103F, 0.9732672685F, + 0.9740442683F, 0.9748052795F, 0.9755504729F, 0.9762800205F, + 0.9769940950F, 0.9776928703F, 0.9783765210F, 0.9790452223F, + 0.9796991504F, 0.9803384823F, 0.9809633954F, 0.9815740679F, + 0.9821706784F, 0.9827534063F, 0.9833224312F, 0.9838779332F, + 0.9844200928F, 0.9849490910F, 0.9854651087F, 0.9859683274F, + 0.9864589286F, 0.9869370940F, 0.9874030054F, 0.9878568447F, + 0.9882987937F, 0.9887290343F, 0.9891477481F, 0.9895551169F, + 0.9899513220F, 0.9903365446F, 0.9907109658F, 0.9910747662F, + 0.9914281260F, 0.9917712252F, 0.9921042433F, 0.9924273593F, + 0.9927407516F, 0.9930445982F, 0.9933390763F, 0.9936243626F, + 0.9939006331F, 0.9941680631F, 0.9944268269F, 0.9946770982F, + 0.9949190498F, 0.9951528537F, 0.9953786808F, 0.9955967011F, + 0.9958070836F, 0.9960099963F, 0.9962056061F, 0.9963940787F, + 0.9965755786F, 0.9967502693F, 0.9969183129F, 0.9970798704F, + 0.9972351013F, 0.9973841640F, 0.9975272151F, 0.9976644103F, + 0.9977959036F, 0.9979218476F, 0.9980423932F, 0.9981576901F, + 0.9982678862F, 0.9983731278F, 0.9984735596F, 0.9985693247F, + 0.9986605645F, 0.9987474186F, 0.9988300248F, 0.9989085193F, + 0.9989830364F, 0.9990537085F, 0.9991206662F, 0.9991840382F, + 0.9992439513F, 0.9993005303F, 0.9993538982F, 0.9994041757F, + 0.9994514817F, 0.9994959330F, 0.9995376444F, 0.9995767286F, + 0.9996132960F, 0.9996474550F, 0.9996793121F, 0.9997089710F, + 0.9997365339F, 0.9997621003F, 0.9997857677F, 0.9998076311F, + 0.9998277836F, 0.9998463156F, 0.9998633155F, 0.9998788692F, + 0.9998930603F, 0.9999059701F, 0.9999176774F, 0.9999282586F, + 0.9999377880F, 0.9999463370F, 0.9999539749F, 0.9999607685F, + 0.9999667820F, 0.9999720773F, 0.9999767136F, 0.9999807479F, + 0.9999842344F, 0.9999872249F, 0.9999897688F, 0.9999919127F, + 0.9999937009F, 0.9999951749F, 0.9999963738F, 0.9999973342F, + 0.9999980900F, 0.9999986724F, 0.9999991103F, 0.9999994297F, + 0.9999996543F, 0.9999998049F, 0.9999999000F, 0.9999999552F, + 0.9999999836F, 0.9999999957F, 0.9999999994F, 1.0000000000F, +}; + +static const float vwin2048[1024] = { + 0.0000009241F, 0.0000083165F, 0.0000231014F, 0.0000452785F, + 0.0000748476F, 0.0001118085F, 0.0001561608F, 0.0002079041F, + 0.0002670379F, 0.0003335617F, 0.0004074748F, 0.0004887765F, + 0.0005774661F, 0.0006735427F, 0.0007770054F, 0.0008878533F, + 0.0010060853F, 0.0011317002F, 0.0012646969F, 0.0014050742F, + 0.0015528307F, 0.0017079650F, 0.0018704756F, 0.0020403610F, + 0.0022176196F, 0.0024022497F, 0.0025942495F, 0.0027936173F, + 0.0030003511F, 0.0032144490F, 0.0034359088F, 0.0036647286F, + 0.0039009061F, 0.0041444391F, 0.0043953253F, 0.0046535621F, + 0.0049191472F, 0.0051920781F, 0.0054723520F, 0.0057599664F, + 0.0060549184F, 0.0063572052F, 0.0066668239F, 0.0069837715F, + 0.0073080449F, 0.0076396410F, 0.0079785566F, 0.0083247884F, + 0.0086783330F, 0.0090391871F, 0.0094073470F, 0.0097828092F, + 0.0101655700F, 0.0105556258F, 0.0109529726F, 0.0113576065F, + 0.0117695237F, 0.0121887200F, 0.0126151913F, 0.0130489335F, + 0.0134899422F, 0.0139382130F, 0.0143937415F, 0.0148565233F, + 0.0153265536F, 0.0158038279F, 0.0162883413F, 0.0167800889F, + 0.0172790660F, 0.0177852675F, 0.0182986882F, 0.0188193231F, + 0.0193471668F, 0.0198822141F, 0.0204244594F, 0.0209738974F, + 0.0215305225F, 0.0220943289F, 0.0226653109F, 0.0232434627F, + 0.0238287784F, 0.0244212519F, 0.0250208772F, 0.0256276481F, + 0.0262415582F, 0.0268626014F, 0.0274907711F, 0.0281260608F, + 0.0287684638F, 0.0294179736F, 0.0300745833F, 0.0307382859F, + 0.0314090747F, 0.0320869424F, 0.0327718819F, 0.0334638860F, + 0.0341629474F, 0.0348690586F, 0.0355822122F, 0.0363024004F, + 0.0370296157F, 0.0377638502F, 0.0385050960F, 0.0392533451F, + 0.0400085896F, 0.0407708211F, 0.0415400315F, 0.0423162123F, + 0.0430993552F, 0.0438894515F, 0.0446864926F, 0.0454904698F, + 0.0463013742F, 0.0471191969F, 0.0479439288F, 0.0487755607F, + 0.0496140836F, 0.0504594879F, 0.0513117642F, 0.0521709031F, + 0.0530368949F, 0.0539097297F, 0.0547893979F, 0.0556758894F, + 0.0565691941F, 0.0574693019F, 0.0583762026F, 0.0592898858F, + 0.0602103410F, 0.0611375576F, 0.0620715250F, 0.0630122324F, + 0.0639596688F, 0.0649138234F, 0.0658746848F, 0.0668422421F, + 0.0678164838F, 0.0687973985F, 0.0697849746F, 0.0707792005F, + 0.0717800645F, 0.0727875547F, 0.0738016591F, 0.0748223656F, + 0.0758496620F, 0.0768835359F, 0.0779239751F, 0.0789709668F, + 0.0800244985F, 0.0810845574F, 0.0821511306F, 0.0832242052F, + 0.0843037679F, 0.0853898056F, 0.0864823050F, 0.0875812525F, + 0.0886866347F, 0.0897984378F, 0.0909166480F, 0.0920412513F, + 0.0931722338F, 0.0943095813F, 0.0954532795F, 0.0966033140F, + 0.0977596702F, 0.0989223336F, 0.1000912894F, 0.1012665227F, + 0.1024480185F, 0.1036357616F, 0.1048297369F, 0.1060299290F, + 0.1072363224F, 0.1084489014F, 0.1096676504F, 0.1108925534F, + 0.1121235946F, 0.1133607577F, 0.1146040267F, 0.1158533850F, + 0.1171088163F, 0.1183703040F, 0.1196378312F, 0.1209113812F, + 0.1221909370F, 0.1234764815F, 0.1247679974F, 0.1260654674F, + 0.1273688740F, 0.1286781995F, 0.1299934263F, 0.1313145365F, + 0.1326415121F, 0.1339743349F, 0.1353129866F, 0.1366574490F, + 0.1380077035F, 0.1393637315F, 0.1407255141F, 0.1420930325F, + 0.1434662677F, 0.1448452004F, 0.1462298115F, 0.1476200814F, + 0.1490159906F, 0.1504175195F, 0.1518246482F, 0.1532373569F, + 0.1546556253F, 0.1560794333F, 0.1575087606F, 0.1589435866F, + 0.1603838909F, 0.1618296526F, 0.1632808509F, 0.1647374648F, + 0.1661994731F, 0.1676668546F, 0.1691395880F, 0.1706176516F, + 0.1721010238F, 0.1735896829F, 0.1750836068F, 0.1765827736F, + 0.1780871610F, 0.1795967468F, 0.1811115084F, 0.1826314234F, + 0.1841564689F, 0.1856866221F, 0.1872218600F, 0.1887621595F, + 0.1903074974F, 0.1918578503F, 0.1934131947F, 0.1949735068F, + 0.1965387630F, 0.1981089393F, 0.1996840117F, 0.2012639560F, + 0.2028487479F, 0.2044383630F, 0.2060327766F, 0.2076319642F, + 0.2092359007F, 0.2108445614F, 0.2124579211F, 0.2140759545F, + 0.2156986364F, 0.2173259411F, 0.2189578432F, 0.2205943168F, + 0.2222353361F, 0.2238808751F, 0.2255309076F, 0.2271854073F, + 0.2288443480F, 0.2305077030F, 0.2321754457F, 0.2338475493F, + 0.2355239869F, 0.2372047315F, 0.2388897560F, 0.2405790329F, + 0.2422725350F, 0.2439702347F, 0.2456721043F, 0.2473781159F, + 0.2490882418F, 0.2508024539F, 0.2525207240F, 0.2542430237F, + 0.2559693248F, 0.2576995986F, 0.2594338166F, 0.2611719498F, + 0.2629139695F, 0.2646598466F, 0.2664095520F, 0.2681630564F, + 0.2699203304F, 0.2716813445F, 0.2734460691F, 0.2752144744F, + 0.2769865307F, 0.2787622079F, 0.2805414760F, 0.2823243047F, + 0.2841106637F, 0.2859005227F, 0.2876938509F, 0.2894906179F, + 0.2912907928F, 0.2930943447F, 0.2949012426F, 0.2967114554F, + 0.2985249520F, 0.3003417009F, 0.3021616708F, 0.3039848301F, + 0.3058111471F, 0.3076405901F, 0.3094731273F, 0.3113087266F, + 0.3131473560F, 0.3149889833F, 0.3168335762F, 0.3186811024F, + 0.3205315294F, 0.3223848245F, 0.3242409552F, 0.3260998886F, + 0.3279615918F, 0.3298260319F, 0.3316931758F, 0.3335629903F, + 0.3354354423F, 0.3373104982F, 0.3391881247F, 0.3410682882F, + 0.3429509551F, 0.3448360917F, 0.3467236642F, 0.3486136387F, + 0.3505059811F, 0.3524006575F, 0.3542976336F, 0.3561968753F, + 0.3580983482F, 0.3600020179F, 0.3619078499F, 0.3638158096F, + 0.3657258625F, 0.3676379737F, 0.3695521086F, 0.3714682321F, + 0.3733863094F, 0.3753063055F, 0.3772281852F, 0.3791519134F, + 0.3810774548F, 0.3830047742F, 0.3849338362F, 0.3868646053F, + 0.3887970459F, 0.3907311227F, 0.3926667998F, 0.3946040417F, + 0.3965428125F, 0.3984830765F, 0.4004247978F, 0.4023679403F, + 0.4043124683F, 0.4062583455F, 0.4082055359F, 0.4101540034F, + 0.4121037117F, 0.4140546246F, 0.4160067058F, 0.4179599190F, + 0.4199142277F, 0.4218695956F, 0.4238259861F, 0.4257833627F, + 0.4277416888F, 0.4297009279F, 0.4316610433F, 0.4336219983F, + 0.4355837562F, 0.4375462803F, 0.4395095337F, 0.4414734797F, + 0.4434380815F, 0.4454033021F, 0.4473691046F, 0.4493354521F, + 0.4513023078F, 0.4532696345F, 0.4552373954F, 0.4572055533F, + 0.4591740713F, 0.4611429123F, 0.4631120393F, 0.4650814151F, + 0.4670510028F, 0.4690207650F, 0.4709906649F, 0.4729606651F, + 0.4749307287F, 0.4769008185F, 0.4788708972F, 0.4808409279F, + 0.4828108732F, 0.4847806962F, 0.4867503597F, 0.4887198264F, + 0.4906890593F, 0.4926580213F, 0.4946266753F, 0.4965949840F, + 0.4985629105F, 0.5005304176F, 0.5024974683F, 0.5044640255F, + 0.5064300522F, 0.5083955114F, 0.5103603659F, 0.5123245790F, + 0.5142881136F, 0.5162509328F, 0.5182129997F, 0.5201742774F, + 0.5221347290F, 0.5240943178F, 0.5260530070F, 0.5280107598F, + 0.5299675395F, 0.5319233095F, 0.5338780330F, 0.5358316736F, + 0.5377841946F, 0.5397355596F, 0.5416857320F, 0.5436346755F, + 0.5455823538F, 0.5475287304F, 0.5494737691F, 0.5514174337F, + 0.5533596881F, 0.5553004962F, 0.5572398218F, 0.5591776291F, + 0.5611138821F, 0.5630485449F, 0.5649815818F, 0.5669129570F, + 0.5688426349F, 0.5707705799F, 0.5726967564F, 0.5746211290F, + 0.5765436624F, 0.5784643212F, 0.5803830702F, 0.5822998743F, + 0.5842146984F, 0.5861275076F, 0.5880382669F, 0.5899469416F, + 0.5918534968F, 0.5937578981F, 0.5956601107F, 0.5975601004F, + 0.5994578326F, 0.6013532732F, 0.6032463880F, 0.6051371429F, + 0.6070255039F, 0.6089114372F, 0.6107949090F, 0.6126758856F, + 0.6145543334F, 0.6164302191F, 0.6183035092F, 0.6201741706F, + 0.6220421700F, 0.6239074745F, 0.6257700513F, 0.6276298674F, + 0.6294868903F, 0.6313410873F, 0.6331924262F, 0.6350408745F, + 0.6368864001F, 0.6387289710F, 0.6405685552F, 0.6424051209F, + 0.6442386364F, 0.6460690702F, 0.6478963910F, 0.6497205673F, + 0.6515415682F, 0.6533593625F, 0.6551739194F, 0.6569852082F, + 0.6587931984F, 0.6605978593F, 0.6623991609F, 0.6641970728F, + 0.6659915652F, 0.6677826081F, 0.6695701718F, 0.6713542268F, + 0.6731347437F, 0.6749116932F, 0.6766850461F, 0.6784547736F, + 0.6802208469F, 0.6819832374F, 0.6837419164F, 0.6854968559F, + 0.6872480275F, 0.6889954034F, 0.6907389556F, 0.6924786566F, + 0.6942144788F, 0.6959463950F, 0.6976743780F, 0.6993984008F, + 0.7011184365F, 0.7028344587F, 0.7045464407F, 0.7062543564F, + 0.7079581796F, 0.7096578844F, 0.7113534450F, 0.7130448359F, + 0.7147320316F, 0.7164150070F, 0.7180937371F, 0.7197681970F, + 0.7214383620F, 0.7231042077F, 0.7247657098F, 0.7264228443F, + 0.7280755871F, 0.7297239147F, 0.7313678035F, 0.7330072301F, + 0.7346421715F, 0.7362726046F, 0.7378985069F, 0.7395198556F, + 0.7411366285F, 0.7427488034F, 0.7443563584F, 0.7459592717F, + 0.7475575218F, 0.7491510873F, 0.7507399471F, 0.7523240803F, + 0.7539034661F, 0.7554780839F, 0.7570479136F, 0.7586129349F, + 0.7601731279F, 0.7617284730F, 0.7632789506F, 0.7648245416F, + 0.7663652267F, 0.7679009872F, 0.7694318044F, 0.7709576599F, + 0.7724785354F, 0.7739944130F, 0.7755052749F, 0.7770111035F, + 0.7785118815F, 0.7800075916F, 0.7814982170F, 0.7829837410F, + 0.7844641472F, 0.7859394191F, 0.7874095408F, 0.7888744965F, + 0.7903342706F, 0.7917888476F, 0.7932382124F, 0.7946823501F, + 0.7961212460F, 0.7975548855F, 0.7989832544F, 0.8004063386F, + 0.8018241244F, 0.8032365981F, 0.8046437463F, 0.8060455560F, + 0.8074420141F, 0.8088331080F, 0.8102188253F, 0.8115991536F, + 0.8129740810F, 0.8143435957F, 0.8157076861F, 0.8170663409F, + 0.8184195489F, 0.8197672994F, 0.8211095817F, 0.8224463853F, + 0.8237777001F, 0.8251035161F, 0.8264238235F, 0.8277386129F, + 0.8290478750F, 0.8303516008F, 0.8316497814F, 0.8329424083F, + 0.8342294731F, 0.8355109677F, 0.8367868841F, 0.8380572148F, + 0.8393219523F, 0.8405810893F, 0.8418346190F, 0.8430825345F, + 0.8443248294F, 0.8455614974F, 0.8467925323F, 0.8480179285F, + 0.8492376802F, 0.8504517822F, 0.8516602292F, 0.8528630164F, + 0.8540601391F, 0.8552515928F, 0.8564373733F, 0.8576174766F, + 0.8587918990F, 0.8599606368F, 0.8611236868F, 0.8622810460F, + 0.8634327113F, 0.8645786802F, 0.8657189504F, 0.8668535195F, + 0.8679823857F, 0.8691055472F, 0.8702230025F, 0.8713347503F, + 0.8724407896F, 0.8735411194F, 0.8746357394F, 0.8757246489F, + 0.8768078479F, 0.8778853364F, 0.8789571146F, 0.8800231832F, + 0.8810835427F, 0.8821381942F, 0.8831871387F, 0.8842303777F, + 0.8852679127F, 0.8862997456F, 0.8873258784F, 0.8883463132F, + 0.8893610527F, 0.8903700994F, 0.8913734562F, 0.8923711263F, + 0.8933631129F, 0.8943494196F, 0.8953300500F, 0.8963050083F, + 0.8972742985F, 0.8982379249F, 0.8991958922F, 0.9001482052F, + 0.9010948688F, 0.9020358883F, 0.9029712690F, 0.9039010165F, + 0.9048251367F, 0.9057436357F, 0.9066565195F, 0.9075637946F, + 0.9084654678F, 0.9093615456F, 0.9102520353F, 0.9111369440F, + 0.9120162792F, 0.9128900484F, 0.9137582595F, 0.9146209204F, + 0.9154780394F, 0.9163296248F, 0.9171756853F, 0.9180162296F, + 0.9188512667F, 0.9196808057F, 0.9205048559F, 0.9213234270F, + 0.9221365285F, 0.9229441704F, 0.9237463629F, 0.9245431160F, + 0.9253344404F, 0.9261203465F, 0.9269008453F, 0.9276759477F, + 0.9284456648F, 0.9292100080F, 0.9299689889F, 0.9307226190F, + 0.9314709103F, 0.9322138747F, 0.9329515245F, 0.9336838721F, + 0.9344109300F, 0.9351327108F, 0.9358492275F, 0.9365604931F, + 0.9372665208F, 0.9379673239F, 0.9386629160F, 0.9393533107F, + 0.9400385220F, 0.9407185637F, 0.9413934501F, 0.9420631954F, + 0.9427278141F, 0.9433873208F, 0.9440417304F, 0.9446910576F, + 0.9453353176F, 0.9459745255F, 0.9466086968F, 0.9472378469F, + 0.9478619915F, 0.9484811463F, 0.9490953274F, 0.9497045506F, + 0.9503088323F, 0.9509081888F, 0.9515026365F, 0.9520921921F, + 0.9526768723F, 0.9532566940F, 0.9538316742F, 0.9544018300F, + 0.9549671786F, 0.9555277375F, 0.9560835241F, 0.9566345562F, + 0.9571808513F, 0.9577224275F, 0.9582593027F, 0.9587914949F, + 0.9593190225F, 0.9598419038F, 0.9603601571F, 0.9608738012F, + 0.9613828546F, 0.9618873361F, 0.9623872646F, 0.9628826591F, + 0.9633735388F, 0.9638599227F, 0.9643418303F, 0.9648192808F, + 0.9652922939F, 0.9657608890F, 0.9662250860F, 0.9666849046F, + 0.9671403646F, 0.9675914861F, 0.9680382891F, 0.9684807937F, + 0.9689190202F, 0.9693529890F, 0.9697827203F, 0.9702082347F, + 0.9706295529F, 0.9710466953F, 0.9714596828F, 0.9718685362F, + 0.9722732762F, 0.9726739240F, 0.9730705005F, 0.9734630267F, + 0.9738515239F, 0.9742360134F, 0.9746165163F, 0.9749930540F, + 0.9753656481F, 0.9757343198F, 0.9760990909F, 0.9764599829F, + 0.9768170175F, 0.9771702164F, 0.9775196013F, 0.9778651941F, + 0.9782070167F, 0.9785450909F, 0.9788794388F, 0.9792100824F, + 0.9795370437F, 0.9798603449F, 0.9801800080F, 0.9804960554F, + 0.9808085092F, 0.9811173916F, 0.9814227251F, 0.9817245318F, + 0.9820228343F, 0.9823176549F, 0.9826090160F, 0.9828969402F, + 0.9831814498F, 0.9834625674F, 0.9837403156F, 0.9840147169F, + 0.9842857939F, 0.9845535692F, 0.9848180654F, 0.9850793052F, + 0.9853373113F, 0.9855921062F, 0.9858437127F, 0.9860921535F, + 0.9863374512F, 0.9865796287F, 0.9868187085F, 0.9870547136F, + 0.9872876664F, 0.9875175899F, 0.9877445067F, 0.9879684396F, + 0.9881894112F, 0.9884074444F, 0.9886225619F, 0.9888347863F, + 0.9890441404F, 0.9892506468F, 0.9894543284F, 0.9896552077F, + 0.9898533074F, 0.9900486502F, 0.9902412587F, 0.9904311555F, + 0.9906183633F, 0.9908029045F, 0.9909848019F, 0.9911640779F, + 0.9913407550F, 0.9915148557F, 0.9916864025F, 0.9918554179F, + 0.9920219241F, 0.9921859437F, 0.9923474989F, 0.9925066120F, + 0.9926633054F, 0.9928176012F, 0.9929695218F, 0.9931190891F, + 0.9932663254F, 0.9934112527F, 0.9935538932F, 0.9936942686F, + 0.9938324012F, 0.9939683126F, 0.9941020248F, 0.9942335597F, + 0.9943629388F, 0.9944901841F, 0.9946153170F, 0.9947383593F, + 0.9948593325F, 0.9949782579F, 0.9950951572F, 0.9952100516F, + 0.9953229625F, 0.9954339111F, 0.9955429186F, 0.9956500062F, + 0.9957551948F, 0.9958585056F, 0.9959599593F, 0.9960595769F, + 0.9961573792F, 0.9962533869F, 0.9963476206F, 0.9964401009F, + 0.9965308483F, 0.9966198833F, 0.9967072261F, 0.9967928971F, + 0.9968769164F, 0.9969593041F, 0.9970400804F, 0.9971192651F, + 0.9971968781F, 0.9972729391F, 0.9973474680F, 0.9974204842F, + 0.9974920074F, 0.9975620569F, 0.9976306521F, 0.9976978122F, + 0.9977635565F, 0.9978279039F, 0.9978908736F, 0.9979524842F, + 0.9980127547F, 0.9980717037F, 0.9981293499F, 0.9981857116F, + 0.9982408073F, 0.9982946554F, 0.9983472739F, 0.9983986810F, + 0.9984488947F, 0.9984979328F, 0.9985458132F, 0.9985925534F, + 0.9986381711F, 0.9986826838F, 0.9987261086F, 0.9987684630F, + 0.9988097640F, 0.9988500286F, 0.9988892738F, 0.9989275163F, + 0.9989647727F, 0.9990010597F, 0.9990363938F, 0.9990707911F, + 0.9991042679F, 0.9991368404F, 0.9991685244F, 0.9991993358F, + 0.9992292905F, 0.9992584038F, 0.9992866914F, 0.9993141686F, + 0.9993408506F, 0.9993667526F, 0.9993918895F, 0.9994162761F, + 0.9994399273F, 0.9994628576F, 0.9994850815F, 0.9995066133F, + 0.9995274672F, 0.9995476574F, 0.9995671978F, 0.9995861021F, + 0.9996043841F, 0.9996220573F, 0.9996391352F, 0.9996556310F, + 0.9996715579F, 0.9996869288F, 0.9997017568F, 0.9997160543F, + 0.9997298342F, 0.9997431088F, 0.9997558905F, 0.9997681914F, + 0.9997800236F, 0.9997913990F, 0.9998023292F, 0.9998128261F, + 0.9998229009F, 0.9998325650F, 0.9998418296F, 0.9998507058F, + 0.9998592044F, 0.9998673362F, 0.9998751117F, 0.9998825415F, + 0.9998896358F, 0.9998964047F, 0.9999028584F, 0.9999090066F, + 0.9999148590F, 0.9999204253F, 0.9999257148F, 0.9999307368F, + 0.9999355003F, 0.9999400144F, 0.9999442878F, 0.9999483293F, + 0.9999521472F, 0.9999557499F, 0.9999591457F, 0.9999623426F, + 0.9999653483F, 0.9999681708F, 0.9999708175F, 0.9999732959F, + 0.9999756132F, 0.9999777765F, 0.9999797928F, 0.9999816688F, + 0.9999834113F, 0.9999850266F, 0.9999865211F, 0.9999879009F, + 0.9999891721F, 0.9999903405F, 0.9999914118F, 0.9999923914F, + 0.9999932849F, 0.9999940972F, 0.9999948336F, 0.9999954989F, + 0.9999960978F, 0.9999966349F, 0.9999971146F, 0.9999975411F, + 0.9999979185F, 0.9999982507F, 0.9999985414F, 0.9999987944F, + 0.9999990129F, 0.9999992003F, 0.9999993596F, 0.9999994939F, + 0.9999996059F, 0.9999996981F, 0.9999997732F, 0.9999998333F, + 0.9999998805F, 0.9999999170F, 0.9999999444F, 0.9999999643F, + 0.9999999784F, 0.9999999878F, 0.9999999937F, 0.9999999972F, + 0.9999999990F, 0.9999999997F, 1.0000000000F, 1.0000000000F, +}; + +static const float vwin4096[2048] = { + 0.0000002310F, 0.0000020791F, 0.0000057754F, 0.0000113197F, + 0.0000187121F, 0.0000279526F, 0.0000390412F, 0.0000519777F, + 0.0000667623F, 0.0000833949F, 0.0001018753F, 0.0001222036F, + 0.0001443798F, 0.0001684037F, 0.0001942754F, 0.0002219947F, + 0.0002515616F, 0.0002829761F, 0.0003162380F, 0.0003513472F, + 0.0003883038F, 0.0004271076F, 0.0004677584F, 0.0005102563F, + 0.0005546011F, 0.0006007928F, 0.0006488311F, 0.0006987160F, + 0.0007504474F, 0.0008040251F, 0.0008594490F, 0.0009167191F, + 0.0009758351F, 0.0010367969F, 0.0010996044F, 0.0011642574F, + 0.0012307558F, 0.0012990994F, 0.0013692880F, 0.0014413216F, + 0.0015151998F, 0.0015909226F, 0.0016684898F, 0.0017479011F, + 0.0018291565F, 0.0019122556F, 0.0019971983F, 0.0020839845F, + 0.0021726138F, 0.0022630861F, 0.0023554012F, 0.0024495588F, + 0.0025455588F, 0.0026434008F, 0.0027430847F, 0.0028446103F, + 0.0029479772F, 0.0030531853F, 0.0031602342F, 0.0032691238F, + 0.0033798538F, 0.0034924239F, 0.0036068338F, 0.0037230833F, + 0.0038411721F, 0.0039610999F, 0.0040828664F, 0.0042064714F, + 0.0043319145F, 0.0044591954F, 0.0045883139F, 0.0047192696F, + 0.0048520622F, 0.0049866914F, 0.0051231569F, 0.0052614583F, + 0.0054015953F, 0.0055435676F, 0.0056873748F, 0.0058330166F, + 0.0059804926F, 0.0061298026F, 0.0062809460F, 0.0064339226F, + 0.0065887320F, 0.0067453738F, 0.0069038476F, 0.0070641531F, + 0.0072262899F, 0.0073902575F, 0.0075560556F, 0.0077236838F, + 0.0078931417F, 0.0080644288F, 0.0082375447F, 0.0084124891F, + 0.0085892615F, 0.0087678614F, 0.0089482885F, 0.0091305422F, + 0.0093146223F, 0.0095005281F, 0.0096882592F, 0.0098778153F, + 0.0100691958F, 0.0102624002F, 0.0104574281F, 0.0106542791F, + 0.0108529525F, 0.0110534480F, 0.0112557651F, 0.0114599032F, + 0.0116658618F, 0.0118736405F, 0.0120832387F, 0.0122946560F, + 0.0125078917F, 0.0127229454F, 0.0129398166F, 0.0131585046F, + 0.0133790090F, 0.0136013292F, 0.0138254647F, 0.0140514149F, + 0.0142791792F, 0.0145087572F, 0.0147401481F, 0.0149733515F, + 0.0152083667F, 0.0154451932F, 0.0156838304F, 0.0159242777F, + 0.0161665345F, 0.0164106001F, 0.0166564741F, 0.0169041557F, + 0.0171536443F, 0.0174049393F, 0.0176580401F, 0.0179129461F, + 0.0181696565F, 0.0184281708F, 0.0186884883F, 0.0189506084F, + 0.0192145303F, 0.0194802535F, 0.0197477772F, 0.0200171008F, + 0.0202882236F, 0.0205611449F, 0.0208358639F, 0.0211123801F, + 0.0213906927F, 0.0216708011F, 0.0219527043F, 0.0222364019F, + 0.0225218930F, 0.0228091769F, 0.0230982529F, 0.0233891203F, + 0.0236817782F, 0.0239762259F, 0.0242724628F, 0.0245704880F, + 0.0248703007F, 0.0251719002F, 0.0254752858F, 0.0257804565F, + 0.0260874117F, 0.0263961506F, 0.0267066722F, 0.0270189760F, + 0.0273330609F, 0.0276489263F, 0.0279665712F, 0.0282859949F, + 0.0286071966F, 0.0289301753F, 0.0292549303F, 0.0295814607F, + 0.0299097656F, 0.0302398442F, 0.0305716957F, 0.0309053191F, + 0.0312407135F, 0.0315778782F, 0.0319168122F, 0.0322575145F, + 0.0325999844F, 0.0329442209F, 0.0332902231F, 0.0336379900F, + 0.0339875208F, 0.0343388146F, 0.0346918703F, 0.0350466871F, + 0.0354032640F, 0.0357616000F, 0.0361216943F, 0.0364835458F, + 0.0368471535F, 0.0372125166F, 0.0375796339F, 0.0379485046F, + 0.0383191276F, 0.0386915020F, 0.0390656267F, 0.0394415008F, + 0.0398191231F, 0.0401984927F, 0.0405796086F, 0.0409624698F, + 0.0413470751F, 0.0417334235F, 0.0421215141F, 0.0425113457F, + 0.0429029172F, 0.0432962277F, 0.0436912760F, 0.0440880610F, + 0.0444865817F, 0.0448868370F, 0.0452888257F, 0.0456925468F, + 0.0460979992F, 0.0465051816F, 0.0469140931F, 0.0473247325F, + 0.0477370986F, 0.0481511902F, 0.0485670064F, 0.0489845458F, + 0.0494038074F, 0.0498247899F, 0.0502474922F, 0.0506719131F, + 0.0510980514F, 0.0515259060F, 0.0519554756F, 0.0523867590F, + 0.0528197550F, 0.0532544624F, 0.0536908800F, 0.0541290066F, + 0.0545688408F, 0.0550103815F, 0.0554536274F, 0.0558985772F, + 0.0563452297F, 0.0567935837F, 0.0572436377F, 0.0576953907F, + 0.0581488412F, 0.0586039880F, 0.0590608297F, 0.0595193651F, + 0.0599795929F, 0.0604415117F, 0.0609051202F, 0.0613704170F, + 0.0618374009F, 0.0623060704F, 0.0627764243F, 0.0632484611F, + 0.0637221795F, 0.0641975781F, 0.0646746555F, 0.0651534104F, + 0.0656338413F, 0.0661159469F, 0.0665997257F, 0.0670851763F, + 0.0675722973F, 0.0680610873F, 0.0685515448F, 0.0690436684F, + 0.0695374567F, 0.0700329081F, 0.0705300213F, 0.0710287947F, + 0.0715292269F, 0.0720313163F, 0.0725350616F, 0.0730404612F, + 0.0735475136F, 0.0740562172F, 0.0745665707F, 0.0750785723F, + 0.0755922207F, 0.0761075143F, 0.0766244515F, 0.0771430307F, + 0.0776632505F, 0.0781851092F, 0.0787086052F, 0.0792337371F, + 0.0797605032F, 0.0802889018F, 0.0808189315F, 0.0813505905F, + 0.0818838773F, 0.0824187903F, 0.0829553277F, 0.0834934881F, + 0.0840332697F, 0.0845746708F, 0.0851176899F, 0.0856623252F, + 0.0862085751F, 0.0867564379F, 0.0873059119F, 0.0878569954F, + 0.0884096867F, 0.0889639840F, 0.0895198858F, 0.0900773902F, + 0.0906364955F, 0.0911972000F, 0.0917595019F, 0.0923233995F, + 0.0928888909F, 0.0934559745F, 0.0940246485F, 0.0945949110F, + 0.0951667604F, 0.0957401946F, 0.0963152121F, 0.0968918109F, + 0.0974699893F, 0.0980497454F, 0.0986310773F, 0.0992139832F, + 0.0997984614F, 0.1003845098F, 0.1009721267F, 0.1015613101F, + 0.1021520582F, 0.1027443692F, 0.1033382410F, 0.1039336718F, + 0.1045306597F, 0.1051292027F, 0.1057292990F, 0.1063309466F, + 0.1069341435F, 0.1075388878F, 0.1081451776F, 0.1087530108F, + 0.1093623856F, 0.1099732998F, 0.1105857516F, 0.1111997389F, + 0.1118152597F, 0.1124323121F, 0.1130508939F, 0.1136710032F, + 0.1142926379F, 0.1149157960F, 0.1155404755F, 0.1161666742F, + 0.1167943901F, 0.1174236211F, 0.1180543652F, 0.1186866202F, + 0.1193203841F, 0.1199556548F, 0.1205924300F, 0.1212307078F, + 0.1218704860F, 0.1225117624F, 0.1231545349F, 0.1237988013F, + 0.1244445596F, 0.1250918074F, 0.1257405427F, 0.1263907632F, + 0.1270424667F, 0.1276956512F, 0.1283503142F, 0.1290064537F, + 0.1296640674F, 0.1303231530F, 0.1309837084F, 0.1316457312F, + 0.1323092193F, 0.1329741703F, 0.1336405820F, 0.1343084520F, + 0.1349777782F, 0.1356485582F, 0.1363207897F, 0.1369944704F, + 0.1376695979F, 0.1383461700F, 0.1390241842F, 0.1397036384F, + 0.1403845300F, 0.1410668567F, 0.1417506162F, 0.1424358061F, + 0.1431224240F, 0.1438104674F, 0.1444999341F, 0.1451908216F, + 0.1458831274F, 0.1465768492F, 0.1472719844F, 0.1479685308F, + 0.1486664857F, 0.1493658468F, 0.1500666115F, 0.1507687775F, + 0.1514723422F, 0.1521773031F, 0.1528836577F, 0.1535914035F, + 0.1543005380F, 0.1550110587F, 0.1557229631F, 0.1564362485F, + 0.1571509124F, 0.1578669524F, 0.1585843657F, 0.1593031499F, + 0.1600233024F, 0.1607448205F, 0.1614677017F, 0.1621919433F, + 0.1629175428F, 0.1636444975F, 0.1643728047F, 0.1651024619F, + 0.1658334665F, 0.1665658156F, 0.1672995067F, 0.1680345371F, + 0.1687709041F, 0.1695086050F, 0.1702476372F, 0.1709879978F, + 0.1717296843F, 0.1724726938F, 0.1732170237F, 0.1739626711F, + 0.1747096335F, 0.1754579079F, 0.1762074916F, 0.1769583819F, + 0.1777105760F, 0.1784640710F, 0.1792188642F, 0.1799749529F, + 0.1807323340F, 0.1814910049F, 0.1822509628F, 0.1830122046F, + 0.1837747277F, 0.1845385292F, 0.1853036062F, 0.1860699558F, + 0.1868375751F, 0.1876064613F, 0.1883766114F, 0.1891480226F, + 0.1899206919F, 0.1906946164F, 0.1914697932F, 0.1922462194F, + 0.1930238919F, 0.1938028079F, 0.1945829643F, 0.1953643583F, + 0.1961469868F, 0.1969308468F, 0.1977159353F, 0.1985022494F, + 0.1992897859F, 0.2000785420F, 0.2008685145F, 0.2016597005F, + 0.2024520968F, 0.2032457005F, 0.2040405084F, 0.2048365175F, + 0.2056337247F, 0.2064321269F, 0.2072317211F, 0.2080325041F, + 0.2088344727F, 0.2096376240F, 0.2104419547F, 0.2112474618F, + 0.2120541420F, 0.2128619923F, 0.2136710094F, 0.2144811902F, + 0.2152925315F, 0.2161050301F, 0.2169186829F, 0.2177334866F, + 0.2185494381F, 0.2193665340F, 0.2201847712F, 0.2210041465F, + 0.2218246565F, 0.2226462981F, 0.2234690680F, 0.2242929629F, + 0.2251179796F, 0.2259441147F, 0.2267713650F, 0.2275997272F, + 0.2284291979F, 0.2292597739F, 0.2300914518F, 0.2309242283F, + 0.2317581001F, 0.2325930638F, 0.2334291160F, 0.2342662534F, + 0.2351044727F, 0.2359437703F, 0.2367841431F, 0.2376255875F, + 0.2384681001F, 0.2393116776F, 0.2401563165F, 0.2410020134F, + 0.2418487649F, 0.2426965675F, 0.2435454178F, 0.2443953122F, + 0.2452462474F, 0.2460982199F, 0.2469512262F, 0.2478052628F, + 0.2486603262F, 0.2495164129F, 0.2503735194F, 0.2512316421F, + 0.2520907776F, 0.2529509222F, 0.2538120726F, 0.2546742250F, + 0.2555373760F, 0.2564015219F, 0.2572666593F, 0.2581327845F, + 0.2589998939F, 0.2598679840F, 0.2607370510F, 0.2616070916F, + 0.2624781019F, 0.2633500783F, 0.2642230173F, 0.2650969152F, + 0.2659717684F, 0.2668475731F, 0.2677243257F, 0.2686020226F, + 0.2694806601F, 0.2703602344F, 0.2712407419F, 0.2721221789F, + 0.2730045417F, 0.2738878265F, 0.2747720297F, 0.2756571474F, + 0.2765431760F, 0.2774301117F, 0.2783179508F, 0.2792066895F, + 0.2800963240F, 0.2809868505F, 0.2818782654F, 0.2827705647F, + 0.2836637447F, 0.2845578016F, 0.2854527315F, 0.2863485307F, + 0.2872451953F, 0.2881427215F, 0.2890411055F, 0.2899403433F, + 0.2908404312F, 0.2917413654F, 0.2926431418F, 0.2935457567F, + 0.2944492061F, 0.2953534863F, 0.2962585932F, 0.2971645230F, + 0.2980712717F, 0.2989788356F, 0.2998872105F, 0.3007963927F, + 0.3017063781F, 0.3026171629F, 0.3035287430F, 0.3044411145F, + 0.3053542736F, 0.3062682161F, 0.3071829381F, 0.3080984356F, + 0.3090147047F, 0.3099317413F, 0.3108495414F, 0.3117681011F, + 0.3126874163F, 0.3136074830F, 0.3145282972F, 0.3154498548F, + 0.3163721517F, 0.3172951841F, 0.3182189477F, 0.3191434385F, + 0.3200686525F, 0.3209945856F, 0.3219212336F, 0.3228485927F, + 0.3237766585F, 0.3247054271F, 0.3256348943F, 0.3265650560F, + 0.3274959081F, 0.3284274465F, 0.3293596671F, 0.3302925657F, + 0.3312261382F, 0.3321603804F, 0.3330952882F, 0.3340308574F, + 0.3349670838F, 0.3359039634F, 0.3368414919F, 0.3377796651F, + 0.3387184789F, 0.3396579290F, 0.3405980113F, 0.3415387216F, + 0.3424800556F, 0.3434220091F, 0.3443645779F, 0.3453077578F, + 0.3462515446F, 0.3471959340F, 0.3481409217F, 0.3490865036F, + 0.3500326754F, 0.3509794328F, 0.3519267715F, 0.3528746873F, + 0.3538231759F, 0.3547722330F, 0.3557218544F, 0.3566720357F, + 0.3576227727F, 0.3585740610F, 0.3595258964F, 0.3604782745F, + 0.3614311910F, 0.3623846417F, 0.3633386221F, 0.3642931280F, + 0.3652481549F, 0.3662036987F, 0.3671597548F, 0.3681163191F, + 0.3690733870F, 0.3700309544F, 0.3709890167F, 0.3719475696F, + 0.3729066089F, 0.3738661299F, 0.3748261285F, 0.3757866002F, + 0.3767475406F, 0.3777089453F, 0.3786708100F, 0.3796331302F, + 0.3805959014F, 0.3815591194F, 0.3825227796F, 0.3834868777F, + 0.3844514093F, 0.3854163698F, 0.3863817549F, 0.3873475601F, + 0.3883137810F, 0.3892804131F, 0.3902474521F, 0.3912148933F, + 0.3921827325F, 0.3931509650F, 0.3941195865F, 0.3950885925F, + 0.3960579785F, 0.3970277400F, 0.3979978725F, 0.3989683716F, + 0.3999392328F, 0.4009104516F, 0.4018820234F, 0.4028539438F, + 0.4038262084F, 0.4047988125F, 0.4057717516F, 0.4067450214F, + 0.4077186172F, 0.4086925345F, 0.4096667688F, 0.4106413155F, + 0.4116161703F, 0.4125913284F, 0.4135667854F, 0.4145425368F, + 0.4155185780F, 0.4164949044F, 0.4174715116F, 0.4184483949F, + 0.4194255498F, 0.4204029718F, 0.4213806563F, 0.4223585987F, + 0.4233367946F, 0.4243152392F, 0.4252939281F, 0.4262728566F, + 0.4272520202F, 0.4282314144F, 0.4292110345F, 0.4301908760F, + 0.4311709343F, 0.4321512047F, 0.4331316828F, 0.4341123639F, + 0.4350932435F, 0.4360743168F, 0.4370555794F, 0.4380370267F, + 0.4390186540F, 0.4400004567F, 0.4409824303F, 0.4419645701F, + 0.4429468716F, 0.4439293300F, 0.4449119409F, 0.4458946996F, + 0.4468776014F, 0.4478606418F, 0.4488438162F, 0.4498271199F, + 0.4508105483F, 0.4517940967F, 0.4527777607F, 0.4537615355F, + 0.4547454165F, 0.4557293991F, 0.4567134786F, 0.4576976505F, + 0.4586819101F, 0.4596662527F, 0.4606506738F, 0.4616351687F, + 0.4626197328F, 0.4636043614F, 0.4645890499F, 0.4655737936F, + 0.4665585880F, 0.4675434284F, 0.4685283101F, 0.4695132286F, + 0.4704981791F, 0.4714831570F, 0.4724681577F, 0.4734531766F, + 0.4744382089F, 0.4754232501F, 0.4764082956F, 0.4773933406F, + 0.4783783806F, 0.4793634108F, 0.4803484267F, 0.4813334237F, + 0.4823183969F, 0.4833033419F, 0.4842882540F, 0.4852731285F, + 0.4862579608F, 0.4872427462F, 0.4882274802F, 0.4892121580F, + 0.4901967751F, 0.4911813267F, 0.4921658083F, 0.4931502151F, + 0.4941345427F, 0.4951187863F, 0.4961029412F, 0.4970870029F, + 0.4980709667F, 0.4990548280F, 0.5000385822F, 0.5010222245F, + 0.5020057505F, 0.5029891553F, 0.5039724345F, 0.5049555834F, + 0.5059385973F, 0.5069214716F, 0.5079042018F, 0.5088867831F, + 0.5098692110F, 0.5108514808F, 0.5118335879F, 0.5128155277F, + 0.5137972956F, 0.5147788869F, 0.5157602971F, 0.5167415215F, + 0.5177225555F, 0.5187033945F, 0.5196840339F, 0.5206644692F, + 0.5216446956F, 0.5226247086F, 0.5236045035F, 0.5245840759F, + 0.5255634211F, 0.5265425344F, 0.5275214114F, 0.5285000474F, + 0.5294784378F, 0.5304565781F, 0.5314344637F, 0.5324120899F, + 0.5333894522F, 0.5343665461F, 0.5353433670F, 0.5363199102F, + 0.5372961713F, 0.5382721457F, 0.5392478287F, 0.5402232159F, + 0.5411983027F, 0.5421730845F, 0.5431475569F, 0.5441217151F, + 0.5450955548F, 0.5460690714F, 0.5470422602F, 0.5480151169F, + 0.5489876368F, 0.5499598155F, 0.5509316484F, 0.5519031310F, + 0.5528742587F, 0.5538450271F, 0.5548154317F, 0.5557854680F, + 0.5567551314F, 0.5577244174F, 0.5586933216F, 0.5596618395F, + 0.5606299665F, 0.5615976983F, 0.5625650302F, 0.5635319580F, + 0.5644984770F, 0.5654645828F, 0.5664302709F, 0.5673955370F, + 0.5683603765F, 0.5693247850F, 0.5702887580F, 0.5712522912F, + 0.5722153800F, 0.5731780200F, 0.5741402069F, 0.5751019362F, + 0.5760632034F, 0.5770240042F, 0.5779843341F, 0.5789441889F, + 0.5799035639F, 0.5808624549F, 0.5818208575F, 0.5827787673F, + 0.5837361800F, 0.5846930910F, 0.5856494961F, 0.5866053910F, + 0.5875607712F, 0.5885156324F, 0.5894699703F, 0.5904237804F, + 0.5913770586F, 0.5923298004F, 0.5932820016F, 0.5942336578F, + 0.5951847646F, 0.5961353179F, 0.5970853132F, 0.5980347464F, + 0.5989836131F, 0.5999319090F, 0.6008796298F, 0.6018267713F, + 0.6027733292F, 0.6037192993F, 0.6046646773F, 0.6056094589F, + 0.6065536400F, 0.6074972162F, 0.6084401833F, 0.6093825372F, + 0.6103242736F, 0.6112653884F, 0.6122058772F, 0.6131457359F, + 0.6140849604F, 0.6150235464F, 0.6159614897F, 0.6168987862F, + 0.6178354318F, 0.6187714223F, 0.6197067535F, 0.6206414213F, + 0.6215754215F, 0.6225087501F, 0.6234414028F, 0.6243733757F, + 0.6253046646F, 0.6262352654F, 0.6271651739F, 0.6280943862F, + 0.6290228982F, 0.6299507057F, 0.6308778048F, 0.6318041913F, + 0.6327298612F, 0.6336548105F, 0.6345790352F, 0.6355025312F, + 0.6364252945F, 0.6373473211F, 0.6382686070F, 0.6391891483F, + 0.6401089409F, 0.6410279808F, 0.6419462642F, 0.6428637869F, + 0.6437805452F, 0.6446965350F, 0.6456117524F, 0.6465261935F, + 0.6474398544F, 0.6483527311F, 0.6492648197F, 0.6501761165F, + 0.6510866174F, 0.6519963186F, 0.6529052162F, 0.6538133064F, + 0.6547205854F, 0.6556270492F, 0.6565326941F, 0.6574375162F, + 0.6583415117F, 0.6592446769F, 0.6601470079F, 0.6610485009F, + 0.6619491521F, 0.6628489578F, 0.6637479143F, 0.6646460177F, + 0.6655432643F, 0.6664396505F, 0.6673351724F, 0.6682298264F, + 0.6691236087F, 0.6700165157F, 0.6709085436F, 0.6717996889F, + 0.6726899478F, 0.6735793167F, 0.6744677918F, 0.6753553697F, + 0.6762420466F, 0.6771278190F, 0.6780126832F, 0.6788966357F, + 0.6797796728F, 0.6806617909F, 0.6815429866F, 0.6824232562F, + 0.6833025961F, 0.6841810030F, 0.6850584731F, 0.6859350031F, + 0.6868105894F, 0.6876852284F, 0.6885589168F, 0.6894316510F, + 0.6903034275F, 0.6911742430F, 0.6920440939F, 0.6929129769F, + 0.6937808884F, 0.6946478251F, 0.6955137837F, 0.6963787606F, + 0.6972427525F, 0.6981057560F, 0.6989677678F, 0.6998287845F, + 0.7006888028F, 0.7015478194F, 0.7024058309F, 0.7032628340F, + 0.7041188254F, 0.7049738019F, 0.7058277601F, 0.7066806969F, + 0.7075326089F, 0.7083834929F, 0.7092333457F, 0.7100821640F, + 0.7109299447F, 0.7117766846F, 0.7126223804F, 0.7134670291F, + 0.7143106273F, 0.7151531721F, 0.7159946602F, 0.7168350885F, + 0.7176744539F, 0.7185127534F, 0.7193499837F, 0.7201861418F, + 0.7210212247F, 0.7218552293F, 0.7226881526F, 0.7235199914F, + 0.7243507428F, 0.7251804039F, 0.7260089715F, 0.7268364426F, + 0.7276628144F, 0.7284880839F, 0.7293122481F, 0.7301353040F, + 0.7309572487F, 0.7317780794F, 0.7325977930F, 0.7334163868F, + 0.7342338579F, 0.7350502033F, 0.7358654202F, 0.7366795059F, + 0.7374924573F, 0.7383042718F, 0.7391149465F, 0.7399244787F, + 0.7407328655F, 0.7415401041F, 0.7423461920F, 0.7431511261F, + 0.7439549040F, 0.7447575227F, 0.7455589797F, 0.7463592723F, + 0.7471583976F, 0.7479563532F, 0.7487531363F, 0.7495487443F, + 0.7503431745F, 0.7511364244F, 0.7519284913F, 0.7527193726F, + 0.7535090658F, 0.7542975683F, 0.7550848776F, 0.7558709910F, + 0.7566559062F, 0.7574396205F, 0.7582221314F, 0.7590034366F, + 0.7597835334F, 0.7605624194F, 0.7613400923F, 0.7621165495F, + 0.7628917886F, 0.7636658072F, 0.7644386030F, 0.7652101735F, + 0.7659805164F, 0.7667496292F, 0.7675175098F, 0.7682841556F, + 0.7690495645F, 0.7698137341F, 0.7705766622F, 0.7713383463F, + 0.7720987844F, 0.7728579741F, 0.7736159132F, 0.7743725994F, + 0.7751280306F, 0.7758822046F, 0.7766351192F, 0.7773867722F, + 0.7781371614F, 0.7788862848F, 0.7796341401F, 0.7803807253F, + 0.7811260383F, 0.7818700769F, 0.7826128392F, 0.7833543230F, + 0.7840945263F, 0.7848334471F, 0.7855710833F, 0.7863074330F, + 0.7870424941F, 0.7877762647F, 0.7885087428F, 0.7892399264F, + 0.7899698137F, 0.7906984026F, 0.7914256914F, 0.7921516780F, + 0.7928763607F, 0.7935997375F, 0.7943218065F, 0.7950425661F, + 0.7957620142F, 0.7964801492F, 0.7971969692F, 0.7979124724F, + 0.7986266570F, 0.7993395214F, 0.8000510638F, 0.8007612823F, + 0.8014701754F, 0.8021777413F, 0.8028839784F, 0.8035888849F, + 0.8042924592F, 0.8049946997F, 0.8056956048F, 0.8063951727F, + 0.8070934020F, 0.8077902910F, 0.8084858381F, 0.8091800419F, + 0.8098729007F, 0.8105644130F, 0.8112545774F, 0.8119433922F, + 0.8126308561F, 0.8133169676F, 0.8140017251F, 0.8146851272F, + 0.8153671726F, 0.8160478598F, 0.8167271874F, 0.8174051539F, + 0.8180817582F, 0.8187569986F, 0.8194308741F, 0.8201033831F, + 0.8207745244F, 0.8214442966F, 0.8221126986F, 0.8227797290F, + 0.8234453865F, 0.8241096700F, 0.8247725781F, 0.8254341097F, + 0.8260942636F, 0.8267530385F, 0.8274104334F, 0.8280664470F, + 0.8287210782F, 0.8293743259F, 0.8300261889F, 0.8306766662F, + 0.8313257566F, 0.8319734591F, 0.8326197727F, 0.8332646963F, + 0.8339082288F, 0.8345503692F, 0.8351911167F, 0.8358304700F, + 0.8364684284F, 0.8371049907F, 0.8377401562F, 0.8383739238F, + 0.8390062927F, 0.8396372618F, 0.8402668305F, 0.8408949977F, + 0.8415217626F, 0.8421471245F, 0.8427710823F, 0.8433936354F, + 0.8440147830F, 0.8446345242F, 0.8452528582F, 0.8458697844F, + 0.8464853020F, 0.8470994102F, 0.8477121084F, 0.8483233958F, + 0.8489332718F, 0.8495417356F, 0.8501487866F, 0.8507544243F, + 0.8513586479F, 0.8519614568F, 0.8525628505F, 0.8531628283F, + 0.8537613897F, 0.8543585341F, 0.8549542611F, 0.8555485699F, + 0.8561414603F, 0.8567329315F, 0.8573229832F, 0.8579116149F, + 0.8584988262F, 0.8590846165F, 0.8596689855F, 0.8602519327F, + 0.8608334577F, 0.8614135603F, 0.8619922399F, 0.8625694962F, + 0.8631453289F, 0.8637197377F, 0.8642927222F, 0.8648642821F, + 0.8654344172F, 0.8660031272F, 0.8665704118F, 0.8671362708F, + 0.8677007039F, 0.8682637109F, 0.8688252917F, 0.8693854460F, + 0.8699441737F, 0.8705014745F, 0.8710573485F, 0.8716117953F, + 0.8721648150F, 0.8727164073F, 0.8732665723F, 0.8738153098F, + 0.8743626197F, 0.8749085021F, 0.8754529569F, 0.8759959840F, + 0.8765375835F, 0.8770777553F, 0.8776164996F, 0.8781538162F, + 0.8786897054F, 0.8792241670F, 0.8797572013F, 0.8802888082F, + 0.8808189880F, 0.8813477407F, 0.8818750664F, 0.8824009653F, + 0.8829254375F, 0.8834484833F, 0.8839701028F, 0.8844902961F, + 0.8850090636F, 0.8855264054F, 0.8860423218F, 0.8865568131F, + 0.8870698794F, 0.8875815212F, 0.8880917386F, 0.8886005319F, + 0.8891079016F, 0.8896138479F, 0.8901183712F, 0.8906214719F, + 0.8911231503F, 0.8916234067F, 0.8921222417F, 0.8926196556F, + 0.8931156489F, 0.8936102219F, 0.8941033752F, 0.8945951092F, + 0.8950854244F, 0.8955743212F, 0.8960618003F, 0.8965478621F, + 0.8970325071F, 0.8975157359F, 0.8979975490F, 0.8984779471F, + 0.8989569307F, 0.8994345004F, 0.8999106568F, 0.9003854005F, + 0.9008587323F, 0.9013306526F, 0.9018011623F, 0.9022702619F, + 0.9027379521F, 0.9032042337F, 0.9036691074F, 0.9041325739F, + 0.9045946339F, 0.9050552882F, 0.9055145376F, 0.9059723828F, + 0.9064288246F, 0.9068838638F, 0.9073375013F, 0.9077897379F, + 0.9082405743F, 0.9086900115F, 0.9091380503F, 0.9095846917F, + 0.9100299364F, 0.9104737854F, 0.9109162397F, 0.9113573001F, + 0.9117969675F, 0.9122352430F, 0.9126721275F, 0.9131076219F, + 0.9135417273F, 0.9139744447F, 0.9144057750F, 0.9148357194F, + 0.9152642787F, 0.9156914542F, 0.9161172468F, 0.9165416576F, + 0.9169646877F, 0.9173863382F, 0.9178066102F, 0.9182255048F, + 0.9186430232F, 0.9190591665F, 0.9194739359F, 0.9198873324F, + 0.9202993574F, 0.9207100120F, 0.9211192973F, 0.9215272147F, + 0.9219337653F, 0.9223389504F, 0.9227427713F, 0.9231452290F, + 0.9235463251F, 0.9239460607F, 0.9243444371F, 0.9247414557F, + 0.9251371177F, 0.9255314245F, 0.9259243774F, 0.9263159778F, + 0.9267062270F, 0.9270951264F, 0.9274826774F, 0.9278688814F, + 0.9282537398F, 0.9286372540F, 0.9290194254F, 0.9294002555F, + 0.9297797458F, 0.9301578976F, 0.9305347125F, 0.9309101919F, + 0.9312843373F, 0.9316571503F, 0.9320286323F, 0.9323987849F, + 0.9327676097F, 0.9331351080F, 0.9335012816F, 0.9338661320F, + 0.9342296607F, 0.9345918694F, 0.9349527596F, 0.9353123330F, + 0.9356705911F, 0.9360275357F, 0.9363831683F, 0.9367374905F, + 0.9370905042F, 0.9374422108F, 0.9377926122F, 0.9381417099F, + 0.9384895057F, 0.9388360014F, 0.9391811985F, 0.9395250989F, + 0.9398677043F, 0.9402090165F, 0.9405490371F, 0.9408877680F, + 0.9412252110F, 0.9415613678F, 0.9418962402F, 0.9422298301F, + 0.9425621392F, 0.9428931695F, 0.9432229226F, 0.9435514005F, + 0.9438786050F, 0.9442045381F, 0.9445292014F, 0.9448525971F, + 0.9451747268F, 0.9454955926F, 0.9458151963F, 0.9461335399F, + 0.9464506253F, 0.9467664545F, 0.9470810293F, 0.9473943517F, + 0.9477064238F, 0.9480172474F, 0.9483268246F, 0.9486351573F, + 0.9489422475F, 0.9492480973F, 0.9495527087F, 0.9498560837F, + 0.9501582243F, 0.9504591325F, 0.9507588105F, 0.9510572603F, + 0.9513544839F, 0.9516504834F, 0.9519452609F, 0.9522388186F, + 0.9525311584F, 0.9528222826F, 0.9531121932F, 0.9534008923F, + 0.9536883821F, 0.9539746647F, 0.9542597424F, 0.9545436171F, + 0.9548262912F, 0.9551077667F, 0.9553880459F, 0.9556671309F, + 0.9559450239F, 0.9562217272F, 0.9564972429F, 0.9567715733F, + 0.9570447206F, 0.9573166871F, 0.9575874749F, 0.9578570863F, + 0.9581255236F, 0.9583927890F, 0.9586588849F, 0.9589238134F, + 0.9591875769F, 0.9594501777F, 0.9597116180F, 0.9599719003F, + 0.9602310267F, 0.9604889995F, 0.9607458213F, 0.9610014942F, + 0.9612560206F, 0.9615094028F, 0.9617616433F, 0.9620127443F, + 0.9622627083F, 0.9625115376F, 0.9627592345F, 0.9630058016F, + 0.9632512411F, 0.9634955555F, 0.9637387471F, 0.9639808185F, + 0.9642217720F, 0.9644616100F, 0.9647003349F, 0.9649379493F, + 0.9651744556F, 0.9654098561F, 0.9656441534F, 0.9658773499F, + 0.9661094480F, 0.9663404504F, 0.9665703593F, 0.9667991774F, + 0.9670269071F, 0.9672535509F, 0.9674791114F, 0.9677035909F, + 0.9679269921F, 0.9681493174F, 0.9683705694F, 0.9685907506F, + 0.9688098636F, 0.9690279108F, 0.9692448948F, 0.9694608182F, + 0.9696756836F, 0.9698894934F, 0.9701022503F, 0.9703139569F, + 0.9705246156F, 0.9707342291F, 0.9709428000F, 0.9711503309F, + 0.9713568243F, 0.9715622829F, 0.9717667093F, 0.9719701060F, + 0.9721724757F, 0.9723738210F, 0.9725741446F, 0.9727734490F, + 0.9729717369F, 0.9731690109F, 0.9733652737F, 0.9735605279F, + 0.9737547762F, 0.9739480212F, 0.9741402656F, 0.9743315120F, + 0.9745217631F, 0.9747110216F, 0.9748992901F, 0.9750865714F, + 0.9752728681F, 0.9754581829F, 0.9756425184F, 0.9758258775F, + 0.9760082627F, 0.9761896768F, 0.9763701224F, 0.9765496024F, + 0.9767281193F, 0.9769056760F, 0.9770822751F, 0.9772579193F, + 0.9774326114F, 0.9776063542F, 0.9777791502F, 0.9779510023F, + 0.9781219133F, 0.9782918858F, 0.9784609226F, 0.9786290264F, + 0.9787962000F, 0.9789624461F, 0.9791277676F, 0.9792921671F, + 0.9794556474F, 0.9796182113F, 0.9797798615F, 0.9799406009F, + 0.9801004321F, 0.9802593580F, 0.9804173813F, 0.9805745049F, + 0.9807307314F, 0.9808860637F, 0.9810405046F, 0.9811940568F, + 0.9813467232F, 0.9814985065F, 0.9816494095F, 0.9817994351F, + 0.9819485860F, 0.9820968650F, 0.9822442750F, 0.9823908186F, + 0.9825364988F, 0.9826813184F, 0.9828252801F, 0.9829683868F, + 0.9831106413F, 0.9832520463F, 0.9833926048F, 0.9835323195F, + 0.9836711932F, 0.9838092288F, 0.9839464291F, 0.9840827969F, + 0.9842183351F, 0.9843530464F, 0.9844869337F, 0.9846199998F, + 0.9847522475F, 0.9848836798F, 0.9850142993F, 0.9851441090F, + 0.9852731117F, 0.9854013101F, 0.9855287073F, 0.9856553058F, + 0.9857811087F, 0.9859061188F, 0.9860303388F, 0.9861537717F, + 0.9862764202F, 0.9863982872F, 0.9865193756F, 0.9866396882F, + 0.9867592277F, 0.9868779972F, 0.9869959993F, 0.9871132370F, + 0.9872297131F, 0.9873454304F, 0.9874603918F, 0.9875746001F, + 0.9876880581F, 0.9878007688F, 0.9879127348F, 0.9880239592F, + 0.9881344447F, 0.9882441941F, 0.9883532104F, 0.9884614962F, + 0.9885690546F, 0.9886758883F, 0.9887820001F, 0.9888873930F, + 0.9889920697F, 0.9890960331F, 0.9891992859F, 0.9893018312F, + 0.9894036716F, 0.9895048100F, 0.9896052493F, 0.9897049923F, + 0.9898040418F, 0.9899024006F, 0.9900000717F, 0.9900970577F, + 0.9901933616F, 0.9902889862F, 0.9903839343F, 0.9904782087F, + 0.9905718122F, 0.9906647477F, 0.9907570180F, 0.9908486259F, + 0.9909395742F, 0.9910298658F, 0.9911195034F, 0.9912084899F, + 0.9912968281F, 0.9913845208F, 0.9914715708F, 0.9915579810F, + 0.9916437540F, 0.9917288928F, 0.9918134001F, 0.9918972788F, + 0.9919805316F, 0.9920631613F, 0.9921451707F, 0.9922265626F, + 0.9923073399F, 0.9923875052F, 0.9924670615F, 0.9925460114F, + 0.9926243577F, 0.9927021033F, 0.9927792508F, 0.9928558032F, + 0.9929317631F, 0.9930071333F, 0.9930819167F, 0.9931561158F, + 0.9932297337F, 0.9933027728F, 0.9933752362F, 0.9934471264F, + 0.9935184462F, 0.9935891985F, 0.9936593859F, 0.9937290112F, + 0.9937980771F, 0.9938665864F, 0.9939345418F, 0.9940019460F, + 0.9940688018F, 0.9941351118F, 0.9942008789F, 0.9942661057F, + 0.9943307950F, 0.9943949494F, 0.9944585717F, 0.9945216645F, + 0.9945842307F, 0.9946462728F, 0.9947077936F, 0.9947687957F, + 0.9948292820F, 0.9948892550F, 0.9949487174F, 0.9950076719F, + 0.9950661212F, 0.9951240679F, 0.9951815148F, 0.9952384645F, + 0.9952949196F, 0.9953508828F, 0.9954063568F, 0.9954613442F, + 0.9955158476F, 0.9955698697F, 0.9956234132F, 0.9956764806F, + 0.9957290746F, 0.9957811978F, 0.9958328528F, 0.9958840423F, + 0.9959347688F, 0.9959850351F, 0.9960348435F, 0.9960841969F, + 0.9961330977F, 0.9961815486F, 0.9962295521F, 0.9962771108F, + 0.9963242274F, 0.9963709043F, 0.9964171441F, 0.9964629494F, + 0.9965083228F, 0.9965532668F, 0.9965977840F, 0.9966418768F, + 0.9966855479F, 0.9967287998F, 0.9967716350F, 0.9968140559F, + 0.9968560653F, 0.9968976655F, 0.9969388591F, 0.9969796485F, + 0.9970200363F, 0.9970600250F, 0.9970996170F, 0.9971388149F, + 0.9971776211F, 0.9972160380F, 0.9972540683F, 0.9972917142F, + 0.9973289783F, 0.9973658631F, 0.9974023709F, 0.9974385042F, + 0.9974742655F, 0.9975096571F, 0.9975446816F, 0.9975793413F, + 0.9976136386F, 0.9976475759F, 0.9976811557F, 0.9977143803F, + 0.9977472521F, 0.9977797736F, 0.9978119470F, 0.9978437748F, + 0.9978752593F, 0.9979064029F, 0.9979372079F, 0.9979676768F, + 0.9979978117F, 0.9980276151F, 0.9980570893F, 0.9980862367F, + 0.9981150595F, 0.9981435600F, 0.9981717406F, 0.9981996035F, + 0.9982271511F, 0.9982543856F, 0.9982813093F, 0.9983079246F, + 0.9983342336F, 0.9983602386F, 0.9983859418F, 0.9984113456F, + 0.9984364522F, 0.9984612638F, 0.9984857825F, 0.9985100108F, + 0.9985339507F, 0.9985576044F, 0.9985809743F, 0.9986040624F, + 0.9986268710F, 0.9986494022F, 0.9986716583F, 0.9986936413F, + 0.9987153535F, 0.9987367969F, 0.9987579738F, 0.9987788864F, + 0.9987995366F, 0.9988199267F, 0.9988400587F, 0.9988599348F, + 0.9988795572F, 0.9988989278F, 0.9989180487F, 0.9989369222F, + 0.9989555501F, 0.9989739347F, 0.9989920780F, 0.9990099820F, + 0.9990276487F, 0.9990450803F, 0.9990622787F, 0.9990792460F, + 0.9990959841F, 0.9991124952F, 0.9991287812F, 0.9991448440F, + 0.9991606858F, 0.9991763084F, 0.9991917139F, 0.9992069042F, + 0.9992218813F, 0.9992366471F, 0.9992512035F, 0.9992655525F, + 0.9992796961F, 0.9992936361F, 0.9993073744F, 0.9993209131F, + 0.9993342538F, 0.9993473987F, 0.9993603494F, 0.9993731080F, + 0.9993856762F, 0.9993980559F, 0.9994102490F, 0.9994222573F, + 0.9994340827F, 0.9994457269F, 0.9994571918F, 0.9994684793F, + 0.9994795910F, 0.9994905288F, 0.9995012945F, 0.9995118898F, + 0.9995223165F, 0.9995325765F, 0.9995426713F, 0.9995526029F, + 0.9995623728F, 0.9995719829F, 0.9995814349F, 0.9995907304F, + 0.9995998712F, 0.9996088590F, 0.9996176954F, 0.9996263821F, + 0.9996349208F, 0.9996433132F, 0.9996515609F, 0.9996596656F, + 0.9996676288F, 0.9996754522F, 0.9996831375F, 0.9996906862F, + 0.9996981000F, 0.9997053804F, 0.9997125290F, 0.9997195474F, + 0.9997264371F, 0.9997331998F, 0.9997398369F, 0.9997463500F, + 0.9997527406F, 0.9997590103F, 0.9997651606F, 0.9997711930F, + 0.9997771089F, 0.9997829098F, 0.9997885973F, 0.9997941728F, + 0.9997996378F, 0.9998049936F, 0.9998102419F, 0.9998153839F, + 0.9998204211F, 0.9998253550F, 0.9998301868F, 0.9998349182F, + 0.9998395503F, 0.9998440847F, 0.9998485226F, 0.9998528654F, + 0.9998571146F, 0.9998612713F, 0.9998653370F, 0.9998693130F, + 0.9998732007F, 0.9998770012F, 0.9998807159F, 0.9998843461F, + 0.9998878931F, 0.9998913581F, 0.9998947424F, 0.9998980473F, + 0.9999012740F, 0.9999044237F, 0.9999074976F, 0.9999104971F, + 0.9999134231F, 0.9999162771F, 0.9999190601F, 0.9999217733F, + 0.9999244179F, 0.9999269950F, 0.9999295058F, 0.9999319515F, + 0.9999343332F, 0.9999366519F, 0.9999389088F, 0.9999411050F, + 0.9999432416F, 0.9999453196F, 0.9999473402F, 0.9999493044F, + 0.9999512132F, 0.9999530677F, 0.9999548690F, 0.9999566180F, + 0.9999583157F, 0.9999599633F, 0.9999615616F, 0.9999631116F, + 0.9999646144F, 0.9999660709F, 0.9999674820F, 0.9999688487F, + 0.9999701719F, 0.9999714526F, 0.9999726917F, 0.9999738900F, + 0.9999750486F, 0.9999761682F, 0.9999772497F, 0.9999782941F, + 0.9999793021F, 0.9999802747F, 0.9999812126F, 0.9999821167F, + 0.9999829878F, 0.9999838268F, 0.9999846343F, 0.9999854113F, + 0.9999861584F, 0.9999868765F, 0.9999875664F, 0.9999882287F, + 0.9999888642F, 0.9999894736F, 0.9999900577F, 0.9999906172F, + 0.9999911528F, 0.9999916651F, 0.9999921548F, 0.9999926227F, + 0.9999930693F, 0.9999934954F, 0.9999939015F, 0.9999942883F, + 0.9999946564F, 0.9999950064F, 0.9999953390F, 0.9999956547F, + 0.9999959541F, 0.9999962377F, 0.9999965062F, 0.9999967601F, + 0.9999969998F, 0.9999972260F, 0.9999974392F, 0.9999976399F, + 0.9999978285F, 0.9999980056F, 0.9999981716F, 0.9999983271F, + 0.9999984724F, 0.9999986081F, 0.9999987345F, 0.9999988521F, + 0.9999989613F, 0.9999990625F, 0.9999991562F, 0.9999992426F, + 0.9999993223F, 0.9999993954F, 0.9999994625F, 0.9999995239F, + 0.9999995798F, 0.9999996307F, 0.9999996768F, 0.9999997184F, + 0.9999997559F, 0.9999997895F, 0.9999998195F, 0.9999998462F, + 0.9999998698F, 0.9999998906F, 0.9999999088F, 0.9999999246F, + 0.9999999383F, 0.9999999500F, 0.9999999600F, 0.9999999684F, + 0.9999999754F, 0.9999999811F, 0.9999999858F, 0.9999999896F, + 0.9999999925F, 0.9999999948F, 0.9999999965F, 0.9999999978F, + 0.9999999986F, 0.9999999992F, 0.9999999996F, 0.9999999998F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +static const float vwin8192[4096] = { + 0.0000000578F, 0.0000005198F, 0.0000014438F, 0.0000028299F, + 0.0000046780F, 0.0000069882F, 0.0000097604F, 0.0000129945F, + 0.0000166908F, 0.0000208490F, 0.0000254692F, 0.0000305515F, + 0.0000360958F, 0.0000421021F, 0.0000485704F, 0.0000555006F, + 0.0000628929F, 0.0000707472F, 0.0000790635F, 0.0000878417F, + 0.0000970820F, 0.0001067842F, 0.0001169483F, 0.0001275744F, + 0.0001386625F, 0.0001502126F, 0.0001622245F, 0.0001746984F, + 0.0001876343F, 0.0002010320F, 0.0002148917F, 0.0002292132F, + 0.0002439967F, 0.0002592421F, 0.0002749493F, 0.0002911184F, + 0.0003077493F, 0.0003248421F, 0.0003423967F, 0.0003604132F, + 0.0003788915F, 0.0003978316F, 0.0004172335F, 0.0004370971F, + 0.0004574226F, 0.0004782098F, 0.0004994587F, 0.0005211694F, + 0.0005433418F, 0.0005659759F, 0.0005890717F, 0.0006126292F, + 0.0006366484F, 0.0006611292F, 0.0006860716F, 0.0007114757F, + 0.0007373414F, 0.0007636687F, 0.0007904576F, 0.0008177080F, + 0.0008454200F, 0.0008735935F, 0.0009022285F, 0.0009313250F, + 0.0009608830F, 0.0009909025F, 0.0010213834F, 0.0010523257F, + 0.0010837295F, 0.0011155946F, 0.0011479211F, 0.0011807090F, + 0.0012139582F, 0.0012476687F, 0.0012818405F, 0.0013164736F, + 0.0013515679F, 0.0013871235F, 0.0014231402F, 0.0014596182F, + 0.0014965573F, 0.0015339576F, 0.0015718190F, 0.0016101415F, + 0.0016489251F, 0.0016881698F, 0.0017278754F, 0.0017680421F, + 0.0018086698F, 0.0018497584F, 0.0018913080F, 0.0019333185F, + 0.0019757898F, 0.0020187221F, 0.0020621151F, 0.0021059690F, + 0.0021502837F, 0.0021950591F, 0.0022402953F, 0.0022859921F, + 0.0023321497F, 0.0023787679F, 0.0024258467F, 0.0024733861F, + 0.0025213861F, 0.0025698466F, 0.0026187676F, 0.0026681491F, + 0.0027179911F, 0.0027682935F, 0.0028190562F, 0.0028702794F, + 0.0029219628F, 0.0029741066F, 0.0030267107F, 0.0030797749F, + 0.0031332994F, 0.0031872841F, 0.0032417289F, 0.0032966338F, + 0.0033519988F, 0.0034078238F, 0.0034641089F, 0.0035208539F, + 0.0035780589F, 0.0036357237F, 0.0036938485F, 0.0037524331F, + 0.0038114775F, 0.0038709817F, 0.0039309456F, 0.0039913692F, + 0.0040522524F, 0.0041135953F, 0.0041753978F, 0.0042376599F, + 0.0043003814F, 0.0043635624F, 0.0044272029F, 0.0044913028F, + 0.0045558620F, 0.0046208806F, 0.0046863585F, 0.0047522955F, + 0.0048186919F, 0.0048855473F, 0.0049528619F, 0.0050206356F, + 0.0050888684F, 0.0051575601F, 0.0052267108F, 0.0052963204F, + 0.0053663890F, 0.0054369163F, 0.0055079025F, 0.0055793474F, + 0.0056512510F, 0.0057236133F, 0.0057964342F, 0.0058697137F, + 0.0059434517F, 0.0060176482F, 0.0060923032F, 0.0061674166F, + 0.0062429883F, 0.0063190183F, 0.0063955066F, 0.0064724532F, + 0.0065498579F, 0.0066277207F, 0.0067060416F, 0.0067848205F, + 0.0068640575F, 0.0069437523F, 0.0070239051F, 0.0071045157F, + 0.0071855840F, 0.0072671102F, 0.0073490940F, 0.0074315355F, + 0.0075144345F, 0.0075977911F, 0.0076816052F, 0.0077658768F, + 0.0078506057F, 0.0079357920F, 0.0080214355F, 0.0081075363F, + 0.0081940943F, 0.0082811094F, 0.0083685816F, 0.0084565108F, + 0.0085448970F, 0.0086337401F, 0.0087230401F, 0.0088127969F, + 0.0089030104F, 0.0089936807F, 0.0090848076F, 0.0091763911F, + 0.0092684311F, 0.0093609276F, 0.0094538805F, 0.0095472898F, + 0.0096411554F, 0.0097354772F, 0.0098302552F, 0.0099254894F, + 0.0100211796F, 0.0101173259F, 0.0102139281F, 0.0103109863F, + 0.0104085002F, 0.0105064700F, 0.0106048955F, 0.0107037766F, + 0.0108031133F, 0.0109029056F, 0.0110031534F, 0.0111038565F, + 0.0112050151F, 0.0113066289F, 0.0114086980F, 0.0115112222F, + 0.0116142015F, 0.0117176359F, 0.0118215252F, 0.0119258695F, + 0.0120306686F, 0.0121359225F, 0.0122416312F, 0.0123477944F, + 0.0124544123F, 0.0125614847F, 0.0126690116F, 0.0127769928F, + 0.0128854284F, 0.0129943182F, 0.0131036623F, 0.0132134604F, + 0.0133237126F, 0.0134344188F, 0.0135455790F, 0.0136571929F, + 0.0137692607F, 0.0138817821F, 0.0139947572F, 0.0141081859F, + 0.0142220681F, 0.0143364037F, 0.0144511927F, 0.0145664350F, + 0.0146821304F, 0.0147982791F, 0.0149148808F, 0.0150319355F, + 0.0151494431F, 0.0152674036F, 0.0153858168F, 0.0155046828F, + 0.0156240014F, 0.0157437726F, 0.0158639962F, 0.0159846723F, + 0.0161058007F, 0.0162273814F, 0.0163494142F, 0.0164718991F, + 0.0165948361F, 0.0167182250F, 0.0168420658F, 0.0169663584F, + 0.0170911027F, 0.0172162987F, 0.0173419462F, 0.0174680452F, + 0.0175945956F, 0.0177215974F, 0.0178490504F, 0.0179769545F, + 0.0181053098F, 0.0182341160F, 0.0183633732F, 0.0184930812F, + 0.0186232399F, 0.0187538494F, 0.0188849094F, 0.0190164200F, + 0.0191483809F, 0.0192807923F, 0.0194136539F, 0.0195469656F, + 0.0196807275F, 0.0198149394F, 0.0199496012F, 0.0200847128F, + 0.0202202742F, 0.0203562853F, 0.0204927460F, 0.0206296561F, + 0.0207670157F, 0.0209048245F, 0.0210430826F, 0.0211817899F, + 0.0213209462F, 0.0214605515F, 0.0216006057F, 0.0217411086F, + 0.0218820603F, 0.0220234605F, 0.0221653093F, 0.0223076066F, + 0.0224503521F, 0.0225935459F, 0.0227371879F, 0.0228812779F, + 0.0230258160F, 0.0231708018F, 0.0233162355F, 0.0234621169F, + 0.0236084459F, 0.0237552224F, 0.0239024462F, 0.0240501175F, + 0.0241982359F, 0.0243468015F, 0.0244958141F, 0.0246452736F, + 0.0247951800F, 0.0249455331F, 0.0250963329F, 0.0252475792F, + 0.0253992720F, 0.0255514111F, 0.0257039965F, 0.0258570281F, + 0.0260105057F, 0.0261644293F, 0.0263187987F, 0.0264736139F, + 0.0266288747F, 0.0267845811F, 0.0269407330F, 0.0270973302F, + 0.0272543727F, 0.0274118604F, 0.0275697930F, 0.0277281707F, + 0.0278869932F, 0.0280462604F, 0.0282059723F, 0.0283661287F, + 0.0285267295F, 0.0286877747F, 0.0288492641F, 0.0290111976F, + 0.0291735751F, 0.0293363965F, 0.0294996617F, 0.0296633706F, + 0.0298275231F, 0.0299921190F, 0.0301571583F, 0.0303226409F, + 0.0304885667F, 0.0306549354F, 0.0308217472F, 0.0309890017F, + 0.0311566989F, 0.0313248388F, 0.0314934211F, 0.0316624459F, + 0.0318319128F, 0.0320018220F, 0.0321721732F, 0.0323429663F, + 0.0325142013F, 0.0326858779F, 0.0328579962F, 0.0330305559F, + 0.0332035570F, 0.0333769994F, 0.0335508829F, 0.0337252074F, + 0.0338999728F, 0.0340751790F, 0.0342508259F, 0.0344269134F, + 0.0346034412F, 0.0347804094F, 0.0349578178F, 0.0351356663F, + 0.0353139548F, 0.0354926831F, 0.0356718511F, 0.0358514588F, + 0.0360315059F, 0.0362119924F, 0.0363929182F, 0.0365742831F, + 0.0367560870F, 0.0369383297F, 0.0371210113F, 0.0373041315F, + 0.0374876902F, 0.0376716873F, 0.0378561226F, 0.0380409961F, + 0.0382263077F, 0.0384120571F, 0.0385982443F, 0.0387848691F, + 0.0389719315F, 0.0391594313F, 0.0393473683F, 0.0395357425F, + 0.0397245537F, 0.0399138017F, 0.0401034866F, 0.0402936080F, + 0.0404841660F, 0.0406751603F, 0.0408665909F, 0.0410584576F, + 0.0412507603F, 0.0414434988F, 0.0416366731F, 0.0418302829F, + 0.0420243282F, 0.0422188088F, 0.0424137246F, 0.0426090755F, + 0.0428048613F, 0.0430010819F, 0.0431977371F, 0.0433948269F, + 0.0435923511F, 0.0437903095F, 0.0439887020F, 0.0441875285F, + 0.0443867889F, 0.0445864830F, 0.0447866106F, 0.0449871717F, + 0.0451881661F, 0.0453895936F, 0.0455914542F, 0.0457937477F, + 0.0459964738F, 0.0461996326F, 0.0464032239F, 0.0466072475F, + 0.0468117032F, 0.0470165910F, 0.0472219107F, 0.0474276622F, + 0.0476338452F, 0.0478404597F, 0.0480475056F, 0.0482549827F, + 0.0484628907F, 0.0486712297F, 0.0488799994F, 0.0490891998F, + 0.0492988306F, 0.0495088917F, 0.0497193830F, 0.0499303043F, + 0.0501416554F, 0.0503534363F, 0.0505656468F, 0.0507782867F, + 0.0509913559F, 0.0512048542F, 0.0514187815F, 0.0516331376F, + 0.0518479225F, 0.0520631358F, 0.0522787775F, 0.0524948475F, + 0.0527113455F, 0.0529282715F, 0.0531456252F, 0.0533634066F, + 0.0535816154F, 0.0538002515F, 0.0540193148F, 0.0542388051F, + 0.0544587222F, 0.0546790660F, 0.0548998364F, 0.0551210331F, + 0.0553426561F, 0.0555647051F, 0.0557871801F, 0.0560100807F, + 0.0562334070F, 0.0564571587F, 0.0566813357F, 0.0569059378F, + 0.0571309649F, 0.0573564168F, 0.0575822933F, 0.0578085942F, + 0.0580353195F, 0.0582624689F, 0.0584900423F, 0.0587180396F, + 0.0589464605F, 0.0591753049F, 0.0594045726F, 0.0596342635F, + 0.0598643774F, 0.0600949141F, 0.0603258735F, 0.0605572555F, + 0.0607890597F, 0.0610212862F, 0.0612539346F, 0.0614870049F, + 0.0617204968F, 0.0619544103F, 0.0621887451F, 0.0624235010F, + 0.0626586780F, 0.0628942758F, 0.0631302942F, 0.0633667331F, + 0.0636035923F, 0.0638408717F, 0.0640785710F, 0.0643166901F, + 0.0645552288F, 0.0647941870F, 0.0650335645F, 0.0652733610F, + 0.0655135765F, 0.0657542108F, 0.0659952636F, 0.0662367348F, + 0.0664786242F, 0.0667209316F, 0.0669636570F, 0.0672068000F, + 0.0674503605F, 0.0676943384F, 0.0679387334F, 0.0681835454F, + 0.0684287742F, 0.0686744196F, 0.0689204814F, 0.0691669595F, + 0.0694138536F, 0.0696611637F, 0.0699088894F, 0.0701570307F, + 0.0704055873F, 0.0706545590F, 0.0709039458F, 0.0711537473F, + 0.0714039634F, 0.0716545939F, 0.0719056387F, 0.0721570975F, + 0.0724089702F, 0.0726612565F, 0.0729139563F, 0.0731670694F, + 0.0734205956F, 0.0736745347F, 0.0739288866F, 0.0741836510F, + 0.0744388277F, 0.0746944166F, 0.0749504175F, 0.0752068301F, + 0.0754636543F, 0.0757208899F, 0.0759785367F, 0.0762365946F, + 0.0764950632F, 0.0767539424F, 0.0770132320F, 0.0772729319F, + 0.0775330418F, 0.0777935616F, 0.0780544909F, 0.0783158298F, + 0.0785775778F, 0.0788397349F, 0.0791023009F, 0.0793652755F, + 0.0796286585F, 0.0798924498F, 0.0801566492F, 0.0804212564F, + 0.0806862712F, 0.0809516935F, 0.0812175231F, 0.0814837597F, + 0.0817504031F, 0.0820174532F, 0.0822849097F, 0.0825527724F, + 0.0828210412F, 0.0830897158F, 0.0833587960F, 0.0836282816F, + 0.0838981724F, 0.0841684682F, 0.0844391688F, 0.0847102740F, + 0.0849817835F, 0.0852536973F, 0.0855260150F, 0.0857987364F, + 0.0860718614F, 0.0863453897F, 0.0866193211F, 0.0868936554F, + 0.0871683924F, 0.0874435319F, 0.0877190737F, 0.0879950175F, + 0.0882713632F, 0.0885481105F, 0.0888252592F, 0.0891028091F, + 0.0893807600F, 0.0896591117F, 0.0899378639F, 0.0902170165F, + 0.0904965692F, 0.0907765218F, 0.0910568740F, 0.0913376258F, + 0.0916187767F, 0.0919003268F, 0.0921822756F, 0.0924646230F, + 0.0927473687F, 0.0930305126F, 0.0933140545F, 0.0935979940F, + 0.0938823310F, 0.0941670653F, 0.0944521966F, 0.0947377247F, + 0.0950236494F, 0.0953099704F, 0.0955966876F, 0.0958838007F, + 0.0961713094F, 0.0964592136F, 0.0967475131F, 0.0970362075F, + 0.0973252967F, 0.0976147805F, 0.0979046585F, 0.0981949307F, + 0.0984855967F, 0.0987766563F, 0.0990681093F, 0.0993599555F, + 0.0996521945F, 0.0999448263F, 0.1002378506F, 0.1005312671F, + 0.1008250755F, 0.1011192757F, 0.1014138675F, 0.1017088505F, + 0.1020042246F, 0.1022999895F, 0.1025961450F, 0.1028926909F, + 0.1031896268F, 0.1034869526F, 0.1037846680F, 0.1040827729F, + 0.1043812668F, 0.1046801497F, 0.1049794213F, 0.1052790813F, + 0.1055791294F, 0.1058795656F, 0.1061803894F, 0.1064816006F, + 0.1067831991F, 0.1070851846F, 0.1073875568F, 0.1076903155F, + 0.1079934604F, 0.1082969913F, 0.1086009079F, 0.1089052101F, + 0.1092098975F, 0.1095149699F, 0.1098204270F, 0.1101262687F, + 0.1104324946F, 0.1107391045F, 0.1110460982F, 0.1113534754F, + 0.1116612359F, 0.1119693793F, 0.1122779055F, 0.1125868142F, + 0.1128961052F, 0.1132057781F, 0.1135158328F, 0.1138262690F, + 0.1141370863F, 0.1144482847F, 0.1147598638F, 0.1150718233F, + 0.1153841631F, 0.1156968828F, 0.1160099822F, 0.1163234610F, + 0.1166373190F, 0.1169515559F, 0.1172661714F, 0.1175811654F, + 0.1178965374F, 0.1182122874F, 0.1185284149F, 0.1188449198F, + 0.1191618018F, 0.1194790606F, 0.1197966960F, 0.1201147076F, + 0.1204330953F, 0.1207518587F, 0.1210709976F, 0.1213905118F, + 0.1217104009F, 0.1220306647F, 0.1223513029F, 0.1226723153F, + 0.1229937016F, 0.1233154615F, 0.1236375948F, 0.1239601011F, + 0.1242829803F, 0.1246062319F, 0.1249298559F, 0.1252538518F, + 0.1255782195F, 0.1259029586F, 0.1262280689F, 0.1265535501F, + 0.1268794019F, 0.1272056241F, 0.1275322163F, 0.1278591784F, + 0.1281865099F, 0.1285142108F, 0.1288422805F, 0.1291707190F, + 0.1294995259F, 0.1298287009F, 0.1301582437F, 0.1304881542F, + 0.1308184319F, 0.1311490766F, 0.1314800881F, 0.1318114660F, + 0.1321432100F, 0.1324753200F, 0.1328077955F, 0.1331406364F, + 0.1334738422F, 0.1338074129F, 0.1341413479F, 0.1344756472F, + 0.1348103103F, 0.1351453370F, 0.1354807270F, 0.1358164801F, + 0.1361525959F, 0.1364890741F, 0.1368259145F, 0.1371631167F, + 0.1375006805F, 0.1378386056F, 0.1381768917F, 0.1385155384F, + 0.1388545456F, 0.1391939129F, 0.1395336400F, 0.1398737266F, + 0.1402141724F, 0.1405549772F, 0.1408961406F, 0.1412376623F, + 0.1415795421F, 0.1419217797F, 0.1422643746F, 0.1426073268F, + 0.1429506358F, 0.1432943013F, 0.1436383231F, 0.1439827008F, + 0.1443274342F, 0.1446725229F, 0.1450179667F, 0.1453637652F, + 0.1457099181F, 0.1460564252F, 0.1464032861F, 0.1467505006F, + 0.1470980682F, 0.1474459888F, 0.1477942620F, 0.1481428875F, + 0.1484918651F, 0.1488411942F, 0.1491908748F, 0.1495409065F, + 0.1498912889F, 0.1502420218F, 0.1505931048F, 0.1509445376F, + 0.1512963200F, 0.1516484516F, 0.1520009321F, 0.1523537612F, + 0.1527069385F, 0.1530604638F, 0.1534143368F, 0.1537685571F, + 0.1541231244F, 0.1544780384F, 0.1548332987F, 0.1551889052F, + 0.1555448574F, 0.1559011550F, 0.1562577978F, 0.1566147853F, + 0.1569721173F, 0.1573297935F, 0.1576878135F, 0.1580461771F, + 0.1584048838F, 0.1587639334F, 0.1591233255F, 0.1594830599F, + 0.1598431361F, 0.1602035540F, 0.1605643131F, 0.1609254131F, + 0.1612868537F, 0.1616486346F, 0.1620107555F, 0.1623732160F, + 0.1627360158F, 0.1630991545F, 0.1634626319F, 0.1638264476F, + 0.1641906013F, 0.1645550926F, 0.1649199212F, 0.1652850869F, + 0.1656505892F, 0.1660164278F, 0.1663826024F, 0.1667491127F, + 0.1671159583F, 0.1674831388F, 0.1678506541F, 0.1682185036F, + 0.1685866872F, 0.1689552044F, 0.1693240549F, 0.1696932384F, + 0.1700627545F, 0.1704326029F, 0.1708027833F, 0.1711732952F, + 0.1715441385F, 0.1719153127F, 0.1722868175F, 0.1726586526F, + 0.1730308176F, 0.1734033121F, 0.1737761359F, 0.1741492886F, + 0.1745227698F, 0.1748965792F, 0.1752707164F, 0.1756451812F, + 0.1760199731F, 0.1763950918F, 0.1767705370F, 0.1771463083F, + 0.1775224054F, 0.1778988279F, 0.1782755754F, 0.1786526477F, + 0.1790300444F, 0.1794077651F, 0.1797858094F, 0.1801641771F, + 0.1805428677F, 0.1809218810F, 0.1813012165F, 0.1816808739F, + 0.1820608528F, 0.1824411530F, 0.1828217739F, 0.1832027154F, + 0.1835839770F, 0.1839655584F, 0.1843474592F, 0.1847296790F, + 0.1851122175F, 0.1854950744F, 0.1858782492F, 0.1862617417F, + 0.1866455514F, 0.1870296780F, 0.1874141211F, 0.1877988804F, + 0.1881839555F, 0.1885693461F, 0.1889550517F, 0.1893410721F, + 0.1897274068F, 0.1901140555F, 0.1905010178F, 0.1908882933F, + 0.1912758818F, 0.1916637828F, 0.1920519959F, 0.1924405208F, + 0.1928293571F, 0.1932185044F, 0.1936079625F, 0.1939977308F, + 0.1943878091F, 0.1947781969F, 0.1951688939F, 0.1955598998F, + 0.1959512141F, 0.1963428364F, 0.1967347665F, 0.1971270038F, + 0.1975195482F, 0.1979123990F, 0.1983055561F, 0.1986990190F, + 0.1990927873F, 0.1994868607F, 0.1998812388F, 0.2002759212F, + 0.2006709075F, 0.2010661974F, 0.2014617904F, 0.2018576862F, + 0.2022538844F, 0.2026503847F, 0.2030471865F, 0.2034442897F, + 0.2038416937F, 0.2042393982F, 0.2046374028F, 0.2050357071F, + 0.2054343107F, 0.2058332133F, 0.2062324145F, 0.2066319138F, + 0.2070317110F, 0.2074318055F, 0.2078321970F, 0.2082328852F, + 0.2086338696F, 0.2090351498F, 0.2094367255F, 0.2098385962F, + 0.2102407617F, 0.2106432213F, 0.2110459749F, 0.2114490220F, + 0.2118523621F, 0.2122559950F, 0.2126599202F, 0.2130641373F, + 0.2134686459F, 0.2138734456F, 0.2142785361F, 0.2146839168F, + 0.2150895875F, 0.2154955478F, 0.2159017972F, 0.2163083353F, + 0.2167151617F, 0.2171222761F, 0.2175296780F, 0.2179373670F, + 0.2183453428F, 0.2187536049F, 0.2191621529F, 0.2195709864F, + 0.2199801051F, 0.2203895085F, 0.2207991961F, 0.2212091677F, + 0.2216194228F, 0.2220299610F, 0.2224407818F, 0.2228518850F, + 0.2232632699F, 0.2236749364F, 0.2240868839F, 0.2244991121F, + 0.2249116204F, 0.2253244086F, 0.2257374763F, 0.2261508229F, + 0.2265644481F, 0.2269783514F, 0.2273925326F, 0.2278069911F, + 0.2282217265F, 0.2286367384F, 0.2290520265F, 0.2294675902F, + 0.2298834292F, 0.2302995431F, 0.2307159314F, 0.2311325937F, + 0.2315495297F, 0.2319667388F, 0.2323842207F, 0.2328019749F, + 0.2332200011F, 0.2336382988F, 0.2340568675F, 0.2344757070F, + 0.2348948166F, 0.2353141961F, 0.2357338450F, 0.2361537629F, + 0.2365739493F, 0.2369944038F, 0.2374151261F, 0.2378361156F, + 0.2382573720F, 0.2386788948F, 0.2391006836F, 0.2395227380F, + 0.2399450575F, 0.2403676417F, 0.2407904902F, 0.2412136026F, + 0.2416369783F, 0.2420606171F, 0.2424845185F, 0.2429086820F, + 0.2433331072F, 0.2437577936F, 0.2441827409F, 0.2446079486F, + 0.2450334163F, 0.2454591435F, 0.2458851298F, 0.2463113747F, + 0.2467378779F, 0.2471646389F, 0.2475916573F, 0.2480189325F, + 0.2484464643F, 0.2488742521F, 0.2493022955F, 0.2497305940F, + 0.2501591473F, 0.2505879549F, 0.2510170163F, 0.2514463311F, + 0.2518758989F, 0.2523057193F, 0.2527357916F, 0.2531661157F, + 0.2535966909F, 0.2540275169F, 0.2544585931F, 0.2548899193F, + 0.2553214948F, 0.2557533193F, 0.2561853924F, 0.2566177135F, + 0.2570502822F, 0.2574830981F, 0.2579161608F, 0.2583494697F, + 0.2587830245F, 0.2592168246F, 0.2596508697F, 0.2600851593F, + 0.2605196929F, 0.2609544701F, 0.2613894904F, 0.2618247534F, + 0.2622602586F, 0.2626960055F, 0.2631319938F, 0.2635682230F, + 0.2640046925F, 0.2644414021F, 0.2648783511F, 0.2653155391F, + 0.2657529657F, 0.2661906305F, 0.2666285329F, 0.2670666725F, + 0.2675050489F, 0.2679436616F, 0.2683825101F, 0.2688215940F, + 0.2692609127F, 0.2697004660F, 0.2701402532F, 0.2705802739F, + 0.2710205278F, 0.2714610142F, 0.2719017327F, 0.2723426830F, + 0.2727838644F, 0.2732252766F, 0.2736669191F, 0.2741087914F, + 0.2745508930F, 0.2749932235F, 0.2754357824F, 0.2758785693F, + 0.2763215837F, 0.2767648251F, 0.2772082930F, 0.2776519870F, + 0.2780959066F, 0.2785400513F, 0.2789844207F, 0.2794290143F, + 0.2798738316F, 0.2803188722F, 0.2807641355F, 0.2812096211F, + 0.2816553286F, 0.2821012574F, 0.2825474071F, 0.2829937773F, + 0.2834403673F, 0.2838871768F, 0.2843342053F, 0.2847814523F, + 0.2852289174F, 0.2856765999F, 0.2861244996F, 0.2865726159F, + 0.2870209482F, 0.2874694962F, 0.2879182594F, 0.2883672372F, + 0.2888164293F, 0.2892658350F, 0.2897154540F, 0.2901652858F, + 0.2906153298F, 0.2910655856F, 0.2915160527F, 0.2919667306F, + 0.2924176189F, 0.2928687171F, 0.2933200246F, 0.2937715409F, + 0.2942232657F, 0.2946751984F, 0.2951273386F, 0.2955796856F, + 0.2960322391F, 0.2964849986F, 0.2969379636F, 0.2973911335F, + 0.2978445080F, 0.2982980864F, 0.2987518684F, 0.2992058534F, + 0.2996600409F, 0.3001144305F, 0.3005690217F, 0.3010238139F, + 0.3014788067F, 0.3019339995F, 0.3023893920F, 0.3028449835F, + 0.3033007736F, 0.3037567618F, 0.3042129477F, 0.3046693306F, + 0.3051259102F, 0.3055826859F, 0.3060396572F, 0.3064968236F, + 0.3069541847F, 0.3074117399F, 0.3078694887F, 0.3083274307F, + 0.3087855653F, 0.3092438920F, 0.3097024104F, 0.3101611199F, + 0.3106200200F, 0.3110791103F, 0.3115383902F, 0.3119978592F, + 0.3124575169F, 0.3129173627F, 0.3133773961F, 0.3138376166F, + 0.3142980238F, 0.3147586170F, 0.3152193959F, 0.3156803598F, + 0.3161415084F, 0.3166028410F, 0.3170643573F, 0.3175260566F, + 0.3179879384F, 0.3184500023F, 0.3189122478F, 0.3193746743F, + 0.3198372814F, 0.3203000685F, 0.3207630351F, 0.3212261807F, + 0.3216895048F, 0.3221530069F, 0.3226166865F, 0.3230805430F, + 0.3235445760F, 0.3240087849F, 0.3244731693F, 0.3249377285F, + 0.3254024622F, 0.3258673698F, 0.3263324507F, 0.3267977045F, + 0.3272631306F, 0.3277287286F, 0.3281944978F, 0.3286604379F, + 0.3291265482F, 0.3295928284F, 0.3300592777F, 0.3305258958F, + 0.3309926821F, 0.3314596361F, 0.3319267573F, 0.3323940451F, + 0.3328614990F, 0.3333291186F, 0.3337969033F, 0.3342648525F, + 0.3347329658F, 0.3352012427F, 0.3356696825F, 0.3361382849F, + 0.3366070492F, 0.3370759749F, 0.3375450616F, 0.3380143087F, + 0.3384837156F, 0.3389532819F, 0.3394230071F, 0.3398928905F, + 0.3403629317F, 0.3408331302F, 0.3413034854F, 0.3417739967F, + 0.3422446638F, 0.3427154860F, 0.3431864628F, 0.3436575938F, + 0.3441288782F, 0.3446003158F, 0.3450719058F, 0.3455436478F, + 0.3460155412F, 0.3464875856F, 0.3469597804F, 0.3474321250F, + 0.3479046189F, 0.3483772617F, 0.3488500527F, 0.3493229914F, + 0.3497960774F, 0.3502693100F, 0.3507426887F, 0.3512162131F, + 0.3516898825F, 0.3521636965F, 0.3526376545F, 0.3531117559F, + 0.3535860003F, 0.3540603870F, 0.3545349157F, 0.3550095856F, + 0.3554843964F, 0.3559593474F, 0.3564344381F, 0.3569096680F, + 0.3573850366F, 0.3578605432F, 0.3583361875F, 0.3588119687F, + 0.3592878865F, 0.3597639402F, 0.3602401293F, 0.3607164533F, + 0.3611929117F, 0.3616695038F, 0.3621462292F, 0.3626230873F, + 0.3631000776F, 0.3635771995F, 0.3640544525F, 0.3645318360F, + 0.3650093496F, 0.3654869926F, 0.3659647645F, 0.3664426648F, + 0.3669206930F, 0.3673988484F, 0.3678771306F, 0.3683555390F, + 0.3688340731F, 0.3693127322F, 0.3697915160F, 0.3702704237F, + 0.3707494549F, 0.3712286091F, 0.3717078857F, 0.3721872840F, + 0.3726668037F, 0.3731464441F, 0.3736262047F, 0.3741060850F, + 0.3745860843F, 0.3750662023F, 0.3755464382F, 0.3760267915F, + 0.3765072618F, 0.3769878484F, 0.3774685509F, 0.3779493686F, + 0.3784303010F, 0.3789113475F, 0.3793925076F, 0.3798737809F, + 0.3803551666F, 0.3808366642F, 0.3813182733F, 0.3817999932F, + 0.3822818234F, 0.3827637633F, 0.3832458124F, 0.3837279702F, + 0.3842102360F, 0.3846926093F, 0.3851750897F, 0.3856576764F, + 0.3861403690F, 0.3866231670F, 0.3871060696F, 0.3875890765F, + 0.3880721870F, 0.3885554007F, 0.3890387168F, 0.3895221349F, + 0.3900056544F, 0.3904892748F, 0.3909729955F, 0.3914568160F, + 0.3919407356F, 0.3924247539F, 0.3929088702F, 0.3933930841F, + 0.3938773949F, 0.3943618021F, 0.3948463052F, 0.3953309035F, + 0.3958155966F, 0.3963003838F, 0.3967852646F, 0.3972702385F, + 0.3977553048F, 0.3982404631F, 0.3987257127F, 0.3992110531F, + 0.3996964838F, 0.4001820041F, 0.4006676136F, 0.4011533116F, + 0.4016390976F, 0.4021249710F, 0.4026109313F, 0.4030969779F, + 0.4035831102F, 0.4040693277F, 0.4045556299F, 0.4050420160F, + 0.4055284857F, 0.4060150383F, 0.4065016732F, 0.4069883899F, + 0.4074751879F, 0.4079620665F, 0.4084490252F, 0.4089360635F, + 0.4094231807F, 0.4099103763F, 0.4103976498F, 0.4108850005F, + 0.4113724280F, 0.4118599315F, 0.4123475107F, 0.4128351648F, + 0.4133228934F, 0.4138106959F, 0.4142985716F, 0.4147865201F, + 0.4152745408F, 0.4157626330F, 0.4162507963F, 0.4167390301F, + 0.4172273337F, 0.4177157067F, 0.4182041484F, 0.4186926583F, + 0.4191812359F, 0.4196698805F, 0.4201585915F, 0.4206473685F, + 0.4211362108F, 0.4216251179F, 0.4221140892F, 0.4226031241F, + 0.4230922221F, 0.4235813826F, 0.4240706050F, 0.4245598887F, + 0.4250492332F, 0.4255386379F, 0.4260281022F, 0.4265176256F, + 0.4270072075F, 0.4274968473F, 0.4279865445F, 0.4284762984F, + 0.4289661086F, 0.4294559743F, 0.4299458951F, 0.4304358704F, + 0.4309258996F, 0.4314159822F, 0.4319061175F, 0.4323963050F, + 0.4328865441F, 0.4333768342F, 0.4338671749F, 0.4343575654F, + 0.4348480052F, 0.4353384938F, 0.4358290306F, 0.4363196149F, + 0.4368102463F, 0.4373009241F, 0.4377916478F, 0.4382824168F, + 0.4387732305F, 0.4392640884F, 0.4397549899F, 0.4402459343F, + 0.4407369212F, 0.4412279499F, 0.4417190198F, 0.4422101305F, + 0.4427012813F, 0.4431924717F, 0.4436837010F, 0.4441749686F, + 0.4446662742F, 0.4451576169F, 0.4456489963F, 0.4461404118F, + 0.4466318628F, 0.4471233487F, 0.4476148690F, 0.4481064230F, + 0.4485980103F, 0.4490896302F, 0.4495812821F, 0.4500729654F, + 0.4505646797F, 0.4510564243F, 0.4515481986F, 0.4520400021F, + 0.4525318341F, 0.4530236942F, 0.4535155816F, 0.4540074959F, + 0.4544994365F, 0.4549914028F, 0.4554833941F, 0.4559754100F, + 0.4564674499F, 0.4569595131F, 0.4574515991F, 0.4579437074F, + 0.4584358372F, 0.4589279881F, 0.4594201595F, 0.4599123508F, + 0.4604045615F, 0.4608967908F, 0.4613890383F, 0.4618813034F, + 0.4623735855F, 0.4628658841F, 0.4633581984F, 0.4638505281F, + 0.4643428724F, 0.4648352308F, 0.4653276028F, 0.4658199877F, + 0.4663123849F, 0.4668047940F, 0.4672972143F, 0.4677896451F, + 0.4682820861F, 0.4687745365F, 0.4692669958F, 0.4697594634F, + 0.4702519387F, 0.4707444211F, 0.4712369102F, 0.4717294052F, + 0.4722219056F, 0.4727144109F, 0.4732069204F, 0.4736994336F, + 0.4741919498F, 0.4746844686F, 0.4751769893F, 0.4756695113F, + 0.4761620341F, 0.4766545571F, 0.4771470797F, 0.4776396013F, + 0.4781321213F, 0.4786246392F, 0.4791171544F, 0.4796096663F, + 0.4801021744F, 0.4805946779F, 0.4810871765F, 0.4815796694F, + 0.4820721561F, 0.4825646360F, 0.4830571086F, 0.4835495732F, + 0.4840420293F, 0.4845344763F, 0.4850269136F, 0.4855193407F, + 0.4860117569F, 0.4865041617F, 0.4869965545F, 0.4874889347F, + 0.4879813018F, 0.4884736551F, 0.4889659941F, 0.4894583182F, + 0.4899506268F, 0.4904429193F, 0.4909351952F, 0.4914274538F, + 0.4919196947F, 0.4924119172F, 0.4929041207F, 0.4933963046F, + 0.4938884685F, 0.4943806116F, 0.4948727335F, 0.4953648335F, + 0.4958569110F, 0.4963489656F, 0.4968409965F, 0.4973330032F, + 0.4978249852F, 0.4983169419F, 0.4988088726F, 0.4993007768F, + 0.4997926539F, 0.5002845034F, 0.5007763247F, 0.5012681171F, + 0.5017598801F, 0.5022516132F, 0.5027433157F, 0.5032349871F, + 0.5037266268F, 0.5042182341F, 0.5047098086F, 0.5052013497F, + 0.5056928567F, 0.5061843292F, 0.5066757664F, 0.5071671679F, + 0.5076585330F, 0.5081498613F, 0.5086411520F, 0.5091324047F, + 0.5096236187F, 0.5101147934F, 0.5106059284F, 0.5110970230F, + 0.5115880766F, 0.5120790887F, 0.5125700587F, 0.5130609860F, + 0.5135518700F, 0.5140427102F, 0.5145335059F, 0.5150242566F, + 0.5155149618F, 0.5160056208F, 0.5164962331F, 0.5169867980F, + 0.5174773151F, 0.5179677837F, 0.5184582033F, 0.5189485733F, + 0.5194388931F, 0.5199291621F, 0.5204193798F, 0.5209095455F, + 0.5213996588F, 0.5218897190F, 0.5223797256F, 0.5228696779F, + 0.5233595755F, 0.5238494177F, 0.5243392039F, 0.5248289337F, + 0.5253186063F, 0.5258082213F, 0.5262977781F, 0.5267872760F, + 0.5272767146F, 0.5277660932F, 0.5282554112F, 0.5287446682F, + 0.5292338635F, 0.5297229965F, 0.5302120667F, 0.5307010736F, + 0.5311900164F, 0.5316788947F, 0.5321677079F, 0.5326564554F, + 0.5331451366F, 0.5336337511F, 0.5341222981F, 0.5346107771F, + 0.5350991876F, 0.5355875290F, 0.5360758007F, 0.5365640021F, + 0.5370521327F, 0.5375401920F, 0.5380281792F, 0.5385160939F, + 0.5390039355F, 0.5394917034F, 0.5399793971F, 0.5404670159F, + 0.5409545594F, 0.5414420269F, 0.5419294179F, 0.5424167318F, + 0.5429039680F, 0.5433911261F, 0.5438782053F, 0.5443652051F, + 0.5448521250F, 0.5453389644F, 0.5458257228F, 0.5463123995F, + 0.5467989940F, 0.5472855057F, 0.5477719341F, 0.5482582786F, + 0.5487445387F, 0.5492307137F, 0.5497168031F, 0.5502028063F, + 0.5506887228F, 0.5511745520F, 0.5516602934F, 0.5521459463F, + 0.5526315103F, 0.5531169847F, 0.5536023690F, 0.5540876626F, + 0.5545728649F, 0.5550579755F, 0.5555429937F, 0.5560279189F, + 0.5565127507F, 0.5569974884F, 0.5574821315F, 0.5579666794F, + 0.5584511316F, 0.5589354875F, 0.5594197465F, 0.5599039080F, + 0.5603879716F, 0.5608719367F, 0.5613558026F, 0.5618395689F, + 0.5623232350F, 0.5628068002F, 0.5632902642F, 0.5637736262F, + 0.5642568858F, 0.5647400423F, 0.5652230953F, 0.5657060442F, + 0.5661888883F, 0.5666716272F, 0.5671542603F, 0.5676367870F, + 0.5681192069F, 0.5686015192F, 0.5690837235F, 0.5695658192F, + 0.5700478058F, 0.5705296827F, 0.5710114494F, 0.5714931052F, + 0.5719746497F, 0.5724560822F, 0.5729374023F, 0.5734186094F, + 0.5738997029F, 0.5743806823F, 0.5748615470F, 0.5753422965F, + 0.5758229301F, 0.5763034475F, 0.5767838480F, 0.5772641310F, + 0.5777442960F, 0.5782243426F, 0.5787042700F, 0.5791840778F, + 0.5796637654F, 0.5801433322F, 0.5806227778F, 0.5811021016F, + 0.5815813029F, 0.5820603814F, 0.5825393363F, 0.5830181673F, + 0.5834968737F, 0.5839754549F, 0.5844539105F, 0.5849322399F, + 0.5854104425F, 0.5858885179F, 0.5863664653F, 0.5868442844F, + 0.5873219746F, 0.5877995353F, 0.5882769660F, 0.5887542661F, + 0.5892314351F, 0.5897084724F, 0.5901853776F, 0.5906621500F, + 0.5911387892F, 0.5916152945F, 0.5920916655F, 0.5925679016F, + 0.5930440022F, 0.5935199669F, 0.5939957950F, 0.5944714861F, + 0.5949470396F, 0.5954224550F, 0.5958977317F, 0.5963728692F, + 0.5968478669F, 0.5973227244F, 0.5977974411F, 0.5982720163F, + 0.5987464497F, 0.5992207407F, 0.5996948887F, 0.6001688932F, + 0.6006427537F, 0.6011164696F, 0.6015900405F, 0.6020634657F, + 0.6025367447F, 0.6030098770F, 0.6034828621F, 0.6039556995F, + 0.6044283885F, 0.6049009288F, 0.6053733196F, 0.6058455606F, + 0.6063176512F, 0.6067895909F, 0.6072613790F, 0.6077330152F, + 0.6082044989F, 0.6086758295F, 0.6091470065F, 0.6096180294F, + 0.6100888977F, 0.6105596108F, 0.6110301682F, 0.6115005694F, + 0.6119708139F, 0.6124409011F, 0.6129108305F, 0.6133806017F, + 0.6138502139F, 0.6143196669F, 0.6147889599F, 0.6152580926F, + 0.6157270643F, 0.6161958746F, 0.6166645230F, 0.6171330088F, + 0.6176013317F, 0.6180694910F, 0.6185374863F, 0.6190053171F, + 0.6194729827F, 0.6199404828F, 0.6204078167F, 0.6208749841F, + 0.6213419842F, 0.6218088168F, 0.6222754811F, 0.6227419768F, + 0.6232083032F, 0.6236744600F, 0.6241404465F, 0.6246062622F, + 0.6250719067F, 0.6255373795F, 0.6260026799F, 0.6264678076F, + 0.6269327619F, 0.6273975425F, 0.6278621487F, 0.6283265800F, + 0.6287908361F, 0.6292549163F, 0.6297188201F, 0.6301825471F, + 0.6306460966F, 0.6311094683F, 0.6315726617F, 0.6320356761F, + 0.6324985111F, 0.6329611662F, 0.6334236410F, 0.6338859348F, + 0.6343480472F, 0.6348099777F, 0.6352717257F, 0.6357332909F, + 0.6361946726F, 0.6366558704F, 0.6371168837F, 0.6375777122F, + 0.6380383552F, 0.6384988123F, 0.6389590830F, 0.6394191668F, + 0.6398790631F, 0.6403387716F, 0.6407982916F, 0.6412576228F, + 0.6417167645F, 0.6421757163F, 0.6426344778F, 0.6430930483F, + 0.6435514275F, 0.6440096149F, 0.6444676098F, 0.6449254119F, + 0.6453830207F, 0.6458404356F, 0.6462976562F, 0.6467546820F, + 0.6472115125F, 0.6476681472F, 0.6481245856F, 0.6485808273F, + 0.6490368717F, 0.6494927183F, 0.6499483667F, 0.6504038164F, + 0.6508590670F, 0.6513141178F, 0.6517689684F, 0.6522236185F, + 0.6526780673F, 0.6531323146F, 0.6535863598F, 0.6540402024F, + 0.6544938419F, 0.6549472779F, 0.6554005099F, 0.6558535373F, + 0.6563063598F, 0.6567589769F, 0.6572113880F, 0.6576635927F, + 0.6581155906F, 0.6585673810F, 0.6590189637F, 0.6594703380F, + 0.6599215035F, 0.6603724598F, 0.6608232064F, 0.6612737427F, + 0.6617240684F, 0.6621741829F, 0.6626240859F, 0.6630737767F, + 0.6635232550F, 0.6639725202F, 0.6644215720F, 0.6648704098F, + 0.6653190332F, 0.6657674417F, 0.6662156348F, 0.6666636121F, + 0.6671113731F, 0.6675589174F, 0.6680062445F, 0.6684533538F, + 0.6689002450F, 0.6693469177F, 0.6697933712F, 0.6702396052F, + 0.6706856193F, 0.6711314129F, 0.6715769855F, 0.6720223369F, + 0.6724674664F, 0.6729123736F, 0.6733570581F, 0.6738015194F, + 0.6742457570F, 0.6746897706F, 0.6751335596F, 0.6755771236F, + 0.6760204621F, 0.6764635747F, 0.6769064609F, 0.6773491204F, + 0.6777915525F, 0.6782337570F, 0.6786757332F, 0.6791174809F, + 0.6795589995F, 0.6800002886F, 0.6804413477F, 0.6808821765F, + 0.6813227743F, 0.6817631409F, 0.6822032758F, 0.6826431785F, + 0.6830828485F, 0.6835222855F, 0.6839614890F, 0.6844004585F, + 0.6848391936F, 0.6852776939F, 0.6857159589F, 0.6861539883F, + 0.6865917815F, 0.6870293381F, 0.6874666576F, 0.6879037398F, + 0.6883405840F, 0.6887771899F, 0.6892135571F, 0.6896496850F, + 0.6900855733F, 0.6905212216F, 0.6909566294F, 0.6913917963F, + 0.6918267218F, 0.6922614055F, 0.6926958471F, 0.6931300459F, + 0.6935640018F, 0.6939977141F, 0.6944311825F, 0.6948644066F, + 0.6952973859F, 0.6957301200F, 0.6961626085F, 0.6965948510F, + 0.6970268470F, 0.6974585961F, 0.6978900980F, 0.6983213521F, + 0.6987523580F, 0.6991831154F, 0.6996136238F, 0.7000438828F, + 0.7004738921F, 0.7009036510F, 0.7013331594F, 0.7017624166F, + 0.7021914224F, 0.7026201763F, 0.7030486779F, 0.7034769268F, + 0.7039049226F, 0.7043326648F, 0.7047601531F, 0.7051873870F, + 0.7056143662F, 0.7060410902F, 0.7064675586F, 0.7068937711F, + 0.7073197271F, 0.7077454264F, 0.7081708684F, 0.7085960529F, + 0.7090209793F, 0.7094456474F, 0.7098700566F, 0.7102942066F, + 0.7107180970F, 0.7111417274F, 0.7115650974F, 0.7119882066F, + 0.7124110545F, 0.7128336409F, 0.7132559653F, 0.7136780272F, + 0.7140998264F, 0.7145213624F, 0.7149426348F, 0.7153636433F, + 0.7157843874F, 0.7162048668F, 0.7166250810F, 0.7170450296F, + 0.7174647124F, 0.7178841289F, 0.7183032786F, 0.7187221613F, + 0.7191407765F, 0.7195591239F, 0.7199772030F, 0.7203950135F, + 0.7208125550F, 0.7212298271F, 0.7216468294F, 0.7220635616F, + 0.7224800233F, 0.7228962140F, 0.7233121335F, 0.7237277813F, + 0.7241431571F, 0.7245582604F, 0.7249730910F, 0.7253876484F, + 0.7258019322F, 0.7262159422F, 0.7266296778F, 0.7270431388F, + 0.7274563247F, 0.7278692353F, 0.7282818700F, 0.7286942287F, + 0.7291063108F, 0.7295181160F, 0.7299296440F, 0.7303408944F, + 0.7307518669F, 0.7311625609F, 0.7315729763F, 0.7319831126F, + 0.7323929695F, 0.7328025466F, 0.7332118435F, 0.7336208600F, + 0.7340295955F, 0.7344380499F, 0.7348462226F, 0.7352541134F, + 0.7356617220F, 0.7360690478F, 0.7364760907F, 0.7368828502F, + 0.7372893259F, 0.7376955176F, 0.7381014249F, 0.7385070475F, + 0.7389123849F, 0.7393174368F, 0.7397222029F, 0.7401266829F, + 0.7405308763F, 0.7409347829F, 0.7413384023F, 0.7417417341F, + 0.7421447780F, 0.7425475338F, 0.7429500009F, 0.7433521791F, + 0.7437540681F, 0.7441556674F, 0.7445569769F, 0.7449579960F, + 0.7453587245F, 0.7457591621F, 0.7461593084F, 0.7465591631F, + 0.7469587259F, 0.7473579963F, 0.7477569741F, 0.7481556590F, + 0.7485540506F, 0.7489521486F, 0.7493499526F, 0.7497474623F, + 0.7501446775F, 0.7505415977F, 0.7509382227F, 0.7513345521F, + 0.7517305856F, 0.7521263229F, 0.7525217636F, 0.7529169074F, + 0.7533117541F, 0.7537063032F, 0.7541005545F, 0.7544945076F, + 0.7548881623F, 0.7552815182F, 0.7556745749F, 0.7560673323F, + 0.7564597899F, 0.7568519474F, 0.7572438046F, 0.7576353611F, + 0.7580266166F, 0.7584175708F, 0.7588082235F, 0.7591985741F, + 0.7595886226F, 0.7599783685F, 0.7603678116F, 0.7607569515F, + 0.7611457879F, 0.7615343206F, 0.7619225493F, 0.7623104735F, + 0.7626980931F, 0.7630854078F, 0.7634724171F, 0.7638591209F, + 0.7642455188F, 0.7646316106F, 0.7650173959F, 0.7654028744F, + 0.7657880459F, 0.7661729100F, 0.7665574664F, 0.7669417150F, + 0.7673256553F, 0.7677092871F, 0.7680926100F, 0.7684756239F, + 0.7688583284F, 0.7692407232F, 0.7696228080F, 0.7700045826F, + 0.7703860467F, 0.7707671999F, 0.7711480420F, 0.7715285728F, + 0.7719087918F, 0.7722886989F, 0.7726682938F, 0.7730475762F, + 0.7734265458F, 0.7738052023F, 0.7741835454F, 0.7745615750F, + 0.7749392906F, 0.7753166921F, 0.7756937791F, 0.7760705514F, + 0.7764470087F, 0.7768231508F, 0.7771989773F, 0.7775744880F, + 0.7779496827F, 0.7783245610F, 0.7786991227F, 0.7790733676F, + 0.7794472953F, 0.7798209056F, 0.7801941982F, 0.7805671729F, + 0.7809398294F, 0.7813121675F, 0.7816841869F, 0.7820558873F, + 0.7824272684F, 0.7827983301F, 0.7831690720F, 0.7835394940F, + 0.7839095957F, 0.7842793768F, 0.7846488373F, 0.7850179767F, + 0.7853867948F, 0.7857552914F, 0.7861234663F, 0.7864913191F, + 0.7868588497F, 0.7872260578F, 0.7875929431F, 0.7879595055F, + 0.7883257445F, 0.7886916601F, 0.7890572520F, 0.7894225198F, + 0.7897874635F, 0.7901520827F, 0.7905163772F, 0.7908803468F, + 0.7912439912F, 0.7916073102F, 0.7919703035F, 0.7923329710F, + 0.7926953124F, 0.7930573274F, 0.7934190158F, 0.7937803774F, + 0.7941414120F, 0.7945021193F, 0.7948624991F, 0.7952225511F, + 0.7955822752F, 0.7959416711F, 0.7963007387F, 0.7966594775F, + 0.7970178875F, 0.7973759685F, 0.7977337201F, 0.7980911422F, + 0.7984482346F, 0.7988049970F, 0.7991614292F, 0.7995175310F, + 0.7998733022F, 0.8002287426F, 0.8005838519F, 0.8009386299F, + 0.8012930765F, 0.8016471914F, 0.8020009744F, 0.8023544253F, + 0.8027075438F, 0.8030603298F, 0.8034127831F, 0.8037649035F, + 0.8041166906F, 0.8044681445F, 0.8048192647F, 0.8051700512F, + 0.8055205038F, 0.8058706222F, 0.8062204062F, 0.8065698556F, + 0.8069189702F, 0.8072677499F, 0.8076161944F, 0.8079643036F, + 0.8083120772F, 0.8086595151F, 0.8090066170F, 0.8093533827F, + 0.8096998122F, 0.8100459051F, 0.8103916613F, 0.8107370806F, + 0.8110821628F, 0.8114269077F, 0.8117713151F, 0.8121153849F, + 0.8124591169F, 0.8128025108F, 0.8131455666F, 0.8134882839F, + 0.8138306627F, 0.8141727027F, 0.8145144038F, 0.8148557658F, + 0.8151967886F, 0.8155374718F, 0.8158778154F, 0.8162178192F, + 0.8165574830F, 0.8168968067F, 0.8172357900F, 0.8175744328F, + 0.8179127349F, 0.8182506962F, 0.8185883164F, 0.8189255955F, + 0.8192625332F, 0.8195991295F, 0.8199353840F, 0.8202712967F, + 0.8206068673F, 0.8209420958F, 0.8212769820F, 0.8216115256F, + 0.8219457266F, 0.8222795848F, 0.8226131000F, 0.8229462721F, + 0.8232791009F, 0.8236115863F, 0.8239437280F, 0.8242755260F, + 0.8246069801F, 0.8249380901F, 0.8252688559F, 0.8255992774F, + 0.8259293544F, 0.8262590867F, 0.8265884741F, 0.8269175167F, + 0.8272462141F, 0.8275745663F, 0.8279025732F, 0.8282302344F, + 0.8285575501F, 0.8288845199F, 0.8292111437F, 0.8295374215F, + 0.8298633530F, 0.8301889382F, 0.8305141768F, 0.8308390688F, + 0.8311636141F, 0.8314878124F, 0.8318116637F, 0.8321351678F, + 0.8324583246F, 0.8327811340F, 0.8331035957F, 0.8334257098F, + 0.8337474761F, 0.8340688944F, 0.8343899647F, 0.8347106867F, + 0.8350310605F, 0.8353510857F, 0.8356707624F, 0.8359900904F, + 0.8363090696F, 0.8366276999F, 0.8369459811F, 0.8372639131F, + 0.8375814958F, 0.8378987292F, 0.8382156130F, 0.8385321472F, + 0.8388483316F, 0.8391641662F, 0.8394796508F, 0.8397947853F, + 0.8401095697F, 0.8404240037F, 0.8407380873F, 0.8410518204F, + 0.8413652029F, 0.8416782347F, 0.8419909156F, 0.8423032456F, + 0.8426152245F, 0.8429268523F, 0.8432381289F, 0.8435490541F, + 0.8438596279F, 0.8441698502F, 0.8444797208F, 0.8447892396F, + 0.8450984067F, 0.8454072218F, 0.8457156849F, 0.8460237959F, + 0.8463315547F, 0.8466389612F, 0.8469460154F, 0.8472527170F, + 0.8475590661F, 0.8478650625F, 0.8481707063F, 0.8484759971F, + 0.8487809351F, 0.8490855201F, 0.8493897521F, 0.8496936308F, + 0.8499971564F, 0.8503003286F, 0.8506031474F, 0.8509056128F, + 0.8512077246F, 0.8515094828F, 0.8518108872F, 0.8521119379F, + 0.8524126348F, 0.8527129777F, 0.8530129666F, 0.8533126015F, + 0.8536118822F, 0.8539108087F, 0.8542093809F, 0.8545075988F, + 0.8548054623F, 0.8551029712F, 0.8554001257F, 0.8556969255F, + 0.8559933707F, 0.8562894611F, 0.8565851968F, 0.8568805775F, + 0.8571756034F, 0.8574702743F, 0.8577645902F, 0.8580585509F, + 0.8583521566F, 0.8586454070F, 0.8589383021F, 0.8592308420F, + 0.8595230265F, 0.8598148556F, 0.8601063292F, 0.8603974473F, + 0.8606882098F, 0.8609786167F, 0.8612686680F, 0.8615583636F, + 0.8618477034F, 0.8621366874F, 0.8624253156F, 0.8627135878F, + 0.8630015042F, 0.8632890646F, 0.8635762690F, 0.8638631173F, + 0.8641496096F, 0.8644357457F, 0.8647215257F, 0.8650069495F, + 0.8652920171F, 0.8655767283F, 0.8658610833F, 0.8661450820F, + 0.8664287243F, 0.8667120102F, 0.8669949397F, 0.8672775127F, + 0.8675597293F, 0.8678415894F, 0.8681230929F, 0.8684042398F, + 0.8686850302F, 0.8689654640F, 0.8692455412F, 0.8695252617F, + 0.8698046255F, 0.8700836327F, 0.8703622831F, 0.8706405768F, + 0.8709185138F, 0.8711960940F, 0.8714733174F, 0.8717501840F, + 0.8720266939F, 0.8723028469F, 0.8725786430F, 0.8728540824F, + 0.8731291648F, 0.8734038905F, 0.8736782592F, 0.8739522711F, + 0.8742259261F, 0.8744992242F, 0.8747721653F, 0.8750447496F, + 0.8753169770F, 0.8755888475F, 0.8758603611F, 0.8761315177F, + 0.8764023175F, 0.8766727603F, 0.8769428462F, 0.8772125752F, + 0.8774819474F, 0.8777509626F, 0.8780196209F, 0.8782879224F, + 0.8785558669F, 0.8788234546F, 0.8790906854F, 0.8793575594F, + 0.8796240765F, 0.8798902368F, 0.8801560403F, 0.8804214870F, + 0.8806865768F, 0.8809513099F, 0.8812156863F, 0.8814797059F, + 0.8817433687F, 0.8820066749F, 0.8822696243F, 0.8825322171F, + 0.8827944532F, 0.8830563327F, 0.8833178556F, 0.8835790219F, + 0.8838398316F, 0.8841002848F, 0.8843603815F, 0.8846201217F, + 0.8848795054F, 0.8851385327F, 0.8853972036F, 0.8856555182F, + 0.8859134764F, 0.8861710783F, 0.8864283239F, 0.8866852133F, + 0.8869417464F, 0.8871979234F, 0.8874537443F, 0.8877092090F, + 0.8879643177F, 0.8882190704F, 0.8884734671F, 0.8887275078F, + 0.8889811927F, 0.8892345216F, 0.8894874948F, 0.8897401122F, + 0.8899923738F, 0.8902442798F, 0.8904958301F, 0.8907470248F, + 0.8909978640F, 0.8912483477F, 0.8914984759F, 0.8917482487F, + 0.8919976662F, 0.8922467284F, 0.8924954353F, 0.8927437871F, + 0.8929917837F, 0.8932394252F, 0.8934867118F, 0.8937336433F, + 0.8939802199F, 0.8942264417F, 0.8944723087F, 0.8947178210F, + 0.8949629785F, 0.8952077815F, 0.8954522299F, 0.8956963239F, + 0.8959400634F, 0.8961834486F, 0.8964264795F, 0.8966691561F, + 0.8969114786F, 0.8971534470F, 0.8973950614F, 0.8976363219F, + 0.8978772284F, 0.8981177812F, 0.8983579802F, 0.8985978256F, + 0.8988373174F, 0.8990764556F, 0.8993152405F, 0.8995536720F, + 0.8997917502F, 0.9000294751F, 0.9002668470F, 0.9005038658F, + 0.9007405317F, 0.9009768446F, 0.9012128048F, 0.9014484123F, + 0.9016836671F, 0.9019185693F, 0.9021531191F, 0.9023873165F, + 0.9026211616F, 0.9028546546F, 0.9030877954F, 0.9033205841F, + 0.9035530210F, 0.9037851059F, 0.9040168392F, 0.9042482207F, + 0.9044792507F, 0.9047099293F, 0.9049402564F, 0.9051702323F, + 0.9053998569F, 0.9056291305F, 0.9058580531F, 0.9060866248F, + 0.9063148457F, 0.9065427159F, 0.9067702355F, 0.9069974046F, + 0.9072242233F, 0.9074506917F, 0.9076768100F, 0.9079025782F, + 0.9081279964F, 0.9083530647F, 0.9085777833F, 0.9088021523F, + 0.9090261717F, 0.9092498417F, 0.9094731623F, 0.9096961338F, + 0.9099187561F, 0.9101410295F, 0.9103629540F, 0.9105845297F, + 0.9108057568F, 0.9110266354F, 0.9112471656F, 0.9114673475F, + 0.9116871812F, 0.9119066668F, 0.9121258046F, 0.9123445945F, + 0.9125630367F, 0.9127811314F, 0.9129988786F, 0.9132162785F, + 0.9134333312F, 0.9136500368F, 0.9138663954F, 0.9140824073F, + 0.9142980724F, 0.9145133910F, 0.9147283632F, 0.9149429890F, + 0.9151572687F, 0.9153712023F, 0.9155847900F, 0.9157980319F, + 0.9160109282F, 0.9162234790F, 0.9164356844F, 0.9166475445F, + 0.9168590595F, 0.9170702296F, 0.9172810548F, 0.9174915354F, + 0.9177016714F, 0.9179114629F, 0.9181209102F, 0.9183300134F, + 0.9185387726F, 0.9187471879F, 0.9189552595F, 0.9191629876F, + 0.9193703723F, 0.9195774136F, 0.9197841119F, 0.9199904672F, + 0.9201964797F, 0.9204021495F, 0.9206074767F, 0.9208124616F, + 0.9210171043F, 0.9212214049F, 0.9214253636F, 0.9216289805F, + 0.9218322558F, 0.9220351896F, 0.9222377821F, 0.9224400335F, + 0.9226419439F, 0.9228435134F, 0.9230447423F, 0.9232456307F, + 0.9234461787F, 0.9236463865F, 0.9238462543F, 0.9240457822F, + 0.9242449704F, 0.9244438190F, 0.9246423282F, 0.9248404983F, + 0.9250383293F, 0.9252358214F, 0.9254329747F, 0.9256297896F, + 0.9258262660F, 0.9260224042F, 0.9262182044F, 0.9264136667F, + 0.9266087913F, 0.9268035783F, 0.9269980280F, 0.9271921405F, + 0.9273859160F, 0.9275793546F, 0.9277724566F, 0.9279652221F, + 0.9281576513F, 0.9283497443F, 0.9285415014F, 0.9287329227F, + 0.9289240084F, 0.9291147586F, 0.9293051737F, 0.9294952536F, + 0.9296849987F, 0.9298744091F, 0.9300634850F, 0.9302522266F, + 0.9304406340F, 0.9306287074F, 0.9308164471F, 0.9310038532F, + 0.9311909259F, 0.9313776654F, 0.9315640719F, 0.9317501455F, + 0.9319358865F, 0.9321212951F, 0.9323063713F, 0.9324911155F, + 0.9326755279F, 0.9328596085F, 0.9330433577F, 0.9332267756F, + 0.9334098623F, 0.9335926182F, 0.9337750434F, 0.9339571380F, + 0.9341389023F, 0.9343203366F, 0.9345014409F, 0.9346822155F, + 0.9348626606F, 0.9350427763F, 0.9352225630F, 0.9354020207F, + 0.9355811498F, 0.9357599503F, 0.9359384226F, 0.9361165667F, + 0.9362943830F, 0.9364718716F, 0.9366490327F, 0.9368258666F, + 0.9370023733F, 0.9371785533F, 0.9373544066F, 0.9375299335F, + 0.9377051341F, 0.9378800087F, 0.9380545576F, 0.9382287809F, + 0.9384026787F, 0.9385762515F, 0.9387494993F, 0.9389224223F, + 0.9390950209F, 0.9392672951F, 0.9394392453F, 0.9396108716F, + 0.9397821743F, 0.9399531536F, 0.9401238096F, 0.9402941427F, + 0.9404641530F, 0.9406338407F, 0.9408032061F, 0.9409722495F, + 0.9411409709F, 0.9413093707F, 0.9414774491F, 0.9416452062F, + 0.9418126424F, 0.9419797579F, 0.9421465528F, 0.9423130274F, + 0.9424791819F, 0.9426450166F, 0.9428105317F, 0.9429757274F, + 0.9431406039F, 0.9433051616F, 0.9434694005F, 0.9436333209F, + 0.9437969232F, 0.9439602074F, 0.9441231739F, 0.9442858229F, + 0.9444481545F, 0.9446101691F, 0.9447718669F, 0.9449332481F, + 0.9450943129F, 0.9452550617F, 0.9454154945F, 0.9455756118F, + 0.9457354136F, 0.9458949003F, 0.9460540721F, 0.9462129292F, + 0.9463714719F, 0.9465297003F, 0.9466876149F, 0.9468452157F, + 0.9470025031F, 0.9471594772F, 0.9473161384F, 0.9474724869F, + 0.9476285229F, 0.9477842466F, 0.9479396584F, 0.9480947585F, + 0.9482495470F, 0.9484040243F, 0.9485581906F, 0.9487120462F, + 0.9488655913F, 0.9490188262F, 0.9491717511F, 0.9493243662F, + 0.9494766718F, 0.9496286683F, 0.9497803557F, 0.9499317345F, + 0.9500828047F, 0.9502335668F, 0.9503840209F, 0.9505341673F, + 0.9506840062F, 0.9508335380F, 0.9509827629F, 0.9511316810F, + 0.9512802928F, 0.9514285984F, 0.9515765982F, 0.9517242923F, + 0.9518716810F, 0.9520187646F, 0.9521655434F, 0.9523120176F, + 0.9524581875F, 0.9526040534F, 0.9527496154F, 0.9528948739F, + 0.9530398292F, 0.9531844814F, 0.9533288310F, 0.9534728780F, + 0.9536166229F, 0.9537600659F, 0.9539032071F, 0.9540460470F, + 0.9541885858F, 0.9543308237F, 0.9544727611F, 0.9546143981F, + 0.9547557351F, 0.9548967723F, 0.9550375100F, 0.9551779485F, + 0.9553180881F, 0.9554579290F, 0.9555974714F, 0.9557367158F, + 0.9558756623F, 0.9560143112F, 0.9561526628F, 0.9562907174F, + 0.9564284752F, 0.9565659366F, 0.9567031017F, 0.9568399710F, + 0.9569765446F, 0.9571128229F, 0.9572488061F, 0.9573844944F, + 0.9575198883F, 0.9576549879F, 0.9577897936F, 0.9579243056F, + 0.9580585242F, 0.9581924497F, 0.9583260824F, 0.9584594226F, + 0.9585924705F, 0.9587252264F, 0.9588576906F, 0.9589898634F, + 0.9591217452F, 0.9592533360F, 0.9593846364F, 0.9595156465F, + 0.9596463666F, 0.9597767971F, 0.9599069382F, 0.9600367901F, + 0.9601663533F, 0.9602956279F, 0.9604246143F, 0.9605533128F, + 0.9606817236F, 0.9608098471F, 0.9609376835F, 0.9610652332F, + 0.9611924963F, 0.9613194733F, 0.9614461644F, 0.9615725699F, + 0.9616986901F, 0.9618245253F, 0.9619500757F, 0.9620753418F, + 0.9622003238F, 0.9623250219F, 0.9624494365F, 0.9625735679F, + 0.9626974163F, 0.9628209821F, 0.9629442656F, 0.9630672671F, + 0.9631899868F, 0.9633124251F, 0.9634345822F, 0.9635564585F, + 0.9636780543F, 0.9637993699F, 0.9639204056F, 0.9640411616F, + 0.9641616383F, 0.9642818359F, 0.9644017549F, 0.9645213955F, + 0.9646407579F, 0.9647598426F, 0.9648786497F, 0.9649971797F, + 0.9651154328F, 0.9652334092F, 0.9653511095F, 0.9654685337F, + 0.9655856823F, 0.9657025556F, 0.9658191538F, 0.9659354773F, + 0.9660515263F, 0.9661673013F, 0.9662828024F, 0.9663980300F, + 0.9665129845F, 0.9666276660F, 0.9667420750F, 0.9668562118F, + 0.9669700766F, 0.9670836698F, 0.9671969917F, 0.9673100425F, + 0.9674228227F, 0.9675353325F, 0.9676475722F, 0.9677595422F, + 0.9678712428F, 0.9679826742F, 0.9680938368F, 0.9682047309F, + 0.9683153569F, 0.9684257150F, 0.9685358056F, 0.9686456289F, + 0.9687551853F, 0.9688644752F, 0.9689734987F, 0.9690822564F, + 0.9691907483F, 0.9692989750F, 0.9694069367F, 0.9695146337F, + 0.9696220663F, 0.9697292349F, 0.9698361398F, 0.9699427813F, + 0.9700491597F, 0.9701552754F, 0.9702611286F, 0.9703667197F, + 0.9704720490F, 0.9705771169F, 0.9706819236F, 0.9707864695F, + 0.9708907549F, 0.9709947802F, 0.9710985456F, 0.9712020514F, + 0.9713052981F, 0.9714082859F, 0.9715110151F, 0.9716134862F, + 0.9717156993F, 0.9718176549F, 0.9719193532F, 0.9720207946F, + 0.9721219794F, 0.9722229080F, 0.9723235806F, 0.9724239976F, + 0.9725241593F, 0.9726240661F, 0.9727237183F, 0.9728231161F, + 0.9729222601F, 0.9730211503F, 0.9731197873F, 0.9732181713F, + 0.9733163027F, 0.9734141817F, 0.9735118088F, 0.9736091842F, + 0.9737063083F, 0.9738031814F, 0.9738998039F, 0.9739961760F, + 0.9740922981F, 0.9741881706F, 0.9742837938F, 0.9743791680F, + 0.9744742935F, 0.9745691707F, 0.9746637999F, 0.9747581814F, + 0.9748523157F, 0.9749462029F, 0.9750398435F, 0.9751332378F, + 0.9752263861F, 0.9753192887F, 0.9754119461F, 0.9755043585F, + 0.9755965262F, 0.9756884496F, 0.9757801291F, 0.9758715650F, + 0.9759627575F, 0.9760537071F, 0.9761444141F, 0.9762348789F, + 0.9763251016F, 0.9764150828F, 0.9765048228F, 0.9765943218F, + 0.9766835802F, 0.9767725984F, 0.9768613767F, 0.9769499154F, + 0.9770382149F, 0.9771262755F, 0.9772140976F, 0.9773016815F, + 0.9773890275F, 0.9774761360F, 0.9775630073F, 0.9776496418F, + 0.9777360398F, 0.9778222016F, 0.9779081277F, 0.9779938182F, + 0.9780792736F, 0.9781644943F, 0.9782494805F, 0.9783342326F, + 0.9784187509F, 0.9785030359F, 0.9785870877F, 0.9786709069F, + 0.9787544936F, 0.9788378484F, 0.9789209714F, 0.9790038631F, + 0.9790865238F, 0.9791689538F, 0.9792511535F, 0.9793331232F, + 0.9794148633F, 0.9794963742F, 0.9795776561F, 0.9796587094F, + 0.9797395345F, 0.9798201316F, 0.9799005013F, 0.9799806437F, + 0.9800605593F, 0.9801402483F, 0.9802197112F, 0.9802989483F, + 0.9803779600F, 0.9804567465F, 0.9805353082F, 0.9806136455F, + 0.9806917587F, 0.9807696482F, 0.9808473143F, 0.9809247574F, + 0.9810019778F, 0.9810789759F, 0.9811557519F, 0.9812323064F, + 0.9813086395F, 0.9813847517F, 0.9814606433F, 0.9815363147F, + 0.9816117662F, 0.9816869981F, 0.9817620108F, 0.9818368047F, + 0.9819113801F, 0.9819857374F, 0.9820598769F, 0.9821337989F, + 0.9822075038F, 0.9822809920F, 0.9823542638F, 0.9824273195F, + 0.9825001596F, 0.9825727843F, 0.9826451940F, 0.9827173891F, + 0.9827893700F, 0.9828611368F, 0.9829326901F, 0.9830040302F, + 0.9830751574F, 0.9831460720F, 0.9832167745F, 0.9832872652F, + 0.9833575444F, 0.9834276124F, 0.9834974697F, 0.9835671166F, + 0.9836365535F, 0.9837057806F, 0.9837747983F, 0.9838436071F, + 0.9839122072F, 0.9839805990F, 0.9840487829F, 0.9841167591F, + 0.9841845282F, 0.9842520903F, 0.9843194459F, 0.9843865953F, + 0.9844535389F, 0.9845202771F, 0.9845868101F, 0.9846531383F, + 0.9847192622F, 0.9847851820F, 0.9848508980F, 0.9849164108F, + 0.9849817205F, 0.9850468276F, 0.9851117324F, 0.9851764352F, + 0.9852409365F, 0.9853052366F, 0.9853693358F, 0.9854332344F, + 0.9854969330F, 0.9855604317F, 0.9856237309F, 0.9856868310F, + 0.9857497325F, 0.9858124355F, 0.9858749404F, 0.9859372477F, + 0.9859993577F, 0.9860612707F, 0.9861229871F, 0.9861845072F, + 0.9862458315F, 0.9863069601F, 0.9863678936F, 0.9864286322F, + 0.9864891764F, 0.9865495264F, 0.9866096826F, 0.9866696454F, + 0.9867294152F, 0.9867889922F, 0.9868483769F, 0.9869075695F, + 0.9869665706F, 0.9870253803F, 0.9870839991F, 0.9871424273F, + 0.9872006653F, 0.9872587135F, 0.9873165721F, 0.9873742415F, + 0.9874317222F, 0.9874890144F, 0.9875461185F, 0.9876030348F, + 0.9876597638F, 0.9877163057F, 0.9877726610F, 0.9878288300F, + 0.9878848130F, 0.9879406104F, 0.9879962225F, 0.9880516497F, + 0.9881068924F, 0.9881619509F, 0.9882168256F, 0.9882715168F, + 0.9883260249F, 0.9883803502F, 0.9884344931F, 0.9884884539F, + 0.9885422331F, 0.9885958309F, 0.9886492477F, 0.9887024838F, + 0.9887555397F, 0.9888084157F, 0.9888611120F, 0.9889136292F, + 0.9889659675F, 0.9890181273F, 0.9890701089F, 0.9891219128F, + 0.9891735392F, 0.9892249885F, 0.9892762610F, 0.9893273572F, + 0.9893782774F, 0.9894290219F, 0.9894795911F, 0.9895299853F, + 0.9895802049F, 0.9896302502F, 0.9896801217F, 0.9897298196F, + 0.9897793443F, 0.9898286961F, 0.9898778755F, 0.9899268828F, + 0.9899757183F, 0.9900243823F, 0.9900728753F, 0.9901211976F, + 0.9901693495F, 0.9902173314F, 0.9902651436F, 0.9903127865F, + 0.9903602605F, 0.9904075659F, 0.9904547031F, 0.9905016723F, + 0.9905484740F, 0.9905951086F, 0.9906415763F, 0.9906878775F, + 0.9907340126F, 0.9907799819F, 0.9908257858F, 0.9908714247F, + 0.9909168988F, 0.9909622086F, 0.9910073543F, 0.9910523364F, + 0.9910971552F, 0.9911418110F, 0.9911863042F, 0.9912306351F, + 0.9912748042F, 0.9913188117F, 0.9913626580F, 0.9914063435F, + 0.9914498684F, 0.9914932333F, 0.9915364383F, 0.9915794839F, + 0.9916223703F, 0.9916650981F, 0.9917076674F, 0.9917500787F, + 0.9917923323F, 0.9918344286F, 0.9918763679F, 0.9919181505F, + 0.9919597769F, 0.9920012473F, 0.9920425621F, 0.9920837217F, + 0.9921247263F, 0.9921655765F, 0.9922062724F, 0.9922468145F, + 0.9922872030F, 0.9923274385F, 0.9923675211F, 0.9924074513F, + 0.9924472294F, 0.9924868557F, 0.9925263306F, 0.9925656544F, + 0.9926048275F, 0.9926438503F, 0.9926827230F, 0.9927214461F, + 0.9927600199F, 0.9927984446F, 0.9928367208F, 0.9928748486F, + 0.9929128285F, 0.9929506608F, 0.9929883459F, 0.9930258841F, + 0.9930632757F, 0.9931005211F, 0.9931376207F, 0.9931745747F, + 0.9932113836F, 0.9932480476F, 0.9932845671F, 0.9933209425F, + 0.9933571742F, 0.9933932623F, 0.9934292074F, 0.9934650097F, + 0.9935006696F, 0.9935361874F, 0.9935715635F, 0.9936067982F, + 0.9936418919F, 0.9936768448F, 0.9937116574F, 0.9937463300F, + 0.9937808629F, 0.9938152565F, 0.9938495111F, 0.9938836271F, + 0.9939176047F, 0.9939514444F, 0.9939851465F, 0.9940187112F, + 0.9940521391F, 0.9940854303F, 0.9941185853F, 0.9941516044F, + 0.9941844879F, 0.9942172361F, 0.9942498495F, 0.9942823283F, + 0.9943146729F, 0.9943468836F, 0.9943789608F, 0.9944109047F, + 0.9944427158F, 0.9944743944F, 0.9945059408F, 0.9945373553F, + 0.9945686384F, 0.9945997902F, 0.9946308112F, 0.9946617017F, + 0.9946924621F, 0.9947230926F, 0.9947535937F, 0.9947839656F, + 0.9948142086F, 0.9948443232F, 0.9948743097F, 0.9949041683F, + 0.9949338995F, 0.9949635035F, 0.9949929807F, 0.9950223315F, + 0.9950515561F, 0.9950806549F, 0.9951096282F, 0.9951384764F, + 0.9951671998F, 0.9951957987F, 0.9952242735F, 0.9952526245F, + 0.9952808520F, 0.9953089564F, 0.9953369380F, 0.9953647971F, + 0.9953925340F, 0.9954201491F, 0.9954476428F, 0.9954750153F, + 0.9955022670F, 0.9955293981F, 0.9955564092F, 0.9955833003F, + 0.9956100720F, 0.9956367245F, 0.9956632582F, 0.9956896733F, + 0.9957159703F, 0.9957421494F, 0.9957682110F, 0.9957941553F, + 0.9958199828F, 0.9958456937F, 0.9958712884F, 0.9958967672F, + 0.9959221305F, 0.9959473784F, 0.9959725115F, 0.9959975300F, + 0.9960224342F, 0.9960472244F, 0.9960719011F, 0.9960964644F, + 0.9961209148F, 0.9961452525F, 0.9961694779F, 0.9961935913F, + 0.9962175930F, 0.9962414834F, 0.9962652627F, 0.9962889313F, + 0.9963124895F, 0.9963359377F, 0.9963592761F, 0.9963825051F, + 0.9964056250F, 0.9964286361F, 0.9964515387F, 0.9964743332F, + 0.9964970198F, 0.9965195990F, 0.9965420709F, 0.9965644360F, + 0.9965866946F, 0.9966088469F, 0.9966308932F, 0.9966528340F, + 0.9966746695F, 0.9966964001F, 0.9967180260F, 0.9967395475F, + 0.9967609651F, 0.9967822789F, 0.9968034894F, 0.9968245968F, + 0.9968456014F, 0.9968665036F, 0.9968873037F, 0.9969080019F, + 0.9969285987F, 0.9969490942F, 0.9969694889F, 0.9969897830F, + 0.9970099769F, 0.9970300708F, 0.9970500651F, 0.9970699601F, + 0.9970897561F, 0.9971094533F, 0.9971290522F, 0.9971485531F, + 0.9971679561F, 0.9971872617F, 0.9972064702F, 0.9972255818F, + 0.9972445968F, 0.9972635157F, 0.9972823386F, 0.9973010659F, + 0.9973196980F, 0.9973382350F, 0.9973566773F, 0.9973750253F, + 0.9973932791F, 0.9974114392F, 0.9974295059F, 0.9974474793F, + 0.9974653599F, 0.9974831480F, 0.9975008438F, 0.9975184476F, + 0.9975359598F, 0.9975533806F, 0.9975707104F, 0.9975879495F, + 0.9976050981F, 0.9976221566F, 0.9976391252F, 0.9976560043F, + 0.9976727941F, 0.9976894950F, 0.9977061073F, 0.9977226312F, + 0.9977390671F, 0.9977554152F, 0.9977716759F, 0.9977878495F, + 0.9978039361F, 0.9978199363F, 0.9978358501F, 0.9978516780F, + 0.9978674202F, 0.9978830771F, 0.9978986488F, 0.9979141358F, + 0.9979295383F, 0.9979448566F, 0.9979600909F, 0.9979752417F, + 0.9979903091F, 0.9980052936F, 0.9980201952F, 0.9980350145F, + 0.9980497515F, 0.9980644067F, 0.9980789804F, 0.9980934727F, + 0.9981078841F, 0.9981222147F, 0.9981364649F, 0.9981506350F, + 0.9981647253F, 0.9981787360F, 0.9981926674F, 0.9982065199F, + 0.9982202936F, 0.9982339890F, 0.9982476062F, 0.9982611456F, + 0.9982746074F, 0.9982879920F, 0.9983012996F, 0.9983145304F, + 0.9983276849F, 0.9983407632F, 0.9983537657F, 0.9983666926F, + 0.9983795442F, 0.9983923208F, 0.9984050226F, 0.9984176501F, + 0.9984302033F, 0.9984426827F, 0.9984550884F, 0.9984674208F, + 0.9984796802F, 0.9984918667F, 0.9985039808F, 0.9985160227F, + 0.9985279926F, 0.9985398909F, 0.9985517177F, 0.9985634734F, + 0.9985751583F, 0.9985867727F, 0.9985983167F, 0.9986097907F, + 0.9986211949F, 0.9986325297F, 0.9986437953F, 0.9986549919F, + 0.9986661199F, 0.9986771795F, 0.9986881710F, 0.9986990946F, + 0.9987099507F, 0.9987207394F, 0.9987314611F, 0.9987421161F, + 0.9987527045F, 0.9987632267F, 0.9987736829F, 0.9987840734F, + 0.9987943985F, 0.9988046584F, 0.9988148534F, 0.9988249838F, + 0.9988350498F, 0.9988450516F, 0.9988549897F, 0.9988648641F, + 0.9988746753F, 0.9988844233F, 0.9988941086F, 0.9989037313F, + 0.9989132918F, 0.9989227902F, 0.9989322269F, 0.9989416021F, + 0.9989509160F, 0.9989601690F, 0.9989693613F, 0.9989784931F, + 0.9989875647F, 0.9989965763F, 0.9990055283F, 0.9990144208F, + 0.9990232541F, 0.9990320286F, 0.9990407443F, 0.9990494016F, + 0.9990580008F, 0.9990665421F, 0.9990750257F, 0.9990834519F, + 0.9990918209F, 0.9991001331F, 0.9991083886F, 0.9991165877F, + 0.9991247307F, 0.9991328177F, 0.9991408491F, 0.9991488251F, + 0.9991567460F, 0.9991646119F, 0.9991724232F, 0.9991801801F, + 0.9991878828F, 0.9991955316F, 0.9992031267F, 0.9992106684F, + 0.9992181569F, 0.9992255925F, 0.9992329753F, 0.9992403057F, + 0.9992475839F, 0.9992548101F, 0.9992619846F, 0.9992691076F, + 0.9992761793F, 0.9992832001F, 0.9992901701F, 0.9992970895F, + 0.9993039587F, 0.9993107777F, 0.9993175470F, 0.9993242667F, + 0.9993309371F, 0.9993375583F, 0.9993441307F, 0.9993506545F, + 0.9993571298F, 0.9993635570F, 0.9993699362F, 0.9993762678F, + 0.9993825519F, 0.9993887887F, 0.9993949785F, 0.9994011216F, + 0.9994072181F, 0.9994132683F, 0.9994192725F, 0.9994252307F, + 0.9994311434F, 0.9994370107F, 0.9994428327F, 0.9994486099F, + 0.9994543423F, 0.9994600303F, 0.9994656739F, 0.9994712736F, + 0.9994768294F, 0.9994823417F, 0.9994878105F, 0.9994932363F, + 0.9994986191F, 0.9995039592F, 0.9995092568F, 0.9995145122F, + 0.9995197256F, 0.9995248971F, 0.9995300270F, 0.9995351156F, + 0.9995401630F, 0.9995451695F, 0.9995501352F, 0.9995550604F, + 0.9995599454F, 0.9995647903F, 0.9995695953F, 0.9995743607F, + 0.9995790866F, 0.9995837734F, 0.9995884211F, 0.9995930300F, + 0.9995976004F, 0.9996021324F, 0.9996066263F, 0.9996110822F, + 0.9996155004F, 0.9996198810F, 0.9996242244F, 0.9996285306F, + 0.9996327999F, 0.9996370326F, 0.9996412287F, 0.9996453886F, + 0.9996495125F, 0.9996536004F, 0.9996576527F, 0.9996616696F, + 0.9996656512F, 0.9996695977F, 0.9996735094F, 0.9996773865F, + 0.9996812291F, 0.9996850374F, 0.9996888118F, 0.9996925523F, + 0.9996962591F, 0.9996999325F, 0.9997035727F, 0.9997071798F, + 0.9997107541F, 0.9997142957F, 0.9997178049F, 0.9997212818F, + 0.9997247266F, 0.9997281396F, 0.9997315209F, 0.9997348708F, + 0.9997381893F, 0.9997414767F, 0.9997447333F, 0.9997479591F, + 0.9997511544F, 0.9997543194F, 0.9997574542F, 0.9997605591F, + 0.9997636342F, 0.9997666797F, 0.9997696958F, 0.9997726828F, + 0.9997756407F, 0.9997785698F, 0.9997814703F, 0.9997843423F, + 0.9997871860F, 0.9997900016F, 0.9997927894F, 0.9997955494F, + 0.9997982818F, 0.9998009869F, 0.9998036648F, 0.9998063157F, + 0.9998089398F, 0.9998115373F, 0.9998141082F, 0.9998166529F, + 0.9998191715F, 0.9998216642F, 0.9998241311F, 0.9998265724F, + 0.9998289884F, 0.9998313790F, 0.9998337447F, 0.9998360854F, + 0.9998384015F, 0.9998406930F, 0.9998429602F, 0.9998452031F, + 0.9998474221F, 0.9998496171F, 0.9998517885F, 0.9998539364F, + 0.9998560610F, 0.9998581624F, 0.9998602407F, 0.9998622962F, + 0.9998643291F, 0.9998663394F, 0.9998683274F, 0.9998702932F, + 0.9998722370F, 0.9998741589F, 0.9998760591F, 0.9998779378F, + 0.9998797952F, 0.9998816313F, 0.9998834464F, 0.9998852406F, + 0.9998870141F, 0.9998887670F, 0.9998904995F, 0.9998922117F, + 0.9998939039F, 0.9998955761F, 0.9998972285F, 0.9998988613F, + 0.9999004746F, 0.9999020686F, 0.9999036434F, 0.9999051992F, + 0.9999067362F, 0.9999082544F, 0.9999097541F, 0.9999112354F, + 0.9999126984F, 0.9999141433F, 0.9999155703F, 0.9999169794F, + 0.9999183709F, 0.9999197449F, 0.9999211014F, 0.9999224408F, + 0.9999237631F, 0.9999250684F, 0.9999263570F, 0.9999276289F, + 0.9999288843F, 0.9999301233F, 0.9999313461F, 0.9999325529F, + 0.9999337437F, 0.9999349187F, 0.9999360780F, 0.9999372218F, + 0.9999383503F, 0.9999394635F, 0.9999405616F, 0.9999416447F, + 0.9999427129F, 0.9999437665F, 0.9999448055F, 0.9999458301F, + 0.9999468404F, 0.9999478365F, 0.9999488185F, 0.9999497867F, + 0.9999507411F, 0.9999516819F, 0.9999526091F, 0.9999535230F, + 0.9999544236F, 0.9999553111F, 0.9999561856F, 0.9999570472F, + 0.9999578960F, 0.9999587323F, 0.9999595560F, 0.9999603674F, + 0.9999611666F, 0.9999619536F, 0.9999627286F, 0.9999634917F, + 0.9999642431F, 0.9999649828F, 0.9999657110F, 0.9999664278F, + 0.9999671334F, 0.9999678278F, 0.9999685111F, 0.9999691835F, + 0.9999698451F, 0.9999704960F, 0.9999711364F, 0.9999717662F, + 0.9999723858F, 0.9999729950F, 0.9999735942F, 0.9999741834F, + 0.9999747626F, 0.9999753321F, 0.9999758919F, 0.9999764421F, + 0.9999769828F, 0.9999775143F, 0.9999780364F, 0.9999785495F, + 0.9999790535F, 0.9999795485F, 0.9999800348F, 0.9999805124F, + 0.9999809813F, 0.9999814417F, 0.9999818938F, 0.9999823375F, + 0.9999827731F, 0.9999832005F, 0.9999836200F, 0.9999840316F, + 0.9999844353F, 0.9999848314F, 0.9999852199F, 0.9999856008F, + 0.9999859744F, 0.9999863407F, 0.9999866997F, 0.9999870516F, + 0.9999873965F, 0.9999877345F, 0.9999880656F, 0.9999883900F, + 0.9999887078F, 0.9999890190F, 0.9999893237F, 0.9999896220F, + 0.9999899140F, 0.9999901999F, 0.9999904796F, 0.9999907533F, + 0.9999910211F, 0.9999912830F, 0.9999915391F, 0.9999917896F, + 0.9999920345F, 0.9999922738F, 0.9999925077F, 0.9999927363F, + 0.9999929596F, 0.9999931777F, 0.9999933907F, 0.9999935987F, + 0.9999938018F, 0.9999940000F, 0.9999941934F, 0.9999943820F, + 0.9999945661F, 0.9999947456F, 0.9999949206F, 0.9999950912F, + 0.9999952575F, 0.9999954195F, 0.9999955773F, 0.9999957311F, + 0.9999958807F, 0.9999960265F, 0.9999961683F, 0.9999963063F, + 0.9999964405F, 0.9999965710F, 0.9999966979F, 0.9999968213F, + 0.9999969412F, 0.9999970576F, 0.9999971707F, 0.9999972805F, + 0.9999973871F, 0.9999974905F, 0.9999975909F, 0.9999976881F, + 0.9999977824F, 0.9999978738F, 0.9999979624F, 0.9999980481F, + 0.9999981311F, 0.9999982115F, 0.9999982892F, 0.9999983644F, + 0.9999984370F, 0.9999985072F, 0.9999985750F, 0.9999986405F, + 0.9999987037F, 0.9999987647F, 0.9999988235F, 0.9999988802F, + 0.9999989348F, 0.9999989873F, 0.9999990379F, 0.9999990866F, + 0.9999991334F, 0.9999991784F, 0.9999992217F, 0.9999992632F, + 0.9999993030F, 0.9999993411F, 0.9999993777F, 0.9999994128F, + 0.9999994463F, 0.9999994784F, 0.9999995091F, 0.9999995384F, + 0.9999995663F, 0.9999995930F, 0.9999996184F, 0.9999996426F, + 0.9999996657F, 0.9999996876F, 0.9999997084F, 0.9999997282F, + 0.9999997469F, 0.9999997647F, 0.9999997815F, 0.9999997973F, + 0.9999998123F, 0.9999998265F, 0.9999998398F, 0.9999998524F, + 0.9999998642F, 0.9999998753F, 0.9999998857F, 0.9999998954F, + 0.9999999045F, 0.9999999130F, 0.9999999209F, 0.9999999282F, + 0.9999999351F, 0.9999999414F, 0.9999999472F, 0.9999999526F, + 0.9999999576F, 0.9999999622F, 0.9999999664F, 0.9999999702F, + 0.9999999737F, 0.9999999769F, 0.9999999798F, 0.9999999824F, + 0.9999999847F, 0.9999999868F, 0.9999999887F, 0.9999999904F, + 0.9999999919F, 0.9999999932F, 0.9999999943F, 0.9999999953F, + 0.9999999961F, 0.9999999969F, 0.9999999975F, 0.9999999980F, + 0.9999999985F, 0.9999999988F, 0.9999999991F, 0.9999999993F, + 0.9999999995F, 0.9999999997F, 0.9999999998F, 0.9999999999F, + 0.9999999999F, 1.0000000000F, 1.0000000000F, 1.0000000000F, + 1.0000000000F, 1.0000000000F, 1.0000000000F, 1.0000000000F, +}; + +const float ff_vorbis_floor1_inverse_db_table[256]={ + 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, + 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, + 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, + 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, + 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, + 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, + 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, + 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, + 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, + 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, + 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, + 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, + 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, + 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, + 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, + 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, + 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, + 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, + 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, + 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, + 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, + 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, + 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, + 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, + 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, + 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, + 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, + 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, + 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, + 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, + 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, + 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, + 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, + 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, + 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, + 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, + 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, + 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, + 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, + 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, + 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, + 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, + 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, + 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, + 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, + 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, + 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, + 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, + 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, + 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, + 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, + 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, + 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, + 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, + 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, + 0.82788260F, 0.88168307F, 0.9389798F, 1.F, +}; + +const float * ff_vorbis_vwin[8] = { vwin64, vwin128, vwin256, vwin512, vwin1024, vwin2048, vwin4096, vwin8192 }; + diff --git a/src/libffmpeg/libavcodec/vp5.c b/src/libffmpeg/libavcodec/vp5.c new file mode 100644 index 000000000..ac953c7aa --- /dev/null +++ b/src/libffmpeg/libavcodec/vp5.c @@ -0,0 +1,290 @@ +/** + * @file vp5.c + * VP5 compatible video decoder + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdlib.h> +#include <string.h> + +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" +#include "mpegvideo.h" + +#include "vp56.h" +#include "vp56data.h" +#include "vp5data.h" + + +static int vp5_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, + int *golden_frame) +{ + vp56_range_coder_t *c = &s->c; + int rows, cols; + + vp56_init_range_decoder(&s->c, buf, buf_size); + s->frames[VP56_FRAME_CURRENT].key_frame = !vp56_rac_get(c); + vp56_rac_get(c); + vp56_init_dequant(s, vp56_rac_gets(c, 6)); + if (s->frames[VP56_FRAME_CURRENT].key_frame) + { + vp56_rac_gets(c, 8); + if(vp56_rac_gets(c, 5) > 5) + return 0; + vp56_rac_gets(c, 2); + if (vp56_rac_get(c)) { + av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); + return 0; + } + rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ + cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ + vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ + vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ + vp56_rac_gets(c, 2); + if (16*cols != s->avctx->coded_width || + 16*rows != s->avctx->coded_height) { + avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); + return 2; + } + } + return 1; +} + +/* Gives very similar result than the vp6 version except in a few cases */ +static int vp5_adjust(int v, int t) +{ + int s2, s1 = v >> 31; + v ^= s1; + v -= s1; + v *= v < 2*t; + v -= t; + s2 = v >> 31; + v ^= s2; + v -= s2; + v = t - v; + v += s1; + v ^= s1; + return v; +} + +static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) +{ + vp56_range_coder_t *c = &s->c; + int comp, di; + + for (comp=0; comp<2; comp++) { + int delta = 0; + if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { + int sign = vp56_rac_get_prob(c, s->vector_model_sig[comp]); + di = vp56_rac_get_prob(c, s->vector_model_pdi[comp][0]); + di |= vp56_rac_get_prob(c, s->vector_model_pdi[comp][1]) << 1; + delta = vp56_rac_get_tree(c, vp56_pva_tree, + s->vector_model_pdv[comp]); + delta = di | (delta << 2); + delta = (delta ^ -sign) + sign; + } + if (!comp) + vect->x = delta; + else + vect->y = delta; + } +} + +static void vp5_parse_vector_models(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + int comp, node; + + for (comp=0; comp<2; comp++) { + if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) + s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); + if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) + s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); + if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) + s->vector_model_pdi[comp][0] = vp56_rac_gets_nn(c, 7); + if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) + s->vector_model_pdi[comp][1] = vp56_rac_gets_nn(c, 7); + } + + for (comp=0; comp<2; comp++) + for (node=0; node<7; node++) + if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) + s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); +} + +static void vp5_parse_coeff_models(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + uint8_t def_prob[11]; + int node, cg, ctx; + int ct; /* code type */ + int pt; /* plane type (0 for Y, 1 for U or V) */ + + memset(def_prob, 0x80, sizeof(def_prob)); + + for (pt=0; pt<2; pt++) + for (node=0; node<11; node++) + if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { + def_prob[node] = vp56_rac_gets_nn(c, 7); + s->coeff_model_dccv[pt][node] = def_prob[node]; + } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { + s->coeff_model_dccv[pt][node] = def_prob[node]; + } + + for (ct=0; ct<3; ct++) + for (pt=0; pt<2; pt++) + for (cg=0; cg<6; cg++) + for (node=0; node<11; node++) + if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { + def_prob[node] = vp56_rac_gets_nn(c, 7); + s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { + s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + } + + /* coeff_model_dcct is a linear combination of coeff_model_dccv */ + for (pt=0; pt<2; pt++) + for (ctx=0; ctx<36; ctx++) + for (node=0; node<5; node++) + s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); + + /* coeff_model_acct is a linear combination of coeff_model_ract */ + for (ct=0; ct<3; ct++) + for (pt=0; pt<2; pt++) + for (cg=0; cg<3; cg++) + for (ctx=0; ctx<6; ctx++) + for (node=0; node<5; node++) + s->coeff_model_acct[pt][ct][cg][ctx][node] = clip(((s->coeff_model_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); +} + +static void vp5_parse_coeff(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + uint8_t *permute = s->scantable.permutated; + uint8_t *model, *model2; + int coeff, sign, coeff_idx; + int b, i, cg, idx, ctx, ctx_last; + int pt = 0; /* plane type (0 for Y, 1 for U or V) */ + + for (b=0; b<6; b++) { + int ct = 1; /* code type */ + + if (b > 3) pt = 1; + + ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] + + s->above_blocks[s->above_block_idx[b]].not_null_dc; + model = s->coeff_model_dccv[pt]; + model2 = s->coeff_model_dcct[pt][ctx]; + + for (coeff_idx=0; coeff_idx<64; ) { + if (vp56_rac_get_prob(c, model2[0])) { + if (vp56_rac_get_prob(c, model2[2])) { + if (vp56_rac_get_prob(c, model2[3])) { + s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; + idx = vp56_rac_get_tree(c, vp56_pc_tree, model); + sign = vp56_rac_get(c); + coeff = vp56_coeff_bias[idx]; + for (i=vp56_coeff_bit_length[idx]; i>=0; i--) + coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; + } else { + if (vp56_rac_get_prob(c, model2[4])) { + coeff = 3 + vp56_rac_get_prob(c, model[5]); + s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; + } else { + coeff = 2; + s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2; + } + sign = vp56_rac_get(c); + } + ct = 2; + } else { + ct = 1; + s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1; + sign = vp56_rac_get(c); + coeff = 1; + } + coeff = (coeff ^ -sign) + sign; + if (coeff_idx) + coeff *= s->dequant_ac; + s->block_coeff[b][permute[coeff_idx]] = coeff; + } else { + if (ct && !vp56_rac_get_prob(c, model2[1])) + break; + ct = 0; + s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0; + } + + cg = vp5_coeff_groups[++coeff_idx]; + ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; + model = s->coeff_model_ract[pt][ct][cg]; + model2 = cg > 2 ? model : s->coeff_model_acct[pt][ct][cg][ctx]; + } + + ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); + s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx; + if (coeff_idx < ctx_last) + for (i=coeff_idx; i<=ctx_last; i++) + s->coeff_ctx[vp56_b6to4[b]][i] = 5; + s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0]; + } +} + +static void vp5_default_models_init(vp56_context_t *s) +{ + int i; + + for (i=0; i<2; i++) { + s->vector_model_sig[i] = 0x80; + s->vector_model_dct[i] = 0x80; + s->vector_model_pdi[i][0] = 0x55; + s->vector_model_pdi[i][1] = 0x80; + } + memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); + memset(s->vector_model_pdv, 0x80, sizeof(s->vector_model_pdv)); +} + +static int vp5_decode_init(AVCodecContext *avctx) +{ + vp56_context_t *s = avctx->priv_data; + + vp56_init(s, avctx, 1); + s->vp56_coord_div = vp5_coord_div; + s->parse_vector_adjustment = vp5_parse_vector_adjustment; + s->adjust = vp5_adjust; + s->parse_coeff = vp5_parse_coeff; + s->default_models_init = vp5_default_models_init; + s->parse_vector_models = vp5_parse_vector_models; + s->parse_coeff_models = vp5_parse_coeff_models; + s->parse_header = vp5_parse_header; + + return 0; +} + +AVCodec vp5_decoder = { + "vp5", + CODEC_TYPE_VIDEO, + CODEC_ID_VP5, + sizeof(vp56_context_t), + vp5_decode_init, + NULL, + vp56_free, + vp56_decode_frame, +}; diff --git a/src/libffmpeg/libavcodec/vp56.c b/src/libffmpeg/libavcodec/vp56.c new file mode 100644 index 000000000..eb78d02e4 --- /dev/null +++ b/src/libffmpeg/libavcodec/vp56.c @@ -0,0 +1,665 @@ +/** + * @file vp56.c + * VP5 and VP6 compatible video decoder (common features) + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" + +#include "vp56.h" +#include "vp56data.h" + + +void vp56_init_dequant(vp56_context_t *s, int quantizer) +{ + s->quantizer = quantizer; + s->dequant_dc = vp56_dc_dequant[quantizer] << 2; + s->dequant_ac = vp56_ac_dequant[quantizer] << 2; +} + +static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col, + vp56_frame_t ref_frame) +{ + int nb_pred = 0; + vp56_mv_t vect[2] = {{0,0}, {0,0}}; + int pos, offset; + vp56_mv_t mvp; + + for (pos=0; pos<12; pos++) { + mvp.x = col + vp56_candidate_predictor_pos[pos][0]; + mvp.y = row + vp56_candidate_predictor_pos[pos][1]; + if (mvp.x < 0 || mvp.x >= s->mb_width || + mvp.y < 0 || mvp.y >= s->mb_height) + continue; + offset = mvp.x + s->mb_width*mvp.y; + + if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame) + continue; + if ((s->macroblocks[offset].mv.x == vect[0].x && + s->macroblocks[offset].mv.y == vect[0].y) || + (s->macroblocks[offset].mv.x == 0 && + s->macroblocks[offset].mv.y == 0)) + continue; + + vect[nb_pred++] = s->macroblocks[offset].mv; + if (nb_pred > 1) { + nb_pred = -1; + break; + } + s->vector_candidate_pos = pos; + } + + s->vector_candidate[0] = vect[0]; + s->vector_candidate[1] = vect[1]; + + return nb_pred+1; +} + +static void vp56_parse_mb_type_models(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + int i, ctx, type; + + for (ctx=0; ctx<3; ctx++) { + if (vp56_rac_get_prob(c, 174)) { + int idx = vp56_rac_gets(c, 4); + memcpy(s->mb_types_stats[ctx],vp56_pre_def_mb_type_stats[idx][ctx], + sizeof(s->mb_types_stats[ctx])); + } + if (vp56_rac_get_prob(c, 254)) { + for (type=0; type<10; type++) { + for(i=0; i<2; i++) { + if (vp56_rac_get_prob(c, 205)) { + int delta, sign = vp56_rac_get(c); + + delta = vp56_rac_get_tree(c, vp56_pmbtm_tree, + vp56_mb_type_model_model); + if (!delta) + delta = 4 * vp56_rac_gets(c, 7); + s->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; + } + } + } + } + } + + /* compute MB type probability tables based on previous MB type */ + for (ctx=0; ctx<3; ctx++) { + int p[10]; + + for (type=0; type<10; type++) + p[type] = 100 * s->mb_types_stats[ctx][type][1]; + + for (type=0; type<10; type++) { + int p02, p34, p0234, p17, p56, p89, p5689, p156789; + + /* conservative MB type probability */ + s->mb_type_model[ctx][type][0] = 255 - (255 * s->mb_types_stats[ctx][type][0]) / (1 + s->mb_types_stats[ctx][type][0] + s->mb_types_stats[ctx][type][1]); + + p[type] = 0; /* same MB type => weight is null */ + + /* binary tree parsing probabilities */ + p02 = p[0] + p[2]; + p34 = p[3] + p[4]; + p0234 = p02 + p34; + p17 = p[1] + p[7]; + p56 = p[5] + p[6]; + p89 = p[8] + p[9]; + p5689 = p56 + p89; + p156789 = p17 + p5689; + + s->mb_type_model[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); + s->mb_type_model[ctx][type][2] = 1 + 255 * p02 / (1+p0234); + s->mb_type_model[ctx][type][3] = 1 + 255 * p17 / (1+p156789); + s->mb_type_model[ctx][type][4] = 1 + 255 * p[0] / (1+p02); + s->mb_type_model[ctx][type][5] = 1 + 255 * p[3] / (1+p34); + s->mb_type_model[ctx][type][6] = 1 + 255 * p[1] / (1+p17); + s->mb_type_model[ctx][type][7] = 1 + 255 * p56 / (1+p5689); + s->mb_type_model[ctx][type][8] = 1 + 255 * p[5] / (1+p56); + s->mb_type_model[ctx][type][9] = 1 + 255 * p[8] / (1+p89); + + /* restore initial value */ + p[type] = 100 * s->mb_types_stats[ctx][type][1]; + } + } +} + +static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s, + vp56_mb_t prev_type, int ctx) +{ + uint8_t *mb_type_model = s->mb_type_model[ctx][prev_type]; + vp56_range_coder_t *c = &s->c; + + if (vp56_rac_get_prob(c, mb_type_model[0])) + return prev_type; + else + return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model); +} + +static void vp56_decode_4mv(vp56_context_t *s, int row, int col) +{ + vp56_mv_t mv = {0,0}; + int type[4]; + int b; + + /* parse each block type */ + for (b=0; b<4; b++) { + type[b] = vp56_rac_gets(&s->c, 2); + if (type[b]) + type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */ + } + + /* get vectors */ + for (b=0; b<4; b++) { + switch (type[b]) { + case VP56_MB_INTER_NOVEC_PF: + s->mv[b] = (vp56_mv_t) {0,0}; + break; + case VP56_MB_INTER_DELTA_PF: + s->parse_vector_adjustment(s, &s->mv[b]); + break; + case VP56_MB_INTER_V1_PF: + s->mv[b] = s->vector_candidate[0]; + break; + case VP56_MB_INTER_V2_PF: + s->mv[b] = s->vector_candidate[1]; + break; + } + mv.x += s->mv[b].x; + mv.y += s->mv[b].y; + } + + /* this is the one selected for the whole MB for prediction */ + s->macroblocks[row * s->mb_width + col].mv = s->mv[3]; + + /* chroma vectors are average luma vectors */ + if (s->avctx->codec->id == CODEC_ID_VP5) { + s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2); + s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2); + } else { + s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4}; + } +} + +static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col) +{ + vp56_mv_t *mv, vect = {0,0}; + int ctx, b; + + ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS); + s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx); + s->macroblocks[row * s->mb_width + col].type = s->mb_type; + + switch (s->mb_type) { + case VP56_MB_INTER_V1_PF: + mv = &s->vector_candidate[0]; + break; + + case VP56_MB_INTER_V2_PF: + mv = &s->vector_candidate[1]; + break; + + case VP56_MB_INTER_V1_GF: + vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); + mv = &s->vector_candidate[0]; + break; + + case VP56_MB_INTER_V2_GF: + vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); + mv = &s->vector_candidate[1]; + break; + + case VP56_MB_INTER_DELTA_PF: + s->parse_vector_adjustment(s, &vect); + mv = &vect; + break; + + case VP56_MB_INTER_DELTA_GF: + vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN); + s->parse_vector_adjustment(s, &vect); + mv = &vect; + break; + + case VP56_MB_INTER_4V: + vp56_decode_4mv(s, row, col); + return s->mb_type; + + default: + mv = &vect; + break; + } + + s->macroblocks[row*s->mb_width + col].mv = *mv; + + /* same vector for all blocks */ + for (b=0; b<6; b++) + s->mv[b] = *mv; + + return s->mb_type; +} + +static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame) +{ + int idx = s->scantable.permutated[0]; + int i; + + for (i=0; i<6; i++) { + vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[i]]; + vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[i]]; + int count = 0; + int dc = 0; + + if (ref_frame == lb->ref_frame) { + dc += lb->dc_coeff; + count++; + } + if (ref_frame == ab->ref_frame) { + dc += ab->dc_coeff; + count++; + } + if (s->avctx->codec->id == CODEC_ID_VP5) { + if (count < 2 && ref_frame == ab[-1].ref_frame) { + dc += ab[-1].dc_coeff; + count++; + } + if (count < 2 && ref_frame == ab[1].ref_frame) { + dc += ab[1].dc_coeff; + count++; + } + } + if (count == 0) + dc = s->prev_dc[vp56_b6to3[i]][ref_frame]; + else if (count == 2) + dc /= 2; + + s->block_coeff[i][idx] += dc; + s->prev_dc[vp56_b6to3[i]][ref_frame] = s->block_coeff[i][idx]; + ab->dc_coeff = s->block_coeff[i][idx]; + ab->ref_frame = ref_frame; + lb->dc_coeff = s->block_coeff[i][idx]; + lb->ref_frame = ref_frame; + s->block_coeff[i][idx] *= s->dequant_dc; + } +} + +static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv, + int pix_inc, int line_inc, int t) +{ + int pix2_inc = 2 * pix_inc; + int i, v; + + for (i=0; i<12; i++) { + v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3; + v = s->adjust(v, t); + yuv[-pix_inc] = clip_uint8(yuv[-pix_inc] + v); + yuv[0] = clip_uint8(yuv[0] - v); + yuv += line_inc; + } +} + +static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv, + int stride, int dx, int dy) +{ + int t = vp56_filter_threshold[s->quantizer]; + if (dx) vp56_edge_filter(s, yuv + 10-dx , 1, stride, t); + if (dy) vp56_edge_filter(s, yuv + stride*(10-dy), stride, 1, t); +} + +static void vp56_mc(vp56_context_t *s, int b, uint8_t *src, + int stride, int x, int y) +{ + int plane = vp56_b6to3[b]; + uint8_t *dst= s->frames[VP56_FRAME_CURRENT].data[plane]+s->block_offset[b]; + uint8_t *src_block; + int src_offset; + int overlap_offset = 0; + int mask = s->vp56_coord_div[b] - 1; + int deblock_filtering = s->deblock_filtering; + int dx; + int dy; + + if (s->avctx->skip_loop_filter >= AVDISCARD_ALL || + (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY + && !s->frames[VP56_FRAME_CURRENT].key_frame)) + deblock_filtering = 0; + + dx = s->mv[b].x / s->vp56_coord_div[b]; + dy = s->mv[b].y / s->vp56_coord_div[b]; + + if (b >= 4) { + x /= 2; + y /= 2; + } + x += dx - 2; + y += dy - 2; + + if (x<0 || x+12>=s->plane_width[plane] || + y<0 || y+12>=s->plane_height[plane]) { + ff_emulated_edge_mc(s->edge_emu_buffer, + src + s->block_offset[b] + (dy-2)*stride + (dx-2), + stride, 12, 12, x, y, + s->plane_width[plane], + s->plane_height[plane]); + src_block = s->edge_emu_buffer; + src_offset = 2 + 2*stride; + } else if (deblock_filtering) { + /* only need a 12x12 block, but there is no such dsp function, */ + /* so copy a 16x12 block */ + s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer, + src + s->block_offset[b] + (dy-2)*stride + (dx-2), + stride, 12); + src_block = s->edge_emu_buffer; + src_offset = 2 + 2*stride; + } else { + src_block = src; + src_offset = s->block_offset[b] + dy*stride + dx; + } + + if (deblock_filtering) + vp56_deblock_filter(s, src_block, stride, dx&7, dy&7); + + if (s->mv[b].x & mask) + overlap_offset += (s->mv[b].x > 0) ? 1 : -1; + if (s->mv[b].y & mask) + overlap_offset += (s->mv[b].y > 0) ? stride : -stride; + + if (overlap_offset) { + if (s->filter) + s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset, + stride, s->mv[b], mask, s->filter_selection, b<4); + else + s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset, + src_block+src_offset+overlap_offset, + stride, 8); + } else { + s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8); + } +} + +static void vp56_decode_mb(vp56_context_t *s, int row, int col) +{ + AVFrame *frame_current, *frame_ref; + vp56_mb_t mb_type; + vp56_frame_t ref_frame; + int b, plan, off; + + if (s->frames[VP56_FRAME_CURRENT].key_frame) + mb_type = VP56_MB_INTRA; + else + mb_type = vp56_decode_mv(s, row, col); + ref_frame = vp56_reference_frame[mb_type]; + + memset(s->block_coeff, 0, sizeof(s->block_coeff)); + + s->parse_coeff(s); + + vp56_add_predictors_dc(s, ref_frame); + + frame_current = &s->frames[VP56_FRAME_CURRENT]; + frame_ref = &s->frames[ref_frame]; + + switch (mb_type) { + case VP56_MB_INTRA: + for (b=0; b<6; b++) { + plan = vp56_b6to3[b]; + s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b], + s->stride[plan], s->block_coeff[b]); + } + break; + + case VP56_MB_INTER_NOVEC_PF: + case VP56_MB_INTER_NOVEC_GF: + for (b=0; b<6; b++) { + plan = vp56_b6to3[b]; + off = s->block_offset[b]; + s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, + frame_ref->data[plan] + off, + s->stride[plan], 8); + s->dsp.idct_add(frame_current->data[plan] + off, + s->stride[plan], s->block_coeff[b]); + } + break; + + case VP56_MB_INTER_DELTA_PF: + case VP56_MB_INTER_V1_PF: + case VP56_MB_INTER_V2_PF: + case VP56_MB_INTER_DELTA_GF: + case VP56_MB_INTER_4V: + case VP56_MB_INTER_V1_GF: + case VP56_MB_INTER_V2_GF: + for (b=0; b<6; b++) { + int x_off = b==1 || b==3 ? 8 : 0; + int y_off = b==2 || b==3 ? 8 : 0; + plan = vp56_b6to3[b]; + vp56_mc(s, b, frame_ref->data[plan], s->stride[plan], + 16*col+x_off, 16*row+y_off); + s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], + s->stride[plan], s->block_coeff[b]); + } + break; + } +} + +static int vp56_size_changed(AVCodecContext *avctx, vp56_context_t *s) +{ + int stride = s->frames[VP56_FRAME_CURRENT].linesize[0]; + int i; + + s->plane_width[0] = s->avctx->coded_width; + s->plane_width[1] = s->plane_width[2] = s->avctx->coded_width/2; + s->plane_height[0] = s->avctx->coded_height; + s->plane_height[1] = s->plane_height[2] = s->avctx->coded_height/2; + + for (i=0; i<3; i++) + s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT].linesize[i]; + + s->mb_width = (s->avctx->coded_width+15) / 16; + s->mb_height = (s->avctx->coded_height+15) / 16; + + if (s->mb_width > 1000 || s->mb_height > 1000) { + av_log(avctx, AV_LOG_ERROR, "picture too big\n"); + return -1; + } + + s->above_blocks = av_realloc(s->above_blocks, + (4*s->mb_width+6) * sizeof(*s->above_blocks)); + s->macroblocks = av_realloc(s->macroblocks, + s->mb_width*s->mb_height*sizeof(*s->macroblocks)); + av_free(s->edge_emu_buffer_alloc); + s->edge_emu_buffer_alloc = av_malloc(16*stride); + s->edge_emu_buffer = s->edge_emu_buffer_alloc; + if (s->flip < 0) + s->edge_emu_buffer += 15 * stride; + + return 0; +} + +int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + vp56_context_t *s = avctx->priv_data; + AVFrame *const p = &s->frames[VP56_FRAME_CURRENT]; + AVFrame *picture = data; + int mb_row, mb_col, mb_row_flip, mb_offset = 0; + int block, y, uv, stride_y, stride_uv; + int golden_frame = 0; + int res; + + res = s->parse_header(s, buf, buf_size, &golden_frame); + if (!res) + return -1; + + p->reference = 1; + if (avctx->get_buffer(avctx, p) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + if (res == 2) + if (vp56_size_changed(avctx, s)) { + avctx->release_buffer(avctx, p); + return -1; + } + + if (p->key_frame) { + p->pict_type = FF_I_TYPE; + s->default_models_init(s); + for (block=0; block<s->mb_height*s->mb_width; block++) + s->macroblocks[block].type = VP56_MB_INTRA; + } else { + p->pict_type = FF_P_TYPE; + vp56_parse_mb_type_models(s); + s->parse_vector_models(s); + s->mb_type = VP56_MB_INTER_NOVEC_PF; + } + + s->parse_coeff_models(s); + + memset(s->prev_dc, 0, sizeof(s->prev_dc)); + s->prev_dc[1][VP56_FRAME_CURRENT] = 128; + s->prev_dc[2][VP56_FRAME_CURRENT] = 128; + + for (block=0; block < 4*s->mb_width+6; block++) { + s->above_blocks[block].ref_frame = -1; + s->above_blocks[block].dc_coeff = 0; + s->above_blocks[block].not_null_dc = 0; + } + s->above_blocks[2*s->mb_width + 2].ref_frame = 0; + s->above_blocks[3*s->mb_width + 4].ref_frame = 0; + + stride_y = p->linesize[0]; + stride_uv = p->linesize[1]; + + if (s->flip < 0) + mb_offset = 7; + + /* main macroblocks loop */ + for (mb_row=0; mb_row<s->mb_height; mb_row++) { + if (s->flip < 0) + mb_row_flip = s->mb_height - mb_row - 1; + else + mb_row_flip = mb_row; + + for (block=0; block<4; block++) { + s->left_block[block].ref_frame = -1; + s->left_block[block].dc_coeff = 0; + s->left_block[block].not_null_dc = 0; + memset(s->coeff_ctx[block], 0, 64*sizeof(s->coeff_ctx[block][0])); + } + memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); + + s->above_block_idx[0] = 1; + s->above_block_idx[1] = 2; + s->above_block_idx[2] = 1; + s->above_block_idx[3] = 2; + s->above_block_idx[4] = 2*s->mb_width + 2 + 1; + s->above_block_idx[5] = 3*s->mb_width + 4 + 1; + + s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; + s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; + s->block_offset[1] = s->block_offset[0] + 8; + s->block_offset[3] = s->block_offset[2] + 8; + s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; + s->block_offset[5] = s->block_offset[4]; + + for (mb_col=0; mb_col<s->mb_width; mb_col++) { + vp56_decode_mb(s, mb_row, mb_col); + + for (y=0; y<4; y++) { + s->above_block_idx[y] += 2; + s->block_offset[y] += 16; + } + + for (uv=4; uv<6; uv++) { + s->above_block_idx[uv] += 1; + s->block_offset[uv] += 8; + } + } + } + + if (s->frames[VP56_FRAME_PREVIOUS].data[0] + && (s->frames[VP56_FRAME_PREVIOUS].data[0] + != s->frames[VP56_FRAME_GOLDEN].data[0])) { + avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]); + } + if (p->key_frame || golden_frame) { + if (s->frames[VP56_FRAME_GOLDEN].data[0]) + avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]); + s->frames[VP56_FRAME_GOLDEN] = *p; + } + s->frames[VP56_FRAME_PREVIOUS] = *p; + + *picture = *p; + *data_size = sizeof(AVPicture); + + return buf_size; +} + +void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip) +{ + int i; + + s->avctx = avctx; + avctx->pix_fmt = PIX_FMT_YUV420P; + + if (s->avctx->idct_algo == FF_IDCT_AUTO) + s->avctx->idct_algo = FF_IDCT_VP3; + dsputil_init(&s->dsp, s->avctx); + ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); + + avcodec_set_dimensions(s->avctx, 0, 0); + + for (i=0; i<3; i++) + s->frames[i].data[0] = NULL; + s->edge_emu_buffer_alloc = NULL; + + s->above_blocks = NULL; + s->macroblocks = NULL; + s->quantizer = -1; + s->deblock_filtering = 1; + + s->filter = NULL; + + if (flip) { + s->flip = -1; + s->frbi = 2; + s->srbi = 0; + } else { + s->flip = 1; + s->frbi = 0; + s->srbi = 2; + } +} + +int vp56_free(AVCodecContext *avctx) +{ + vp56_context_t *s = avctx->priv_data; + + av_free(s->above_blocks); + av_free(s->macroblocks); + av_free(s->edge_emu_buffer_alloc); + if (s->frames[VP56_FRAME_GOLDEN].data[0] + && (s->frames[VP56_FRAME_PREVIOUS].data[0] + != s->frames[VP56_FRAME_GOLDEN].data[0])) + avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]); + if (s->frames[VP56_FRAME_PREVIOUS].data[0]) + avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]); + return 0; +} diff --git a/src/libffmpeg/libavcodec/vp56.h b/src/libffmpeg/libavcodec/vp56.h new file mode 100644 index 000000000..50e201550 --- /dev/null +++ b/src/libffmpeg/libavcodec/vp56.h @@ -0,0 +1,252 @@ +/** + * @file vp56.h + * VP5 and VP6 compatible video decoder (common features) + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef VP56_H +#define VP56_H + +#include "vp56data.h" +#include "dsputil.h" +#include "mpegvideo.h" + + +typedef struct vp56_context vp56_context_t; +typedef struct vp56_mv vp56_mv_t; + +typedef void (*vp56_parse_vector_adjustment_t)(vp56_context_t *s, + vp56_mv_t *vect); +typedef int (*vp56_adjust_t)(int v, int t); +typedef void (*vp56_filter_t)(vp56_context_t *s, uint8_t *dst, uint8_t *src, + int offset1, int offset2, int stride, + vp56_mv_t mv, int mask, int select, int luma); +typedef void (*vp56_parse_coeff_t)(vp56_context_t *s); +typedef void (*vp56_default_models_init_t)(vp56_context_t *s); +typedef void (*vp56_parse_vector_models_t)(vp56_context_t *s); +typedef void (*vp56_parse_coeff_models_t)(vp56_context_t *s); +typedef int (*vp56_parse_header_t)(vp56_context_t *s, uint8_t *buf, + int buf_size, int *golden_frame); + +typedef struct { + int high; + int bits; + const uint8_t *buffer; + unsigned long code_word; +} vp56_range_coder_t; + +typedef struct { + uint8_t not_null_dc; + vp56_frame_t ref_frame; + DCTELEM dc_coeff; +} vp56_ref_dc_t; + +struct vp56_mv { + int x; + int y; +}; + +typedef struct { + uint8_t type; + vp56_mv_t mv; +} vp56_macroblock_t; + +struct vp56_context { + AVCodecContext *avctx; + DSPContext dsp; + ScanTable scantable; + AVFrame frames[3]; + uint8_t *edge_emu_buffer_alloc; + uint8_t *edge_emu_buffer; + vp56_range_coder_t c; + vp56_range_coder_t cc; + vp56_range_coder_t *ccp; + int sub_version; + + /* frame info */ + int plane_width[3]; + int plane_height[3]; + int mb_width; /* number of horizontal MB */ + int mb_height; /* number of vertical MB */ + int block_offset[6]; + + int quantizer; + uint16_t dequant_dc; + uint16_t dequant_ac; + + /* DC predictors management */ + vp56_ref_dc_t *above_blocks; + vp56_ref_dc_t left_block[4]; + int above_block_idx[6]; + DCTELEM prev_dc[3][3]; /* [plan][ref_frame] */ + + /* blocks / macroblock */ + vp56_mb_t mb_type; + vp56_macroblock_t *macroblocks; + DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]); + uint8_t coeff_reorder[64]; /* used in vp6 only */ + uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ + + /* motion vectors */ + vp56_mv_t mv[6]; /* vectors for each block in MB */ + vp56_mv_t vector_candidate[2]; + int vector_candidate_pos; + + /* filtering hints */ + int filter_header; /* used in vp6 only */ + int deblock_filtering; + int filter_selection; + int filter_mode; + int max_vector_length; + int sample_variance_threshold; + + /* AC models */ + uint8_t vector_model_sig[2]; /* delta sign */ + uint8_t vector_model_dct[2]; /* delta coding types */ + uint8_t vector_model_pdi[2][2]; /* predefined delta init */ + uint8_t vector_model_pdv[2][7]; /* predefined delta values */ + uint8_t vector_model_fdv[2][8]; /* 8 bit delta value definition */ + uint8_t mb_type_model[3][10][10]; /* model for decoding MB type */ + uint8_t coeff_model_dccv[2][11]; /* DC coeff value */ + uint8_t coeff_model_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ + uint8_t coeff_model_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ + uint8_t coeff_model_dcct[2][36][5]; /* DC coeff coding type */ + uint8_t coeff_model_runv[2][14]; /* run value (vp6 only) */ + uint8_t mb_types_stats[3][10][2]; /* contextual, next MB type stats */ + uint8_t coeff_ctx[4][64]; /* used in vp5 only */ + uint8_t coeff_ctx_last[4]; /* used in vp5 only */ + + /* upside-down flipping hints */ + int flip; /* are we flipping ? */ + int frbi; /* first row block index in MB */ + int srbi; /* second row block index in MB */ + int stride[3]; /* stride for each plan */ + + const uint8_t *vp56_coord_div; + vp56_parse_vector_adjustment_t parse_vector_adjustment; + vp56_adjust_t adjust; + vp56_filter_t filter; + vp56_parse_coeff_t parse_coeff; + vp56_default_models_init_t default_models_init; + vp56_parse_vector_models_t parse_vector_models; + vp56_parse_coeff_models_t parse_coeff_models; + vp56_parse_header_t parse_header; +}; + + +void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip); +int vp56_free(AVCodecContext *avctx); +void vp56_init_dequant(vp56_context_t *s, int quantizer); +int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + uint8_t *buf, int buf_size); + + +/** + * vp56 specific range coder implementation + */ + +static inline void vp56_init_range_decoder(vp56_range_coder_t *c, + const uint8_t *buf, int buf_size) +{ + c->high = 255; + c->bits = 8; + c->buffer = buf; + c->code_word = *c->buffer++ << 8; + c->code_word |= *c->buffer++; +} + +static inline int vp56_rac_get_prob(vp56_range_coder_t *c, uint8_t prob) +{ + unsigned int low = 1 + (((c->high - 1) * prob) / 256); + unsigned int low_shift = low << 8; + int bit = c->code_word >= low_shift; + + if (bit) { + c->high -= low; + c->code_word -= low_shift; + } else { + c->high = low; + } + + /* normalize */ + while (c->high < 128) { + c->high <<= 1; + c->code_word <<= 1; + if (--c->bits == 0) { + c->bits = 8; + c->code_word |= *c->buffer++; + } + } + return bit; +} + +static inline int vp56_rac_get(vp56_range_coder_t *c) +{ + /* equiprobable */ + int low = (c->high + 1) >> 1; + unsigned int low_shift = low << 8; + int bit = c->code_word >= low_shift; + if (bit) { + c->high = (c->high - low) << 1; + c->code_word -= low_shift; + } else { + c->high = low << 1; + } + + /* normalize */ + c->code_word <<= 1; + if (--c->bits == 0) { + c->bits = 8; + c->code_word |= *c->buffer++; + } + return bit; +} + +static inline int vp56_rac_gets(vp56_range_coder_t *c, int bits) +{ + int value = 0; + + while (bits--) { + value = (value << 1) | vp56_rac_get(c); + } + + return value; +} + +static inline int vp56_rac_gets_nn(vp56_range_coder_t *c, int bits) +{ + int v = vp56_rac_gets(c, 7) << 1; + return v + !v; +} + +static inline int vp56_rac_get_tree(vp56_range_coder_t *c, + const vp56_tree_t *tree, + const uint8_t *probs) +{ + while (tree->val > 0) { + if (vp56_rac_get_prob(c, probs[tree->prob_idx])) + tree += tree->val; + else + tree++; + } + return -tree->val; +} + +#endif /* VP56_H */ diff --git a/src/libffmpeg/libavcodec/vp56data.c b/src/libffmpeg/libavcodec/vp56data.c new file mode 100644 index 000000000..e75c6d1ce --- /dev/null +++ b/src/libffmpeg/libavcodec/vp56data.c @@ -0,0 +1,66 @@ +/** + * @file vp56data.c + * VP5 and VP6 compatible video decoder (common data) + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "vp56data.h" + +const uint8_t vp56_b6to3[] = { 0, 0, 0, 0, 1, 2 }; +const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 }; + +const uint8_t vp56_coeff_parse_table[6][11] = { + { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0 }, + { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0 }, + { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254 }, +}; + +const uint8_t vp56_def_mb_types_stats[3][10][2] = { + { { 69, 42 }, { 1, 2 }, { 1, 7 }, { 44, 42 }, { 6, 22 }, + { 1, 3 }, { 0, 2 }, { 1, 5 }, { 0, 1 }, { 0, 0 }, }, + { { 229, 8 }, { 1, 1 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, + { 1, 2 }, { 0, 1 }, { 0, 0 }, { 1, 1 }, { 0, 0 }, }, + { { 122, 35 }, { 1, 1 }, { 1, 6 }, { 46, 34 }, { 0, 0 }, + { 1, 2 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, +}; + +const vp56_tree_t vp56_pva_tree[] = { + { 8, 0}, + { 4, 1}, + { 2, 2}, {-0}, {-1}, + { 2, 3}, {-2}, {-3}, + { 4, 4}, + { 2, 5}, {-4}, {-5}, + { 2, 6}, {-6}, {-7}, +}; + +const vp56_tree_t vp56_pc_tree[] = { + { 4, 6}, + { 2, 7}, {-0}, {-1}, + { 4, 8}, + { 2, 9}, {-2}, {-3}, + { 2,10}, {-4}, {-5}, +}; + +const uint8_t vp56_coeff_bias[] = { 5, 7, 11, 19, 35, 67 }; +const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 }; diff --git a/src/libffmpeg/libavcodec/vp56data.h b/src/libffmpeg/libavcodec/vp56data.h new file mode 100644 index 000000000..dbf92dd68 --- /dev/null +++ b/src/libffmpeg/libavcodec/vp56data.h @@ -0,0 +1,248 @@ +/** + * @file vp56data.h + * VP5 and VP6 compatible video decoder (common data) + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef VP56DATA_H +#define VP56DATA_H + +#include "common.h" + +typedef enum { + VP56_FRAME_CURRENT = 0, + VP56_FRAME_PREVIOUS = 1, + VP56_FRAME_GOLDEN = 2, +} vp56_frame_t; + +typedef enum { + VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ + VP56_MB_INTRA = 1, /**< Intra MB */ + VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ + VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ + VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ + VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ + VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ + VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ + VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ + VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ +} vp56_mb_t; + +typedef struct { + int8_t val; + int8_t prob_idx; +} vp56_tree_t; + +extern const uint8_t vp56_b6to3[]; +extern const uint8_t vp56_b6to4[]; +extern const uint8_t vp56_coeff_parse_table[6][11]; +extern const uint8_t vp56_def_mb_types_stats[3][10][2]; +extern const vp56_tree_t vp56_pva_tree[]; +extern const vp56_tree_t vp56_pc_tree[]; +extern const uint8_t vp56_coeff_bias[]; +extern const uint8_t vp56_coeff_bit_length[]; + +static const vp56_frame_t vp56_reference_frame[] = { + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_NOVEC_PF */ + VP56_FRAME_CURRENT, /* VP56_MB_INTRA */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_DELTA_PF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V1_PF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_V2_PF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_NOVEC_GF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_DELTA_GF */ + VP56_FRAME_PREVIOUS, /* VP56_MB_INTER_4V */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V1_GF */ + VP56_FRAME_GOLDEN, /* VP56_MB_INTER_V2_GF */ +}; + +static const uint8_t vp56_ac_dequant[64] = { + 94, 92, 90, 88, 86, 82, 78, 74, + 70, 66, 62, 58, 54, 53, 52, 51, + 50, 49, 48, 47, 46, 45, 44, 43, + 42, 40, 39, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1, +}; + +static const uint8_t vp56_dc_dequant[64] = { + 47, 47, 47, 47, 45, 43, 43, 43, + 43, 43, 42, 41, 41, 40, 40, 40, + 40, 35, 35, 35, 35, 33, 33, 33, + 33, 32, 32, 32, 27, 27, 26, 26, + 25, 25, 24, 24, 23, 23, 19, 19, + 19, 19, 18, 18, 17, 16, 16, 16, + 16, 16, 15, 11, 11, 11, 10, 10, + 9, 8, 7, 5, 3, 3, 2, 2, +}; + +static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = { + { { { 9, 15 }, { 32, 25 }, { 7, 19 }, { 9, 21 }, { 1, 12 }, + { 14, 12 }, { 3, 18 }, { 14, 23 }, { 3, 10 }, { 0, 4 }, }, + { { 41, 22 }, { 1, 0 }, { 1, 31 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 1, 7 }, { 0, 1 }, { 98, 25 }, { 4, 10 }, }, + { { 2, 3 }, { 2, 3 }, { 0, 2 }, { 0, 2 }, { 0, 0 }, + { 11, 4 }, { 1, 4 }, { 0, 2 }, { 3, 2 }, { 0, 4 }, }, }, + { { { 48, 39 }, { 1, 2 }, { 11, 27 }, { 29, 44 }, { 7, 27 }, + { 1, 4 }, { 0, 3 }, { 1, 6 }, { 1, 2 }, { 0, 0 }, }, + { { 123, 37 }, { 6, 4 }, { 1, 27 }, { 0, 0 }, { 0, 0 }, + { 5, 8 }, { 1, 7 }, { 0, 1 }, { 12, 10 }, { 0, 2 }, }, + { { 49, 46 }, { 3, 4 }, { 7, 31 }, { 42, 41 }, { 0, 0 }, + { 2, 6 }, { 1, 7 }, { 1, 4 }, { 2, 4 }, { 0, 1 }, }, }, + { { { 21, 32 }, { 1, 2 }, { 4, 10 }, { 32, 43 }, { 6, 23 }, + { 2, 3 }, { 1, 19 }, { 1, 6 }, { 12, 21 }, { 0, 7 }, }, + { { 26, 14 }, { 14, 12 }, { 0, 24 }, { 0, 0 }, { 0, 0 }, + { 55, 17 }, { 1, 9 }, { 0, 36 }, { 5, 7 }, { 1, 3 }, }, + { { 26, 25 }, { 1, 1 }, { 2, 10 }, { 67, 39 }, { 0, 0 }, + { 1, 1 }, { 0, 14 }, { 0, 2 }, { 31, 26 }, { 1, 6 }, }, }, + { { { 69, 83 }, { 0, 0 }, { 0, 2 }, { 10, 29 }, { 3, 12 }, + { 0, 1 }, { 0, 3 }, { 0, 3 }, { 2, 2 }, { 0, 0 }, }, + { { 209, 5 }, { 0, 0 }, { 0, 27 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 103, 46 }, { 1, 2 }, { 2, 10 }, { 33, 42 }, { 0, 0 }, + { 1, 4 }, { 0, 3 }, { 0, 1 }, { 1, 3 }, { 0, 0 }, }, }, + { { { 11, 20 }, { 1, 4 }, { 18, 36 }, { 43, 48 }, { 13, 35 }, + { 0, 2 }, { 0, 5 }, { 3, 12 }, { 1, 2 }, { 0, 0 }, }, + { { 2, 5 }, { 4, 5 }, { 0, 121 }, { 0, 0 }, { 0, 0 }, + { 0, 3 }, { 2, 4 }, { 1, 4 }, { 2, 2 }, { 0, 1 }, }, + { { 14, 31 }, { 9, 13 }, { 14, 54 }, { 22, 29 }, { 0, 0 }, + { 2, 6 }, { 4, 18 }, { 6, 13 }, { 1, 5 }, { 0, 1 }, }, }, + { { { 70, 44 }, { 0, 1 }, { 2, 10 }, { 37, 46 }, { 8, 26 }, + { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 175, 5 }, { 0, 1 }, { 0, 48 }, { 0, 0 }, { 0, 0 }, + { 0, 2 }, { 0, 1 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 85, 39 }, { 0, 0 }, { 1, 9 }, { 69, 40 }, { 0, 0 }, + { 0, 1 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 0 }, }, }, + { { { 8, 15 }, { 0, 1 }, { 8, 21 }, { 74, 53 }, { 22, 42 }, + { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 0, 0 }, }, + { { 83, 5 }, { 2, 3 }, { 0, 102 }, { 0, 0 }, { 0, 0 }, + { 1, 3 }, { 0, 2 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 31, 28 }, { 0, 0 }, { 3, 14 }, { 130, 34 }, { 0, 0 }, + { 0, 1 }, { 0, 3 }, { 0, 1 }, { 3, 3 }, { 0, 1 }, }, }, + { { { 141, 42 }, { 0, 0 }, { 1, 4 }, { 11, 24 }, { 1, 11 }, + { 0, 1 }, { 0, 1 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, }, + { { 233, 6 }, { 0, 0 }, { 0, 8 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, + { { 171, 25 }, { 0, 0 }, { 1, 5 }, { 25, 21 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, }, + { { { 8, 19 }, { 4, 10 }, { 24, 45 }, { 21, 37 }, { 9, 29 }, + { 0, 3 }, { 1, 7 }, { 11, 25 }, { 0, 2 }, { 0, 1 }, }, + { { 34, 16 }, { 112, 21 }, { 1, 28 }, { 0, 0 }, { 0, 0 }, + { 6, 8 }, { 1, 7 }, { 0, 3 }, { 2, 5 }, { 0, 2 }, }, + { { 17, 21 }, { 68, 29 }, { 6, 15 }, { 13, 22 }, { 0, 0 }, + { 6, 12 }, { 3, 14 }, { 4, 10 }, { 1, 7 }, { 0, 3 }, }, }, + { { { 46, 42 }, { 0, 1 }, { 2, 10 }, { 54, 51 }, { 10, 30 }, + { 0, 2 }, { 0, 2 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, + { { 159, 35 }, { 2, 2 }, { 0, 25 }, { 0, 0 }, { 0, 0 }, + { 3, 6 }, { 0, 5 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, + { { 51, 39 }, { 0, 1 }, { 2, 12 }, { 91, 44 }, { 0, 0 }, + { 0, 2 }, { 0, 3 }, { 0, 1 }, { 2, 3 }, { 0, 1 }, }, }, + { { { 28, 32 }, { 0, 0 }, { 3, 10 }, { 75, 51 }, { 14, 33 }, + { 0, 1 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, + { { 75, 39 }, { 5, 7 }, { 2, 48 }, { 0, 0 }, { 0, 0 }, + { 3, 11 }, { 2, 16 }, { 1, 4 }, { 7, 10 }, { 0, 2 }, }, + { { 81, 25 }, { 0, 0 }, { 2, 9 }, { 106, 26 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, + { { { 100, 46 }, { 0, 1 }, { 3, 9 }, { 21, 37 }, { 5, 20 }, + { 0, 1 }, { 0, 2 }, { 1, 2 }, { 0, 1 }, { 0, 0 }, }, + { { 212, 21 }, { 0, 1 }, { 0, 9 }, { 0, 0 }, { 0, 0 }, + { 1, 2 }, { 0, 2 }, { 0, 0 }, { 2, 2 }, { 0, 0 }, }, + { { 140, 37 }, { 0, 1 }, { 1, 8 }, { 24, 33 }, { 0, 0 }, + { 1, 2 }, { 0, 2 }, { 0, 1 }, { 1, 2 }, { 0, 0 }, }, }, + { { { 27, 29 }, { 0, 1 }, { 9, 25 }, { 53, 51 }, { 12, 34 }, + { 0, 1 }, { 0, 3 }, { 1, 5 }, { 0, 2 }, { 0, 0 }, }, + { { 4, 2 }, { 0, 0 }, { 0, 172 }, { 0, 0 }, { 0, 0 }, + { 0, 1 }, { 0, 2 }, { 0, 0 }, { 2, 0 }, { 0, 0 }, }, + { { 14, 23 }, { 1, 3 }, { 11, 53 }, { 90, 31 }, { 0, 0 }, + { 0, 3 }, { 1, 5 }, { 2, 6 }, { 1, 2 }, { 0, 0 }, }, }, + { { { 80, 38 }, { 0, 0 }, { 1, 4 }, { 69, 33 }, { 5, 16 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 1 }, { 0, 0 }, }, + { { 187, 22 }, { 1, 1 }, { 0, 17 }, { 0, 0 }, { 0, 0 }, + { 3, 6 }, { 0, 4 }, { 0, 1 }, { 4, 4 }, { 0, 1 }, }, + { { 123, 29 }, { 0, 0 }, { 1, 7 }, { 57, 30 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, }, }, + { { { 16, 20 }, { 0, 0 }, { 2, 8 }, { 104, 49 }, { 15, 33 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, + { { 133, 6 }, { 1, 2 }, { 1, 70 }, { 0, 0 }, { 0, 0 }, + { 0, 2 }, { 0, 4 }, { 0, 3 }, { 1, 1 }, { 0, 0 }, }, + { { 13, 14 }, { 0, 0 }, { 4, 20 }, { 175, 20 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 1, 1 }, { 0, 0 }, }, }, + { { { 194, 16 }, { 0, 0 }, { 1, 1 }, { 1, 9 }, { 1, 3 }, + { 0, 0 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, + { { 251, 1 }, { 0, 0 }, { 0, 2 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, }, + { { 202, 23 }, { 0, 0 }, { 1, 3 }, { 2, 9 }, { 0, 0 }, + { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, }, }, +}; + +static const uint8_t vp56_filter_threshold[] = { + 14, 14, 13, 13, 12, 12, 10, 10, + 10, 10, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, + 7, 7, 6, 6, 6, 6, 6, 6, + 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 3, 3, 3, 3, 2, +}; + +static const uint8_t vp56_mb_type_model_model[] = { + 171, 83, 199, 140, 125, 104, +}; + +static const vp56_tree_t vp56_pmbtm_tree[] = { + { 4, 0}, + { 2, 1}, {-8}, {-4}, + { 8, 2}, + { 6, 3}, + { 4, 4}, + { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0}, +}; + +static const vp56_tree_t vp56_pmbt_tree[] = { + { 8, 1}, + { 4, 2}, + { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF}, + { 2, 5}, {-VP56_MB_INTER_V1_PF}, {-VP56_MB_INTER_V2_PF}, + { 4, 3}, + { 2, 6}, {-VP56_MB_INTRA}, {-VP56_MB_INTER_4V}, + { 4, 7}, + { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF}, + { 2, 9}, {-VP56_MB_INTER_V1_GF}, {-VP56_MB_INTER_V2_GF}, +}; + +/* relative pos of surrounding blocks, from closest to farthest */ +static const int8_t vp56_candidate_predictor_pos[12][2] = { + { 0, -1 }, + { -1, 0 }, + { -1, -1 }, + { 1, -1 }, + { 0, -2 }, + { -2, 0 }, + { -2, -1 }, + { -1, -2 }, + { 1, -2 }, + { 2, -1 }, + { -2, -2 }, + { 2, -2 }, +}; + +#endif /* VP56DATA */ diff --git a/src/libffmpeg/libavcodec/vp5data.h b/src/libffmpeg/libavcodec/vp5data.h new file mode 100644 index 000000000..effc17c2c --- /dev/null +++ b/src/libffmpeg/libavcodec/vp5data.h @@ -0,0 +1,173 @@ +/** + * @file vp5data.h + * VP5 compatible video decoder + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef VP5DATA_H +#define VP5DATA_H + +static const uint8_t vp5_coeff_groups[] = { + -1, 0, 1, 1, 2, 1, 1, 2, + 2, 1, 1, 2, 2, 2, 1, 2, + 2, 2, 2, 2, 1, 1, 2, 2, + 3, 3, 4, 3, 4, 4, 4, 3, + 3, 3, 3, 3, 4, 3, 3, 3, + 4, 4, 4, 4, 4, 3, 3, 4, + 4, 4, 3, 4, 4, 4, 4, 4, + 4, 4, 5, 5, 5, 5, 5, 5, +}; + +static const uint8_t vp5_vmc_pct[2][11] = { + { 243, 220, 251, 253, 237, 232, 241, 245, 247, 251, 253 }, + { 235, 211, 246, 249, 234, 231, 248, 249, 252, 252, 254 }, +}; + +static const uint8_t vp5_dccv_pct[2][11] = { + { 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, + { 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 }, +}; + +static const uint8_t vp5_ract_pct[3][2][6][11] = { + { { { 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 }, + { 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 }, + { 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 }, + { 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 }, + { 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, + { { 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 }, + { 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, + { { { 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 }, + { 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 }, + { 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 }, + { 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 }, + { 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, + { { 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, + { { { 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 }, + { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 }, + { 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 }, + { 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 }, + { 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } }, + { { 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 }, + { 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 }, + { 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 }, + { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } }, +}; + +static const int16_t vp5_dccv_lc[5][36][2] = { + { {154, 61}, {141, 54}, { 90, 45}, { 54, 34}, { 54, 13}, {128, 109}, + {136, 54}, {148, 45}, { 92, 41}, { 54, 33}, { 51, 15}, { 87, 113}, + { 87, 44}, { 97, 40}, { 67, 36}, { 46, 29}, { 41, 15}, { 64, 80}, + { 59, 33}, { 61, 31}, { 51, 28}, { 44, 22}, { 33, 12}, { 49, 63}, + { 69, 12}, { 59, 16}, { 46, 14}, { 31, 13}, { 26, 6}, { 92, 26}, + {128, 108}, { 77, 119}, { 54, 84}, { 26, 71}, { 87, 19}, { 95, 155} }, + { {154, 4}, {182, 0}, {159, -8}, {128, -5}, {143, -5}, {187, 55}, + {182, 0}, {228, -3}, {187, -7}, {174, -9}, {189, -11}, {169, 79}, + {161, -9}, {192, -8}, {187, -9}, {169, -10}, {136, -9}, {184, 40}, + {164, -11}, {179, -10}, {174, -10}, {161, -10}, {115, -7}, {197, 20}, + {195, -11}, {195, -11}, {146, -10}, {110, -6}, { 95, -4}, {195, 39}, + {182, 55}, {172, 77}, {177, 37}, {169, 29}, {172, 52}, { 92, 162} }, + { {174, 80}, {164, 80}, { 95, 80}, { 46, 66}, { 56, 24}, { 36, 193}, + {164, 80}, {166, 77}, {105, 76}, { 49, 68}, { 46, 31}, { 49, 186}, + { 97, 78}, {110, 74}, { 72, 72}, { 44, 60}, { 33, 30}, { 69, 131}, + { 61, 61}, { 69, 63}, { 51, 57}, { 31, 48}, { 26, 27}, { 64, 89}, + { 67, 23}, { 51, 32}, { 36, 33}, { 26, 28}, { 20, 12}, { 44, 68}, + { 26, 197}, { 41, 189}, { 61, 129}, { 28, 103}, { 49, 52}, {-12, 245} }, + { {102, 141}, { 79, 166}, { 72, 162}, { 97, 125}, {179, 4}, {307, 0}, + { 72, 168}, { 69, 175}, { 84, 160}, {105, 127}, {148, 34}, {310, 0}, + { 84, 151}, { 82, 161}, { 87, 153}, { 87, 135}, {115, 51}, {317, 0}, + { 97, 125}, {102, 131}, {105, 125}, { 87, 122}, { 84, 64}, { 54, 184}, + {166, 18}, {146, 43}, {125, 51}, { 90, 64}, { 95, 7}, { 38, 154}, + {294, 0}, { 13, 225}, { 10, 225}, { 67, 168}, { 0, 167}, {161, 94} }, + { {172, 76}, {172, 75}, {136, 80}, { 64, 98}, { 74, 67}, {315, 0}, + {169, 76}, {207, 56}, {164, 66}, { 97, 80}, { 67, 72}, {328, 0}, + {136, 80}, {187, 53}, {154, 62}, { 72, 85}, { -2, 105}, {305, 0}, + { 74, 91}, {128, 64}, {113, 64}, { 61, 77}, { 41, 75}, {259, 0}, + { 46, 84}, { 51, 81}, { 28, 89}, { 31, 78}, { 23, 77}, {202, 0}, + {323, 0}, {323, 0}, {300, 0}, {236, 0}, {195, 0}, {328, 0} }, +}; + +static const int16_t vp5_ract_lc[3][3][5][6][2] = { + { { { {276, 0}, {238, 0}, {195, 0}, {156, 0}, {113, 0}, {274, 0} }, + { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, + { {192, 59}, {182, 50}, {141, 48}, {110, 40}, { 92, 19}, {125,128} }, + { {169, 87}, {169, 83}, {184, 62}, {220, 16}, {184, 0}, {264, 0} }, + { {212, 40}, {212, 36}, {169, 49}, {174, 27}, { 8,120}, {182, 71} } }, + { { {259, 10}, {197, 19}, {143, 22}, {123, 16}, {110, 8}, {133, 88} }, + { { 0, 1}, {256, 0}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, + { {207, 46}, {187, 50}, { 97, 83}, { 23,100}, { 41, 56}, { 56,188} }, + { {166, 90}, {146,108}, {161, 88}, {136, 95}, {174, 0}, {266, 0} }, + { {264, 7}, {243, 18}, {184, 43}, {-14,154}, { 20,112}, { 20,199} } }, + { { {230, 26}, {197, 22}, {159, 20}, {146, 12}, {136, 4}, { 54,162} }, + { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, + { {192, 59}, {156, 72}, { 84,101}, { 49,101}, { 79, 47}, { 79,167} }, + { {138,115}, {136,116}, {166, 80}, {238, 0}, {195, 0}, {261, 0} }, + { {225, 33}, {205, 42}, {159, 61}, { 79, 96}, { 92, 66}, { 28,195} } }, + }, { + { { {200, 37}, {197, 18}, {159, 13}, {143, 7}, {102, 5}, {123,126} }, + { {197, 3}, {220, -9}, {210,-12}, {187, -6}, {151, -2}, {174, 80} }, + { {200, 53}, {187, 47}, {159, 40}, {118, 38}, {100, 18}, {141,111} }, + { {179, 78}, {166, 86}, {197, 50}, {207, 27}, {187, 0}, {115,139} }, + { {218, 34}, {220, 29}, {174, 46}, {128, 61}, { 54, 89}, {187, 65} } }, + { { {238, 14}, {197, 18}, {125, 26}, { 90, 25}, { 82, 13}, {161, 86} }, + { {189, 1}, {205, -2}, {156, -4}, {143, -4}, {146, -4}, {172, 72} }, + { {230, 31}, {192, 45}, {102, 76}, { 38, 85}, { 56, 41}, { 64,173} }, + { {166, 91}, {141,111}, {128,116}, {118,109}, {177, 0}, { 23,222} }, + { {253, 14}, {236, 21}, {174, 49}, { 33,118}, { 44, 93}, { 23,187} } }, + { { {218, 28}, {179, 28}, {118, 35}, { 95, 30}, { 72, 24}, {128,108} }, + { {187, 1}, {174, -1}, {125, -1}, {110, -1}, {108, -1}, {202, 52} }, + { {197, 53}, {146, 75}, { 46,118}, { 33,103}, { 64, 50}, {118,126} }, + { {138,114}, {128,122}, {161, 86}, {243, -6}, {195, 0}, { 38,210} }, + { {215, 39}, {179, 58}, { 97,101}, { 95, 85}, { 87, 70}, { 69,152} } }, + }, { + { { {236, 24}, {205, 18}, {172, 12}, {154, 6}, {125, 1}, {169, 75} }, + { {187, 4}, {230, -2}, {228, -4}, {236, -4}, {241, -2}, {192, 66} }, + { {200, 46}, {187, 42}, {159, 34}, {136, 25}, {105, 10}, {179, 62} }, + { {207, 55}, {192, 63}, {192, 54}, {195, 36}, {177, 1}, {143, 98} }, + { {225, 27}, {207, 34}, {200, 30}, {131, 57}, { 97, 60}, {197, 45} } }, + { { {271, 8}, {218, 13}, {133, 19}, { 90, 19}, { 72, 7}, {182, 51} }, + { {179, 1}, {225, -1}, {154, -2}, {110, -1}, { 92, 0}, {195, 41} }, + { {241, 26}, {189, 40}, { 82, 64}, { 33, 60}, { 67, 17}, {120, 94} }, + { {192, 68}, {151, 94}, {146, 90}, {143, 72}, {161, 0}, {113,128} }, + { {256, 12}, {218, 29}, {166, 48}, { 44, 99}, { 31, 87}, {148, 78} } }, + { { {238, 20}, {184, 22}, {113, 27}, { 90, 22}, { 74, 9}, {192, 37} }, + { {184, 0}, {215, -1}, {141, -1}, { 97, 0}, { 49, 0}, {264, 13} }, + { {182, 51}, {138, 61}, { 95, 63}, { 54, 59}, { 64, 25}, {200, 45} }, + { {179, 75}, {156, 87}, {174, 65}, {177, 44}, {174, 0}, {164, 85} }, + { {195, 45}, {148, 65}, {105, 79}, { 95, 72}, { 87, 60}, {169, 63} } }, + } +}; + +static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 }; + +#endif /* VP5DATA_H */ diff --git a/src/libffmpeg/libavcodec/vp6.c b/src/libffmpeg/libavcodec/vp6.c new file mode 100644 index 000000000..df4ebf87d --- /dev/null +++ b/src/libffmpeg/libavcodec/vp6.c @@ -0,0 +1,556 @@ +/** + * @file vp6.c + * VP6 compatible video decoder + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The VP6F decoder accept an optional 1 byte extradata. It is composed of: + * - upper 4bits: difference between encoded width and visible width + * - lower 4bits: difference between encoded height and visible height + */ + +#include <stdlib.h> + +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" +#include "mpegvideo.h" + +#include "vp56.h" +#include "vp56data.h" +#include "vp6data.h" + + +static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, + int *golden_frame) +{ + vp56_range_coder_t *c = &s->c; + int parse_filter_info = 0; + int coeff_offset = 0; + int vrt_shift = 0; + int sub_version; + int rows, cols; + int res = 1; + int separated_coeff = buf[0] & 1; + + s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80); + vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); + + if (s->frames[VP56_FRAME_CURRENT].key_frame) { + sub_version = buf[1] >> 3; + if (sub_version > 8) + return 0; + s->filter_header = buf[1] & 0x06; + if (buf[1] & 1) { + av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); + return 0; + } + if (separated_coeff || !s->filter_header) { + coeff_offset = AV_RB16(buf+2) - 2; + buf += 2; + buf_size -= 2; + } + + rows = buf[2]; /* number of stored macroblock rows */ + cols = buf[3]; /* number of stored macroblock cols */ + /* buf[4] is number of displayed macroblock rows */ + /* buf[5] is number of displayed macroblock cols */ + + if (16*cols != s->avctx->coded_width || + 16*rows != s->avctx->coded_height) { + avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); + if (s->avctx->extradata_size == 1) { + s->avctx->width -= s->avctx->extradata[0] >> 4; + s->avctx->height -= s->avctx->extradata[0] & 0x0F; + } + res = 2; + } + + vp56_init_range_decoder(c, buf+6, buf_size-6); + vp56_rac_gets(c, 2); + + parse_filter_info = s->filter_header; + if (sub_version < 8) + vrt_shift = 5; + s->sub_version = sub_version; + } else { + if (!s->sub_version) + return 0; + + if (separated_coeff || !s->filter_header) { + coeff_offset = AV_RB16(buf+1) - 2; + buf += 2; + buf_size -= 2; + } + vp56_init_range_decoder(c, buf+1, buf_size-1); + + *golden_frame = vp56_rac_get(c); + if (s->filter_header) { + s->deblock_filtering = vp56_rac_get(c); + if (s->deblock_filtering) + vp56_rac_get(c); + if (s->sub_version > 7) + parse_filter_info = vp56_rac_get(c); + } + } + + if (parse_filter_info) { + if (vp56_rac_get(c)) { + s->filter_mode = 2; + s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift; + s->max_vector_length = 2 << vp56_rac_gets(c, 3); + } else if (vp56_rac_get(c)) { + s->filter_mode = 1; + } else { + s->filter_mode = 0; + } + if (s->sub_version > 7) + s->filter_selection = vp56_rac_gets(c, 4); + else + s->filter_selection = 16; + } + + vp56_rac_get(c); + + if (coeff_offset) { + vp56_init_range_decoder(&s->cc, buf+coeff_offset, + buf_size-coeff_offset); + s->ccp = &s->cc; + } else { + s->ccp = &s->c; + } + + return res; +} + +static void vp6_coeff_order_table_init(vp56_context_t *s) +{ + int i, pos, idx = 1; + + s->coeff_index_to_pos[0] = 0; + for (i=0; i<16; i++) + for (pos=1; pos<64; pos++) + if (s->coeff_reorder[pos] == i) + s->coeff_index_to_pos[idx++] = pos; +} + +static void vp6_default_models_init(vp56_context_t *s) +{ + s->vector_model_dct[0] = 0xA2; + s->vector_model_dct[1] = 0xA4; + s->vector_model_sig[0] = 0x80; + s->vector_model_sig[1] = 0x80; + + memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); + memcpy(s->vector_model_fdv, vp6_def_fdv_vector_model, sizeof(s->vector_model_fdv)); + memcpy(s->vector_model_pdv, vp6_def_pdv_vector_model, sizeof(s->vector_model_pdv)); + memcpy(s->coeff_model_runv, vp6_def_runv_coeff_model, sizeof(s->coeff_model_runv)); + memcpy(s->coeff_reorder, vp6_def_coeff_reorder, sizeof(s->coeff_reorder)); + + vp6_coeff_order_table_init(s); +} + +static void vp6_parse_vector_models(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + int comp, node; + + for (comp=0; comp<2; comp++) { + if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) + s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); + if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) + s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); + } + + for (comp=0; comp<2; comp++) + for (node=0; node<7; node++) + if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) + s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); + + for (comp=0; comp<2; comp++) + for (node=0; node<8; node++) + if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) + s->vector_model_fdv[comp][node] = vp56_rac_gets_nn(c, 7); +} + +static void vp6_parse_coeff_models(vp56_context_t *s) +{ + vp56_range_coder_t *c = &s->c; + int def_prob[11]; + int node, cg, ctx, pos; + int ct; /* code type */ + int pt; /* plane type (0 for Y, 1 for U or V) */ + + memset(def_prob, 0x80, sizeof(def_prob)); + + for (pt=0; pt<2; pt++) + for (node=0; node<11; node++) + if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { + def_prob[node] = vp56_rac_gets_nn(c, 7); + s->coeff_model_dccv[pt][node] = def_prob[node]; + } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { + s->coeff_model_dccv[pt][node] = def_prob[node]; + } + + if (vp56_rac_get(c)) { + for (pos=1; pos<64; pos++) + if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) + s->coeff_reorder[pos] = vp56_rac_gets(c, 4); + vp6_coeff_order_table_init(s); + } + + for (cg=0; cg<2; cg++) + for (node=0; node<14; node++) + if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) + s->coeff_model_runv[cg][node] = vp56_rac_gets_nn(c, 7); + + for (ct=0; ct<3; ct++) + for (pt=0; pt<2; pt++) + for (cg=0; cg<6; cg++) + for (node=0; node<11; node++) + if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { + def_prob[node] = vp56_rac_gets_nn(c, 7); + s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + } else if (s->frames[VP56_FRAME_CURRENT].key_frame) { + s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + } + + /* coeff_model_dcct is a linear combination of coeff_model_dccv */ + for (pt=0; pt<2; pt++) + for (ctx=0; ctx<3; ctx++) + for (node=0; node<5; node++) + s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); +} + +static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) +{ + vp56_range_coder_t *c = &s->c; + int comp; + + *vect = (vp56_mv_t) {0,0}; + if (s->vector_candidate_pos < 2) + *vect = s->vector_candidate[0]; + + for (comp=0; comp<2; comp++) { + int i, delta = 0; + + if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { + static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; + for (i=0; i<sizeof(prob_order); i++) { + int j = prob_order[i]; + delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][j])<<j; + } + if (delta & 0xF0) + delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][3])<<3; + else + delta |= 8; + } else { + delta = vp56_rac_get_tree(c, vp56_pva_tree, + s->vector_model_pdv[comp]); + } + + if (delta && vp56_rac_get_prob(c, s->vector_model_sig[comp])) + delta = -delta; + + if (!comp) + vect->x += delta; + else + vect->y += delta; + } +} + +static void vp6_parse_coeff(vp56_context_t *s) +{ + vp56_range_coder_t *c = s->ccp; + uint8_t *permute = s->scantable.permutated; + uint8_t *model, *model2, *model3; + int coeff, sign, coeff_idx; + int b, i, cg, idx, ctx; + int pt = 0; /* plane type (0 for Y, 1 for U or V) */ + + for (b=0; b<6; b++) { + int ct = 1; /* code type */ + int run = 1; + + if (b > 3) pt = 1; + + ctx = s->left_block[vp56_b6to4[b]].not_null_dc + + s->above_blocks[s->above_block_idx[b]].not_null_dc; + model = s->coeff_model_dccv[pt]; + model2 = s->coeff_model_dcct[pt][ctx]; + + for (coeff_idx=0; coeff_idx<64; ) { + if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { + /* parse a coeff */ + if (coeff_idx == 0) { + s->left_block[vp56_b6to4[b]].not_null_dc = 1; + s->above_blocks[s->above_block_idx[b]].not_null_dc = 1; + } + + if (vp56_rac_get_prob(c, model2[2])) { + if (vp56_rac_get_prob(c, model2[3])) { + idx = vp56_rac_get_tree(c, vp56_pc_tree, model); + coeff = vp56_coeff_bias[idx]; + for (i=vp56_coeff_bit_length[idx]; i>=0; i--) + coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; + } else { + if (vp56_rac_get_prob(c, model2[4])) + coeff = 3 + vp56_rac_get_prob(c, model[5]); + else + coeff = 2; + } + ct = 2; + } else { + ct = 1; + coeff = 1; + } + sign = vp56_rac_get(c); + coeff = (coeff ^ -sign) + sign; + if (coeff_idx) + coeff *= s->dequant_ac; + idx = s->coeff_index_to_pos[coeff_idx]; + s->block_coeff[b][permute[idx]] = coeff; + run = 1; + } else { + /* parse a run */ + ct = 0; + if (coeff_idx == 0) { + s->left_block[vp56_b6to4[b]].not_null_dc = 0; + s->above_blocks[s->above_block_idx[b]].not_null_dc = 0; + } else { + if (!vp56_rac_get_prob(c, model2[1])) + break; + + model3 = s->coeff_model_runv[coeff_idx >= 6]; + run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); + if (!run) + for (run=9, i=0; i<6; i++) + run += vp56_rac_get_prob(c, model3[i+8]) << i; + } + } + + cg = vp6_coeff_groups[coeff_idx+=run]; + model = model2 = s->coeff_model_ract[pt][ct][cg]; + } + } +} + +static int vp6_adjust(int v, int t) +{ + int V = v, s = v >> 31; + V ^= s; + V -= s; + if (V-t-1 >= (unsigned)(t-1)) + return v; + V = 2*t - V; + V += s; + V ^= s; + return V; +} + +static int vp6_block_variance(uint8_t *src, int stride) +{ + int sum = 0, square_sum = 0; + int y, x; + + for (y=0; y<8; y+=2) { + for (x=0; x<8; x+=2) { + sum += src[x]; + square_sum += src[x]*src[x]; + } + src += 2*stride; + } + return (16*square_sum - sum*sum) >> 8; +} + +static void vp6_filter_hv2(vp56_context_t *s, uint8_t *dst, uint8_t *src, + int stride, int delta, int16_t weight) +{ + s->dsp.put_pixels_tab[1][0](dst, src, stride, 8); + s->dsp.biweight_h264_pixels_tab[3](dst, src+delta, stride, 2, + 8-weight, weight, 0); +} + +static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, + int delta, const int16_t *weights) +{ + int x, y; + + for (y=0; y<8; y++) { + for (x=0; x<8; x++) { + dst[x] = clip_uint8(( src[x-delta ] * weights[0] + + src[x ] * weights[1] + + src[x+delta ] * weights[2] + + src[x+2*delta] * weights[3] + 64) >> 7); + } + src += stride; + dst += stride; + } +} + +static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src, + int stride, int h_weight, int v_weight) +{ + uint8_t *tmp = s->edge_emu_buffer+16; + int x, xmax; + + s->dsp.put_pixels_tab[1][0](tmp, src, stride, 8); + s->dsp.biweight_h264_pixels_tab[3](tmp, src+1, stride, 2, + 8-h_weight, h_weight, 0); + /* we need a 8x9 block to do vertical filter, so compute one more line */ + for (x=8*stride, xmax=x+8; x<xmax; x++) + tmp[x] = (src[x]*(8-h_weight) + src[x+1]*h_weight + 4) >> 3; + + s->dsp.put_pixels_tab[1][0](dst, tmp, stride, 8); + s->dsp.biweight_h264_pixels_tab[3](dst, tmp+stride, stride, 2, + 8-v_weight, v_weight, 0); +} + +static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride, + const int16_t *h_weights,const int16_t *v_weights) +{ + int x, y; + int tmp[8*11]; + int *t = tmp; + + src -= stride; + + for (y=0; y<11; y++) { + for (x=0; x<8; x++) { + t[x] = clip_uint8(( src[x-1] * h_weights[0] + + src[x ] * h_weights[1] + + src[x+1] * h_weights[2] + + src[x+2] * h_weights[3] + 64) >> 7); + } + src += stride; + t += 8; + } + + t = tmp + 8; + for (y=0; y<8; y++) { + for (x=0; x<8; x++) { + dst[x] = clip_uint8(( t[x-8 ] * v_weights[0] + + t[x ] * v_weights[1] + + t[x+8 ] * v_weights[2] + + t[x+16] * v_weights[3] + 64) >> 7); + } + dst += stride; + t += 8; + } +} + +static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src, + int offset1, int offset2, int stride, + vp56_mv_t mv, int mask, int select, int luma) +{ + int filter4 = 0; + int x8 = mv.x & mask; + int y8 = mv.y & mask; + + if (luma) { + x8 *= 2; + y8 *= 2; + filter4 = s->filter_mode; + if (filter4 == 2) { + if (s->max_vector_length && + (FFABS(mv.x) > s->max_vector_length || + FFABS(mv.y) > s->max_vector_length)) { + filter4 = 0; + } else if (s->sample_variance_threshold + && (vp6_block_variance(src+offset1, stride) + < s->sample_variance_threshold)) { + filter4 = 0; + } + } + } + + if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) { + offset1 = offset2; + } + + if (filter4) { + if (!y8) { /* left or right combine */ + vp6_filter_hv4(dst, src+offset1, stride, 1, + vp6_block_copy_filter[select][x8]); + } else if (!x8) { /* above or below combine */ + vp6_filter_hv4(dst, src+offset1, stride, stride, + vp6_block_copy_filter[select][y8]); + } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ + vp6_filter_diag4(dst, src+offset1-1, stride, + vp6_block_copy_filter[select][x8], + vp6_block_copy_filter[select][y8]); + } else { /* lower-right or upper-left combine */ + vp6_filter_diag4(dst, src+offset1, stride, + vp6_block_copy_filter[select][x8], + vp6_block_copy_filter[select][y8]); + } + } else { + if (!y8) { /* left or right combine */ + vp6_filter_hv2(s, dst, src+offset1, stride, 1, x8); + } else if (!x8) { /* above or below combine */ + vp6_filter_hv2(s, dst, src+offset1, stride, stride, y8); + } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ + vp6_filter_diag2(s, dst, src+offset1-1, stride, x8, y8); + } else { /* lower-right or upper-left combine */ + vp6_filter_diag2(s, dst, src+offset1, stride, x8, y8); + } + } +} + +static int vp6_decode_init(AVCodecContext *avctx) +{ + vp56_context_t *s = avctx->priv_data; + + vp56_init(s, avctx, avctx->codec->id == CODEC_ID_VP6); + s->vp56_coord_div = vp6_coord_div; + s->parse_vector_adjustment = vp6_parse_vector_adjustment; + s->adjust = vp6_adjust; + s->filter = vp6_filter; + s->parse_coeff = vp6_parse_coeff; + s->default_models_init = vp6_default_models_init; + s->parse_vector_models = vp6_parse_vector_models; + s->parse_coeff_models = vp6_parse_coeff_models; + s->parse_header = vp6_parse_header; + + return 0; +} + +AVCodec vp6_decoder = { + "vp6", + CODEC_TYPE_VIDEO, + CODEC_ID_VP6, + sizeof(vp56_context_t), + vp6_decode_init, + NULL, + vp56_free, + vp56_decode_frame, +}; + +/* flash version, not flipped upside-down */ +AVCodec vp6f_decoder = { + "vp6f", + CODEC_TYPE_VIDEO, + CODEC_ID_VP6F, + sizeof(vp56_context_t), + vp6_decode_init, + NULL, + vp56_free, + vp56_decode_frame, +}; diff --git a/src/libffmpeg/libavcodec/vp6data.h b/src/libffmpeg/libavcodec/vp6data.h new file mode 100644 index 000000000..0545a9d66 --- /dev/null +++ b/src/libffmpeg/libavcodec/vp6data.h @@ -0,0 +1,300 @@ +/** + * @file vp6data.h + * VP6 compatible video decoder + * + * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef VP6DATA_H +#define VP6DATA_H + +#include "vp56data.h" + +static const uint8_t vp6_def_fdv_vector_model[2][8] = { + { 247, 210, 135, 68, 138, 220, 239, 246 }, + { 244, 184, 201, 44, 173, 221, 239, 253 }, +}; + +static const uint8_t vp6_def_pdv_vector_model[2][7] = { + { 225, 146, 172, 147, 214, 39, 156 }, + { 204, 170, 119, 235, 140, 230, 228 }, +}; + +static const uint8_t vp6_def_coeff_reorder[] = { + 0, 0, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 3, 3, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 7, 7, + 7, 7, 7, 8, 8, 9, 9, 9, + 9, 9, 9, 10, 10, 11, 11, 11, + 11, 11, 11, 12, 12, 12, 12, 12, + 12, 13, 13, 13, 13, 13, 14, 14, + 14, 14, 15, 15, 15, 15, 15, 15, +}; + +static const uint8_t vp6_def_runv_coeff_model[2][14] = { + { 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 }, + { 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 }, +}; + +static const uint8_t vp6_sig_dct_pct[2][2] = { + { 237, 246 }, + { 231, 243 }, +}; + +static const uint8_t vp6_pdv_pct[2][7] = { + { 253, 253, 254, 254, 254, 254, 254 }, + { 245, 253, 254, 254, 254, 254, 254 }, +}; + +static const uint8_t vp6_fdv_pct[2][8] = { + { 254, 254, 254, 254, 254, 250, 250, 252 }, + { 254, 254, 254, 254, 254, 251, 251, 254 }, +}; + +static const uint8_t vp6_dccv_pct[2][11] = { + { 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 }, + { 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 }, +}; + +static const uint8_t vp6_coeff_reorder_pct[] = { + 255, 132, 132, 159, 153, 151, 161, 170, + 164, 162, 136, 110, 103, 114, 129, 118, + 124, 125, 132, 136, 114, 110, 142, 135, + 134, 123, 143, 126, 153, 183, 166, 161, + 171, 180, 179, 164, 203, 218, 225, 217, + 215, 206, 203, 217, 229, 241, 248, 243, + 253, 255, 253, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, +}; + +static const uint8_t vp6_runv_pct[2][14] = { + { 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 }, + { 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 }, +}; + +static const uint8_t vp6_ract_pct[3][2][6][11] = { + { { { 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 }, + { 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 }, + { 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, + { { 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, + { { { 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 }, + { 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 }, + { 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 }, + { 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 }, + { 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, + { { 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }, + { { { 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 }, + { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 }, + { 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 }, + { 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 }, + { 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } }, + { { 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 }, + { 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 }, + { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } } +}; + +static const int vp6_dccv_lc[3][5][2] = { + { { 122, 133 }, { 0, 1 }, { 78, 171 }, { 139, 117 }, { 168, 79 } }, + { { 133, 51 }, { 0, 1 }, { 169, 71 }, { 214, 44 }, { 210, 38 } }, + { { 142, -16 }, { 0, 1 }, { 221, -30 }, { 246, -3 }, { 203, 17 } }, +}; + +static const uint8_t vp6_coeff_groups[] = { + 0, 0, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, +}; + +static const int16_t vp6_block_copy_filter[17][8][4] = { + { { 0, 128, 0, 0 }, /* 0 */ + { -3, 122, 9, 0 }, + { -4, 109, 24, -1 }, + { -5, 91, 45, -3 }, + { -4, 68, 68, -4 }, + { -3, 45, 91, -5 }, + { -1, 24, 109, -4 }, + { 0, 9, 122, -3 } }, + { { 0, 128, 0, 0 }, /* 1 */ + { -4, 124, 9, -1 }, + { -5, 110, 25, -2 }, + { -6, 91, 46, -3 }, + { -5, 69, 69, -5 }, + { -3, 46, 91, -6 }, + { -2, 25, 110, -5 }, + { -1, 9, 124, -4 } }, + { { 0, 128, 0, 0 }, /* 2 */ + { -4, 123, 10, -1 }, + { -6, 110, 26, -2 }, + { -7, 92, 47, -4 }, + { -6, 70, 70, -6 }, + { -4, 47, 92, -7 }, + { -2, 26, 110, -6 }, + { -1, 10, 123, -4 } }, + { { 0, 128, 0, 0 }, /* 3 */ + { -5, 124, 10, -1 }, + { -7, 110, 27, -2 }, + { -7, 91, 48, -4 }, + { -6, 70, 70, -6 }, + { -4, 48, 92, -8 }, + { -2, 27, 110, -7 }, + { -1, 10, 124, -5 } }, + { { 0, 128, 0, 0 }, /* 4 */ + { -6, 124, 11, -1 }, + { -8, 111, 28, -3 }, + { -8, 92, 49, -5 }, + { -7, 71, 71, -7 }, + { -5, 49, 92, -8 }, + { -3, 28, 111, -8 }, + { -1, 11, 124, -6 } }, + { { 0, 128, 0, 0 }, /* 5 */ + { -6, 123, 12, -1 }, + { -9, 111, 29, -3 }, + { -9, 93, 50, -6 }, + { -8, 72, 72, -8 }, + { -6, 50, 93, -9 }, + { -3, 29, 111, -9 }, + { -1, 12, 123, -6 } }, + { { 0, 128, 0, 0 }, /* 6 */ + { -7, 124, 12, -1 }, + { -10, 111, 30, -3 }, + { -10, 93, 51, -6 }, + { -9, 73, 73, -9 }, + { -6, 51, 93, -10 }, + { -3, 30, 111, -10 }, + { -1, 12, 124, -7 } }, + { { 0, 128, 0, 0 }, /* 7 */ + { -7, 123, 13, -1 }, + { -11, 112, 31, -4 }, + { -11, 94, 52, -7 }, + { -10, 74, 74, -10 }, + { -7, 52, 94, -11 }, + { -4, 31, 112, -11 }, + { -1, 13, 123, -7 } }, + { { 0, 128, 0, 0 }, /* 8 */ + { -8, 124, 13, -1 }, + { -12, 112, 32, -4 }, + { -12, 94, 53, -7 }, + { -10, 74, 74, -10 }, + { -7, 53, 94, -12 }, + { -4, 32, 112, -12 }, + { -1, 13, 124, -8 } }, + { { 0, 128, 0, 0 }, /* 9 */ + { -9, 124, 14, -1 }, + { -13, 112, 33, -4 }, + { -13, 95, 54, -8 }, + { -11, 75, 75, -11 }, + { -8, 54, 95, -13 }, + { -4, 33, 112, -13 }, + { -1, 14, 124, -9 } }, + { { 0, 128, 0, 0 }, /* 10 */ + { -9, 123, 15, -1 }, + { -14, 113, 34, -5 }, + { -14, 95, 55, -8 }, + { -12, 76, 76, -12 }, + { -8, 55, 95, -14 }, + { -5, 34, 112, -13 }, + { -1, 15, 123, -9 } }, + { { 0, 128, 0, 0 }, /* 11 */ + { -10, 124, 15, -1 }, + { -14, 113, 34, -5 }, + { -15, 96, 56, -9 }, + { -13, 77, 77, -13 }, + { -9, 56, 96, -15 }, + { -5, 34, 113, -14 }, + { -1, 15, 124, -10 } }, + { { 0, 128, 0, 0 }, /* 12 */ + { -10, 123, 16, -1 }, + { -15, 113, 35, -5 }, + { -16, 98, 56, -10 }, + { -14, 78, 78, -14 }, + { -10, 56, 98, -16 }, + { -5, 35, 113, -15 }, + { -1, 16, 123, -10 } }, + { { 0, 128, 0, 0 }, /* 13 */ + { -11, 124, 17, -2 }, + { -16, 113, 36, -5 }, + { -17, 98, 57, -10 }, + { -14, 78, 78, -14 }, + { -10, 57, 98, -17 }, + { -5, 36, 113, -16 }, + { -2, 17, 124, -11 } }, + { { 0, 128, 0, 0 }, /* 14 */ + { -12, 125, 17, -2 }, + { -17, 114, 37, -6 }, + { -18, 99, 58, -11 }, + { -15, 79, 79, -15 }, + { -11, 58, 99, -18 }, + { -6, 37, 114, -17 }, + { -2, 17, 125, -12 } }, + { { 0, 128, 0, 0 }, /* 15 */ + { -12, 124, 18, -2 }, + { -18, 114, 38, -6 }, + { -19, 99, 59, -11 }, + { -16, 80, 80, -16 }, + { -11, 59, 99, -19 }, + { -6, 38, 114, -18 }, + { -2, 18, 124, -12 } }, + { { 0, 128, 0, 0 }, /* 16 */ + { -4, 118, 16, -2 }, + { -7, 106, 34, -5 }, + { -8, 90, 53, -7 }, + { -8, 72, 72, -8 }, + { -7, 53, 90, -8 }, + { -5, 34, 106, -7 }, + { -2, 16, 118, -4 } }, +}; + +static const vp56_tree_t vp6_pcr_tree[] = { + { 8, 0}, + { 4, 1}, + { 2, 2}, {-1}, {-2}, + { 2, 3}, {-3}, {-4}, + { 8, 4}, + { 4, 5}, + { 2, 6}, {-5}, {-6}, + { 2, 7}, {-7}, {-8}, + {-0}, +}; + +static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 }; + +#endif /* VP6DATA_H */ diff --git a/src/libffmpeg/libavcodec/wavpack.c b/src/libffmpeg/libavcodec/wavpack.c new file mode 100644 index 000000000..b462174da --- /dev/null +++ b/src/libffmpeg/libavcodec/wavpack.c @@ -0,0 +1,556 @@ +/* + * WavPack lossless audio decoder + * Copyright (c) 2006 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define ALT_BITSTREAM_READER_LE +#include "avcodec.h" +#include "bitstream.h" + +/** + * @file wavpack.c + * WavPack lossless audio decoder + */ + +#define WV_JOINT 0x0010 + +enum WP_ID_Flags{ + WP_IDF_MASK = 0x1F, + WP_IDF_IGNORE = 0x20, + WP_IDF_ODD = 0x40, + WP_IDF_LONG = 0x80 +}; + +enum WP_ID{ + WP_ID_DUMMY = 0, + WP_ID_ENCINFO, + WP_ID_DECTERMS, + WP_ID_DECWEIGHTS, + WP_ID_DECSAMPLES, + WP_ID_ENTROPY, + WP_ID_HYBRID, + WP_ID_SHAPING, + WP_ID_FLOATINFO, + WP_ID_INT32INFO, + WP_ID_DATA, + WP_ID_CORR, + WP_ID_FLT, + WP_ID_CHANINFO +}; + +#define MAX_TERMS 16 + +typedef struct Decorr { + int delta; + int value; + int weightA; + int weightB; + int samplesA[8]; + int samplesB[8]; +} Decorr; + +typedef struct WavpackContext { + AVCodecContext *avctx; + int stereo; + int joint; + uint32_t CRC; + GetBitContext gb; + int data_size; // in bits + int samples; + int median[6]; + int terms; + Decorr decorr[MAX_TERMS]; + int zero, one, zeroes; +} WavpackContext; + +// exponent table copied from WavPack source +static const uint8_t wp_exp2_table [256] = { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, + 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, + 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, + 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, + 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, + 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff +}; + +static av_always_inline int wp_exp2(int16_t val) +{ + int res, neg = 0; + + if(val < 0){ + val = -val; + neg = 1; + } + + res = wp_exp2_table[val & 0xFF] | 0x100; + val >>= 8; + res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); + return neg ? -res : res; +} + +static inline int get_unary(GetBitContext *gb){ + int r=0; + while(get_bits1(gb) && r<33)r++; + return r; +} + +// macros for manipulating median values +#define GET_MED(n) ((median[n] >> 4) + 1) +#define DEC_MED(n) median[n] -= ((median[n] + (128>>n) - 2) / (128>>n)) * 2 +#define INC_MED(n) median[n] += ((median[n] + (128>>n)) / (128>>n)) * 5 + +// macros for applying weight +#define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ + if(samples && in){ \ + if((samples ^ in) < 0){ \ + weight -= delta; \ + if(weight < -1024) weight = -1024; \ + }else{ \ + weight += delta; \ + if(weight > 1024) weight = 1024; \ + } \ + } + + +static av_always_inline int get_tail(GetBitContext *gb, int k) +{ + int p, e, res; + + if(k<1)return 0; + p = av_log2(k); + e = (1 << (p + 1)) - k - 1; + res = p ? get_bits(gb, p) : 0; + if(res >= e){ + res = (res<<1) - e + get_bits1(gb); + } + return res; +} + +static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int *last) +{ + int t, t2; + int sign, base, add, ret; + + *last = 0; + + if((ctx->median[0] < 2U) && (ctx->median[3] < 2U) && !ctx->zero && !ctx->one){ + if(ctx->zeroes){ + ctx->zeroes--; + if(ctx->zeroes) + return 0; + }else{ + t = get_unary(gb); + if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); + ctx->zeroes = t; + if(ctx->zeroes){ + memset(ctx->median, 0, sizeof(ctx->median)); + return 0; + } + } + } + + if(get_bits_count(gb) >= ctx->data_size){ + *last = 1; + return 0; + } + + if(ctx->zero){ + t = 0; + ctx->zero = 0; + }else{ + t = get_unary(gb); + if(get_bits_count(gb) >= ctx->data_size){ + *last = 1; + return 0; + } + if(t == 16) { + t2 = get_unary(gb); + if(t2 < 2) t += t2; + else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + } + + if(ctx->one){ + ctx->one = t&1; + t = (t>>1) + 1; + }else{ + ctx->one = t&1; + t >>= 1; + } + ctx->zero = !ctx->one; + } + + if(!t){ + base = 0; + add = GET_MED(0) - 1; + DEC_MED(0); + }else if(t == 1){ + base = GET_MED(0); + add = GET_MED(1) - 1; + INC_MED(0); + DEC_MED(1); + }else if(t == 2){ + base = GET_MED(0) + GET_MED(1); + add = GET_MED(2) - 1; + INC_MED(0); + INC_MED(1); + DEC_MED(2); + }else{ + base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2); + add = GET_MED(2) - 1; + INC_MED(0); + INC_MED(1); + INC_MED(2); + } + ret = base + get_tail(gb, add); + sign = get_bits1(gb); + return sign ? ~ret : ret; +} + +static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst) +{ + int i, j, count = 0; + int last, t; + int A, B, L, L2, R, R2; + int pos = 0; + uint32_t crc = 0xFFFFFFFF; + + s->one = s->zero = s->zeroes = 0; + do{ + L = wv_get_value(s, gb, s->median, &last); + if(last) break; + R = wv_get_value(s, gb, s->median + 3, &last); + if(last) break; + for(i = 0; i < s->terms; i++){ + t = s->decorr[i].value; + j = 0; + if(t > 0){ + if(t > 8){ + if(t & 1){ + A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; + B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]; + }else{ + A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; + B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1; + } + s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; + s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0]; + j = 0; + }else{ + A = s->decorr[i].samplesA[pos]; + B = s->decorr[i].samplesB[pos]; + j = (pos + t) & 7; + } + L2 = L + ((s->decorr[i].weightA * A + 512) >> 10); + R2 = R + ((s->decorr[i].weightB * B + 512) >> 10); + if(A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; + if(B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta; + s->decorr[i].samplesA[j] = L = L2; + s->decorr[i].samplesB[j] = R = R2; + }else if(t == -1){ + L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10); + UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L); + L = L2; + R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10); + UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R); + R = R2; + s->decorr[i].samplesA[0] = R; + }else{ + R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10); + UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R); + R = R2; + + if(t == -3){ + R2 = s->decorr[i].samplesA[0]; + s->decorr[i].samplesA[0] = R; + } + + L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10); + UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L); + L = L2; + s->decorr[i].samplesB[0] = L; + } + } + pos = (pos + 1) & 7; + if(s->joint) + L += (R -= (L >> 1)); + crc = (crc * 3 + L) * 3 + R; + *dst++ = L; + *dst++ = R; + + count++; + }while(!last && count < s->samples); + + if(crc != s->CRC){ + av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); + return -1; + } + return count * 2; +} + +static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst) +{ + int i, j, count = 0; + int last, t; + int A, S, T; + int pos = 0; + uint32_t crc = 0xFFFFFFFF; + + s->one = s->zero = s->zeroes = 0; + do{ + T = wv_get_value(s, gb, s->median, &last); + S = 0; + if(last) break; + for(i = 0; i < s->terms; i++){ + t = s->decorr[i].value; + if(t > 8){ + if(t & 1) + A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; + else + A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; + s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; + j = 0; + }else{ + A = s->decorr[i].samplesA[pos]; + j = (pos + t) & 7; + } + S = T + ((s->decorr[i].weightA * A + 512) >> 10); + if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; + s->decorr[i].samplesA[j] = T = S; + } + pos = (pos + 1) & 7; + crc = crc * 3 + S; + *dst++ = S; + count++; + }while(!last && count < s->samples); + + if(crc != s->CRC){ + av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); + return -1; + } + return count; +} + +static int wavpack_decode_init(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + + s->avctx = avctx; + s->stereo = (avctx->channels == 2); + + return 0; +} + +static int wavpack_decode_close(AVCodecContext *avctx) +{ +// WavpackContext *s = avctx->priv_data; + + return 0; +} + +static int wavpack_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + WavpackContext *s = avctx->priv_data; + int16_t *samples = data; + int samplecount; + int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0; + uint8_t* buf_end = buf + buf_size; + int i, j, id, size, ssize, weights, t; + + if (buf_size == 0) return 0; + + memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); + + s->samples = AV_RL32(buf); buf += 4; + if(!s->samples) return buf_size; + /* should not happen but who knows */ + if(s->samples * 2 * avctx->channels > AVCODEC_MAX_AUDIO_FRAME_SIZE){ + av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n"); + return -1; + } + s->joint = AV_RL32(buf) & WV_JOINT; buf += 4; + s->CRC = AV_RL32(buf); buf += 4; + // parse metadata blocks + while(buf < buf_end){ + id = *buf++; + size = *buf++; + if(id & WP_IDF_LONG) { + size |= (*buf++) << 8; + size |= (*buf++) << 16; + } + size <<= 1; // size is specified in words + ssize = size; + if(id & WP_IDF_ODD) size--; + if(size < 0){ + av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size); + break; + } + if(buf + ssize > buf_end){ + av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size); + break; + } + if(id & WP_IDF_IGNORE){ + buf += ssize; + continue; + } + switch(id & WP_IDF_MASK){ + case WP_ID_DECTERMS: + s->terms = size; + if(s->terms > MAX_TERMS){ + av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); + buf += ssize; + continue; + } + for(i = 0; i < s->terms; i++) { + s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5; + s->decorr[s->terms - i - 1].delta = *buf >> 5; + buf++; + } + got_terms = 1; + break; + case WP_ID_DECWEIGHTS: + if(!got_terms){ + av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); + continue; + } + weights = size >> s->stereo; + if(weights > MAX_TERMS || weights > s->terms){ + av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); + buf += ssize; + continue; + } + for(i = 0; i < weights; i++) { + t = (int8_t)(*buf++); + s->decorr[s->terms - i - 1].weightA = t << 3; + if(s->decorr[s->terms - i - 1].weightA > 0) + s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; + if(s->stereo){ + t = (int8_t)(*buf++); + s->decorr[s->terms - i - 1].weightB = t << 3; + if(s->decorr[s->terms - i - 1].weightB > 0) + s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; + } + } + got_weights = 1; + break; + case WP_ID_DECSAMPLES: + if(!got_terms){ + av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); + continue; + } + t = 0; + for(i = s->terms - 1; (i >= 0) && (t < size); i--) { + if(s->decorr[i].value > 8){ + s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; + if(s->stereo){ + s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; + t += 4; + } + t += 4; + }else if(s->decorr[i].value < 0){ + s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; + s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; + t += 4; + }else{ + for(j = 0; j < s->decorr[i].value; j++){ + s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; + if(s->stereo){ + s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; + } + } + t += s->decorr[i].value * 2 * avctx->channels; + } + } + got_samples = 1; + break; + case WP_ID_ENTROPY: + if(size != 6 * avctx->channels){ + av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * avctx->channels, size); + buf += ssize; + continue; + } + for(i = 0; i < 3 * avctx->channels; i++){ + s->median[i] = wp_exp2(AV_RL16(buf)); + buf += 2; + } + got_entropy = 1; + break; + case WP_ID_DATA: + init_get_bits(&s->gb, buf, size * 8); + s->data_size = size * 8; + buf += size; + got_bs = 1; + break; + default: + buf += size; + } + if(id & WP_IDF_ODD) buf++; + } + if(!got_terms){ + av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); + return -1; + } + if(!got_weights){ + av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); + return -1; + } + if(!got_samples){ + av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); + return -1; + } + if(!got_entropy){ + av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); + return -1; + } + if(!got_bs){ + av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); + return -1; + } + + if(s->stereo) + samplecount = wv_unpack_stereo(s, &s->gb, samples); + else + samplecount = wv_unpack_mono(s, &s->gb, samples); + *data_size = samplecount * 2; + + return buf_size; +} + +AVCodec wavpack_decoder = { + "wavpack", + CODEC_TYPE_AUDIO, + CODEC_ID_WAVPACK, + sizeof(WavpackContext), + wavpack_decode_init, + NULL, + wavpack_decode_close, + wavpack_decode_frame, +}; diff --git a/src/libspucc/.cvsignore b/src/libffmpeg/libavutil/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libspucc/.cvsignore +++ b/src/libffmpeg/libavutil/.hgignore diff --git a/src/libffmpeg/libavutil/intreadwrite.h b/src/libffmpeg/libavutil/intreadwrite.h new file mode 100644 index 000000000..e6db5ce6f --- /dev/null +++ b/src/libffmpeg/libavutil/intreadwrite.h @@ -0,0 +1,65 @@ +#ifndef INTREADWRITE_H +#define INTREADWRITE_H + +#ifdef __GNUC__ + +struct unaligned_64 { uint64_t l; } __attribute__((packed)); +struct unaligned_32 { uint32_t l; } __attribute__((packed)); +struct unaligned_16 { uint16_t l; } __attribute__((packed)); + +#define LD16(a) (((const struct unaligned_16 *) (a))->l) +#define LD32(a) (((const struct unaligned_32 *) (a))->l) +#define LD64(a) (((const struct unaligned_64 *) (a))->l) + +#define ST16(a, b) (((struct unaligned_16 *) (a))->l) = (b) +#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) + +#else /* __GNUC__ */ + +#define LD16(a) (*((uint16_t*)(a))) +#define LD32(a) (*((uint32_t*)(a))) +#define LD64(a) (*((uint64_t*)(a))) + +#define ST16(a, b) *((uint16_t*)(a)) = (b) +#define ST32(a, b) *((uint32_t*)(a)) = (b) + +#endif /* !__GNUC__ */ + +/* endian macros */ +#define AV_RB8(x) (((uint8_t*)(x))[0]) +#define AV_WB8(p, i, d) { ((uint8_t*)(p))[(i)] = (d); } + +#define AV_RB16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1]) +#define AV_WB16(p, i, d) { \ + ((uint8_t*)(p))[(i)+1] = (d); \ + ((uint8_t*)(p))[(i)] = (d)>>8; } + +#define AV_RB32(x) ((((uint8_t*)(x))[0] << 24) | \ + (((uint8_t*)(x))[1] << 16) | \ + (((uint8_t*)(x))[2] << 8) | \ + ((uint8_t*)(x))[3]) +#define AV_WB32(p, i, d) { \ + ((uint8_t*)(p))[(i)+3] = (d); \ + ((uint8_t*)(p))[(i)+2] = (d)>>8; \ + ((uint8_t*)(p))[(i)+1] = (d)>>16; \ + ((uint8_t*)(p))[(i)] = (d)>>24; } + +#define AV_RL8(x) AV_RB8(x) +#define AV_WL8(p, i, d) AV_WB8(p, i, d) + +#define AV_RL16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0]) +#define AV_WL16(p, i, d) { \ + ((uint8_t*)(p))[(i)] = (d); \ + ((uint8_t*)(p))[(i)+1] = (d)>>8; } + +#define AV_RL32(x) ((((uint8_t*)(x))[3] << 24) | \ + (((uint8_t*)(x))[2] << 16) | \ + (((uint8_t*)(x))[1] << 8) | \ + ((uint8_t*)(x))[0]) +#define AV_WL32(p, i, d) { \ + ((uint8_t*)(p))[(i)] = (d); \ + ((uint8_t*)(p))[(i)+1] = (d)>>8; \ + ((uint8_t*)(p))[(i)+2] = (d)>>16; \ + ((uint8_t*)(p))[(i)+3] = (d)>>24; } + +#endif /* INTREADWRITE_H */ diff --git a/src/libffmpeg/libavutil/mem.c b/src/libffmpeg/libavutil/mem.c new file mode 100644 index 000000000..f43fb5420 --- /dev/null +++ b/src/libffmpeg/libavutil/mem.c @@ -0,0 +1,171 @@ +/* + * default memory allocator for libavutil + * Copyright (c) 2002 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file mem.c + * default memory allocator for libavutil. + */ + +#include "common.h" + +/* here we can use OS dependant allocation functions */ +#undef malloc +#undef free +#undef realloc + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +/* you can redefine av_malloc and av_free in your project to use your + memory allocator. You do not need to suppress this file because the + linker will do it automatically */ + +/** + * Memory allocation of size byte with alignment suitable for all + * memory accesses (including vectors if available on the + * CPU). av_malloc(0) must return a non NULL pointer. + */ +void *av_malloc(unsigned int size) +{ + void *ptr; +#ifdef CONFIG_MEMALIGN_HACK + long diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#ifdef CONFIG_MEMALIGN_HACK + ptr = malloc(size+16); + if(!ptr) + return ptr; + diff= ((-(long)ptr - 1)&15) + 1; + ptr += diff; + ((char*)ptr)[-1]= diff; +#elif defined (HAVE_MEMALIGN) + ptr = memalign(16,size); + /* Why 64? + Indeed, we should align it: + on 4 for 386 + on 16 for 486 + on 32 for 586, PPro - k6-III + on 64 for K7 (maybe for P3 too). + Because L1 and L2 caches are aligned on those values. + But I don't want to code such logic here! + */ + /* Why 16? + because some cpus need alignment, for example SSE2 on P4, & most RISC cpus + it will just trigger an exception and the unaligned load will be done in the + exception handler or it will just segfault (SSE2 on P4) + Why not larger? because i didnt see a difference in benchmarks ... + */ + /* benchmarks with p3 + memalign(64)+1 3071,3051,3032 + memalign(64)+2 3051,3032,3041 + memalign(64)+4 2911,2896,2915 + memalign(64)+8 2545,2554,2550 + memalign(64)+16 2543,2572,2563 + memalign(64)+32 2546,2545,2571 + memalign(64)+64 2570,2533,2558 + + btw, malloc seems to do 8 byte alignment by default here + */ +#else + ptr = malloc(size); +#endif + return ptr; +} + +/** + * av_realloc semantics (same as glibc): if ptr is NULL and size > 0, + * identical to malloc(size). If size is zero, it is identical to + * free(ptr) and NULL is returned. + */ +void *av_realloc(void *ptr, unsigned int size) +{ +#ifdef CONFIG_MEMALIGN_HACK + int diff; +#endif + + /* let's disallow possible ambiguous cases */ + if(size > (INT_MAX-16) ) + return NULL; + +#ifdef CONFIG_MEMALIGN_HACK + //FIXME this isn't aligned correctly, though it probably isn't needed + if(!ptr) return av_malloc(size); + diff= ((char*)ptr)[-1]; + return realloc(ptr - diff, size + diff) + diff; +#else + return realloc(ptr, size); +#endif +} + +/** + * Free memory which has been allocated with av_malloc(z)() or av_realloc(). + * NOTE: ptr = NULL is explicetly allowed + * Note2: it is recommended that you use av_freep() instead + */ +void av_free(void *ptr) +{ + /* XXX: this test should not be needed on most libcs */ + if (ptr) +#ifdef CONFIG_MEMALIGN_HACK + free(ptr - ((char*)ptr)[-1]); +#else + free(ptr); +#endif +} + +/** + * Frees memory and sets the pointer to NULL. + * @param arg pointer to the pointer which should be freed + */ +void av_freep(void *arg) +{ + void **ptr= (void**)arg; + av_free(*ptr); + *ptr = NULL; +} + +void *av_mallocz(unsigned int size) +{ + void *ptr; + + ptr = av_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +char *av_strdup(const char *s) +{ + char *ptr; + int len; + len = strlen(s) + 1; + ptr = av_malloc(len); + if (ptr) + memcpy(ptr, s, len); + return ptr; +} + diff --git a/src/libffmpeg/mpeg_parser.c b/src/libffmpeg/mpeg_parser.c index d9ee602b2..14a08a456 100644 --- a/src/libffmpeg/mpeg_parser.c +++ b/src/libffmpeg/mpeg_parser.c @@ -20,7 +20,7 @@ * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. * - * $Id: mpeg_parser.c,v 1.4 2006/09/26 01:19:31 dgp85 Exp $ + * $Id: mpeg_parser.c,v 1.7 2007/03/29 18:52:45 dgp85 Exp $ */ #define LOG_MODULE "mpeg_parser" #define LOG_VERBOSE @@ -52,9 +52,17 @@ static const int frame_rate_tab[][2] = { void mpeg_parser_init (mpeg_parser_t *parser) { + parser->chunk_buffer = xine_xmalloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); mpeg_parser_reset(parser); } +void mpeg_parser_dispose (mpeg_parser_t *parser) +{ + if ( parser == NULL ) return; + + free(parser->chunk_buffer); +} + void mpeg_parser_reset (mpeg_parser_t *parser) { parser->shift = 0xffffff00; @@ -162,8 +170,7 @@ static int parse_chunk (mpeg_parser_t *parser, int code, uint8_t *buffer, int le case 0xb3: /* sequence_header_code */ { int value; - int width; - int height; + uint16_t width, height; if (parser->is_sequence_needed) { parser->is_sequence_needed = 0; diff --git a/src/libffmpeg/mpeg_parser.h b/src/libffmpeg/mpeg_parser.h index 9cc12f380..859a0fcec 100644 --- a/src/libffmpeg/mpeg_parser.h +++ b/src/libffmpeg/mpeg_parser.h @@ -20,7 +20,7 @@ * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. * - * $Id: mpeg_parser.h,v 1.2 2004/09/21 19:27:18 tmattern Exp $ + * $Id: mpeg_parser.h,v 1.5 2007/03/29 18:52:45 dgp85 Exp $ */ #ifndef HAVE_MPEG_PARSER_H #define HAVE_MPEG_PARSER_H @@ -37,23 +37,26 @@ #define D_TYPE 4 typedef struct mpeg_parser_s { - uint32_t shift; - int is_sequence_needed; - uint8_t chunk_buffer[BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; + uint8_t *chunk_buffer; uint8_t *chunk_ptr; uint8_t *chunk_start; + uint32_t shift; int buffer_size; uint8_t code; uint8_t picture_coding_type; - int rate_code; + + uint8_t is_sequence_needed:1; + uint8_t is_mpeg1:1; /* public */ + uint8_t has_sequence:1; /* public */ + uint8_t in_slice:1; + + uint8_t rate_code:4; + int aspect_ratio_info; - int in_slice; /* public properties */ - int is_mpeg1; - int has_sequence; - int width; - int height; + uint16_t width; + uint16_t height; int frame_duration; double frame_aspect_ratio; @@ -62,6 +65,9 @@ typedef struct mpeg_parser_s { /* parser initialization */ void mpeg_parser_init (mpeg_parser_t *parser); +/* parser disposal */ +void mpeg_parser_dispose (mpeg_parser_t *parser); + /* read a frame * return a pointer to the first byte of the next frame * or NULL if more bytes are needed diff --git a/src/libffmpeg/video_decoder.c b/src/libffmpeg/video_decoder.c index 2d5733211..e366a945c 100644 --- a/src/libffmpeg/video_decoder.c +++ b/src/libffmpeg/video_decoder.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2004 the xine project + * Copyright (C) 2001-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_decoder.c,v 1.63.2.1 2006/12/02 01:20:07 dgp85 Exp $ + * $Id: video_decoder.c,v 1.73 2007/03/29 18:41:02 dgp85 Exp $ * * xine video decoder plugin using ffmpeg * @@ -25,6 +25,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" +#include "ffmpeg_config.h" #endif #include <stdlib.h> @@ -74,8 +75,14 @@ struct ff_video_decoder_s { xine_stream_t *stream; int64_t pts; int video_step; - int decoder_ok; - int decoder_init_mode; + + uint8_t decoder_ok:1; + uint8_t decoder_init_mode:1; + uint8_t is_mpeg12:1; + uint8_t pp_available:1; + uint8_t yuv_init:1; + uint8_t is_direct_rendering_disabled:1; + uint8_t cs_convert_init:1; xine_bmiheader bih; unsigned char *buf; @@ -89,15 +96,13 @@ struct ff_video_decoder_s { AVCodecContext *context; AVCodec *codec; - int pp_available; int pp_quality; int pp_flags; pp_context_t *pp_context; pp_mode_t *pp_mode; /* mpeg-es parsing */ - mpeg_parser_t mpeg_parser; - int is_mpeg12; + mpeg_parser_t *mpeg_parser; double aspect_ratio; int aspect_ratio_prio; @@ -105,11 +110,10 @@ struct ff_video_decoder_s { int crop_right, crop_bottom; int output_format; - yuv_planes_t yuv; - int yuv_init; - int cs_convert_init; - int is_direct_rendering_disabled; + xine_list_t *dr1_frames; + + yuv_planes_t yuv; AVPaletteControl palette_control; }; @@ -199,16 +203,25 @@ static int get_buffer(AVCodecContext *context, AVFrame *av_frame){ av_frame->type= FF_BUFFER_TYPE_USER; + xine_list_push_back(this->dr1_frames, av_frame); + return 0; } static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ + ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; if (av_frame->type == FF_BUFFER_TYPE_USER) { vo_frame_t *img = (vo_frame_t *)av_frame->opaque; + xine_list_iterator_t it; assert(av_frame->opaque); img->free(img); + + it = xine_list_find(this->dr1_frames, av_frame); + assert(it); + if( it != NULL ) + xine_list_remove(this->dr1_frames, it); } else { avcodec_default_release_buffer(context, av_frame); } @@ -233,7 +246,7 @@ static const ff_codec_t ff_video_lookup[] = { {BUF_VIDEO_3IVX, CODEC_ID_MPEG4, "ISO MPEG-4 (3ivx, ffmpeg)"}, {BUF_VIDEO_JPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, {BUF_VIDEO_MJPEG, CODEC_ID_MJPEG, "Motion JPEG (ffmpeg)"}, - {BUF_VIDEO_MJPEG_B, CODEC_ID_MJPEGB, "Motion JPEG B (ffmpeg"}, + {BUF_VIDEO_MJPEG_B, CODEC_ID_MJPEGB, "Motion JPEG B (ffmpeg)"}, {BUF_VIDEO_I263, CODEC_ID_H263I, "ITU H.263 (ffmpeg)"}, {BUF_VIDEO_H263, CODEC_ID_H263, "H.263 (ffmpeg)"}, {BUF_VIDEO_RV10, CODEC_ID_RV10, "Real Video 1.0 (ffmpeg)"}, @@ -245,6 +258,9 @@ static const ff_codec_t ff_video_lookup[] = { {BUF_VIDEO_DV, CODEC_ID_DVVIDEO, "DV (ffmpeg)"}, {BUF_VIDEO_HUFFYUV, CODEC_ID_HUFFYUV, "HuffYUV (ffmpeg)"}, {BUF_VIDEO_VP31, CODEC_ID_VP3, "On2 VP3.1 (ffmpeg)"}, + {BUF_VIDEO_VP5, CODEC_ID_VP5, "On2 VP5 (ffmpeg)"}, + {BUF_VIDEO_VP6, CODEC_ID_VP6, "On2 VP6 (ffmpeg)"}, + {BUF_VIDEO_VP6F, CODEC_ID_VP6F, "On2 VP6 (ffmpeg)"}, {BUF_VIDEO_4XM, CODEC_ID_4XM, "4X Video (ffmpeg)"}, {BUF_VIDEO_CINEPAK, CODEC_ID_CINEPAK, "Cinepak (ffmpeg)"}, {BUF_VIDEO_MSVC, CODEC_ID_MSVIDEO1, "Microsoft Video 1 (ffmpeg)"}, @@ -372,7 +388,7 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) /* enable direct rendering by default */ this->output_format = XINE_IMGFMT_YV12; #ifdef ENABLE_DIRECT_RENDERING - if( this->codec->capabilities & CODEC_CAP_DR1 ) { + if( this->codec->capabilities & CODEC_CAP_DR1 && this->codec->id != CODEC_ID_H264 ) { this->context->get_buffer = get_buffer; this->context->release_buffer = release_buffer; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, @@ -411,7 +427,7 @@ static void pp_change_quality (ff_video_decoder_t *this) { this->pp_quality = this->class->pp_quality; if(this->pp_available && this->pp_quality) { - if(!this->pp_context) + if(!this->pp_context && this->context) this->pp_context = pp_get_context(this->context->width, this->context->height, this->pp_flags); if(this->pp_mode) @@ -504,7 +520,7 @@ static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *pars data.pan_scan = 0; xine_event_send(this->stream, &event); } - this->video_step = this->mpeg_parser.frame_duration; + this->video_step = this->mpeg_parser->frame_duration; return 1; } @@ -797,7 +813,7 @@ static void ff_check_bufsize (ff_video_decoder_t *this, int size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); - this->buf = realloc(this->buf, this->bufsize); + this->buf = realloc(this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE ); } } @@ -807,8 +823,14 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b lprintf ("preview buffer\n"); codec_type = buf->type & 0xFFFF0000; - if (codec_type == BUF_VIDEO_MPEG) + if (codec_type == BUF_VIDEO_MPEG) { this->is_mpeg12 = 1; + if ( this->mpeg_parser == NULL ) { + this->mpeg_parser = xine_xmalloc(sizeof(mpeg_parser_t)); + mpeg_parser_init(this->mpeg_parser); + this->decoder_init_mode = 0; + } + } if (this->decoder_init_mode && !this->is_mpeg12) { init_video_codec(this, codec_type); @@ -822,7 +844,7 @@ static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *bu lprintf ("header buffer\n"); /* accumulate data */ - ff_check_bufsize(this, this->size + buf->size + FF_INPUT_BUFFER_PADDING_SIZE); + ff_check_bufsize(this, this->size + buf->size); xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; @@ -961,7 +983,7 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu got_picture = 0; if (!flush) { - current = mpeg_parser_decode_data(&this->mpeg_parser, + current = mpeg_parser_decode_data(this->mpeg_parser, buf->content + offset, buf->content + offset + size, &next_flush); } else { @@ -973,8 +995,8 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu return; } - if (this->mpeg_parser.has_sequence) { - ff_handle_mpeg_sequence(this, &this->mpeg_parser); + if (this->mpeg_parser->has_sequence) { + ff_handle_mpeg_sequence(this, this->mpeg_parser); } if (!this->decoder_ok) @@ -983,16 +1005,16 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu if (flush) { lprintf("flush lavc buffers\n"); /* hack: ffmpeg outputs the last frame if size=0 */ - this->mpeg_parser.buffer_size = 0; + this->mpeg_parser->buffer_size = 0; } /* skip decoding b frames if too late */ this->context->hurry_up = (this->skipframes > 0); - lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser.buffer_size); + lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser->buffer_size); len = avcodec_decode_video (this->context, this->av_frame, - &got_picture, this->mpeg_parser.chunk_buffer, - this->mpeg_parser.buffer_size); + &got_picture, this->mpeg_parser->chunk_buffer, + this->mpeg_parser->buffer_size); lprintf("avcodec_decode_video: decoded_size=%d, got_picture=%d\n", len, got_picture); len = current - buf->content - offset; @@ -1098,7 +1120,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { lprintf("no memcpy needed to accumulate data\n"); } else { /* copy data into our internal buffer */ - ff_check_bufsize(this, this->size + buf->size + FF_INPUT_BUFFER_PADDING_SIZE); + ff_check_bufsize(this, this->size + buf->size); chunk_buf = this->buf; /* ff_check_bufsize might realloc this->buf */ xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); @@ -1118,7 +1140,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type = buf->type & 0xFFFF0000; /* pad input data */ - chunk_buf[this->size] = 0; + /* note: bitstream, alt bitstream reader or something will cause + * severe mpeg4 artifacts if padding is less than 32 bits. + */ + memset(&chunk_buf[this->size], 0, FF_INPUT_BUFFER_PADDING_SIZE); while (this->size > 0) { @@ -1146,7 +1171,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { this->size -= len; if (this->size > 0) { - ff_check_bufsize(this, this->size + FF_INPUT_BUFFER_PADDING_SIZE); + ff_check_bufsize(this, this->size); memmove (this->buf, &chunk_buf[offset], this->size); chunk_buf = this->buf; } @@ -1252,7 +1277,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { img->crop_bottom = this->crop_bottom; this->skipframes = img->draw(img, this->stream); - + if(free_img) img->free(img); } @@ -1342,7 +1367,7 @@ static void ff_reset (video_decoder_t *this_gen) { avcodec_flush_buffers(this->context); if (this->is_mpeg12) - mpeg_parser_reset(&this->mpeg_parser); + mpeg_parser_reset(this->mpeg_parser); } static void ff_discontinuity (video_decoder_t *this_gen) { @@ -1356,12 +1381,23 @@ static void ff_dispose (video_decoder_t *this_gen) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("ff_dispose\n"); - + if (this->decoder_ok) { + xine_list_iterator_t it; + AVFrame *av_frame; + pthread_mutex_lock(&ffmpeg_lock); avcodec_close (this->context); pthread_mutex_unlock(&ffmpeg_lock); - + + /* frame garbage collector here - workaround for buggy ffmpeg codecs that + * don't release their DR1 frames */ + while( (it = xine_list_front(this->dr1_frames)) != NULL ) + { + av_frame = (AVFrame *)xine_list_get_value(this->dr1_frames, it); + release_buffer(this->context, av_frame); + } + this->stream->video_out->close(this->stream->video_out, this->stream); this->decoder_ok = 0; } @@ -1390,6 +1426,10 @@ static void ff_dispose (video_decoder_t *this_gen) { if(this->pp_mode) pp_free_mode(this->pp_mode); + + mpeg_parser_dispose(this->mpeg_parser); + + xine_list_delete(this->dr1_frames); free (this_gen); } @@ -1429,7 +1469,9 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, this->pp_context = NULL; this->pp_mode = NULL; - mpeg_parser_init(&this->mpeg_parser); + this->mpeg_parser = NULL; + + this->dr1_frames = xine_list_new(); return &this->video_decoder; } @@ -1479,74 +1521,224 @@ void *init_video_plugin (xine_t *xine, void *data) { } static uint32_t supported_video_types[] = { - BUF_VIDEO_MSMPEG4_V1, + #ifdef CONFIG_MSMPEG4V1_DECODER + BUF_VIDEO_MSMPEG4_V1, + #endif + #ifdef CONFIG_MSMPEG4V2_DECODER BUF_VIDEO_MSMPEG4_V2, - BUF_VIDEO_MSMPEG4_V3, - BUF_VIDEO_WMV7, + #endif + #ifdef CONFIG_MSMPEG4V3_DECODER + BUF_VIDEO_MSMPEG4_V3, + #endif + #ifdef CONFIG_WMV1_DECODER + BUF_VIDEO_WMV7, + #endif + #ifdef CONFIG_WMV2_DECODER + BUF_VIDEO_WMV8, + #endif + #ifdef CONFIG_WMV3_DECODER + BUF_VIDEO_WMV9, + #endif + #ifdef CONFIG_MPEG4_DECODER BUF_VIDEO_MPEG4, - BUF_VIDEO_XVID, - BUF_VIDEO_DIVX5, + #endif + #ifdef CONFIG_MPEG4_DECODER + BUF_VIDEO_XVID, + #endif + #ifdef CONFIG_MPEG4_DECODER + BUF_VIDEO_DIVX5, + #endif + #ifdef CONFIG_MPEG4_DECODER BUF_VIDEO_3IVX, + #endif + #ifdef CONFIG_MJPEG_DECODER + BUF_VIDEO_JPEG, + #endif + #ifdef CONFIG_MJPEG_DECODER BUF_VIDEO_MJPEG, + #endif + #ifdef CONFIG_MJPEGB_DECODER BUF_VIDEO_MJPEG_B, + #endif + #ifdef CONFIG_H263I_DECODER + BUF_VIDEO_I263, + #endif + #ifdef CONFIG_H263_DECODER BUF_VIDEO_H263, + #endif + #ifdef CONFIG_RV10_DECODER BUF_VIDEO_RV10, + #endif + #ifdef CONFIG_RV20_DECODER BUF_VIDEO_RV20, + #endif + #ifdef CONFIG_INDEO3_DECODER BUF_VIDEO_IV31, + #endif + #ifdef CONFIG_INDEO3_DECODER BUF_VIDEO_IV32, + #endif + #ifdef CONFIG_SVQ1_DECODER BUF_VIDEO_SORENSON_V1, + #endif + #ifdef CONFIG_SVQ3_DECODER BUF_VIDEO_SORENSON_V3, - BUF_VIDEO_JPEG, - BUF_VIDEO_MPEG, + #endif + #ifdef CONFIG_DVVIDEO_DECODER BUF_VIDEO_DV, + #endif + #ifdef CONFIG_HUFFYUV_DECODER BUF_VIDEO_HUFFYUV, + #endif + #ifdef CONFIG_VP3_DECODER BUF_VIDEO_VP31, + #endif + #ifdef CONFIG_VP5_DECODER + BUF_VIDEO_VP5, + #endif + #ifdef CONFIG_VP6_DECODER + BUF_VIDEO_VP6, + BUF_VIDEO_VP6F, + #endif + #ifdef CONFIG_4XM_DECODER BUF_VIDEO_4XM, + #endif + #ifdef CONFIG_CINEPAK_DECODER BUF_VIDEO_CINEPAK, + #endif + #ifdef CONFIG_MSVIDEO1_DECODER BUF_VIDEO_MSVC, + #endif + #ifdef CONFIG_MSRLE_DECODER BUF_VIDEO_MSRLE, + #endif + #ifdef CONFIG_RPZA_DECODER BUF_VIDEO_RPZA, + #endif + #ifdef CONFIG_CYUV_DECODER BUF_VIDEO_CYUV, + #endif + #ifdef CONFIG_ROQ_DECODER BUF_VIDEO_ROQ, + #endif + #ifdef CONFIG_IDCIN_DECODER BUF_VIDEO_IDCIN, + #endif + #ifdef CONFIG_XAN_WC3_DECODER BUF_VIDEO_WC3, + #endif + #ifdef CONFIG_WS_VQA_DECODER BUF_VIDEO_VQA, + #endif + #ifdef CONFIG_INTERPLAY_VIDEO_DECODER BUF_VIDEO_INTERPLAY, + #endif + #ifdef CONFIG_FLIC_DECODER BUF_VIDEO_FLI, + #endif + #ifdef CONFIG_8BPS_DECODER BUF_VIDEO_8BPS, + #endif + #ifdef CONFIG_SMC_DECODER BUF_VIDEO_SMC, - BUF_VIDEO_VMD, + #endif + #ifdef CONFIG_TRUEMOTION1_DECODER BUF_VIDEO_DUCKTM1, + #endif + #ifdef CONFIG_TRUEMOTION2_DECODER BUF_VIDEO_DUCKTM2, + #endif + #ifdef CONFIG_VMDVIDEO_DECODER + BUF_VIDEO_VMD, + #endif + #ifdef CONFIG_ZLIB_DECODER BUF_VIDEO_ZLIB, + #endif + #ifdef CONFIG_MSZH_DECODER BUF_VIDEO_MSZH, + #endif + #ifdef CONFIG_ASV1_DECODER BUF_VIDEO_ASV1, + #endif + #ifdef CONFIG_ASV2_DECODER BUF_VIDEO_ASV2, + #endif + #ifdef CONFIG_VCR1_DECODER BUF_VIDEO_ATIVCR1, + #endif + #ifdef CONFIG_FLV_DECODER BUF_VIDEO_FLV1, + #endif + #ifdef CONFIG_QTRLE_DECODER BUF_VIDEO_QTRLE, + #endif + #ifdef CONFIG_H264_DECODER BUF_VIDEO_H264, + #endif + #ifdef CONFIG_H261_DECODER BUF_VIDEO_H261, + #endif + #ifdef CONFIG_AASC_DECODER BUF_VIDEO_AASC, + #endif + #ifdef CONFIG_LOCO_DECODER BUF_VIDEO_LOCO, + #endif + #ifdef CONFIG_QDRAW_DECODER BUF_VIDEO_QDRW, + #endif + #ifdef CONFIG_QPEG_DECODER BUF_VIDEO_QPEG, + #endif + #ifdef CONFIG_TSCC_DECODER BUF_VIDEO_TSCC, + #endif + #ifdef CONFIG_ULTI_DECODER BUF_VIDEO_ULTI, + #endif + #ifdef CONFIG_WNV1_DECODER BUF_VIDEO_WNV1, + #endif + #ifdef CONFIG_VIXL_DECODER BUF_VIDEO_XL, + #endif + #ifdef CONFIG_INDEO2_DECODER BUF_VIDEO_RT21, + #endif + #ifdef CONFIG_FRAPS_DECODER BUF_VIDEO_FPS1, - BUF_VIDEO_WMV9, + #endif + #ifdef CONFIG_MPEG1VIDEO_DECODER + BUF_VIDEO_MPEG, + #endif + #ifdef CONFIG_CSCD_DECODER BUF_VIDEO_CSCD, + #endif + #ifdef CONFIG_AVS_DECODER + BUF_VIDEO_AVS, + #endif + #ifdef CONFIG_MMVIDEO_DECODER BUF_VIDEO_ALGMM, + #endif + #ifdef CONFIG_ZMBV_DECODER BUF_VIDEO_ZMBV, - BUF_VIDEO_AVS, + #endif + #ifdef CONFIG_SMACKVIDEO_DECODER BUF_VIDEO_SMACKER, + #endif + #ifdef CONFIG_NUV_DECODER BUF_VIDEO_NUV, + #endif + #ifdef CONFIG_KMVC_DECODER BUF_VIDEO_KMVC, + #endif + #ifdef CONFIG_FLASHSV_DECODER BUF_VIDEO_FLASHSV, + #endif + #ifdef CONFIG_CAVS_DECODER BUF_VIDEO_CAVS, + #endif + 0 }; diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c index 10f420997..2eeb9746b 100644 --- a/src/libffmpeg/xine_decoder.c +++ b/src/libffmpeg/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.171 2006/10/11 12:53:12 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.173 2007/01/13 21:19:52 miguelfreitas Exp $ * * xine decoder plugin using ffmpeg * @@ -25,6 +25,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" +#include "ffmpeg_config.h" #endif #include "xine_internal.h" @@ -39,114 +40,273 @@ pthread_once_t once_control = PTHREAD_ONCE_INIT; pthread_mutex_t ffmpeg_lock; #ifndef HAVE_FFMPEG + +#define REGISTER_ENCODER(X,x) \ + if(ENABLE_##X##_ENCODER) register_avcodec(&x##_encoder) +#define REGISTER_DECODER(X,x) \ + if(ENABLE_##X##_DECODER) register_avcodec(&x##_decoder) +#define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x) + +#define REGISTER_PARSER(X,x) \ + if(ENABLE_##X##_PARSER) av_register_codec_parser(&x##_parser) + +/* If you do not call this function, then you can select exactly which + formats you want to support */ + +/** + * simple call to register all the codecs. + */ void avcodec_register_all(void) { static int inited = 0; - + if (inited != 0) - return; + return; inited = 1; - /* decoders */ - register_avcodec(&h263_decoder); - register_avcodec(&mpeg4_decoder); - register_avcodec(&msmpeg4v1_decoder); - register_avcodec(&msmpeg4v2_decoder); - register_avcodec(&msmpeg4v3_decoder); - register_avcodec(&wmv1_decoder); - register_avcodec(&wmv2_decoder); - register_avcodec(&h263i_decoder); - register_avcodec(&rv10_decoder); - register_avcodec(&rv20_decoder); - register_avcodec(&svq1_decoder); - register_avcodec(&svq3_decoder); - register_avcodec(&wmav1_decoder); - register_avcodec(&wmav2_decoder); - register_avcodec(&indeo3_decoder); - register_avcodec(&mpeg1video_decoder); - register_avcodec(&dvvideo_decoder); - register_avcodec(&pcm_s16le_decoder); - register_avcodec(&mjpeg_decoder); - register_avcodec(&mjpegb_decoder); - register_avcodec(&mp2_decoder); - register_avcodec(&mp3_decoder); - register_avcodec(&mace3_decoder); - register_avcodec(&mace6_decoder); - register_avcodec(&huffyuv_decoder); - register_avcodec(&cyuv_decoder); - register_avcodec(&h264_decoder); - register_avcodec(&vp3_decoder); - register_avcodec(&fourxm_decoder); - register_avcodec(&ra_144_decoder); - register_avcodec(&ra_288_decoder); - register_avcodec(&adpcm_ms_decoder); - register_avcodec(&adpcm_ima_qt_decoder); - register_avcodec(&adpcm_ima_wav_decoder); - register_avcodec(&adpcm_ima_dk3_decoder); - register_avcodec(&adpcm_ima_dk4_decoder); - register_avcodec(&adpcm_ima_ws_decoder); - register_avcodec(&adpcm_ima_smjpeg_decoder); - register_avcodec(&adpcm_xa_decoder); - register_avcodec(&adpcm_4xm_decoder); - register_avcodec(&adpcm_ea_decoder); - register_avcodec(&pcm_alaw_decoder); - register_avcodec(&pcm_mulaw_decoder); - register_avcodec(&roq_dpcm_decoder); - register_avcodec(&interplay_dpcm_decoder); - register_avcodec(&cinepak_decoder); - register_avcodec(&msvideo1_decoder); - register_avcodec(&msrle_decoder); - register_avcodec(&rpza_decoder); - register_avcodec(&roq_decoder); - register_avcodec(&idcin_decoder); - register_avcodec(&xan_wc3_decoder); - register_avcodec(&vqa_decoder); - register_avcodec(&interplay_video_decoder); - register_avcodec(&flic_decoder); - register_avcodec(&smc_decoder); - register_avcodec(&eightbps_decoder); - register_avcodec(&vmdvideo_decoder); - register_avcodec(&vmdaudio_decoder); - register_avcodec(&truemotion1_decoder); - register_avcodec(&mszh_decoder); - register_avcodec(&zlib_decoder); - register_avcodec(&xan_dpcm_decoder); - register_avcodec(&asv1_decoder); - register_avcodec(&asv2_decoder); - register_avcodec(&vcr1_decoder); - register_avcodec(&flv_decoder); - register_avcodec(&qtrle_decoder); - register_avcodec(&flac_decoder); - register_avcodec(&aasc_decoder); - register_avcodec(&alac_decoder); - register_avcodec(&h261_decoder); - register_avcodec(&loco_decoder); - register_avcodec(&qdraw_decoder); - register_avcodec(&qpeg_decoder); - register_avcodec(&tscc_decoder); - register_avcodec(&ulti_decoder); - register_avcodec(&wnv1_decoder); - register_avcodec(&xl_decoder); - register_avcodec(&indeo2_decoder); - register_avcodec(&fraps_decoder); - register_avcodec(&shorten_decoder); - register_avcodec(&qdm2_decoder); - register_avcodec(&truemotion2_decoder); - register_avcodec(&wmv3_decoder); - register_avcodec(&cscd_decoder); - register_avcodec(&mmvideo_decoder); - register_avcodec(&zmbv_decoder); - register_avcodec(&avs_decoder); - register_avcodec(&smacker_decoder); - register_avcodec(&smackaud_decoder); - register_avcodec(&nuv_decoder); - register_avcodec(&kmvc_decoder); - register_avcodec(&flashsv_decoder); - register_avcodec(&cavs_decoder); - register_avcodec(&cook_decoder); - register_avcodec(&truespeech_decoder); - register_avcodec(&tta_decoder); + /* video codecs */ + REGISTER_DECODER(AASC, aasc); + REGISTER_ENCDEC (ASV1, asv1); + REGISTER_ENCDEC (ASV2, asv2); + REGISTER_DECODER(AVS, avs); + REGISTER_DECODER(BMP, bmp); + REGISTER_DECODER(CAVS, cavs); + REGISTER_DECODER(CINEPAK, cinepak); + REGISTER_DECODER(CLJR, cljr); + REGISTER_DECODER(CSCD, cscd); + REGISTER_DECODER(CYUV, cyuv); + REGISTER_DECODER(DSICINVIDEO, dsicinvideo); + REGISTER_ENCDEC (DVVIDEO, dvvideo); + REGISTER_DECODER(EIGHTBPS, eightbps); + REGISTER_ENCDEC (FFV1, ffv1); + REGISTER_ENCDEC (FFVHUFF, ffvhuff); + REGISTER_DECODER(FLASHSV, flashsv); + REGISTER_DECODER(FLIC, flic); + REGISTER_ENCDEC (FLV, flv); + REGISTER_DECODER(FOURXM, fourxm); + REGISTER_DECODER(FRAPS, fraps); + REGISTER_ENCDEC (GIF, gif); + REGISTER_ENCDEC (H261, h261); + REGISTER_ENCDEC (H263, h263); + REGISTER_DECODER(H263I, h263i); + REGISTER_ENCODER(H263P, h263p); + REGISTER_DECODER(H264, h264); + REGISTER_ENCDEC (HUFFYUV, huffyuv); + REGISTER_DECODER(IDCIN, idcin); + REGISTER_DECODER(INDEO2, indeo2); + REGISTER_DECODER(INDEO3, indeo3); + REGISTER_DECODER(INTERPLAY_VIDEO, interplay_video); + REGISTER_ENCODER(JPEGLS, jpegls); + REGISTER_DECODER(KMVC, kmvc); + REGISTER_ENCODER(LJPEG, ljpeg); + REGISTER_DECODER(LOCO, loco); + REGISTER_DECODER(MDEC, mdec); + REGISTER_ENCDEC (MJPEG, mjpeg); + REGISTER_DECODER(MJPEGB, mjpegb); + REGISTER_DECODER(MMVIDEO, mmvideo); +#ifdef HAVE_XVMC + REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc); +#endif + REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); + REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); + REGISTER_ENCDEC (MPEG4, mpeg4); + REGISTER_DECODER(MPEGVIDEO, mpegvideo); + REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); + REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); + REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); + REGISTER_DECODER(MSRLE, msrle); + REGISTER_DECODER(MSVIDEO1, msvideo1); + REGISTER_DECODER(MSZH, mszh); + REGISTER_DECODER(NUV, nuv); + REGISTER_ENCODER(PAM, pam); + REGISTER_ENCODER(PBM, pbm); + REGISTER_ENCODER(PGM, pgm); + REGISTER_ENCODER(PGMYUV, pgmyuv); +#ifdef CONFIG_ZLIB + REGISTER_ENCDEC (PNG, png); +#endif + REGISTER_ENCODER(PPM, ppm); + REGISTER_DECODER(QDRAW, qdraw); + REGISTER_DECODER(QPEG, qpeg); + REGISTER_DECODER(QTRLE, qtrle); + REGISTER_ENCDEC (RAWVIDEO, rawvideo); + REGISTER_DECODER(ROQ, roq); + REGISTER_DECODER(RPZA, rpza); + REGISTER_ENCDEC (RV10, rv10); + REGISTER_ENCDEC (RV20, rv20); + REGISTER_DECODER(SMACKER, smacker); + REGISTER_DECODER(SMC, smc); + REGISTER_ENCDEC (SNOW, snow); + REGISTER_DECODER(SP5X, sp5x); + REGISTER_ENCDEC (SVQ1, svq1); + REGISTER_DECODER(SVQ3, svq3); + REGISTER_DECODER(TARGA, targa); + REGISTER_DECODER(THEORA, theora); + REGISTER_DECODER(TIERTEXSEQVIDEO, tiertexseqvideo); + REGISTER_DECODER(TIFF, tiff); + REGISTER_DECODER(TRUEMOTION1, truemotion1); + REGISTER_DECODER(TRUEMOTION2, truemotion2); + REGISTER_DECODER(TSCC, tscc); + REGISTER_DECODER(ULTI, ulti); + REGISTER_DECODER(VC1, vc1); + REGISTER_DECODER(VCR1, vcr1); + REGISTER_DECODER(VMDVIDEO, vmdvideo); + REGISTER_DECODER(VMNC, vmnc); + REGISTER_DECODER(VP3, vp3); + REGISTER_DECODER(VP5, vp5); + REGISTER_DECODER(VP6, vp6); + REGISTER_DECODER(VP6F, vp6f); + REGISTER_DECODER(VQA, vqa); + REGISTER_ENCDEC (WMV1, wmv1); + REGISTER_ENCDEC (WMV2, wmv2); + REGISTER_DECODER(WMV3, wmv3); + REGISTER_DECODER(WNV1, wnv1); +#ifdef CONFIG_X264 + REGISTER_ENCODER(X264, x264); +#endif + REGISTER_DECODER(XAN_WC3, xan_wc3); + REGISTER_DECODER(XL, xl); +#ifdef CONFIG_XVID + REGISTER_ENCODER(XVID, xvid); +#endif + REGISTER_ENCDEC (ZLIB, zlib); +#ifdef CONFIG_ZLIB + REGISTER_ENCDEC (ZMBV, zmbv); +#endif + + /* audio codecs */ +#ifdef CONFIG_LIBFAAD + REGISTER_DECODER(AAC, aac); + REGISTER_DECODER(MPEG4AAC, mpeg4aac); +#endif +#ifdef CONFIG_LIBA52 + REGISTER_DECODER(AC3, ac3); +#endif + REGISTER_ENCODER(AC3, ac3); + REGISTER_DECODER(ALAC, alac); +#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED) + REGISTER_ENCDEC (AMR_NB, amr_nb); +#endif +#ifdef CONFIG_AMR_WB + REGISTER_ENCDEC (AMR_WB, amr_wb); +#endif + REGISTER_DECODER(COOK, cook); + REGISTER_DECODER(DSICINAUDIO, dsicinaudio); +#ifdef CONFIG_LIBDTS + REGISTER_DECODER(DTS, dts); +#endif +#ifdef CONFIG_LIBFAAC + REGISTER_ENCODER(FAAC, faac); +#endif + REGISTER_ENCDEC (FLAC, flac); + REGISTER_DECODER(IMC, imc); +#ifdef CONFIG_LIBGSM + REGISTER_ENCDEC (LIBGSM, libgsm); +#endif + REGISTER_DECODER(MACE3, mace3); + REGISTER_DECODER(MACE6, mace6); + REGISTER_ENCDEC (MP2, mp2); + REGISTER_DECODER(MP3, mp3); + REGISTER_DECODER(MP3ADU, mp3adu); +#ifdef CONFIG_LIBMP3LAME + REGISTER_ENCODER(MP3LAME, mp3lame); +#endif + REGISTER_DECODER(MP3ON4, mp3on4); + REGISTER_DECODER(MPC7, mpc7); +#ifdef CONFIG_LIBVORBIS + if (!ENABLE_VORBIS_ENCODER) REGISTER_ENCODER(OGGVORBIS, oggvorbis); + if (!ENABLE_VORBIS_DECODER) REGISTER_DECODER(OGGVORBIS, oggvorbis); +#endif + REGISTER_DECODER(QDM2, qdm2); + REGISTER_DECODER(RA_144, ra_144); + REGISTER_DECODER(RA_288, ra_288); + REGISTER_DECODER(SHORTEN, shorten); + REGISTER_DECODER(SMACKAUD, smackaud); + REGISTER_ENCDEC (SONIC, sonic); + REGISTER_ENCODER(SONIC_LS, sonic_ls); + REGISTER_DECODER(TRUESPEECH, truespeech); + REGISTER_DECODER(TTA, tta); + REGISTER_DECODER(VMDAUDIO, vmdaudio); + REGISTER_ENCDEC (VORBIS, vorbis); + REGISTER_DECODER(WAVPACK, wavpack); + REGISTER_DECODER(WMAV1, wmav1); + REGISTER_DECODER(WMAV2, wmav2); + REGISTER_DECODER(WS_SND1, ws_snd1); + + /* pcm codecs */ + REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); + REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); + REGISTER_ENCDEC (PCM_S8, pcm_s8); + REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); + REGISTER_ENCDEC (PCM_S16LE, pcm_s16le); + REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); + REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); + REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); + REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); + REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); + REGISTER_ENCDEC (PCM_U8, pcm_u8); + REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); + REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); + REGISTER_ENCDEC (PCM_U24BE, pcm_u24be); + REGISTER_ENCDEC (PCM_U24LE, pcm_u24le); + REGISTER_ENCDEC (PCM_U32BE, pcm_u32be); + REGISTER_ENCDEC (PCM_U32LE, pcm_u32le); + + /* dpcm codecs */ + REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm); + REGISTER_DECODER(ROQ_DPCM, roq_dpcm); + REGISTER_DECODER(SOL_DPCM, sol_dpcm); + REGISTER_DECODER(XAN_DPCM, xan_dpcm); + + /* adpcm codecs */ + REGISTER_ENCDEC (ADPCM_4XM, adpcm_4xm); + REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); + REGISTER_ENCDEC (ADPCM_CT, adpcm_ct); + REGISTER_ENCDEC (ADPCM_EA, adpcm_ea); + REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); + REGISTER_ENCDEC (ADPCM_IMA_DK3, adpcm_ima_dk3); + REGISTER_ENCDEC (ADPCM_IMA_DK4, adpcm_ima_dk4); + REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); + REGISTER_ENCDEC (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); + REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); + REGISTER_ENCDEC (ADPCM_IMA_WS, adpcm_ima_ws); + REGISTER_ENCDEC (ADPCM_MS, adpcm_ms); + REGISTER_ENCDEC (ADPCM_SBPRO_2, adpcm_sbpro_2); + REGISTER_ENCDEC (ADPCM_SBPRO_3, adpcm_sbpro_3); + REGISTER_ENCDEC (ADPCM_SBPRO_4, adpcm_sbpro_4); + REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); + REGISTER_ENCDEC (ADPCM_XA, adpcm_xa); + REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); + + /* subtitles */ + REGISTER_ENCDEC (DVBSUB, dvbsub); + REGISTER_ENCDEC (DVDSUB, dvdsub); + + /* parsers */ + REGISTER_PARSER (AAC, aac); + REGISTER_PARSER (AC3, ac3); + REGISTER_PARSER (CAVSVIDEO, cavsvideo); + REGISTER_PARSER (DVBSUB, dvbsub); + REGISTER_PARSER (DVDSUB, dvdsub); + REGISTER_PARSER (H261, h261); + REGISTER_PARSER (H263, h263); + REGISTER_PARSER (H264, h264); + REGISTER_PARSER (MJPEG, mjpeg); + REGISTER_PARSER (MPEG4VIDEO, mpeg4video); + REGISTER_PARSER (MPEGAUDIO, mpegaudio); + REGISTER_PARSER (MPEGVIDEO, mpegvideo); + REGISTER_PARSER (PNM, pnm); + + /* + av_register_bitstream_filter(&dump_extradata_bsf); + av_register_bitstream_filter(&remove_extradata_bsf); + av_register_bitstream_filter(&noise_bsf); + av_register_bitstream_filter(&mp3_header_compress_bsf); + av_register_bitstream_filter(&mp3_header_decompress_bsf); + av_register_bitstream_filter(&mjpega_dump_header_bsf); + */ } + #endif void init_once_routine(void) { diff --git a/src/libspucmml/.cvsignore b/src/libflac/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libspucmml/.cvsignore +++ b/src/libflac/.hgignore diff --git a/src/libflac/Makefile.am b/src/libflac/Makefile.am index 12304ff84..6449820bc 100644 --- a/src/libflac/Makefile.am +++ b/src/libflac/Makefile.am @@ -1,12 +1,10 @@ include $(top_srcdir)/misc/Makefile.common -if HAVE_FLAC -flac_module = xineplug_flac.la -endif - libdir = $(XINE_PLUGINDIR) -lib_LTLIBRARIES = $(flac_module) +if HAVE_LIBFLAC +lib_LTLIBRARIES = xineplug_flac.la +endif xineplug_flac_la_SOURCES = demux_flac.c decoder_flac.c xineplug_flac_la_LIBADD = $(LIBFLAC_LIBS) $(XINE_LIB) diff --git a/src/libflac/decoder_flac.c b/src/libflac/decoder_flac.c index b62286eaa..9b77cc27d 100644 --- a/src/libflac/decoder_flac.c +++ b/src/libflac/decoder_flac.c @@ -30,6 +30,13 @@ #include <FLAC/stream_decoder.h> +#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 +#include <FLAC/seekable_stream_decoder.h> +#define LEGACY_FLAC +#else +#undef LEGACY_FLAC +#endif + #define LOG_MODULE "flac_decoder" #define LOG_VERBOSE @@ -344,6 +351,7 @@ open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { this->flac_decoder = FLAC__stream_decoder_new(); +#ifdef LEGACY_FLAC FLAC__stream_decoder_set_read_callback (this->flac_decoder, flac_read_callback); FLAC__stream_decoder_set_write_callback (this->flac_decoder, @@ -355,10 +363,26 @@ open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { FLAC__stream_decoder_set_client_data (this->flac_decoder, this); - if (FLAC__stream_decoder_init (this->flac_decoder) == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { + if (FLAC__stream_decoder_init (this->flac_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { + free (this); + return NULL; + } +#else + if ( FLAC__stream_decoder_init_stream (this->flac_decoder, + flac_read_callback, + NULL, /* seek */ + NULL, /* tell */ + NULL, /* length */ + NULL, /* eof */ + flac_write_callback, + NULL, /* metadata */ + flac_error_callback, + this + ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { free (this); return NULL; } +#endif return (audio_decoder_t *) this; } diff --git a/src/libflac/demux_flac.c b/src/libflac/demux_flac.c index efee0b179..43ee17d5c 100644 --- a/src/libflac/demux_flac.c +++ b/src/libflac/demux_flac.c @@ -441,7 +441,11 @@ demux_flac_dispose (demux_plugin_t *this_gen) { lprintf("demux_flac_dispose\n"); if (this->flac_decoder) +#ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif free(this); return; @@ -494,8 +498,13 @@ demux_flac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int } target_sample = (uint64_t)(distance * this->total_samples); +#ifdef LEGACY_FLAC s = FLAC__seekable_stream_decoder_seek_absolute (this->flac_decoder, target_sample); +#else + s = FLAC__stream_decoder_seek_absolute (this->flac_decoder, + target_sample); +#endif if (s) { lprintf ("Seek to: %d successfull!\n", start_time); @@ -618,9 +627,6 @@ open_plugin (demux_class_t *class_gen, /* Get a new FLAC decoder and hook up callbacks */ #ifdef LEGACY_FLAC this->flac_decoder = FLAC__seekable_stream_decoder_new(); -#else - this->flac_decoder = FLAC__stream_decoder_new(); -#endif lprintf("this->flac_decoder: %p\n", this->flac_decoder); FLAC__seekable_stream_decoder_set_md5_checking (this->flac_decoder, false); @@ -644,6 +650,37 @@ open_plugin (demux_class_t *class_gen, this); FLAC__seekable_stream_decoder_init (this->flac_decoder); +#else + this->flac_decoder = FLAC__stream_decoder_new(); + lprintf("this->flac_decoder: %p\n", this->flac_decoder); + + if ( ! this->flac_decoder ) { + free(this); + return NULL; + } + + FLAC__stream_decoder_set_md5_checking (this->flac_decoder, false); + + if ( FLAC__stream_decoder_init_stream(this->flac_decoder, + flac_read_callback, + flac_seek_callback, + flac_tell_callback, + flac_length_callback, + flac_eof_callback, + flac_write_callback, + flac_metadata_callback, + flac_error_callback, + this + ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { +#ifdef LEGACY_FLAC + FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif + free(this); + return NULL; + } +#endif /* Get some stream info */ this->data_size = this->input->get_length (this->input); @@ -653,13 +690,21 @@ open_plugin (demux_class_t *class_gen, * this flac stream */ this->status = DEMUX_OK; +#ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_process_until_end_of_metadata (this->flac_decoder); +#else + FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); +#endif lprintf("Processed file until end of metadata: %s\n", this->status == DEMUX_OK ? "success" : "failure"); if (this->status != DEMUX_OK) { +#ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_delete (this->flac_decoder); +#else + FLAC__stream_decoder_delete (this->flac_decoder); +#endif free (this); return NULL; } diff --git a/src/libspudec/.cvsignore b/src/liblpcm/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libspudec/.cvsignore +++ b/src/liblpcm/.hgignore diff --git a/src/liblpcm/xine_decoder.c b/src/liblpcm/xine_decoder.c index 65ec012d7..43bea4cbf 100644 --- a/src/liblpcm/xine_decoder.c +++ b/src/liblpcm/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.61 2006/07/10 22:08:29 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.62 2007/03/17 20:59:36 dgp85 Exp $ * * 31-8-2001 Added LPCM rate sensing. * (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk @@ -191,20 +191,16 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { int n = buf->size; while (n >= 0) { - *d++ = s[8]; - *d++ = s[0]; - - *d++ = s[9]; - *d++ = s[2]; - - *d++ = s[10]; - *d++ = s[4]; - - *d++ = s[11]; - *d++ = s[6]; + if ( stream_be ) { + *d++ = s[0]; + *d++ = s[1]; + } else { + *d++ = s[1]; + *d++ = s[2]; + } - s += 12; - n -= 12; + s += 3; + n -= 3; } } else { memcpy (audio_buffer->mem, sample_buffer, buf->size); diff --git a/src/libspudvb/.cvsignore b/src/libmad/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libspudvb/.cvsignore +++ b/src/libmad/.hgignore diff --git a/src/libsputext/.cvsignore b/src/libmpeg2/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libsputext/.cvsignore +++ b/src/libmpeg2/.hgignore diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am index cbc79fabd..550ce581f 100644 --- a/src/libmpeg2/Makefile.am +++ b/src/libmpeg2/Makefile.am @@ -26,7 +26,7 @@ xineplug_decode_mpeg2_la_SOURCES = \ xine_decoder.c \ libmpeg2_accel.c -xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) +xineplug_decode_mpeg2_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) -lm xineplug_decode_mpeg2_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index f20698520..a2bb868df 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -130,7 +130,7 @@ static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) (mpeg2dec->rff_pattern & 0xff) == 0x55) && !mpeg2dec->picture->progressive_sequence ) { /* special case for ntsc 3:2 pulldown */ - duration *= 5 / 4; + duration *= 5.0 / 4.0; } else { @@ -139,7 +139,7 @@ static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) frame->progressive_frame ) { /* decoder should output 3 fields, so adjust duration to count on this extra field time */ - duration *= 3 / 2; + duration *= 3.0 / 2.0; } else if( mpeg2dec->picture->progressive_sequence ) { /* for progressive sequences the output should repeat the frame 1 or 2 times depending on top_field_first flag. */ diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c index f214f1f25..8cb5c33b6 100644 --- a/src/libmpeg2/slice.c +++ b/src/libmpeg2/slice.c @@ -45,7 +45,7 @@ static inline int get_macroblock_modes (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int macroblock_modes; - MBtab * tab; + const MBtab * tab; switch (picture->picture_coding_type) { case I_TYPE: @@ -160,7 +160,7 @@ static inline int get_motion_delta (picture_t * picture, int f_code) int delta; int sign; - MVtab * tab; + const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); @@ -230,7 +230,7 @@ static inline int get_dmv (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DMVtab * tab; + const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); @@ -246,7 +246,7 @@ static inline int get_coded_block_pattern (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - CBPtab * tab; + const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); @@ -273,7 +273,7 @@ static inline int get_luma_dc_dct_diff (picture_t * picture) #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DCtab * tab; + const DCtab * tab; int size; int dc_diff; @@ -310,7 +310,7 @@ static inline int get_chroma_dc_dct_diff (picture_t * picture) #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DCtab * tab; + const DCtab * tab; int size; int dc_diff; @@ -357,7 +357,7 @@ static void get_intra_block_B14 (picture_t * picture) uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -471,7 +471,7 @@ static void get_intra_block_B15 (picture_t * picture) uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -584,7 +584,7 @@ static void get_non_intra_block (picture_t * picture) uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -706,7 +706,7 @@ static void get_mpeg1_intra_block (picture_t * picture) uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -825,7 +825,7 @@ static void get_mpeg1_non_intra_block (picture_t * picture) uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -1463,7 +1463,7 @@ static inline int slice_init (picture_t * picture, int code) int offset, height; struct vo_frame_s * forward_reference_frame; struct vo_frame_s * backward_reference_frame; - MBAtab * mba; + const MBAtab * mba; offset = picture->picture_structure == BOTTOM_FIELD; picture->pitches[0] = picture->current_frame->pitches[0]; @@ -1634,7 +1634,7 @@ void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer) while (1) { int macroblock_modes; int mba_inc; - MBAtab * mba; + const MBAtab * mba; NEEDBITS (bit_buf, bits, bit_ptr); diff --git a/src/libmpeg2/slice_xvmc.c b/src/libmpeg2/slice_xvmc.c index 4aa383b9a..e21b1eb98 100644 --- a/src/libmpeg2/slice_xvmc.c +++ b/src/libmpeg2/slice_xvmc.c @@ -96,7 +96,7 @@ static inline int get_xvmc_macroblock_modes (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int macroblock_modes; - MBtab * tab; + const MBtab * tab; switch (picture->picture_coding_type) { case I_TYPE: @@ -211,7 +211,7 @@ static inline int get_xvmc_motion_delta (picture_t * picture, int f_code) int delta; int sign; - MVtab * tab; + const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); @@ -281,7 +281,7 @@ static inline int get_xvmc_dmv (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DMVtab * tab; + const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); @@ -297,7 +297,7 @@ static inline int get_xvmc_coded_block_pattern (picture_t * picture) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - CBPtab * tab; + const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); @@ -324,7 +324,7 @@ static inline int get_xvmc_luma_dc_dct_diff (picture_t * picture) #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DCtab * tab; + const DCtab * tab; int size; int dc_diff; @@ -361,7 +361,7 @@ static inline int get_xvmc_chroma_dc_dct_diff (picture_t * picture) #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) - DCtab * tab; + const DCtab * tab; int size; int dc_diff; @@ -405,12 +405,12 @@ static void get_xvmc_intra_block_B14 (picture_t * picture) int j; int l; int val; - uint8_t * scan = picture->scan; + const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -534,12 +534,12 @@ static void get_xvmc_intra_block_B15 (picture_t * picture) int j; int l; int val; - uint8_t * scan = picture->scan; + const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -661,12 +661,12 @@ static void get_xvmc_non_intra_block (picture_t * picture) int j; int l; int val; - uint8_t * scan = picture->scan; + const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -797,11 +797,11 @@ static void get_xvmc_mpeg1_intra_block (picture_t * picture) int j; int l; int val; - uint8_t * scan = picture->scan; + const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -929,11 +929,11 @@ static void get_xvmc_mpeg1_non_intra_block (picture_t * picture) int j; int l; int val; - uint8_t * scan = picture->scan; + const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; - DCTtab * tab; + const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; @@ -1473,7 +1473,7 @@ static inline int slice_xvmc_init (picture_t * picture, int code) int offset, height; struct vo_frame_s * forward_reference_frame; struct vo_frame_s * backward_reference_frame; - MBAtab * mba; + const MBAtab * mba; offset = picture->picture_structure == BOTTOM_FIELD; picture->pitches[0] = picture->current_frame->pitches[0]; @@ -1664,7 +1664,7 @@ void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, u while (1) { int macroblock_modes; int mba_inc; - MBAtab * mba; + const MBAtab * mba; NEEDBITS (bit_buf, bits, bit_ptr); diff --git a/src/libtheora/.cvsignore b/src/libmpeg2new/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libtheora/.cvsignore +++ b/src/libmpeg2new/.hgignore diff --git a/src/libmpeg2new/include/.cvsignore b/src/libmpeg2new/include/.hgignore index 282522db0..282522db0 100644 --- a/src/libmpeg2new/include/.cvsignore +++ b/src/libmpeg2new/include/.hgignore diff --git a/src/libvorbis/.cvsignore b/src/libmpeg2new/libmpeg2/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libvorbis/.cvsignore +++ b/src/libmpeg2new/libmpeg2/.hgignore diff --git a/src/libw32dll/.cvsignore b/src/libmusepack/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libw32dll/.cvsignore +++ b/src/libmusepack/.hgignore diff --git a/src/libmusepack/Makefile.am b/src/libmusepack/Makefile.am index 477dc31f9..021ec0985 100644 --- a/src/libmusepack/Makefile.am +++ b/src/libmusepack/Makefile.am @@ -6,11 +6,24 @@ EXTRA_DIST = diff_against_svn.patch libdir = $(XINE_PLUGINDIR) +if MUSEPACK lib_LTLIBRARIES = xineplug_decode_mpc.la +endif -xineplug_decode_mpc_la_SOURCES = huffsv46.c huffsv7.c idtag.c mpc_decoder.c \ - mpc_reader.c requant.c streaminfo.c synth_filter.c xine_decoder.c +if EXTERNAL_MPCDEC +internal_sources = +else +internal_sources = huffsv46.c huffsv7.c idtag.c mpc_decoder.c \ + mpc_reader.c requant.c streaminfo.c synth_filter.c +endif + +if EXTERNAL_MPCDEC +xineplug_decode_mpc_la_LIBADD = $(XINE_LIB) -lmpcdec +else xineplug_decode_mpc_la_LIBADD = $(XINE_LIB) +endif + +xineplug_decode_mpc_la_SOURCES = $(internal_sources) xine_decoder.c xineplug_decode_mpc_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_decode_mpc_la_LDFLAGS = -avoid-version -module diff --git a/src/libmusepack/musepack/.cvsignore b/src/libmusepack/musepack/.hgignore index 282522db0..282522db0 100644 --- a/src/libmusepack/musepack/.cvsignore +++ b/src/libmusepack/musepack/.hgignore diff --git a/src/libmusepack/xine_decoder.c b/src/libmusepack/xine_decoder.c index 03d43fb63..26c2eddf5 100644 --- a/src/libmusepack/xine_decoder.c +++ b/src/libmusepack/xine_decoder.c @@ -23,7 +23,7 @@ * 32bit float output * Seeking?? * - * $Id: xine_decoder.c,v 1.9 2006/07/10 22:08:29 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.10 2007/01/19 02:35:36 dgp85 Exp $ */ #include <stdio.h> @@ -43,7 +43,11 @@ #include "buffer.h" #include "xineutils.h" -#include "musepack/musepack.h" +#ifdef HAVE_MPCDEC_MPCDEC_H +# include <mpcdec/mpcdec.h> +#else +# include "musepack/musepack.h" +#endif #define MPC_DECODER_MEMSIZE 65536 #define MPC_DECODER_MEMSIZE2 (MPC_DECODER_MEMSIZE/2) diff --git a/src/libw32dll/DirectShow/.cvsignore b/src/libreal/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libw32dll/DirectShow/.cvsignore +++ b/src/libreal/.hgignore diff --git a/src/libreal/Makefile.am b/src/libreal/Makefile.am index 72dac45a1..114a473a7 100644 --- a/src/libreal/Makefile.am +++ b/src/libreal/Makefile.am @@ -1,15 +1,12 @@ include $(top_srcdir)/misc/Makefile.common -libdir = $(XINE_PLUGINDIR) +if ENABLE_REAL +xineplug_LTLIBRARIES = xineplug_decode_real.la +endif -lib_LTLIBRARIES = xineplug_decode_real.la xineplug_decode_real_audio.la - -xineplug_decode_real_la_SOURCES = xine_decoder.c +xineplug_decode_real_la_SOURCES = xine_decoder.c real_common.c audio_decoder.c xineplug_decode_real_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) xineplug_decode_real_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_decode_real_la_LDFLAGS = -avoid-version -module +xineplug_decode_real_la_LDFLAGS = $(xineplug_ldflags) -xineplug_decode_real_audio_la_SOURCES = audio_decoder.c -xineplug_decode_real_audio_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) -xineplug_decode_real_audio_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_decode_real_audio_la_LDFLAGS = -avoid-version -module +noinst_HEADERS = real_common.h diff --git a/src/libreal/audio_decoder.c b/src/libreal/audio_decoder.c index d5b2b2d26..d1bb94230 100644 --- a/src/libreal/audio_decoder.c +++ b/src/libreal/audio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_decoder.c,v 1.49 2006/07/10 22:08:30 dgp85 Exp $ + * $Id: audio_decoder.c,v 1.59 2007/03/17 15:45:41 dgp85 Exp $ * * thin layer to use real binary-only codecs in xine * @@ -32,9 +32,6 @@ #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> -#ifdef __x86_64__ - #include <elf.h> -#endif #define LOG_MODULE "real_audio_decoder" #define LOG_VERBOSE @@ -48,6 +45,8 @@ #include "buffer.h" #include "xineutils.h" +#include "real_common.h" + typedef struct { audio_decoder_class_t decoder_class; @@ -105,94 +104,14 @@ typedef struct { void *extras; } ra_init_t; -void *__builtin_new(unsigned long size); -void __builtin_delete (void *foo); -void *__builtin_vec_new(unsigned long size); -void __builtin_vec_delete(void *mem); -void __pure_virtual(void); - - -void *__builtin_new(unsigned long size) { - return malloc(size); -} - -void __builtin_delete (void *foo) { - /* printf ("libareal: __builtin_delete called\n"); */ - free (foo); -} - -#ifdef __x86_64__ -/* (gb) quick-n-dirty check to be run natively */ -static int is_x86_64_object_(FILE *f) -{ - Elf64_Ehdr *hdr = malloc(sizeof(Elf64_Ehdr)); - if (hdr == NULL) - return 0; - - if (fseek(f, 0, SEEK_SET) != 0) { - free(hdr); - return 0; - } - - if (fread(hdr, sizeof(Elf64_Ehdr), 1, f) != 1) { - free(hdr); - return 0; - } - - if (hdr->e_ident[EI_MAG0] != ELFMAG0 || - hdr->e_ident[EI_MAG1] != ELFMAG1 || - hdr->e_ident[EI_MAG2] != ELFMAG2 || - hdr->e_ident[EI_MAG3] != ELFMAG3) { - free(hdr); - return 0; - } - - return hdr->e_machine == EM_X86_64; -} - -static inline int is_x86_64_object(const char *filename) -{ - FILE *f; - int ret; - - if ((f = fopen(filename, "r")) == NULL) - return 0; - - ret = is_x86_64_object_(f); - fclose(f); - return ret; -} -#endif - -static int load_syms_linux (realdec_decoder_t *this, char *codec_name, - const char *alt_codec_name) { - - cfg_entry_t* entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "decoder.external.real_codecs_path"); - char path[1024]; - struct stat sb; +static int load_syms_linux (realdec_decoder_t *this, const char *const codec_name, const char *const codec_alternate) { + cfg_entry_t* entry = + this->stream->xine->config->lookup_entry(this->stream->xine->config, + "decoder.external.real_codecs_path"); - snprintf (path, sizeof(path), "%s/%s", entry->str_value, codec_name); - if (stat(path, &sb)) - snprintf (path, sizeof(path), "%s/%s", entry->str_value, alt_codec_name); - -#ifdef __x86_64__ - /* check whether it's a real x86-64 library */ - if (!is_x86_64_object(path)) - return 0; -#endif - - lprintf ("(audio) opening shared obj '%s'\n", path); - - this->ra_handle = dlopen (path, RTLD_LAZY); - - if (!this->ra_handle) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: error: %s\n", dlerror()); - _x_message(this->stream, XINE_MSG_LIBRARY_LOAD_ERROR, - codec_name, NULL); + if ( (this->ra_handle = _x_real_codec_open(this->stream, entry->str_value, codec_name, codec_alternate)) == NULL ) return 0; - } - + this->raCloseCodec = dlsym (this->ra_handle, "RACloseCodec"); this->raDecode = dlsym (this->ra_handle, "RADecode"); this->raFlush = dlsym (this->ra_handle, "RAFlush"); @@ -208,7 +127,7 @@ static int load_syms_linux (realdec_decoder_t *this, char *codec_name, !this->raGetFlavorProperty || !this->raOpenCodec2 || !this->raSetFlavor || /*!raSetDLLAccessPath ||*/ !this->raInitDecoder){ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, - _("libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n"), path); + _("libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n"), codec_name); return 0; } @@ -443,7 +362,7 @@ static unsigned char sipr_swaps[38][2]={ static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; - lprintf ("decode_data %d bytes, flags=0x%08x, pts=%lld ...\n", + lprintf ("decode_data %d bytes, flags=0x%08x, pts=%"PRId64" ...\n", buf->size, buf->decoder_flags, buf->pts); if (buf->decoder_flags & BUF_FLAG_PREVIEW) { @@ -678,35 +597,10 @@ static void dispose_class (audio_decoder_class_t *this) { free (this); } -/* - * some fake functions to make real codecs happy - */ -void *__builtin_vec_new(unsigned long size) EXPORTED; -void __builtin_vec_delete(void *mem) EXPORTED; -void __pure_virtual(void) EXPORTED; - -void *__builtin_vec_new(unsigned long size) { - return malloc(size); -} -void __builtin_vec_delete(void *mem) { - free(mem); -} -void __pure_virtual(void) { - lprintf("libareal: FATAL: __pure_virtual() called!\n"); - /* exit(1); */ -} - -/* - * real audio codec loader - */ - -static void *init_class (xine_t *xine, void *data) { +void *init_realadec (xine_t *xine, void *data) { real_class_t *this; config_values_t *config = xine->config; - char *real_codec_path; - char *default_real_codec_path = ""; - struct stat s; this = (real_class_t *) xine_xmalloc (sizeof (real_class_t)); @@ -715,44 +609,7 @@ static void *init_class (xine_t *xine, void *data) { this->decoder_class.get_description = get_description; this->decoder_class.dispose = dispose_class; - /* try some auto-detection */ - - if (!stat ("/usr/local/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/local/RealPlayer8/Codecs"; - if (!stat ("/usr/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/RealPlayer8/Codecs"; - if (!stat ("/usr/lib/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/RealPlayer8/Codecs"; - if (!stat ("/opt/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/opt/RealPlayer8/Codecs"; - if (!stat ("/usr/lib/RealPlayer9/users/Real/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/RealPlayer9/users/Real/Codecs"; - if (!stat ("/usr/lib/RealPlayer10/codecs/drvc.so", &s)) - default_real_codec_path = "/usr/lib/RealPlayer10/codecs"; - if (!stat ("/usr/lib64/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer8/Codecs"; - if (!stat ("/usr/lib64/RealPlayer9/users/Real/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer9/users/Real/Codecs"; - if (!stat ("/usr/lib64/RealPlayer10/codecs/drvc.so", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer10/codecs"; - if (!stat ("/usr/lib/codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/codecs"; - if (!stat ("/usr/lib/win32/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/win32"; - - real_codec_path = config->register_string (config, "decoder.external.real_codecs_path", - default_real_codec_path, - _("path to RealPlayer codecs"), - _("If you have RealPlayer installed, specify the path " - "to its codec directory here. You can easily find " - "the codec directory by looking for a file named " - "\"drv3.so.6.0\" in it. If xine can find the RealPlayer " - "codecs, it will use them to decode RealPlayer content " - "for you. Consult the xine FAQ for more information on " - "how to install the codecs."), - 10, NULL, this); - - lprintf ("real codec path : %s\n", real_codec_path); + _x_real_codecs_init(xine); return this; } @@ -765,13 +622,7 @@ static uint32_t audio_types[] = { BUF_AUDIO_COOK, BUF_AUDIO_ATRK, /* BUF_AUDIO_14_4, BUF_AUDIO_28_8, */ BUF_AUDIO_SIPRO, 0 }; -static const decoder_info_t dec_info_audio = { +const decoder_info_t dec_info_realaudio = { audio_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 15, "realadec", XINE_VERSION_CODE, &dec_info_audio, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } + 7 /* priority */ }; diff --git a/src/libreal/real_common.c b/src/libreal/real_common.c new file mode 100644 index 000000000..925a5cc71 --- /dev/null +++ b/src/libreal/real_common.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2000-2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: real_common.c,v 1.12 2007/03/17 15:45:41 dgp85 Exp $ + * + * Common function for the thin layer to use Real binary-only codecs in xine + */ + +#define LOG_MODULE "real_common" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include "config.h" + +#include <sys/stat.h> +#include <string.h> +#include <dlfcn.h> + +#include "real_common.h" + +#ifdef __alpha__ + +void *__builtin_new(size_t size) { + return malloc(size); +} + +void __builtin_delete (void *foo) { + /* printf ("libareal: __builtin_delete called\n"); */ + free (foo); +} + +void *__builtin_vec_new(size_t size) { + return malloc(size); +} + +void __builtin_vec_delete(void *mem) { + free(mem); +} + +void __pure_virtual(void) { + lprintf("libreal: FATAL: __pure_virtual() called!\n"); + /* exit(1); */ +} + +#endif + +#ifndef HAVE____BRK_ADDR +void ___brk_addr(void) { exit(0); } +#endif + +#ifndef HAVE___CTYPE_B +void __ctype_b(void) { exit(0); } +#endif + +void _x_real_codecs_init(xine_t *const xine) { + const char *real_codecs_path = NULL; +#ifdef REAL_CODEC_PATH + const char *const default_real_codecs_path = REAL_CODEC_PATH; +#else + const char *default_real_codecs_path = ""; + struct stat s; + +#define try_real_path(path) \ + if (!stat (path "/dvrc.so", &s)) \ + default_real_codecs_path = path; +#define try_real_subpath(path) \ + try_real_path("/usr/" path) \ + else try_real_path("/usr/local" path) \ + else try_real_path("/opt" path) + + /* The priority is for the first found */ + try_real_subpath("lib/win32") + else try_real_subpath("lib/codecs") + else try_real_subpath("lib64/RealPlayer10/codecs") + else try_real_subpath("lib/RealPlayer10/codecs") + else try_real_subpath("lib64/RealPlayer9/users/Real/Codecs") + else try_real_subpath("lib/RealPlayer9/users/Real/Codecs") + else try_real_subpath("lib/RealPlayer8/Codecs") + else try_real_subpath("RealPlayer8/Codecs"); + +#undef try_real_path +#undef try_real_subpath +#endif + + real_codecs_path = + xine->config->register_filename (xine->config, "decoder.external.real_codecs_path", + default_real_codecs_path, + XINE_CONFIG_STRING_IS_DIRECTORY_NAME, + _("path to RealPlayer codecs"), + _("If you have RealPlayer installed, specify the path " + "to its codec directory here. You can easily find " + "the codec directory by looking for a file named " + "\"drvc.so\" in it. If xine can find the RealPlayer " + "codecs, it will use them to decode RealPlayer content " + "for you. Consult the xine FAQ for more information on " + "how to install the codecs."), + 10, NULL, NULL); + + lprintf ("real codecs path : %s\n", real_codec_path); +} + +void *_x_real_codec_open(xine_stream_t *const stream, const char *const path, + const char *const codec_name, + const char *const codec_alternate) { + char *codecpath = NULL; + void *codecmodule = NULL; + + asprintf(&codecpath, "%s/%s", path, codec_name); + if ( (codecmodule = dlopen(codecpath, RTLD_NOW)) ) { + free(codecpath); + return codecmodule; + } + + xprintf (stream->xine, XINE_VERBOSITY_DEBUG, + LOG_MODULE ": error loading %s: %s\n", codecpath, dlerror()); + + free(codecpath); + + if ( codec_alternate ) { + asprintf(&codecpath, "%s/%s", path, codec_alternate); + if ( (codecmodule = dlopen(codecpath, RTLD_NOW)) ) { + free(codecpath); + return codecmodule; + } + + xprintf (stream->xine, XINE_VERBOSITY_DEBUG, + LOG_MODULE ": error loading %s: %s\n", codecpath, dlerror()); + } + + _x_message(stream, XINE_MSG_LIBRARY_LOAD_ERROR, codec_name, NULL); + + return NULL; +} + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 18, "realvdec", XINE_VERSION_CODE, &dec_info_realvideo, init_realvdec }, + { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 15, "realadec", XINE_VERSION_CODE, &dec_info_realaudio, init_realadec }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/libreal/real_common.h b/src/libreal/real_common.h new file mode 100644 index 000000000..232bf2a4d --- /dev/null +++ b/src/libreal/real_common.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2000-2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: real_common.h,v 1.7 2007/03/17 15:45:41 dgp85 Exp $ + * + * Common function for the thin layer to use Real binary-only codecs in xine + */ + +#ifndef __REAL_COMMON_H__ +#define __REAL_COMMON_H__ + +#include "xine_internal.h" + +/* + * some fake functions to make real codecs happy + * These are, on current date (20070316) needed only for Alpha + * codecs. + * As they are far from being proper replacements, define them only there + * until new codecs are available there too. + */ +#ifdef __alpha__ + +void *__builtin_new(size_t size); +void __builtin_delete (void *foo); +void *__builtin_vec_new(size_t size) EXPORTED; +void __builtin_vec_delete(void *mem) EXPORTED; +void __pure_virtual(void) EXPORTED; + +#endif + +#ifndef HAVE___ENVIRON +# ifdef HAVE__ENVIRON + char **__environ __attribute__((weak, alias("_environ"))); +# elif defined(HAVE_ENVIRON) + char **__environ __attribute__((weak, alias("environ"))); +# else + char **fake__environ = { NULL }; + char **__environ __attribute__((weak, alias("fake__environ"))); +# endif +#endif + +#ifndef HAVE_STDERR +# ifdef HAVE___STDERRP +# undef stderr +FILE *stderr __attribute__((weak, alias("__stderrp"))); +# else +# error Your stderr alias is not supported, please report to xine developers. +# endif +#endif + +#ifndef HAVE____BRK_ADDR +void ___brk_addr(void) EXPORTED; +#endif + +#ifndef HAVE___CTYPE_B +void __ctype_b(void) EXPORTED; +#endif + +void _x_real_codecs_init(xine_t *const xine); +void *_x_real_codec_open(xine_stream_t *const stream, const char *const path, + const char *const codec_name, + const char *const codec_alternate); + +const decoder_info_t dec_info_realvideo; +void *init_realvdec (xine_t *xine, void *data); + +const decoder_info_t dec_info_realaudio; +void *init_realadec (xine_t *xine, void *data); + +#endif diff --git a/src/libreal/xine_decoder.c b/src/libreal/xine_decoder.c index 0ed7f12d8..ea1fc8c54 100644 --- a/src/libreal/xine_decoder.c +++ b/src/libreal/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.83 2006/07/10 22:08:30 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.93 2007/03/17 15:45:41 dgp85 Exp $ * * thin layer to use real binary-only codecs in xine * @@ -32,9 +32,6 @@ #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> -#ifdef __x86_64__ - #include <elf.h> -#endif #define LOG_MODULE "real_decoder" #define LOG_VERBOSE @@ -47,6 +44,8 @@ #include "buffer.h" #include "xineutils.h" +#include "real_common.h" + typedef struct { video_decoder_class_t decoder_class; @@ -64,11 +63,11 @@ typedef struct realdec_decoder_s { void *rv_handle; - uint32_t (*rvyuv_custom_message)(uint32_t*, void*); + uint32_t (*rvyuv_custom_message)(void*, void*); uint32_t (*rvyuv_free)(void*); uint32_t (*rvyuv_hive_message)(uint32_t, uint32_t); uint32_t (*rvyuv_init)(void*, void*); /* initdata,context */ - uint32_t (*rvyuv_transform)(char*, char*, uint32_t*, uint32_t*,void*); + uint32_t (*rvyuv_transform)(char*, char*, void*, uint32_t*,void*); void *context; @@ -101,87 +100,40 @@ typedef struct { int32_t format; } rv_init_t; - -void *__builtin_vec_new(uint32_t size); -void __builtin_vec_delete(void *mem); -void __pure_virtual(void); - -#ifdef __x86_64__ -/* (gb) quick-n-dirty check to be run natively */ -static int is_x86_64_object_(FILE *f) -{ - Elf64_Ehdr *hdr = malloc(sizeof(Elf64_Ehdr)); - if (hdr == NULL) - return 0; - - if (fseek(f, 0, SEEK_SET) != 0) { - free(hdr); - return 0; - } - - if (fread(hdr, sizeof(Elf64_Ehdr), 1, f) != 1) { - free(hdr); - return 0; - } - - if (hdr->e_ident[EI_MAG0] != ELFMAG0 || - hdr->e_ident[EI_MAG1] != ELFMAG1 || - hdr->e_ident[EI_MAG2] != ELFMAG2 || - hdr->e_ident[EI_MAG3] != ELFMAG3) { - free(hdr); - return 0; - } - - return hdr->e_machine == EM_X86_64; -} - -static inline int is_x86_64_object(const char *filename) -{ - FILE *f; - int ret; - - if ((f = fopen(filename, "r")) == NULL) - return 0; - - ret = is_x86_64_object_(f); - fclose(f); - return ret; -} -#endif +/* + * Structures for data packets. These used to be tables of unsigned ints, but + * that does not work on 64 bit platforms (e.g. Alpha). The entries that are + * pointers get truncated. Pointers on 64 bit platforms are 8 byte longs. + * So we have to use structures so the compiler will assign the proper space + * for the pointer. + */ +typedef struct cmsg_data_s { + uint32_t data1; + uint32_t data2; + uint32_t* dimensions; +} cmsg_data_t; + +typedef struct transform_in_s { + uint32_t len; + uint32_t unknown1; + uint32_t chunks; + uint32_t* extra; + uint32_t unknown2; + uint32_t timestamp; +} transform_in_t; /* * real codec loader */ -static int load_syms_linux (realdec_decoder_t *this, char *codec_name, - const char *alt_codec_name) { - - cfg_entry_t* entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "decoder.external.real_codecs_path"); - char path[1024]; - struct stat sb; - - snprintf (path, sizeof(path), "%s/%s", entry->str_value, codec_name); - if (stat(path, &sb)) - snprintf (path, sizeof(path), "%s/%s", entry->str_value, alt_codec_name); +static int load_syms_linux (realdec_decoder_t *this, const char *codec_name, const char *const codec_alternate) { + cfg_entry_t* entry = + this->stream->xine->config->lookup_entry(this->stream->xine->config, + "decoder.external.real_codecs_path"); -#ifdef __x86_64__ - /* check whether it's a real x86-64 library */ - if (!is_x86_64_object(path)) - return 0; -#endif - - lprintf ("opening shared obj '%s'\n", path); - - this->rv_handle = dlopen (path, RTLD_LAZY); - - if (!this->rv_handle) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libreal: error: %s\n", dlerror()); - _x_message(this->stream, XINE_MSG_LIBRARY_LOAD_ERROR, - codec_name, NULL); + if ( (this->rv_handle = _x_real_codec_open(this->stream, entry->str_value, codec_name, codec_alternate)) == NULL ) return 0; - } - + this->rvyuv_custom_message = dlsym (this->rv_handle, "RV20toYUV420CustomMessage"); this->rvyuv_free = dlsym (this->rv_handle, "RV20toYUV420Free"); this->rvyuv_hive_message = dlsym (this->rv_handle, "RV20toYUV420HiveMessage"); @@ -233,7 +185,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { break; case BUF_VIDEO_RV40: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 4.0"); - if (!load_syms_linux(this, "drvc.so", "drv4.so.6.0")) + if (!load_syms_linux(this, "drvc.so", "drv3.so.6.0")) return 0; break; default: @@ -262,7 +214,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { this->duration = 90000.0 / this->fps; #endif - lprintf("this->ratio=%d\n", this->ratio); + lprintf("this->ratio=%f\n", this->ratio); lprintf ("init_data.w=%d(0x%x), init_data.h=%d(0x%x)," "this->width=%d(0x%x), this->height=%d(0x%x)\n", @@ -298,20 +250,14 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { /* setup rv30 codec (codec sub-type and image dimensions): */ if ((init_data.format>=0x20200002) && (buf->type != BUF_VIDEO_RV40)) { int i, j; - uint32_t *cmsg24; - uint32_t cmsg_data[9]; + uint32_t cmsg24[(buf->size - 34 + 2) * sizeof(uint32_t)]; + cmsg_data_t cmsg_data = { 0x24, 1 + ((init_data.subformat >> 16) & 7), &cmsg24[0] }; - cmsg24 = xine_xmalloc((buf->size - 34 + 2) * sizeof(uint32_t)); - cmsg24[0] = this->width; cmsg24[1] = this->height; for(i = 2, j = 34; j < buf->size; i++, j++) cmsg24[i] = 4 * buf->content[j]; - cmsg_data[0] = 0x24; - cmsg_data[1] = 1 + ((init_data.subformat >> 16) & 7); - cmsg_data[2] = (uint32_t) cmsg24; - #ifdef LOG printf ("libreal: CustomMessage cmsg_data:\n"); xine_hexdump ((uint8_t *) cmsg_data, sizeof (cmsg_data)); @@ -319,9 +265,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { xine_hexdump ((uint8_t *) cmsg24, (buf->size - 34 + 2) * sizeof(uint32_t)); #endif - this->rvyuv_custom_message (cmsg_data, this->context); - - free(cmsg24); + this->rvyuv_custom_message (&cmsg_data, this->context); } this->stream->video_out->open(this->stream->video_out, this->stream); @@ -338,7 +282,7 @@ static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; - lprintf ("decode_data, flags=0x%08x, len=%d, pts=%lld ...\n", + lprintf ("decode_data, flags=0x%08x, len=%d, pts=%"PRId64" ...\n", buf->decoder_flags, buf->size, buf->pts); if (buf->decoder_flags & BUF_FLAG_PREVIEW) { @@ -374,7 +318,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) this->chunk_buffer_size = 0; this->pts = buf->pts; - lprintf ("new frame starting, pts=%lld\n", this->pts); + lprintf ("new frame starting, pts=%"PRId64"\n", this->pts); } if ((this->chunk_buffer_size + buf->size) > this->chunk_buffer_max) { @@ -401,16 +345,23 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) vo_frame_t *img; uint32_t transform_out[5]; - uint32_t transform_in[6]; + transform_in_t transform_in = { + this->chunk_buffer_size, + /* length of the packet (sub-packets appended) */ + 0, + /* unknown, seems to be unused */ + buf->decoder_info[2], + /* number of sub-packets - 1 */ + buf->decoder_info_ptr[2], + /* table of sub-packet offsets */ + 0, + /* unknown, seems to be unused */ + this->pts / 90 + /* timestamp (the integer value from the stream) */ + }; lprintf ("chunk table\n"); - transform_in[0] = this->chunk_buffer_size; /* length of the packet (sub-packets appended) */ - transform_in[1] = 0; /* unknown, seems to be unused */ - transform_in[2] = buf->decoder_info[2]; /* number of sub-packets - 1 */ - transform_in[3] = (uint32_t) buf->decoder_info_ptr[2]; /* table of sub-packet offsets */ - transform_in[4] = 0; /* unknown, seems to be unused */ - transform_in[5] = this->pts / 90; /* timestamp (the integer value from the stream) */ #ifdef LOG printf ("libreal: got %d chunks\n", @@ -429,7 +380,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) result = this->rvyuv_transform (this->chunk_buffer, this->frame_buffer, - transform_in, + &transform_in, transform_out, this->context); @@ -574,32 +525,10 @@ static void dispose_class (video_decoder_class_t *this) { free (this); } -/* - * some fake functions to make real codecs happy - */ -void *__builtin_vec_new(uint32_t size) EXPORTED; -void __builtin_vec_delete(void *mem) EXPORTED; -void __pure_virtual(void) EXPORTED; - -void *__builtin_vec_new(uint32_t size) { - return malloc(size); -} -void __builtin_vec_delete(void *mem) { - free(mem); -} -void __pure_virtual(void) { - lprintf("libreal: FATAL: __pure_virtual() called!\n"); - /* exit(1); */ -} - - -static void *init_class (xine_t *xine, void *data) { +void *init_realvdec (xine_t *xine, void *data) { real_class_t *this; config_values_t *config = xine->config; - char *real_codec_path; - char *default_real_codec_path = ""; - struct stat s; this = (real_class_t *) xine_xmalloc (sizeof (real_class_t)); @@ -608,44 +537,7 @@ static void *init_class (xine_t *xine, void *data) { this->decoder_class.get_description = get_description; this->decoder_class.dispose = dispose_class; - /* try some auto-detection */ - - if (!stat ("/usr/local/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/local/RealPlayer8/Codecs"; - if (!stat ("/usr/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/RealPlayer8/Codecs"; - if (!stat ("/usr/lib/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/RealPlayer8/Codecs"; - if (!stat ("/opt/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/opt/RealPlayer8/Codecs"; - if (!stat ("/usr/lib/RealPlayer9/users/Real/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/RealPlayer9/users/Real/Codecs"; - if (!stat ("/usr/lib/RealPlayer10/codecs/drvc.so", &s)) - default_real_codec_path = "/usr/lib/RealPlayer10/codecs"; - if (!stat ("/usr/lib64/RealPlayer8/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer8/Codecs"; - if (!stat ("/usr/lib64/RealPlayer9/users/Real/Codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer9/users/Real/Codecs"; - if (!stat ("/usr/lib64/RealPlayer10/codecs/drvc.so", &s)) - default_real_codec_path = "/usr/lib64/RealPlayer10/codecs"; - if (!stat ("/usr/lib/codecs/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/codecs"; - if (!stat ("/usr/lib/win32/drv3.so.6.0", &s)) - default_real_codec_path = "/usr/lib/win32"; - - real_codec_path = config->register_string (config, "decoder.external.real_codecs_path", - default_real_codec_path, - _("path to RealPlayer codecs"), - _("If you have RealPlayer installed, specify the path " - "to its codec directory here. You can easily find " - "the codec directory by looking for a file named " - "\"drv3.so.6.0\" in it. If xine can find the RealPlayer " - "codecs, it will use them to decode RealPlayer content " - "for you. Consult the xine FAQ for more information on " - "how to install the codecs."), - 10, NULL, this); - - lprintf ("real codec path : %s\n", real_codec_path); + _x_real_codecs_init(xine); return this; } @@ -659,13 +551,7 @@ static uint32_t supported_types[] = { BUF_VIDEO_RV20, BUF_VIDEO_RV40, 0 }; -static const decoder_info_t dec_info_real = { +const decoder_info_t dec_info_realvideo = { supported_types, /* supported types */ 7 /* priority */ }; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 18, "real", XINE_VERSION_CODE, &dec_info_real, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libw32dll/dmo/.cvsignore b/src/libspeex/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libw32dll/dmo/.cvsignore +++ b/src/libspeex/.hgignore diff --git a/src/libspeex/xine_decoder.c b/src/libspeex/xine_decoder.c index e324eb3ed..b729dc3bb 100644 --- a/src/libspeex/xine_decoder.c +++ b/src/libspeex/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.21 2006/09/14 02:07:01 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.22 2007/01/19 01:48:05 dgp85 Exp $ * * (ogg/)speex audio decoder plugin (libspeex wrapper) for xine */ @@ -298,7 +298,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { int bitrate; ogg_int16_t * ptr = audio_buffer->mem; - ret = speex_decode (this->st, &this->bits, (short *) this->output); + ret = speex_decode (this->st, &this->bits, this->output); if (ret==-1) break; @@ -312,7 +312,7 @@ static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { } if (this->channels == 2) { - speex_decode_stereo ( (short *) this->output, this->frame_size, &this->stereo); + speex_decode_stereo (this->output, this->frame_size, &this->stereo); } speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); diff --git a/src/libw32dll/wine/.cvsignore b/src/libspucc/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libw32dll/wine/.cvsignore +++ b/src/libspucc/.hgignore diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c index 4acd2cf0e..ba688accf 100644 --- a/src/libspucc/cc_decoder.c +++ b/src/libspucc/cc_decoder.c @@ -20,7 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: cc_decoder.c,v 1.27 2005/09/25 00:44:04 miguelfreitas Exp $ + * $Id: cc_decoder.c,v 1.28 2007/02/20 00:56:36 dgp85 Exp $ * * stuff needed to provide closed captioning decoding and display * @@ -213,13 +213,6 @@ static uint8_t *cc_alpha_palettes[NUM_CC_PALETTES] = { cc_text_solid_alpha }; - -char *cc_schemes[NUM_CC_PALETTES + 1] = { - "White/Gray/Translucent", - "White/Black/Solid", - NULL -}; - /* --------------------- misc. EIA 608 definitions -------------------*/ #define TRANSP_SPACE 0x19 /* code for transparent space, essentially diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h index 1e298515e..0e7fb69a5 100644 --- a/src/libspucc/cc_decoder.h +++ b/src/libspucc/cc_decoder.h @@ -20,7 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: cc_decoder.h,v 1.7 2004/05/05 17:36:48 mroi Exp $ + * $Id: cc_decoder.h,v 1.8 2007/02/20 00:56:36 dgp85 Exp $ * * stuff needed to provide closed captioning decoding and display * @@ -33,7 +33,11 @@ typedef struct cc_decoder_s cc_decoder_t; typedef struct cc_renderer_s cc_renderer_t; #define NUM_CC_PALETTES 2 -extern char *cc_schemes[NUM_CC_PALETTES + 1]; +static const char *cc_schemes[NUM_CC_PALETTES + 1] = { + "White/Gray/Translucent", + "White/Black/Solid", + NULL +}; #define CC_FONT_MAX 256 diff --git a/src/libxineadec/.cvsignore b/src/libspucmml/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libxineadec/.cvsignore +++ b/src/libspucmml/.hgignore diff --git a/src/libxineadec/gsm610/.cvsignore b/src/libspudec/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libxineadec/gsm610/.cvsignore +++ b/src/libspudec/.hgignore diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am index aedfb2e71..d50c49ca6 100644 --- a/src/libspudec/Makefile.am +++ b/src/libspudec/Makefile.am @@ -9,7 +9,7 @@ if HAVE_DVDNAV xineplug_decode_spu_la_SOURCES = \ spu.c \ xine_decoder.c -xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(THREAD_LIBS) +xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS) else @@ -18,7 +18,7 @@ xineplug_decode_spu_la_SOURCES = \ spu.c \ xine_decoder.c AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav -xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) endif diff --git a/src/libxineadec/nosefart/.cvsignore b/src/libspudvb/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libxineadec/nosefart/.cvsignore +++ b/src/libspudvb/.hgignore diff --git a/src/libspudvb/Makefile.am b/src/libspudvb/Makefile.am index 704d085c5..1efc8252f 100644 --- a/src/libspudvb/Makefile.am +++ b/src/libspudvb/Makefile.am @@ -5,6 +5,6 @@ libdir = $(XINE_PLUGINDIR) lib_LTLIBRARIES = xineplug_decode_spudvb.la xineplug_decode_spudvb_la_SOURCES = xine_decoder.c -xineplug_decode_spudvb_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_decode_spudvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_decode_spudvb_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_decode_spudvb_la_LDFLAGS = -avoid-version -module diff --git a/src/libxinevdec/.cvsignore b/src/libsputext/.hgignore index 7d926a554..7d926a554 100644 --- a/src/libxinevdec/.cvsignore +++ b/src/libsputext/.hgignore diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index d5c591212..c17dde6c8 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_sputext.c,v 1.49 2006/07/10 22:08:30 dgp85 Exp $ + * $Id: demux_sputext.c,v 1.53 2007/01/19 01:05:25 dgp85 Exp $ * * code based on old libsputext/xine_decoder.c * @@ -727,7 +727,7 @@ static subtitle_t *sub_read_line_aqt (demux_sputext_t *this, subtitle_t *current sub_readtext((char *) &line,¤t->text[1]); current->lines = 2; - if ((current->text[0]=="") && (current->text[1]=="")) { + if ((current->text[0][0]==0) && (current->text[1][0]==0)) { return NULL; } @@ -915,7 +915,8 @@ static subtitle_t *sub_read_line_jacobsub(demux_sputext_t *this, subtitle_t *cur return NULL; trail_space(directive); strncat(line2, directive, - (LINE_LEN > 511) ? LINE_LEN : 511); + ((LINE_LEN > 511) ? LINE_LEN-1 : 511) + - strlen(line2)); break; } default: @@ -1403,10 +1404,8 @@ static demux_plugin_t *open_demux_plugin (demux_class_t *class_gen, xine_stream_ switch (stream->content_detection_method) { case METHOD_BY_EXTENSION: { - char *mrl, *ending; - - mrl = input->get_mrl(input); - ending = strrchr(mrl, '.'); + const char *const mrl = input->get_mrl(input); + const char *const ending = strrchr(mrl, '.'); if (!ending || ( (strncasecmp(ending, ".asc", 4) != 0) && @@ -1451,19 +1450,19 @@ static demux_plugin_t *open_demux_plugin (demux_class_t *class_gen, xine_stream_ return NULL; } -static char *get_demux_description (demux_class_t *this_gen) { +static const char *get_demux_description (demux_class_t *this_gen) { return "sputext demuxer plugin"; } -static char *get_demux_identifier (demux_class_t *this_gen) { +static const char *get_demux_identifier (demux_class_t *this_gen) { return "sputext"; } -static char *get_demux_extensions (demux_class_t *this_gen) { +static const char *get_demux_extensions (demux_class_t *this_gen) { return "asc txt sub srt smi ssa"; } -static char *get_demux_mimetypes (demux_class_t *this_gen) { +static const char *get_demux_mimetypes (demux_class_t *this_gen) { return NULL; /* do not report this mimetype, it might confuse browsers. */ diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c index 851a9af93..e8ef631ca 100644 --- a/src/libsputext/xine_decoder.c +++ b/src/libsputext/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.96 2006/09/26 02:36:55 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.99 2007/02/20 01:04:07 dgp85 Exp $ * */ @@ -64,6 +64,10 @@ typedef struct sputext_class_s { subtitle_size subtitle_size; /* size of subtitles */ int vertical_offset; char font[FONTNAME_SIZE]; /* subtitle font */ +#ifdef HAVE_FT2 + char font_ft[FILENAME_MAX]; /* subtitle font */ + int use_font_ft; /* use Freetype */ +#endif char *src_encoding; /* encoding of subtitle file */ int use_unscaled; /* use unscaled OSD if possible */ @@ -87,7 +91,7 @@ typedef struct sputext_decoder_s { */ subtitle_size subtitle_size; /* size of subtitles */ int vertical_offset; - char font[FONTNAME_SIZE]; /* subtitle font */ + char font[FILENAME_MAX]; /* subtitle font */ char *buf_encoding; /* encoding of subtitle buffer */ int width; /* frame width */ @@ -107,6 +111,14 @@ typedef struct sputext_decoder_s { int last_lines; /* number of lines of the previous subtitle */ } sputext_decoder_t; +static inline char *get_font (sputext_class_t *class) +{ +#ifdef HAVE_FT2 + return class->use_font_ft ? class->font_ft : class->font; +#else + return class->font; +#endif +} static void update_font_size (sputext_decoder_t *this, int force_update) { static int sizes[SUBTITLE_SIZE_NUM] = { 16, 20, 24, 32, 48, 64 }; @@ -138,7 +150,7 @@ static void update_font_size (sputext_decoder_t *this, int force_update) { this->width, SUB_MAX_TEXT * this->line_height); - this->renderer->set_font (this->osd, this->class->font, this->font_size); + this->renderer->set_font (this->osd, get_font (this->class), this->font_size); this->renderer->set_position (this->osd, 0, y); } } @@ -338,6 +350,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su int line, y; int font_size; + char *font; _x_assert(this->renderer != NULL); if ( ! this->renderer ) @@ -345,10 +358,11 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su update_font_size(this, 0); - if( strcmp(this->font, this->class->font) ) { - strncpy(this->font, this->class->font, FONTNAME_SIZE); - this->font[FONTNAME_SIZE - 1] = '\0'; - this->renderer->set_font (this->osd, this->class->font, this->font_size); + font = get_font (this->class); + if( strcmp(this->font, font) ) { + strncpy(this->font, font, FILENAME_MAX); + this->font[FILENAME_MAX - 1] = '\0'; + this->renderer->set_font (this->osd, font, this->font_size); } font_size = this->font_size; @@ -546,7 +560,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su if( w > this->width && font_size > 16 ) { font_size -= 4; - this->renderer->set_font (this->osd, this->class->font, font_size); + this->renderer->set_font (this->osd, get_font (this->class), font_size); } else { break; } @@ -561,7 +575,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } if( font_size != this->font_size ) - this->renderer->set_font (this->osd, this->class->font, this->font_size); + this->renderer->set_font (this->osd, get_font (this->class), this->font_size); if( this->last_subtitle_end && sub_start < this->last_subtitle_end ) { sub_start = this->last_subtitle_end; @@ -577,7 +591,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->renderer->hide (this->osd, sub_end); - lprintf ("scheduling subtitle >%s< at %lld until %lld, current time is %lld\n", + lprintf ("scheduling subtitle >%s< at %"PRId64" until %"PRId64", current time is %"PRId64"\n", this->text[0], sub_start, sub_end, this->stream->xine->clock->get_current_time (this->stream->xine->clock)); } @@ -824,6 +838,27 @@ static void update_osd_font(void *class_gen, xine_cfg_entry_t *entry) xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_font = %s\n", class->font ); } +#ifdef HAVE_FT2 +static void update_osd_font_ft(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + strncpy(class->font_ft, entry->str_value, FILENAME_MAX); + class->font_ft[FILENAME_MAX - 1] = '\0'; + + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_font_ft = %s\n", class->font_ft); +} + +static void update_osd_use_font_ft(void *class_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *class = (sputext_class_t *)class_gen; + + class->use_font_ft = entry->num_value; + + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "libsputext: spu_use_font_ft = %d\n", class->use_font_ft); +} +#endif + static void update_subtitle_size(void *class_gen, xine_cfg_entry_t *entry) { sputext_class_t *class = (sputext_class_t *)class_gen; @@ -890,7 +925,7 @@ static void update_src_encoding(void *class_gen, xine_cfg_entry_t *entry) static void *init_spu_decoder_plugin (xine_t *xine, void *data) { - static char *subtitle_size_strings[] = { + static const char *subtitle_size_strings[] = { "tiny", "small", "normal", "large", "very large", "huge", NULL }; sputext_class_t *this ; @@ -929,6 +964,21 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) { "subtitle text."), 10, update_osd_font, this), FONTNAME_SIZE); this->font[FONTNAME_SIZE - 1] = '\0'; +#ifdef HAVE_FT2 + strncpy(this->font_ft, xine->config->register_filename(xine->config, + "subtitles.separate.font_freetype", + "", XINE_CONFIG_STRING_IS_FILENAME, + _("font for subtitles"), + _("An outline font file (e.g. a .ttf) to be used for the subtitle text."), + 10, update_osd_font_ft, this), FILENAME_MAX); + this->font_ft[FILENAME_MAX - 1] = '\0'; + this->use_font_ft = xine->config->register_bool(xine->config, + "subtitles.separate.font_use_freetype", + 0, + _("whether to use a freetype font"), + NULL, + 10, update_osd_use_font_ft, this); +#endif this->src_encoding = xine->config->register_string(xine->config, "subtitles.separate.src_encoding", xine_guess_spu_encoding(), diff --git a/src/post/audio/.cvsignore b/src/libtheora/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/audio/.cvsignore +++ b/src/libtheora/.hgignore diff --git a/src/post/deinterlace/.cvsignore b/src/libvorbis/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/deinterlace/.cvsignore +++ b/src/libvorbis/.hgignore diff --git a/src/libvorbis/xine_decoder.c b/src/libvorbis/xine_decoder.c index 12d0a83f2..ef8575949 100644 --- a/src/libvorbis/xine_decoder.c +++ b/src/libvorbis/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.47 2006/07/10 22:08:30 dgp85 Exp $ + * $Id: xine_decoder.c,v 1.48 2006/12/04 13:59:38 dgp85 Exp $ * * (ogg/)vorbis audio decoder plugin (libvorbis wrapper) for xine */ @@ -148,13 +148,16 @@ static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { lprintf ("%d headers to go\n", this->header_count); if (this->header_count) { + int res = 0; if (this->header_count == 3) this->op.b_o_s = 1; - if(vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)<0){ + + if( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ){ /* error case; not a vorbis header */ - printf("libvorbis: this bitstream does not contain vorbis audio data.\n"); + xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res); + xine_hexdump(this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64); return; } diff --git a/src/post/deinterlace/plugins/.cvsignore b/src/libw32dll/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/deinterlace/plugins/.cvsignore +++ b/src/libw32dll/.hgignore diff --git a/src/post/goom/.cvsignore b/src/libw32dll/DirectShow/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/goom/.cvsignore +++ b/src/libw32dll/DirectShow/.hgignore diff --git a/src/libw32dll/DirectShow/DS_VideoDecoder.c b/src/libw32dll/DirectShow/DS_VideoDecoder.c index e34659f91..44c6d26d7 100644 --- a/src/libw32dll/DirectShow/DS_VideoDecoder.c +++ b/src/libw32dll/DirectShow/DS_VideoDecoder.c @@ -110,6 +110,7 @@ DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEAD this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs); memcpy(this->iv.m_bh, format, bihs); + this->iv.m_bh->biSize = bihs; this->iv.m_State = STOP; //this->iv.m_pFrame = 0; diff --git a/src/libw32dll/Makefile.am b/src/libw32dll/Makefile.am index aa42cd8e3..46027d0f1 100644 --- a/src/libw32dll/Makefile.am +++ b/src/libw32dll/Makefile.am @@ -16,21 +16,23 @@ lib_LTLIBRARIES = $(w32dll_codec) $(qt_codec) EXTRA_DIST = common.c xineplug_decode_w32dll_la_SOURCES = w32codec.c -xineplug_decode_w32dll_la_LDFLAGS = -avoid-version -module \ - @IMPURE_TEXT_LDFLAGS@ +xineplug_decode_w32dll_la_LDFLAGS = -avoid-version -module xineplug_decode_w32dll_la_LIBADD = \ $(top_builddir)/src/libw32dll/wine/libwine.la \ $(XINE_LIB) \ + $(PTHREAD_LIBS) \ + -lm \ $(top_builddir)/src/libw32dll/DirectShow/libds_filter.la \ $(top_builddir)/src/libw32dll/dmo/libdmo_filter.la \ @KSTAT_LIBS@ xineplug_decode_qt_la_SOURCES = qt_decoder.c -xineplug_decode_qt_la_LDFLAGS = -avoid-version -module \ - IMPURE_TEXT_LDFLAGS@ +xineplug_decode_qt_la_LDFLAGS = -avoid-version -module xineplug_decode_qt_la_LIBADD = \ $(top_builddir)/src/libw32dll/wine/libwine.la \ $(XINE_LIB) \ + $(PTHREAD_LIBS) \ + -lm \ @KSTAT_LIBS@ noinst_HEADERS = libwin32.h w32codec.h diff --git a/src/libw32dll/common.c b/src/libw32dll/common.c index 1f42288c2..35fe41941 100644 --- a/src/libw32dll/common.c +++ b/src/libw32dll/common.c @@ -13,7 +13,7 @@ static char *get_win32_codecs_path(config_values_t *cfg) { NULL }; int i = 0; - cfgpath = cfg->register_string (cfg, "decoder.external.win32_codecs_path", WIN32_PATH, + cfgpath = cfg->register_filename (cfg, "decoder.external.win32_codecs_path", WIN32_PATH, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("path to Win32 codecs"), _("If you have the Windows or Apple Quicktime codec packs " "installed, specify the path the codec directory here. " diff --git a/src/post/mosaico/.cvsignore b/src/libw32dll/dmo/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/mosaico/.cvsignore +++ b/src/libw32dll/dmo/.hgignore diff --git a/src/libw32dll/dmo/DMO_VideoDecoder.c b/src/libw32dll/dmo/DMO_VideoDecoder.c index 564c26ec8..3ad85645a 100644 --- a/src/libw32dll/dmo/DMO_VideoDecoder.c +++ b/src/libw32dll/dmo/DMO_VideoDecoder.c @@ -118,6 +118,7 @@ DMO_VideoDecoder * DMO_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHE this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs); memcpy(this->iv.m_bh, format, bihs); + this->iv.m_bh->biSize = bihs; this->iv.m_State = STOP; //this->iv.m_pFrame = 0; diff --git a/src/libw32dll/qtx/.cvsignore b/src/libw32dll/qtx/.hgignore index 22a4e7292..22a4e7292 100644 --- a/src/libw32dll/qtx/.cvsignore +++ b/src/libw32dll/qtx/.hgignore diff --git a/src/libw32dll/qtx/qtxsdk/.cvsignore b/src/libw32dll/qtx/qtxsdk/.hgignore index 282522db0..282522db0 100644 --- a/src/libw32dll/qtx/qtxsdk/.cvsignore +++ b/src/libw32dll/qtx/qtxsdk/.hgignore diff --git a/src/post/planar/.cvsignore b/src/libw32dll/wine/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/planar/.cvsignore +++ b/src/libw32dll/wine/.hgignore diff --git a/src/libw32dll/wine/ldt_keeper.c b/src/libw32dll/wine/ldt_keeper.c index 11711ce62..7f7169b86 100644 --- a/src/libw32dll/wine/ldt_keeper.c +++ b/src/libw32dll/wine/ldt_keeper.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: ldt_keeper.c,v 1.15 2006/05/07 09:31:57 valtri Exp $ + * $Id: ldt_keeper.c,v 1.16 2007/03/09 23:49:35 dgp85 Exp $ * * * contents: @@ -54,6 +54,7 @@ /* applied some modification to make make our xine friend more happy */ #include "ldt_keeper.h" +#include "config.h" #include <string.h> #include <stdlib.h> @@ -90,6 +91,7 @@ int modify_ldt(int func, void *ptr, unsigned long bytecount); #include <sys/sysi86.h> /* solaris x86: add missing prototype for sysi86() */ +#ifndef HAVE_SYSI86 #ifdef __cplusplus extern "C" { #endif @@ -97,6 +99,7 @@ int sysi86(int, void*); #ifdef __cplusplus } #endif +#endif #ifndef NUMSYSLDTS /* SunOS 2.5.1 does not define NUMSYSLDTS */ #define NUMSYSLDTS 6 /* Let's hope the SunOS 5.8 value is OK */ diff --git a/src/libw32dll/wine/module.c b/src/libw32dll/wine/module.c index 6e9235584..0331f141f 100644 --- a/src/libw32dll/wine/module.c +++ b/src/libw32dll/wine/module.c @@ -39,8 +39,8 @@ #ifdef EMU_QTX_API #include "wrapper.h" -static int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); -static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); +int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); +int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); #endif //#undef TRACE @@ -389,9 +389,7 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) strncpy(path, libname, sizeof(path) - 1); } else { /* check default user path */ - strncpy(path, win32_def_path, sizeof(path) - 2); - strcat(path, "/"); - strncat(path, libname, sizeof(path) - strlen(libname)); + snprintf(path, sizeof(path), "%s/%s", win32_def_path, libname); } wm = MODULE_LoadLibraryExA( path, hfile, flags ); @@ -521,8 +519,6 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) printf ("wine/module: QuickTime.qts patched!!! old entry=%p\n",ptr[0]); #ifdef EMU_QTX_API - report_entry = report_func; - report_ret = report_func_ret; wrapper_target=ptr[0]; ptr[0]=wrapper; #endif @@ -685,7 +681,7 @@ static int dump_component(char* name,int type,void* _orig, ComponentParameters * static u_int32_t ret_array[4096]; static int ret_i=0; -static int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) +int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) { #ifdef DEBUG_QTX_API int i; @@ -884,7 +880,7 @@ static int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_ return 0; } -static int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) +int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) { #ifdef DEBUG_QTX_API int i; @@ -999,8 +995,6 @@ FARPROC MODULE_GetProcAddress( // || !strcmp(function,"_CallComponent") ){ fprintf(stderr,"theQuickTimeDispatcher caught -> %p\n",retproc); - report_entry = report_func; - report_ret = report_func_ret; wrapper_target=(void *)retproc; retproc=(void *)wrapper; } diff --git a/src/libw32dll/wine/pe_image.c b/src/libw32dll/wine/pe_image.c index 92017f906..aa29098c1 100644 --- a/src/libw32dll/wine/pe_image.c +++ b/src/libw32dll/wine/pe_image.c @@ -47,6 +47,9 @@ #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif #include "windef.h" #include "winbase.h" #include "winerror.h" diff --git a/src/libw32dll/wine/pshpack1.h b/src/libw32dll/wine/pshpack1.h index 659b2ed67..15876039c 100644 --- a/src/libw32dll/wine/pshpack1.h +++ b/src/libw32dll/wine/pshpack1.h @@ -2,7 +2,7 @@ #define __WINE_PSHPACK_H 1 #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__ICC) -//#pragma pack(1) +#pragma pack(1) #elif !defined(RC_INVOKED) #error "1 as alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ diff --git a/src/libw32dll/wine/pshpack2.h b/src/libw32dll/wine/pshpack2.h index a0830be0b..0145d8b13 100644 --- a/src/libw32dll/wine/pshpack2.h +++ b/src/libw32dll/wine/pshpack2.h @@ -2,7 +2,7 @@ #define __WINE_PSHPACK_H 2 #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__ICC) -//#pragma pack(2) +#pragma pack(2) #elif !defined(RC_INVOKED) #error "2 as alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ diff --git a/src/libw32dll/wine/stubs.s b/src/libw32dll/wine/stubs.s index 6aa90ee9d..2c6270616 100644 --- a/src/libw32dll/wine/stubs.s +++ b/src/libw32dll/wine/stubs.s @@ -33,3 +33,6 @@ exp_EH_prolog: leal 12(%esp), %ebp pushl %eax ret + +.section .note.GNU-stack,"",@progbits + diff --git a/src/libw32dll/wine/wrapper.S b/src/libw32dll/wine/wrapper.S index fe2d85619..72b4dfe8f 100644 --- a/src/libw32dll/wine/wrapper.S +++ b/src/libw32dll/wine/wrapper.S @@ -1,17 +1,19 @@ .section .data -.globl caller_return caller_return: .long 0 -.globl report_entry -report_entry: - .long null_call -.globl report_ret -report_ret: - .long null_call .global wrapper_target wrapper_target: .long null_call +#undef __i686 /* gcc define gets in our way */ + .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits +.globl __i686.get_pc_thunk.bx + .hidden __i686.get_pc_thunk.bx + .type __i686.get_pc_thunk.bx,@function +__i686.get_pc_thunk.bx: + movl (%esp), %ebx + ret + .section .text .globl null_call .type null_call, @function @@ -22,46 +24,61 @@ null_call: .type wrapper, @function .balign 16,0x90 wrapper: + pushl $0 pusha # store registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) pushf # store flags push %ebp # set up a stack frame movl %esp, %ebp + call __i686.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr push %eax - leal 40(%ebp), %edx + leal 44(%ebp), %edx movl (%ebp), %eax subl %edx, %eax push %eax push %edx - call *report_entry # report entry + call report_func@PLT # report entry test %eax, %eax jnz .Ldone + movl 44(%ebp), %eax # switch return addresses + movl %eax, caller_return@GOTOFF(%ebx) + leal .Lwrapper_return@GOTOFF(%ebx), %eax + movl %eax, 40(%ebp) + + movl wrapper_target@GOT(%ebx), %eax + movl (%eax), %eax + mov %eax, 40(%ebp) # wrapper_target should return at .Lwrapper_return + leave # restore %esp, %ebp popf # restore flags popa # restore registers - - popl caller_return # switch return addresses - pushl $.Lwrapper_return - - jmp *wrapper_target # wrapper_target should return at .Lwrapper_return + + ret # fake 'return' to wrapper_target actually .balign 16, 0x90 .Lwrapper_return: - pushl caller_return # restore the original return address + pushl $0 pusha # more for reference sake here pushf push %ebp # set up a stack frame movl %esp, %ebp + call __i686.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl caller_return@GOTOFF(%ebx), %eax + movl %eax, 40(%ebp) # restore the original return address + leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr @@ -73,11 +90,13 @@ wrapper: push %eax push %edx - call *report_ret # report the return information (same args) + call report_func_ret@PLT# report the return information (same args) .Ldone: leave popf popa ret - + +.section .note.GNU-stack,"",@progbits + diff --git a/src/libw32dll/wine/wrapper.h b/src/libw32dll/wine/wrapper.h index a9943ce78..5e2cf804e 100644 --- a/src/libw32dll/wine/wrapper.h +++ b/src/libw32dll/wine/wrapper.h @@ -11,10 +11,6 @@ typedef struct { u_int32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; } reg386_t; -typedef int (*wrapper_func_t)(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); - -extern wrapper_func_t report_entry, report_ret; - extern void (*wrapper_target)(void); extern int wrapper(void); diff --git a/src/post/visualizations/.cvsignore b/src/libxineadec/.hgignore index 7d926a554..7d926a554 100644 --- a/src/post/visualizations/.cvsignore +++ b/src/libxineadec/.hgignore diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am index edd259f8f..7f34b4bfd 100644 --- a/src/libxineadec/Makefile.am +++ b/src/libxineadec/Makefile.am @@ -20,7 +20,7 @@ xineplug_decode_gsm610_la_LIBADD = \ xineplug_decode_nsf_la_SOURCES = nsf.c xineplug_decode_nsf_la_CFLAGS = $(VISIBILITY_FLAG) -DNSF_PLAYER -fno-strict-aliasing xineplug_decode_nsf_la_LDFLAGS = -avoid-version -module -xineplug_decode_nsf_la_LIBADD = \ +xineplug_decode_nsf_la_LIBADD = -lm \ $(XINE_LIB) \ $(top_builddir)/src/libxineadec/nosefart/libnosefart.la diff --git a/src/video_out/.cvsignore b/src/libxineadec/gsm610/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/.cvsignore +++ b/src/libxineadec/gsm610/.hgignore diff --git a/src/video_out/libdha/bin/.cvsignore b/src/libxineadec/nosefart/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/libdha/bin/.cvsignore +++ b/src/libxineadec/nosefart/.hgignore diff --git a/src/libxineadec/nosefart/nsf.h b/src/libxineadec/nosefart/nsf.h index 61cc14f60..163e2f62f 100644 --- a/src/libxineadec/nosefart/nsf.h +++ b/src/libxineadec/nosefart/nsf.h @@ -20,7 +20,7 @@ ** nsf.h ** ** NSF loading/saving related defines / prototypes -** $Id: nsf.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +** $Id: nsf.h,v 1.3 2007/01/18 21:34:10 dgp85 Exp $ */ #ifndef _NSF_H_ @@ -66,22 +66,22 @@ enum typedef struct nsf_s { /* NESM header */ - uint8 id[5] __PACKED__; /* NESM\x1A */ - uint8 version __PACKED__; /* spec version */ - uint8 num_songs __PACKED__; /* total num songs */ - uint8 start_song __PACKED__; /* first song */ - uint16 load_addr __PACKED__; /* loc to load code */ - uint16 init_addr __PACKED__; /* init call address */ - uint16 play_addr __PACKED__; /* play call address */ - uint8 song_name[32] __PACKED__; /* name of song */ - uint8 artist_name[32] __PACKED__; /* artist name */ - uint8 copyright[32] __PACKED__; /* copyright info */ - uint16 ntsc_speed __PACKED__; /* playback speed (if NTSC) */ - uint8 bankswitch_info[8] __PACKED__; /* initial code banking */ - uint16 pal_speed __PACKED__; /* playback speed (if PAL) */ - uint8 pal_ntsc_bits __PACKED__; /* NTSC/PAL determination bits */ - uint8 ext_sound_type __PACKED__; /* type of external sound gen. */ - uint8 reserved[4] __PACKED__; /* reserved */ + uint8 id[5]; /* NESM\x1A */ + uint8 version; /* spec version */ + uint8 num_songs; /* total num songs */ + uint8 start_song; /* first song */ + uint16 load_addr; /* loc to load code */ + uint16 init_addr; /* init call address */ + uint16 play_addr; /* play call address */ + uint8 song_name[32]; /* name of song */ + uint8 artist_name[32]; /* artist name */ + uint8 copyright[32]; /* copyright info */ + uint16 ntsc_speed; /* playback speed (if NTSC) */ + uint8 bankswitch_info[8]; /* initial code banking */ + uint16 pal_speed; /* playback speed (if PAL) */ + uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ + uint8 ext_sound_type; /* type of external sound gen. */ + uint8 reserved[4]; /* reserved */ /* things that the NSF player needs */ uint8 *data; /* actual NSF data */ @@ -96,7 +96,7 @@ typedef struct nsf_s /* our main processing routine, calls all external mixing routines */ void (*process)(void *buffer, int num_samples); -} nsf_t; +} __PACKED__ nsf_t; /* Function prototypes */ extern void nsf_init(void); @@ -114,6 +114,9 @@ extern void nsf_setfilter(nsf_t *nsf, int filter_type); /* ** $Log: nsf.h,v $ +** Revision 1.3 2007/01/18 21:34:10 dgp85 +** __attribute__(packed) is used on the struct, not on its members. +** ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** diff --git a/src/video_out/libdha/kernelhelper/.cvsignore b/src/libxinevdec/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/libdha/kernelhelper/.cvsignore +++ b/src/libxinevdec/.hgignore diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am index 8783b6530..903399cbb 100644 --- a/src/libxinevdec/Makefile.am +++ b/src/libxinevdec/Makefile.am @@ -1,5 +1,8 @@ include $(top_srcdir)/misc/Makefile.common +AM_CFLAGS = $(VISIBILITY_FLAG) +AM_LDFLAGS = $(xineplug_ldflags) + EXTRA_DIST = foovideo.c if HAVE_WAND @@ -10,9 +13,7 @@ if HAVE_GDK_PIXBUF gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la endif -libdir = $(XINE_PLUGINDIR) - -lib_LTLIBRARIES = $(image_module) \ +xineplug_LTLIBRARIES = $(image_module) \ $(gdkpixbuf_module) \ xineplug_decode_bitplane.la \ xineplug_decode_rgb.la \ @@ -20,23 +21,18 @@ lib_LTLIBRARIES = $(image_module) \ xineplug_decode_bitplane_la_SOURCES = bitplane.c xineplug_decode_bitplane_la_LIBADD = $(XINE_LIB) -xineplug_decode_bitplane_la_LDFLAGS = -avoid-version -module xineplug_decode_rgb_la_SOURCES = rgb.c xineplug_decode_rgb_la_LIBADD = $(XINE_LIB) -xineplug_decode_rgb_la_LDFLAGS = -avoid-version -module xineplug_decode_yuv_la_SOURCES = yuv.c xineplug_decode_yuv_la_LIBADD = $(XINE_LIB) -xineplug_decode_yuv_la_LDFLAGS = -avoid-version -module xineplug_decode_image_la_SOURCES = image.c -xineplug_decode_image_la_CFLAGS = $(WAND_CFLAGS) +xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS) xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS) -xineplug_decode_image_la_LDFLAGS = -avoid-version -module xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c -xineplug_decode_gdk_pixbuf_la_CFLAGS = $(GDK_PIXBUF_CFLAGS) +xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXBUF_LIBS) -xineplug_decode_gdk_pixbuf_la_LDFLAGS = -avoid-version -module diff --git a/src/post/.cvsignore b/src/post/.hgignore index 282522db0..282522db0 100644 --- a/src/post/.cvsignore +++ b/src/post/.hgignore diff --git a/src/video_out/libdha/oth/.cvsignore b/src/post/audio/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/libdha/oth/.cvsignore +++ b/src/post/audio/.hgignore diff --git a/src/post/audio/Makefile.am b/src/post/audio/Makefile.am index 7ed37bc5b..9cb93dd5a 100644 --- a/src/post/audio/Makefile.am +++ b/src/post/audio/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = xineplug_post_audio_filters.la xineplug_post_audio_filters_la_SOURCES = \ upmix.c upmix_mono.c filter.c window.c stretch.c volnorm.c audio_filters.c -xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) -lm +xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) -lm xineplug_post_audio_filters_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_post_audio_filters_la_LDFLAGS = -avoid-version -module diff --git a/src/video_out/libdha/sysdep/.cvsignore b/src/post/deinterlace/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/libdha/sysdep/.cvsignore +++ b/src/post/deinterlace/.hgignore diff --git a/src/video_out/macosx/.cvsignore b/src/post/deinterlace/plugins/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/macosx/.cvsignore +++ b/src/post/deinterlace/plugins/.hgignore diff --git a/src/post/deinterlace/plugins/greedy2frame_template.c b/src/post/deinterlace/plugins/greedy2frame_template.c index 42c575f58..728bceed5 100644 --- a/src/post/deinterlace/plugins/greedy2frame_template.c +++ b/src/post/deinterlace/plugins/greedy2frame_template.c @@ -1,5 +1,5 @@ /***************************************************************************** -** $Id: greedy2frame_template.c,v 1.9 2006/02/04 14:06:29 miguelfreitas Exp $ +** $Id: greedy2frame_template.c,v 1.10 2006/12/21 09:54:45 dgp85 Exp $ ****************************************************************************** ** Copyright (c) 2000 John Adcock, Tom Barry, Steve Grimm All rights reserved. ** port copyright (c) 2003 Miguel Freitas @@ -19,6 +19,9 @@ ** CVS Log ** ** $Log: greedy2frame_template.c,v $ +** Revision 1.10 2006/12/21 09:54:45 dgp85 +** Apply the textrel patch from Gentoo, thanks to PaX team for providing it. The patch was applied and tested for a while in Gentoo and Pardus, and solves also Debian's problems with non-PIC code. If problems will arise, they'll be debugged. +** ** Revision 1.9 2006/02/04 14:06:29 miguelfreitas ** Enable AMD64 mmx/sse support in some plugins (tvtime, libmpeg2, goom...) ** patch by dani3l @@ -187,7 +190,7 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, * See above for a description of the algorithm. */ ".align 8 \n\t" - "movq "MANGLE(Mask)", %%mm6 \n\t" + "movq %4, %%mm6 \n\t" "movq %0, %%mm1 \n\t" // T1 "movq %1, %%mm0 \n\t" // M1 @@ -195,7 +198,7 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, "movq %3, %%mm2 \n\t" // M0 : /* no output */ : "m" (*T1), "m" (*M1), - "m" (*B1), "m" (*M0) ); + "m" (*B1), "m" (*M0), "m" (Mask) ); asm volatile( @@ -252,10 +255,10 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, #endif /* if |M1-M0| > Threshold we want dword worth of twos */ - "pcmpgtb "MANGLE(qwGreedyTwoFrameThreshold)", %%mm4 \n\t" - "pand "MANGLE(Mask)", %%mm4 \n\t" /* get rid of sign bit */ - "pcmpgtd "MANGLE(DwordOne)", %%mm4 \n\t" /* do we want to bob */ - "pandn "MANGLE(DwordTwo)", %%mm4 \n\t" + "pcmpgtb %3, %%mm4 \n\t" + "pand %4, %%mm4 \n\t" /* get rid of sign bit */ + "pcmpgtd %5, %%mm4 \n\t" /* do we want to bob */ + "pandn %6, %%mm4 \n\t" "movq %1, %%mm2 \n\t" /* mm2 = T0 */ @@ -268,11 +271,11 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, "pand %%mm6, %%mm5 \n\t" /* if |T1-T0| > Threshold we want dword worth of ones */ - "pcmpgtb "MANGLE(qwGreedyTwoFrameThreshold)", %%mm5 \n\t" + "pcmpgtb %3, %%mm5 \n\t" "pand %%mm6, %%mm5 \n\t" /* get rid of sign bit */ - "pcmpgtd "MANGLE(DwordOne)", %%mm5 \n\t" - "pandn "MANGLE(DwordOne)", %%mm5 \n\t" + "pcmpgtd %5, %%mm5 \n\t" + "pandn %5, %%mm5 \n\t" "paddd %%mm5, %%mm4 \n\t" "movq %2, %%mm2 \n\t" /* B0 */ @@ -286,13 +289,13 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, "pand %%mm6, %%mm5 \n\t" /* if |B1-B0| > Threshold we want dword worth of ones */ - "pcmpgtb "MANGLE(qwGreedyTwoFrameThreshold)", %%mm5 \n\t" + "pcmpgtb %3, %%mm5 \n\t" "pand %%mm6, %%mm5 \n\t" /* get rid of any sign bit */ - "pcmpgtd "MANGLE(DwordOne)", %%mm5 \n\t" - "pandn "MANGLE(DwordOne)", %%mm5 \n\t" + "pcmpgtd %5, %%mm5 \n\t" + "pandn %5, %%mm5 \n\t" "paddd %%mm5, %%mm4 \n\t" - "pcmpgtd "MANGLE(DwordTwo)", %%mm4 \n\t" + "pcmpgtd %6, %%mm4 \n\t" /* debugging feature * output the value of mm4 at this point which is pink where we will weave @@ -318,7 +321,7 @@ static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, #endif : "=m" (*Dest2) - : "m" (*T0), "m" (*B0) ); + : "m" (*T0), "m" (*B0), "m" (qwGreedyTwoFrameThreshold), "m" (Mask), "m" (DwordOne), "m" (DwordTwo) ); /* Advance to the next set of pixels. */ T1 += 8; diff --git a/src/post/deinterlace/plugins/greedyh.asm b/src/post/deinterlace/plugins/greedyh.asm index 0bbd745aa..11b28ca76 100644 --- a/src/post/deinterlace/plugins/greedyh.asm +++ b/src/post/deinterlace/plugins/greedyh.asm @@ -43,7 +43,6 @@ static void FUNCT_NAME(uint8_t *output, int outstride, int Line; long LoopCtr; - long oldbx; unsigned int Pitch = stride*2; int FieldHeight = height / 2; @@ -52,6 +51,7 @@ static void FUNCT_NAME(uint8_t *output, int outstride, unsigned char* L3; // ptr to Line3 unsigned char* L2P; // ptr to prev Line2 + unsigned char* temp; unsigned char* Dest = output; int64_t LastAvg=0; //interp value from left qword @@ -121,25 +121,21 @@ static void FUNCT_NAME(uint8_t *output, int outstride, #define asmLastAvg "%0" #define asmL1 "%1" #define asmL3 "%2" -#define asmL2P "%3" +#define asmtemp "%3" #define asmL2 "%4" #define asmDest "%5" #define asmLoopCtr "%6" -#define asmoldbx "%7" #endif // For ease of reading, the comments below assume that we're operating on an odd // field (i.e., that InfoIsOdd is true). Assume the obvious for even lines.. + temp = L2P; __asm__ __volatile__ ( - // save ebx (-fPIC) - MOVX" %%"XBX", "asmoldbx"\n\t" - MOVX" "asmL1", %%"XAX"\n\t" - LEAX" 8(%%"XAX"), %%"XBX"\n\t" // next qword needed by DJR + LEAX" 8(%%"XAX"), %%"XDX"\n\t" // next qword needed by DJR MOVX" "asmL3", %%"XCX"\n\t" SUBX" %%"XAX", %%"XCX"\n\t" // carry L3 addr as an offset - MOVX" "asmL2P", %%"XDX"\n\t" MOVX" "asmL2", %%"XSI"\n\t" MOVX" "asmDest", %%"XDI"\n\t" // DL1 if Odd or DL2 if Even @@ -148,11 +144,14 @@ static void FUNCT_NAME(uint8_t *output, int outstride, "movq (%%"XSI"), %%mm0\n\t" // L2 - the newest weave pixel value "movq (%%"XAX"), %%mm1\n\t" // L1 - the top pixel + PUSHX" %%"XDX "\n\t" + MOVX" "asmtemp", %%"XDX"\n\t" "movq (%%"XDX"), %%mm2\n\t" // L2P - the prev weave pixel + POPX" %%"XDX "\n\t" "movq (%%"XAX", %%"XCX"), %%mm3\n\t" // L3, next odd row "movq %%mm1, %%mm6\n\t" // L1 - get simple single pixel interp // pavgb mm6, mm3 // use macro below - V_PAVGB ("%%mm6", "%%mm3", "%%mm4", MANGLE(ShiftMask)) + V_PAVGB ("%%mm6", "%%mm3", "%%mm4", "%8") // DJR - Diagonal Jaggie Reduction // In the event that we are going to use an average (Bob) pixel we do not want a jagged @@ -166,24 +165,24 @@ static void FUNCT_NAME(uint8_t *output, int outstride, "psllq $16, %%mm7\n\t" // left justify 3 pixels "por %%mm7, %%mm4\n\t" // and combine - "movq (%%"XBX"), %%mm5\n\t" // next horiz qword from L1 + "movq (%%"XDX"), %%mm5\n\t" // next horiz qword from L1 // pavgb mm5, qword ptr[ebx+ecx] // next horiz qword from L3, use macro below - V_PAVGB ("%%mm5", "(%%"XBX",%%"XCX")", "%%mm7", MANGLE(ShiftMask)) + V_PAVGB ("%%mm5", "(%%"XDX",%%"XCX")", "%%mm7", "%8") "psllq $48, %%mm5\n\t" // left just 1 pixel "movq %%mm6, %%mm7\n\t" // another copy of simple bob pixel "psrlq $16, %%mm7\n\t" // right just 3 pixels "por %%mm7, %%mm5\n\t" // combine // pavgb mm4, mm5 // avg of forward and prev by 1 pixel, use macro - V_PAVGB ("%%mm4", "%%mm5", "%%mm5", MANGLE(ShiftMask)) // mm5 gets modified if MMX + V_PAVGB ("%%mm4", "%%mm5", "%%mm5", "%8") // mm5 gets modified if MMX // pavgb mm6, mm4 // avg of center and surround interp vals, use macro - V_PAVGB ("%%mm6", "%%mm4", "%%mm7", MANGLE(ShiftMask)) + V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%8") // Don't do any more averaging than needed for mmx. It hurts performance and causes rounding errors. #ifndef IS_MMX // pavgb mm4, mm6 // 1/4 center, 3/4 adjacent - V_PAVGB ("%%mm4", "%%mm6", "%%mm7", MANGLE(ShiftMask)) + V_PAVGB ("%%mm4", "%%mm6", "%%mm7", "%8") // pavgb mm6, mm4 // 3/8 center, 5/8 adjacent - V_PAVGB ("%%mm6", "%%mm4", "%%mm7", MANGLE(ShiftMask)) + V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%8") #endif // get abs value of possible L2 comb @@ -236,64 +235,71 @@ static void FUNCT_NAME(uint8_t *output, int outstride, // pminub mm5, mm3 // now = Min(L1,L3), use macro V_PMINUB ("%%mm5", "%%mm3", "%%mm7") // allow the value to be above the high or below the low by amt of MaxComb - "psubusb "MANGLE(MaxComb)", %%mm5\n\t" // lower min by diff - "paddusb "MANGLE(MaxComb)", %%mm2\n\t" // increase max by diff + "psubusb %9, %%mm5\n\t" // lower min by diff + "paddusb %9, %%mm2\n\t" // increase max by diff // pmaxub mm4, mm5 // now = Max(best,Min(L1,L3) use macro V_PMAXUB ("%%mm4", "%%mm5") // pminub mm4, mm2 // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped V_PMINUB ("%%mm4", "%%mm2", "%%mm7") // Blend weave pixel with bob pixel, depending on motion val in mm0 - "psubusb "MANGLE(MotionThreshold)", %%mm0\n\t"// test Threshold, clear chroma change >>>?? - "pmullw "MANGLE(MotionSense)", %%mm0\n\t" // mul by user factor, keep low 16 bits - "movq "MANGLE(QW256)", %%mm7\n\t" + "psubusb %10, %%mm0\n\t"// test Threshold, clear chroma change >>>?? + "pmullw %11, %%mm0\n\t" // mul by user factor, keep low 16 bits + "movq %12, %%mm7\n\t" #ifdef IS_SSE "pminsw %%mm7, %%mm0\n\t" // max = 256 #else - "paddusw "MANGLE(QW256B)", %%mm0\n\t" // add, may sat at fff.. - "psubusw "MANGLE(QW256B)", %%mm0\n\t" // now = Min(L1,256) + "paddusw %13, %%mm0\n\t" // add, may sat at fff.. + "psubusw %13, %%mm0\n\t" // now = Min(L1,256) #endif "psubusw %%mm0, %%mm7\n\t" // so the 2 sum to 256, weighted avg "movq %%mm4, %%mm2\n\t" // save weave chroma info before trashing - "pand "MANGLE(YMask)", %%mm4\n\t" // keep only luma from calc'd value + "pand %14, %%mm4\n\t" // keep only luma from calc'd value "pmullw %%mm7, %%mm4\n\t" // use more weave for less motion - "pand "MANGLE(YMask)", %%mm6\n\t" // keep only luma from calc'd value + "pand %14, %%mm6\n\t" // keep only luma from calc'd value "pmullw %%mm0, %%mm6\n\t" // use more bob for large motion "paddusw %%mm6, %%mm4\n\t" // combine "psrlw $8, %%mm4\n\t" // div by 256 to get weighted avg // chroma comes from weave pixel - "pand "MANGLE(UVMask)", %%mm2\n\t" // keep chroma + "pand %15, %%mm2\n\t" // keep chroma "por %%mm4, %%mm2\n\t" // and combine V_MOVNTQ ("(%%"XDI")", "%%mm2") // move in our clipped best, use macro // bump ptrs and loop LEAX" 8(%%"XAX"), %%"XAX"\n\t" - LEAX" 8(%%"XBX"), %%"XBX"\n\t" LEAX" 8(%%"XDX"), %%"XDX"\n\t" + ADDX" $8, "asmtemp"\n\t" LEAX" 8(%%"XDI"), %%"XDI"\n\t" LEAX" 8(%%"XSI"), %%"XSI"\n\t" DECX" "asmLoopCtr"\n\t" "jg 1b\n\t" // loop if not to last line // note P-III default assumes backward branches taken "jl 1f\n\t" // done - MOVX" %%"XAX", %%"XBX"\n\t" // sharpness lookahead 1 byte only, be wrong on 1 + MOVX" %%"XAX", %%"XDX"\n\t" // sharpness lookahead 1 byte only, be wrong on 1 "jmp 1b\n\t" "1:\n\t" - MOVX" "asmoldbx", %%"XBX"\n\t" : /* no outputs */ : "m"(LastAvg), "m"(L1), "m"(L3), - "m"(L2P), + "m"(temp), "m"(L2), "m"(Dest), "m"(LoopCtr), - "m"(oldbx) + "m"(temp), + "m"(ShiftMask), + "m"(MaxComb), + "m"(MotionThreshold), + "m"(MotionSense), + "m"(QW256), + "m"(QW256B), + "m"(YMask), + "m"(UVMask) : XAX, XCX, XDX, XSI, XDI, #ifdef ARCH_X86 diff --git a/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h index 3d7ae308e..a3b92a51c 100644 --- a/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h +++ b/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h @@ -1,8 +1,6 @@ #include <string.h> #include <math.h> -#ifdef HAVE_MALLOC_H -#include <malloc.h> -#endif +#include <stdlib.h> #define USE_FOR_DSCALER diff --git a/src/post/deinterlace/plugins/x86-64_macros.inc b/src/post/deinterlace/plugins/x86-64_macros.inc index 3dfd9b63a..b52227763 100644 --- a/src/post/deinterlace/plugins/x86-64_macros.inc +++ b/src/post/deinterlace/plugins/x86-64_macros.inc @@ -34,8 +34,7 @@ #ifndef XAX -#if defined (ARCH_X86) - +#if defined (ARCH_X86) && !defined (ARCH_X86_64) #define XAX "eax" #define XBX "ebx" #define XCX "ecx" @@ -55,7 +54,6 @@ #define SUBX "subl" #elif defined (ARCH_X86_64) - #define XAX "rax" #define XBX "rbx" #define XCX "rcx" diff --git a/src/video_out/vidix/.cvsignore b/src/post/goom/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/vidix/.cvsignore +++ b/src/post/goom/.hgignore diff --git a/src/post/goom/Makefile.am b/src/post/goom/Makefile.am index 5905c16cf..4aeda8f04 100644 --- a/src/post/goom/Makefile.am +++ b/src/post/goom/Makefile.am @@ -18,9 +18,8 @@ lib_LTLIBRARIES = xineplug_post_goom.la #AM_CPPFLAGS = -DCPU_POWERPC #endif -if HAVE_FFMMX +if HAVE_MMX extra_files = mmx.c xmmx.c -AM_CPPFLAGS = -DHAVE_MMX endif xineplug_post_goom_la_SOURCES = $(extra_files) xine_goom.c \ @@ -28,7 +27,7 @@ xineplug_post_goom_la_SOURCES = $(extra_files) xine_goom.c \ gfontlib.c goom_core.c goom_tools.c goomsl.c goomsl_hash.c goomsl_heap.c \ goomsl_lex.c goomsl_yacc.c graphic.c ifs.c lines.c \ plugin_info.c sound_tester.c surf3d.c tentacle3d.c v3d.c -xineplug_post_goom_la_LIBADD = $(XINE_LIB) $(GOOM_LIBS) $(THREAD_LIBS) +xineplug_post_goom_la_LIBADD = $(XINE_LIB) $(GOOM_LIBS) $(PTHREAD_LIBS) -lm xineplug_post_goom_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_post_goom_la_LDFLAGS = -avoid-version -module diff --git a/src/post/goom/mmx.c b/src/post/goom/mmx.c index 5f887cf77..e2f25b47d 100644 --- a/src/post/goom/mmx.c +++ b/src/post/goom/mmx.c @@ -1,3 +1,5 @@ +#include "config.h" + #ifdef HAVE_MMX #define BUFFPOINTNB 16 diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c index f879f1ebc..5871618e0 100644 --- a/src/post/goom/xine_goom.c +++ b/src/post/goom/xine_goom.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_goom.c,v 1.63 2006/10/23 21:13:44 hadess Exp $ + * $Id: xine_goom.c,v 1.65 2007/02/20 00:58:51 dgp85 Exp $ * * GOOM post plugin. * @@ -43,7 +43,7 @@ #include "goom.h" -#define NUMSAMPLES 512 +#define NUMSAMPLES 512 /* hardcoded into goom api */ #define FPS 14 #define GOOM_WIDTH 320 @@ -83,7 +83,7 @@ struct post_plugin_goom_s { PluginInfo *goom; int data_idx; - gint16 data [2][512]; + gint16 data [2][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; @@ -218,7 +218,7 @@ static void *goom_init_plugin(xine_t *xine, void *data) cfg->register_enum (cfg, "effects.goom.csc_method", 0, - (char **)goom_csc_methods, + goom_csc_methods, _("colorspace conversion method"), _("You can choose the colorspace conversion method used by goom.\n" "The available selections should be self-explaining."), @@ -386,6 +386,7 @@ 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; @@ -445,7 +446,6 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, buf = &this->buf; this->sample_counter += buf->num_frames; - j = (this->channels >= 2) ? 1 : 0; do { @@ -455,7 +455,7 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; 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; @@ -464,16 +464,15 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, data = buf->mem; data += samples_used * this->channels; - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; 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 && - this->data_idx == NUMSAMPLES ) { - this->data_idx = 0; + if( this->sample_counter >= this->samples_per_frame ) { + samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, this->width_back, this->height_back, @@ -481,14 +480,23 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - frame->bad_frame = 0; + + /* 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) { + if (!this->skip_frame && !frame->bad_frame) { /* Try to be fast */ goom_frame = (uint8_t *)goom_update (this->goom, this->data, 0, 0, NULL, NULL); diff --git a/src/post/goom/xmmx.c b/src/post/goom/xmmx.c index 7fc9acfc8..0048a20e8 100644 --- a/src/post/goom/xmmx.c +++ b/src/post/goom/xmmx.c @@ -1,3 +1,4 @@ +#include "config.h" #ifdef HAVE_MMX diff --git a/src/video_out/vidix/drivers/.cvsignore b/src/post/mosaico/.hgignore index 7d926a554..7d926a554 100644 --- a/src/video_out/vidix/drivers/.cvsignore +++ b/src/post/mosaico/.hgignore diff --git a/src/post/mosaico/Makefile.am b/src/post/mosaico/Makefile.am index aefb290c6..f5497b1af 100644 --- a/src/post/mosaico/Makefile.am +++ b/src/post/mosaico/Makefile.am @@ -5,11 +5,11 @@ libdir = $(XINE_PLUGINDIR)/post lib_LTLIBRARIES = xineplug_post_mosaico.la xineplug_post_switch.la xineplug_post_mosaico_la_SOURCES = mosaico.c -xineplug_post_mosaico_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_post_mosaico_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_post_mosaico_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_post_mosaico_la_LDFLAGS = -avoid-version -module xineplug_post_switch_la_SOURCES = switch.c -xineplug_post_switch_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_post_switch_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_post_switch_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_post_switch_la_LDFLAGS = -avoid-version -module diff --git a/src/xine-engine/.cvsignore b/src/post/planar/.hgignore index 7d926a554..7d926a554 100644 --- a/src/xine-engine/.cvsignore +++ b/src/post/planar/.hgignore diff --git a/src/post/planar/Makefile.am b/src/post/planar/Makefile.am index 9f8ffed45..cc0647808 100644 --- a/src/post/planar/Makefile.am +++ b/src/post/planar/Makefile.am @@ -23,7 +23,7 @@ lib_LTLIBRARIES = xineplug_post_planar.la xineplug_post_planar_la_SOURCES = planar.c invert.c expand.c fill.c boxblur.c \ denoise3d.c eq.c eq2.c unsharp.c pp.c noise.c -xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(postproc_lib) -lm $(THREAD_LIBS) +xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(postproc_lib) -lm $(PTHREAD_LIBS) xineplug_post_planar_la_LDFLAGS = -avoid-version -module \ @IMPURE_TEXT_LDFLAGS@ xineplug_post_planar_la_CFLAGS = $(VISIBILITY_FLAG) $(AM_CFLAGS) diff --git a/src/post/planar/eq.c b/src/post/planar/eq.c index 50fd03b7f..8c7b00e4b 100644 --- a/src/post/planar/eq.c +++ b/src/post/planar/eq.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: eq.c,v 1.14 2006/02/04 14:06:52 miguelfreitas Exp $ + * $Id: eq.c,v 1.15 2007/03/22 23:32:05 dgp85 Exp $ * * mplayer's eq (soft video equalizer) * Copyright (C) Richard Felker @@ -52,7 +52,7 @@ static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, in "movq (%6), %%mm4 \n\t" "pxor %%mm0, %%mm0 \n\t" "movl %4, %%eax\n\t" - ".balign 16 \n\t" + ASMALIGN(4) "1: \n\t" "movq (%0), %%mm1 \n\t" "movq (%0), %%mm2 \n\t" diff --git a/src/post/planar/eq2.c b/src/post/planar/eq2.c index 806a4ea6c..38f9117db 100644 --- a/src/post/planar/eq2.c +++ b/src/post/planar/eq2.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: eq2.c,v 1.16 2006/03/26 14:45:41 valtri Exp $ + * $Id: eq2.c,v 1.18 2007/03/22 23:32:05 dgp85 Exp $ * * mplayer's eq2 (soft video equalizer) * Software equalizer (brightness, contrast, gamma, saturation) @@ -128,7 +128,7 @@ void affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src, "movq (%6), %%mm4 \n\t" "pxor %%mm0, %%mm0 \n\t" "movl %4, %%eax\n\t" - ".balign 16 \n\t" + ASMALIGN(4) "1: \n\t" "movq (%0), %%mm1 \n\t" "movq (%0), %%mm2 \n\t" @@ -599,12 +599,12 @@ static int eq2_draw(vo_frame_t *frame, xine_stream_t *stream) pthread_mutex_lock (&this->lock); for (i = 0; i < 3; i++) { - int height; + int height, width; height = (i==0) ? frame->height : frame->height/2; - + width = (i==0) ? frame->width : frame->width/2; if (eq2->param[i].adjust != NULL) { eq2->param[i].adjust (&eq2->param[i], out_frame->base[i], yv12_frame->base[i], - frame->width, height, out_frame->pitches[i], yv12_frame->pitches[i]); + width, height, out_frame->pitches[i], yv12_frame->pitches[i]); } else { xine_fast_memcpy(out_frame->base[i],yv12_frame->base[i], diff --git a/src/post/planar/expand.c b/src/post/planar/expand.c index 51cc4eac2..cf288921f 100644 --- a/src/post/planar/expand.c +++ b/src/post/planar/expand.c @@ -21,7 +21,8 @@ * * expand video filter by James Stembridge 24/05/2003 * improved by Michael Roitzsch - * + * centre_crop_out_mode by Reinhard Nissl + * * based on invert.c * */ @@ -52,6 +53,11 @@ * This way, the decoder (or any other post plugin up the tree) will only * see the frame area between the black bars and by that modify the * enlarged version directly. No need for later copying. + * + * When centre_crop_out_mode is enabled, the plugin will detect the black + * bars to the left and right of the image and will then set up cropping + * to efficiently remove the black border around the 4:3 image, which the + * plugin would produce otherwise for this case. */ @@ -63,6 +69,7 @@ typedef struct expand_parameters_s { int enable_automatic_shift; int overlay_y_offset; double aspect; + int centre_cut_out_mode; } expand_parameters_t; START_PARAM_DESCR(expand_parameters_t) @@ -72,6 +79,8 @@ PARAM_ITEM(POST_PARAM_TYPE_INT, overlay_y_offset, NULL, -500, 500, 0, "manually shift the overlay vertically") PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, aspect, NULL, 1.0, 3.5, 0, "target aspect ratio") +PARAM_ITEM(POST_PARAM_TYPE_BOOL, centre_cut_out_mode, NULL, 0, 1, 0, + "cut out centred 4:3 image contained in 16:9 frame") END_PARAM_DESCR(expand_param_descr) typedef struct post_expand_s { @@ -83,6 +92,8 @@ typedef struct post_expand_s { int overlay_y_offset; double aspect; int top_bar_height; + int centre_cut_out_mode; + int cropping_active; } post_expand_t; /* plugin class functions */ @@ -106,6 +117,8 @@ static char *expand_get_help (void); static vo_frame_t *expand_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags); + +/* replaced vo_frame functions */ static int expand_draw(vo_frame_t *frame, xine_stream_t *stream); /* overlay manager intercept check */ @@ -153,6 +166,8 @@ static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs, this->enable_automatic_shift = 0; this->overlay_y_offset = 0; this->aspect = 4.0 / 3.0; + this->centre_cut_out_mode = 0; + this->cropping_active = 0; port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.get_frame = expand_get_frame; @@ -166,8 +181,8 @@ static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs, input_param->data = &post_api; xine_list_push_back(this->post.input, input_param); - input->xine_in.name = "video"; - output->xine_out.name = "expanded video"; + input->xine_in.name = "video"; + output->xine_out.name = "expanded video"; this->post.xine_post.video_input[0] = &port->new_port; @@ -214,6 +229,8 @@ static int expand_set_parameters(xine_post_t *this_gen, void *param_gen) this->enable_automatic_shift = param->enable_automatic_shift; this->overlay_y_offset = param->overlay_y_offset; this->aspect = param->aspect; + this->centre_cut_out_mode = param->centre_cut_out_mode; + return 1; } @@ -225,6 +242,8 @@ static int expand_get_parameters(xine_post_t *this_gen, void *param_gen) param->enable_automatic_shift = this->enable_automatic_shift; param->overlay_y_offset = this->overlay_y_offset; param->aspect = this->aspect; + param->centre_cut_out_mode = this->centre_cut_out_mode; + return 1; } @@ -238,22 +257,86 @@ static char *expand_get_help(void) { " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" + " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" ); } +static int is_pixel_black(vo_frame_t *frame, int x, int y) +{ + int Y = 0x00, Cr = 0x00, Cb = 0x00; + + if (x < 0) x = 0; + if (x >= frame->width) x = frame->width - 1; + if (y < 0) y = 0; + if (y >= frame->height) y = frame->height - 1; + + switch (frame->format) + { + case XINE_IMGFMT_YV12: + Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x); + Cr = *(frame->base[ 1 ] + frame->pitches[ 1 ] * y / 2 + x / 2); + Cb = *(frame->base[ 2 ] + frame->pitches[ 2 ] * y / 2 + x / 2); + break; + + case XINE_IMGFMT_YUY2: + Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 0); + x &= ~1; + Cr = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 1); + Cb = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 3); + break; + } + + return (Y == 0x10 && Cr == 0x80 && Cb == 0x80); +} + + static int expand_draw(vo_frame_t *frame, xine_stream_t *stream) { - post_video_port_t *port = (post_video_port_t *)frame->port; - post_expand_t *this = (post_expand_t *)port->post; - int skip; - - frame->ratio = this->aspect; - _x_post_frame_copy_down(frame, frame->next); - skip = frame->next->draw(frame->next, stream); - _x_post_frame_copy_up(frame, frame->next); - return skip; + post_video_port_t *port = (post_video_port_t *)frame->port; + post_expand_t *this = (post_expand_t *)port->post; + int skip; + + if (this->centre_cut_out_mode && !frame->bad_frame) + { + /* expected area of inner 4:3 image */ + int centre_width = frame->width * (9 * 4) / (16 * 3); + int centre_left = (frame->width - centre_width ) / 2; + + /* centre point for detecting a black frame */ + int centre_x = frame->width / 2; + int centre_y = frame->height / 2; + + /* ignore a black frame as it could lead to wrong results */ + if (!is_pixel_black(frame, centre_x, centre_y)) + { + /* coordinates for testing black border near the centre area */ + int test_left = centre_left - 16; + int test_right = centre_left + 16 + centre_width; + + /* enable cropping when these pixels are black */ + this->cropping_active = is_pixel_black(frame, test_left, centre_y) + && is_pixel_black(frame, test_right, centre_y); + } + + /* crop frame */ + if (this->centre_cut_out_mode && this->cropping_active) { + frame->crop_left += centre_left; + frame->crop_right += centre_left; + + /* get_frame() allocated an extra high frame */ + frame->crop_top += (frame->next->height - frame->height) / 2; + frame->crop_bottom += (frame->next->height - frame->height) / 2; + } + } + + frame->ratio = this->aspect; + _x_post_frame_copy_down(frame, frame->next); + skip = frame->next->draw(frame->next, stream); + _x_post_frame_copy_up(frame, frame->next); + + return skip; } @@ -338,6 +421,10 @@ static vo_frame_t *expand_get_frame(xine_video_port_t *port_gen, uint32_t width, static int expand_intercept_ovl(post_video_port_t *port) { + post_expand_t *this = (post_expand_t *)port->post; + + if (this->centre_cut_out_mode && this->cropping_active) return 0; + /* we always intercept overlay manager */ return 1; } diff --git a/src/post/planar/noise.c b/src/post/planar/noise.c index 1b46825db..154d5f8cc 100644 --- a/src/post/planar/noise.c +++ b/src/post/planar/noise.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: noise.c,v 1.3 2006/03/26 14:45:41 valtri Exp $ + * $Id: noise.c,v 1.4 2007/03/22 23:32:05 dgp85 Exp $ * * mplayer's noise filter, ported by Jason Tackaberry. Original filter * is copyright 2002 Michael Niedermayer <michaelni@gmx.at> @@ -159,7 +159,7 @@ static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int "pcmpeqb %%mm7, %%mm7 \n\t" "psllw $15, %%mm7 \n\t" "packsswb %%mm7, %%mm7 \n\t" - ".balign 16 \n\t" + ASMALIGN(4) "1: \n\t" "movq (%0, %%"REG_a"), %%mm0 \n\t" "movq (%1, %%"REG_a"), %%mm1 \n\t" @@ -186,7 +186,7 @@ static inline void lineNoise_MMX2(uint8_t *dst, uint8_t *src, int8_t *noise, int "pcmpeqb %%mm7, %%mm7 \n\t" "psllw $15, %%mm7 \n\t" "packsswb %%mm7, %%mm7 \n\t" - ".balign 16 \n\t" + ASMALIGN(4) "1: \n\t" "movq (%0, %%"REG_a"), %%mm0 \n\t" "movq (%1, %%"REG_a"), %%mm1 \n\t" @@ -225,7 +225,7 @@ static inline void lineNoiseAvg_MMX(uint8_t *dst, uint8_t *src, int len, int8_t asm volatile( "mov %5, %%"REG_a" \n\t" - ".balign 16 \n\t" + ASMALIGN(4) "1: \n\t" "movq (%1, %%"REG_a"), %%mm1 \n\t" "movq (%0, %%"REG_a"), %%mm0 \n\t" diff --git a/src/xine-utils/.cvsignore b/src/post/visualizations/.hgignore index 7d926a554..7d926a554 100644 --- a/src/xine-utils/.cvsignore +++ b/src/post/visualizations/.hgignore diff --git a/src/post/visualizations/Makefile.am b/src/post/visualizations/Makefile.am index 8891b1c53..dc7679103 100644 --- a/src/post/visualizations/Makefile.am +++ b/src/post/visualizations/Makefile.am @@ -8,7 +8,7 @@ lib_LTLIBRARIES = xineplug_post_visualizations.la xineplug_post_visualizations_la_SOURCES = \ visualizations.c fft.c fftscope.c oscope.c fftgraph.c -xineplug_post_visualizations_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) -lm +xineplug_post_visualizations_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) -lm xineplug_post_visualizations_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_post_visualizations_la_LDFLAGS = -avoid-version -module diff --git a/src/post/visualizations/fftgraph.c b/src/post/visualizations/fftgraph.c index f9f8f0d4a..669a4bc94 100644 --- a/src/post/visualizations/fftgraph.c +++ b/src/post/visualizations/fftgraph.c @@ -20,7 +20,7 @@ * FftGraph Visualization Post Plugin For xine * by Thibaut Mattern (tmattern@noos.fr) * - * $Id: fftgraph.c,v 1.14 2006/01/27 07:46:14 tmattern Exp $ + * $Id: fftgraph.c,v 1.15 2006/12/02 22:35:18 miguelfreitas Exp $ * */ @@ -230,6 +230,7 @@ static int fftgraph_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream this->lines_per_channel = FFTGRAPH_HEIGHT / this->channels; this->samples_per_frame = rate / FPS; this->data_idx = 0; + this->sample_counter = 0; this->vo_port->open(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); @@ -342,7 +343,7 @@ static void fftgraph_port_put_buffer (xine_audio_port_t *port_gen, data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)(data8[c] << 8) - 0x8000; @@ -353,7 +354,7 @@ static void fftgraph_port_put_buffer (xine_audio_port_t *port_gen, data = buf->mem; data += samples_used * this->channels; - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)data[c]; @@ -362,17 +363,24 @@ static void fftgraph_port_put_buffer (xine_audio_port_t *port_gen, } } - if( this->sample_counter >= this->samples_per_frame && - this->data_idx == NUMSAMPLES ) { + if( this->sample_counter >= this->samples_per_frame ) { - this->data_idx = 0; samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FFTGRAPH_WIDTH, FFTGRAPH_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - frame->bad_frame = 0; + + /* 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 / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); diff --git a/src/post/visualizations/fftscope.c b/src/post/visualizations/fftscope.c index 8448f3a65..aef517c59 100644 --- a/src/post/visualizations/fftscope.c +++ b/src/post/visualizations/fftscope.c @@ -22,7 +22,7 @@ * * FFT code by Steve Haehnichen, originally licensed under GPL v1 * - * $Id: fftscope.c,v 1.29 2006/01/27 07:46:14 tmattern Exp $ + * $Id: fftscope.c,v 1.30 2006/12/02 22:35:18 miguelfreitas Exp $ * */ @@ -289,6 +289,7 @@ static int fftscope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream this->channels = MAXCHANNELS; this->samples_per_frame = rate / FPS; this->data_idx = 0; + this->sample_counter = 0; this->fft = fft_new(FFT_BITS); this->vo_port->open(this->vo_port, XINE_ANON_STREAM); @@ -363,7 +364,7 @@ static void fftscope_port_put_buffer (xine_audio_port_t *port_gen, data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)(data8[c] << 8) - 0x8000; @@ -374,7 +375,7 @@ static void fftscope_port_put_buffer (xine_audio_port_t *port_gen, data = buf->mem; data += samples_used * this->channels; - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)data[c]; @@ -383,17 +384,24 @@ static void fftscope_port_put_buffer (xine_audio_port_t *port_gen, } } - if( this->sample_counter >= this->samples_per_frame && - this->data_idx == NUMSAMPLES ) { + if( this->sample_counter >= this->samples_per_frame ) { - this->data_idx = 0; samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FFT_WIDTH, FFT_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - frame->bad_frame = 0; + + /* 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 / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); diff --git a/src/post/visualizations/fooviz.c b/src/post/visualizations/fooviz.c index 8d1e84150..9e69fefab 100644 --- a/src/post/visualizations/fooviz.c +++ b/src/post/visualizations/fooviz.c @@ -23,7 +23,7 @@ * process. It simply paints the screen a solid color and rotates through * colors on each iteration. * - * $Id: fooviz.c,v 1.27 2006/07/10 22:08:44 dgp85 Exp $ + * $Id: fooviz.c,v 1.28 2006/12/02 22:35:18 miguelfreitas Exp $ * */ @@ -118,6 +118,7 @@ static int fooviz_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, this->channels = _x_ao_mode2channels(mode); this->samples_per_frame = rate / FPS; this->data_idx = 0; + this->sample_counter = 0; this->vo_port->open(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); @@ -180,7 +181,7 @@ static void fooviz_port_put_buffer (xine_audio_port_t *port_gen, data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; 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; @@ -189,24 +190,31 @@ static void fooviz_port_put_buffer (xine_audio_port_t *port_gen, data = buf->mem; data += samples_used * this->channels; - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; 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 && - this->data_idx == NUMSAMPLES ) { + if( this->sample_counter >= this->samples_per_frame ) { - this->data_idx = 0; samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FOO_WIDTH, FOO_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - frame->bad_frame = 0; + + /* 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 / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); diff --git a/src/post/visualizations/oscope.c b/src/post/visualizations/oscope.c index 68ae0e054..483fc39ab 100644 --- a/src/post/visualizations/oscope.c +++ b/src/post/visualizations/oscope.c @@ -20,7 +20,7 @@ * Basic Oscilloscope Visualization Post Plugin For xine * by Mike Melanson (melanson@pcisys.net) * - * $Id: oscope.c,v 1.20 2006/01/27 07:46:14 tmattern Exp $ + * $Id: oscope.c,v 1.21 2006/12/02 22:35:18 miguelfreitas Exp $ * */ @@ -191,6 +191,7 @@ static int oscope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, this->channels = MAXCHANNELS; this->samples_per_frame = rate / FPS; this->data_idx = 0; + this->sample_counter = 0; init_yuv_planes(&this->yuv, OSCOPE_WIDTH, OSCOPE_HEIGHT); this->vo_port->open(this->vo_port, XINE_ANON_STREAM); @@ -252,7 +253,7 @@ static void oscope_port_put_buffer (xine_audio_port_t *port_gen, data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) for( c = 0; c < this->channels; c++) this->data[c][this->data_idx] = ((int16_t)data8[c] << 8) - 0x8000; @@ -260,23 +261,30 @@ static void oscope_port_put_buffer (xine_audio_port_t *port_gen, data = buf->mem; data += samples_used * this->channels; - for( i = 0; i < buf->num_frames && this->data_idx < NUMSAMPLES; + for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) for( c = 0; c < this->channels; c++) this->data[c][this->data_idx] = data[c]; } - if( this->sample_counter >= this->samples_per_frame && - this->data_idx == NUMSAMPLES ) { + if( this->sample_counter >= this->samples_per_frame ) { - this->data_idx = 0; samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, OSCOPE_WIDTH, OSCOPE_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - frame->bad_frame = 0; + + /* 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 / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); diff --git a/src/video_out/.hgignore b/src/video_out/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index 2121c009d..34971377c 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -1,6 +1,7 @@ include $(top_srcdir)/misc/Makefile.common AM_CPPFLAGS = -DXINE_COMPILE +AM_LDFLAGS = $(xineplug_ldflags) SUBDIRS = libdha vidix macosx @@ -9,8 +10,6 @@ EXTRA_DIST = video_out_directfb.c video_out_directx.c video_out_macosx.m VIDIX_CFLAGS = -I$(top_builddir)/src/video_out/vidix \ -I$(top_srcdir)/src/video_out/vidix -libdir = $(XINE_PLUGINDIR) - if HAVE_X11 X11OSD = x11osd.c xshm_module = xineplug_vo_out_xshm.la @@ -37,6 +36,16 @@ endif endif endif +if HAVE_XCB +XCBOSD = xcbosd.c +if HAVE_XCBSHM +xcbshm_module = xineplug_vo_out_xcbshm.la +endif +if HAVE_XCBXV +xcbxv_module = xineplug_vo_out_xcbxv.la +endif +endif + if HAVE_VIDIX vidix_module = xineplug_vo_out_vidix.la endif @@ -73,7 +82,7 @@ if HAVE_MACOSX_VIDEO macosx_module = xineplug_vo_out_macosx.la endif -lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \ +xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \ $(opengl_module) \ $(syncfb_module) \ $(pgx64_module) $(pgx32_module)\ @@ -86,111 +95,103 @@ lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \ $(caca_module) \ $(macosx_module) \ $(xxmc_module) \ + $(xcbshm_module) \ + $(xcbxv_module) \ xineplug_vo_out_none.la +xineplug_vo_out_xcbshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_xcbshm.c $(XCBOSD) +xineplug_vo_out_xcbshm_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(XCB_LIBS) $(XCBSHM_LIBS) +xineplug_vo_out_xcbshm_la_CFLAGS = $(VISIBILITY_FLAG) $(MLIB_CFLAGS) $(XCB_CFLAGS) $(XCBSHM_CFLAGS) + +xineplug_vo_out_xcbxv_la_SOURCES = deinterlace.c video_out_xcbxv.c $(XCBOSD) +xineplug_vo_out_xcbxv_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(XCBXV_LIBS) $(XCB_LIBS) +xineplug_vo_out_xcbxv_la_CFLAGS = $(VISIBILITY_FLAG) $(XCB_CFLAGS) $(XCBXV_CFLAGS) + xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ video_out_xshm.c $(X11OSD) -xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_xshm_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(MLIB_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module xineplug_vo_out_xv_la_SOURCES = $(X11OSD) deinterlace.c video_out_xv.c -xineplug_vo_out_xv_la_LIBADD = $(XV_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS) -xineplug_vo_out_xv_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_xv_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_xv_la_LIBADD = $(XV_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) +xineplug_vo_out_xv_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing xineplug_vo_out_xvmc_la_SOURCES = deinterlace.c video_out_xvmc.c -xineplug_vo_out_xvmc_la_LIBADD = $(XVMC_LIBS) $(XV_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS) -xineplug_vo_out_xvmc_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) -xineplug_vo_out_xvmc_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_xvmc_la_LIBADD = $(XVMC_LIBS) $(XV_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) +xineplug_vo_out_xvmc_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(XV_CFLAGS) xineplug_vo_out_xxmc_la_SOURCES = $(X11OSD) deinterlace.c video_out_xxmc.c\ xvmc_mocomp.c xvmc_vld.c xxmc.h -xineplug_vo_out_xxmc_la_LIBADD = $(XXMC_LIBS) $(XV_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS) -xineplug_vo_out_xxmc_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_xxmc_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_xxmc_la_LIBADD = $(XXMC_LIBS) $(XV_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) +xineplug_vo_out_xxmc_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing xineplug_vo_out_opengl_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ video_out_opengl.c myglext.h $(X11OSD) xineplug_vo_out_opengl_la_LIBADD = $(MLIB_LIBS) $(OPENGL_LIBS) $(GLUT_LIBS) \ - $(GLU_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS) + $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) xineplug_vo_out_opengl_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(MLIB_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_opengl_la_LDFLAGS = -avoid-version -module xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c -xineplug_vo_out_syncfb_la_LIBADD = $(X_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_syncfb_la_LIBADD = $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_syncfb_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_vo_out_syncfb_la_LDFLAGS = -avoid-version -module xineplug_vo_out_pgx64_la_SOURCES = video_out_pgx64.c -xineplug_vo_out_pgx64_la_LIBADD = $(X_LIBS) $(SUNDGA_LIBS) $(THREAD_LIBS) -xineplug_vo_out_pgx64_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_vo_out_pgx64_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_pgx64_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(SUNDGA_LIBS) $(PTHREAD_LIBS) +xineplug_vo_out_pgx64_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) xineplug_vo_out_pgx32_la_SOURCES = video_out_pgx32.c -xineplug_vo_out_pgx32_la_LIBADD = $(X_LIBS) $(SUNDGA_LIBS) $(THREAD_LIBS) -xineplug_vo_out_pgx32_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_vo_out_pgx32_la_LDFLAGS = -avoid-version -module +xineplug_vo_out_pgx32_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(SUNDGA_LIBS) $(PTHREAD_LIBS) +xineplug_vo_out_pgx32_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) xineplug_vo_out_vidix_la_SOURCES = video_out_vidix.c $(X11OSD) -xineplug_vo_out_vidix_la_LIBADD = $(X_LIBS) \ - $(top_builddir)/src/video_out/vidix/libvidix.la \ - $(top_builddir)/src/video_out/libdha/libdha.la $(THREAD_LIBS) +xineplug_vo_out_vidix_la_LIBADD = $(XINE_LIB) $(X_LIBS) \ + $(top_builddir)/src/video_out/vidix/libvidix.la $(PTHREAD_LIBS) xineplug_vo_out_vidix_la_CFLAGS = $(VISIBILITY_FLAG) $(VIDIX_CFLAGS) $(X_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_vidix_la_LDFLAGS = -avoid-version -module xineplug_vo_out_aa_la_SOURCES = video_out_aa.c -xineplug_vo_out_aa_la_LIBADD = $(AALIB_LIBS) $(THREAD_LIBS) +xineplug_vo_out_aa_la_LIBADD = $(AALIB_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_aa_la_CFLAGS = $(VISIBILITY_FLAG) $(AALIB_CFLAGS) -xineplug_vo_out_aa_la_LDFLAGS = -avoid-version -module xineplug_vo_out_caca_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ video_out_caca.c -xineplug_vo_out_caca_la_LIBADD = $(CACA_LIBS) $(THREAD_LIBS) +xineplug_vo_out_caca_la_LIBADD = $(CACA_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_caca_la_CFLAGS = $(VISIBILITY_FLAG) $(CACA_CFLAGS) -xineplug_vo_out_caca_la_LDFLAGS = -avoid-version -module xineplug_vo_out_fb_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \ video_out_fb.c -xineplug_vo_out_fb_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_fb_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_fb_la_CFLAGS = $(VISIBILITY_FLAG) $(MLIB_CFLAGS) -xineplug_vo_out_fb_la_LDFLAGS = -avoid-version -module xineplug_vo_out_directfb_la_SOURCES = video_out_directfb.c $(X11OSD) -xineplug_vo_out_directfb_la_LIBADD = $(DIRECTFB_LIBS) $(X_LIBS) $(THREAD_LIBS) +xineplug_vo_out_directfb_la_LIBADD = $(XINE_LIB) $(DIRECTFB_LIBS) $(X_LIBS) $(PTHREAD_LIBS) xineplug_vo_out_directfb_la_CFLAGS = $(VISIBILITY_FLAG) $(DIRECTFB_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_directfb_la_LDFLAGS = -avoid-version -module xineplug_vo_out_sdl_la_SOURCES = video_out_sdl.c -xineplug_vo_out_sdl_la_LIBADD = $(SDL_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_sdl_la_LIBADD = $(SDL_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_sdl_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(SDL_CFLAGS) -xineplug_vo_out_sdl_la_LDFLAGS = -avoid-version -module xineplug_vo_out_stk_la_SOURCES = video_out_stk.c -xineplug_vo_out_stk_la_LIBADD = $(LIBSTK_LIBS) $(THREAD_LIBS) +xineplug_vo_out_stk_la_LIBADD = $(XINE_LIB) $(LIBSTK_LIBS) $(PTHREAD_LIBS) xineplug_vo_out_stk_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBSTK_CFLAGS) -xineplug_vo_out_stk_la_LDFLAGS = -avoid-version -module xineplug_vo_out_directx_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_directx.c -xineplug_vo_out_directx_la_CPPFLAGS = $(DIRECTX_CPPFLAGS) -xineplug_vo_out_directx_la_LIBADD = $(DIRECTX_VIDEO_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS) +xineplug_vo_out_directx_la_LIBADD = $(DIRECTX_VIDEO_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_directx_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_vo_out_directx_la_LDFLAGS = -avoid-version -module xineplug_vo_out_none_la_SOURCES = video_out_none.c -xineplug_vo_out_none_la_LIBADD = $(XINE_LIB) $(THREAD_LIBS) +xineplug_vo_out_none_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_none_la_CFLAGS = $(VISIBILITY_FLAG) -xineplug_vo_out_none_la_LDFLAGS = -avoid-version -module xineplug_vo_out_macosx_la_SOURCES = video_out_macosx.m -xineplug_vo_out_macosx_la_CPPFLAGS = $(X_CFLAGS) $(MLIB_CFLAGS) -xineplug_vo_out_macosx_la_CFLAGS = $(VISIBILITY_FLAG) +xineplug_vo_out_macosx_la_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) $(MLIB_CFLAGS) +xineplug_vo_out_macosx_la_OBJCFLAGS = $(VISIBILITY_FLAG) xineplug_vo_out_macosx_la_LIBADD = $(MLIB_LIBS) $(OPENGL_LIBS) $(GLUT_LIBS) \ - $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(THREAD_LIBS) + $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) # The "-Wl,-framework -Wl,Cocoa" is needed for libtool versions before # 1.5.x (1.257): the default version that ships with Mac OS X is 1.5 (1.1220) -xineplug_vo_out_macosx_la_LDFLAGS = -avoid-version -module \ +xineplug_vo_out_macosx_la_LDFLAGS = $(AM_LDFLAGS) \ -Wl,-framework -Wl,Cocoa -framework Cocoa -framework OpenGL noinst_HEADERS = deinterlace.h video_out_syncfb.h \ - yuv2rgb.h x11osd.h + yuv2rgb.h x11osd.h xcbosd.h diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c index 347185b2f..1fda3d733 100644 --- a/src/video_out/deinterlace.c +++ b/src/video_out/deinterlace.c @@ -845,15 +845,3 @@ int deinterlace_yuv_supported ( int method ) return 0; } -char *deinterlace_methods[] = { - "none", - "bob", - "weave", - "greedy", - "onefield", - "onefield_xv", - "linearblend", - NULL -}; - - diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h index e4a1329c3..a9904b42a 100644 --- a/src/video_out/deinterlace.h +++ b/src/video_out/deinterlace.h @@ -41,6 +41,15 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[], #define DEINTERLACE_ONEFIELDXV 5 #define DEINTERLACE_LINEARBLEND 6 -extern char *deinterlace_methods[]; +static const char *deinterlace_methods[] = { + "none", + "bob", + "weave", + "greedy", + "onefield", + "onefield_xv", + "linearblend", + NULL +}; #endif diff --git a/src/video_out/libdha/.cvsignore b/src/video_out/libdha/.hgignore index ac32e12c7..ac32e12c7 100644 --- a/src/video_out/libdha/.cvsignore +++ b/src/video_out/libdha/.hgignore diff --git a/src/video_out/libdha/bin/.hgignore b/src/video_out/libdha/bin/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/libdha/bin/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/libdha/kernelhelper/.hgignore b/src/video_out/libdha/kernelhelper/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/libdha/kernelhelper/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/libdha/oth/.hgignore b/src/video_out/libdha/oth/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/libdha/oth/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/libdha/sysdep/.hgignore b/src/video_out/libdha/sysdep/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/libdha/sysdep/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/macosx/.hgignore b/src/video_out/macosx/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/macosx/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/macosx/Makefile.am b/src/video_out/macosx/Makefile.am index 76968ceab..a69f30dc5 100644 --- a/src/video_out/macosx/Makefile.am +++ b/src/video_out/macosx/Makefile.am @@ -1,5 +1,7 @@ include $(top_srcdir)/misc/Makefile.common +AM_CPPFLAGS = -DXINE_COMPILE + EXTRA_DIST = \ video_window.h \ XineOpenGLView.m \ @@ -18,9 +20,8 @@ libxineMacOSXVideo_la_LDFLAGS = -version-info \ $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) \ -Wl,-framework -Wl,Cocoa -framework Cocoa \ -Wl,-framework -Wl,OpenGL -framework OpenGL -libxine_MacOSXVideo_la_OBJCFLAGS = $(OBJCFLAGS) -include_HEADERS = video_window.h XineOpenGLView.h XineVideoWindow.h +xineinclude_HEADERS = video_window.h XineOpenGLView.h XineVideoWindow.h endif diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c index 960bcdbf4..a51940952 100644 --- a/src/video_out/video_out_directfb.c +++ b/src/video_out/video_out_directfb.c @@ -1444,7 +1444,14 @@ static void init_subpicture (directfb_driver_t *this) { config.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS; config.pixelformat = DSPF_ARGB; config.options = DLOP_ALPHACHANNEL; + ret = this->underlay->SetConfiguration (this->underlay, &config); + if (ret) { + /* try AiRGB if the previous failed */ + config.pixelformat = DSPF_AiRGB; + ret = this->underlay->SetConfiguration (this->underlay, &config); + } + if (ret == DFB_OK) { this->underlay->AddRef (this->underlay); this->spic_layer = this->underlay; diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index 808092a03..e88def112 100644 --- a/src/video_out/video_out_fb.c +++ b/src/video_out/video_out_fb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_fb.c,v 1.48 2006/07/10 22:08:44 dgp85 Exp $ + * $Id: video_out_fb.c,v 1.49 2006/12/19 19:10:51 dsalt Exp $ * * video_out_fb.c, frame buffer xine driver by Miguel Freitas * @@ -848,7 +848,7 @@ static int open_fb_device(config_values_t *config, xine_t *xine) /* This config entry is security critical, is it really necessary * or is a number enough? */ - device_name = config->register_string(config, devkey, "", + device_name = config->register_filename(config, devkey, "", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("framebuffer device name"), _("Specifies the file name for the framebuffer device " "to be used.\nThis setting is security critical, " diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c index 9760105c2..f03d0ea97 100644 --- a/src/video_out/video_out_syncfb.c +++ b/src/video_out/video_out_syncfb.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_syncfb.c,v 1.107 2006/09/02 01:10:46 dgp85 Exp $ + * $Id: video_out_syncfb.c,v 1.108 2006/12/19 19:10:51 dsalt Exp $ * * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine * @@ -1073,7 +1073,8 @@ static void *init_class (xine_t *xine, void *visual_gen) { char* device_name; int fd; - device_name = xine->config->register_string(xine->config, "video.device.syncfb_device", "/dev/syncfb", + device_name = xine->config->register_filename(xine->config, "video.device.syncfb_device", "/dev/syncfb", + XINE_CONFIG_STRING_IS_DEVICE_NAME, _("SyncFB device name"), _("Specifies the file name for the SyncFB (TeleTux) device " "to be used.\nThis setting is security critical, " diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c index 188b5271a..b90a162ca 100644 --- a/src/video_out/video_out_vidix.c +++ b/src/video_out/video_out_vidix.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_vidix.c,v 1.74 2006/07/10 22:08:44 dgp85 Exp $ + * $Id: video_out_vidix.c,v 1.75 2006/12/19 19:10:51 dsalt Exp $ * * video_out_vidix.c * @@ -1235,7 +1235,7 @@ static vo_driver_t *vidixfb_open_plugin (video_driver_class_t *class_gen, const this->visual_type = XINE_VISUAL_TYPE_FB; /* Register config option for fb device */ - device = config->register_string(config, "video.device.vidixfb_device", "/dev/fb0", + device = config->register_filename(config, "video.device.vidixfb_device", "/dev/fb0", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("framebuffer device name"), _("Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, xine " diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c new file mode 100644 index 000000000..5b4eb1fa3 --- /dev/null +++ b/src/video_out/video_out_xcbshm.c @@ -0,0 +1,1279 @@ +/* + * Copyright (C) 2000-2003, 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: video_out_xcbshm.c,v 1.3 2007/03/25 23:13:53 dgp85 Exp $ + * + * video_out_xcbshm.c, X11 shared memory extension interface for xine + * + * based on mpeg2dec code from + * Aaron Holtzman <aholtzma@ess.engr.uvic.ca> + * + * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de> + * + * ported to xcb by Christoph Pfister - Feb 2007 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "xine.h" +#include "video_out.h" + +#include <errno.h> + +#include <xcb/shm.h> + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/time.h> + +#include <pthread.h> +#include <netinet/in.h> + +#define LOG_MODULE "video_out_xcbshm" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include "xine_internal.h" +#include "yuv2rgb.h" +#include "xineutils.h" +#include "vo_scale.h" +#include "xcbosd.h" + +typedef struct { + vo_frame_t vo_frame; + + /* frame properties as delivered by the decoder: */ + /* obs: for width/height use vo_scale_t struct */ + int format; + int flags; + + vo_scale_t sc; + + uint8_t *image; + int bytes_per_line; + xcb_shm_seg_t shmseg; + + uint8_t *chunk[3]; /* mem alloc by xmalloc_aligned */ + + yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ + uint8_t *rgb_dst; + +} xshm_frame_t; + +typedef struct { + + vo_driver_t vo_driver; + + /* xcb / shm related stuff */ + xcb_connection_t *connection; + xcb_screen_t *screen; + xcb_window_t window; + xcb_gcontext_t gc; + int depth; + int bpp; + int scanline_pad; + int use_shm; + + int yuv2rgb_brightness; + int yuv2rgb_contrast; + int yuv2rgb_saturation; + uint8_t *yuv2rgb_cmap; + yuv2rgb_factory_t *yuv2rgb_factory; + + vo_scale_t sc; + + xshm_frame_t *cur_frame; + xcbosd *xoverlay; + int ovl_changed; + + xine_t *xine; + + alphablend_t alphablend_extra_data; + + pthread_mutex_t main_mutex; + +} xshm_driver_t; + +typedef struct { + video_driver_class_t driver_class; + + config_values_t *config; + xine_t *xine; +} xshm_class_t; + + +/* + * allocate an XImage, try XShm first but fall back to + * plain X11 if XShm should fail + */ +static void create_ximage(xshm_driver_t *this, xshm_frame_t *frame, int width, int height) +{ + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + frame->bytes_per_line = ((this->bpp * width + this->scanline_pad - 1) & + (~(this->scanline_pad - 1))) >> 3; + + if (this->use_shm) { + int shmid; + xcb_void_cookie_t shm_attach_cookie; + xcb_generic_error_t *generic_error; + + /* + * try shm + */ + + shmid = shmget(IPC_PRIVATE, frame->bytes_per_line * height, IPC_CREAT | 0777); + + if (shmid < 0) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbshm: %s: allocating image\n" + "video_out_xcbshm: => not using MIT Shared Memory extension.\n"), strerror(errno)); + goto shm_fail1; + } + + frame->image = shmat(shmid, 0, 0); + + if (frame->image == ((void *) -1)) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbshm: shared memory error (address error) when allocating image \n" + "video_out_xcbshm: => not using MIT Shared Memory extension.\n")); + goto shm_fail2; + } + + frame->shmseg = xcb_generate_id(this->connection); + shm_attach_cookie = xcb_shm_attach_checked(this->connection, frame->shmseg, shmid, 0); + generic_error = xcb_request_check(this->connection, shm_attach_cookie); + + if (generic_error != NULL) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbshm: x11 error during shared memory XImage creation\n" + "video_out_xcbshm: => not using MIT Shared Memory extension.\n")); + free(generic_error); + goto shm_fail3; + } + + /* + * Now that the Xserver has learned about and attached to the + * shared memory segment, delete it. It's actually deleted by + * the kernel when all users of that segment have detached from + * it. Gives an automatic shared memory cleanup in case we crash. + */ + + shmctl(shmid, IPC_RMID, 0); + + return; + + shm_fail3: + frame->shmseg = 0; + shmdt(frame->image); + shm_fail2: + shmctl(shmid, IPC_RMID, 0); + shm_fail1: + this->use_shm = 0; + } + + /* + * fall back to plain X11 if necessary + */ + + frame->image = malloc(frame->bytes_per_line * height); +} + +static void dispose_ximage(xshm_driver_t *this, xshm_frame_t *frame) +{ + if (frame->shmseg) { + xcb_shm_detach(this->connection, frame->shmseg); + frame->shmseg = 0; + shmdt(frame->image); + } else + free(frame->image); + frame->image = NULL; +} + + +/* + * and now, the driver functions + */ + +static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2; + + if( this->xoverlay ) + capabilities |= VO_CAP_UNSCALED_OVERLAY; + + return capabilities; +} + +static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { + xshm_frame_t *frame = (xshm_frame_t *) vo_img ; + /*xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; */ + + vo_img->proc_called = 1; + + if( frame->vo_frame.crop_left || frame->vo_frame.crop_top || + frame->vo_frame.crop_right || frame->vo_frame.crop_bottom ) + { + /* we don't support crop, so don't even waste cpu cycles. + * cropping will be performed by video_out.c + */ + return; + } + + lprintf ("copy... (format %d)\n", frame->format); + + if (frame->format == XINE_IMGFMT_YV12) + frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, + src[0], src[1], src[2]); + else + frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, + src[0]); + + lprintf ("copy...done\n"); +} + +static void xshm_frame_field (vo_frame_t *vo_img, int which_field) { + xshm_frame_t *frame = (xshm_frame_t *) vo_img ; + /* xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; */ + + switch (which_field) { + case VO_TOP_FIELD: + frame->rgb_dst = frame->image; + break; + case VO_BOTTOM_FIELD: + frame->rgb_dst = frame->image + frame->bytes_per_line; + break; + case VO_BOTH_FIELDS: + frame->rgb_dst = frame->image; + break; + } + + frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); +} + +static void xshm_frame_dispose (vo_frame_t *vo_img) { + xshm_frame_t *frame = (xshm_frame_t *) vo_img ; + xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; + + if (frame->image) { + pthread_mutex_lock(&this->main_mutex); + dispose_ximage(this, frame); + pthread_mutex_unlock(&this->main_mutex); + } + + frame->yuv2rgb->dispose (frame->yuv2rgb); + + free (frame->chunk[0]); + free (frame->chunk[1]); + free (frame->chunk[2]); + free (frame); +} + + +static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) { + xshm_frame_t *frame; + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + frame = (xshm_frame_t *) xine_xmalloc (sizeof (xshm_frame_t)); + if (!frame) + return NULL; + + memcpy (&frame->sc, &this->sc, sizeof(vo_scale_t)); + + pthread_mutex_init (&frame->vo_frame.mutex, NULL); + + /* + * supply required functions/fields + */ + + frame->vo_frame.proc_slice = xshm_frame_proc_slice; + frame->vo_frame.proc_frame = NULL; + frame->vo_frame.field = xshm_frame_field; + frame->vo_frame.dispose = xshm_frame_dispose; + frame->vo_frame.driver = this_gen; + + /* + * colorspace converter for this frame + */ + + frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); + + return (vo_frame_t *) frame; +} + +static void xshm_compute_ideal_size (xshm_driver_t *this, xshm_frame_t *frame) { + _x_vo_scale_compute_ideal_size( &frame->sc ); +} + +static void xshm_compute_rgb_size (xshm_driver_t *this, xshm_frame_t *frame) { + _x_vo_scale_compute_output_size( &frame->sc ); + + /* avoid problems in yuv2rgb */ + if (frame->sc.output_height < 1) + frame->sc.output_height = 1; + if (frame->sc.output_width < 8) + frame->sc.output_width = 8; + if (frame->sc.output_width & 1) /* yuv2rgb_mlib needs an even YUV2 width */ + frame->sc.output_width++; + + lprintf("frame source (%d) %d x %d => screen output %d x %d%s\n", + frame->vo_frame.id, + frame->sc.delivered_width, frame->sc.delivered_height, + frame->sc.output_width, frame->sc.output_height, + ( frame->sc.delivered_width != frame->sc.output_width + || frame->sc.delivered_height != frame->sc.output_height + ? ", software scaling" + : "" ) + ); +} + +static void xshm_update_frame_format (vo_driver_t *this_gen, + vo_frame_t *frame_gen, + uint32_t width, uint32_t height, + double ratio, int format, int flags) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + xshm_frame_t *frame = (xshm_frame_t *) frame_gen; + int do_adapt; + int gui_width; + int gui_height; + double gui_pixel_aspect; + + flags &= VO_BOTH_FIELDS; + + /* ask gui what output size we'll have for this frame */ + /* get the gui_pixel_aspect before calling xshm_compute_ideal_size() */ + /* note: gui_width and gui_height may be bogus because we may have not yet*/ + /* updated video_pixel_aspect (see _x_vo_scale_compute_ideal_size). */ + frame->sc.dest_size_cb (frame->sc.user_data, width, height, + frame->sc.video_pixel_aspect, + &gui_width, &gui_height, + &gui_pixel_aspect); + + /* find out if we need to adapt this frame */ + do_adapt = 0; + + if ((width != frame->sc.delivered_width) + || (height != frame->sc.delivered_height) + || (ratio != frame->sc.delivered_ratio) + || (flags != frame->flags) + || (format != frame->format) + || (gui_pixel_aspect != frame->sc.gui_pixel_aspect) + || (this->sc.user_ratio != frame->sc.user_ratio)) { + + do_adapt = 1; + + lprintf ("frame format (from decoder) has changed => adapt\n"); + + frame->sc.delivered_width = width; + frame->sc.delivered_height = height; + frame->sc.delivered_ratio = ratio; + frame->sc.gui_pixel_aspect = gui_pixel_aspect; + frame->flags = flags; + frame->format = format; + frame->sc.user_ratio = this->sc.user_ratio; + + xshm_compute_ideal_size (this, frame); + + /* now we have updated video_aspect_pixel we use the callback */ + /* again to obtain the correct gui_width and gui_height values. */ + frame->sc.dest_size_cb (frame->sc.user_data, width, height, + frame->sc.video_pixel_aspect, + &gui_width, &gui_height, + &gui_pixel_aspect); + } + + if ((frame->sc.gui_width != gui_width) || + (frame->sc.gui_height != gui_height) || + do_adapt) { + + do_adapt = 1; + frame->sc.gui_width = gui_width; + frame->sc.gui_height = gui_height; + + xshm_compute_rgb_size (this, frame); + + lprintf ("gui_size has changed => adapt\n"); + } + + + /* ok, now do what we have to do */ + + if (do_adapt) { + + lprintf ("updating frame to %d x %d\n", + frame->sc.output_width, frame->sc.output_height); + + pthread_mutex_lock(&this->main_mutex); + + /* + * (re-) allocate XImage + */ + + if (frame->image) { + + dispose_ximage(this, frame); + + if (frame->chunk[0]){ + free (frame->chunk[0]); + frame->chunk[0] = NULL; + } + if (frame->chunk[1]) { + free (frame->chunk[1]); + frame->chunk[1] = NULL; + } + if (frame->chunk[2]) { + free (frame->chunk[2]); + frame->chunk[2] = NULL; + } + } + + create_ximage(this, frame, frame->sc.output_width, frame->sc.output_height); + + pthread_mutex_unlock(&this->main_mutex); + + if (format == XINE_IMGFMT_YV12) { + frame->vo_frame.pitches[0] = 8*((width + 7) / 8); + frame->vo_frame.pitches[1] = 8*((width + 15) / 16); + frame->vo_frame.pitches[2] = 8*((width + 15) / 16); + frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]); + frame->vo_frame.base[1] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[1] * ((height+1)/2), (void **) &frame->chunk[1]); + frame->vo_frame.base[2] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[2] * ((height+1)/2), (void **) &frame->chunk[2]); + } else { + frame->vo_frame.pitches[0] = 8*((width + 3) / 4); + frame->vo_frame.base[0] = xine_xmalloc_aligned (16, frame->vo_frame.pitches[0] * height, (void **) &frame->chunk[0]); + frame->chunk[1] = NULL; + frame->chunk[2] = NULL; + } + + lprintf ("stripe out_ht=%i, deliv_ht=%i\n", + frame->sc.output_height, frame->sc.delivered_height); + + /* + * set up colorspace converter + */ + + switch (flags) { + case VO_TOP_FIELD: + case VO_BOTTOM_FIELD: + frame->yuv2rgb->configure (frame->yuv2rgb, + frame->sc.delivered_width, + frame->sc.delivered_height, + 2*frame->vo_frame.pitches[0], + 2*frame->vo_frame.pitches[1], + frame->sc.output_width, + frame->sc.output_height, + frame->bytes_per_line*2); + break; + case VO_BOTH_FIELDS: + frame->yuv2rgb->configure (frame->yuv2rgb, + frame->sc.delivered_width, + frame->sc.delivered_height, + frame->vo_frame.pitches[0], + frame->vo_frame.pitches[1], + frame->sc.output_width, + frame->sc.output_height, + frame->bytes_per_line); + break; + } + } + + xshm_frame_field ((vo_frame_t *)frame, flags); +} + +static void xshm_overlay_clut_yuv2rgb(xshm_driver_t *this, vo_overlay_t *overlay, + xshm_frame_t *frame) { + size_t i; + clut_t* clut = (clut_t*) overlay->color; + + if (!overlay->rgb_clut) { + for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) { + *((uint32_t *)&clut[i]) = + frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, + clut[i].y, clut[i].cb, clut[i].cr); + } + overlay->rgb_clut++; + } + if (!overlay->hili_rgb_clut) { + clut = (clut_t*) overlay->hili_color; + for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) { + *((uint32_t *)&clut[i]) = + frame->yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb, + clut[i].y, clut[i].cb, clut[i].cr); + } + overlay->hili_rgb_clut++; + } +} + +static void xshm_overlay_begin (vo_driver_t *this_gen, + vo_frame_t *frame_gen, int changed) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + this->ovl_changed += changed; + + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_clear(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; + this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; +} + +static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_expose(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + this->ovl_changed = 0; +} + +static void xshm_overlay_blend (vo_driver_t *this_gen, + vo_frame_t *frame_gen, vo_overlay_t *overlay) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + xshm_frame_t *frame = (xshm_frame_t *) frame_gen; + + /* Alpha Blend here */ + if (overlay->rle) { + if( overlay->unscaled ) { + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_blend(this->xoverlay, overlay); + pthread_mutex_unlock(&this->main_mutex); + } + } else { + if (!overlay->rgb_clut || !overlay->hili_rgb_clut) + xshm_overlay_clut_yuv2rgb (this, overlay, frame); + + switch (this->bpp) { + case 16: + _x_blend_rgb16(frame->image, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); + break; + case 24: + _x_blend_rgb24(frame->image, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); + break; + case 32: + _x_blend_rgb32(frame->image, overlay, + frame->sc.output_width, frame->sc.output_height, + frame->sc.delivered_width, frame->sc.delivered_height, + &this->alphablend_extra_data); + break; + default: + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "xine-lib:video_out_xcbshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp); + /* it should never get here, unless a user tries to play in bpp:8 */ + break; + } + } + } +} + +static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) { + int i; + xcb_rectangle_t rects[4]; + int rects_count = 0; + + memcpy( this->sc.border, frame->sc.border, sizeof(this->sc.border) ); + + pthread_mutex_lock(&this->main_mutex); + + for( i = 0; i < 4; i++ ) { + if( this->sc.border[i].w && this->sc.border[i].h ) + rects[rects_count].x = this->sc.border[i].x; + rects[rects_count].y = this->sc.border[i].y; + rects[rects_count].width = this->sc.border[i].w; + rects[rects_count].height = this->sc.border[i].h; + rects_count++; + } + + if (rects_count > 0) + xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); + + if (this->xoverlay) { + xcbosd_resize(this->xoverlay, this->sc.gui_width, this->sc.gui_height); + this->ovl_changed = 1; + } + + pthread_mutex_unlock(&this->main_mutex); +} + +static int xshm_redraw_needed (vo_driver_t *this_gen) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + int ret = 0; + + if( this->cur_frame ) { + this->sc.delivered_height = this->cur_frame->sc.delivered_height; + this->sc.delivered_width = this->cur_frame->sc.delivered_width; + this->sc.video_pixel_aspect = this->cur_frame->sc.video_pixel_aspect; + if( _x_vo_scale_redraw_needed( &this->sc ) ) { + + clean_output_area (this, this->cur_frame); + ret = 1; + } + } + else + ret = 1; + + return ret; +} + +static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + xshm_frame_t *frame = (xshm_frame_t *) frame_gen; + + lprintf ("display frame...\n"); + lprintf ("about to draw frame (%d) %d x %d...\n", + frame->vo_frame.id, + frame->sc.output_width, frame->sc.output_height); + + /* + * tell gui that we are about to display a frame, + * ask for offset + */ + + this->sc.delivered_height = frame->sc.delivered_height; + this->sc.delivered_width = frame->sc.delivered_width; + this->sc.video_pixel_aspect = frame->sc.video_pixel_aspect; + if( _x_vo_scale_redraw_needed( &this->sc ) ) { + + clean_output_area (this, frame); + } + + if (this->cur_frame) { + + if ( (this->cur_frame->sc.output_width != frame->sc.output_width) + || (this->cur_frame->sc.output_height != frame->sc.output_height) + || (this->cur_frame->sc.output_xoffset != frame->sc.output_xoffset) + || (this->cur_frame->sc.output_yoffset != frame->sc.output_yoffset) ) + clean_output_area (this, frame); + + this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); + } + + this->cur_frame = frame; + + pthread_mutex_lock(&this->main_mutex); + lprintf ("display locked...\n"); + + if (frame->shmseg) { + + lprintf ("put image (shm)\n"); + xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width, + this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width, + this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset, + this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, + 0, this->cur_frame->shmseg, 0); + + } else { + + lprintf ("put image (plain/remote)\n"); + xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc, + frame->sc.output_width, frame->sc.output_height, frame->sc.output_xoffset, frame->sc.output_yoffset, + 0, this->depth, frame->bytes_per_line * frame->sc.output_height, frame->image); + + } + xcb_flush(this->connection); + pthread_mutex_unlock(&this->main_mutex); + + lprintf ("display frame done\n"); +} + +static int xshm_get_property (vo_driver_t *this_gen, int property) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + switch (property) { + case VO_PROP_ASPECT_RATIO: + return this->sc.user_ratio; + case VO_PROP_MAX_NUM_FRAMES: + return 15; + case VO_PROP_BRIGHTNESS: + return this->yuv2rgb_brightness; + case VO_PROP_CONTRAST: + return this->yuv2rgb_contrast; + case VO_PROP_SATURATION: + return this->yuv2rgb_saturation; + case VO_PROP_WINDOW_WIDTH: + return this->sc.gui_width; + case VO_PROP_WINDOW_HEIGHT: + return this->sc.gui_height; + default: + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbshm: tried to get unsupported property %d\n", property); + } + + return 0; +} + +static int xshm_set_property (vo_driver_t *this_gen, + int property, int value) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + if ( property == VO_PROP_ASPECT_RATIO) { + + if (value>=XINE_VO_ASPECT_NUM_RATIOS) + value = XINE_VO_ASPECT_AUTO; + this->sc.user_ratio = value; + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbshm: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name(value)); + + } else if (property == VO_PROP_BRIGHTNESS) { + + this->yuv2rgb_brightness = value; + this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, + this->yuv2rgb_brightness, + this->yuv2rgb_contrast, + this->yuv2rgb_saturation); + + this->sc.force_redraw = 1; + + } else if (property == VO_PROP_CONTRAST) { + + this->yuv2rgb_contrast = value; + this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, + this->yuv2rgb_brightness, + this->yuv2rgb_contrast, + this->yuv2rgb_saturation); + + this->sc.force_redraw = 1; + + } else if (property == VO_PROP_SATURATION) { + + this->yuv2rgb_saturation = value; + this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, + this->yuv2rgb_brightness, + this->yuv2rgb_contrast, + this->yuv2rgb_saturation); + + this->sc.force_redraw = 1; + + } else { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbshm: tried to set unsupported property %d\n", property); + } + + return value; +} + +static void xshm_get_property_min_max (vo_driver_t *this_gen, + int property, int *min, int *max) { + /* xshm_driver_t *this = (xshm_driver_t *) this_gen; */ + + if (property == VO_PROP_BRIGHTNESS) { + *min = -128; + *max = +127; + } else if (property == VO_PROP_CONTRAST) { + *min = 0; + *max = 255; + } else if (property == VO_PROP_SATURATION) { + *min = 0; + *max = 255; + } else { + *min = 0; + *max = 0; + } +} + +static int xshm_gui_data_exchange (vo_driver_t *this_gen, + int data_type, void *data) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + switch (data_type) { +#ifndef XINE_DISABLE_DEPRECATED_FEATURES + case XINE_GUI_SEND_COMPLETION_EVENT: + break; +#endif + + case XINE_GUI_SEND_EXPOSE_EVENT: + + lprintf ("expose event\n"); + + if (this->cur_frame) { + xcb_expose_event_t *xev = (xcb_expose_event_t *) data; + + if (xev && xev->count == 0) { + int i; + xcb_rectangle_t rects[4]; + int rects_count = 0; + + pthread_mutex_lock(&this->main_mutex); + if (this->cur_frame->shmseg) + xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width, + this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width, + this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset, + this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, + 0, this->cur_frame->shmseg, 0); + else + xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc, + this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, + this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, + 0, this->depth, this->cur_frame->bytes_per_line * this->cur_frame->sc.output_height, + this->cur_frame->image); + + for( i = 0; i < 4; i++ ) { + if( this->sc.border[i].w && this->sc.border[i].h ) + rects[rects_count].x = this->sc.border[i].x; + rects[rects_count].y = this->sc.border[i].y; + rects[rects_count].width = this->sc.border[i].w; + rects[rects_count].height = this->sc.border[i].h; + rects_count++; + } + + if (rects_count > 0) + xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); + + if(this->xoverlay) + xcbosd_expose(this->xoverlay); + + xcb_flush(this->connection); + pthread_mutex_unlock(&this->main_mutex); + } + } + break; + + case XINE_GUI_SEND_DRAWABLE_CHANGED: + this->window = (xcb_window_t) data; + + pthread_mutex_lock(&this->main_mutex); + xcb_free_gc(this->connection, this->gc); + this->gc = xcb_generate_id(this->connection); + xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel); + if(this->xoverlay) + xcbosd_drawable_changed(this->xoverlay, this->window); + this->ovl_changed = 1; + pthread_mutex_unlock(&this->main_mutex); + break; + + case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: + + if (this->cur_frame) { + x11_rectangle_t *rect = data; + int x1, y1, x2, y2; + + _x_vo_scale_translate_gui2video(&this->cur_frame->sc, + rect->x, rect->y, + &x1, &y1); + _x_vo_scale_translate_gui2video(&this->cur_frame->sc, + rect->x + rect->w, rect->y + rect->h, + &x2, &y2); + rect->x = x1; + rect->y = y1; + rect->w = x2-x1; + rect->h = y2-y1; + } + break; + + default: + return -1; + } + + return 0; +} + +static void xshm_dispose (vo_driver_t *this_gen) { + xshm_driver_t *this = (xshm_driver_t *) this_gen; + + if (this->cur_frame) + this->cur_frame->vo_frame.dispose (&this->cur_frame->vo_frame); + + this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); + + pthread_mutex_lock(&this->main_mutex); + xcb_free_gc(this->connection, this->gc); + pthread_mutex_unlock(&this->main_mutex); + + if( this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_destroy(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + pthread_mutex_destroy(&this->main_mutex); + + _x_alphablend_free(&this->alphablend_extra_data); + + free (this); +} + +static int ImlibPaletteLUTGet(xshm_driver_t *this) { + static const xcb_atom_t CARDINAL = 6; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + xcb_get_property_cookie_t prop_cookie; + xcb_get_property_reply_t *prop_reply; + + atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("_IMLIB_COLORMAP"), "_IMLIB_COLORMAP"); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + + if (atom_reply == NULL) + return 0; + + prop_cookie = xcb_get_property(this->connection, 0, this->window, atom_reply->atom, CARDINAL, 0, 0x7fffffff); + prop_reply = xcb_get_property_reply(this->connection, prop_cookie, NULL); + + free(atom_reply); + + if (prop_reply == NULL) + return 0; + + if (prop_reply->format == 8) { + unsigned int i; + unsigned long j; + int num_ret = xcb_get_property_value_length(prop_reply); + char *retval = xcb_get_property_value(prop_reply); + + j = 1 + retval[0]*4; + this->yuv2rgb_cmap = malloc(sizeof(uint8_t) * 32 * 32 * 32); + for (i = 0; i < 32 * 32 * 32 && j < num_ret; i++) + this->yuv2rgb_cmap[i] = retval[1+4*retval[j++]+3]; + + free(prop_reply); + return 1; + } + + free(prop_reply); + return 0; +} + + +static char *visual_class_name(xcb_visualtype_t *visual) { + + switch (visual->_class) { + case XCB_VISUAL_CLASS_STATIC_GRAY: + return "StaticGray"; + case XCB_VISUAL_CLASS_GRAY_SCALE: + return "GrayScale"; + case XCB_VISUAL_CLASS_STATIC_COLOR: + return "StaticColor"; + case XCB_VISUAL_CLASS_PSEUDO_COLOR: + return "PseudoColor"; + case XCB_VISUAL_CLASS_TRUE_COLOR: + return "TrueColor"; + case XCB_VISUAL_CLASS_DIRECT_COLOR: + return "DirectColor"; + default: + return "unknown visual class"; + } +} + +static vo_driver_t *xshm_open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { + xshm_class_t *class = (xshm_class_t *) class_gen; + config_values_t *config = class->config; + xcb_visual_t *visual = (xcb_visual_t *) visual_gen; + xshm_driver_t *this; + xcb_visualtype_t *visualtype; + int mode; + int swapped; + int cpu_byte_order; + int image_byte_order; + + xcb_get_window_attributes_cookie_t window_attrs_cookie; + xcb_get_window_attributes_reply_t *window_attrs_reply; + + xcb_get_geometry_cookie_t geometry_cookie; + xcb_get_geometry_reply_t *geometry_reply; + + const xcb_query_extension_reply_t *query_extension_reply; + + this = (xshm_driver_t *) xine_xmalloc (sizeof (xshm_driver_t)); + + if (!this) + return NULL; + + pthread_mutex_init(&this->main_mutex, NULL); + + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + + this->connection = visual->connection; + this->screen = visual->screen; + this->window = visual->window; + + _x_vo_scale_init( &this->sc, 0, 0, config ); + this->sc.frame_output_cb = visual->frame_output_cb; + this->sc.dest_size_cb = visual->dest_size_cb; + this->sc.user_data = visual->user_data; + + this->sc.user_ratio = XINE_VO_ASPECT_AUTO; + + this->cur_frame = NULL; + this->gc = xcb_generate_id(this->connection); + xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel); + this->xoverlay = NULL; + this->ovl_changed = 0; + + this->xine = class->xine; + + this->vo_driver.get_capabilities = xshm_get_capabilities; + this->vo_driver.alloc_frame = xshm_alloc_frame; + this->vo_driver.update_frame_format = xshm_update_frame_format; + this->vo_driver.overlay_begin = xshm_overlay_begin; + this->vo_driver.overlay_blend = xshm_overlay_blend; + this->vo_driver.overlay_end = xshm_overlay_end; + this->vo_driver.display_frame = xshm_display_frame; + this->vo_driver.get_property = xshm_get_property; + this->vo_driver.set_property = xshm_set_property; + this->vo_driver.get_property_min_max = xshm_get_property_min_max; + this->vo_driver.gui_data_exchange = xshm_gui_data_exchange; + this->vo_driver.dispose = xshm_dispose; + this->vo_driver.redraw_needed = xshm_redraw_needed; + + /* + * + * depth in X11 terminology land is the number of bits used to + * actually represent the colour. + * + * bpp in X11 land means how many bits in the frame buffer per + * pixel. + * + * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit + * color is 24 bit depth, but can be 24 bpp or 32 bpp. + */ + + window_attrs_cookie = xcb_get_window_attributes(this->connection, this->window); + geometry_cookie = xcb_get_geometry(this->connection, this->window); + xcb_prefetch_extension_data(this->connection, &xcb_shm_id); + + window_attrs_reply = xcb_get_window_attributes_reply(this->connection, window_attrs_cookie, NULL); + + visualtype = NULL; + { + xcb_depth_t *depth = xcb_screen_allowed_depths_iterator(this->screen).data; + xcb_visualtype_t *vis = xcb_depth_visuals(depth); + xcb_visualtype_t *vis_end = vis + xcb_depth_visuals_length(depth); + + for (; vis != vis_end; ++vis) + if (window_attrs_reply->visual == vis->visual_id) { + visualtype = vis; + break; + } + } + + free(window_attrs_reply); + + geometry_reply = xcb_get_geometry_reply(this->connection, geometry_cookie, NULL); + + this->depth = geometry_reply->depth; + + free(geometry_reply); + + if (this->depth>16) + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("\n\nWARNING: current display depth is %d. For better performance\n" + "a depth of 16 bpp is recommended!\n\n"), this->depth); + + /* + * check for X shared memory support + */ + + query_extension_reply = xcb_get_extension_data(this->connection, &xcb_shm_id); + if (query_extension_reply && query_extension_reply->present) { + this->use_shm = 1; + } + else { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbshm: MIT shared memory extension not present on display.\n")); + this->use_shm = 0; + } + + { + const xcb_setup_t *setup = xcb_get_setup(this->connection); + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmt_end = fmt + xcb_setup_pixmap_formats_length(setup); + + for (; fmt != fmt_end; ++fmt) + if(fmt->depth == this->depth) { + this->bpp = fmt->bits_per_pixel; + this->scanline_pad = fmt->scanline_pad; + break; + } + + if (fmt == fmt_end) { + if (this->depth <= 4) + this->bpp = 4; + else if (this->depth <= 8) + this->bpp = 8; + else if (this->depth <= 16) + this->bpp = 16; + else + this->bpp = 32; + this->scanline_pad = setup->bitmap_format_scanline_pad; + } + + image_byte_order = setup->image_byte_order; + } + + /* + * Is the same byte order in use on the X11 client and server? + */ + cpu_byte_order = htonl(1) == 1 ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST; + swapped = cpu_byte_order != image_byte_order; + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbshm: video mode depth is %d (%d bpp), %s, %sswapped,\n" + "\tred: %08x, green: %08x, blue: %08x\n", + this->depth, this->bpp, + visual_class_name(visualtype), + swapped ? "" : "not ", + visualtype->red_mask, visualtype->green_mask, visualtype->blue_mask); + + mode = 0; + + switch (visualtype->_class) { + case XCB_VISUAL_CLASS_TRUE_COLOR: + switch (this->depth) { + case 24: + case 32: + if (this->bpp == 32) { + if (visualtype->red_mask == 0x00ff0000) + mode = MODE_32_RGB; + else + mode = MODE_32_BGR; + } else { + if (visualtype->red_mask == 0x00ff0000) + mode = MODE_24_RGB; + else + mode = MODE_24_BGR; + } + break; + case 16: + if (visualtype->red_mask == 0xf800) + mode = MODE_16_RGB; + else + mode = MODE_16_BGR; + break; + case 15: + if (visualtype->red_mask == 0x7C00) + mode = MODE_15_RGB; + else + mode = MODE_15_BGR; + break; + case 8: + if (visualtype->red_mask == 0xE0) + mode = MODE_8_RGB; /* Solaris x86: RGB332 */ + else + mode = MODE_8_BGR; /* XFree86: BGR233 */ + break; + } + break; + + case XCB_VISUAL_CLASS_STATIC_GRAY: + if (this->depth == 8) + mode = MODE_8_GRAY; + break; + + case XCB_VISUAL_CLASS_PSEUDO_COLOR: + case XCB_VISUAL_CLASS_GRAY_SCALE: + if (this->depth <= 8 && ImlibPaletteLUTGet(this)) + mode = MODE_PALETTE; + break; + } + + if (!mode) { + xprintf (this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbshm: your video mode was not recognized, sorry :-(\n")); + return NULL; + } + + this->yuv2rgb_brightness = 0; + this->yuv2rgb_contrast = 128; + this->yuv2rgb_saturation = 128; + + this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped, + this->yuv2rgb_cmap); + this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, + this->yuv2rgb_brightness, + this->yuv2rgb_contrast, + this->yuv2rgb_saturation); + + this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, + this->window, XCBOSD_SHAPED); + + return &this->vo_driver; +} + +/* + * class functions + */ + +static char* xshm_get_identifier (video_driver_class_t *this_gen) { + return "XShm"; +} + +static char* xshm_get_description (video_driver_class_t *this_gen) { + return _("xine video output plugin using the MIT X shared memory extension"); +} + +static void xshm_dispose_class (video_driver_class_t *this_gen) { + xshm_class_t *this = (xshm_class_t *) this_gen; + + free (this); +} + +static void *xshm_init_class (xine_t *xine, void *visual_gen) { + xshm_class_t *this = (xshm_class_t *) xine_xmalloc (sizeof (xshm_class_t)); + + this->driver_class.open_plugin = xshm_open_plugin; + this->driver_class.get_identifier = xshm_get_identifier; + this->driver_class.get_description = xshm_get_description; + this->driver_class.dispose = xshm_dispose_class; + this->config = xine->config; + this->xine = xine; + + return this; +} + + +static const vo_info_t vo_info_xshm = { + 6, /* priority */ + XINE_VISUAL_TYPE_XCB /* visual type */ +}; + + +/* + * exported plugin catalog entry + */ + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_OUT, 21, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c new file mode 100644 index 000000000..db4be14fa --- /dev/null +++ b/src/video_out/video_out_xcbxv.c @@ -0,0 +1,1622 @@ +/* + * Copyright (C) 2000-2004, 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: video_out_xcbxv.c,v 1.6 2007/03/29 18:58:21 dgp85 Exp $ + * + * video_out_xcbxv.c, X11 video extension interface for xine + * + * based on mpeg2dec code from + * Aaron Holtzman <aholtzma@ess.engr.uvic.ca> + * + * Xv image support by Gerd Knorr <kraxel@goldbach.in-berlin.de> + * + * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de> + * + * overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001 + * X11 unscaled overlay support by Miguel Freitas - Nov 2003 + * ported to xcb by Christoph Pfister - Feb 2007 + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_XV + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include <sys/types.h> +#if defined(__FreeBSD__) +#include <machine/param.h> +#endif +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/time.h> + +#include <xcb/xv.h> + +#define LOG_MODULE "video_out_xcbxv" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include "xine.h" +#include "video_out.h" +#include "xine_internal.h" +/* #include "overlay.h" */ +#include "deinterlace.h" +#include "xineutils.h" +#include "vo_scale.h" +#include "xcbosd.h" + +typedef struct xv_driver_s xv_driver_t; + +typedef struct { + int value; + int min; + int max; + xcb_atom_t atom; + + cfg_entry_t *entry; + + xv_driver_t *this; +} xv_property_t; + +typedef struct { + char *name; + int value; +} xv_portattribute_t; + +typedef struct { + vo_frame_t vo_frame; + + int width, height, format; + double ratio; + + uint8_t *image; + xcb_shm_seg_t shmseg; + unsigned int xv_format; + unsigned int xv_data_size; + unsigned int xv_width; + unsigned int xv_height; + unsigned int xv_pitches[3]; + unsigned int xv_offsets[3]; + +} xv_frame_t; + + +struct xv_driver_s { + + vo_driver_t vo_driver; + + config_values_t *config; + + /* xcb / xv related stuff */ + xcb_connection_t *connection; + xcb_screen_t *screen; + xcb_window_t window; + unsigned int xv_format_yv12; + unsigned int xv_format_yuy2; + xcb_gc_t gc; + xcb_xv_port_t xv_port; + + int use_shm; + int use_pitch_alignment; + uint32_t capabilities; + xv_property_t props[VO_NUM_PROPERTIES]; + + xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; + xv_frame_t *cur_frame; + xcbosd *xoverlay; + int ovl_changed; + + /* all scaling information goes here */ + vo_scale_t sc; + + xv_frame_t deinterlace_frame; + int deinterlace_method; + int deinterlace_enabled; + + int use_colorkey; + uint32_t colorkey; + + /* hold initial port attributes values to restore on exit */ + xine_list_t *port_attributes; + + xine_t *xine; + + alphablend_t alphablend_extra_data; + + pthread_mutex_t main_mutex; + +}; + +typedef struct { + video_driver_class_t driver_class; + + config_values_t *config; + xine_t *xine; +} xv_class_t; + +static uint32_t xv_get_capabilities (vo_driver_t *this_gen) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + return this->capabilities; +} + +static void xv_frame_field (vo_frame_t *vo_img, int which_field) { + /* not needed for Xv */ +} + +static void xv_frame_dispose (vo_frame_t *vo_img) { + xv_frame_t *frame = (xv_frame_t *) vo_img ; + xv_driver_t *this = (xv_driver_t *) vo_img->driver; + + if (frame->shmseg) { + pthread_mutex_lock(&this->main_mutex); + xcb_shm_detach(this->connection, frame->shmseg); + frame->shmseg = 0; + pthread_mutex_unlock(&this->main_mutex); + shmdt(frame->image); + } + else + free(frame->image); + + free (frame); +} + +static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) { + /* xv_driver_t *this = (xv_driver_t *) this_gen; */ + xv_frame_t *frame ; + + frame = (xv_frame_t *) xine_xmalloc (sizeof (xv_frame_t)); + if (!frame) + return NULL; + + pthread_mutex_init (&frame->vo_frame.mutex, NULL); + + /* + * supply required functions + */ + frame->vo_frame.proc_slice = NULL; + frame->vo_frame.proc_frame = NULL; + frame->vo_frame.field = xv_frame_field; + frame->vo_frame.dispose = xv_frame_dispose; + frame->vo_frame.driver = this_gen; + + return (vo_frame_t *) frame; +} + +static void create_ximage(xv_driver_t *this, xv_frame_t *frame, int width, int height, int format) +{ + xcb_xv_query_image_attributes_cookie_t query_attributes_cookie; + xcb_xv_query_image_attributes_reply_t *query_attributes_reply; + + unsigned int length; + + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + + if (this->use_pitch_alignment) { + width = (width + 7) & ~0x7; + } + + switch (format) { + case XINE_IMGFMT_YV12: + frame->xv_format = this->xv_format_yv12; + break; + case XINE_IMGFMT_YUY2: + frame->xv_format = this->xv_format_yuy2; + break; + default: + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); + _x_abort(); + } + + query_attributes_cookie = xcb_xv_query_image_attributes(this->connection, this->xv_port, frame->xv_format, width, height); + query_attributes_reply = xcb_xv_query_image_attributes_reply(this->connection, query_attributes_cookie, NULL); + + if (query_attributes_reply == NULL) + return; + + frame->xv_data_size = query_attributes_reply->data_size; + frame->xv_width = query_attributes_reply->width; + frame->xv_height = query_attributes_reply->height; + + length = xcb_xv_query_image_attributes_pitches_length(query_attributes_reply); + if (length > 3) + length = 3; + memcpy(frame->xv_pitches, xcb_xv_query_image_attributes_pitches(query_attributes_reply), length * sizeof(frame->xv_pitches[0])); + + length = xcb_xv_query_image_attributes_offsets_length(query_attributes_reply); + if (length > 3) + length = 3; + memcpy(frame->xv_offsets, xcb_xv_query_image_attributes_offsets(query_attributes_reply), length * sizeof(frame->xv_offsets[0])); + + free(query_attributes_reply); + + if (this->use_shm) { + int shmid; + xcb_void_cookie_t shm_attach_cookie; + xcb_generic_error_t *generic_error; + + /* + * try shm + */ + + if (frame->xv_data_size == 0) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: XvShmCreateImage returned a zero size\n" + "video_out_xcbxv: => not using MIT Shared Memory extension.\n")); + goto shm_fail1; + } + + shmid = shmget(IPC_PRIVATE, frame->xv_data_size, IPC_CREAT | 0777); + + if (shmid < 0 ) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: shared memory error in shmget: %s\n" + "video_out_xcbxv: => not using MIT Shared Memory extension.\n"), strerror(errno)); + goto shm_fail1; + } + + frame->image = shmat(shmid, 0, 0); + + if (frame->image == ((void *) -1)) { + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbxv: shared memory error (address error)\n"); + goto shm_fail2; + } + + frame->shmseg = xcb_generate_id(this->connection); + shm_attach_cookie = xcb_shm_attach_checked(this->connection, frame->shmseg, shmid, 0); + generic_error = xcb_request_check(this->connection, shm_attach_cookie); + + if (generic_error != NULL) { + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: x11 error during shared memory XImage creation\n" + "video_out_xcbxv: => not using MIT Shared Memory extension.\n")); + free(generic_error); + goto shm_fail3; + } + + /* + * Now that the Xserver has learned about and attached to the + * shared memory segment, delete it. It's actually deleted by + * the kernel when all users of that segment have detached from + * it. Gives an automatic shared memory cleanup in case we crash. + */ + + shmctl(shmid, IPC_RMID, 0); + + return; + + shm_fail3: + frame->shmseg = 0; + shmdt(frame->image); + shm_fail2: + shmctl(shmid, IPC_RMID, 0); + shm_fail1: + this->use_shm = 0; + } + + /* + * fall back to plain Xv if necessary + */ + + switch (format) { + case XINE_IMGFMT_YV12: + frame->image = malloc(width * height * 3/2); + break; + case XINE_IMGFMT_YUY2: + frame->image = malloc(width * height * 2); + break; + default: + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); + _x_abort(); + } +} + +static void dispose_ximage(xv_driver_t *this, xv_frame_t *frame) +{ + if (frame->shmseg) { + xcb_shm_detach(this->connection, frame->shmseg); + frame->shmseg = 0; + shmdt(frame->image); + } else + free(frame->image); + frame->image = NULL; +} + +static void xv_update_frame_format (vo_driver_t *this_gen, + vo_frame_t *frame_gen, + uint32_t width, uint32_t height, + double ratio, int format, int flags) { + xv_driver_t *this = (xv_driver_t *) this_gen; + xv_frame_t *frame = (xv_frame_t *) frame_gen; + + if (this->use_pitch_alignment) { + width = (width + 7) & ~0x7; + } + + if ((frame->width != width) + || (frame->height != height) + || (frame->format != format)) { + + /* printf ("video_out_xcbxv: updating frame to %d x %d (ratio=%d, format=%08x)\n",width,height,ratio_code,format); */ + + pthread_mutex_lock(&this->main_mutex); + + /* + * (re-) allocate xvimage + */ + + if (frame->image) + dispose_ximage(this, frame); + + create_ximage(this, frame, width, height, format); + + if(format == XINE_IMGFMT_YUY2) { + frame->vo_frame.pitches[0] = frame->xv_pitches[0]; + frame->vo_frame.base[0] = frame->image + frame->xv_offsets[0]; + } + else { + frame->vo_frame.pitches[0] = frame->xv_pitches[0]; + frame->vo_frame.pitches[1] = frame->xv_pitches[2]; + frame->vo_frame.pitches[2] = frame->xv_pitches[1]; + frame->vo_frame.base[0] = frame->image + frame->xv_offsets[0]; + frame->vo_frame.base[1] = frame->image + frame->xv_offsets[2]; + frame->vo_frame.base[2] = frame->image + frame->xv_offsets[1]; + } + + frame->width = width; + frame->height = height; + frame->format = format; + + pthread_mutex_unlock(&this->main_mutex); + } + + frame->ratio = ratio; +} + +#define DEINTERLACE_CROMA +static void xv_deinterlace_frame (xv_driver_t *this) { + uint8_t *recent_bitmaps[VO_NUM_RECENT_FRAMES]; + xv_frame_t *frame = this->recent_frames[0]; + int i; + int xvscaling; + + xvscaling = (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) ? 2 : 1; + + if (!this->deinterlace_frame.image + || (frame->width != this->deinterlace_frame.width) + || (frame->height != this->deinterlace_frame.height ) + || (frame->format != this->deinterlace_frame.format) + || (frame->ratio != this->deinterlace_frame.ratio)) { + pthread_mutex_lock(&this->main_mutex); + + if(this->deinterlace_frame.image) + dispose_ximage(this, &this->deinterlace_frame); + + create_ximage(this, &this->deinterlace_frame, frame->width, frame->height / xvscaling, frame->format); + this->deinterlace_frame.width = frame->width; + this->deinterlace_frame.height = frame->height; + this->deinterlace_frame.format = frame->format; + this->deinterlace_frame.ratio = frame->ratio; + + pthread_mutex_unlock(&this->main_mutex); + } + + + if ( this->deinterlace_method != DEINTERLACE_ONEFIELDXV ) { +#ifdef DEINTERLACE_CROMA + + /* I don't think this is the right way to do it (deinterlacing croma by croma info). + DScaler deinterlaces croma together with luma, but it's easier for them because + they have that components 1:1 at the same table. + */ + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + if( this->recent_frames[i] && this->recent_frames[i]->width == frame->width && + this->recent_frames[i]->height == frame->height ) + recent_bitmaps[i] = this->recent_frames[i]->image + frame->width*frame->height; + else + recent_bitmaps[i] = NULL; + + deinterlace_yuv( this->deinterlace_frame.image+frame->width*frame->height, + recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + if( this->recent_frames[i] && this->recent_frames[i]->width == frame->width && + this->recent_frames[i]->height == frame->height ) + recent_bitmaps[i] = this->recent_frames[i]->image + frame->width*frame->height*5/4; + else + recent_bitmaps[i] = NULL; + + deinterlace_yuv( this->deinterlace_frame.image+frame->width*frame->height*5/4, + recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); + +#else + + /* know bug: we are not deinterlacing Cb and Cr */ + xine_fast_memcpy(this->deinterlace_frame.image + frame->width*frame->height, + frame->image + frame->width*frame->height, + frame->width*frame->height*1/2); + +#endif + + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + if( this->recent_frames[i] && this->recent_frames[i]->width == frame->width && + this->recent_frames[i]->height == frame->height ) + recent_bitmaps[i] = this->recent_frames[i]->image; + else + recent_bitmaps[i] = NULL; + + deinterlace_yuv( this->deinterlace_frame.image, recent_bitmaps, + frame->width, frame->height, this->deinterlace_method ); + } + else { + /* + dirty and cheap deinterlace method: we give half of the lines to xv + driver and let it scale for us. + note that memcpy's below don't seem to impact much on performance, + specially when fast memcpys are available. + */ + uint8_t *dst, *src; + + dst = this->deinterlace_frame.image; + src = this->recent_frames[0]->image; + for( i = 0; i < frame->height; i+=2 ) { + xine_fast_memcpy(dst,src,frame->width); + dst += frame->width; + src += 2 * frame->width; + } + + dst = this->deinterlace_frame.image + frame->width * frame->height / 2; + src = this->recent_frames[0]->image + frame->width * frame->height; + for( i = 0; i < frame->height; i+=4 ) { + xine_fast_memcpy(dst,src,frame->width / 2); + dst += frame->width / 2; + src += frame->width; + } + + dst = this->deinterlace_frame.image + frame->width * frame->height * 5 / 8; + src = this->recent_frames[0]->image + frame->width * frame->height * 5 / 4; + for( i = 0; i < frame->height; i+=4 ) { + xine_fast_memcpy(dst,src,frame->width / 2); + dst += frame->width / 2; + src += frame->width; + } + } + + this->cur_frame = &this->deinterlace_frame; +} + +static void xv_clean_output_area (xv_driver_t *this) { + int i; + xcb_rectangle_t rects[4]; + int rects_count = 0; + + pthread_mutex_lock(&this->main_mutex); + + xcb_change_gc(this->connection, this->gc, XCB_GC_FOREGROUND, &this->screen->black_pixel); + + for( i = 0; i < 4; i++ ) { + if( this->sc.border[i].w && this->sc.border[i].h ) { + rects[rects_count].x = this->sc.border[i].x; + rects[rects_count].y = this->sc.border[i].y; + rects[rects_count].width = this->sc.border[i].w; + rects[rects_count].height = this->sc.border[i].h; + rects_count++; + } + } + + if (rects_count > 0) + xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); + + if (this->use_colorkey) { + xcb_change_gc(this->connection, this->gc, XCB_GC_FOREGROUND, &this->colorkey); + xcb_rectangle_t rectangle = { this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height }; + xcb_poly_fill_rectangle(this->connection, this->window, this->gc, 1, &rectangle); + } + + if (this->xoverlay) { + xcbosd_resize(this->xoverlay, this->sc.gui_width, this->sc.gui_height); + this->ovl_changed = 1; + } + + pthread_mutex_unlock(&this->main_mutex); +} + +/* + * convert delivered height/width to ideal width/height + * taking into account aspect ratio and zoom factor + */ + +static void xv_compute_ideal_size (xv_driver_t *this) { + _x_vo_scale_compute_ideal_size( &this->sc ); +} + + +/* + * make ideal width/height "fit" into the gui + */ + +static void xv_compute_output_size (xv_driver_t *this) { + + _x_vo_scale_compute_output_size( &this->sc ); + + /* onefield_xv divide by 2 the number of lines */ + if (this->deinterlace_enabled + && (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) + && this->cur_frame && (this->cur_frame->format == XINE_IMGFMT_YV12)) { + this->sc.displayed_height = this->sc.displayed_height / 2 - 1; + this->sc.displayed_yoffset = this->sc.displayed_yoffset / 2; + } +} + +static void xv_overlay_begin (vo_driver_t *this_gen, + vo_frame_t *frame_gen, int changed) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + this->ovl_changed += changed; + + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_clear(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; + this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; +} + +static void xv_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_expose(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + this->ovl_changed = 0; +} + +static void xv_overlay_blend (vo_driver_t *this_gen, + vo_frame_t *frame_gen, vo_overlay_t *overlay) { + xv_driver_t *this = (xv_driver_t *) this_gen; + xv_frame_t *frame = (xv_frame_t *) frame_gen; + + if (overlay->rle) { + if( overlay->unscaled ) { + if( this->ovl_changed && this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_blend(this->xoverlay, overlay); + pthread_mutex_unlock(&this->main_mutex); + } + } else { + if (frame->format == XINE_IMGFMT_YV12) + _x_blend_yuv(frame->vo_frame.base, overlay, + frame->width, frame->height, frame->vo_frame.pitches, + &this->alphablend_extra_data); + else + _x_blend_yuy2(frame->vo_frame.base[0], overlay, + frame->width, frame->height, frame->vo_frame.pitches[0], + &this->alphablend_extra_data); + } + } +} + +static void xv_add_recent_frame (xv_driver_t *this, xv_frame_t *frame) { + int i; + + i = VO_NUM_RECENT_FRAMES-1; + if( this->recent_frames[i] ) + this->recent_frames[i]->vo_frame.free + (&this->recent_frames[i]->vo_frame); + + for( ; i ; i-- ) + this->recent_frames[i] = this->recent_frames[i-1]; + + this->recent_frames[0] = frame; +} + +/* currently not used - we could have a method to call this from video loop */ +#if 0 +static void xv_flush_recent_frames (xv_driver_t *this) { + int i; + + for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { + if( this->recent_frames[i] ) + this->recent_frames[i]->vo_frame.free + (&this->recent_frames[i]->vo_frame); + this->recent_frames[i] = NULL; + } +} +#endif + +static int xv_redraw_needed (vo_driver_t *this_gen) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int ret = 0; + + if( this->cur_frame ) { + + this->sc.delivered_height = this->cur_frame->height; + this->sc.delivered_width = this->cur_frame->width; + this->sc.delivered_ratio = this->cur_frame->ratio; + + this->sc.crop_left = this->cur_frame->vo_frame.crop_left; + this->sc.crop_right = this->cur_frame->vo_frame.crop_right; + this->sc.crop_top = this->cur_frame->vo_frame.crop_top; + this->sc.crop_bottom = this->cur_frame->vo_frame.crop_bottom; + + xv_compute_ideal_size(this); + + if( _x_vo_scale_redraw_needed( &this->sc ) ) { + + xv_compute_output_size (this); + + xv_clean_output_area (this); + + ret = 1; + } + } + else + ret = 1; + + return ret; +} + +static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { + xv_driver_t *this = (xv_driver_t *) this_gen; + xv_frame_t *frame = (xv_frame_t *) frame_gen; + /* + printf ("video_out_xcbxv: xv_display_frame...\n"); + */ + + /* + * queue frames (deinterlacing) + * free old frames + */ + + xv_add_recent_frame (this, frame); /* deinterlacing */ + + this->cur_frame = frame; + + /* + * let's see if this frame is different in size / aspect + * ratio from the previous one + */ + if ( (frame->width != this->sc.delivered_width) + || (frame->height != this->sc.delivered_height) + || (frame->ratio != this->sc.delivered_ratio) ) { + lprintf("frame format changed\n"); + this->sc.force_redraw = 1; /* trigger re-calc of output size */ + } + + /* + * deinterlace frame if necessary + * (currently only working for YUV images) + */ + + if (this->deinterlace_enabled && this->deinterlace_method + && frame->format == XINE_IMGFMT_YV12 + && (deinterlace_yuv_supported( this->deinterlace_method ) == 1 + || this->deinterlace_method == DEINTERLACE_ONEFIELDXV)) + xv_deinterlace_frame (this); + + /* + * tell gui that we are about to display a frame, + * ask for offset and output size + */ + xv_redraw_needed (this_gen); + + pthread_mutex_lock(&this->main_mutex); + + if (this->cur_frame->shmseg) { + xcb_xv_shm_put_image(this->connection, this->xv_port, this->window, this->gc, + this->cur_frame->shmseg, this->cur_frame->xv_format, 0, + this->sc.displayed_xoffset, this->sc.displayed_yoffset, + this->sc.displayed_width, this->sc.displayed_height, + this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height, + this->cur_frame->xv_width, this->cur_frame->xv_height, 0); + + } else { + xcb_xv_put_image(this->connection, this->xv_port, this->window, this->gc, + this->cur_frame->xv_format, + this->sc.displayed_xoffset, this->sc.displayed_yoffset, + this->sc.displayed_width, this->sc.displayed_height, + this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height, + this->cur_frame->xv_width, this->cur_frame->xv_height, + this->cur_frame->xv_data_size, this->cur_frame->image); + } + + xcb_flush(this->connection); + + pthread_mutex_unlock(&this->main_mutex); + + /* + printf ("video_out_xcbxv: xv_display_frame... done\n"); + */ +} + +static int xv_get_property (vo_driver_t *this_gen, int property) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + switch (property) { + case VO_PROP_WINDOW_WIDTH: + this->props[property].value = this->sc.gui_width; + break; + case VO_PROP_WINDOW_HEIGHT: + this->props[property].value = this->sc.gui_height; + break; + } + + lprintf("video_out_xcbxv: property #%d = %d\n", property, this->props[property].value); + + return this->props[property].value; +} + +static void xv_property_callback (void *property_gen, xine_cfg_entry_t *entry) { + xv_property_t *property = (xv_property_t *) property_gen; + xv_driver_t *this = property->this; + + pthread_mutex_lock(&this->main_mutex); + xcb_xv_set_port_attribute(this->connection, this->xv_port, + property->atom, entry->num_value); + pthread_mutex_unlock(&this->main_mutex); +} + +static int xv_set_property (vo_driver_t *this_gen, + int property, int value) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + if (this->props[property].atom != XCB_NONE) { + xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; + xcb_xv_get_port_attribute_reply_t *get_attribute_reply; + + /* value is out of bound */ + if((value < this->props[property].min) || (value > this->props[property].max)) + value = (this->props[property].min + this->props[property].max) >> 1; + + pthread_mutex_lock(&this->main_mutex); + xcb_xv_set_port_attribute(this->connection, this->xv_port, + this->props[property].atom, value); + + get_attribute_cookie = xcb_xv_get_port_attribute(this->connection, this->xv_port, this->props[property].atom); + get_attribute_reply = xcb_xv_get_port_attribute_reply(this->connection, get_attribute_cookie, NULL); + this->props[property].value = get_attribute_reply->value; + free(get_attribute_reply); + + pthread_mutex_unlock(&this->main_mutex); + + if (this->props[property].entry) + this->props[property].entry->num_value = this->props[property].value; + + return this->props[property].value; + } + else { + switch (property) { + + case VO_PROP_INTERLACED: + this->props[property].value = value; + xprintf(this->xine, XINE_VERBOSITY_LOG, + "video_out_xcbxv: VO_PROP_INTERLACED(%d)\n", this->props[property].value); + this->deinterlace_enabled = value; + if (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) { + xv_compute_ideal_size (this); + xv_compute_output_size (this); + } + break; + + case VO_PROP_ASPECT_RATIO: + if (value>=XINE_VO_ASPECT_NUM_RATIOS) + value = XINE_VO_ASPECT_AUTO; + + this->props[property].value = value; + xprintf(this->xine, XINE_VERBOSITY_LOG, + "video_out_xcbxv: VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); + this->sc.user_ratio = value; + + xv_compute_ideal_size (this); + + this->sc.force_redraw = 1; /* trigger re-calc of output size */ + break; + + case VO_PROP_ZOOM_X: + if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { + this->props[property].value = value; + xprintf(this->xine, XINE_VERBOSITY_LOG, + "video_out_xcbxv: VO_PROP_ZOOM_X = %d\n", this->props[property].value); + + this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; + + xv_compute_ideal_size (this); + + this->sc.force_redraw = 1; /* trigger re-calc of output size */ + } + break; + + case VO_PROP_ZOOM_Y: + if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { + this->props[property].value = value; + xprintf(this->xine, XINE_VERBOSITY_LOG, + "video_out_xcbxv: VO_PROP_ZOOM_Y = %d\n", this->props[property].value); + + this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; + + xv_compute_ideal_size (this); + + this->sc.force_redraw = 1; /* trigger re-calc of output size */ + } + break; + } + } + + return value; +} + +static void xv_get_property_min_max (vo_driver_t *this_gen, + int property, int *min, int *max) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + *min = this->props[property].min; + *max = this->props[property].max; +} + +static int xv_gui_data_exchange (vo_driver_t *this_gen, + int data_type, void *data) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + switch (data_type) { +#ifndef XINE_DISABLE_DEPRECATED_FEATURES + case XINE_GUI_SEND_COMPLETION_EVENT: + break; +#endif + + case XINE_GUI_SEND_EXPOSE_EVENT: { + /* XExposeEvent * xev = (XExposeEvent *) data; */ + + if (this->cur_frame) { + int i; + xcb_rectangle_t rects[4]; + int rects_count = 0; + + pthread_mutex_lock(&this->main_mutex); + + if (this->cur_frame->shmseg) { + xcb_xv_shm_put_image(this->connection, this->xv_port, this->window, this->gc, + this->cur_frame->shmseg, this->cur_frame->xv_format, 0, + this->sc.displayed_xoffset, this->sc.displayed_yoffset, + this->sc.displayed_width, this->sc.displayed_height, + this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height, + this->cur_frame->xv_width, this->cur_frame->xv_height, 0); + } else { + xcb_xv_put_image(this->connection, this->xv_port, this->window, this->gc, + this->cur_frame->xv_format, + this->sc.displayed_xoffset, this->sc.displayed_yoffset, + this->sc.displayed_width, this->sc.displayed_height, + this->sc.output_xoffset, this->sc.output_yoffset, + this->sc.output_width, this->sc.output_height, + this->cur_frame->xv_width, this->cur_frame->xv_height, + this->cur_frame->xv_data_size, this->cur_frame->image); + } + + xcb_change_gc(this->connection, this->gc, XCB_GC_FOREGROUND, &this->screen->black_pixel); + + for( i = 0; i < 4; i++ ) { + if( this->sc.border[i].w && this->sc.border[i].h ) { + rects[rects_count].x = this->sc.border[i].x; + rects[rects_count].y = this->sc.border[i].y; + rects[rects_count].width = this->sc.border[i].w; + rects[rects_count].height = this->sc.border[i].h; + rects_count++; + } + } + + if (rects_count > 0) + xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); + + if(this->xoverlay) + xcbosd_expose(this->xoverlay); + + xcb_flush(this->connection); + pthread_mutex_unlock(&this->main_mutex); + } + } + break; + + case XINE_GUI_SEND_DRAWABLE_CHANGED: + pthread_mutex_lock(&this->main_mutex); + this->window = (xcb_window_t) data; + xcb_free_gc(this->connection, this->gc); + this->gc = xcb_generate_id(this->connection); + xcb_create_gc(this->connection, this->gc, this->window, 0, NULL); + if(this->xoverlay) + xcbosd_drawable_changed(this->xoverlay, this->window); + this->ovl_changed = 1; + pthread_mutex_unlock(&this->main_mutex); + this->sc.force_redraw = 1; + break; + + case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: + { + int x1, y1, x2, y2; + x11_rectangle_t *rect = data; + + _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, + &x1, &y1); + _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, + &x2, &y2); + rect->x = x1; + rect->y = y1; + rect->w = x2-x1; + rect->h = y2-y1; + + /* onefield_xv divide by 2 the number of lines */ + if (this->deinterlace_enabled + && (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) + && (this->cur_frame->format == XINE_IMGFMT_YV12)) { + rect->y = rect->y * 2; + rect->h = rect->h * 2; + } + + } + break; + + default: + return -1; + } + + return 0; +} + +static void xv_store_port_attribute(xv_driver_t *this, char *name) { + xv_portattribute_t *attr; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; + xcb_xv_get_port_attribute_reply_t *get_attribute_reply; + + attr = (xv_portattribute_t *)malloc( sizeof(xv_portattribute_t) ); + attr->name = strdup(name); + + pthread_mutex_lock(&this->main_mutex); + atom_cookie = xcb_intern_atom(this->connection, 0, strlen(attr->name), attr->name); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + get_attribute_cookie = xcb_xv_get_port_attribute(this->connection, this->xv_port, atom_reply->atom); + get_attribute_reply = xcb_xv_get_port_attribute_reply(this->connection, get_attribute_cookie, NULL); + attr->value = get_attribute_reply->value; + free(atom_reply); + free(get_attribute_reply); + pthread_mutex_unlock(&this->main_mutex); + + xine_list_push_back (this->port_attributes, attr); +} + +static void xv_restore_port_attributes(xv_driver_t *this) { + xine_list_iterator_t ite; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + while ((ite = xine_list_front(this->port_attributes)) != NULL) { + xv_portattribute_t *attr = xine_list_get_value(this->port_attributes, ite); + xine_list_remove (this->port_attributes, ite); + + pthread_mutex_lock(&this->main_mutex); + atom_cookie = xcb_intern_atom(this->connection, 0, strlen(attr->name), attr->name); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, attr->value); + free(atom_reply); + pthread_mutex_unlock(&this->main_mutex); + + free( attr->name ); + free( attr ); + } + + pthread_mutex_lock(&this->main_mutex); + xcb_flush(this->connection); + pthread_mutex_unlock(&this->main_mutex); + + xine_list_delete( this->port_attributes ); +} + +static void xv_dispose (vo_driver_t *this_gen) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int i; + + /* restore port attributes to their initial values */ + xv_restore_port_attributes(this); + + if (this->deinterlace_frame.image) { + pthread_mutex_lock(&this->main_mutex); + dispose_ximage(this, &this->deinterlace_frame); + pthread_mutex_unlock(&this->main_mutex); + } + + pthread_mutex_lock(&this->main_mutex); + xcb_xv_ungrab_port(this->connection, this->xv_port, XCB_CURRENT_TIME); + xcb_free_gc(this->connection, this->gc); + pthread_mutex_unlock(&this->main_mutex); + + for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { + if( this->recent_frames[i] ) + this->recent_frames[i]->vo_frame.dispose + (&this->recent_frames[i]->vo_frame); + this->recent_frames[i] = NULL; + } + + if( this->xoverlay ) { + pthread_mutex_lock(&this->main_mutex); + xcbosd_destroy(this->xoverlay); + pthread_mutex_unlock(&this->main_mutex); + } + + pthread_mutex_destroy(&this->main_mutex); + + _x_alphablend_free(&this->alphablend_extra_data); + + free (this); +} + +static int xv_check_yv12(xcb_connection_t *connection, xcb_xv_port_t port) { + xcb_xv_list_image_formats_cookie_t list_formats_cookie; + xcb_xv_list_image_formats_reply_t *list_formats_reply; + + xcb_xv_image_format_info_iterator_t format_it; + + list_formats_cookie = xcb_xv_list_image_formats(connection, port); + list_formats_reply = xcb_xv_list_image_formats_reply(connection, list_formats_cookie, NULL); + format_it = xcb_xv_list_image_formats_format_iterator(list_formats_reply); + + for (; format_it.rem; xcb_xv_image_format_info_next(&format_it)) + if ((format_it.data->id == XINE_IMGFMT_YV12) && + (! (strcmp ((char *) format_it.data->guid, "YV12")))) { + free(list_formats_reply); + return 0; + } + + free(list_formats_reply); + return 1; +} + +static void xv_check_capability (xv_driver_t *this, + int property, xcb_xv_attribute_info_t *attr, + int base_id, + char *config_name, + char *config_desc, + char *config_help) { + int int_default; + cfg_entry_t *entry; + char *str_prop = xcb_xv_attribute_info_name(attr); + + xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; + xcb_xv_get_port_attribute_reply_t *get_attribute_reply; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + /* + * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. + */ + if (VO_PROP_COLORKEY && (attr->max == ~0)) + attr->max = 2147483615; + + atom_cookie = xcb_intern_atom(this->connection, 0, strlen(str_prop), str_prop); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + + this->props[property].min = attr->min; + this->props[property].max = attr->max; + this->props[property].atom = atom_reply->atom; + + free(atom_reply); + + get_attribute_cookie = xcb_xv_get_port_attribute(this->connection, this->xv_port, this->props[property].atom); + get_attribute_reply = xcb_xv_get_port_attribute_reply(this->connection, get_attribute_cookie, NULL); + + int_default = get_attribute_reply->value; + + free(get_attribute_reply); + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbxv: port attribute %s (%d) value is %d\n", str_prop, property, int_default); + + /* disable autopaint colorkey by default */ + /* might be overridden using config entry */ + if(strcmp(str_prop, "XV_AUTOPAINT_COLORKEY") == 0) + int_default = 0; + + if (config_name) { + /* is this a boolean property ? */ + if ((attr->min == 0) && (attr->max == 1)) { + this->config->register_bool (this->config, config_name, int_default, + config_desc, + config_help, 20, xv_property_callback, &this->props[property]); + + } else { + this->config->register_range (this->config, config_name, int_default, + this->props[property].min, this->props[property].max, + config_desc, + config_help, 20, xv_property_callback, &this->props[property]); + } + + entry = this->config->lookup_entry (this->config, config_name); + + if((entry->num_value < this->props[property].min) || + (entry->num_value > this->props[property].max)) { + + this->config->update_num(this->config, config_name, + ((this->props[property].min + this->props[property].max) >> 1)); + + entry = this->config->lookup_entry (this->config, config_name); + } + + this->props[property].entry = entry; + + xv_set_property (&this->vo_driver, property, entry->num_value); + + if (strcmp(str_prop, "XV_COLORKEY") == 0) { + this->use_colorkey |= 1; + this->colorkey = entry->num_value; + } else if(strcmp(str_prop, "XV_AUTOPAINT_COLORKEY") == 0) { + if(entry->num_value==1) + this->use_colorkey |= 2; /* colorkey is autopainted */ + } + } else + this->props[property].value = int_default; + +} + +static void xv_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + this->deinterlace_method = entry->num_value; +} + +static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int xv_filter; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + xv_filter = entry->num_value; + + pthread_mutex_lock(&this->main_mutex); + atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_FILTER"), "XV_FILTER"); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, xv_filter); + free(atom_reply); + pthread_mutex_unlock(&this->main_mutex); + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbxv: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter); +} + +static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int xv_double_buffer; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + xv_double_buffer = entry->num_value; + + pthread_mutex_lock(&this->main_mutex); + atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_DOUBLE_BUFFER"), "XV_DOUBLE_BUFFER"); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, xv_double_buffer); + free(atom_reply); + pthread_mutex_unlock(&this->main_mutex); + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbxv: double buffering mode = %d\n", xv_double_buffer); +} + +static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + + this->use_pitch_alignment = entry->num_value; +} + +static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { + xv_class_t *class = (xv_class_t *) class_gen; + config_values_t *config = class->config; + xv_driver_t *this; + int i; + xcb_visual_t *visual = (xcb_visual_t *) visual_gen; + unsigned int j; + xcb_xv_port_t xv_port; + + const xcb_query_extension_reply_t *query_extension_reply; + + xcb_xv_query_adaptors_cookie_t query_adaptors_cookie; + xcb_xv_query_adaptors_reply_t *query_adaptors_reply; + xcb_xv_query_port_attributes_cookie_t query_attributes_cookie; + xcb_xv_query_port_attributes_reply_t *query_attributes_reply; + xcb_xv_list_image_formats_cookie_t list_formats_cookie; + xcb_xv_list_image_formats_reply_t *list_formats_reply; + + xcb_xv_adaptor_info_iterator_t adaptor_it; + xcb_xv_image_format_info_iterator_t format_it; + + this = (xv_driver_t *) xine_xmalloc (sizeof (xv_driver_t)); + if (!this) + return NULL; + + pthread_mutex_init(&this->main_mutex, NULL); + + _x_alphablend_init(&this->alphablend_extra_data, class->xine); + + this->connection = visual->connection; + this->screen = visual->screen; + this->window = visual->window; + this->config = config; + + /* + * check for Xvideo support + */ + + query_extension_reply = xcb_get_extension_data(this->connection, &xcb_xv_id); + if (!query_extension_reply || !query_extension_reply->present) { + xprintf (class->xine, XINE_VERBOSITY_LOG, _("video_out_xcbxv: Xv extension not present.\n")); + return NULL; + } + + /* + * check adaptors, search for one that supports (at least) yuv12 + */ + + query_adaptors_cookie = xcb_xv_query_adaptors(this->connection, this->window); + query_adaptors_reply = xcb_xv_query_adaptors_reply(this->connection, query_adaptors_cookie, NULL); + + if (!query_adaptors_reply) { + xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_xcbxv: XvQueryAdaptors failed.\n"); + return NULL; + } + + adaptor_it = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply); + + xv_port = 0; + + for (; adaptor_it.rem && !xv_port; xcb_xv_adaptor_info_next(&adaptor_it)) { + + if (adaptor_it.data->type & XCB_XV_TYPE_IMAGE_MASK) { + + for (j = 0; j < adaptor_it.data->num_ports; j++) + if (!xv_check_yv12(this->connection, adaptor_it.data->base_id + j)) { + xcb_xv_grab_port_cookie_t grab_port_cookie; + xcb_xv_grab_port_reply_t *grab_port_reply; + grab_port_cookie = xcb_xv_grab_port(this->connection, adaptor_it.data->base_id + j, XCB_CURRENT_TIME); + grab_port_reply = xcb_xv_grab_port_reply(this->connection, grab_port_cookie, NULL); + if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS)) { + free(grab_port_reply); + xv_port = adaptor_it.data->base_id + j; + break; + } + free(grab_port_reply); + } + } + } + + if (!xv_port) { + xprintf(class->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: Xv extension is present but I couldn't find a usable yuv12 port.\n" + " Looks like your graphics hardware driver doesn't support Xv?!\n")); + + /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/ + return NULL; + } + else + xprintf(class->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: using Xv port %d from adaptor %s for hardware " + "colorspace conversion and scaling.\n"), xv_port, + xcb_xv_adaptor_info_name(adaptor_it.data)); + + this->xv_port = xv_port; + + _x_vo_scale_init (&this->sc, 1, 0, config ); + this->sc.frame_output_cb = visual->frame_output_cb; + this->sc.user_data = visual->user_data; + + this->gc = xcb_generate_id(this->connection); + xcb_create_gc(this->connection, this->gc, this->window, 0, NULL); + this->capabilities = VO_CAP_CROP; + this->use_shm = 1; + this->deinterlace_method = 0; + this->deinterlace_frame.image = NULL; + this->use_colorkey = 0; + this->colorkey = 0; + this->xoverlay = NULL; + this->ovl_changed = 0; + this->xine = class->xine; + + this->vo_driver.get_capabilities = xv_get_capabilities; + this->vo_driver.alloc_frame = xv_alloc_frame; + this->vo_driver.update_frame_format = xv_update_frame_format; + this->vo_driver.overlay_begin = xv_overlay_begin; + this->vo_driver.overlay_blend = xv_overlay_blend; + this->vo_driver.overlay_end = xv_overlay_end; + this->vo_driver.display_frame = xv_display_frame; + this->vo_driver.get_property = xv_get_property; + this->vo_driver.set_property = xv_set_property; + this->vo_driver.get_property_min_max = xv_get_property_min_max; + this->vo_driver.gui_data_exchange = xv_gui_data_exchange; + this->vo_driver.dispose = xv_dispose; + this->vo_driver.redraw_needed = xv_redraw_needed; + + /* + * init properties + */ + + for (i = 0; i < VO_NUM_PROPERTIES; i++) { + this->props[i].value = 0; + this->props[i].min = 0; + this->props[i].max = 0; + this->props[i].atom = XCB_NONE; + this->props[i].entry = NULL; + this->props[i].this = this; + } + + this->props[VO_PROP_INTERLACED].value = 0; + this->sc.user_ratio = + this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; + this->props[VO_PROP_ZOOM_X].value = 100; + this->props[VO_PROP_ZOOM_Y].value = 100; + + /* + * check this adaptor's capabilities + */ + this->port_attributes = xine_list_new(); + + query_attributes_cookie = xcb_xv_query_port_attributes(this->connection, xv_port); + query_attributes_reply = xcb_xv_query_port_attributes_reply(this->connection, query_attributes_cookie, NULL); + if(query_attributes_reply) { + xcb_xv_attribute_info_iterator_t attribute_it; + attribute_it = xcb_xv_query_port_attributes_attributes_iterator(query_attributes_reply); + + for (; attribute_it.rem; xcb_xv_attribute_info_next(&attribute_it)) { + if ((attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_SETTABLE) && (attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_GETTABLE)) { + /* store initial port attribute value */ + xv_store_port_attribute(this, xcb_xv_attribute_info_name(attribute_it.data)); + + 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"); + } else { + xv_check_capability (this, VO_PROP_HUE, attribute_it.data, + adaptor_it.data->base_id, + NULL, NULL, NULL); + } + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_SATURATION")) { + xv_check_capability (this, VO_PROP_SATURATION, attribute_it.data, + adaptor_it.data->base_id, + NULL, NULL, NULL); + + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_BRIGHTNESS")) { + xv_check_capability (this, VO_PROP_BRIGHTNESS, attribute_it.data, + adaptor_it.data->base_id, + NULL, NULL, NULL); + + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_CONTRAST")) { + xv_check_capability (this, VO_PROP_CONTRAST, attribute_it.data, + adaptor_it.data->base_id, + NULL, NULL, NULL); + + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_COLORKEY")) { + xv_check_capability (this, VO_PROP_COLORKEY, attribute_it.data, + adaptor_it.data->base_id, + "video.device.xv_colorkey", + _("video overlay colour key"), + _("The colour key is used to tell the graphics card where to " + "overlay the video image. Try different values, if you experience " + "windows becoming transparent.")); + + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_AUTOPAINT_COLORKEY")) { + xv_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attribute_it.data, + adaptor_it.data->base_id, + "video.device.xv_autopaint_colorkey", + _("autopaint colour key"), + _("Make Xv autopaint its colorkey.")); + + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_FILTER")) { + int xv_filter; + /* This setting is specific to Permedia 2/3 cards. */ + xv_filter = config->register_range (config, "video.device.xv_filter", 0, + attribute_it.data->min, attribute_it.data->max, + _("bilinear scaling mode"), + _("Selects the bilinear scaling mode for Permedia cards. " + "The individual values are:\n\n" + "Permedia 2\n" + "0 - disable bilinear filtering\n" + "1 - enable bilinear filtering\n\n" + "Permedia 3\n" + "0 - disable bilinear filtering\n" + "1 - horizontal linear filtering\n" + "2 - enable full bilinear filtering"), + 20, xv_update_XV_FILTER, this); + config->update_num(config,"video.device.xv_filter",xv_filter); + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_DOUBLE_BUFFER")) { + int xv_double_buffer; + xv_double_buffer = + config->register_bool (config, "video.device.xv_double_buffer", 1, + _("enable double buffering"), + _("Double buffering will synchronize the update of the video image to the " + "repainting of the entire screen (\"vertical retrace\"). This eliminates " + "flickering and tearing artifacts, but will use more graphics memory."), + 20, xv_update_XV_DOUBLE_BUFFER, this); + config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer); + } + } + } + free(query_attributes_reply); + } + else + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_xcbxv: no port attributes defined.\n"); + free(query_adaptors_reply); + + /* + * check supported image formats + */ + + list_formats_cookie = xcb_xv_list_image_formats(this->connection, xv_port); + list_formats_reply = xcb_xv_list_image_formats_reply(this->connection, list_formats_cookie, NULL); + + format_it = xcb_xv_list_image_formats_format_iterator(list_formats_reply); + + this->xv_format_yv12 = 0; + this->xv_format_yuy2 = 0; + + for (; format_it.rem; xcb_xv_image_format_info_next(&format_it)) { + lprintf ("Xv image format: 0x%x (%4.4s) %s\n", + format_it.data->id, (char*)&format_it.data->id, + (format_it.data->format == XCB_XV_IMAGE_FORMAT_INFO_FORMAT_PACKED) + ? "packed" : "planar"); + + if (format_it.data->id == XINE_IMGFMT_YV12) { + this->xv_format_yv12 = format_it.data->id; + this->capabilities |= VO_CAP_YV12; + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: this adaptor supports the yv12 format.\n")); + } else if (format_it.data->id == XINE_IMGFMT_YUY2) { + this->xv_format_yuy2 = format_it.data->id; + this->capabilities |= VO_CAP_YUY2; + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("video_out_xcbxv: this adaptor supports the yuy2 format.\n")); + } + } + + free(list_formats_reply); + + this->use_pitch_alignment = + config->register_bool (config, "video.device.xv_pitch_alignment", 0, + _("pitch alignment workaround"), + _("Some buggy video drivers need a workaround to function properly."), + 10, xv_update_xv_pitch_alignment, this); + + this->deinterlace_method = + config->register_enum (config, "video.output.xv_deinterlace_method", 4, + deinterlace_methods, + _("deinterlace method (deprecated)"), + _("This config setting is deprecated. You should use the new deinterlacing " + "post processing settings instead.\n\n" + "From the old days of analog television, where the even and odd numbered " + "lines of a video frame would be displayed at different times comes the " + "idea to increase motion smoothness by also recording the lines at " + "different times. This is called \"interlacing\". But unfortunately, " + "todays displays show the even and odd numbered lines as one complete frame " + "all at the same time (called \"progressive display\"), which results in " + "ugly frame errors known as comb artifacts. Software deinterlacing is an " + "approach to reduce these artifacts. The individual values are:\n\n" + "none\n" + "Disables software deinterlacing.\n\n" + "bob\n" + "Interpolates between the lines for moving parts of the image.\n\n" + "weave\n" + "Similar to bob, but with a tendency to preserve the full resolution, " + "better for high detail in low movement scenes.\n\n" + "greedy\n" + "Very good adaptive deinterlacer, but needs a lot of CPU power.\n\n" + "onefield\n" + "Always interpolates and reduces vertical resolution.\n\n" + "onefieldxv\n" + "Same as onefield, but does the interpolation in hardware.\n\n" + "linearblend\n" + "Applies a slight vertical blur to remove the comb artifacts. Good results " + "with medium CPU usage."), + 10, xv_update_deinterlace, this); + this->deinterlace_enabled = 0; + + if(this->use_colorkey==1) { + this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, + this->window, XCBOSD_COLORKEY); + if(this->xoverlay) + xcbosd_colorkey(this->xoverlay, this->colorkey, &this->sc); + } else { + this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, + this->window, XCBOSD_SHAPED); + } + + if( this->xoverlay ) + this->capabilities |= VO_CAP_UNSCALED_OVERLAY; + + return &this->vo_driver; +} + +/* + * class functions + */ + +static char* get_identifier (video_driver_class_t *this_gen) { + return "Xv"; +} + +static char* get_description (video_driver_class_t *this_gen) { + return _("xine video output plugin using the MIT X video extension"); +} + +static void dispose_class (video_driver_class_t *this_gen) { + xv_class_t *this = (xv_class_t *) this_gen; + + free (this); +} + +static void *init_class (xine_t *xine, void *visual_gen) { + xv_class_t *this = (xv_class_t *) xine_xmalloc (sizeof (xv_class_t)); + + this->driver_class.open_plugin = open_plugin; + this->driver_class.get_identifier = get_identifier; + this->driver_class.get_description = get_description; + this->driver_class.dispose = dispose_class; + + this->config = xine->config; + this->xine = xine; + + return this; +} + +static const vo_info_t vo_info_xv = { + 9, /* priority */ + XINE_VISUAL_TYPE_XCB /* visual type */ +}; + +/* + * exported plugin catalog entry + */ + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_OUT, 21, "xv", XINE_VERSION_CODE, &vo_info_xv, init_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + +#endif diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index d109fb455..00d3bee1c 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xshm.c,v 1.148 2006/10/28 18:51:08 miguelfreitas Exp $ + * $Id: video_out_xshm.c,v 1.150 2007/03/25 23:13:53 dgp85 Exp $ * * video_out_xshm.c, X11 shared memory extension interface for xine * @@ -87,7 +87,6 @@ typedef struct { yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ uint8_t *rgb_dst; - int yuv_stride; } xshm_frame_t; @@ -105,8 +104,6 @@ typedef struct { int use_shm; XColor black; - int yuv2rgb_mode; - int yuv2rgb_swap; int yuv2rgb_brightness; int yuv2rgb_contrast; int yuv2rgb_saturation; @@ -178,6 +175,11 @@ static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo, int width, int height) { XImage *myimage = NULL; + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + if (this->use_shm) { /* @@ -585,7 +587,6 @@ static void xshm_update_frame_format (vo_driver_t *this_gen, frame->sc.output_width, frame->sc.output_height, frame->image->bytes_per_line*2); - frame->yuv_stride = frame->image->bytes_per_line*2; break; case VO_BOTH_FIELDS: frame->yuv2rgb->configure (frame->yuv2rgb, @@ -596,7 +597,6 @@ static void xshm_update_frame_format (vo_driver_t *this_gen, frame->sc.output_width, frame->sc.output_height, frame->image->bytes_per_line); - frame->yuv_stride = frame->image->bytes_per_line; break; } } @@ -1255,8 +1255,6 @@ static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const v return NULL; } - this->yuv2rgb_mode = mode; - this->yuv2rgb_swap = swapped; this->yuv2rgb_brightness = 0; this->yuv2rgb_contrast = 128; this->yuv2rgb_saturation = 128; diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 64533a88f..55340a9e7 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xv.c,v 1.220 2006/10/28 18:51:08 miguelfreitas Exp $ + * $Id: video_out_xv.c,v 1.224 2007/03/29 19:01:03 dgp85 Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -130,10 +130,10 @@ struct xv_driver_s { xv_property_t props[VO_NUM_PROPERTIES]; uint32_t capabilities; + int ovl_changed; xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xv_frame_t *cur_frame; x11osd *xoverlay; - int ovl_changed; /* all scaling information goes here */ vo_scale_t sc; @@ -187,7 +187,7 @@ static void xv_frame_dispose (vo_frame_t *vo_img) { if (frame->image) { - if (this->use_shm) { + if (frame->shminfo.shmaddr) { LOCK_DISPLAY(this); XShmDetach (this->display, &frame->shminfo); XFree (frame->image); @@ -258,6 +258,11 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, unsigned int xv_format; XvImage *image = NULL; + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } @@ -382,6 +387,7 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, image = XvCreateImage (this->display, this->xv_port, xv_format, data, width, height); + shminfo->shmaddr = 0; } return image; } @@ -391,7 +397,7 @@ static void dispose_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, XvImage *myimage) { - if (this->use_shm) { + if (shminfo->shmaddr) { XShmDetach (this->display, shminfo); XFree (myimage); @@ -952,6 +958,7 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, /* XExposeEvent * xev = (XExposeEvent *) data; */ if (this->cur_frame) { + int i; LOCK_DISPLAY(this); @@ -971,6 +978,16 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, this->sc.output_width, this->sc.output_height); } + XSetForeground (this->display, this->gc, this->black.pixel); + + for( i = 0; i < 4; i++ ) { + if( this->sc.border[i].w && this->sc.border[i].h ) { + XFillRectangle(this->display, this->drawable, this->gc, + this->sc.border[i].x, this->sc.border[i].y, + this->sc.border[i].w, this->sc.border[i].h); + } + } + if(this->xoverlay) x11osd_expose(this->xoverlay); diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index fd0299435..53d09b7d5 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xvmc.c,v 1.28 2006/07/10 22:08:44 dgp85 Exp $ + * $Id: video_out_xvmc.c,v 1.29 2007/03/25 23:07:23 dgp85 Exp $ * * video_out_xvmc.c, X11 video motion compensation extension interface for xine * @@ -1074,7 +1074,7 @@ static int xvmc_set_property (vo_driver_t *this_gen, if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xv: VO_PROP_ZOOM_X = %d\n", this->props[property].value); + "video_out_xvmc: VO_PROP_ZOOM_X = %d\n", this->props[property].value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; xvmc_compute_ideal_size (this); @@ -1086,7 +1086,7 @@ static int xvmc_set_property (vo_driver_t *this_gen, if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xv: VO_PROP_ZOOM_Y = %d\n", this->props[property].value); + "video_out_xvmc: VO_PROP_ZOOM_Y = %d\n", this->props[property].value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; xvmc_compute_ideal_size (this); diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 4292ca0b6..0abe2f0fc 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_xxmc.c,v 1.22 2006/07/10 22:08:44 dgp85 Exp $ + * $Id: video_out_xxmc.c,v 1.23 2007/03/25 23:13:53 dgp85 Exp $ * * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine * @@ -608,6 +608,11 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, unsigned int xv_format; XvImage *image = NULL; + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } diff --git a/src/video_out/vidix/.hgignore b/src/video_out/vidix/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/vidix/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/vidix/Makefile.am b/src/video_out/vidix/Makefile.am index e2f8665be..2ca8f168a 100644 --- a/src/video_out/vidix/Makefile.am +++ b/src/video_out/vidix/Makefile.am @@ -13,7 +13,7 @@ endif noinst_LTLIBRARIES = $(vidix_lib) libvidix_la_SOURCES = vidixlib.c -libvidix_la_LIBADD = $(DYNAMIC_LD_LIBS) +libvidix_la_LIBADD = $(DYNAMIC_LD_LIBS) $(top_builddir)/src/video_out/libdha/libdha.la noinst_HEADERS = fourcc.h vidix.h vidixlib.h diff --git a/src/video_out/vidix/drivers/.hgignore b/src/video_out/vidix/drivers/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/video_out/vidix/drivers/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/video_out/vidix/drivers/Makefile.am b/src/video_out/vidix/drivers/Makefile.am index 9e31be6cb..3c0369af7 100644 --- a/src/video_out/vidix/drivers/Makefile.am +++ b/src/video_out/vidix/drivers/Makefile.am @@ -23,11 +23,10 @@ endif lib_LTLIBRARIES = $(vidix_drivers) radeon_vid_la_SOURCES = radeon_vid.c -radeon_vid_la_LIBADD = -lm -radeon_vid_la_LDFLAGS = -avoid-version -module +radeon_vid_la_LDFLAGS = -avoid-version -module -lm rage128_vid_la_SOURCES = radeon_vid.c -rage128_vid_la_LDFLAGS = -avoid-version -module +rage128_vid_la_LDFLAGS = -avoid-version -module -lm rage128_vid_la_CFLAGS = -DRAGE128 $(AM_CFLAGS) pm2_vid_la_SOURCES = pm2_vid.c @@ -40,12 +39,10 @@ mach64_vid_la_SOURCES = mach64_vid.c mach64_vid_la_LDFLAGS = -avoid-version -module mga_vid_la_SOURCES = mga_vid.c -mga_vid_la_LIBADD = -lm -mga_vid_la_LDFLAGS = -avoid-version -module +mga_vid_la_LDFLAGS = -avoid-version -module -lm mga_crtc2_vid_la_SOURCES = mga_vid.c -mga_crtc2_vid_la_LIBADD = -lm -mga_crtc2_vid_la_LDFLAGS = -avoid-version -module +mga_crtc2_vid_la_LDFLAGS = -avoid-version -module -lm mga_crtc2_vid_la_CFLAGS = -DCRTC2 $(AM_CFLAGS) cyberblade_vid_la_SOURCES = cyberblade_vid.c @@ -61,8 +58,7 @@ sis_vid_la_SOURCES = sis_vid.c sis_bridge.c sis_vid_la_LDFLAGS = -avoid-version -module savage_vid_la_SOURCES = savage_vid.c -savage_vid_la_LIBADD = -lm -savage_vid_la_LDFLAGS = -avoid-version -module +savage_vid_la_LDFLAGS = -avoid-version -module -lm noinst_HEADERS = mach64.h glint_regs.h pm3_regs.h radeon.h savage_regs.h \ cyberblade_regs.h unichrome_regs.h sis_defs.h sis_regs.h diff --git a/src/video_out/xcbosd.c b/src/video_out/xcbosd.c new file mode 100644 index 000000000..9013bab10 --- /dev/null +++ b/src/video_out/xcbosd.c @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2003, 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: xcbosd.c,v 1.1 2007/02/15 15:19:33 dgp85 Exp $ + * + * xcbosd.c, use X11 Nonrectangular Window Shape Extension to draw xine OSD + * + * Nov 2003 - Miguel Freitas + * Feb 2007 - ported to xcb by Christoph Pfister + * + * based on ideas and code of + * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) + * + * colorkey support by Yann Vernier + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> + +#include <assert.h> + +#include <netinet/in.h> + +#include <xcb/shape.h> + +#define LOG_MODULE "xcbosd" +#define LOG_VERBOSE + +/* +#define LOG +*/ + +#include "xine_internal.h" +#include "xcbosd.h" + +struct xcbosd +{ + xcb_connection_t *connection; + xcb_screen_t *screen; + enum xcbosd_mode mode; + + union { + struct { + xcb_window_t window; + xcb_pixmap_t mask_bitmap; + xcb_gc_t mask_gc; + xcb_gc_t mask_gc_back; + int mapped; + } shaped; + struct { + uint32_t colorkey; + vo_scale_t *sc; + } colorkey; + } u; + xcb_window_t window; + unsigned int depth; + xcb_pixmap_t bitmap; + xcb_visualid_t visual; + xcb_colormap_t cmap; + + xcb_gc_t gc; + + int width; + int height; + int x; + int y; + enum {DRAWN, WIPED, UNDEFINED} clean; + xine_t *xine; +}; + + +void xcbosd_expose(xcbosd *osd) +{ + assert (osd); + + lprintf("expose (state:%d)\n", osd->clean ); + + switch (osd->mode) { + case XCBOSD_SHAPED: + xcb_shape_mask(osd->connection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, + osd->u.shaped.window, 0, 0, osd->u.shaped.mask_bitmap); + if( osd->clean==DRAWN ) { + + if( !osd->u.shaped.mapped ) { + unsigned int stack_mode = XCB_STACK_MODE_ABOVE; + xcb_configure_window(osd->connection, osd->u.shaped.window, XCB_CONFIG_WINDOW_STACK_MODE, &stack_mode); + xcb_map_window(osd->connection, osd->u.shaped.window); + } + osd->u.shaped.mapped = 1; + + xcb_copy_area(osd->connection, osd->bitmap, osd->u.shaped.window, + osd->gc, 0, 0, 0, 0, osd->width, osd->height); + } else { + if( osd->u.shaped.mapped ) + xcb_unmap_window(osd->connection, osd->u.shaped.window); + osd->u.shaped.mapped = 0; + } + break; + case XCBOSD_COLORKEY: + if( osd->clean!=UNDEFINED ) + xcb_copy_area(osd->connection, osd->bitmap, osd->window, osd->gc, 0, 0, + 0, 0, osd->width, osd->height); + } +} + + +void xcbosd_resize(xcbosd *osd, int width, int height) +{ + assert (osd); + assert (width); + assert (height); + + lprintf("resize old:%dx%d new:%dx%d\n", osd->width, osd->height, width, height ); + + osd->width = width; + osd->height = height; + + xcb_free_pixmap(osd->connection, osd->bitmap); + switch(osd->mode) { + case XCBOSD_SHAPED: { + unsigned int window_config[] = { osd->width, osd->height }; + xcb_configure_window(osd->connection, osd->u.shaped.window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, window_config); + xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); + osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); + break; + } + case XCBOSD_COLORKEY: + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); + break; + } + + osd->clean = UNDEFINED; + xcbosd_clear(osd); +} + +void xcbosd_drawable_changed(xcbosd *osd, xcb_window_t window) +{ + xcb_get_geometry_cookie_t get_geometry_cookie; + xcb_get_geometry_reply_t *get_geometry_reply; + + assert (osd); + + lprintf("drawable changed\n"); + +/* + Do I need to recreate the GC's?? + + XFreeGC (osd->display, osd->gc); + XFreeGC (osd->display, osd->mask_gc); + XFreeGC (osd->display, osd->mask_gc_back); +*/ + xcb_free_pixmap(osd->connection, osd->bitmap); + xcb_free_colormap(osd->connection, osd->cmap); + + /* we need to call XSync(), because otherwise, calling XDestroyWindow() + on the parent window could destroy our OSD window twice !! */ + /* XSync (osd->display, False); FIXME don't think that we need that --pfister */ + + osd->window = window; + + get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); + get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); + osd->depth = get_geometry_reply->depth; + osd->width = get_geometry_reply->width; + osd->height = get_geometry_reply->height; + free(get_geometry_reply); + + assert(osd->width); + assert(osd->height); + + switch(osd->mode) { + case XCBOSD_SHAPED: { + xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); + xcb_destroy_window(osd->connection, osd->u.shaped.window); + + unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; + osd->u.shaped.window = xcb_generate_id(osd->connection); + xcb_create_window(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, + osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, + XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, + window_params); + + osd->u.shaped.mapped = 0; + + osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); + + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); + + osd->cmap = xcb_generate_id(osd->connection); + xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); + break; + } + case XCBOSD_COLORKEY: + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); + osd->cmap = xcb_generate_id(osd->connection); + xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); + + break; + } + + osd->clean = UNDEFINED; + /* do not xcbosd_clear() here: osd->u.colorkey.sc has not being updated yet */ +} + +xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode) +{ + xcbosd *osd; + + xcb_get_geometry_cookie_t get_geometry_cookie; + xcb_get_geometry_reply_t *get_geometry_reply; + + xcb_void_cookie_t generic_cookie; + xcb_generic_error_t *generic_error; + + osd = xine_xmalloc (sizeof (xcbosd)); + if (!osd) + return NULL; + + osd->mode = mode; + osd->xine = xine; + osd->connection = connection; + osd->screen = screen; + osd->window = window; + + osd->visual = osd->screen->root_visual; + + get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); + get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); + osd->depth = get_geometry_reply->depth; + osd->width = get_geometry_reply->width; + osd->height = get_geometry_reply->height; + free(get_geometry_reply); + + assert(osd->width); + assert(osd->height); + + switch (mode) { + case XCBOSD_SHAPED: { + const xcb_query_extension_reply_t *query_extension_reply = xcb_get_extension_data(osd->connection, &xcb_shape_id); + + if (!query_extension_reply || !query_extension_reply->present) { + xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: XShape extension not available. unscaled overlay disabled.\n")); + goto error2; + } + + unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; + osd->u.shaped.window = xcb_generate_id(osd->connection); + generic_cookie = xcb_create_window_checked(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, + osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, + XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, + window_params); + generic_error = xcb_request_check(osd->connection, generic_cookie); + + if (generic_error != NULL) { + xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating window. unscaled overlay disabled.\n")); + free(generic_error); + goto error_window; + } + + osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); + generic_cookie = xcb_create_pixmap_checked(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); + generic_error = xcb_request_check(osd->connection, generic_cookie); + + if (generic_error != NULL) { + xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating pixmap. unscaled overlay disabled.\n")); + free(generic_error); + goto error_aftermaskbitmap; + } + + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); + osd->gc = xcb_generate_id(osd->connection); + xcb_create_gc(osd->connection, osd->gc, osd->u.shaped.window, 0, NULL); + + osd->u.shaped.mask_gc = xcb_generate_id(osd->connection); + xcb_create_gc(osd->connection, osd->u.shaped.mask_gc, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->white_pixel); + + osd->u.shaped.mask_gc_back = xcb_generate_id(osd->connection); + xcb_create_gc(osd->connection, osd->u.shaped.mask_gc_back, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->black_pixel); + + osd->u.shaped.mapped = 0; + osd->cmap = xcb_generate_id(osd->connection); + xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); + break; + } + case XCBOSD_COLORKEY: + osd->bitmap = xcb_generate_id(osd->connection); + xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); + osd->gc = xcb_generate_id(osd->connection); + xcb_create_gc(osd->connection, osd->gc, osd->window, 0, NULL); + osd->cmap = xcb_generate_id(osd->connection); + xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); + /* FIXME: the expose event doesn't seem to happen? */ + /*XSelectInput (osd->display, osd->window, ExposureMask);*/ + break; + default: + goto error2; + } + + osd->clean = UNDEFINED; + xcbosd_expose(osd); + + xprintf(osd->xine, XINE_VERBOSITY_DEBUG, + _("x11osd: unscaled overlay created (%s mode).\n"), + (mode==XCBOSD_SHAPED) ? "XShape" : "Colorkey" ); + + return osd; + +/* + XFreeGC (osd->display, osd->gc); + XFreeGC (osd->display, osd->mask_gc); + XFreeGC (osd->display, osd->mask_gc_back); +*/ + +error_aftermaskbitmap: + if(mode==XCBOSD_SHAPED) + xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); +error_window: + if(mode==XCBOSD_SHAPED) + xcb_destroy_window(osd->connection, osd->u.shaped.window); +error2: + free (osd); + return NULL; +} + +void xcbosd_colorkey(xcbosd *osd, uint32_t colorkey, vo_scale_t *scaling) +{ + assert (osd); + assert (osd->mode==XCBOSD_COLORKEY); + + osd->u.colorkey.colorkey=colorkey; + osd->u.colorkey.sc=scaling; + osd->clean = UNDEFINED; + xcbosd_clear(osd); + xcbosd_expose(osd); +} + +void xcbosd_destroy(xcbosd *osd) +{ + + assert (osd); + + xcb_free_gc(osd->connection, osd->gc); + xcb_free_pixmap(osd->connection, osd->bitmap); + xcb_free_colormap(osd->connection, osd->cmap); + if(osd->mode==XCBOSD_SHAPED) { + xcb_free_gc(osd->connection, osd->u.shaped.mask_gc); + xcb_free_gc(osd->connection, osd->u.shaped.mask_gc_back); + xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); + xcb_destroy_window(osd->connection, osd->u.shaped.window); + } + + free (osd); +} + +void xcbosd_clear(xcbosd *osd) +{ + int i; + + lprintf("clear (state:%d)\n", osd->clean ); + + if( osd->clean != WIPED ) + switch (osd->mode) { + case XCBOSD_SHAPED: { + xcb_rectangle_t rectangle = { 0, 0, osd->width, osd->height }; + xcb_poly_fill_rectangle(osd->connection, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc_back, 1, &rectangle); + break; + } + case XCBOSD_COLORKEY: + xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &osd->u.colorkey.colorkey); + if(osd->u.colorkey.sc) { + xcb_rectangle_t rectangle = { osd->u.colorkey.sc->output_xoffset, osd->u.colorkey.sc->output_yoffset, + osd->u.colorkey.sc->output_width, osd->u.colorkey.sc->output_height }; + xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); + xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &osd->screen->black_pixel); + + xcb_rectangle_t rects[4]; + int rects_count = 0; + + for( i = 0; i < 4; i++ ) { + if( osd->u.colorkey.sc->border[i].w && osd->u.colorkey.sc->border[i].h ) { + rects[rects_count].x = osd->u.colorkey.sc->border[i].x; + rects[rects_count].y = osd->u.colorkey.sc->border[i].y; + rects[rects_count].width = osd->u.colorkey.sc->border[i].w; + rects[rects_count].height = osd->u.colorkey.sc->border[i].h; + rects_count++; + } + + if (rects_count > 0) + xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, rects_count, rects); + } + } else { + xcb_rectangle_t rectangle = { 0, 0, osd->width, osd->height }; + xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); + } + break; + } + osd->clean = WIPED; +} + +#define TRANSPARENT 0xffffffff + +#define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n))) + +void xcbosd_blend(xcbosd *osd, vo_overlay_t *overlay) +{ + xcb_alloc_color_cookie_t alloc_color_cookie; + xcb_alloc_color_reply_t *alloc_color_reply; + + if (osd->clean==UNDEFINED) + xcbosd_clear(osd); /* Workaround. Colorkey mode needs sc data before the clear. */ + + if (overlay->rle) { + int i, x, y, len, width; + int use_clip_palette, max_palette_colour[2]; + uint32_t palette[2][OVL_PALETTE_SIZE]; + + max_palette_colour[0] = -1; + max_palette_colour[1] = -1; + + for (i=0, x=0, y=0; i<overlay->num_rle; i++) { + len = overlay->rle[i].len; + + while (len > 0) { + use_clip_palette = 0; + if (len > overlay->width) { + width = overlay->width; + len -= overlay->width; + } + else { + width = len; + len = 0; + } + if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { + if ((x < overlay->hili_left) && (x + width - 1 >= overlay->hili_left)) { + width -= overlay->hili_left - x; + len += overlay->hili_left - x; + } + else if (x > overlay->hili_left) { + use_clip_palette = 1; + if (x + width - 1 > overlay->hili_right) { + width -= overlay->hili_right - x; + len += overlay->hili_right - x; + } + } + } + + if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) { + int j; + clut_t *src_clut; + uint8_t *src_trans; + + if (use_clip_palette) { + src_clut = (clut_t *)&overlay->hili_color; + src_trans = (uint8_t *)&overlay->hili_trans; + } + else { + src_clut = (clut_t *)&overlay->color; + src_trans = (uint8_t *)&overlay->trans; + } + for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) { + if (src_trans[j]) { + if (1) { + int red, green, blue; + int y, u, v, r, g, b; + + y = saturate(src_clut[j].y, 16, 235); + u = saturate(src_clut[j].cb, 16, 240); + v = saturate(src_clut[j].cr, 16, 240); + y = (9 * y) / 8; + r = y + (25 * v) / 16 - 218; + red = (65536 * saturate(r, 0, 255)) / 256; + g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136; + green = (65536 * saturate(g, 0, 255)) / 256; + b = y + 2 * u - 274; + blue = (65536 * saturate(b, 0, 255)) / 256; + + alloc_color_cookie = xcb_alloc_color(osd->connection, osd->cmap, red, green, blue); + alloc_color_reply = xcb_alloc_color_reply(osd->connection, alloc_color_cookie, NULL); + + palette[use_clip_palette][j] = alloc_color_reply->pixel; + free(alloc_color_reply); + } + else { + if (src_clut[j].y > 127) { + palette[use_clip_palette][j] = osd->screen->white_pixel; + } + else { + palette[use_clip_palette][j] = osd->screen->black_pixel; + } + } + } + else { + palette[use_clip_palette][j] = TRANSPARENT; + } + } + max_palette_colour[use_clip_palette] = overlay->rle[i].color; + } + + if(palette[use_clip_palette][overlay->rle[i].color] != TRANSPARENT) { + xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &palette[use_clip_palette][overlay->rle[i].color]); + xcb_rectangle_t rectangle = { overlay->x + x, overlay->y + y, width, 1 }; + xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); + if(osd->mode==XCBOSD_SHAPED) + xcb_poly_fill_rectangle(osd->connection, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc, 1, &rectangle); + } + + x += width; + if (x == overlay->width) { + x = 0; + y++; + } + } + } + osd->clean = DRAWN; + } +} + diff --git a/src/video_out/xcbosd.h b/src/video_out/xcbosd.h new file mode 100644 index 000000000..f948c9baf --- /dev/null +++ b/src/video_out/xcbosd.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2003, 2007 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: xcbosd.h,v 1.1 2007/02/15 15:19:33 dgp85 Exp $ + * + * xcbosd.h, use X11 Nonrectangular Window Shape Extension to draw xine OSD + * + * Nov 2003 - Miguel Freitas + * Feb 2007 - ported to xcb by Christoph Pfister + * + * based on ideas and code of + * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) + */ + +#ifndef XCBOSD_H +#define XCBOSD_H + +#include "vo_scale.h" + +typedef struct xcbosd xcbosd; +enum xcbosd_mode {XCBOSD_SHAPED, XCBOSD_COLORKEY}; + +xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode); + +void xcbosd_colorkey(xcbosd *osd, uint32_t colorkey, vo_scale_t *scaling); + +void xcbosd_destroy(xcbosd *osd); + +void xcbosd_expose(xcbosd *osd); + +void xcbosd_resize(xcbosd *osd, int width, int height); + +void xcbosd_drawable_changed(xcbosd *osd, xcb_window_t window); + +void xcbosd_clear(xcbosd *osd); + +void xcbosd_blend(xcbosd *osd, vo_overlay_t *overlay); + +#endif diff --git a/src/xine-engine/.hgignore b/src/xine-engine/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/xine-engine/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index 2b317d2aa..ecd1968f2 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -26,16 +26,16 @@ EXTRA_DIST = lrb.c lrb.h accel_xvmc.h libxine_la_DEPENDENCIES = $(XINEUTILS_LIB) \ $(pthread_dep) $(LIBXINEPOSIX) -libxine_la_LIBADD = $(THREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(ZLIB_LIBS) \ +libxine_la_LIBADD = $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(ZLIB_LIBS) \ -lm $(XINEUTILS_LIB) $(LIBICONV) $(FT2_LIBS) $(FONTCONFIG_LIBS) \ - $(LIBXINEPOSIX) $(RT_LIBS) + $(LIBXINEPOSIX) $(RT_LIBS) $(NET_LIBS) libxine_la_LDFLAGS = \ -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) \ $(def_ldflags) -include_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ +xineinclude_HEADERS = buffer.h metronom.h configfile.h vo_scale.h \ audio_out.h resample.h video_out.h xine_internal.h spu_decoder.h \ video_overlay.h osd.h scratch.h xine_plugin.h xineintl.h \ plugin_catalog.h audio_decoder.h video_decoder.h post.h \ diff --git a/src/xine-engine/alphablend.c b/src/xine-engine/alphablend.c index a0ff6ccf3..9947da365 100644 --- a/src/xine-engine/alphablend.c +++ b/src/xine-engine/alphablend.c @@ -66,7 +66,7 @@ static void mem_blend24(uint8_t *mem, uint8_t r, uint8_t g, uint8_t b, } } -static void mem_blend32(uint8_t *mem, uint8_t *src, uint8_t o, int len) { +static void mem_blend32(uint8_t *mem, const uint8_t *src, uint8_t o, int len) { uint8_t *limit = mem + len*4; while (mem < limit) { *mem = BLEND_BYTE(*mem, src[0], o); diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c index d504d9511..549c19b02 100644 --- a/src/xine-engine/audio_decoder.c +++ b/src/xine-engine/audio_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_decoder.c,v 1.138 2006/09/08 21:11:29 miguelfreitas Exp $ + * $Id: audio_decoder.c,v 1.139 2007/02/20 00:34:57 dgp85 Exp $ * * * functions that implement audio decoding @@ -67,7 +67,7 @@ static void *audio_decoder_loop (void *stream_gen) { if( !replaying_headers ) buf = stream->audio_fifo->get (stream->audio_fifo); - lprintf ("audio_loop: got package pts = %lld, type = %08x\n", buf->pts, buf->type); + lprintf ("audio_loop: got package pts = %"PRId64", type = %08x\n", buf->pts, buf->type); _x_extra_info_merge( stream->audio_decoder_extra_info, buf->extra_info ); stream->audio_decoder_extra_info->seek_count = stream->video_seek_count; diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index ce8cbe536..cd87c2947 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -17,7 +17,7 @@ * along with self program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_out.c,v 1.207 2006/11/04 23:30:14 dsalt Exp $ + * $Id: audio_out.c,v 1.210 2007/04/01 00:52:36 dgp85 Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> @@ -204,36 +204,45 @@ typedef struct { /* private stuff */ ao_driver_t *driver; pthread_mutex_t driver_lock; - int driver_open; - pthread_mutex_t driver_action_lock; /* protects num_driver_actions */ + + uint32_t driver_open:1; + uint32_t audio_loop_running:1; + uint32_t audio_thread_created:1; + uint32_t grab_only:1; /* => do not start thread, frontend will consume samples */ + uint32_t do_resample:1; + uint32_t do_compress:1; + uint32_t do_amp:1; + uint32_t amp_mute:1; + uint32_t do_equ:1; + int num_driver_actions; /* number of threads, that wish to call * functions needing driver_lock */ + pthread_mutex_t driver_action_lock; /* protects num_driver_actions */ + metronom_clock_t *clock; xine_t *xine; xine_list_t *streams; pthread_mutex_t streams_lock; - int audio_loop_running; - int grab_only; /* => do not start thread, frontend will consume samples */ pthread_t audio_thread; - int audio_thread_created; int64_t audio_step; /* pts per 32 768 samples (sample = #bytes/2) */ int32_t frames_per_kpts; /* frames per 1024/90000 sec */ - ao_format_t input, output; /* format conversion done at audio_out.c */ - double frame_rate_factor; - double output_frame_excess; /* used to keep track of 'half' frames */ - int av_sync_method_conf; resample_sync_t resample_sync_info; - int resample_sync_method; /* fix sound card clock drift by resampling */ double resample_sync_factor; /* correct buffer length by this factor * to sync audio hardware to (dxr3) clock */ + int resample_sync_method; /* fix sound card clock drift by resampling */ + + int gap_tolerance; + + ao_format_t input, output; /* format conversion done at audio_out.c */ + double frame_rate_factor; + double output_frame_excess; /* used to keep track of 'half' frames */ + int resample_conf; uint32_t force_rate; /* force audio output rate to this value if non-zero */ - int do_resample; - int gap_tolerance; audio_fifo_t *free_fifo; audio_fifo_t *out_fifo; int64_t last_audio_vpts; @@ -247,22 +256,18 @@ typedef struct { int64_t passthrough_offset; int flush_audio_driver; + int discard_buffers; pthread_mutex_t flush_audio_driver_lock; pthread_cond_t flush_audio_driver_reached; - int discard_buffers; /* some built-in audio filters */ - int do_compress; double compression_factor; /* current compression */ double compression_factor_max; /* user limit on compression */ - int do_amp; - int amp_mute; double amp_factor; /* 10-band equalizer */ - int do_equ; int eq_gain[EQ_BANDS]; int eq_preamp; int eq_i; @@ -1055,9 +1060,7 @@ static void *ao_loop (void *this_gen) { delay = this->driver->delay(this->driver); while (delay < 0 && this->audio_loop_running) { /* Get the audio card into RUNNING state. */ - pthread_mutex_unlock( &this->driver_lock ); ao_fill_gap (this, 10000); /* FIXME, this PTS of 1000 should == period size */ - pthread_mutex_lock( &this->driver_lock ); delay = this->driver->delay(this->driver); } pthread_mutex_unlock( &this->driver_lock ); @@ -1200,7 +1203,7 @@ static void *ao_loop (void *this_gen) { if (this->driver_open) { pthread_mutex_lock( &this->driver_lock ); - result = this->driver->write (this->driver, out_buf->mem, out_buf->num_frames ); + result = this->driver_open ? this->driver->write (this->driver, out_buf->mem, out_buf->num_frames ) : 0; pthread_mutex_unlock( &this->driver_lock ); } else { result = 0; @@ -1762,13 +1765,15 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value this->amp_factor = (double) value / 100.0; - this->do_amp = (this->amp_factor != 1.0); + this->do_amp = (this->amp_factor != 1.0 || this->amp_mute); ret = this->amp_factor*100; break; case AO_PROP_AMP_MUTE: ret = this->amp_mute = value; + + this->do_amp = (this->amp_factor != 1.0 || this->amp_mute); break; case AO_PROP_EQ_30HZ: @@ -1984,6 +1989,7 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, aos_t *this; int i, err; pthread_attr_t pth_attrs; + pthread_mutexattr_t attr; static const char* resample_modes[] = {"auto", "off", "on", NULL}; static const char* av_sync_methods[] = {"metronom feedback", "resample", NULL}; @@ -1994,8 +2000,14 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, this->clock = xine->clock; this->streams = xine_list_new(); + /* warning: driver_lock is a recursive mutex. it must NOT be + * used with neither pthread_cond_wait() or pthread_cond_timedwait() + */ + pthread_mutexattr_init( &attr ); + pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); + pthread_mutex_init( &this->streams_lock, NULL ); - pthread_mutex_init( &this->driver_lock, NULL ); + pthread_mutex_init( &this->driver_lock, &attr ); pthread_mutex_init( &this->driver_action_lock, NULL ); this->ao.open = ao_open; diff --git a/src/xine-engine/broadcaster.c b/src/xine-engine/broadcaster.c index edf52e474..3beacb226 100644 --- a/src/xine-engine/broadcaster.c +++ b/src/xine-engine/broadcaster.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: broadcaster.c,v 1.12 2006/06/20 00:18:44 dgp85 Exp $ + * $Id: broadcaster.c,v 1.15 2007/01/19 01:23:06 dgp85 Exp $ * * broadcaster.c - xine network broadcaster * @@ -305,7 +305,10 @@ static void audio_put_cb (fifo_buffer_t *fifo, buf_element_t *buf, void *this_ge broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) { broadcaster_t *this; - struct sockaddr_in servAddr; + union { + struct sockaddr_in in; + struct sockaddr sa; + } servAddr; int msock, err; msock = socket(PF_INET, SOCK_STREAM, 0); @@ -314,11 +317,11 @@ broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: error opening master socket.\n"); return NULL; } - servAddr.sin_family = AF_INET; - servAddr.sin_addr.s_addr = htonl(INADDR_ANY); - servAddr.sin_port = htons(port); + servAddr.in.sin_family = AF_INET; + servAddr.in.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.in.sin_port = htons(port); - if(bind(msock, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) + if(bind(msock, &servAddr.sa, sizeof(servAddr.in))<0) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: error binding to port %d\n", port); return NULL; diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c index c36e97877..389146dcb 100644 --- a/src/xine-engine/buffer.c +++ b/src/xine-engine/buffer.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer.c,v 1.36 2006/06/20 00:35:07 dgp85 Exp $ + * $Id: buffer.c,v 1.37 2006/12/25 21:59:32 dgp85 Exp $ * * * contents: @@ -64,7 +64,7 @@ static void buffer_pool_free (buf_element_t *element) { this->buffer_pool_num_free++; if (this->buffer_pool_num_free > this->buffer_pool_capacity) { - printf("xine-lib:buffer: Their has been a fatal error: TOO MANY FREE's\n"); + fprintf(stderr, _("xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n")); _x_abort(); } diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index fa8d96388..64fe52a20 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer.h,v 1.159 2006/11/14 14:11:59 dgp85 Exp $ + * $Id: buffer.h,v 1.162 2007/01/14 16:53:37 klan Exp $ * * * contents: @@ -190,6 +190,7 @@ extern "C" { #define BUF_VIDEO_KMVC 0x02600000 #define BUF_VIDEO_FLASHSV 0x02610000 #define BUF_VIDEO_CAVS 0x02620000 +#define BUF_VIDEO_VP6F 0x02630000 /* audio buffer types: (please keep in sync with buffer_types.c) */ @@ -255,6 +256,8 @@ extern "C" { #define BUF_AUDIO_TRUESPEECH 0x03390000 #define BUF_AUDIO_TTA 0x033A0000 #define BUF_AUDIO_SMACKER 0x033B0000 +#define BUF_AUDIO_FLVADPCM 0x033C0000 +#define BUF_AUDIO_WAVPACK 0x033D0000 /* spu buffer types: */ diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index ea8d58842..161ec70a9 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: buffer_types.c,v 1.106 2006/10/02 15:56:06 valtri Exp $ + * $Id: buffer_types.c,v 1.107 2006/12/26 03:18:56 dgp85 Exp $ * * * contents: @@ -1114,6 +1114,13 @@ static audio_db_t audio_db[] = { BUF_AUDIO_MPC, "Musepack" }, +{ + { + 0 + }, + BUF_AUDIO_WAVPACK, + "Wavpack" +}, { { 0 }, 0, "last entry" } }; diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index 21ebfd5be..28b44fd51 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.c,v 1.81 2006/09/26 21:51:11 dgp85 Exp $ + * $Id: configfile.c,v 1.85 2007/02/22 15:49:16 dgp85 Exp $ * * config object (was: file) management - implementation * @@ -491,14 +491,15 @@ static cfg_entry_t *config_register_key (config_values_t *this, return entry; } -static char *config_register_string (config_values_t *this, - const char *key, - const char *def_value, - const char *description, - const char *help, - int exp_level, - xine_config_cb_t changed_cb, - void *cb_data) { +static cfg_entry_t *config_register_string_internal (config_values_t *this, + const char *key, + const char *def_value, + int num_value, + const char *description, + const char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { cfg_entry_t *entry; _x_assert(this); @@ -512,7 +513,7 @@ static char *config_register_string (config_values_t *this, if (entry->type != XINE_CONFIG_TYPE_UNKNOWN) { lprintf("config entry already registered: %s\n", key); pthread_mutex_unlock(&this->config_lock); - return entry->str_value; + return entry; } config_reset_value(entry); @@ -525,13 +526,40 @@ static char *config_register_string (config_values_t *this, else entry->str_value = strdup(def_value); + entry->num_value = num_value; + /* fill out rest of struct */ entry->str_default = strdup(def_value); entry->description = (description) ? strdup(description) : NULL; entry->help = (help) ? strdup(help) : NULL; pthread_mutex_unlock(&this->config_lock); - return entry->str_value; + return entry; +} + +static char *config_register_string (config_values_t *this, + const char *key, + const char *def_value, + const char *description, + const char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return config_register_string_internal (this, key, def_value, 0, description, + help, exp_level, changed_cb, cb_data)->str_value; +} + +static char *config_register_filename (config_values_t *this, + const char *key, + const char *def_value, + int req_type, + const char *description, + const char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return config_register_string_internal (this, key, def_value, req_type, description, + help, exp_level, changed_cb, cb_data)->str_value; } static int config_register_num (config_values_t *this, @@ -661,9 +689,9 @@ static int config_register_range (config_values_t *this, return entry->num_value; } -static int config_parse_enum (const char *str, char **values) { +static int config_parse_enum (const char *str, const char **values) { - char **value; + const char **value; int i; @@ -697,7 +725,8 @@ static int config_register_enum (config_values_t *this, void *cb_data) { cfg_entry_t *entry; - char **value_src, **value_dest; + const char **value_src; + char **value_dest; int value_count; @@ -1184,6 +1213,7 @@ config_values_t *_x_config_init (void) { pthread_mutex_init(&this->config_lock, &attr); this->register_string = config_register_string; + this->register_filename = config_register_filename; this->register_range = config_register_range; this->register_enum = config_register_enum; this->register_num = config_register_num; diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h index 2a98be9f1..859214d1c 100644 --- a/src/xine-engine/configfile.h +++ b/src/xine-engine/configfile.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: configfile.h,v 1.38 2006/09/26 05:19:48 dgp85 Exp $ + * $Id: configfile.h,v 1.42 2007/02/22 15:49:16 dgp85 Exp $ * * config file management * @@ -108,6 +108,16 @@ struct config_values_s { xine_config_cb_t changed_cb, void *cb_data); + char* (*register_filename) (config_values_t *self, + const char *key, + const char *def_value, + int req_type, + const char *description, + const char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data); + int (*register_range) (config_values_t *self, const char *key, int def_value, @@ -153,7 +163,7 @@ struct config_values_s { void (*update_string) (config_values_t *self, const char *key, const char *value); /* small utility function for enum handling */ - int (*parse_enum) (const char *str, char **values); + int (*parse_enum) (const char *str, const char **values); /* * lookup config entries diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c index c6a234ae5..d1bd2bc1d 100644 --- a/src/xine-engine/demux.c +++ b/src/xine-engine/demux.c @@ -20,7 +20,7 @@ * Demuxer helper functions * hide some xine engine details from demuxers and reduce code duplication * - * $Id: demux.c,v 1.64 2006/08/13 23:51:34 miguelfreitas Exp $ + * $Id: demux.c,v 1.66 2007/01/18 23:28:46 dgp85 Exp $ */ @@ -336,7 +336,7 @@ static void *demux_loop (void *stream_gen) { finished_count_video = stream->finished_count_video + 1; pthread_mutex_unlock (&stream->counter_lock); - /* demux_thread_running is zero if demux loop has being stopped by user */ + /* demux_thread_running is zero if demux loop has been stopped by user */ non_user = stream->demux_thread_running; stream->demux_thread_running = 0; @@ -448,7 +448,7 @@ int _x_demux_read_header( input_plugin_t *input, unsigned char *buffer, off_t si return read_size; } -int _x_demux_check_extension (char *mrl, char *extensions){ +int _x_demux_check_extension (const char *mrl, const char *extensions){ char *last_dot, *e, *ext_copy, *ext_work; ext_copy = strdup(extensions); diff --git a/src/xine-engine/input_cache.c b/src/xine-engine/input_cache.c index 33b8b47da..a566e1f84 100644 --- a/src/xine-engine/input_cache.c +++ b/src/xine-engine/input_cache.c @@ -22,7 +22,7 @@ * The goal of this input plugin is to reduce * the number of calls to the real input plugin. * - * $Id: input_cache.c,v 1.12 2006/09/08 06:20:37 tmattern Exp $ + * $Id: input_cache.c,v 1.14 2007/02/20 00:34:57 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -67,7 +67,7 @@ static off_t cache_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { off_t read_len = 0; off_t main_read; - lprintf("cache_plugin_read: len=%lld\n", len); + lprintf("cache_plugin_read: len=%"PRId64"\n", len); this->read_call++; /* optimized for common cases */ @@ -205,7 +205,7 @@ static off_t cache_plugin_seek(input_plugin_t *this_gen, off_t offset, int origi off_t rel_offset; off_t new_buf_pos; - lprintf("offset: %lld, origin: %d\n", offset, origin); + lprintf("offset: %"PRId64", origin: %d\n", offset, origin); this->seek_call++; if( !this->buf_len ) { @@ -236,7 +236,7 @@ static off_t cache_plugin_seek(input_plugin_t *this_gen, off_t offset, int origi } new_buf_pos = (off_t)this->buf_pos + rel_offset; - lprintf("buf_len: %d, rel_offset=%lld, new_buf_pos=%lld\n", + lprintf("buf_len: %d, rel_offset=%"PRId64", new_buf_pos=%"PRId64"\n", this->buf_len, rel_offset, new_buf_pos); if ((new_buf_pos < 0) || (new_buf_pos >= this->buf_len)) { @@ -304,7 +304,7 @@ static uint32_t cache_plugin_get_blocksize(input_plugin_t *this_gen) { return this->main_input_plugin->get_blocksize(this->main_input_plugin); } -static char* cache_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* cache_plugin_get_mrl (input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; return this->main_input_plugin->get_mrl(this->main_input_plugin); diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c index bb6548bc2..d8715fb85 100644 --- a/src/xine-engine/input_rip.c +++ b/src/xine-engine/input_rip.c @@ -29,7 +29,7 @@ * - it's possible speeder saving streams in the xine without playing: * xine stream_mrl#save:file.raw\;noaudio\;novideo * - * $Id: input_rip.c,v 1.31 2006/06/20 00:35:07 dgp85 Exp $ + * $Id: input_rip.c,v 1.34 2007/02/20 00:34:57 dgp85 Exp $ */ /* TODO: @@ -103,7 +103,7 @@ static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; off_t retlen, npreview, nread, nwrite, nread_orig, nread_file; - lprintf("reading %lld bytes (curpos = %lld, savepos = %lld)\n", len, this->curpos, this->savepos); + lprintf("reading %"PRId64" bytes (curpos = %"PRId64", savepos = %"PRId64")\n", len, this->curpos, this->savepos); if (len < 0) return -1; @@ -117,7 +117,7 @@ static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { nread = min_off(this->savepos - this->preview_size, len - npreview); } - lprintf(" => get %lld bytes from preview (%lld bytes)\n", npreview, this->preview_size); + lprintf(" => get %"PRId64" bytes from preview (%"PRId64" bytes)\n", npreview, this->preview_size); memcpy(buf, &this->preview[this->curpos], npreview); } else { @@ -134,7 +134,7 @@ static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { /* re-reading from file */ if (nread_file) { - lprintf(" => read %lld bytes from file\n", nread_file); + lprintf(" => read %"PRId64" bytes from file\n", nread_file); if (fread(&buf[npreview], nread_file, 1, this->file) != 1) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: reading of saved data failed: %s\n"), strerror(errno)); return -1; @@ -143,11 +143,11 @@ static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { /* really to read/catch */ if (nread_orig + nwrite) { - lprintf(" => read %lld bytes from input plugin\n", nread_orig + nwrite); + lprintf(" => read %"PRId64" bytes from input plugin\n", nread_orig + nwrite); /* read from main input plugin */ retlen = this->main_input_plugin->read(this->main_input_plugin, &buf[npreview + nread_file], nread_orig + nwrite); - lprintf("%s => returned %lld" CLR_RST "\n", retlen == nread_orig + nwrite ? "" : CLR_FAIL, retlen); + lprintf("%s => returned %"PRId64"" CLR_RST "\n", retlen == nread_orig + nwrite ? "" : CLR_FAIL, retlen); if (retlen < 0) { xine_log(this->stream->xine, XINE_LOG_MSG, @@ -163,7 +163,7 @@ static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) { return -1; } this->savepos += nwrite; - lprintf(" => saved %lld bytes\n", nwrite); + lprintf(" => saved %"PRId64" bytes\n", nwrite); } else nwrite = 0; } @@ -212,7 +212,7 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe buf_element_t *buf = NULL; off_t retlen, npreview, nread, nwrite, nread_orig, nread_file; - lprintf("reading %lld bytes (curpos = %lld, savepos = %lld) (block)\n", todo, this->curpos, this->savepos); + lprintf("reading %"PRId64" bytes (curpos = %"PRId64", savepos = %"PRId64") (block)\n", todo, this->curpos, this->savepos); if (todo <= 0) return NULL; @@ -226,7 +226,7 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe nread = min_off(this->savepos - this->preview_size, todo - npreview); } - lprintf(" => get %lld bytes from preview (%lld bytes) (block)\n", npreview, this->preview_size); + lprintf(" => get %"PRId64" bytes from preview (%"PRId64" bytes) (block)\n", npreview, this->preview_size); } else { npreview = 0; nread = min_off(this->savepos - this->curpos, todo); @@ -247,13 +247,13 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe /* get data from preview */ if (npreview) { - lprintf(" => get %lld bytes from the preview (block)\n", npreview); + lprintf(" => get %"PRId64" bytes from the preview (block)\n", npreview); memcpy(buf->content, &this->preview[this->curpos], npreview); } /* re-reading from the file */ if (nread_file) { - lprintf(" => read %lld bytes from the file (block)\n", nread_file); + lprintf(" => read %"PRId64" bytes from the file (block)\n", nread_file); if (fread(&buf->content[npreview], nread_file, 1, this->file) != 1) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: reading of saved data failed: %s\n"), @@ -267,10 +267,10 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe if (nread_orig + nwrite) { /* read from main input plugin */ if (buf) { - lprintf(" => read %lld bytes from input plugin (block)\n", nread_orig + nwrite); + lprintf(" => read %"PRId64" bytes from input plugin (block)\n", nread_orig + nwrite); retlen = this->main_input_plugin->read(this->main_input_plugin, &buf->content[npreview + nread_file], nread_orig + nwrite); } else { - lprintf(" => read block of %lld bytes from input plugin (block)\n", nread_orig + nwrite); + lprintf(" => read block of %"PRId64" bytes from input plugin (block)\n", nread_orig + nwrite); buf = this->main_input_plugin->read_block(this->main_input_plugin, fifo, nread_orig + nwrite); if (buf) retlen = buf->size; else { @@ -279,7 +279,7 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe } } if (retlen != nread_orig + nwrite) { - lprintf(CLR_FAIL " => returned %lld" CLR_RST "\n", retlen); + lprintf(CLR_FAIL " => returned %"PRId64"" CLR_RST "\n", retlen); return NULL; } @@ -293,7 +293,7 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe return NULL; } this->savepos += nwrite; - lprintf(" => saved %lld bytes\n", nwrite); + lprintf(" => saved %"PRId64" bytes\n", nwrite); } else nwrite = 0; } @@ -307,7 +307,7 @@ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffe static off_t rip_seek_original(rip_input_plugin_t *this, off_t reqpos) { off_t pos; - lprintf(" => seeking original input plugin to %lld\n", reqpos); + lprintf(" => seeking original input plugin to %"PRId64"\n", reqpos); pos = this->main_input_plugin->seek(this->main_input_plugin, reqpos, SEEK_SET); if (pos == -1) { @@ -316,7 +316,7 @@ static off_t rip_seek_original(rip_input_plugin_t *this, off_t reqpos) { } #ifdef LOG if (pos != reqpos) { - lprintf(CLR_FAIL " => reqested position %lld differs from result position %lld" CLR_RST "\n", reqpos, pos); + lprintf(CLR_FAIL " => reqested position %"PRId64" differs from result position %"PRId64"" CLR_RST "\n", reqpos, pos); } #endif @@ -339,7 +339,7 @@ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) struct timeval time1, time2; double interval = 0; - lprintf("seek, offset %lld, origin %d (curpos %lld, savepos %lld)\n", offset, origin, this->curpos, this->savepos); + lprintf("seek, offset %"PRId64", origin %d (curpos %"PRId64", savepos %"PRId64")\n", offset, origin, this->curpos, this->savepos); switch (origin) { case SEEK_SET: newpos = offset; break; @@ -355,7 +355,7 @@ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) blocksize = 0; if (newpos < this->savepos) { - lprintf(" => virtual seeking from %lld to %lld\n", this->curpos, newpos); + lprintf(" => virtual seeking from %"PRId64" to %"PRId64"\n", this->curpos, newpos); /* don't seek into preview area */ if (this->preview && newpos < this->preview_size) { @@ -366,7 +366,7 @@ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) if (this->regular) { if (reqpos != this->savepos) { - lprintf(" => seeking file to %lld\n", reqpos); + lprintf(" => seeking file to %"PRId64"\n", reqpos); if (fseeko(this->file, reqpos, SEEK_SET) != 0) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed: %s\n"), strerror(errno)); return -1; @@ -382,9 +382,9 @@ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) } if (this->curpos < this->savepos) { - lprintf(" => seeking to end: %lld\n", this->savepos); + lprintf(" => seeking to end: %"PRId64"\n", this->savepos); if (this->regular) { - lprintf(" => seeking file to end: %lld\n", this->savepos); + lprintf(" => seeking file to end: %"PRId64"\n", this->savepos); if (fseeko(this->file, this->savepos, SEEK_SET) != 0) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed: %s\n"), strerror(errno)); return -1; @@ -425,11 +425,19 @@ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) + (double)(time2.tv_usec - time1.tv_usec) / 1000000; } - lprintf(" => new position %lld\n", this->curpos); + lprintf(" => new position %"PRId64"\n", this->curpos); return this->curpos; } +static off_t rip_plugin_seek_time(input_plugin_t *this_gen, int time_offset, int origin) { + rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; + + lprintf("seek_time, time_offset: %d, origin: %d\n", time_offset, origin); + + return this->main_input_plugin->seek_time(this->main_input_plugin, time_offset, origin); +} + /* * return current position, * check values for debug build @@ -441,13 +449,19 @@ static off_t rip_plugin_get_current_pos(input_plugin_t *this_gen) { pos = this->main_input_plugin->get_current_pos(this->main_input_plugin); if (pos != this->curpos) { - lprintf(CLR_FAIL "position: computed = %lld, input plugin = %lld" CLR_RST "\n", this->curpos, pos); + lprintf(CLR_FAIL "position: computed = %"PRId64", input plugin = %"PRId64"" CLR_RST "\n", this->curpos, pos); } #endif return this->curpos; } +static int rip_plugin_get_current_time(input_plugin_t *this_gen) { + rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; + + return this->main_input_plugin->get_current_time(this->main_input_plugin); +} + static off_t rip_plugin_get_length (input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; off_t length; @@ -465,7 +479,7 @@ static uint32_t rip_plugin_get_blocksize(input_plugin_t *this_gen) { return this->main_input_plugin->get_blocksize(this->main_input_plugin); } -static char* rip_plugin_get_mrl (input_plugin_t *this_gen) { +static const char* rip_plugin_get_mrl (input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; return this->main_input_plugin->get_mrl(this->main_input_plugin); @@ -646,7 +660,7 @@ input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *f free(this); return NULL; } - lprintf(" => saved %lld bytes (preview)\n", this->preview_size); + lprintf(" => saved %"PRId64" bytes (preview)\n", this->preview_size); this->savepos = this->preview_size; } @@ -655,7 +669,11 @@ input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *f this->input_plugin.read = rip_plugin_read; this->input_plugin.read_block = rip_plugin_read_block; this->input_plugin.seek = rip_plugin_seek; + if(this->main_input_plugin->seek_time) + this->input_plugin.seek_time = rip_plugin_seek_time; this->input_plugin.get_current_pos = rip_plugin_get_current_pos; + if(this->main_input_plugin->get_current_time) + this->input_plugin.get_current_time = rip_plugin_get_current_time; this->input_plugin.get_length = rip_plugin_get_length; this->input_plugin.get_blocksize = rip_plugin_get_blocksize; this->input_plugin.get_mrl = rip_plugin_get_mrl; diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 62f4705fa..d35eba736 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: load_plugins.c,v 1.228 2006/11/23 21:05:31 klan Exp $ + * $Id: load_plugins.c,v 1.230 2007/02/19 23:33:33 dgp85 Exp $ * * * Load input/demux/audio_out/video_out/codec plugins @@ -1989,18 +1989,19 @@ int _x_decoder_available (xine_t *xine, uint32_t buftype) return 0; } - #ifdef LOG static void _display_file_plugin_list (xine_list_t *list, plugin_file_t *file) { - plugin_node_t *node; + xine_list_iterator_t ite = xine_list_front(list); + + while (ite) { + plugin_node_t *node = xine_list_get_value(list, ite); - node = xine_list_first_content(list); - while (node) { if ((node->file == file) && (node->ref)) { printf(" plugin: %s, class: %p , %d instance(s)\n", node->info->id, node->plugin_class, node->ref); } - node = xine_list_next_content(list); + + ite = xine_list_next(list, ite); } } #endif @@ -2375,14 +2376,14 @@ char *xine_get_file_extensions (xine_t *self) { list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - char *exts; + const char *exts; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class(self, node, NULL)) { cls = (demux_class_t *)node->plugin_class; - if((exts = cls->get_extensions(cls)) && strlen(exts)) + if((exts = cls->get_extensions(cls)) && *exts) len += strlen(exts) + 1; } } @@ -2394,7 +2395,7 @@ char *xine_get_file_extensions (xine_t *self) { list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - char *e; + const char *e; int l; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); @@ -2402,7 +2403,7 @@ char *xine_get_file_extensions (xine_t *self) { cls = (demux_class_t *)node->plugin_class; - if((e = cls->get_extensions (cls)) && strlen(e)) { + if((e = cls->get_extensions (cls)) && *e) { l = strlen(e); memcpy (&str[pos], e, l); @@ -2444,7 +2445,7 @@ char *xine_get_mime_types (xine_t *self) { for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - char *s; + const char *s; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class(self, node, NULL)) { @@ -2466,7 +2467,7 @@ char *xine_get_mime_types (xine_t *self) { for (list_id = 0; list_id < list_size; list_id++) { demux_class_t *cls; - char *s; + const char *s; int l; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); @@ -2503,6 +2504,7 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) { char *id = NULL; char *mime_arg, *mime_demux; char *s; + const char *mt; int list_id, list_size; /* create a copy and convert to lower case */ @@ -2522,9 +2524,9 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) { cls = (demux_class_t *)node->plugin_class; - s = cls->get_mimetypes (cls); - if (s) { - mime_demux = strdup(s); + mt = cls->get_mimetypes (cls); + if (mt) { + mime_demux = strdup(mt); for(s=mime_demux; *s; s++) *s = tolower(*s); diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c index 809204af9..fa33da9e1 100644 --- a/src/xine-engine/metronom.c +++ b/src/xine-engine/metronom.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: metronom.c,v 1.143 2006/01/27 22:35:07 dsalt Exp $ + * $Id: metronom.c,v 1.144 2007/02/20 00:34:57 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -524,7 +524,7 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) { img->vpts = this->video_vpts + this->av_offset; if (this->video_mode == VIDEO_PREDICTION_MODE) { - lprintf("video vpts for %10lld : %10lld (duration:%d drift:%" PRId64 " step:%" PRId64 ")\n", + lprintf("video vpts for %10"PRId64" : %10"PRId64" (duration:%d drift:%" PRId64 " step:%" PRId64 ")\n", pts, this->video_vpts, img->duration, this->video_drift, this->video_drift_step ); if (this->video_drift * this->video_drift_step > 0) { @@ -681,7 +681,7 @@ static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts, this->audio_samples += nsamples; this->vpts_offset += nsamples * this->audio_drift_step / AUDIO_SAMPLE_NUM; - lprintf("audio vpts for %10lld : %10lld\n", pts, vpts); + lprintf("audio vpts for %10"PRId64" : %10"PRId64"\n", pts, vpts); pthread_mutex_unlock (&this->lock); diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index b5f45d0af..b33d81f6e 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -102,6 +102,12 @@ # define KERNING_DEFAULT ft_kerning_default #endif +#ifdef ENABLE_ANTIALIASING +# define FT_LOAD_FLAGS FT_LOAD_DEFAULT +#else +# define FT_LOAD_FLAGS (FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING) +#endif + typedef struct osd_fontchar_s { uint16_t code; uint16_t width; @@ -194,7 +200,7 @@ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { int x, y, required; uint8_t *c; - lprintf("osd=%p vpts=%lld\n", osd, vpts); + lprintf("osd=%p vpts=%"PRId64"\n", osd, vpts); this->stream->xine->port_ticket->acquire(this->stream->xine->port_ticket, 1); @@ -341,7 +347,7 @@ static int _osd_hide (osd_object_t *osd, int64_t vpts) { osd_renderer_t *this = osd->renderer; video_overlay_manager_t *ovl_manager; - lprintf("osd=%p vpts=%lld\n",osd, vpts); + lprintf("osd=%p vpts=%"PRId64"\n",osd, vpts); if( osd->handle < 0 ) return 0; @@ -1171,7 +1177,7 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, } previous = i; - if (FT_Load_Glyph(osd->ft2->face, i, FT_LOAD_DEFAULT)) { + if (FT_Load_Glyph(osd->ft2->face, i, FT_LOAD_FLAGS)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("osd: error loading glyph\n")); continue; } @@ -1475,7 +1481,16 @@ static void osd_free_object (osd_object_t *osd_to_close) { while( osd ) { if ( osd == osd_to_close ) { free( osd->area ); - if( osd->ft2 ) free( osd->ft2 ); + +#ifdef HAVE_FT2 + if( osd->ft2 ) { + if ( osd->ft2->library ) + FT_Done_FreeType(osd->ft2->library); + + free( osd->ft2 ); + } +#endif + osd_free_encoding(osd); if( last ) diff --git a/src/xine-engine/post.h b/src/xine-engine/post.h index f8aba5cef..bcdc3c54b 100644 --- a/src/xine-engine/post.h +++ b/src/xine-engine/post.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: post.h,v 1.23 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: post.h,v 1.26 2007/02/20 01:13:08 dgp85 Exp $ * * post plugin definitions * @@ -259,7 +259,7 @@ void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) XINE_PROTECTED; /* when you shortcut a frames usual draw() travel so that it will never reach * the draw() function of the original issuer, you still have to do some * housekeeping on the frame, before returning control up the pipe */ -void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream); +void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) XINE_PROTECTED; /* use this to create a new, trivially decorated overlay manager in which * port functions can be replaced with own implementations */ @@ -380,7 +380,7 @@ static xine_post_api_parameter_t temp_p[] = { #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ { param_type, #var, sizeof(temp_s.var), \ - (char *)&temp_s.var-(char *)&temp_s, enumv, min, max, readonly, descr }, + (char*)&temp_s.var-(char*)&temp_s, enumv, min, max, readonly, descr }, #define END_PARAM_DESCR( name ) \ { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c index eac5eee63..67281b041 100644 --- a/src/xine-engine/scratch.c +++ b/src/xine-engine/scratch.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: scratch.c,v 1.22 2006/10/18 18:46:17 hadess Exp $ + * $Id: scratch.c,v 1.24 2007/01/19 00:12:22 dgp85 Exp $ * * top-level xine functions * @@ -47,6 +47,8 @@ static void __attribute__((__format__(__printf__, 2, 0))) struct tm tm; size_t l; + pthread_mutex_lock (&this->lock); + time (&t); localtime_r (&t, &tm); @@ -61,37 +63,46 @@ static void __attribute__((__format__(__printf__, 2, 0))) lprintf ("printing format %s to line %d\n", format, this->cur); this->cur = (this->cur + 1) % this->num_lines; + + pthread_mutex_unlock (&this->lock); } -static const char **scratch_get_content (scratch_buffer_t *this) { +static char **scratch_get_content (scratch_buffer_t *this) { int i, j; + pthread_mutex_lock (&this->lock); + for(i = 0, j = (this->cur - 1); i < this->num_lines; i++, j--) { if(j < 0) j = (this->num_lines - 1); - this->ordered[i] = this->lines[j]; + free (this->ordered[i]); + this->ordered[i] = this->lines[j] ? strdup (this->lines[j]) : NULL; lprintf ("line %d contains >%s<\n", i , this->lines[j]); } + pthread_mutex_unlock (&this->lock); return this->ordered; } static void scratch_dispose (scratch_buffer_t *this) { - char *mem; int i; - mem = (char *) this->lines[0]; - + pthread_mutex_lock (&this->lock); + for(i = 0; i < this->num_lines; i++ ) { + free(this->ordered[i]); free(this->lines[i]); - this->lines[i] = NULL; } free (this->lines); free (this->ordered); + + pthread_mutex_unlock (&this->lock); + pthread_mutex_destroy (&this->lock); + free (this); } @@ -104,16 +115,15 @@ scratch_buffer_t *_x_new_scratch_buffer (int num_lines) { this->lines = xine_xmalloc (sizeof (char *) * (num_lines + 1)); this->ordered = xine_xmalloc (sizeof (char *) * (num_lines + 1)); - for (i = 0; i < num_lines; i++) - this->lines[i] = NULL; + for (i = 0; i <= num_lines; i++) + this->lines[i] = this->ordered[i] = NULL; - this->ordered[i] = NULL; - this->lines[i] = NULL; this->scratch_printf = scratch_printf; this->get_content = scratch_get_content; this->dispose = scratch_dispose; this->num_lines = num_lines; this->cur = 0; + pthread_mutex_init (&this->lock, NULL); return this; } diff --git a/src/xine-engine/scratch.h b/src/xine-engine/scratch.h index d23d68503..bcfe815c3 100644 --- a/src/xine-engine/scratch.h +++ b/src/xine-engine/scratch.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: scratch.h,v 1.11 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: scratch.h,v 1.13 2007/01/19 00:12:22 dgp85 Exp $ * * scratch buffer for log output * @@ -27,6 +27,7 @@ #define HAVE_SCRATCH_H #include <stdarg.h> +#include <pthread.h> typedef struct scratch_buffer_s scratch_buffer_t; @@ -40,16 +41,17 @@ struct scratch_buffer_s { #endif (*scratch_printf) (scratch_buffer_t *this, const char *format, va_list ap); - const char **(*get_content) (scratch_buffer_t *this); + char **(*get_content) (scratch_buffer_t *this); void (*dispose) (scratch_buffer_t *this); char **lines; - const char **ordered; + char **ordered; int num_lines; int cur; + pthread_mutex_t lock; }; scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_PROTECTED; diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 16ebb61b2..fee75ec76 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_decoder.c,v 1.161 2006/09/08 21:11:29 miguelfreitas Exp $ + * $Id: video_decoder.c,v 1.163 2007/02/20 00:34:58 dgp85 Exp $ * */ @@ -193,8 +193,13 @@ static void *video_decoder_loop (void *stream_gen) { /* * wait the output fifos to run dry before sending the notification event - * to the frontend. this test is only valid if there is only a single - * stream attached to the current output port. + * to the frontend. exceptions: + * 1) don't wait if there is more than one stream attached to the current + * output port (the other stream might be sending data so we would be + * here forever) + * 2) early_finish_event: send notification asap to allow gapless switch + * 3) slave stream: don't wait. get into an unblocked state asap to allow + * new master actions. */ while(1) { int num_bufs, num_streams; @@ -204,7 +209,8 @@ static void *video_decoder_loop (void *stream_gen) { num_streams = stream->video_out->get_property(stream->video_out, VO_PROP_NUM_STREAMS); running_ticket->release(running_ticket, 0); - if( num_bufs > 0 && num_streams == 1 && !stream->early_finish_event ) + if( num_bufs > 0 && num_streams == 1 && !stream->early_finish_event && + stream->master == stream ) xine_usec_sleep (10000); else break; @@ -302,7 +308,7 @@ static void *video_decoder_loop (void *stream_gen) { break; case BUF_CONTROL_NEWPTS: - lprintf ("new pts %lld\n", buf->disc_off); + lprintf ("new pts %"PRId64"\n", buf->disc_off); if (stream->video_decoder_plugin) { running_ticket->acquire(running_ticket, 0); diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c index 19d635d76..2a3ee1980 100644 --- a/src/xine-engine/video_out.c +++ b/src/xine-engine/video_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out.c,v 1.225 2006/03/25 01:26:34 dsalt Exp $ + * $Id: video_out.c,v 1.228 2007/04/01 01:03:06 dgp85 Exp $ * * frame allocation / queuing / scheduling / output functions */ @@ -93,11 +93,20 @@ typedef struct { vo_frame_t *last_frame; vo_frame_t *img_backup; - int redraw_needed; + + uint32_t video_loop_running:1; + uint32_t video_opened:1; + + uint32_t overlay_enabled:1; + + uint32_t warn_threshold_event_sent:1; + + /* do we true real-time output or is this a grab only instance ? */ + uint32_t grab_only:1; + + uint32_t redraw_needed:3; int discard_frames; - int video_loop_running; - int video_opened; pthread_t video_thread; int num_frames_delivered; @@ -108,17 +117,12 @@ typedef struct { int warn_skipped_threshold; int warn_discarded_threshold; int warn_threshold_exceeded; - int warn_threshold_event_sent; /* pts value when decoder delivered last video frame */ int64_t last_delivery_pts; video_overlay_manager_t *overlay_source; - int overlay_enabled; - - /* do we true real-time output or is this a grab only instance ? */ - int grab_only; extra_info_t *extra_info_base; /* used to free mem chunk */ @@ -600,7 +604,7 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) { */ send_event = (this->warn_threshold_exceeded == 5 && !this->warn_threshold_event_sent); - this->warn_threshold_event_sent += send_event; + this->warn_threshold_event_sent = send_event; pthread_mutex_lock(&this->streams_lock); for (ite = xine_list_front(this->streams); ite; @@ -1195,7 +1199,7 @@ static void *video_out_loop (void *this_gen) { if (this->clock->speed == XINE_SPEED_PAUSE) paused_loop (this, vpts); - if (next_frame_vpts) { + if (next_frame_vpts && this->clock->speed > 0) { usec_to_sleep = (next_frame_vpts - vpts) * 100 * XINE_FINE_SPEED_NORMAL / (9 * this->clock->speed); } else { /* we don't know when the next frame is due, only wait a little */ @@ -1783,11 +1787,23 @@ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabon this->frame_drop_limit = 3; this->frame_drop_cpt = 0; - num_frame_buffers = driver->get_property (driver, VO_PROP_MAX_NUM_FRAMES); - - if (!num_frame_buffers) - num_frame_buffers = NUM_FRAME_BUFFERS; /* default */ - else if (num_frame_buffers<5) + /* default number of video frames from config */ + num_frame_buffers = xine->config->register_num (xine->config, + "engine.buffers.video_num_frames", + NUM_FRAME_BUFFERS, /* default */ + _("default number of video frames"), + _("The default number of video frames to request " + "from xine video out driver. Some drivers will " + "override this setting with their own values."), + 20, NULL, NULL); + + /* check driver's limit and use the smaller value */ + i = driver->get_property (driver, VO_PROP_MAX_NUM_FRAMES); + if (i && i < num_frame_buffers) + num_frame_buffers = i; + + /* we need at least 5 frames */ + if (num_frame_buffers<5) num_frame_buffers = 5; this->extra_info_base = calloc (num_frame_buffers, diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 78476a768..f49a988c9 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.c,v 1.335 2006/10/16 22:18:24 valtri Exp $ + * $Id: xine.c,v 1.342 2007/02/20 00:37:02 dgp85 Exp $ */ /* @@ -78,6 +78,10 @@ #endif /* WIN32 */ +static void mutex_cleanup (void *mutex) { + pthread_mutex_unlock ((pthread_mutex_t *) mutex); +} + void _x_handle_stream_end (xine_stream_t *stream, int non_user) { if (stream->status == XINE_STATUS_QUIT) @@ -294,6 +298,7 @@ static void stop_internal (xine_stream_t *stream) { void xine_stop (xine_stream_t *stream) { pthread_mutex_lock (&stream->frontend_lock); + pthread_cleanup_push (mutex_cleanup, (void *) &stream->frontend_lock); /* make sure that other threads cannot change the speed, especially pauseing the stream */ pthread_mutex_lock(&stream->speed_change_lock); @@ -320,6 +325,7 @@ void xine_stop (xine_stream_t *stream) { stream->xine->port_ticket->release(stream->xine->port_ticket, 1); stream->ignore_speed_change = 0; + pthread_cleanup_pop (0); pthread_mutex_unlock (&stream->frontend_lock); } @@ -395,6 +401,7 @@ static void close_internal (xine_stream_t *stream) { void xine_close (xine_stream_t *stream) { pthread_mutex_lock (&stream->frontend_lock); + pthread_cleanup_push (mutex_cleanup, (void *) &stream->frontend_lock); close_internal (stream); @@ -408,6 +415,7 @@ void xine_close (xine_stream_t *stream) { if (stream->status != XINE_STATUS_QUIT) stream->status = XINE_STATUS_IDLE; + pthread_cleanup_pop (0); pthread_mutex_unlock (&stream->frontend_lock); } @@ -1131,11 +1139,13 @@ int xine_open (xine_stream_t *stream, const char *mrl) { int ret; pthread_mutex_lock (&stream->frontend_lock); + pthread_cleanup_push (mutex_cleanup, (void *) &stream->frontend_lock); lprintf ("open MRL:%s\n", mrl); ret = open_internal (stream, mrl); + pthread_cleanup_pop (0); pthread_mutex_unlock (&stream->frontend_lock); return ret; @@ -1263,6 +1273,7 @@ int xine_play (xine_stream_t *stream, int start_pos, int start_time) { int ret; pthread_mutex_lock (&stream->frontend_lock); + pthread_cleanup_push (mutex_cleanup, (void *) &stream->frontend_lock); stream->delay_finish_event = 0; @@ -1272,6 +1283,7 @@ int xine_play (xine_stream_t *stream, int start_pos, int start_time) { stream->gapless_switch = 0; + pthread_cleanup_pop (0); pthread_mutex_unlock (&stream->frontend_lock); return ret; @@ -1285,6 +1297,7 @@ int xine_eject (xine_stream_t *stream) { return 0; pthread_mutex_lock (&stream->frontend_lock); + pthread_cleanup_push (mutex_cleanup, (void *) &stream->frontend_lock); status = 0; /* only eject, if we are stopped OR a different input plugin is playing */ @@ -1295,7 +1308,9 @@ int xine_eject (xine_stream_t *stream) { status = stream->eject_class->eject_media (stream->eject_class); } + pthread_cleanup_pop (0); pthread_mutex_unlock (&stream->frontend_lock); + return status; } @@ -1520,8 +1535,8 @@ static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { } void xine_init (xine_t *this) { - static char *demux_strategies[] = {"default", "reverse", "content", - "extension", NULL}; + static const char *demux_strategies[] = {"default", "reverse", "content", + "extension", NULL}; /* initialize color conversion tables and functions */ init_yuv_conversion(); @@ -1561,9 +1576,9 @@ void xine_init (xine_t *this) { /* * save directory */ - this->save_path = this->config->register_string ( + this->save_path = this->config->register_filename ( this->config, - "media.capture.save_dir", "", + "media.capture.save_dir", "", XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("directory for saving streams"), _("When using the stream save feature, files will be written only into this directory.\n" "This setting is security critical, because when changed to a different directory, xine " @@ -1604,9 +1619,10 @@ void xine_init (xine_t *this) { this->streams = xine_list_new(); /* - * streams lock + * locks */ pthread_mutex_init (&this->streams_lock, NULL); + pthread_mutex_init (&this->log_lock, NULL); /* * start metronom clock @@ -1951,12 +1967,21 @@ const char *const *xine_get_log_names (xine_t *this) { return log_sections; } +static inline void check_log_alloc (xine_t *this, int buf) +{ + pthread_mutex_lock (&this->log_lock); + + if ( ! this->log_buffers[buf] ) + this->log_buffers[buf] = _x_new_scratch_buffer(150); + + pthread_mutex_unlock (&this->log_lock); +} + void xine_log (xine_t *this, int buf, const char *format, ...) { va_list argp; char buffer[SCRATCH_LINE_LEN_MAX]; - if ( ! this->log_buffers[buf] ) - this->log_buffers[buf] = _x_new_scratch_buffer(150); + check_log_alloc (this, buf); va_start (argp, format); this->log_buffers[buf]->scratch_printf (this->log_buffers[buf], format, argp); @@ -1973,13 +1998,12 @@ void xine_log (xine_t *this, int buf, const char *format, ...) { void xine_vlog(xine_t *this, int buf, const char *format, va_list args) { - if ( ! this->log_buffers[buf] ) - this->log_buffers[buf] = _x_new_scratch_buffer(150); + check_log_alloc (this, buf); this->log_buffers[buf]->scratch_printf(this->log_buffers[buf], format, args); } -const char *const *xine_get_log (xine_t *this, int buf) { +char *const *xine_get_log (xine_t *this, int buf) { if(buf >= XINE_LOG_NUM) return NULL; diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c index d0dc0e4a5..e58d9ed61 100644 --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_interface.c,v 1.99 2006/10/16 06:29:38 dgp85 Exp $ + * $Id: xine_interface.c,v 1.104 2007/03/26 11:48:01 dgp85 Exp $ * * convenience/abstraction layer, functions to implement * libxine's public interface @@ -100,7 +100,23 @@ const char* xine_config_register_string (xine_t *self, cb_data); } + +const char* xine_config_register_filename (xine_t *self, + const char *key, + const char *def_value, + int req_type, + const char *description, + const char *help, + int exp_level, + xine_config_cb_t changed_cb, + void *cb_data) { + return self->config->register_filename (self->config, + key, def_value, req_type, + description, help, exp_level, + changed_cb, cb_data); +} + int xine_config_register_range (xine_t *self, const char *key, int def_value, @@ -325,6 +341,24 @@ int xine_port_send_gui_data (xine_video_port_t *vo, type, data); } +static void send_audio_amp_event_internal(xine_stream_t *stream) +{ + xine_event_t event; + xine_audio_level_data_t data; + + data.left + = data.right + = stream->audio_out->get_property (stream->audio_out, AO_PROP_AMP); + data.mute + = stream->audio_out->get_property (stream->audio_out, AO_PROP_AMP_MUTE); + + event.type = XINE_EVENT_AUDIO_AMP_LEVEL; + event.data = &data; + event.data_length = sizeof (data); + + xine_event_send(stream, &event); +} + void xine_set_param (xine_stream_t *stream, int param, int value) { /* Avoid crashing */ if ( ! stream ) { @@ -396,15 +430,21 @@ void xine_set_param (xine_stream_t *stream, int param, int value) { case XINE_PARAM_AUDIO_AMP_LEVEL: stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0); - if (stream->audio_out) - stream->audio_out->set_property (stream->audio_out, AO_PROP_AMP, value); + if (stream->audio_out) { + int old_value = stream->audio_out->get_property (stream->audio_out, AO_PROP_AMP); + if (old_value != stream->audio_out->set_property (stream->audio_out, AO_PROP_AMP, value)) + send_audio_amp_event_internal(stream); + } stream->xine->port_ticket->release(stream->xine->port_ticket, 0); break; case XINE_PARAM_AUDIO_AMP_MUTE: stream->xine->port_ticket->acquire(stream->xine->port_ticket, 0); - if (stream->audio_out) - stream->audio_out->set_property (stream->audio_out, AO_PROP_AMP_MUTE, value); + if (stream->audio_out) { + int old_value = stream->audio_out->get_property (stream->audio_out, AO_PROP_AMP_MUTE); + if (old_value != stream->audio_out->set_property (stream->audio_out, AO_PROP_AMP_MUTE, value)) + send_audio_amp_event_internal(stream); + } stream->xine->port_ticket->release(stream->xine->port_ticket, 0); break; @@ -913,7 +953,7 @@ int _x_message(xine_stream_t *stream, int type, ...) { va_list ap; char *s, *params; char *args[1025]; - static char *std_explanation[] = { + static const char *std_explanation[] = { "", N_("Warning:"), N_("Unknown host:"), diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 8ee5d8219..30899a4b3 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_internal.h,v 1.179 2006/10/02 15:56:06 valtri Exp $ + * $Id: xine_internal.h,v 1.181 2007/01/18 23:28:46 dgp85 Exp $ * */ @@ -118,6 +118,7 @@ struct xine_s { #ifdef XINE_ENGINE_INTERNAL xine_ticket_t *port_ticket; + pthread_mutex_t log_lock; #endif }; @@ -415,7 +416,7 @@ void _x_demux_control_end (xine_stream_t *stream, uint32_t flags) XINE_ int _x_demux_start_thread (xine_stream_t *stream) XINE_PROTECTED; int _x_demux_stop_thread (xine_stream_t *stream) XINE_PROTECTED; int _x_demux_read_header (input_plugin_t *input, unsigned char *buffer, off_t size) XINE_PROTECTED; -int _x_demux_check_extension (char *mrl, char *extensions) XINE_PROTECTED; +int _x_demux_check_extension (const char *mrl, const char *extensions) XINE_PROTECTED; off_t _x_read_abort (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; diff --git a/src/xine-engine/xine_plugin.h b/src/xine-engine/xine_plugin.h index f55c5be63..4ddb65eda 100644 --- a/src/xine-engine/xine_plugin.h +++ b/src/xine-engine/xine_plugin.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_plugin.h,v 1.21 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: xine_plugin.h,v 1.23 2007/01/19 02:49:31 dgp85 Exp $ * * generic plugin definitions * @@ -73,7 +73,7 @@ typedef struct { /* special_info for a decoder plugin */ typedef struct { - uint32_t *supported_types; /* streamtypes this decoder can handle */ + uint32_t *supported_types; /* streamtypes this decoder can handle */ int priority; } decoder_info_t; diff --git a/src/xine-utils/.hgignore b/src/xine-utils/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/xine-utils/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la diff --git a/src/xine-utils/Makefile.am b/src/xine-utils/Makefile.am index 7406abf86..95de06b9e 100644 --- a/src/xine-utils/Makefile.am +++ b/src/xine-utils/Makefile.am @@ -32,7 +32,7 @@ libxineutils_la_SOURCES = $(pppc_files) \ pool.c \ ring_buffer.c -include_HEADERS = \ +xineinclude_HEADERS = \ attributes.h \ compat.h \ xine_buffer.h \ diff --git a/src/xine-utils/array.c b/src/xine-utils/array.c index 4fcecbb4b..ed529515b 100644 --- a/src/xine-utils/array.c +++ b/src/xine-utils/array.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: array.c,v 1.3 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: array.c,v 1.4 2007/02/03 16:31:55 dsalt Exp $ * */ #ifdef HAVE_CONFIG_H @@ -78,7 +78,7 @@ void xine_array_delete(xine_array_t *array) { free(array); } -size_t xine_array_size(xine_array_t *array) { +size_t xine_array_size(const xine_array_t *array) { return array->size; } @@ -116,7 +116,7 @@ void xine_array_remove(xine_array_t *array, unsigned int position) { } } -void *xine_array_get(xine_array_t *array, unsigned int position) { +void *xine_array_get(const xine_array_t *array, unsigned int position) { if (position < array->size) return array->chunk[position]; else diff --git a/src/xine-utils/array.h b/src/xine-utils/array.h index 45fc7b137..80b7d3c9b 100644 --- a/src/xine-utils/array.h +++ b/src/xine-utils/array.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: array.h,v 1.2 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: array.h,v 1.3 2007/02/03 16:31:55 dsalt Exp $ * * Array that can grow automatically when you add elements. * Inserting an element in the middle of the array implies memory moves. @@ -35,7 +35,7 @@ xine_array_t *xine_array_new(size_t initial_size) XINE_PROTECTED; void xine_array_delete(xine_array_t *array) XINE_PROTECTED; /* Returns the number of element stored in the array */ -size_t xine_array_size(xine_array_t *array) XINE_PROTECTED; +size_t xine_array_size(const xine_array_t *array) XINE_PROTECTED; /* Removes all elements from an array */ void xine_array_clear(xine_array_t *array) XINE_PROTECTED; @@ -50,7 +50,7 @@ void xine_array_insert(xine_array_t *array, unsigned int position, void *value) void xine_array_remove(xine_array_t *array, unsigned int position) XINE_PROTECTED; /* Get the element at the position specified */ -void *xine_array_get(xine_array_t *array, unsigned int position) XINE_PROTECTED; +void *xine_array_get(const xine_array_t *array, unsigned int position) XINE_PROTECTED; /* Set the element at the position specified */ void xine_array_set(xine_array_t *array, unsigned int position, void *value) XINE_PROTECTED; diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h index dd70d4309..4d22226ac 100644 --- a/src/xine-utils/attributes.h +++ b/src/xine-utils/attributes.h @@ -47,8 +47,10 @@ #endif /* Export protected only for libxine functions */ -#if defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY) +#if defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_PROTECTED) # define XINE_PROTECTED __attribute__((visibility("protected"))) +#elif defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT) +# define XINE_PROTECTED __attribute__((visibility("default"))) #else # define XINE_PROTECTED #endif @@ -59,4 +61,12 @@ # define XINE_SENTINEL #endif +#ifndef __attr_unused +# ifdef SUPPORT_ATTRIBUTE_UNUSED +# define __attr_unused __attribute__((unused)) +# else +# define __attr_unused +# endif +#endif + #endif /* ATTRIBUTE_H_ */ diff --git a/src/xine-utils/list.h b/src/xine-utils/list.h index 9b9506a84..8273d30f1 100644 --- a/src/xine-utils/list.h +++ b/src/xine-utils/list.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: list.h,v 1.4 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: list.h,v 1.5 2007/02/19 23:34:32 dgp85 Exp $ * * Doubly-linked linked list. * @@ -33,7 +33,7 @@ * xine_list_iterator_t ite = xine_list_front(list); * while (ite) { * _useful code here_ - * ite = xine_list_iterator_next(ite); + * ite = xine_list_next(list, ite); * } * * The list elements are managed using memory chunks and a free list. The first diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c index 15301f108..539f4c8dd 100644 --- a/src/xine-utils/memcpy.c +++ b/src/xine-utils/memcpy.c @@ -461,7 +461,7 @@ void xine_probe_fast_memcpy(xine_t *xine) char *buf1, *buf2; int i, j, best; int config_flags = -1; - static char *memcpy_methods[] = { + static const char *memcpy_methods[] = { "probe", "libc", #if (defined(ARCH_X86) || defined(ARCH_X86_64)) && !defined(_MSC_VER) "kernel", "mmx", "mmxext", "sse", diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index 15f771da0..03c5f689a 100644 --- a/src/xine-utils/xineutils.h +++ b/src/xine-utils/xineutils.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xineutils.h,v 1.105 2006/10/16 22:18:24 valtri Exp $ + * $Id: xineutils.h,v 1.107 2006/12/25 15:16:33 dgp85 Exp $ * */ #ifndef XINEUTILS_H @@ -847,6 +847,7 @@ void xine_hexdump (const char *buf, int length) XINE_PROTECTED; do { \ LONG_LOG_MODULE_STRING \ printf(fmt, ##args); \ + fflush(stdout); \ } while(0) #else /* __GNUC__ */ #ifdef _MSC_VER @@ -854,12 +855,14 @@ void xine_hexdump (const char *buf, int length) XINE_PROTECTED; do { \ LONG_LOG_MODULE_STRING \ printf("%s", fmtargs); \ + fflush(stdout); \ } while(0) #else /* _MSC_VER */ - #define lprintf(fmt, ...) \ + #define lprintf(...) \ do { \ LONG_LOG_MODULE_STRING \ printf(__VA_ARGS__); \ + fflush(stdout); \ } while(0) #endif /* _MSC_VER */ #endif /* __GNUC__ */ diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c index cc112b64a..575c37611 100644 --- a/src/xine-utils/xmllexer.c +++ b/src/xine-utils/xmllexer.c @@ -1,23 +1,24 @@ /* - * Copyright (C) 2002-2003 the xine project + * Copyright (C) 2002-2003,2007 the xine project * * This file is part of xine, a free video player. * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * The xine-lib XML parser is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * The xine-lib XML parser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * $Id: xmllexer.c,v 1.12 2006/06/20 00:35:08 dgp85 Exp $ + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * $Id: xmllexer.c,v 1.13 2007/03/04 16:19:12 hadess Exp $ * */ @@ -27,11 +28,17 @@ #define LOG */ +#ifdef XINE_COMPILE #include "xineutils.h" +#else +#define lprintf(...) +#define xine_xmalloc malloc +#endif #include "xmllexer.h" #include <stdio.h> #include <ctype.h> #include <string.h> +#include <stdlib.h> /* private constants*/ #define NORMAL 0 /* normal lex mode */ diff --git a/src/xine-utils/xmllexer.h b/src/xine-utils/xmllexer.h index bd69204ff..5a217fcd8 100644 --- a/src/xine-utils/xmllexer.h +++ b/src/xine-utils/xmllexer.h @@ -1,23 +1,24 @@ /* - * Copyright (C) 2002-2003 the xine project + * Copyright (C) 2002-2003,2007 the xine project * * This file is part of xine, a free video player. * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * The xine-lib XML parser is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * The xine-lib XML parser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * - * $Id: xmllexer.h,v 1.7 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: xmllexer.h,v 1.8 2007/03/04 16:19:12 hadess Exp $ * */ @@ -25,6 +26,10 @@ #ifndef XML_LEXER_H #define XML_LEXER_H +#ifndef XINE_PROTECTED +#define XINE_PROTECTED +#endif + /* public constants */ #define T_ERROR -1 /* lexer error */ #define T_EOF 0 /* end of file */ diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index 2e8c84ae0..47096705a 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -1,24 +1,24 @@ /* - * Copyright (C) 2002-2003 the xine project + * Copyright (C) 2002-2003,2007 the xine project * * This file is part of xine, a free video player. - * This file is part of gxine, a free video player. * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * The xine-lib XML parser is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * The xine-lib XML parser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * - * $Id: xmlparser.c,v 1.15 2006/02/14 02:25:01 dsalt Exp $ + * $Id: xmlparser.c,v 1.16 2007/03/04 16:19:12 hadess Exp $ * */ @@ -35,7 +35,12 @@ #define LOG */ +#ifdef XINE_COMPILE #include "xineutils.h" +#else +#define lprintf(...) +#define xine_xmalloc malloc +#endif #include "xmllexer.h" #include "xmlparser.h" @@ -466,7 +471,7 @@ int xml_parser_build_tree(xml_node_t **root_node) { return res; } -char *xml_parser_get_property (const xml_node_t *node, const char *name) { +const char *xml_parser_get_property (const xml_node_t *node, const char *name) { xml_property_t *prop; @@ -489,8 +494,8 @@ char *xml_parser_get_property (const xml_node_t *node, const char *name) { int xml_parser_get_property_int (const xml_node_t *node, const char *name, int def_value) { - char *v; - int ret; + const char *v; + int ret; v = xml_parser_get_property (node, name); @@ -506,7 +511,7 @@ int xml_parser_get_property_int (const xml_node_t *node, const char *name, int xml_parser_get_property_bool (const xml_node_t *node, const char *name, int def_value) { - char *v; + const char *v; v = xml_parser_get_property (node, name); diff --git a/src/xine-utils/xmlparser.h b/src/xine-utils/xmlparser.h index a19c81ec3..f202ca28d 100644 --- a/src/xine-utils/xmlparser.h +++ b/src/xine-utils/xmlparser.h @@ -1,28 +1,34 @@ /* - * Copyright (C) 2002-2003 the xine project + * Copyright (C) 2002-2003,2007 the xine project * * This file is part of xine, a free video player. * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * The xine-lib XML parser is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * The xine-lib XML parser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * You should have received a copy of the GNU Library General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * - * $Id: xmlparser.h,v 1.5 2006/09/26 05:19:49 dgp85 Exp $ + * $Id: xmlparser.h,v 1.6 2007/03/04 16:19:12 hadess Exp $ * */ + #ifndef XML_PARSER_H #define XML_PARSER_H +#ifndef XINE_PROTECTED +#define XINE_PROTECTED +#endif + /* parser modes */ #define XML_PARSER_CASE_INSENSITIVE 0 #define XML_PARSER_CASE_SENSITIVE 1 @@ -54,7 +60,7 @@ int xml_parser_build_tree(xml_node_t **root_node) XINE_PROTECTED; void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED; -char *xml_parser_get_property (const xml_node_t *node, const char *name) XINE_PROTECTED; +const char *xml_parser_get_property (const xml_node_t *node, const char *name) XINE_PROTECTED; int xml_parser_get_property_int (const xml_node_t *node, const char *name, int def_value) XINE_PROTECTED; int xml_parser_get_property_bool (const xml_node_t *node, const char *name, |