summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_out/Makefile.am4
-rw-r--r--src/audio_out/audio_directx2_out.c460
-rw-r--r--src/audio_out/audio_oss_out.c4
-rw-r--r--src/audio_out/audio_pulse_out.c6
-rw-r--r--src/combined/demux_flac.c10
-rw-r--r--src/combined/ffmpeg/Makefile.am2
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c11
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c105
-rw-r--r--src/combined/ffmpeg/ffmpeg_decoder.h4
-rw-r--r--src/demuxers/Makefile.am6
-rw-r--r--src/demuxers/demux_dts.c8
-rw-r--r--src/demuxers/demux_flac.c43
-rw-r--r--src/demuxers/demux_fli.c2
-rw-r--r--src/demuxers/demux_flv.c232
-rw-r--r--src/demuxers/demux_matroska.c14
-rw-r--r--src/demuxers/demux_mpeg.c6
-rw-r--r--src/demuxers/demux_mpeg_pes.c3
-rw-r--r--src/demuxers/demux_real.c6
-rw-r--r--src/demuxers/demux_str.c5
-rw-r--r--src/demuxers/demux_ts.c9
-rw-r--r--src/demuxers/demux_wav.c21
-rw-r--r--src/demuxers/id3.c1
-rw-r--r--src/demuxers/matroska.h2
-rw-r--r--src/input/input_cdda.c18
-rw-r--r--src/input/input_dvb.c5
-rw-r--r--src/input/input_smb.c12
-rw-r--r--src/input/input_v4l.c12
-rw-r--r--src/input/input_vcd.c4
-rw-r--r--src/input/mms.c14
-rw-r--r--src/input/vcd/xineplug_inp_vcd.c8
-rw-r--r--src/libfaad/xine_faad_decoder.c27
-rw-r--r--src/libmad/bit.c3
-rw-r--r--src/libmad/layer12.c3
-rw-r--r--src/libmad/layer3.c3
-rw-r--r--src/libmpeg2/Makefile.am2
-rw-r--r--src/libmpeg2/mpeg2.h6
-rw-r--r--src/libreal/xine_real_audio_decoder.c3
-rw-r--r--src/libreal/xine_real_video_decoder.c3
-rw-r--r--src/libspucc/cc_decoder.h8
-rw-r--r--src/libspucc/xine_cc_decoder.c10
-rw-r--r--src/libspucmml/xine_cmml_decoder.c4
-rw-r--r--src/libspudec/Makefile.am4
-rw-r--r--src/libspudec/xine_spu_decoder.c3
-rw-r--r--src/libspudvb/xine_spudvb_decoder.c114
-rw-r--r--src/libw32dll/wine/win32.c7
-rw-r--r--src/libxineadec/Makefile.am2
-rw-r--r--src/libxinevdec/Makefile.am2
-rw-r--r--src/post/audio/filter.c2
-rw-r--r--src/post/audio/filter.h2
-rw-r--r--src/post/audio/volnorm.c3
-rw-r--r--src/post/deinterlace/tvtime.c14
-rw-r--r--src/post/deinterlace/tvtime.h5
-rw-r--r--src/post/deinterlace/xine_plugin.c9
-rw-r--r--src/post/goom/convolve_fx.c2
-rw-r--r--src/post/goom/diff_against_release.patch37
-rw-r--r--src/post/goom/goom_core.c8
-rw-r--r--src/post/planar/eq2.c4
-rw-r--r--src/video_out/Makefile.am2
-rw-r--r--src/video_out/deinterlace.c14
-rw-r--r--src/video_out/deinterlace.h13
-rw-r--r--src/video_out/video_out_caca.c10
-rw-r--r--src/video_out/video_out_directx.c115
-rw-r--r--src/video_out/video_out_raw.c6
-rw-r--r--src/video_out/video_out_sdl.c16
-rw-r--r--src/video_out/video_out_xcbxv.c95
-rw-r--r--src/video_out/video_out_xv.c79
-rw-r--r--src/video_out/video_out_xvmc.c2
-rw-r--r--src/video_out/video_out_xxmc.c60
-rw-r--r--src/video_out/xv_common.h24
-rw-r--r--src/video_out/xxmc.h10
-rw-r--r--src/xine-engine/buffer.h6
-rw-r--r--src/xine-engine/buffer_types.c8
-rw-r--r--src/xine-engine/configfile.c34
-rw-r--r--src/xine-engine/demux.c28
-rw-r--r--src/xine-engine/load_plugins.c26
-rw-r--r--src/xine-utils/attributes.h6
-rw-r--r--src/xine-utils/monitor.c3
-rw-r--r--src/xine-utils/utils.c20
78 files changed, 1157 insertions, 747 deletions
diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am
index b0c3d292e..8bd32e98a 100644
--- a/src/audio_out/Makefile.am
+++ b/src/audio_out/Makefile.am
@@ -110,7 +110,7 @@ xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module
xineplug_ao_out_directx_la_SOURCES = audio_directx_out.c
xineplug_ao_out_directx_la_CPPFLAGS = $(DIRECTX_CPPFLAGS)
-xineplug_ao_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS)
+xineplug_ao_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(LTLIBINTL)
xineplug_ao_out_directx_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_ao_out_directx_la_LDFLAGS = -avoid-version -module
@@ -131,7 +131,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) $(PTHREAD_LIBS)
+xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_ao_out_directx2_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_ao_out_directx2_la_LDFLAGS = -avoid-version -module
diff --git a/src/audio_out/audio_directx2_out.c b/src/audio_out/audio_directx2_out.c
index 5fffd1e2d..e91e919fc 100644
--- a/src/audio_out/audio_directx2_out.c
+++ b/src/audio_out/audio_directx2_out.c
@@ -31,6 +31,9 @@
*
* Authors:
* - Frantisek Dvorak <valtri@atlas.cz>
+ * - Original version with slotted ring buffer
+ * - Matthias Ringald <mringwal@inf.ethz.ch>
+ * - non-slotted simpler version for ring buffer handling
*
* Inspiration:
* - mplayer for workarounding -lguid idea
@@ -55,8 +58,8 @@
#define LOG_MODULE "audio_directx2_out"
#define LOG_VERBOSE
/*
-#define LOG
-*/
+ #define LOG
+ */
#include "xine_internal.h"
#include "audio_out.h"
@@ -64,29 +67,33 @@
#define AO_OUT_DIRECTX2_IFACE_VERSION 8
+
+/*
+ * If GAP_TOLERANCE is lower than AO_MAX_GAP, xine will
+ * try to smooth playback without skipping frames or
+ * inserting silence.
+ */
+#define GAP_TOLERANCE (AO_MAX_GAP/3)
+
/*
* buffer size in miliseconds
* (one second takes 11-192 KB)
*/
#define BUFFER_MS 1000
-/*
- * number of parts in the buffer,
- * one is always locked for playing
+/*
+ * buffer below this threshold is considered a buffer underrun
*/
-#define PARTS 3
+#define BUFFER_MIN_MS 200
/*
* base power factor for volume remapping
*/
#define FACTOR 60.0
-
-/* experiments */
-/*#define EXACT_WAIT*/
-/*#define EXACT_SLEEP*/
-/*#define PANIC_OVERRUN*/
-
+/*
+ * buffer handler status
+ */
#define STATUS_START 0
#define STATUS_WAIT 1
#define STATUS_RUNNING 2
@@ -108,12 +115,14 @@ typedef struct {
LPDIRECTSOUND ds; /* DirectSound device */
LPDIRECTSOUNDBUFFER dsbuffer; /* DirectSound buffer */
- DSBPOSITIONNOTIFY events[PARTS]; /* position events */
- LPDIRECTSOUNDNOTIFY notify; /* notify interface */
size_t buffer_size; /* size of the buffer */
- size_t part_size; /* second half of buffer */
- size_t read_size; /* size of prepared data */
+ size_t write_pos; /* positition in ring buffer for writing*/
+
+ int status; /* current status of the driver */
+ int paused; /* paused mode */
+ int finished; /* driver finished */
+ int failed; /* don't open modal dialog again */
uint32_t bits;
uint32_t rate;
@@ -123,12 +132,6 @@ typedef struct {
int volume;
int muted;
- int status; /* current status of the driver */
- int paused; /* paused mode */
- int finished; /* driver finished */
- int failed; /* don't open modal dialog again */
- int count; /* current free part number */
-
pthread_t buffer_service; /* service thread for operating with DSB */
pthread_cond_t data_cond; /* signals on data */
pthread_mutex_t data_mutex; /* data lock */
@@ -141,16 +144,14 @@ typedef struct {
* the linking stage.
*****************************************************************************/
static const GUID IID_IDirectSoundNotify = {
- 0xB0210783, 0x89CD, 0x11D0, {0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16}
+0xB0210783, 0x89CD, 0x11D0, {0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16}
};
-static int buffer_ready(dx2_driver_t *this);
-
/* popup a dialog with error */
static void XINE_FORMAT_PRINTF(1, 2)
- error_message(const char *fmt, ...) {
+error_message(const char *fmt, ...) {
char message[256];
va_list ap;
@@ -214,7 +215,7 @@ static LPDIRECTSOUND dsound_create() {
/* destroy direct sound object */
static void dsound_destroy(LPDIRECTSOUND ds) {
- IDirectSound_Release(ds);
+ IDirectSound_Release(ds);
}
@@ -266,12 +267,10 @@ static int audio_create_buffers(dx2_driver_t *this) {
HRESULT err;
size_t buffer_size;
- buffer_size = this->rate * this->frame_size * BUFFER_MS / 1000;
+ buffer_size = this->rate * BUFFER_MS / 1000 * this->frame_size;
if (buffer_size > DSBSIZE_MAX) buffer_size = DSBSIZE_MAX;
if (buffer_size < DSBSIZE_MIN) buffer_size = DSBSIZE_MIN;
- this->part_size = (buffer_size / PARTS / this->frame_size) * this->frame_size;
- if (!this->part_size) this->part_size = this->frame_size;
- this->buffer_size = this->part_size * PARTS;
+ this->buffer_size = buffer_size;
flags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
dsound_fill_wfx(&wfx, this->bits, this->rate, this->channels, this->frame_size);
@@ -282,7 +281,7 @@ static int audio_create_buffers(dx2_driver_t *this) {
return 0;
}
- lprintf("created direct sound buffer, size = %u, part = %u\n", this->buffer_size, this->part_size);
+ lprintf("created direct sound buffer, size = %u\n", this->buffer_size);
return 1;
}
@@ -293,43 +292,6 @@ static void audio_destroy_buffers(dx2_driver_t *this) {
}
-/* create position events */
-static int audio_create_events(dx2_driver_t *this) {
- HANDLE handle[PARTS];
- HRESULT err;
- int i;
-
- for (i = 0; i < PARTS; i++) {
- handle[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!handle[i]) {
- error_message(_("Unable to create buffer position events."));
- return 0;
- }
- this->events[i].dwOffset = i * this->part_size;
- this->events[i].hEventNotify = handle[i];
- }
-
- if ((err = IDirectSoundBuffer_QueryInterface(this->dsbuffer, &IID_IDirectSoundNotify, (void **)&this->notify)) != DS_OK) {
- audio_error(this, err, _("Unable to get notification interface"));
- return 0;
- }
-
- if ((err = IDirectSoundNotify_SetNotificationPositions(this->notify, PARTS, this->events)) != DS_OK) {
- audio_error(this, err, _("Unable to set notification positions"));
- IDirectSoundNotify_Release(this->notify);
- return 0;
- }
-
- return 1;
-}
-
-
-/* destroy notification interface */
-static void audio_destroy_events(dx2_driver_t *this) {
- IDirectSoundNotify_Release(this->notify);
-}
-
-
/* start playback */
static int audio_play(dx2_driver_t *this) {
HRESULT err;
@@ -385,8 +347,7 @@ static int audio_seek(dx2_driver_t *this, size_t pos) {
/* flush audio buffers */
static int audio_flush(dx2_driver_t *this) {
this->status = STATUS_WAIT;
- this->count = 0;
- this->read_size = 0;
+ this->write_pos = 0;
return audio_seek(this, 0);
}
@@ -421,12 +382,12 @@ static int audio_fill(dx2_driver_t *this, char *data, size_t size) {
HRESULT err;
/* lock a part of the buffer, begin position on free space */
- err = IDirectSoundBuffer_Lock(this->dsbuffer, (this->count * this->part_size + this->read_size) % this->buffer_size, size, &ptr1, &size1, &ptr2, &size2, 0);
+ err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0);
/* try to restore the buffer, if necessary */
if (err == DSERR_BUFFERLOST) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": buffer lost, tryig to restore\n"));
IDirectSoundBuffer_Restore(this->dsbuffer);
- err = IDirectSoundBuffer_Lock(this->dsbuffer, (this->count * this->part_size + this->read_size) % this->buffer_size, size, &ptr1, &size1, &ptr2, &size2, 0); }
+ err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0); }
if (err != DS_OK) {
audio_error(this, err, _("Couldn't lock direct sound buffer"));
return 0;
@@ -436,19 +397,15 @@ static int audio_fill(dx2_driver_t *this, char *data, size_t size) {
if (ptr1 && size1) xine_fast_memcpy(ptr1, data, size1);
if (ptr2 && size2) xine_fast_memcpy(ptr2, data + size1, size2);
- this->read_size += size;
+ // this->read_size += size;
+ this->write_pos = (this->write_pos + size ) % this->buffer_size;
+ lprintf("size %u, write_pos %u\n", size, this->write_pos);
if ((err = IDirectSoundBuffer_Unlock(this->dsbuffer, ptr1, size1, ptr2, size2)) != DS_OK) {
audio_error(this, err, _("Couldn't unlock direct sound buffer"));
return 0;
}
- /* signal, if are waiting and need wake up */
- if ((this->status == STATUS_WAIT) && buffer_ready(this)) {
- lprintf("buffer ready, waking up\n");
- pthread_cond_signal(&this->data_cond);
- }
-
return 1;
}
@@ -458,28 +415,28 @@ static int mode2channels(uint32_t mode) {
int channels;
switch(mode) {
- case AO_CAP_MODE_MONO:
- channels = 1;
- break;
-
- case AO_CAP_MODE_STEREO:
- channels = 2;
- break;
-
- case AO_CAP_MODE_4CHANNEL:
- channels = 4;
- break;
-
- case AO_CAP_MODE_5CHANNEL:
- channels = 5;
- break;
-
- case AO_CAP_MODE_5_1CHANNEL:
- channels = 6;
- break;
-
- default:
- return 0;
+ case AO_CAP_MODE_MONO:
+ channels = 1;
+ break;
+
+ case AO_CAP_MODE_STEREO:
+ channels = 2;
+ break;
+
+ case AO_CAP_MODE_4CHANNEL:
+ channels = 4;
+ break;
+
+ case AO_CAP_MODE_5CHANNEL:
+ channels = 5;
+ break;
+
+ case AO_CAP_MODE_5_1CHANNEL:
+ channels = 6;
+ break;
+
+ default:
+ return 0;
}
return channels;
@@ -556,109 +513,96 @@ static int test_capabilities(dx2_driver_t *this) {
/* size of free space in the ring buffer */
static size_t buffer_free_size(dx2_driver_t *this) {
- size_t used_full_size;
+
+ int ret;
+ size_t play_pos;
+ size_t free_space;
- used_full_size = this->read_size + ((this->status != STATUS_WAIT) ? this->part_size : 0);
- _x_assert(used_full_size <= this->buffer_size);
- return this->buffer_size - used_full_size;
+ // get current play pos
+ ret = audio_tell(this, &play_pos);
+ if (!ret)
+ return 0;
+
+ // calc free space (-1)
+ free_space = (this->buffer_size + play_pos - this->write_pos - 1) % this->buffer_size;
+
+ return free_space;
}
-/* enough data in the ring buffer for playing next part? */
-static int buffer_ready(dx2_driver_t *this) {
- return this->read_size >= this->part_size;
+/* size of occupied space in the ring buffer */
+static size_t buffer_occupied_size(dx2_driver_t *this) {
+ int ret;
+ size_t play_pos;
+ size_t used_space;
+
+ // get current play pos
+ ret = audio_tell(this, &play_pos);
+ if (!ret) return 0;
+
+ // calc used space
+ used_space = (this->buffer_size + this->write_pos - play_pos) % this->buffer_size;
+
+ return used_space;
}
/* service thread working with direct sound buffer */
static void *buffer_service(void *data) {
dx2_driver_t *this = (dx2_driver_t *)data;
- HANDLE handles[PARTS];
DWORD ret;
- int i;
-#if defined(EXACT_SLEEP) || defined(EXACT_WAIT)
- size_t play_pos, req_delay;
-#endif
+ size_t play_pos;
+ size_t buffer_min;
+ size_t data_in_buffer;
/* prepare empty buffer */
audio_flush(this);
- for (i = 0; i < PARTS; i++) handles[i] = this->events[i].hEventNotify;
-
+ /* prepare min buffer fill */
+ buffer_min = BUFFER_MIN_MS * this->rate / 1000 * this->frame_size;
+
/* we live! */
pthread_mutex_lock(&this->data_mutex);
pthread_cond_signal(&this->data_cond);
pthread_mutex_unlock(&this->data_mutex);
while (!this->finished) {
+
pthread_mutex_lock(&this->data_mutex);
- if (!buffer_ready(this)) {
- if (!audio_stop(this)) goto fail;
- lprintf("no data (count=%d,free=%" PRIsizet ",avail=%" PRIsizet "), sleeping...\n", this->count, buffer_free_size(this), this->read_size);
- this->status = STATUS_WAIT;
- pthread_cond_wait(&this->data_cond, &this->data_mutex);
- lprintf("wake up (count=%d,free=%" PRIsizet "--,avail=%" PRIsizet ")\n", this->count, buffer_free_size(this), this->read_size);
- if (this->finished) goto finished;
- if (!audio_seek(this, this->count * this->part_size)) goto fail;
- if (!this->paused) {
- if (!audio_play(this)) goto fail;
- }
- this->status = STATUS_RUNNING;
- this->count = (this->count + 1) % PARTS;
- this->read_size -= this->part_size;
- pthread_mutex_unlock(&this->data_mutex);
- lprintf("wait for playback (newcount=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", this->count, buffer_free_size(this), this->read_size);
- do {
- ret = WaitForMultipleObjects(PARTS, handles, FALSE, 250) - WAIT_OBJECT_0;
+ switch( this->status){
+
+ case STATUS_WAIT:
+
+ // pre: stop/buffer flushed
+ lprintf("no data, sleeping...\n");
+ pthread_cond_wait(&this->data_cond, &this->data_mutex);
+ lprintf("woke up (write_pos=%d,free=%" PRIsizet")\n", this->write_pos, buffer_free_size(this));
if (this->finished) goto finished;
- } while (ret > PARTS);
- lprintf("playback started (newcount=%d,ev=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", this->count, ret, buffer_free_size(this), this->read_size);
- _x_assert(ret == ((PARTS + this->count - 1) % PARTS));
- } else {
- this->count = (this->count + 1) % PARTS;
- this->read_size -= this->part_size;
- pthread_mutex_unlock(&this->data_mutex);
- }
- lprintf("waiting for sound event(count=%d,free=%" PRIsizet ",avail=%" PRIsizet ")...\n", this->count, buffer_free_size(this), this->read_size);
- do {
- ret = WaitForMultipleObjects(PARTS, handles, FALSE, 250) - WAIT_OBJECT_0;
- if (this->finished) goto finished;
- } while (ret > PARTS);
- lprintf("end wait(ev=%" PRIdword ",count=%d,free=%" PRIsizet ",avail=%" PRIsizet ")\n", ret, this->count, buffer_free_size(this), this->read_size);
-#ifdef PANIC_OVERRUN
- _x_abort(ret == this->count);
-#else
- if (ret != this->count) {
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": play cursor overran, flushing buffers\n"));
- pthread_mutex_lock(&this->data_mutex);
- if (!audio_stop(this)) goto fail;
- if (!audio_flush(this)) goto fail;
- pthread_mutex_unlock(&this->data_mutex);
- }
-#endif
-
-#if defined(EXACT_SLEEP) || defined(EXACT_WAIT)
- /* ugly hack: wait for right time, + little over for sure */
- pthread_mutex_lock(&this->data_mutex);
- if (!audio_tell(this, &play_pos)) goto fail;
- req_delay = (this->buffer_size + play_pos - this->count * this->part_size) % this->buffer_size;
- pthread_mutex_unlock(&this->data_mutex);
- if (req_delay > (this->buffer_size >> 1)) {
- long delay;
-
- delay = 1000 * (this->buffer_size - req_delay) / (this->frame_size * this->rate) + 1 + BUFFER_MS / PARTS / 4;
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": delayed by %ld msec\n"), delay);
- printf("should be delayed %ld msec\n", delay);
-#ifdef EXACT_SLEEP
- xine_usec_sleep(delay * 1000);
-#endif
-#ifdef EXACT_WAIT
- WaitForMultipleObjects(PARTS, handles, FALSE, delay);
-#endif
+ if (!audio_seek(this, 0)) goto fail;
+ if (!this->paused) {
+ if (!audio_play(this)) goto fail;
+ }
+ this->status = STATUS_RUNNING;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
+
+ case STATUS_RUNNING:
+
+ // check for buffer underrun
+ data_in_buffer = buffer_occupied_size(this);
+ if ( data_in_buffer < buffer_min){
+ xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": play cursor overran (data %u, min %u), flushing buffers\n"),
+ data_in_buffer, buffer_min);
+ if (!audio_stop(this)) goto fail;
+ if (!audio_flush(this)) goto fail;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+
+ // just wait BUFFER_MIN_MS before next check
+ xine_usec_sleep(BUFFER_MIN_MS * 1000);
+ break;
}
-#endif
}
-
return NULL;
fail:
@@ -683,15 +627,15 @@ static int ao_dx2_get_property(ao_driver_t *this_gen, int property) {
switch(property) {
- case AO_PROP_MIXER_VOL:
- case AO_PROP_PCM_VOL:
- return this->volume;
+ case AO_PROP_MIXER_VOL:
+ case AO_PROP_PCM_VOL:
+ return this->volume;
- case AO_PROP_MUTE_VOL:
- return this->muted;
+ case AO_PROP_MUTE_VOL:
+ return this->muted;
- default:
- return 0;
+ default:
+ return 0;
}
}
@@ -702,26 +646,26 @@ static int ao_dx2_set_property(ao_driver_t *this_gen, int property, int value) {
switch(property) {
- case AO_PROP_MIXER_VOL:
- case AO_PROP_PCM_VOL:
- lprintf("set volume to %d\n", value);
- pthread_mutex_lock(&this->data_mutex);
- if (!this->muted) {
- if (this->dsbuffer && !audio_set_volume(this, value)) return ~value;
- }
- this->volume = value;
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_PROP_MIXER_VOL:
+ case AO_PROP_PCM_VOL:
+ lprintf("set volume to %d\n", value);
+ pthread_mutex_lock(&this->data_mutex);
+ if (!this->muted) {
+ if (this->dsbuffer && !audio_set_volume(this, value)) return ~value;
+ }
+ this->volume = value;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- case AO_PROP_MUTE_VOL:
- pthread_mutex_lock(&this->data_mutex);
- if (this->dsbuffer && !audio_set_volume(this, value ? 0 : this->volume)) return ~value;
- this->muted = value;
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_PROP_MUTE_VOL:
+ pthread_mutex_lock(&this->data_mutex);
+ if (this->dsbuffer && !audio_set_volume(this, value ? 0 : this->volume)) return ~value;
+ this->muted = value;
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- default:
- return ~value;
+ default:
+ return ~value;
}
@@ -747,18 +691,17 @@ static int ao_dx2_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int
this->status = STATUS_START;
if (!audio_create_buffers(this)) return 0;
- if (!audio_create_events(this)) goto fail_buffers;
- if (!audio_set_volume(this, this->volume)) goto fail_events;
+ if (!audio_set_volume(this, this->volume)) goto fail_buffers;
if (pthread_cond_init(&this->data_cond, NULL) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread condition: %s\n"), strerror(errno));
- goto fail_events;
+ goto fail_buffers;
}
if (pthread_mutex_init(&this->data_mutex, NULL) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread mutex: %s\n"), strerror(errno));
goto fail_cond;
}
-
+
/* creating the service thread and waiting for its signal */
pthread_mutex_lock(&this->data_mutex);
if (pthread_create(&this->buffer_service, NULL, buffer_service, this) != 0) {
@@ -775,8 +718,6 @@ fail_mutex:
pthread_mutex_destroy(&this->data_mutex);
fail_cond:
pthread_cond_destroy(&this->data_cond);
-fail_events:
- audio_destroy_events(this);
fail_buffers:
audio_destroy_buffers(this);
return 0;
@@ -803,22 +744,26 @@ static int ao_dx2_bytes_per_frame(ao_driver_t *this_gen) {
static int ao_dx2_delay(ao_driver_t *this_gen) {
dx2_driver_t *this = (dx2_driver_t *)this_gen;
- int frames;
- size_t final_pos, play_pos;
-
- if (this->status != STATUS_RUNNING) return this->read_size / this->frame_size;
+ int frames = 0;
+ int ret;
+ size_t play_pos;
pthread_mutex_lock(&this->data_mutex);
- if (!audio_tell(this, &play_pos)) {
- pthread_mutex_unlock(&this->data_mutex);
- return 0;
- }
- final_pos = this->read_size + (((PARTS + this->count - 1) % PARTS) + 1) * this->part_size - 1;
- frames = (this->buffer_size + final_pos - play_pos) % this->buffer_size / this->frame_size;
+
+ if (this->status != STATUS_RUNNING){
+ frames = this->write_pos / this->frame_size;
+ } else {
+ ret = audio_tell(this, &play_pos);
+ if (ret){
+ frames = buffer_occupied_size(this) / this->frame_size;
+ }
+ }
+
pthread_mutex_unlock(&this->data_mutex);
#ifdef LOG
- if ((rand() % 10) == 0) lprintf("frames=%d, play_pos=%" PRIdword ", block=%" PRIsizet "..%" PRIsizet "\n", frames, play_pos, final_pos - this->part_size + 1, final_pos);
+ if ((rand() % 10) == 0)
+ lprintf("frames=%d, play_pos=%" PRIdword ", write_pos=%u\n", frames, play_pos, this->write_pos);
#endif
return frames;
@@ -840,7 +785,7 @@ static int ao_dx2_write(ao_driver_t *this_gen, int16_t* audio_data, uint32_t num
while (((free_size = buffer_free_size(this)) == 0) && !this->finished) {
lprintf("buffer full, waiting\n");
pthread_mutex_unlock(&this->data_mutex);
- xine_usec_sleep(1000 * BUFFER_MS / PARTS / 5);
+ xine_usec_sleep(1000 * BUFFER_MS / 10);
pthread_mutex_lock(&this->data_mutex);
}
if (free_size >= input_size) size = input_size;
@@ -856,6 +801,12 @@ static int ao_dx2_write(ao_driver_t *this_gen, int16_t* audio_data, uint32_t num
input_size -= size;
}
+ /* signal, if are waiting and need wake up */
+ if ((this->status == STATUS_WAIT) && (buffer_occupied_size(this) > BUFFER_MIN_MS * this->rate / 1000 * this->frame_size)) {
+ lprintf("buffer ready, waking up\n");
+ pthread_cond_signal(&this->data_cond);
+ }
+
return 1;
}
@@ -881,7 +832,6 @@ static void ao_dx2_close(ao_driver_t *this_gen) {
if (pthread_mutex_destroy(&this->data_mutex) != 0) {
xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't destroy pthread mutex: %s\n"), strerror(errno));
}
- audio_destroy_events(this);
audio_destroy_buffers(this);
}
@@ -896,12 +846,8 @@ static void ao_dx2_exit(ao_driver_t *this_gen) {
}
-/*
- * TODO: check
- */
static int ao_dx2_get_gap_tolerance(ao_driver_t *this_gen) {
- /* half of part of the buffer in pts (1 msec = 90 pts) */
- return (90 * (BUFFER_MS / PARTS)) >> 1;
+ return GAP_TOLERANCE;
}
@@ -910,36 +856,36 @@ static int ao_dx2_control(ao_driver_t *this_gen, int cmd, ...) {
switch(cmd) {
- case AO_CTRL_PLAY_PAUSE:
- lprintf("control pause\n");
- pthread_mutex_lock(&this->data_mutex);
- if (!this->paused) {
- audio_stop(this);
- this->paused = 1;
- }
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_CTRL_PLAY_PAUSE:
+ lprintf("control pause\n");
+ pthread_mutex_lock(&this->data_mutex);
+ if (!this->paused) {
+ audio_stop(this);
+ this->paused = 1;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- case AO_CTRL_PLAY_RESUME:
- lprintf("control resume\n");
- pthread_mutex_lock(&this->data_mutex);
- if (this->paused) {
- if (this->status != STATUS_WAIT) audio_play(this);
- this->paused = 0;
- }
- pthread_mutex_unlock(&this->data_mutex);
- break;
-
- case AO_CTRL_FLUSH_BUFFERS:
- lprintf("control flush\n");
- pthread_mutex_lock(&this->data_mutex);
- audio_stop(this);
- audio_flush(this);
- pthread_mutex_unlock(&this->data_mutex);
- break;
+ case AO_CTRL_PLAY_RESUME:
+ lprintf("control resume\n");
+ pthread_mutex_lock(&this->data_mutex);
+ if (this->paused) {
+ if (this->status != STATUS_WAIT) audio_play(this);
+ this->paused = 0;
+ }
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
+
+ case AO_CTRL_FLUSH_BUFFERS:
+ lprintf("control flush\n");
+ pthread_mutex_lock(&this->data_mutex);
+ audio_stop(this);
+ audio_flush(this);
+ pthread_mutex_unlock(&this->data_mutex);
+ break;
- default:
- xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": unknown control command %d\n"), cmd);
+ default:
+ xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": unknown control command %d\n"), cmd);
}
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index 2ae116970..ba1044ed4 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_out.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -666,7 +666,7 @@ static int probe_audio_devices(oss_driver_t *this) {
int base_num, i;
int audio_fd, rate;
int best_rate;
- char *devname[30];
+ char devname[30];
strcpy(this->audio_dev, "auto");
diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c
index dfae98c31..4b66fbaed 100644
--- a/src/audio_out/audio_pulse_out.c
+++ b/src/audio_out/audio_pulse_out.c
@@ -218,7 +218,8 @@ static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info
this->cvolume = info->volume;
this->swvolume = pa_cvolume_avg(&info->volume);
-#ifdef HAVE_PULSEAUDIO_0_9_7
+#if PA_PROTOCOL_VERSION >= 11
+ /* PulseAudio 0.9.7 and newer */
this->muted = info->mute;
#else
this->muted = pa_cvolume_is_muted (&this->cvolume);
@@ -665,7 +666,8 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value
this->muted = value;
-#ifdef HAVE_PULSEAUDIO_0_9_7
+#if PA_PROTOCOL_VERSION >= 11
+ /* PulseAudio 0.9.7 and newer */
o = pa_context_set_sink_input_mute(this->context, pa_stream_get_index(this->stream),
value, __xine_pa_context_success_callback, this);
#else
diff --git a/src/combined/demux_flac.c b/src/combined/demux_flac.c
index ebba63701..fc638fe35 100644
--- a/src/combined/demux_flac.c
+++ b/src/combined/demux_flac.c
@@ -583,7 +583,7 @@ open_plugin (demux_class_t *class_gen,
}
break;
case METHOD_BY_EXTENSION: {
- char *ending, *mrl;
+ const char *ending, *mrl;
mrl = input->get_mrl (input);
@@ -715,22 +715,22 @@ open_plugin (demux_class_t *class_gen,
/* FLAC Demuxer class */
-static char *
+static const char *
get_description (demux_class_t *this_gen) {
return "FLAC demux plugin";
}
-static char *
+static const char *
get_identifier (demux_class_t *this_gen) {
return "FLAC";
}
-static char *
+static const char *
get_extensions (demux_class_t *this_gen) {
return "flac";
}
-static char *
+static const char *
get_mimetypes (demux_class_t *this_gen) {
return "audio/x-flac: flac: FLAC Audio;"
"audio/flac: flac: FLAC Audio;";
diff --git a/src/combined/ffmpeg/Makefile.am b/src/combined/ffmpeg/Makefile.am
index 3c78fa9d3..4d7e70423 100644
--- a/src/combined/ffmpeg/Makefile.am
+++ b/src/combined/ffmpeg/Makefile.am
@@ -4,7 +4,7 @@ DEFAULT_INCLUDES = -I.
if HAVE_FFMPEG
ff_cppflags = $(FFMPEG_CFLAGS) $(FFMPEG_POSTPROC_CFLAGS)
-link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_POSTPROC_LIBS)
+link_ffmpeg = $(FFMPEG_LIBS) $(FFMPEG_UTIL_LIBS) $(FFMPEG_POSTPROC_LIBS)
else
ff_cppflags = -I$(top_builddir)/src/libffmpeg -I$(top_srcdir)/src/libffmpeg/libavcodec -I$(top_srcdir)/src/libffmpeg/libavutil
link_ffmpeg = \
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index a08c3ac35..a9f630506 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2005 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -324,7 +324,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
if (!this->output_open) {
if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) {
- avcodec_decode_audio (this->context,
+ avcodec_decode_audio2 (this->context,
(int16_t *)this->decode_buffer,
&decode_buffer_size,
&this->buf[0],
@@ -369,6 +369,11 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf)
/* dispatch the decoded audio */
out = 0;
while (out < decode_buffer_size) {
+ int stream_status = xine_get_status(this->stream);
+
+ if (stream_status == XINE_STATUS_QUIT || stream_status == XINE_STATUS_STOP)
+ return;
+
audio_buffer =
this->stream->audio_out->get_buffer (this->stream->audio_out);
if (audio_buffer->mem_size == 0) {
@@ -445,7 +450,7 @@ static void ff_audio_dispose (audio_decoder_t *this_gen) {
free(this->context->extradata);
if(this->context)
- free(this->context);
+ av_free(this->context);
free (this_gen);
}
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
index e643708df..a1ab3696c 100644
--- a/src/combined/ffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2007 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -78,6 +78,9 @@ struct ff_video_decoder_s {
xine_stream_t *stream;
int64_t pts;
+ uint64_t pts_tag_mask;
+ uint64_t pts_tag;
+ int pts_tag_counter;
int video_step;
uint8_t decoder_ok:1;
@@ -1178,6 +1181,42 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu
}
}
+static uint64_t ff_tag_pts(ff_video_decoder_t *this, uint64_t pts)
+{
+ return pts | this->pts_tag;
+}
+
+static uint64_t ff_untag_pts(ff_video_decoder_t *this, uint64_t pts)
+{
+ if (this->pts_tag_mask == 0)
+ return pts; /* pts tagging inactive */
+
+ if (this->pts_tag != 0 && (pts & this->pts_tag_mask) != this->pts_tag)
+ return 0; /* reset pts if outdated while waiting for first pass (see below) */
+
+ return pts & ~this->pts_tag_mask;
+}
+
+static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts)
+{
+ if (this->pts_tag_mask == 0)
+ return; /* pts tagging inactive */
+
+ if ((pts & this->pts_tag_mask) != this->pts_tag)
+ return; /* pts still outdated */
+
+ if (this->pts_tag != 0) {
+ /* first pass: reset pts_tag */
+ this->pts_tag = 0;
+ } else if (pts == 0)
+ return; /* cannot detect second pass */
+ else {
+ /* second pass: reset pts_tag_mask and pts_tag_counter */
+ this->pts_tag_mask = 0;
+ this->pts_tag_counter = 0;
+ }
+}
+
static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
uint8_t *chunk_buf = this->buf;
AVRational avr00 = {0, 1};
@@ -1202,6 +1241,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
this->size = 0;
}
+ if (this->size == 0) {
+ /* take over pts when we are about to buffer a frame */
+ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->pts = 0;
+ }
+
/* data accumulation */
if (buf->size > 0) {
if ((this->size == 0) &&
@@ -1254,6 +1300,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
len = avcodec_decode_video (this->context, this->av_frame,
&got_picture, &chunk_buf[offset],
this->size);
+
+ /* reset consumed pts value */
+ this->context->reordered_opaque = ff_tag_pts(this, 0);
+
lprintf("consumed size: %d, got_picture: %d\n", len, got_picture);
if ((len <= 0) || (len > this->size)) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1269,6 +1319,11 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
ff_check_bufsize(this, this->size);
memmove (this->buf, &chunk_buf[offset], this->size);
chunk_buf = this->buf;
+
+ /* take over pts for next access unit */
+ this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ this->pts = 0;
}
}
}
@@ -1363,8 +1418,9 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
ff_convert_frame(this, img);
}
- img->pts = this->pts;
- this->pts = 0;
+ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+ ff_check_pts_tagging(this, this->av_frame->reordered_opaque); /* only check for valid frames */
+ this->av_frame->reordered_opaque = 0;
/* workaround for weird 120fps streams */
if( video_step_to_use == 750 ) {
@@ -1404,8 +1460,8 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
this->output_format,
VO_BOTH_FIELDS|this->frame_flags);
/* set PTS to allow early syncing */
- img->pts = this->pts;
- this->pts = 0;
+ img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+ this->av_frame->reordered_opaque = 0;
img->duration = video_step_to_use;
@@ -1490,6 +1546,10 @@ static void ff_reset (video_decoder_t *this_gen) {
if (this->is_mpeg12)
mpeg_parser_reset(this->mpeg_parser);
+
+ this->pts_tag_mask = 0;
+ this->pts_tag = 0;
+ this->pts_tag_counter = 0;
}
static void ff_discontinuity (video_decoder_t *this_gen) {
@@ -1497,6 +1557,37 @@ static void ff_discontinuity (video_decoder_t *this_gen) {
lprintf ("ff_discontinuity\n");
this->pts = 0;
+
+ /*
+ * there is currently no way to reset all the pts which are stored in the decoder.
+ * therefore, we add a unique tag (generated from pts_tag_counter) to pts (see
+ * ff_tag_pts()) and wait for it to appear on returned frames.
+ * until then, any retrieved pts value will be reset to 0 (see ff_untag_pts()).
+ * when we see the tag returned, pts_tag will be reset to 0. from now on, any
+ * untagged pts value is valid already.
+ * when tag 0 appears too, there are no tags left in the decoder so pts_tag_mask
+ * and pts_tag_counter will be reset to 0 too (see ff_check_pts_tagging()).
+ */
+ this->pts_tag_counter++;
+ this->pts_tag_mask = 0;
+ this->pts_tag = 0;
+ {
+ /* pts values typically don't use the uppermost bits. therefore we put the tag there */
+ int counter_mask = 1;
+ uint64_t tag_mask = 0x8000000000000000ull;
+ while (this->pts_tag_counter >= counter_mask)
+ {
+ /*
+ * mirror the counter into the uppermost bits. this allows us to enlarge mask as
+ * necessary and while previous taggings can still be detected to be outdated.
+ */
+ if (this->pts_tag_counter & counter_mask)
+ this->pts_tag |= tag_mask;
+ this->pts_tag_mask |= tag_mask;
+ tag_mask >>= 1;
+ counter_mask <<= 1;
+ }
+ }
}
static void ff_dispose (video_decoder_t *this_gen) {
@@ -1534,10 +1625,10 @@ static void ff_dispose (video_decoder_t *this_gen) {
free_yuv_planes(&this->yuv);
if( this->context )
- free( this->context );
+ av_free( this->context );
if( this->av_frame )
- free( this->av_frame );
+ av_free( this->av_frame );
if (this->buf)
free(this->buf);
diff --git a/src/combined/ffmpeg/ffmpeg_decoder.h b/src/combined/ffmpeg/ffmpeg_decoder.h
index f47421253..0f4ff1f1e 100644
--- a/src/combined/ffmpeg/ffmpeg_decoder.h
+++ b/src/combined/ffmpeg/ffmpeg_decoder.h
@@ -33,6 +33,10 @@
# include "../../libffmpeg/libavcodec/avcodec.h"
#endif
+#if LIBAVCODEC_VERSION_MAJOR > 51
+#define bits_per_sample bits_per_coded_sample
+#endif
+
typedef struct ff_codec_s {
uint32_t type;
enum CodecID id;
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
index 2c4b38e4a..f5b0befbe 100644
--- a/src/demuxers/Makefile.am
+++ b/src/demuxers/Makefile.am
@@ -70,10 +70,10 @@ xineplug_dmx_mpeg_pes_la_SOURCES = demux_mpeg_pes.c
xineplug_dmx_mpeg_pes_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
xineplug_dmx_mpeg_ts_la_SOURCES = demux_ts.c
-xineplug_dmx_mpeg_ts_la_LIBADD = $(XINE_LIB)
+xineplug_dmx_mpeg_ts_la_LIBADD = $(XINE_LIB) $(LTLIBINTL)
xineplug_dmx_qt_la_SOURCES = demux_qt.c
-xineplug_dmx_qt_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS)
+xineplug_dmx_qt_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(LTLIBINTL)
xineplug_dmx_qt_la_CPPFLAGS = $(ZLIB_CPPFLAGS)
xineplug_dmx_asf_la_SOURCES = demux_asf.c asfheader.c
@@ -130,7 +130,7 @@ xineplug_dmx_nsv_la_SOURCES = demux_nsv.c
xineplug_dmx_nsv_la_LIBADD = $(XINE_LIB)
xineplug_dmx_matroska_la_SOURCES = demux_matroska.c ebml.c
-xineplug_dmx_matroska_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS)
+xineplug_dmx_matroska_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(LTLIBINTL)
xineplug_dmx_matroska_la_CPPFLAGS = $(ZLIB_CPPFLAGS)
xineplug_dmx_matroska_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing
diff --git a/src/demuxers/demux_dts.c b/src/demuxers/demux_dts.c
index 55fc8fb98..ed1f16d33 100644
--- a/src/demuxers/demux_dts.c
+++ b/src/demuxers/demux_dts.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 the xine project
+ * Copyright (C) 2005-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -199,6 +199,12 @@ static int open_dts_file(demux_dts_t *this) {
sfreq = peak[this->data_start+8] & 0x0f;
break;
+ default:
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ LOG_MODULE ": unsupported DTS bitstream encoding %d\n",
+ dts_version);
+ return 0;
+
}
if ((sfreq > sizeof(dts_sample_rates)/sizeof(int)) ||
diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c
index e6d6f6376..c14536040 100644
--- a/src/demuxers/demux_flac.c
+++ b/src/demuxers/demux_flac.c
@@ -232,6 +232,9 @@ static int open_flac_file(demux_flac_t *flac) {
} else if ((strncasecmp ("ARTIST=", comment, 7) == 0)
&& (length - 7 > 0)) {
_x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ARTIST, comment + 7);
+ } else if ((strncasecmp ("COMPOSER=", comment, 9) == 0)
+ && (length - 9 > 0)) {
+ _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_COMPOSER, comment + 9);
} else if ((strncasecmp ("ALBUM=", comment, 6) == 0)
&& (length - 6 > 0)) {
_x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ALBUM, comment + 6);
@@ -390,12 +393,13 @@ static int demux_flac_seek (demux_plugin_t *this_gen,
demux_flac_t *this = (demux_flac_t *) this_gen;
int seekpoint_index = 0;
int64_t start_pts;
+ unsigned char buf[4];
start_pos = (off_t) ( (double) start_pos / 65535 *
this->data_size );
/* if thread is not running, initialize demuxer */
- if( !playing ) {
+ if( !playing && !start_pos) {
/* send new pts */
_x_demux_control_newpts(this->stream, 0, 0);
@@ -403,28 +407,39 @@ static int demux_flac_seek (demux_plugin_t *this_gen,
this->status = DEMUX_OK;
} else {
- if (this->seekpoints == NULL) {
+ if (this->seekpoints == NULL && !start_pos) {
/* cannot seek if there is no seekpoints */
this->status = DEMUX_OK;
return this->status;
}
- /* do a lazy, linear seek based on the assumption that there are not
- * that many seek points */
+ /* Don't use seekpoints if start_pos != 0. This allows smooth seeking */
if (start_pos) {
/* offset-based seek */
- if (start_pos < this->seekpoints[0].offset)
- seekpoint_index = 0;
- else {
- for (seekpoint_index = 0; seekpoint_index < this->seekpoint_count - 1;
- seekpoint_index++) {
- if (start_pos < this->seekpoints[seekpoint_index + 1].offset) {
- break;
- }
- }
+ this->status = DEMUX_OK;
+ start_pos += this->data_start;
+ this->input->seek(this->input, start_pos, SEEK_SET);
+ while(1){ /* here we try to find something that resembles a frame header */
+
+ if (this->input->read(this->input, buf, 2) != 2){
+ this->status = DEMUX_FINISHED; /* we sought past the end of stream ? */
+ break;
+ }
+
+ if (buf[0] == 0xff && buf[1] == 0xf8)
+ break; /* this might be the frame header... or it may be not. We pass it to the decoder
+ * to decide, but this way we reduce the number of warnings */
+ start_pos +=2;
}
+
+ _x_demux_flush_engine(this->stream);
+ this->input->seek(this->input, start_pos, SEEK_SET);
+ _x_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK);
+ return this->status;
+
} else {
- /* time-based seek */
+ /* do a lazy, linear seek based on the assumption that there are not
+ * that many seek points; time-based seek */
start_pts = start_time;
start_pts *= 90;
if (start_pts < this->seekpoints[0].pts)
diff --git a/src/demuxers/demux_fli.c b/src/demuxers/demux_fli.c
index fabc2c788..12ae81609 100644
--- a/src/demuxers/demux_fli.c
+++ b/src/demuxers/demux_fli.c
@@ -244,7 +244,7 @@ static void demux_fli_send_headers(demux_plugin_t *this_gen) {
BUF_FLAG_FRAME_END;
buf->decoder_info[0] = this->frame_pts_inc; /* initial video_step */
buf->size = this->bih.biSize;
- memcpy(buf->content, &this->bih, sizeof(xine_bmiheader) + this->bih.biSize);
+ memcpy(buf->content, &this->bih, this->bih.biSize);
buf->type = BUF_VIDEO_FLI;
this->video_fifo->put (this->video_fifo, buf);
}
diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c
index d319ece74..d3da20136 100644
--- a/src/demuxers/demux_flv.c
+++ b/src/demuxers/demux_flv.c
@@ -21,10 +21,10 @@
/*
* Flash Video (.flv) File Demuxer
* by Mike Melanson (melanson@pcisys.net) and
- * Claudio Ciccani (klan@directfb.org)
+ * Claudio Ciccani (klan@users.sf.net)
*
* For more information on the FLV file format, visit:
- * http://download.macromedia.com/pub/flash/flash_file_format_specification.pdf
+ * http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v9.pdf
*/
#ifdef HAVE_CONFIG_H
@@ -110,14 +110,20 @@ typedef struct {
#define FLV_SOUND_FORMAT_ADPCM 0x01
#define FLV_SOUND_FORMAT_MP3 0x02
#define FLV_SOUND_FORMAT_PCM_LE 0x03
+#define FLV_SOUND_FORMAT_NELLY16 0x04 /* Nellymoser 16KHz */
#define FLV_SOUND_FORMAT_NELLY8 0x05 /* Nellymoser 8KHz */
#define FLV_SOUND_FORMAT_NELLY 0x06 /* Nellymoser */
+#define FLV_SOUND_FORMAT_ALAW 0x07 /* G.711 A-LAW */
+#define FLV_SOUND_FORMAT_MULAW 0x08 /* G.711 MU-LAW */
+#define FLV_SOUND_FORMAT_AAC 0x0a
+#define FLV_SOUND_FORMAT_MP38 0x0e /* MP3 8KHz */
#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_VIDEO_FORMAT_H264 0x07
#define FLV_DATA_TYPE_NUMBER 0x00
#define FLV_DATA_TYPE_BOOL 0x01
@@ -429,11 +435,24 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf_type = BUF_AUDIO_FLVADPCM;
break;
case FLV_SOUND_FORMAT_MP3:
+ case FLV_SOUND_FORMAT_MP38:
buf_type = BUF_AUDIO_MPEG;
break;
case FLV_SOUND_FORMAT_PCM_LE:
buf_type = BUF_AUDIO_LPCM_LE;
break;
+ case FLV_SOUND_FORMAT_ALAW:
+ buf_type = BUF_AUDIO_ALAW;
+ break;
+ case FLV_SOUND_FORMAT_MULAW:
+ buf_type = BUF_AUDIO_MULAW;
+ break;
+ case FLV_SOUND_FORMAT_AAC:
+ buf_type = BUF_AUDIO_AAC;
+ /* AAC extra header */
+ this->input->read(this->input, buffer, 1 );
+ remaining_bytes--;
+ break;
default:
lprintf(" unsupported audio format (%d)...\n", buffer[0] >> 4);
buf_type = BUF_AUDIO_UNKNOWN;
@@ -464,8 +483,17 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
}
remaining_bytes--;
- if ((buffer[0] >> 4) == 0x01)
- buf_flags = BUF_FLAG_KEYFRAME;
+ switch ((buffer[0] >> 4)) {
+ case 0x01:
+ buf_flags = BUF_FLAG_KEYFRAME;
+ break;
+ case 0x05:
+ /* skip server command */
+ this->input->seek(this->input, remaining_bytes, SEEK_CUR);
+ continue;
+ default:
+ break;
+ }
this->videocodec = buffer[0] & 0x0F; /* override */
switch (this->videocodec) {
@@ -484,6 +512,12 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
this->input->read(this->input, buffer, 4);
remaining_bytes -= 4;
break;
+ case FLV_VIDEO_FORMAT_H264:
+ buf_type = BUF_VIDEO_H264;
+ /* AVC 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;
@@ -511,6 +545,23 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
bih->biSize++;
buf->size++;
}
+ else if (buf_type == BUF_VIDEO_H264 && buffer[0] == 0) {
+ /* AVC sequence header */
+ if (remaining_bytes > buf->max_size-buf->size) {
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
+ this->input->read(this->input, buf->content+buf->size, buf->max_size-buf->size);
+ this->input->seek(this->input, remaining_bytes-buf->max_size-buf->size, SEEK_CUR);
+ bih->biSize = buf->max_size;
+ buf->size = buf->max_size;
+ }
+ else {
+ this->input->read(this->input, buf->content+buf->size, remaining_bytes);
+ bih->biSize += remaining_bytes;
+ buf->size += remaining_bytes;
+ }
+ remaining_bytes = 0;
+ }
fifo->put(fifo, buf);
this->got_video_header = 1;
}
@@ -537,11 +588,21 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf->type = BUF_AUDIO_FLVADPCM;
break;
case FLV_SOUND_FORMAT_MP3:
+ case FLV_SOUND_FORMAT_MP38:
buf->type = BUF_AUDIO_MPEG;
break;
case FLV_SOUND_FORMAT_PCM_LE:
buf->type = BUF_AUDIO_LPCM_LE;
break;
+ case FLV_SOUND_FORMAT_ALAW:
+ buf->type = BUF_AUDIO_ALAW;
+ break;
+ case FLV_SOUND_FORMAT_MULAW:
+ buf->type = BUF_AUDIO_MULAW;
+ break;
+ case FLV_SOUND_FORMAT_AAC:
+ buf->type = BUF_AUDIO_AAC;
+ break;
default:
buf->type = BUF_AUDIO_UNKNOWN;
break;
@@ -549,9 +610,10 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
buf->size = 0;
this->audio_fifo->put(this->audio_fifo, buf);
this->got_audio_header = 1;
+ lprintf(" got audio header from metadata...\n");
}
- if (!this->got_video_header && this->videocodec) {
+ if (!this->got_video_header && this->videocodec && this->videocodec != FLV_VIDEO_FORMAT_H264) {
xine_bmiheader *bih;
buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER |
@@ -583,6 +645,7 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
}
this->video_fifo->put(this->video_fifo, buf);
this->got_video_header = 1;
+ lprintf(" got video header from metadata...\n");
}
return this->status;
@@ -600,33 +663,61 @@ static int read_flv_packet(demux_flv_t *this, int preview) {
while (remaining_bytes) {
buf = fifo->buffer_pool_alloc(fifo);
buf->type = buf_type;
- buf->pts = (int64_t) pts * 90;
-
- if (!preview)
- 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 ((buf_type == BUF_VIDEO_H264 || buf_type == BUF_AUDIO_AAC) && buffer[0] == 0) {
+ /* AVC/AAC sequence header */
+ buf->pts = 0;
+ buf->size = 0;
+
+ buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_HEADER;
+ if (preview)
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
- if (remaining_bytes > buf->max_size)
- buf->size = buf->max_size;
- else
- buf->size = remaining_bytes;
- remaining_bytes -= buf->size;
-
- buf->decoder_flags = buf_flags;
- if (preview)
- buf->decoder_flags |= BUF_FLAG_PREVIEW;
- if (!remaining_bytes)
- buf->decoder_flags |= BUF_FLAG_FRAME_END;
-
- if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
+ buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG;
+ buf->decoder_info[2] = MIN(remaining_bytes, buf->max_size);
+ buf->decoder_info_ptr[2] = buf->mem;
+
+ if (this->input->read(this->input, buf->mem, buf->decoder_info[2]) != buf->decoder_info[2]) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ }
+
+ if (remaining_bytes > buf->max_size) {
+ xprintf(this->xine, XINE_VERBOSITY_LOG,
+ _("sequence header too big (%u bytes)!\n"), remaining_bytes);
+ this->input->seek(this->input, remaining_bytes-buf->max_size, SEEK_CUR);
+ }
+ remaining_bytes = 0;
+ }
+ else {
+ buf->pts = (int64_t) pts * 90;
+ if (!preview)
+ check_newpts(this, buf->pts, (tag_type == FLV_TAG_TYPE_VIDEO));
+
+ if (remaining_bytes > buf->max_size)
+ buf->size = buf->max_size;
+ else
+ buf->size = remaining_bytes;
+ remaining_bytes -= buf->size;
+
+ buf->decoder_flags = buf_flags;
+ if (preview)
+ buf->decoder_flags |= BUF_FLAG_PREVIEW;
+ if (!remaining_bytes)
+ buf->decoder_flags |= BUF_FLAG_FRAME_END;
+
+ if (this->input->read(this->input, buf->content, buf->size) != buf->size) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ }
}
fifo->put(fifo, buf);
@@ -649,8 +740,8 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
lprintf(" seeking %s to %d...\n",
do_rewind ? "backward" : "forward", seek_pts);
-
- if (seek_pts == 0) {
+
+ if (seek_pos == 0 && seek_pts == 0) {
this->input->seek(this->input, this->start, SEEK_SET);
this->cur_pts = 0;
return;
@@ -676,11 +767,9 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
this->input->seek(this->input, this->index[i].offset-4, SEEK_SET);
this->cur_pts = this->index[i].pts;
- return;
}
}
-
- if (seek_pos && this->videocodec && abs(seek_pts-this->cur_pts) > 300000) {
+ else if (seek_pos && this->videocodec && abs(seek_pts-this->cur_pts) > 300000) {
off_t pos, size;
pos = this->input->get_current_pos(this->input);
@@ -715,49 +804,50 @@ static void seek_flv_file(demux_flv_t *this, off_t seek_pos, int seek_pts) {
lprintf(" ...resync failed!\n");
this->input->seek(this->input, pos, SEEK_SET);
- return;
}
-
- while (do_rewind ? (seek_pts < this->cur_pts) : (seek_pts > this->cur_pts)) {
- unsigned char tag_type;
- int data_size;
- int ptag_size;
+ else if (seek_pts) {
+ 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);
+ 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;
- }
+ len = this->input->read(this->input, buffer, 16);
+ if (len != 16) {
+ len = (len < 0) ? 0 : len;
+ break;
+ }
- ptag_size = _X_BE_32(&buffer[0]);
- tag_type = buffer[4];
- data_size = _X_BE_24(&buffer[5]);
- pts = _X_BE_24(&buffer[8]) | (buffer[11] << 24);
+ ptag_size = _X_BE_32(&buffer[0]);
+ tag_type = buffer[4];
+ data_size = _X_BE_24(&buffer[5]);
+ pts = _X_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 (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);
+ 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;
}
- this->cur_pts = pts;
- }
- /* seek back to the beginning of the tag */
- this->input->seek(this->input, -len, SEEK_CUR);
+ /* seek back to the beginning of the tag */
+ this->input->seek(this->input, -len, SEEK_CUR);
- lprintf( " seeked to %d.\n", pts);
+ lprintf( " seeked to %d.\n", pts);
+ }
}
@@ -807,8 +897,12 @@ static int demux_flv_seek (demux_plugin_t *this_gen,
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 (start_pos && !start_time) {
+ if (this->length)
+ start_time = (int64_t) this->length * start_pos / 65535;
+ else if (this->index)
+ start_time = this->index[(int)(start_pos * (this->num_indices-1) / 65535)].pts;
+ }
if (!this->length || start_time < this->length) {
seek_flv_file(this, start_pos, start_time);
@@ -875,12 +969,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
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)) {
diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c
index f1a423e67..086e0cc98 100644
--- a/src/demuxers/demux_matroska.c
+++ b/src/demuxers/demux_matroska.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2007 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -680,7 +680,11 @@ static void init_codec_aac(demux_matroska_t *this, matroska_track_t *track) {
/* Create a DecoderSpecificInfo for initialising libfaad */
sr_index = aac_get_sr_index(atrack->sampling_freq);
- if (!strncmp (&track->codec_id[12], "MAIN", 4))
+ /* newer specification with appended CodecPrivate */
+ if (strlen(track->codec_id) <= 12)
+ profile = 3;
+ /* older specification */
+ else if (!strncmp (&track->codec_id[12], "MAIN", 4))
profile = 0;
else if (!strncmp (&track->codec_id[12], "LC", 2))
profile = 1;
@@ -1312,7 +1316,7 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader);
/* create a bitmap info header struct for MPEG 4 */
- bih = malloc(sizeof(xine_bmiheader) + track->codec_private_len);
+ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len);
bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len;
bih->biCompression = ME_FOURCC('M', 'P', '4', 'S');
bih->biWidth = track->video_track->pixel_width;
@@ -1336,7 +1340,7 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) {
track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader);
/* create a bitmap info header struct for h264 */
- bih = malloc(sizeof(xine_bmiheader) + track->codec_private_len);
+ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len);
bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len;
bih->biCompression = ME_FOURCC('a', 'v', 'c', '1');
bih->biWidth = track->video_track->pixel_width;
@@ -1925,7 +1929,7 @@ static int parse_block (demux_matroska_t *this, size_t block_size,
lprintf("no lacing\n");
block_size_left = (this->block_data + block_size) - data;
- lprintf("size: %d, block_size: %" PRIu64 "\n", block_size_left, block_size);
+ lprintf("size: %d, block_size: %u\n", block_size_left, block_size);
if (track->handle_content != NULL) {
track->handle_content((demux_plugin_t *)this, track,
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index a9dae3040..85b62f48e 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -342,7 +342,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if((this->dummy_space[0] & 0xf0) == 0x80) {
/* read rest of header - AC3 */
- i = this->input->read (this->input, this->dummy_space+1, 3);
+ this->input->read (this->input, this->dummy_space+1, 3);
/* contents */
for (i = len - 4; i > 0; i -= (this->audio_fifo)
@@ -447,7 +447,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
header_len -= 5 ;
}
- i = this->input->read (this->input, this->dummy_space, header_len);
+ this->input->read (this->input, this->dummy_space, header_len);
for (i = len; i > 0; i -= (this->audio_fifo)
? this->audio_fifo->buffer_pool_buf_size : this->video_fifo->buffer_pool_buf_size) {
@@ -519,7 +519,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
}
/* read rest of header */
- i = this->input->read (this->input, this->dummy_space, header_len);
+ this->input->read (this->input, this->dummy_space, header_len);
/* contents */
diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c
index fd0411e9d..b7c0e7e6d 100644
--- a/src/demuxers/demux_mpeg_pes.c
+++ b/src/demuxers/demux_mpeg_pes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -257,7 +257,6 @@ static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode)
uint8_t *p;
int32_t result;
off_t i;
- int32_t n;
uint8_t buf6[ 6 ];
this->scr = 0;
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index f2e89afee..0df9a426e 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -1088,7 +1088,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
/* read the packet information */
const uint16_t stream = _X_BE_16(&header[4]);
- const off_t offset = this->input->get_current_pos(this->input);
+ const off_t offset __attr_unused = this->input->get_current_pos(this->input);
uint16_t size = _X_BE_16(&header[2]) - DATA_PACKET_HEADER_SIZE;
const uint32_t timestamp= _X_BE_32(&header[6]);
int64_t pts = (int64_t) timestamp * 90;
@@ -1132,7 +1132,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
* seems to be a very short header
* 2 bytes, purpose of the second byte yet unknown
*/
- const int bummer = stream_read_char (this);
+ const int bummer __attr_unused = stream_read_char (this);
lprintf ("bummer == %02X\n",bummer);
vpkg_offset = 0;
diff --git a/src/demuxers/demux_str.c b/src/demuxers/demux_str.c
index a49084ba7..442bffadc 100644
--- a/src/demuxers/demux_str.c
+++ b/src/demuxers/demux_str.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -139,8 +139,7 @@
#define CD_RAW_SECTOR_SIZE 2352
-static const uint8_t STR_MAGIC =
- { 0x60, 0x01, 0x01, 0x80 };
+#define STR_MAGIC "\x60\x01\x01\x80"
#define STR_MAX_CHANNELS 32
#define CDXA_TYPE_MASK 0x0E
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index f53a5a3f4..98de1f9ea 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -249,6 +249,7 @@ typedef struct {
int64_t packet_count;
int corrupted_pes;
uint32_t buffered_bytes;
+ int autodetected;
} demux_ts_media;
@@ -932,9 +933,11 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
m->buf->free_buffer(m->buf);
m->buf = NULL;
- if (m->corrupted_pes > CORRUPT_PES_THRESHOLD) {
- if (this->videoPid == m->pid)
+ if (m->corrupted_pes > CORRUPT_PES_THRESHOLD && m->autodetected) {
+ if (this->videoPid == m->pid) {
this->videoPid = INVALID_PID;
+ this->last_pmt_crc = 0;
+ }
} else {
m->corrupted_pes++;
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1855,6 +1858,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
} else if (!found) {
this->videoPid = pid;
this->videoMedia = this->media_num;
+ this->media[this->videoMedia].autodetected = 1;
demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, 0x100 + pes_stream_id);
}
@@ -2269,6 +2273,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
for (i = 0; i < MAX_PIDS; i++) {
this->media[i].pid = INVALID_PID;
this->media[i].buf = NULL;
+ this->media[i].autodetected = 0;
}
for (i = 0; i < MAX_PMTS; i++) {
diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c
index 4a1cc78ec..5f39395ad 100644
--- a/src/demuxers/demux_wav.c
+++ b/src/demuxers/demux_wav.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2005 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -112,6 +112,7 @@ static int find_chunk_by_tag(demux_wav_t *this, const uint32_t given_chunk_tag,
static int open_wav_file(demux_wav_t *this) {
uint8_t signature[WAV_SIGNATURE_SIZE];
off_t wave_pos;
+ uint32_t wave_size;
/* check the signature */
if (_x_demux_read_header(this->input, signature, WAV_SIGNATURE_SIZE) != WAV_SIGNATURE_SIZE)
@@ -122,8 +123,9 @@ static int open_wav_file(demux_wav_t *this) {
/* search for the 'fmt ' chunk first */
wave_pos = 0;
- if (find_chunk_by_tag(this, fmt_TAG, &this->wave_size, &wave_pos)==0)
+ if (find_chunk_by_tag(this, fmt_TAG, &wave_size, &wave_pos)==0)
return 0;
+ this->wave_size = wave_size;
this->input->seek(this->input, wave_pos, SEEK_SET);
this->wave = malloc( this->wave_size );
@@ -146,7 +148,7 @@ static int open_wav_file(demux_wav_t *this) {
/* search for the 'data' chunk */
this->data_start = this->data_size = 0;
- if (find_chunk_by_tag(this, data_TAG, &this->data_size, &this->data_start)==0)
+ if (find_chunk_by_tag(this, data_TAG, NULL, &this->data_start)==0)
{
free (this->wave);
return 0;
@@ -207,11 +209,16 @@ static int demux_wav_send_chunk(demux_plugin_t *this_gen) {
buf->size = remaining_sample_bytes;
remaining_sample_bytes -= buf->size;
- if (this->input->read(this->input, buf->content, buf->size) !=
+ off_t read;
+ if ((read = this->input->read(this->input, buf->content, buf->size)) !=
buf->size) {
- buf->free_buffer(buf);
- this->status = DEMUX_FINISHED;
- break;
+ if (read == 0) {
+ buf->free_buffer(buf);
+ this->status = DEMUX_FINISHED;
+ break;
+ } else {
+ buf->size = read;
+ }
}
#if 0
diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c
index 3c03fdc68..ba8f50676 100644
--- a/src/demuxers/id3.c
+++ b/src/demuxers/id3.c
@@ -767,6 +767,7 @@ static int id3v24_interp_frame(input_plugin_t *input,
break;
case ( FOURCC_TAG('T', 'Y', 'E', 'R') ):
+ case ( FOURCC_TAG('T', 'D', 'R', 'C') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]);
break;
diff --git a/src/demuxers/matroska.h b/src/demuxers/matroska.h
index 6806c207d..23af84af0 100644
--- a/src/demuxers/matroska.h
+++ b/src/demuxers/matroska.h
@@ -235,7 +235,7 @@ struct matroska_track_s {
void (*handle_content) (demux_plugin_t *this_gen,
matroska_track_t *track,
int decoder_flags,
- uint8_t *data, int data_len,
+ uint8_t *data, size_t data_len,
int64_t data_pts, int data_duration,
int input_normpos, int input_time);
};
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index 06ab9d626..996460832 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -1033,13 +1033,13 @@ network_command( xine_stream_t *stream, int socket, char *data_buf, char *msg, .
#ifndef WIN32
-static int network_connect(xine_stream_t *stream, char *url )
+static int network_connect(xine_stream_t *stream, const char *got_url )
{
- char *host;
+ char *host, *url;
int port;
int fd;
- url = strdup(url);
+ url = strdup(got_url);
parse_url(url, &host, &port);
if( !host || !strlen(host) || !port )
@@ -1450,7 +1450,7 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
while((pdir = readdir(dir)) != NULL) {
char discid[9];
- snprintf(discid, sizeof(discid), "%08lx", this->cddb.disc_id);
+ snprintf(discid, sizeof(discid), "%08" PRIx32, this->cddb.disc_id);
if(!strcasecmp(pdir->d_name, discid)) {
FILE *fd;
@@ -1549,7 +1549,7 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
}
}
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_cdda: cached entry for disc ID %08lx not found.\n", this->cddb.disc_id);
+ "input_cdda: cached entry for disc ID %08" PRIx32 " not found.\n", this->cddb.disc_id);
closedir(dir);
}
@@ -1573,7 +1573,7 @@ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *fileco
_cdda_mkdir_recursive_safe(this->stream->xine, cfile);
- snprintf(cfile, sizeof(cfile), "%s/%08lx", this->cddb.cache_dir, this->cddb.disc_id);
+ snprintf(cfile, sizeof(cfile), "%s/%08" PRIx32 , this->cddb.cache_dir, this->cddb.disc_id);
if((fd = fopen(cfile, "w")) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
@@ -1712,7 +1712,7 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
/* Send query command */
memset(&buffer, 0, sizeof(buffer));
- size_t size = sprintf(buffer, "cddb query %08lx %d ", this->cddb.disc_id, this->cddb.num_tracks);
+ size_t size = sprintf(buffer, "cddb query %08" PRIx32 " %d ", this->cddb.disc_id, this->cddb.num_tracks);
for (i = 0; i < this->cddb.num_tracks; i++) {
size += snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start);
}
@@ -2004,7 +2004,7 @@ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) {
*/
static int cdda_open(cdda_input_plugin_t *this_gen,
- char *cdda_device, cdrom_toc *toc, int *fdd) {
+ const char *cdda_device, cdrom_toc *toc, int *fdd) {
#ifndef WIN32
int fd = -1;
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 29a38bbf1..4a1e71a38 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -286,7 +286,7 @@ typedef struct {
xine_t *xine;
- char *mrls[5];
+ char *mrls[6];
int numchannels;
@@ -3200,7 +3200,6 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
{
dvb_input_class_t *class = (dvb_input_class_t *) this_gen;
channel_t *channels=NULL;
- char foobuffer[BUFSIZE];
int ch, apch, num_channels = 0;
int default_channel = -1;
xine_cfg_entry_t lastchannel_enable = {0};
diff --git a/src/input/input_smb.c b/src/input/input_smb.c
index 9050e6ec3..4d7e9a94a 100644
--- a/src/input/input_smb.c
+++ b/src/input/input_smb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 the xine project
+ * Copyright (C) 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -51,7 +51,7 @@ typedef struct {
xine_stream_t *stream;
/* File */
- char *mrl;
+ const char *mrl;
int fd;
} smb_input_t;
@@ -145,7 +145,7 @@ smb_plugin_get_length (input_plugin_t *this_gen)
return st.st_size;
}
-static char*
+static const char*
smb_plugin_get_mrl (input_plugin_t *this_gen)
{
smb_input_t *this = (smb_input_t *) this_gen;
@@ -157,7 +157,7 @@ static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) {
return 0;
}
-static char
+static const char
*smb_class_get_description (input_class_t *this_gen)
{
return _("CIFS/SMB input plugin based on libsmbclient");
@@ -287,7 +287,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup("smb:/");
- asprintf(*(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
} else if (pdirent->smbc_type == SMBC_FILE_SHARE){
@@ -430,7 +430,7 @@ smb_plugin_dispose (input_plugin_t *this_gen )
if (this->fd>=0)
smbc_close(this->fd);
if (this->mrl)
- free (this->mrl);
+ free ((char *)this->mrl);
free (this);
}
diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c
index b97f11ace..3a020bd69 100644
--- a/src/input/input_v4l.c
+++ b/src/input/input_v4l.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2004 the xine project
+ * Copyright (C) 2003-2008 the xine project
* Copyright (C) 2003 J.Asselman <j.asselman@itsec-ps.nl>
*
* This file is part of xine, a free video player.
@@ -100,10 +100,6 @@ static const resolution_t resolutions[] = {
static char *tv_standard_names[] = { "AUTO", "PAL", "NTSC", "SECAM", "OLD", NULL };
static int tv_standard_values[] = { VIDEO_MODE_AUTO, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM, -1 };
-#if !defined(NDELAY) && defined(O_NDELAY)
-#define FNDELAY O_NDELAY
-#endif
-
typedef struct pvrscr_s pvrscr_t;
typedef struct {
@@ -844,7 +840,7 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
{
int found = 0;
int tuner_found = 0;
- int i, ret;
+ int ret;
unsigned int j;
cfg_entry_t *entry;
@@ -1870,11 +1866,11 @@ static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen,
* v4l input plugin class stuff
*/
-static char *v4l_class_get_video_description (input_class_t *this_gen) {
+static const char *v4l_class_get_video_description (input_class_t *this_gen) {
return _("v4l tv input plugin");
}
-static char *v4l_class_get_radio_description (input_class_t *this_gen) {
+static const char *v4l_class_get_radio_description (input_class_t *this_gen) {
return _("v4l radio input plugin");
}
diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c
index 90f6fcc70..760910a01 100644
--- a/src/input/input_vcd.c
+++ b/src/input/input_vcd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -939,7 +939,6 @@ static void vcd_filelist_dispose(vcd_input_class_t *this) {
static void vcd_class_dispose (input_class_t *this_gen) {
vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
- int i;
config_values_t *config = this->xine->config;
config->unregister_callback(config, "media.vcd.device");
@@ -1068,7 +1067,6 @@ static void *init_class (xine_t *xine, void *data) {
vcd_input_class_t *this;
config_values_t *config = xine->config;
- int i;
this = calloc(1, sizeof (vcd_input_class_t));
diff --git a/src/input/mms.c b/src/input/mms.c
index ab1983955..b2d00a46e 100644
--- a/src/input/mms.c
+++ b/src/input/mms.c
@@ -290,7 +290,7 @@ static int send_command (mms_t *this, int command,
#ifdef USE_ICONV
static iconv_t string_utf16_open() {
- return iconv_open("UTF-16LE", nl_langinfo(CODESET));
+ return iconv_open("UTF-16LE", "UTF-8");
}
static void string_utf16_close(iconv_t url_conv) {
@@ -771,10 +771,17 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
/* command 0x5 */
{
mms_buffer_t command_buffer;
- char *path = this->uri;
- size_t pathlen = strlen(path);
+ char *path, *unescaped;
+ size_t pathlen;
+
+ unescaped = strdup (this->uri);
+ if (!unescaped)
+ goto fail;
+ _x_mrl_unescape (unescaped);
/* remove the first '/' */
+ path = unescaped;
+ pathlen = strlen (path);
if (pathlen > 1) {
path++;
pathlen--;
@@ -785,6 +792,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
string_utf16 (url_conv, this->scmd_body + command_buffer.pos, path, pathlen);
+ free (unescaped);
if (!send_command (this, 5, 1, 0xffffffff, pathlen * 2 + 12))
goto fail;
}
diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c
index f4f823918..55b7f9b84 100644
--- a/src/input/vcd/xineplug_inp_vcd.c
+++ b/src/input/vcd/xineplug_inp_vcd.c
@@ -966,7 +966,7 @@ vcd_class_eject_media (input_class_t *this_gen)
* From spec:
* return current MRL
*/
-static char *
+static const char *
vcd_plugin_get_mrl (input_plugin_t *this_gen)
{
vcd_input_plugin_t *t = (vcd_input_plugin_t *) this_gen;
@@ -987,7 +987,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
/* Bad type. */
LOG_ERR("%s %d", _("Invalid current entry type"),
vcdplayer->play_item.type);
- return strdup("");
+ return "";
} else {
n += offset;
if (n < t->class->num_mrls) {
@@ -995,7 +995,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
t->class->mrls[n]->mrl);
return t->class->mrls[n]->mrl;
} else {
- return strdup("");
+ return "";
}
}
}
@@ -1005,7 +1005,7 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
return human readable (verbose = 1 line) description for this plugin
*/
-static char *
+static const char *
vcd_class_get_description (input_class_t *this_gen)
{
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
diff --git a/src/libfaad/xine_faad_decoder.c b/src/libfaad/xine_faad_decoder.c
index ae71af155..9c657610e 100644
--- a/src/libfaad/xine_faad_decoder.c
+++ b/src/libfaad/xine_faad_decoder.c
@@ -275,7 +275,32 @@ static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) {
lprintf("decoded %d/%d output %ld\n",
used, this->size, this->faac_finfo.samples );
-
+
+ /* Performing necessary channel reordering because aac uses a different
+ * layout than alsa:
+ *
+ * aac 5.1 channel layout: c l r ls rs lfe
+ * alsa 5.1 channel layout: l r ls rs c lfe
+ *
+ * Reordering is only necessary for 5.0 and above. Currently only 5.0
+ * and 5.1 is being taken care of, the rest will stay in the wrong order
+ * for now.
+ *
+ * WARNING: the following needs a output format of 16 bits per sample.
+ * TODO: - reorder while copying (in the while() loop) and optimizing
+ */
+ if(this->num_channels == 5 || this->num_channels == 6)
+ {
+ int i = 0;
+ uint16_t* buf = (uint16_t*)(sample_buffer);
+
+ for(; i < this->faac_finfo.samples; i += this->num_channels) {
+ uint16_t center = buf[i];
+ *((uint64_t*)(buf + i)) = *((uint64_t*)(buf + i + 1));
+ buf[i + 4] = center;
+ }
+ }
+
while( decoded ) {
audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out);
diff --git a/src/libmad/bit.c b/src/libmad/bit.c
index 8d9571e8f..cd0fe4904 100644
--- a/src/libmad/bit.c
+++ b/src/libmad/bit.c
@@ -27,7 +27,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+# endif
+# ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmad/layer12.c b/src/libmad/layer12.c
index 25fd04d70..76def1189 100644
--- a/src/libmad/layer12.c
+++ b/src/libmad/layer12.c
@@ -27,7 +27,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+# endif
+#ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmad/layer3.c b/src/libmad/layer3.c
index c5d46e8d1..899102e0d 100644
--- a/src/libmad/layer3.c
+++ b/src/libmad/layer3.c
@@ -34,7 +34,8 @@
# ifdef HAVE_LIMITS_H
# include <limits.h>
-# else
+#endif
+# ifndef CHAR_BIT
# define CHAR_BIT 8
# endif
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
index 9895aa5d7..5a9f1302c 100644
--- a/src/libmpeg2/Makefile.am
+++ b/src/libmpeg2/Makefile.am
@@ -22,7 +22,7 @@ xineplug_decode_mpeg2_la_SOURCES = \
xine_mpeg2_decoder.c \
libmpeg2_accel.c
-xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm
+xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(LTLIBINTL) -lm
xineplug_decode_mpeg2_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBMPEG2_CFLAGS)
xineplug_decode_mpeg2_la_LDFLAGS = $(xineplug_ldflags)
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index 253f300a2..ae69688f5 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -31,7 +31,8 @@ typedef struct mpeg2dec_s {
uint32_t frame_format;
/* this is where we keep the state of the decoder */
- struct picture_s * picture, *picture_base;
+ struct picture_s * picture;
+ void *picture_base;
uint32_t shift;
int new_sequence;
@@ -45,7 +46,8 @@ typedef struct mpeg2dec_s {
/* which is 224K for MP@ML streams. */
/* (we make no pretenses of decoding anything more than that) */
/* allocated in init - gcc has problems allocating such big structures */
- uint8_t * chunk_buffer, *chunk_base;
+ uint8_t * chunk_buffer;
+ void *chunk_base;
/* pointer to current position in chunk_buffer */
uint8_t * chunk_ptr;
/* last start code ? */
diff --git a/src/libreal/xine_real_audio_decoder.c b/src/libreal/xine_real_audio_decoder.c
index 7f4942cc5..20f67a984 100644
--- a/src/libreal/xine_real_audio_decoder.c
+++ b/src/libreal/xine_real_audio_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -510,7 +510,6 @@ static void dispose_class (audio_decoder_class_t *this) {
void *init_realadec (xine_t *xine, void *data) {
real_class_t *this;
- config_values_t *config = xine->config;
this = (real_class_t *) calloc(1, sizeof(real_class_t));
diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c
index e048b04d6..3c575d0a8 100644
--- a/src/libreal/xine_real_video_decoder.c
+++ b/src/libreal/xine_real_video_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -533,7 +533,6 @@ static void dispose_class (video_decoder_class_t *this) {
void *init_realvdec (xine_t *xine, void *data) {
real_class_t *this;
- config_values_t *config = xine->config;
this = (real_class_t *) calloc(1, sizeof(real_class_t));
diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h
index 8698189a6..47703b6d1 100644
--- a/src/libspucc/cc_decoder.h
+++ b/src/libspucc/cc_decoder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* Copyright (C) Christian Vogler
* cvogler@gradient.cis.upenn.edu - December 2001
@@ -31,11 +31,7 @@ typedef struct cc_decoder_s cc_decoder_t;
typedef struct cc_renderer_s cc_renderer_t;
#define NUM_CC_PALETTES 2
-static const char *cc_schemes[NUM_CC_PALETTES + 1] = {
- "White/Gray/Translucent",
- "White/Black/Solid",
- NULL
-};
+extern const char *cc_schemes[];
#define CC_FONT_MAX 256
diff --git a/src/libspucc/xine_cc_decoder.c b/src/libspucc/xine_cc_decoder.c
index 0018bfa1e..1d9c87366 100644
--- a/src/libspucc/xine_cc_decoder.c
+++ b/src/libspucc/xine_cc_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -33,6 +33,12 @@
#define LOG_DEBUG 1
*/
+const char *cc_schemes[NUM_CC_PALETTES + 1] = {
+ "White/Gray/Translucent",
+ "White/Black/Solid",
+ NULL
+};
+
typedef struct spucc_decoder_s {
spu_decoder_t spu_decoder;
@@ -193,7 +199,7 @@ static void spucc_register_cfg_vars(spucc_class_t *this,
cc_vars->cc_scheme = xine_cfg->register_enum(xine_cfg,
"subtitles.closedcaption.scheme", 0,
- cc_schemes,
+ (char **)cc_schemes,
_("closed-captioning foreground/background scheme"),
_("Choose your favourite rendering of the closed "
"captions."),
diff --git a/src/libspucmml/xine_cmml_decoder.c b/src/libspucmml/xine_cmml_decoder.c
index 1a8f65e14..c3da1b0fd 100644
--- a/src/libspucmml/xine_cmml_decoder.c
+++ b/src/libspucmml/xine_cmml_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -446,7 +446,7 @@ static spu_decoder_t *spucmml_class_open_plugin (spu_decoder_class_t *class_gen,
this->spu_decoder.set_button = NULL;
this->spu_decoder.dispose = spudec_dispose;
- this->class = class_gen;
+ this->class = class;
this->stream = stream;
this->event_queue = xine_event_new_queue (this->stream);
diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am
index 208d994f5..7c0dcd78d 100644
--- a/src/libspudec/Makefile.am
+++ b/src/libspudec/Makefile.am
@@ -7,7 +7,7 @@ if HAVE_DVDNAV
xineplug_decode_spu_la_SOURCES = \
spu.c \
xine_spu_decoder.c
-xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS)
+xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(DVDNAV_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
else
@@ -16,7 +16,7 @@ xineplug_decode_spu_la_SOURCES = \
spu.c \
xine_spu_decoder.c
AM_CPPFLAGS = -I$(top_srcdir)/src/input/libdvdnav
-xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS)
+xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL)
endif
diff --git a/src/libspudec/xine_spu_decoder.c b/src/libspudec/xine_spu_decoder.c
index e63bdf8b9..02bae6ac9 100644
--- a/src/libspudec/xine_spu_decoder.c
+++ b/src/libspudec/xine_spu_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001
*
@@ -70,7 +70,6 @@ static const clut_t default_clut[] = {
static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spudec_decoder_t *this = (spudec_decoder_t *) this_gen;
const uint8_t stream_id = buf->type & 0x1f ;
- spudec_seq_t *cur_seq = &this->spudec_stream_state[stream_id].ra_seq;
#ifdef LOG_DEBUG
printf("libspudec:got buffer type = %x\n", buf->type);
diff --git a/src/libspudvb/xine_spudvb_decoder.c b/src/libspudvb/xine_spudvb_decoder.c
index 957374799..bcb0cbf96 100644
--- a/src/libspudvb/xine_spudvb_decoder.c
+++ b/src/libspudvb/xine_spudvb_decoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 the xine project
+ * Copyright (C) 2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -48,6 +48,7 @@ typedef struct {
} page_t;
typedef struct {
+ int version_number;
int width, height;
int empty;
int depth;
@@ -141,7 +142,6 @@ static void update_region (dvb_spu_decoder_t * this, int region_id, int region_w
dvbsub_func_t *dvbsub = this->dvbsub;
region_t *reg = &dvbsub->regions[region_id];
- page_t *page = &dvbsub->page;
/* reject invalid sizes and set some limits ! */
if ( region_width<=0 || region_height<=0 || region_width>720 || region_height>576 ) {
@@ -166,20 +166,18 @@ static void update_region (dvb_spu_decoder_t * this, int region_id, int region_w
lprintf( "can't allocate mem for region %d\n", region_id );
return;
}
- fill_color = 15;
fill = 1;
}
-
+
if ( fill ) {
memset( reg->img, fill_color, region_width*region_height );
reg->empty = 1;
#ifdef LOG
- printf("SPUDVB : FILL REGION %d\n", region_id);
+ printf("SPUDVB : FILL REGION %d\n", region_id);
#endif
}
reg->width = region_width;
reg->height = region_height;
- page->regions[region_id].is_visible = 1;
}
@@ -328,22 +326,27 @@ static void set_clut(dvb_spu_decoder_t *this,int CLUT_id,int CLUT_entry_id,int Y
static void process_CLUT_definition_segment(dvb_spu_decoder_t *this) {
dvbsub_func_t *dvbsub = this->dvbsub;
- const uint16_t page_id= _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ /*
+ const uint16_t page_id= _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ */
dvbsub->i+=2;
const uint16_t segment_length= _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i+=2;
const int j=dvbsub->i+segment_length;
const uint8_t CLUT_id=dvbsub->buf[dvbsub->i++];
- const uint8_t CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4;
+ /*
+ const uint8_t CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4;
+ */
dvbsub->i++;
while (dvbsub->i < j) {
const uint8_t CLUT_entry_id=dvbsub->buf[dvbsub->i++];
-
- const uint8_t CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7;
- const uint8_t CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6;
- const uint8_t CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5;
+ /*
+ const uint8_t CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7;
+ const uint8_t CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6;
+ const uint8_t CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5;
+ */
const uint8_t full_range_flag=dvbsub->buf[dvbsub->i]&1;
dvbsub->i++;
@@ -409,17 +412,18 @@ static void process_page_composition_segment (dvb_spu_decoder_t * this)
const int j = dvbsub->i + segment_length;
dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++];
+ if ( dvbsub->page.page_time_out>6 ) /* some timeout are insane, e.g. 65s ! */
+ dvbsub->page.page_time_out = 6;
- dvbsub->page.page_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ int version = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ if ( version == dvbsub->page.page_version_number )
+ return;
+ dvbsub->page.page_version_number = version;
dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
dvbsub->i++;
- if (dvbsub->page.page_state==2) {
- int r;
- for (r=0; r<MAX_REGIONS; r++)
- dvbsub->page.regions[r].is_visible = 0;
- }
- else if ( dvbsub->page.page_state!=0 && dvbsub->page.page_state!=1 ) {
- return;
+ int r;
+ for (r=0; r<MAX_REGIONS; r++) { /* reset */
+ dvbsub->page.regions[r].is_visible = 0;
}
while (dvbsub->i < j) {
@@ -432,6 +436,7 @@ static void process_page_composition_segment (dvb_spu_decoder_t * this)
dvbsub->page.regions[region_id].x = region_x;
dvbsub->page.regions[region_id].y = region_y;
+ dvbsub->page.regions[region_id].is_visible = 1;
}
}
@@ -454,17 +459,29 @@ static void process_region_composition_segment (dvb_spu_decoder_t * this)
dvbsub->i += 2;
const uint16_t region_height = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
- const uint8_t region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5;
- const uint8_t region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2;
+ /*
+ const uint8_t region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5;
+ const uint8_t region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2;
+ */
dvbsub->i++;
const uint8_t CLUT_id = dvbsub->buf[dvbsub->i++];
- const uint8_t region_8_bit_pixel_code = dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t region_8_bit_pixel_code = dvbsub->buf[dvbsub->i];
+ */
+ dvbsub->i++;
const uint8_t region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
- const uint8_t region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
+ /*
+ const uint8_t region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
+ */
dvbsub->i++;
if(region_id>=MAX_REGIONS)
return;
+
+ if ( dvbsub->regions[region_id].version_number == region_version_number )
+ return;
+
+ dvbsub->regions[region_id].version_number = region_version_number;
/* Check if region size has changed and fill background. */
update_region (this, region_id, region_width, region_height, region_fill_flag, region_4_bit_pixel_code);
@@ -485,7 +502,9 @@ static void process_region_composition_segment (dvb_spu_decoder_t * this)
const uint16_t object_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
const uint8_t object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6;
- const uint8_t object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4;
+ /*
+ const uint8_t object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4;
+ */
const uint16_t object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
dvbsub->i += 2;
const uint16_t object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
@@ -494,8 +513,11 @@ static void process_region_composition_segment (dvb_spu_decoder_t * this)
dvbsub->regions[region_id].object_pos[object_id] = (object_x << 16) | object_y;
if ((object_type == 0x01) || (object_type == 0x02)) {
- const uint8_t foreground_pixel_code = dvbsub->buf[dvbsub->i++];
- const uint8_t background_pixel_code = dvbsub->buf[dvbsub->i++];
+ /*
+ const uint8_t foreground_pixel_code = dvbsub->buf[dvbsub->i];
+ const uint8_t background_pixel_code = dvbsub->buf[dvbsub->i+1];
+ */
+ dvbsub->i += 2;
}
}
@@ -507,16 +529,19 @@ static void process_object_data_segment (dvb_spu_decoder_t * this)
dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
dvbsub->i += 2;
- const uint16_t segment_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ /*
+ const uint16_t segment_length = _X_BE_16(&dvbsub->buf[dvbsub->i]);
+ */
dvbsub->i += 2;
- const int j = dvbsub->i + segment_length;
const uint16_t object_id = _X_BE_16(&dvbsub->buf[dvbsub->i]);
dvbsub->i += 2;
dvbsub->curr_obj = object_id;
- const uint8_t object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
const uint8_t object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
- const uint8_t non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1;
+ /*
+ const uint8_t object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
+ const uint8_t non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1;
+ */
dvbsub->i++;
if ( object_coding_method != 0 )
@@ -673,6 +698,9 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
printf("SPUDVB: this->vpts=%llu\n",this->vpts);
#endif
for ( r=0; r<MAX_REGIONS; r++ ) {
+#ifdef LOG
+ printf("SPUDVB : region=%d, visible=%d, osd=%d, empty=%d\n", r, this->dvbsub->page.regions[r].is_visible, this->dvbsub->regions[r].osd?1:0, this->dvbsub->regions[r].empty );
+#endif
if ( this->dvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) {
this->stream->osd_renderer->set_position( this->dvbsub->regions[r].osd, this->dvbsub->page.regions[r].x, this->dvbsub->page.regions[r].y );
this->stream->osd_renderer->show( this->dvbsub->regions[r].osd, this->vpts );
@@ -761,17 +789,22 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
this->vpts = vpts;
}
+ /* completely ignore pts since it makes a lot of problems with various providers */
+ this->vpts = 0;
+
/* process the pes section */
const int PES_packet_length = this->pes_pkt_size;
this->dvbsub->buf = this->pes_pkt;
- int PES_header_data_length = 0;
this->dvbsub->i = 0;
- const uint8_t data_identifier = this->dvbsub->buf[this->dvbsub->i++];
- const uint8_t subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i++];
+ /*
+ const uint8_t data_identifier = this->dvbsub->buf[this->dvbsub->i];
+ const uint8_t subtitle_stream_id = this->dvbsub->buf[this->dvbsub->i+1];
+ */
+ this->dvbsub->i += 2;
while (this->dvbsub->i <= (PES_packet_length)) {
/* SUBTITLING SEGMENT */
@@ -791,10 +824,10 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
/* SEGMENT_DATA_FIELD */
switch (segment_type) {
case 0x10:
- process_page_composition_segment (this);
+ process_page_composition_segment(this);
break;
case 0x11:
- process_region_composition_segment (this);
+ process_region_composition_segment(this);
break;
case 0x12:
process_CLUT_definition_segment(this);
@@ -802,8 +835,8 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
case 0x13:
process_object_data_segment (this);
break;
- case 0x80: /* Page is now completely rendered */
- draw_subtitles( this );
+ case 0x80:
+ draw_subtitles( this ); /* Page is now completely rendered */
break;
default:
return;
@@ -824,7 +857,9 @@ static void spudec_reset (spu_decoder_t * this_gen)
for ( i=0; i<MAX_REGIONS; i++ ) {
if ( this->dvbsub->regions[i].osd )
this->stream->osd_renderer->hide(this->dvbsub->regions[i].osd, 0);
+ this->dvbsub->regions[i].version_number = -1;
}
+ this->dvbsub->page.page_version_number = -1;
pthread_mutex_unlock(&this->dvbsub_osd_mutex);
}
@@ -861,6 +896,7 @@ static void spudec_dispose (spu_decoder_t * this_gen)
static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream)
{
dvb_spu_decoder_t *this = calloc(1, sizeof (dvb_spu_decoder_t));
+ dvb_spu_class_t *class = (dvb_spu_class_t *)class_gen;
this->spu_decoder.decode_data = spudec_decode_data;
this->spu_decoder.reset = spudec_reset;
@@ -869,7 +905,7 @@ static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen
this->spu_decoder.get_interact_info = NULL;
this->spu_decoder.set_button = NULL;
- this->class = class_gen;
+ this->class = class;
this->stream = stream;
this->pes_pkt = calloc(65, 1024);
diff --git a/src/libw32dll/wine/win32.c b/src/libw32dll/wine/win32.c
index 9d99e1a25..d9744ae35 100644
--- a/src/libw32dll/wine/win32.c
+++ b/src/libw32dll/wine/win32.c
@@ -1430,7 +1430,7 @@ static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
}
static int WINAPI expGetCurrentThreadId()
{
- dbgprintf("GetCurrentThreadId() => %ld\n", pthread_self());
+ dbgprintf("GetCurrentThreadId() => %ld\n", (long int)pthread_self());
return (int)pthread_self();
}
static int WINAPI expGetCurrentProcess()
@@ -2134,7 +2134,6 @@ static const char* WINAPI expGetCommandLineA()
dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
return "c:\\aviplay.exe";
}
-static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
static LPWSTR WINAPI expGetEnvironmentStringsW()
{
dbgprintf("GetEnvironmentStringsW() => 0\n");
@@ -3998,7 +3997,7 @@ static int XINE_FORMAT_PRINTF(2, 3) expsprintf(char* str, const char* format, ..
va_end(args);
return r;
}
-static int XINE_FORMAT_PRINTF(2, 3) expsscanf(const char* str, const char* format, ...)
+static int XINE_FORMAT_SCANF(2, 3) expsscanf(const char* str, const char* format, ...)
{
va_list args;
int r;
@@ -4162,7 +4161,7 @@ static void* expmemset(void* dest, int c, size_t n)
static time_t exptime(time_t* t)
{
time_t result = time(t);
- dbgprintf("time(%p) => %ld\n", t, result);
+ dbgprintf("time(%p) => %ld\n", t, (long int)result);
return result;
}
diff --git a/src/libxineadec/Makefile.am b/src/libxineadec/Makefile.am
index d502b7955..a97cd1934 100644
--- a/src/libxineadec/Makefile.am
+++ b/src/libxineadec/Makefile.am
@@ -39,7 +39,7 @@ xineplug_decode_lpcm_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB)
xineplug_decode_vorbis_la_SOURCES = xine_vorbis_decoder.c
-xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS)
+xineplug_decode_vorbis_la_LIBADD = $(XINE_LIB) $(VORBIS_LIBS) $(OGG_LIBS) $(LTLIBINTL)
xineplug_decode_vorbis_la_CFLAGS = $(VISIBILITY_FLAG) $(VORBIS_CFLAGS)
xineplug_decode_speex_la_SOURCES = xine_speex_decoder.c
diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am
index 9805eb09e..81219d67e 100644
--- a/src/libxinevdec/Makefile.am
+++ b/src/libxinevdec/Makefile.am
@@ -43,4 +43,4 @@ xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXB
xineplug_decode_theora_la_SOURCES = xine_theora_decoder.c
xineplug_decode_theora_la_CFLAGS = $(AM_CFLAGS) $(OGG_CFLAGS) $(THEORA_CFLAGS)
-xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS)
+xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS) $(LTLIBINTL)
diff --git a/src/post/audio/filter.c b/src/post/audio/filter.c
index c5602736c..55d75e1e4 100644
--- a/src/post/audio/filter.c
+++ b/src/post/audio/filter.c
@@ -414,7 +414,7 @@ void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef
*
* return -1 if fail 0 if success.
*/
-int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef)
+int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef)
{
_ftype_t at[3];
_ftype_t bt[3];
diff --git a/src/post/audio/filter.h b/src/post/audio/filter.h
index 0b0ce1c1b..0e08aa2b9 100644
--- a/src/post/audio/filter.h
+++ b/src/post/audio/filter.h
@@ -55,7 +55,7 @@ extern int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** p
extern void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs);
void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef);
-extern int szxform(_ftype_t* a, _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef);
+extern int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef);
/* Add new data to circular queue designed to be used with a FIR
* filter. xq is the circular queue, in pointing at the new sample, xi
diff --git a/src/post/audio/volnorm.c b/src/post/audio/volnorm.c
index 4fdb7dbfc..792618322 100644
--- a/src/post/audio/volnorm.c
+++ b/src/post/audio/volnorm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -412,7 +412,6 @@ static post_plugin_t *volnorm_open_plugin(post_class_t *class_gen, int inputs,
post_out_t *output;
xine_post_in_t *input_api;
post_audio_port_t *port;
- int i;
if (!this || !audio_target || !audio_target[0] ) {
free(this);
diff --git a/src/post/deinterlace/tvtime.c b/src/post/deinterlace/tvtime.c
index eff43d5e8..97da6543e 100644
--- a/src/post/deinterlace/tvtime.c
+++ b/src/post/deinterlace/tvtime.c
@@ -38,14 +38,6 @@
#include "tvtime.h"
/**
- * This is how many frames to wait until deciding if the pulldown phase
- * has changed or if we've really found a pulldown sequence. This is
- * currently set to about 1 second, that is, we won't go into film mode
- * until we've seen a pulldown sequence successfully for 1 second.
- */
-#define PULLDOWN_ERROR_WAIT 60
-
-/**
* This is how many predictions have to be incorrect before we fall back to
* video mode. Right now, if we mess up, we jump to video mode immediately.
*/
@@ -192,13 +184,13 @@ int tvtime_build_deinterlaced_frame( tvtime_t *tvtime, uint8_t *output,
if( !tvtime->pdoffset ) {
/* No pulldown offset applies, drop out of pulldown immediately. */
tvtime->pdlastbusted = 0;
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
} else if( tvtime->pdoffset != predicted ) {
if( tvtime->pdlastbusted ) {
tvtime->pdlastbusted--;
tvtime->pdoffset = predicted;
} else {
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
}
} else {
if( tvtime->pderror ) {
@@ -437,7 +429,7 @@ void tvtime_reset_context( tvtime_t *tvtime )
tvtime->last_botdiff = 0;
tvtime->pdoffset = PULLDOWN_SEQ_AA;
- tvtime->pderror = PULLDOWN_ERROR_WAIT;
+ tvtime->pderror = tvtime->pulldown_error_wait;
tvtime->pdlastbusted = 0;
tvtime->filmmode = 0;
}
diff --git a/src/post/deinterlace/tvtime.h b/src/post/deinterlace/tvtime.h
index 8e4c5abc2..2253f264e 100644
--- a/src/post/deinterlace/tvtime.h
+++ b/src/post/deinterlace/tvtime.h
@@ -56,6 +56,11 @@ typedef struct {
*/
deinterlace_method_t *curmethod;
+ /**
+ * This is how many frames to wait until deciding if the pulldown phase
+ * has changed or if we've really found a pulldown sequence.
+ */
+ unsigned int pulldown_error_wait;
/* internal data */
int last_topdiff;
diff --git a/src/post/deinterlace/xine_plugin.c b/src/post/deinterlace/xine_plugin.c
index 8115198af..dfc07e434 100644
--- a/src/post/deinterlace/xine_plugin.c
+++ b/src/post/deinterlace/xine_plugin.c
@@ -69,6 +69,7 @@ typedef struct deinterlace_parameters_s {
int method;
int enabled;
int pulldown;
+ int pulldown_error_wait;
int framerate_mode;
int judder_correction;
int use_progressive_frame_flag;
@@ -87,6 +88,8 @@ PARAM_ITEM( POST_PARAM_TYPE_BOOL, enabled, NULL, 0, 1, 0,
"enable/disable" )
PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown, enum_pulldown, 0, 0, 0,
"pulldown algorithm" )
+PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown_error_wait, NULL, 0, 0, 0,
+ "number of frames of telecine pattern sync required before mode change" )
PARAM_ITEM( POST_PARAM_TYPE_INT, framerate_mode, enum_framerate, 0, 0, 0,
"framerate output mode" )
PARAM_ITEM( POST_PARAM_TYPE_BOOL, judder_correction, NULL, 0, 1, 0,
@@ -165,6 +168,7 @@ static int set_parameters (xine_post_t *this_gen, void *param_gen) {
this->enabled = param->enabled;
this->pulldown = param->pulldown;
+ this->tvtime->pulldown_error_wait = param->pulldown_error_wait;
this->framerate_mode = param->framerate_mode;
this->judder_correction = param->judder_correction;
this->use_progressive_frame_flag = param->use_progressive_frame_flag;
@@ -185,6 +189,7 @@ static int get_parameters (xine_post_t *this_gen, void *param_gen) {
param->method = this->cur_method;
param->enabled = this->enabled;
param->pulldown = this->pulldown;
+ param->pulldown_error_wait = this->tvtime->pulldown_error_wait;
param->framerate_mode = this->framerate_mode;
param->judder_correction = this->judder_correction;
param->use_progressive_frame_flag = this->use_progressive_frame_flag;
@@ -212,6 +217,9 @@ static char * get_static_help (void) {
"\n"
" Enabled: Enable/disable the plugin.\n"
"\n"
+ " Pulldown_error_wait: Ensures that the telecine pattern has been "
+ "locked for this many frames before changing to filmmode.\n"
+ "\n"
" Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films "
"that have being converted to NTSC can be detected and intelligently "
"reconstructed to their original (non-interlaced) frames.\n"
@@ -350,6 +358,7 @@ static void *deinterlace_init_plugin(xine_t *xine, void *data)
class->init_param.method = 1; /* First (plugin) method available */
class->init_param.enabled = 1;
class->init_param.pulldown = 1; /* vektor */
+ class->init_param.pulldown_error_wait = 60; /* about one second */
class->init_param.framerate_mode = 0; /* full */
class->init_param.judder_correction = 1;
class->init_param.use_progressive_frame_flag = 1;
diff --git a/src/post/goom/convolve_fx.c b/src/post/goom/convolve_fx.c
index c394f3bf8..ee36dfd0b 100644
--- a/src/post/goom/convolve_fx.c
+++ b/src/post/goom/convolve_fx.c
@@ -73,7 +73,7 @@ static void set_motif(ConvData *data, Motif motif)
static void convolve_init(VisualFX *_this, PluginInfo *info) {
ConvData *data;
- data = (ConvData*)malloc(sizeof(ConvData));
+ data = (ConvData*)calloc(1, sizeof(ConvData));
_this->fx_data = (void*)data;
data->light = secure_f_param("Screen Brightness");
diff --git a/src/post/goom/diff_against_release.patch b/src/post/goom/diff_against_release.patch
index bde85c285..a5e84b8d1 100644
--- a/src/post/goom/diff_against_release.patch
+++ b/src/post/goom/diff_against_release.patch
@@ -653,3 +653,40 @@ diff -u -p -r1.2 -r1.3
#endif
+diff -r 96c7f8460d61 src/post/goom/convolve_fx.c
+--- convolve_fx.c Mon Nov 10 16:33:51 2008 +0100
++++ convolve_fx.c Sun Nov 16 21:14:29 2008 +0100
+@@ -73,7 +73,7 @@ static void set_motif(ConvData *data, Mo
+
+ static void convolve_init(VisualFX *_this, PluginInfo *info) {
+ ConvData *data;
+- data = (ConvData*)malloc(sizeof(ConvData));
++ data = (ConvData*)calloc(1, sizeof(ConvData));
+ _this->fx_data = (void*)data;
+
+ data->light = secure_f_param("Screen Brightness");
+diff -r 96c7f8460d61 src/post/goom/goom_core.c
+--- goom_core.c Mon Nov 10 16:33:51 2008 +0100
++++ goom_core.c Sun Nov 16 21:14:29 2008 +0100
+@@ -76,6 +76,10 @@ PluginInfo *goom_init (guint32 resx, gui
+ goomInfo->tentacles_fx = tentacle_fx_create();
+ goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo);
+
++ goomInfo->screen.width = resx;
++ goomInfo->screen.height = resy;
++ goomInfo->screen.size = resx * resy;
++
+ goomInfo->convolve_fx = convolve_create();
+ goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo);
+
+@@ -83,10 +87,6 @@ PluginInfo *goom_init (guint32 resx, gui
+ plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx);
+ plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
+ plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
+-
+- goomInfo->screen.width = resx;
+- goomInfo->screen.height = resy;
+- goomInfo->screen.size = resx * resy;
+
+ init_buffers(goomInfo, goomInfo->screen.size);
+ goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel);
diff --git a/src/post/goom/goom_core.c b/src/post/goom/goom_core.c
index 35fd7fc35..62d9a27b6 100644
--- a/src/post/goom/goom_core.c
+++ b/src/post/goom/goom_core.c
@@ -76,6 +76,10 @@ PluginInfo *goom_init (guint32 resx, guint32 resy)
goomInfo->tentacles_fx = tentacle_fx_create();
goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo);
+ goomInfo->screen.width = resx;
+ goomInfo->screen.height = resy;
+ goomInfo->screen.size = resx * resy;
+
goomInfo->convolve_fx = convolve_create();
goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo);
@@ -84,10 +88,6 @@ PluginInfo *goom_init (guint32 resx, guint32 resy)
plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
- goomInfo->screen.width = resx;
- goomInfo->screen.height = resy;
- goomInfo->screen.size = resx * resy;
-
init_buffers(goomInfo, goomInfo->screen.size);
goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel);
diff --git a/src/post/planar/eq2.c b/src/post/planar/eq2.c
index 0ead54f55..a1c208919 100644
--- a/src/post/planar/eq2.c
+++ b/src/post/planar/eq2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -432,8 +432,6 @@ static post_plugin_t *eq2_open_plugin(post_class_t *class_gen, int inputs,
xine_post_in_t *input_api;
post_out_t *output;
post_video_port_t *port;
- vf_eq2_t *eq2;
- int i;
if (!this || !video_target || !video_target[0]) {
free(this);
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 80dd1e92c..f8ce7fc1f 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -184,7 +184,7 @@ xineplug_vo_out_stk_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBSTK_CFLAGS)
xineplug_vo_out_directx_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c video_out_directx.c
xineplug_vo_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS)
-xineplug_vo_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_VIDEO_LIBS) $(PTHREAD_LIBS)
+xineplug_vo_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_VIDEO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL)
xineplug_vo_out_directx_la_CFLAGS = $(VISIBILITY_FLAG)
xineplug_vo_out_none_la_SOURCES = video_out_none.c
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c
index 8ba161ebb..263160808 100644
--- a/src/video_out/deinterlace.c
+++ b/src/video_out/deinterlace.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -37,6 +37,18 @@
#include "xineutils.h"
+const char *deinterlace_methods[] = {
+ "none",
+ "bob",
+ "weave",
+ "greedy",
+ "onefield",
+ "onefield_xv",
+ "linearblend",
+ NULL
+};
+
+
/*
DeinterlaceFieldBob algorithm
Based on Virtual Dub plugin by Gunnar Thalin
diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h
index 2ebbf53d9..d7712f581 100644
--- a/src/video_out/deinterlace.h
+++ b/src/video_out/deinterlace.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 the xine project
+ * Copyright (C) 2001-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -41,15 +41,6 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
#define DEINTERLACE_ONEFIELDXV 5
#define DEINTERLACE_LINEARBLEND 6
-static const char *deinterlace_methods[] = {
- "none",
- "bob",
- "weave",
- "greedy",
- "onefield",
- "onefield_xv",
- "linearblend",
- NULL
-};
+extern const char *deinterlace_methods[];
#endif
diff --git a/src/video_out/video_out_caca.c b/src/video_out/video_out_caca.c
index 3eec45211..65ebf707e 100644
--- a/src/video_out/video_out_caca.c
+++ b/src/video_out/video_out_caca.c
@@ -276,6 +276,7 @@ static int caca_redraw_needed (vo_driver_t *this_gen) {
static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
caca_class_t *class = (caca_class_t *) class_gen;
+ caca_display_t *dp = (caca_display_t *)visual_gen;
caca_driver_t *this;
this = calloc(1, sizeof (caca_driver_t));
@@ -300,8 +301,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
this->yuv2rgb_factory = yuv2rgb_factory_init(MODE_32_RGB, 0, NULL);
this->yuv2rgb_factory->set_csc_levels(this->yuv2rgb_factory, 0, 128, 128);
- this->cv = cucul_create_canvas(0, 0);
- this->dp = caca_create_display(this->cv);
+ if (dp) {
+ this->cv = caca_get_canvas(dp);
+ this->dp = dp;
+ } else {
+ this->cv = cucul_create_canvas(0, 0);
+ this->dp = caca_create_display(this->cv);
+ }
caca_refresh_display(this->dp);
return &this->vo_driver;
diff --git a/src/video_out/video_out_directx.c b/src/video_out/video_out_directx.c
index f1136eab0..dda8664ee 100644
--- a/src/video_out/video_out_directx.c
+++ b/src/video_out/video_out_directx.c
@@ -117,7 +117,8 @@ typedef struct {
yuv2rgb_t *yuv2rgb; /* used for format conversion */
int mode; /* rgb mode */
int bytespp; /* rgb bits per pixel */
-
+ DDPIXELFORMAT primary_pixel_format;
+ DDSURFACEDESC ddsd; /* set by Lock(), used during display_frame */
alphablend_t alphablend_extra_data;
} win32_driver_t;
@@ -367,8 +368,9 @@ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int he
lprintf("CreateSecondary() - Falling back to back buffer same as primary\n");
lprintf("CreateSecondary() - act_format = (NATIVE) %d\n", IMGFMT_NATIVE);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+ ddsd.ddpfPixelFormat = win32_driver->primary_pixel_format;
win32_driver->act_format = IMGFMT_NATIVE;
if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK )
@@ -429,6 +431,10 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
Error( 0, "IDirectDrawSurface_GetPixelFormat ( CheckPixelFormat ) : error 0x%lx", result );
return 0;
}
+
+ /* store pixel format for CreateSecondary */
+
+ win32_driver->primary_pixel_format = ddpf;
/* TODO : support paletized video modes */
@@ -478,6 +484,7 @@ static boolean CheckPixelFormat( win32_driver_t * win32_driver )
win32_driver->mode = MODE_15_BGR;
}
+ lprintf("win32 mode: %u\n", win32_driver->mode);
return TRUE;
}
@@ -755,23 +762,22 @@ static boolean DisplayFrame( win32_driver_t * win32_driver )
/* Lock our back buffer to update its contents. */
-static void * Lock( void * surface )
+static void * Lock( win32_driver_t * win32_driver, void * surface )
{
LPDIRECTDRAWSURFACE lock_surface = ( LPDIRECTDRAWSURFACE ) surface;
- DDSURFACEDESC ddsd;
HRESULT result;
if( !surface )
return 0;
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
+ memset( &win32_driver->ddsd, 0, sizeof( win32_driver->ddsd ) );
+ win32_driver->ddsd.dwSize = sizeof( win32_driver->ddsd );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result == DDERR_SURFACELOST )
{
IDirectDrawSurface_Restore( lock_surface );
- result = IDirectDrawSurface_Lock( lock_surface, 0, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
+ result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 );
if( result != DD_OK )
return 0;
@@ -786,7 +792,7 @@ static void * Lock( void * surface )
}
}
- return ddsd.lpSurface;
+ return win32_driver->ddsd.lpSurface;
}
/* Unlock our back buffer to prepair for display. */
@@ -946,8 +952,6 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
{
win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver;
win32_frame_t *win32_frame = ( win32_frame_t * ) vo_frame;
- int offset;
- int size;
/* if the required width, height or format has changed
@@ -966,7 +970,7 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* lock our surface to update its contents */
- win32_driver->contents = Lock( win32_driver->secondary );
+ win32_driver->contents = Lock( win32_driver, win32_driver->secondary );
/* surface unavailable, skip frame render */
@@ -1051,37 +1055,47 @@ static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame
/* the actual format is identical to our
* stream format. we just need to copy it */
- switch(win32_frame->format)
+ int line;
+ uint8_t * src;
+ vo_frame_t * frame = vo_frame;
+ uint8_t * dst = (uint8_t *)win32_driver->contents;
+
+ switch(win32_frame->format)
{
- case XINE_IMGFMT_YV12:
- {
- vo_frame_t *frame;
- uint8_t *img;
-
- frame = vo_frame;
- img = (uint8_t *)win32_driver->contents;
-
- offset = 0;
- size = frame->pitches[0] * frame->height;
- xine_fast_memcpy( img+offset, frame->base[0], size);
-
- offset += size;
- size = frame->pitches[2]* frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[2], size);
-
- offset += size;
- size = frame->pitches[1] * frame->height / 2;
- xine_fast_memcpy( img+offset, frame->base[1], size);
- }
+ case XINE_IMGFMT_YV12:
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
+
+ src = frame->base[2];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[2];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
+
+ src = frame->base[1];
+ for (line = 0; line < frame->height/2 ; line++){
+ xine_fast_memcpy( dst, src, frame->width/2);
+ src += vo_frame->pitches[1];
+ dst += win32_driver->ddsd.lPitch/2;
+ }
break;
+
case XINE_IMGFMT_YUY2:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
- break;
default:
- xine_fast_memcpy( win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.pitches[0] * win32_frame->vo_frame.height * 2);
+ src = frame->base[0];
+ for (line = 0; line < frame->height ; line++){
+ xine_fast_memcpy( dst, src, frame->width*2);
+ src += vo_frame->pitches[0];
+ dst += win32_driver->ddsd.lPitch;
+ }
break;
}
- }
+ }
/* unlock the surface */
@@ -1143,10 +1157,37 @@ static int win32_gui_data_exchange( vo_driver_t * vo_driver, int data_type, void
switch( data_type )
{
+
case GUI_WIN32_MOVED_OR_RESIZED:
UpdateRect( win32_driver->win32_visual );
DisplayFrame( win32_driver );
break;
+
+ case XINE_GUI_SEND_DRAWABLE_CHANGED:
+ {
+ HRESULT result;
+ HWND newWndHnd = (HWND) data;
+
+ /* set cooperative level */
+ result = IDirectDraw_SetCooperativeLevel( win32_driver->ddobj, newWndHnd, DDSCL_NORMAL );
+ if( result != DD_OK )
+ {
+ Error( 0, "SetCooperativeLevel : error 0x%lx", result );
+ return 0;
+ }
+ /* associate our clipper with new window */
+ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, newWndHnd );
+ if( result != DD_OK )
+ {
+ Error( 0, "ddclipper->SetHWnd : error 0x%lx", result );
+ return 0;
+ }
+ /* store our objects in our visual struct */
+ win32_driver->win32_visual->WndHnd = newWndHnd;
+ /* update video area and redraw current frame */
+ UdateRect( win32_driver->win32_visual );
+ DisplayFrame( win32_driver );
+ break;
}
return 0;
diff --git a/src/video_out/video_out_raw.c b/src/video_out/video_out_raw.c
index 45cfc1eda..99e2c0004 100644
--- a/src/video_out/video_out_raw.c
+++ b/src/video_out/video_out_raw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 the xine project
+ * Copyright (C) 2007-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -212,7 +212,7 @@ static void raw_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img)
if ( !this->ovl_changed )
return;
- this->raw_overlay_cb( this->user_data, this->ovl_changed-1, &this->overlays );
+ this->raw_overlay_cb( this->user_data, this->ovl_changed-1, this->overlays );
this->ovl_changed = 0;
}
@@ -473,7 +473,7 @@ static int raw_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *da
static uint32_t raw_get_capabilities (vo_driver_t *this_gen)
{
- uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2;
+ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP;
return capabilities;
}
diff --git a/src/video_out/video_out_sdl.c b/src/video_out/video_out_sdl.c
index b53d1d31c..89150f5d0 100644
--- a/src/video_out/video_out_sdl.c
+++ b/src/video_out/video_out_sdl.c
@@ -469,9 +469,11 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
sdl_driver_t *this;
const SDL_VideoInfo *vidInfo;
-#ifdef HAVE_X11
+#if defined(HAVE_X11) || defined(WIN32)
static char SDL_windowhack[32];
x11_visual_t *visual = (x11_visual_t *) visual_gen;
+#endif
+#ifdef HAVE_X11
XWindowAttributes window_attributes;
#endif
@@ -502,14 +504,18 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
_x_vo_scale_init( &this->sc, 0, 0, config);
this->sc.frame_output_cb = visual->frame_output_cb;
this->sc.user_data = visual->user_data;
-
- /* set SDL to use our existing X11 window */
- sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) this->drawable );
- putenv(SDL_windowhack);
#else
_x_vo_scale_init( &this->sc, 0, 0, config );
#endif
+#if defined(HAVE_X11) || defined(WIN32)
+ /* set SDL to use our existing X11/win32 window */
+ if (visual->d){
+ sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) visual->d);
+ putenv(SDL_windowhack);
+ }
+#endif
+
if ((SDL_Init (SDL_INIT_VIDEO)) < 0) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: open_plugin - sdl video initialization failed.\n");
return NULL;
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index 807bb766d..1e6e2b663 100644
--- a/src/video_out/video_out_xcbxv.c
+++ b/src/video_out/video_out_xcbxv.c
@@ -138,6 +138,8 @@ struct xv_driver_s {
int use_colorkey;
uint32_t colorkey;
+ int sync_is_vsync;
+
/* hold initial port attributes values to restore on exit */
xine_list_t *port_attributes;
@@ -156,7 +158,9 @@ typedef struct {
xine_t *xine;
} xv_class_t;
-static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_SYNC_ATOMS;
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -1212,66 +1216,43 @@ static void xv_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry) {
this->deinterlace_method = entry->num_value;
}
-static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xv_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
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_cookie = xcb_intern_atom(this->connection, 0, strlen (atomstr), atomstr);
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);
+ xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, entry->num_value);
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);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-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);
+static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xcbxv: double buffering mode = %d\n", xv_double_buffer);
+static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
}
static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) {
- xv_driver_t *this = (xv_driver_t *) this_gen;
- int xv_sync_to_vblank;
-
- xcb_intern_atom_cookie_t atom_cookie;
- xcb_intern_atom_reply_t *atom_reply;
-
- xv_sync_to_vblank = entry->num_value;
-
- pthread_mutex_lock(&this->main_mutex);
- atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_SYNC_TO_VBLANK"), "XV_SYNC_TO_VBLANK");
- 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_sync_to_vblank);
- free(atom_reply);
- pthread_mutex_unlock(&this->main_mutex);
-
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xcbxv: sync to vblank = %d\n", xv_sync_to_vblank);
+ xv_update_attr (this_gen, entry,
+ sync_atoms[((xv_driver_t *)this_gen)->sync_is_vsync],
+ "sync to vblank");
}
+static void xv_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xv_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
+}
static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -1314,12 +1295,10 @@ static xcb_xv_port_t xv_autodetect_port(xv_driver_t *this,
xcb_xv_port_t base,
xv_prefertype prefer_type)
{
- xcb_xv_adaptor_info_iterator_t *start = adaptor_it;
-
for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it))
if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK &&
(prefer_type == xv_prefer_none ||
- strcasestr (xcb_xv_adaptor_info_name (adaptor_it->data), prefer_types[prefer_type])))
+ strcasestr (xcb_xv_adaptor_info_name (adaptor_it->data), prefer_substrings[prefer_type])))
{
int j;
for (j = 0; j < adaptor_it->data->num_ports; ++j)
@@ -1350,7 +1329,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
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_adaptor_info_iterator_t adaptor_it, adaptor_first;
xcb_xv_image_format_info_iterator_t format_it;
this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t));
@@ -1388,12 +1367,12 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
return NULL;
}
- adaptor_it = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply);
+ adaptor_first = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply);
xv_port = config->register_num (config, "video.device.xv_port", 0,
VIDEO_DEVICE_XV_PORT_HELP,
20, NULL, NULL);
prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
- prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
10, NULL, NULL);
if (xv_port != 0) {
@@ -1401,14 +1380,25 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
xprintf(class->xine, XINE_VERBOSITY_NONE,
_("%s: could not open Xv port %d - autodetecting\n"),
LOG_MODULE, xv_port);
+ adaptor_it = adaptor_first;
xv_port = xv_autodetect_port (this, &adaptor_it, xv_port, prefer_type);
} else
xv_find_adaptor_by_port (xv_port, &adaptor_it);
}
if (!xv_port)
+ {
+ adaptor_it = adaptor_first;
xv_port = xv_autodetect_port (this, &adaptor_it, 0, prefer_type);
+ }
if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
+ adaptor_it = adaptor_first;
xv_port = xv_autodetect_port (this, &adaptor_it, 0, xv_prefer_none);
+ }
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -1536,7 +1526,8 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
20, xv_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
- } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_SYNC_TO_VBLANK")) {
+ } else if(!strcmp(name, sync_atoms[this->sync_is_vsync = 0]) ||
+ !strcmp(name, sync_atoms[this->sync_is_vsync = 1])) {
int xv_sync_to_vblank;
xv_sync_to_vblank =
config->register_bool (config, "video.device.xv_sync_to_vblank", 1,
@@ -1548,6 +1539,12 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
"sync to under the XVideo Settings tab"),
20, xv_update_XV_SYNC_TO_VBLANK, this);
config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xv_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 6a11ebc34..f2c47ef7e 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -143,6 +143,8 @@ struct xv_driver_s {
int use_colorkey;
uint32_t colorkey;
+ int sync_is_vsync;
+
/* hold initial port attributes values to restore on exit */
xine_list_t *port_attributes;
@@ -169,7 +171,9 @@ typedef struct {
static int gX11Fail;
-static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_SYNC_ATOMS;
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -1093,7 +1097,7 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen,
return 0;
}
-static void xv_store_port_attribute(xv_driver_t *this, char *name) {
+static void xv_store_port_attribute(xv_driver_t *this, const char *name) {
Atom atom;
xv_portattribute_t *attr;
@@ -1269,52 +1273,38 @@ static void xv_update_deinterlace(void *this_gen, xine_cfg_entry_t *entry) {
this->deinterlace_method = entry->num_value;
}
-static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xv_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xv_driver_t *this = (xv_driver_t *) this_gen;
Atom atom;
- int xv_filter;
-
- xv_filter = entry->num_value;
LOCK_DISPLAY(this);
- atom = XInternAtom (this->display, "XV_FILTER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_filter);
+ atom = XInternAtom (this->display, atomstr, False);
+ XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value);
UNLOCK_DISPLAY(this);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xv: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xv_driver_t *this = (xv_driver_t *) this_gen;
- Atom atom;
- int xv_double_buffer;
-
- xv_double_buffer = entry->num_value;
-
- LOCK_DISPLAY(this);
- atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_double_buffer);
- UNLOCK_DISPLAY(this);
+static void xv_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xv: double buffering mode = %d\n", xv_double_buffer);
+static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xv_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
}
static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) {
- xv_driver_t *this = (xv_driver_t *) this_gen;
- Atom atom;
- int xv_sync_to_vblank;
-
- xv_sync_to_vblank = entry->num_value;
-
- LOCK_DISPLAY(this);
- atom = XInternAtom (this->display, "XV_SYNC_TO_VBLANK", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_sync_to_vblank);
- UNLOCK_DISPLAY(this);
+ xv_update_attr (this_gen, entry,
+ sync_atoms[((xv_driver_t *)this_gen)->sync_is_vsync],
+ "sync to vblank");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xv: sync to vblank = %d\n", xv_sync_to_vblank);
+static void xv_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xv_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -1357,7 +1347,7 @@ static XvPortID xv_autodetect_port(xv_driver_t *this,
for (an = 0; an < adaptors; an++)
if (adaptor_info[an].type & XvImageMask &&
(prefer_type == xv_prefer_none ||
- strcasestr (adaptor_info[an].name, prefer_types[prefer_type])))
+ strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type])))
for (j = 0; j < adaptor_info[an].num_ports; j++) {
XvPortID port = adaptor_info[an].base_id + j;
if (port >= base && xv_open_port(this, port)) {
@@ -1429,13 +1419,13 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
VIDEO_DEVICE_XV_PORT_HELP,
20, NULL, NULL);
prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
- prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
10, NULL, NULL);
if (xv_port != 0) {
if (! xv_open_port(this, xv_port)) {
xprintf(class->xine, XINE_VERBOSITY_NONE,
- _("%s: could not open Xv port %d - autodetecting\n"),
+ _("%s: could not open Xv port %"PRId32" - autodetecting\n"),
LOG_MODULE, xv_port);
xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port, prefer_type);
} else
@@ -1444,7 +1434,13 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
if (!xv_port)
xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type);
if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
+ }
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -1583,7 +1579,8 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
20, xv_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
- } else if(!strcmp(attr[k].name, "XV_SYNC_TO_VBLANK")) {
+ } else if(((this->sync_is_vsync = 0), !strcmp(name, sync_atoms[0])) ||
+ ((this->sync_is_vsync = 1), !strcmp(name, sync_atoms[1]))) {
int xv_sync_to_vblank;
xv_sync_to_vblank =
config->register_bool (config, "video.device.xv_sync_to_vblank", 1,
@@ -1595,6 +1592,12 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
"sync to under the XVideo Settings tab"),
20, xv_update_XV_SYNC_TO_VBLANK, this);
config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xv_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
index 366a03859..c2560ccc0 100644
--- a/src/video_out/video_out_xvmc.c
+++ b/src/video_out/video_out_xvmc.c
@@ -699,6 +699,7 @@ static cxid_t *xvmc_set_context (xvmc_driver_t *this,
return NULL;
}
+#if 0
static XvImage *create_ximage (xvmc_driver_t *this, XShmSegmentInfo *shminfo,
int width, int height, int format) {
unsigned int xvmc_format;
@@ -754,6 +755,7 @@ static void dispose_ximage (xvmc_driver_t *this,
lprintf ("dispose_ximage\n");
XFree(myimage);
}
+#endif
static void xvmc_update_frame_format (vo_driver_t *this_gen,
vo_frame_t *frame_gen,
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index b8d6abf83..61e0139e3 100644
--- a/src/video_out/video_out_xxmc.c
+++ b/src/video_out/video_out_xxmc.c
@@ -45,7 +45,8 @@ static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame,
static void dispose_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo,
XvImage *myimage);
-static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
/*
* Acceleration level priority. Static for now. It may well turn out that IDCT
@@ -159,7 +160,6 @@ static void xxmc_xvmc_dump_subpictures(xxmc_driver_t *this)
static void xxmc_xvmc_surface_handler_construct(xxmc_driver_t *this)
{
- int i;
xvmc_surface_handler_t *handler = &this->xvmc_surf_handler;
pthread_mutex_init(&handler->mutex,NULL);
@@ -1608,8 +1608,8 @@ static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
* other than 100 %, so let's disable deinterlacing at all for this frame
*/
if (this->deinterlace_enabled && this->bob) {
- disable_deinterlace = this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame
- || this->disable_bob_for_scaled_osd && this->scaled_osd_active
+ disable_deinterlace = (this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame)
+ || (this->disable_bob_for_scaled_osd && this->scaled_osd_active)
|| !frame->vo_frame.stream
|| xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) != XINE_FINE_SPEED_NORMAL;
if (!disable_deinterlace) {
@@ -2130,36 +2130,32 @@ static void xxmc_check_capability (xxmc_driver_t *this,
this->props[property].value = int_default;
}
-static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xxmc_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
Atom atom;
- int xv_filter;
-
- xv_filter = entry->num_value;
XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_FILTER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_filter);
+ atom = XInternAtom (this->display, atomstr, False);
+ XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value);
XUnlockDisplay(this->display);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
- Atom atom;
- int xv_double_buffer;
-
- xv_double_buffer = entry->num_value;
+static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_double_buffer);
- XUnlockDisplay(this->display);
+static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: double buffering mode = %d\n", xv_double_buffer);
+static void xxmc_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xxmc_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xxmc_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -2232,7 +2228,7 @@ static XvPortID xxmc_autodetect_port(xxmc_driver_t *this,
for (an = 0; an < adaptors; an++)
if (adaptor_info[an].type & XvImageMask &&
(prefer_type == xv_prefer_none ||
- strcasestr (adaptor_info[an].name, prefer_types[prefer_type])))
+ strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type])))
for (j = 0; j < adaptor_info[an].num_ports; j++) {
XvPortID port = adaptor_info[an].base_id + j;
if (port >= base && xxmc_open_port(this, port)) {
@@ -2406,7 +2402,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
x11_visual_t *visual = (x11_visual_t *) visual_gen;
XColor dummy;
XvImage *myimage;
- unsigned int adaptors, j;
+ unsigned int adaptors;
unsigned int ver,rel,req,ev,err;
XShmSegmentInfo myshminfo;
XvPortID xv_port;
@@ -2452,7 +2448,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
VIDEO_DEVICE_XV_PORT_HELP,
20, NULL, NULL);
prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
- prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
10, NULL, NULL);
if (xv_port != 0) {
@@ -2467,7 +2463,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
if (!xv_port)
xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type);
if (!xv_port)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
+ }
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -2603,6 +2605,12 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP,
20, xxmc_update_XV_DOUBLE_BUFFER, this);
config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xxmc_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
diff --git a/src/video_out/xv_common.h b/src/video_out/xv_common.h
index 259afe616..ff49286f0 100644
--- a/src/video_out/xv_common.h
+++ b/src/video_out/xv_common.h
@@ -57,13 +57,27 @@
_("pitch alignment workaround"), \
_("Some buggy video drivers need a workaround to function properly.")
-typedef enum {
- xv_prefer_none, xv_prefer_overlay, xv_prefer_textured
-} xv_prefertype;
-#define VIDEO_DEVICE_XV_PREFER_TYPES \
- { "Any", "Overlay", "Textured Video", NULL }
+#define VIDEO_DEVICE_XV_DECL_SYNC_ATOMS \
+ static const char *const sync_atoms[] = \
+ { "XV_SYNC_TO_VBLANK", "XV_VSYNC" };
+
+#define VIDEO_DEVICE_XV_DECL_PREFER_TYPES \
+ typedef enum { \
+ xv_prefer_none, xv_prefer_overlay, xv_prefer_textured, xv_prefer_blitter, \
+ } xv_prefertype; \
+ static const char *const prefer_labels[] = \
+ { "Any", "Overlay", "Textured Video", "Blitter", NULL }; \
+ static const char prefer_substrings[][8] = \
+ { "", "Overlay", "Texture", "Blitter" };
#define VIDEO_DEVICE_XV_PREFER_TYPE_HELP \
_("video display method preference"), \
_("Selects which video output method is preferred. " \
"Detection is done using the reported Xv adaptor names.\n" \
"(Only applies when auto-detecting which Xv port to use.)")
+
+#define VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES \
+ static const char *const bicubic_types[] = { "Off", "On", "Auto", NULL };
+#define VIDEO_DEVICE_XV_BICUBIC_HELP \
+ _("bicubic filtering"), \
+ _("This option controls bicubic filtering of the video image. " \
+ "It may be used instead of, or as well as, xine's deinterlacers.")
diff --git a/src/video_out/xxmc.h b/src/video_out/xxmc.h
index 1c24991be..03b12c15b 100644
--- a/src/video_out/xxmc.h
+++ b/src/video_out/xxmc.h
@@ -37,6 +37,14 @@
#define XVMC_THREAD_SAFE
+/*
+ * some implementations are not aware of the display having been locked
+ * already before calling the xvmc function and may therefore deadlock.
+ */
+/*
+#define XVMC_LOCKDISPLAY_SAFE
+*/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -171,7 +179,7 @@ typedef struct context_lock_s {
return; \
}
-#ifdef XVMC_THREAD_SAFE
+#if defined(XVMC_THREAD_SAFE) && defined(XVMC_LOCKDISPLAY_SAFE)
#define XVMCLOCKDISPLAY(display)
#define XVMCUNLOCKDISPLAY(display)
#else
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 9a30ea7e8..04fa030bf 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -622,13 +622,13 @@ fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XIN
uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED;
/* return codec name given BUF_VIDEO_xxx */
-char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED;
/* return BUF_AUDIO_xxx given the formattag */
uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED;
/* return codec name given BUF_AUDIO_xxx */
-char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
+const char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED;
#ifndef SUPPORT_ATTRIBUTE_PACKED
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 911e123ed..b7571d1d7 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -659,6 +659,8 @@ static const video_db_t video_db[] = {
ME_FOURCC('a','v','c','1'),
ME_FOURCC('h','2','6','4'),
ME_FOURCC('H','2','6','4'),
+ ME_FOURCC('x','2','6','4'),
+ ME_FOURCC('X','2','6','4'),
0
},
BUF_VIDEO_H264,
@@ -1198,7 +1200,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_video_name( uint32_t buf_type ) {
+const char * _x_buf_video_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
@@ -1232,7 +1234,7 @@ static uint32_t cached_buf_type=0;
return 0;
}
-char * _x_buf_audio_name( uint32_t buf_type ) {
+const char * _x_buf_audio_name( uint32_t buf_type ) {
int i;
buf_type &= 0xffff0000;
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index cfe6f6a35..81acab348 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2004 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -356,21 +356,22 @@ static const char *config_xlate_internal (const char *key, const xine_config_ent
return NULL;
}
-static const char *config_translate_key (const char *key) {
+static const char *config_translate_key (const char *key, char **tmp) {
/* Returns translated key or, if no translation found, NULL.
* Translated key may be in a static buffer allocated within this function.
* NOT re-entrant; assumes that config_lock is held.
*/
unsigned trans;
- static char *newkey = NULL;
+ const char *newkey = NULL;
/* first, special-case the decoder entries (so that new ones can be added
* without requiring modification of the translation table)
*/
+ *tmp = NULL;
if (!strncmp (key, "decoder.", 8) &&
!strcmp (key + (trans = strlen (key)) - 9, "_priority")) {
- asprintf (&newkey, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
- return newkey;
+ asprintf (tmp, "engine.decoder_priorities.%.*s", trans - 17, key + 8);
+ return *tmp;
}
/* search the translation table... */
@@ -385,6 +386,7 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
cfg_entry_t **entry, cfg_entry_t **prev) {
int trans;
+ char *tmp = NULL;
/* try twice at most (second time with translation from old key name) */
for (trans = 2; trans; --trans) {
@@ -396,14 +398,18 @@ static void config_lookup_entry_int (config_values_t *this, const char *key,
*entry = (*entry)->next;
}
- if (*entry)
+ if (*entry) {
+ free(tmp);
return;
+ }
/* we did not find a match, maybe this is an old config entry name
* trying to translate */
- key = config_translate_key(key);
- if (!key)
+ key = config_translate_key(key, &tmp);
+ if (!key) {
+ free(tmp);
return;
+ }
}
}
@@ -747,7 +753,7 @@ static int config_register_enum (config_values_t *this,
entry->type = XINE_CONFIG_TYPE_ENUM;
if (entry->unknown_value)
- entry->num_value = config_parse_enum (entry->unknown_value, values);
+ entry->num_value = config_parse_enum (entry->unknown_value, (const char **)values);
else
entry->num_value = def_value;
@@ -755,14 +761,14 @@ static int config_register_enum (config_values_t *this,
entry->num_default = def_value;
/* allocate and copy the enum values */
- value_src = values;
+ value_src = (const char **)values;
value_count = 0;
while (*value_src) {
value_src++;
value_count++;
}
entry->enum_values = malloc (sizeof(char*) * (value_count + 1));
- value_src = values;
+ value_src = (const char **)values;
value_dest = entry->enum_values;
while (*value_src) {
*value_dest = strdup(*value_src);
@@ -861,7 +867,7 @@ static void config_update_string (config_values_t *this,
/* if an enum is updated with a string, we convert the string to
* its index and use update number */
if (entry->type == XINE_CONFIG_TYPE_ENUM) {
- config_update_num(this, key, config_parse_enum(value, entry->enum_values));
+ config_update_num(this, key, config_parse_enum(value, (const char **)entry->enum_values));
return;
}
@@ -943,15 +949,17 @@ void xine_config_load (xine_t *xine, const char *filename) {
if (!(entry = config_lookup_entry(this, line))) {
const char *key = line;
+ char *tmp = NULL;
pthread_mutex_lock(&this->config_lock);
if (this->current_version < CONFIG_FILE_VERSION) {
/* old config file -> let's see if we have to rename this one */
- key = config_translate_key(key);
+ key = config_translate_key(key, &tmp);
if (!key)
key = line; /* no translation? fall back on untranslated key */
}
entry = config_add (this, key, 50);
entry->unknown_value = strdup(value);
+ free(tmp);
pthread_mutex_unlock(&this->config_lock);
} else {
switch (entry->type) {
diff --git a/src/xine-engine/demux.c b/src/xine-engine/demux.c
index 257a72383..4f40c9848 100644
--- a/src/xine-engine/demux.c
+++ b/src/xine-engine/demux.c
@@ -138,6 +138,28 @@ void _x_demux_control_newpts( xine_stream_t *stream, int64_t pts, uint32_t flags
pthread_mutex_unlock(&stream->demux_mutex);
}
+/* avoid ao_loop being stuck in a pthread_cond_wait, waiting for data;
+ * return 1 if the stream is stopped
+ * (better fix wanted!)
+ */
+static int demux_unstick_ao_loop (xine_stream_t *stream)
+{
+ if (!stream->audio_thread_created)
+ return 0;
+
+ int status = xine_get_status (stream);
+ if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP)
+ return 0;
+
+ /* right, stream is stopped... */
+ audio_buffer_t *buf = stream->audio_out->get_buffer (stream->audio_out);
+ buf->num_frames = 0;
+ buf->stream = NULL;
+ stream->audio_out->put_buffer (stream->audio_out, buf, stream);
+
+ return 1;
+}
+
/* sync with decoder fifos, making sure everything gets processed */
void _x_demux_control_headers_done (xine_stream_t *stream) {
@@ -190,6 +212,9 @@ void _x_demux_control_headers_done (xine_stream_t *stream) {
ts.tv_nsec = tv.tv_usec * 1000;
/* use timedwait to workaround buggy pthread broadcast implementations */
pthread_cond_timedwait (&stream->counter_changed, &stream->counter_lock, &ts);
+
+ if (demux_unstick_ao_loop (stream))
+ break;
}
stream->demux_action_pending = 0;
@@ -347,6 +372,9 @@ static void *demux_loop (void *stream_gen) {
(stream->finished_count_video < finished_count_video)) {
lprintf ("waiting for finisheds.\n");
pthread_cond_wait (&stream->counter_changed, &stream->counter_lock);
+
+ if (demux_unstick_ao_loop (stream))
+ break;
}
pthread_mutex_unlock (&stream->counter_lock);
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 3d1c0e4a8..4f7492c65 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -1140,15 +1140,23 @@ void _x_scan_plugins (xine_t *this) {
load_cached_catalog (this);
if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL && *pluginpath) {
- char *p = pluginpath - 1;
- while (p[1])
+ char *p = pluginpath;
+ while (p && p[0])
{
- char *dir, *q = p;
- p = strchr (p + 1, XINE_PATH_SEPARATOR_CHAR);
+ size_t len;
+ char *dir, *q;
+
+ q = p;
+ p = strchr (p, XINE_PATH_SEPARATOR_CHAR);
+ if (p) {
+ p++;
+ len = p - q;
+ } else
+ len = strlen(q);
if (q[0] == '~' && q[1] == '/')
- asprintf (&dir, "%s%.*s", homedir, (int)(p - q - 1), q + 1);
+ asprintf (&dir, "%s%.*s", homedir, (int)(len - 1), q + 1);
else
- dir = strndup (q, p - q);
+ dir = strndup (q, len);
push_if_dir (plugindirs, dir); /* store or free it */
}
} else {
@@ -1393,7 +1401,6 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha
i = 0;
while (methods[i] != -1 && !plugin) {
int list_id, list_size;
- const char *mime_type;
stream->content_detection_method = methods[i];
@@ -2456,12 +2463,11 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
* @param joining String to use to join the various strings together.
* @param final_length The pre-calculated final length of the string.
*/
-static char *_x_concatenate_with_string(char **strings, size_t count, char *joining, size_t final_length) {
+static char *_x_concatenate_with_string(char const **strings, size_t count, char *joining, size_t final_length) {
size_t i;
char *const result = malloc(final_length+1); /* Better be safe */
char *str = result;
- size_t pos = 0;
for(i = 0; i < count; i++, strings++) {
if ( *strings ) {
int offset = snprintf(str, final_length, "%s%s", *strings, joining);
diff --git a/src/xine-utils/attributes.h b/src/xine-utils/attributes.h
index 3819818d5..d7a0e2f1e 100644
--- a/src/xine-utils/attributes.h
+++ b/src/xine-utils/attributes.h
@@ -1,7 +1,7 @@
/*
* attributes.h
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
- * Copyright (C) 2001-2007 xine developers
+ * Copyright (C) 2001-2008 xine developers
*
* This file was originally part of mpeg2dec, a free MPEG-2 video stream
* decoder.
@@ -72,7 +72,7 @@
# define XINE_SENTINEL
#endif
-#ifdef SUPPORT_ATTRIBUTE_DEPRECATED
+#if defined(SUPPORT_ATTRIBUTE_DEPRECATED) && !defined(XINE_COMPILE)
# define XINE_DEPRECATED __attribute__((__deprecated__))
#else
# define XINE_DEPRECATED
@@ -89,8 +89,10 @@
/* Format attributes */
#ifdef SUPPORT_ATTRIBUTE_FORMAT
# define XINE_FORMAT_PRINTF(fmt,var) __attribute__((__format__(__printf__, fmt, var)))
+# define XINE_FORMAT_SCANF(fmt,var) __attribute__((__format__(__scanf__, fmt, var)))
#else
# define XINE_FORMAT_PRINTF(fmt,var)
+# define XINE_FORMAT_SCANF(fmt,var)
#endif
#ifdef SUPPORT_ATTRIBUTE_FORMAT_ARG
# define XINE_FORMAT_PRINTF_ARG(fmt) __attribute__((__format_arg__(fmt)))
diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c
index 301d6c22f..650c10f99 100644
--- a/src/xine-utils/monitor.c
+++ b/src/xine-utils/monitor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2003 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -38,7 +38,6 @@ static long profiler_calls[MAX_ID] ;
static const char *profiler_label[MAX_ID] ;
void xine_profiler_init () {
- int i;
memset(profiler_times, 0, sizeof(profiler_times));
memset(profiler_start, 0, sizeof(profiler_start));
memset(profiler_calls, 0, sizeof(profiler_calls));
diff --git a/src/xine-utils/utils.c b/src/xine-utils/utils.c
index 57a92623c..689b68502 100644
--- a/src/xine-utils/utils.c
+++ b/src/xine-utils/utils.c
@@ -456,23 +456,22 @@ char *xine_chomp(char *str) {
* a thread-safe usecond sleep
*/
void xine_usec_sleep(unsigned usec) {
-#if 0
-#if HAVE_NANOSLEEP
+#ifdef WIN32
+ /* select does not work on win32 */
+ Sleep(usec / 1000);
+#else
+# if 0
+# if HAVE_NANOSLEEP
/* nanosleep is prefered on solaris, because it's mt-safe */
struct timespec ts, remaining;
-
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
while (nanosleep (&ts, &remaining) == -1 && errno == EINTR)
ts = remaining;
-#else
-# if WIN32
- Sleep(usec / 1000);
-# else
+# else
usleep(usec);
-# endif
-#endif
-#else
+# endif
+# else
if (usec < 10000) {
usec = 10000;
}
@@ -480,6 +479,7 @@ void xine_usec_sleep(unsigned usec) {
tm.tv_sec = usec / 1000000;
tm.tv_usec = usec % 1000000;
select(0, 0, 0, 0, &tm);
+# endif
#endif
}