summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_dec/xine_a52_decoder.c6
-rw-r--r--src/combined/ffmpeg/ff_audio_decoder.c6
-rw-r--r--src/demuxers/demux_ts.c460
-rw-r--r--src/input/Makefile.am2
-rw-r--r--src/input/input_cdda.c32
-rw-r--r--src/input/input_file.c11
-rw-r--r--src/input/input_net.c15
-rw-r--r--src/input/input_pvr.c8
-rw-r--r--src/input/input_smb.c20
-rw-r--r--src/input/net_buf_ctrl.c4
-rw-r--r--src/spu_dec/spudvb_decoder.c54
-rw-r--r--src/video_dec/image.c26
-rw-r--r--src/xine-engine/buffer_types.c2
-rw-r--r--src/xine-engine/configfile.c4
-rw-r--r--src/xine-engine/io_helper.c16
-rw-r--r--src/xine-utils/memcpy.c24
16 files changed, 476 insertions, 214 deletions
diff --git a/src/audio_dec/xine_a52_decoder.c b/src/audio_dec/xine_a52_decoder.c
index 85e20d1d4..628920fbc 100644
--- a/src/audio_dec/xine_a52_decoder.c
+++ b/src/audio_dec/xine_a52_decoder.c
@@ -53,12 +53,6 @@
# include "a52.h"
#endif
-#ifdef HAVE_A52DEC_A52_INTERNAL_H
-# include <a52dec/a52_internal.h>
-#else
-# include "a52_internal.h"
-#endif
-
#include <xine/buffer.h>
#include <xine/xineutils.h>
diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c
index 6b524e80c..a45d57c69 100644
--- a/src/combined/ffmpeg/ff_audio_decoder.c
+++ b/src/combined/ffmpeg/ff_audio_decoder.c
@@ -172,7 +172,7 @@ static void ff_audio_init_codec(ff_audio_decoder_t *this, unsigned int codec_typ
* - DVB streams where multiple AAC LATM frames are packed to single PES
* - DVB streams where MPEG audio frames do not follow PES packet boundaries
*/
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 94)
if (codec_type == BUF_AUDIO_AAC_LATM ||
codec_type == BUF_AUDIO_MPEG) {
@@ -355,7 +355,7 @@ static int ff_audio_decode(xine_t *xine,
int consumed;
int parser_consumed = 0;
-#if LIBAVCODEC_VERSION_MAJOR >= 53
+#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 94)
if (parser_ctx) {
uint8_t *outbuf;
int outsize;
@@ -382,7 +382,7 @@ static int ff_audio_decode(xine_t *xine,
buf = outbuf;
size = outsize;
}
-#endif /* LIBAVCODEC_VERSION_MAJOR >= 53 */
+#endif /* LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 94) */
#if AVAUDIO > 2
AVPacket avpkt;
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 2b20fef7a..d69c29938 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -189,8 +189,6 @@
#define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4))
-#define MAX_PES_BUF_SIZE 2048
-
#define CORRUPT_PES_THRESHOLD 10
#define NULL_PID 0x1fff
@@ -257,6 +255,10 @@
HDMV_SPU_INTERACTIVE = 0x91,
HDMV_SPU_TEXT = 0x92,
+ /* pseudo tags */
+ STREAM_AUDIO_EAC3 = (DESCRIPTOR_EAC3 << 8),
+ STREAM_AUDIO_DTS = (DESCRIPTOR_DTS << 8),
+
} streamType;
#define WRAP_THRESHOLD 270000
@@ -292,13 +294,14 @@
typedef struct {
unsigned int pid;
fifo_buffer_t *fifo;
- uint32_t size;
uint32_t type;
int64_t pts;
buf_element_t *buf;
unsigned int counter;
uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
+ uint8_t keep; /* used by demux_ts_dynamic_pmt_*() */
int corrupted_pes;
+ int pes_bytes_left; /* butes left if PES packet size is known */
int input_normpos;
int input_time;
@@ -420,6 +423,167 @@ typedef struct {
} demux_ts_t;
+static void reset_track_map(fifo_buffer_t *fifo)
+{
+ buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+
+ buf->type = BUF_CONTROL_RESET_TRACK_MAP;
+ buf->decoder_info[1] = -1;
+
+ fifo->put (fifo, buf);
+}
+
+/* TJ. dynamic PMT support. The idea is:
+ First, reuse unchanged pids and add new ones.
+ Then, comb out those who are no longer referenced.
+ For example, the Kaffeine dvb frontend preserves original pids but only
+ sends the currently user selected ones, plus matching generated pat/pmt */
+
+static int demux_ts_dynamic_pmt_find (demux_ts_t *this,
+ int pid, int type, unsigned int descriptor_tag) {
+ unsigned int i;
+ demux_ts_media *m;
+ for (i = 0; i < this->media_num; i++) {
+ m = &this->media[i];
+ if ((m->pid == pid) && ((m->type & BUF_MAJOR_MASK) == type)) {
+ /* mark this media decriptor for reuse */
+ m->keep = 1;
+ return i;
+ }
+ }
+ if (i < MAX_PIDS) {
+ /* prepare new media descriptor */
+#ifdef LOG_DYNAMIC_PMT
+ char *name = "";
+ if (type == BUF_VIDEO_BASE) name = "video";
+ else if (type == BUF_AUDIO_BASE) name = "audio";
+ else if (type == BUF_SPU_BASE) name = "subtitle";
+ printf ("demux_ts: new %s pid %d\n", name, pid);
+#endif
+ m = &this->media[i];
+ if (type == BUF_AUDIO_BASE) {
+ /* allocate new audio track as well */
+ if (this->audio_tracks_count >= MAX_AUDIO_TRACKS) {
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "demux_ts: too many audio PIDs, ignoring pid %d\n", pid);
+ return -1;
+ }
+ m->type = type | this->audio_tracks_count;
+ this->audio_tracks[this->audio_tracks_count].pid = pid;
+ this->audio_tracks[this->audio_tracks_count].media_index = i;
+ this->audio_tracks_count++;
+ m->fifo = this->stream->audio_fifo;
+ } else {
+ m->type = type;
+ m->fifo = this->stream->video_fifo;
+ }
+ m->pid = pid;
+
+ if (m->buf) {
+ m->buf->free_buffer(m->buf);
+ m->buf = NULL;
+ }
+ m->counter = INVALID_CC;
+ m->corrupted_pes = 1;
+
+ m->descriptor_tag = descriptor_tag;
+
+ m->keep = 1;
+ this->media_num++;
+ return i;
+ }
+ /* table full */
+ return -1;
+}
+
+static void demux_ts_dynamic_pmt_clean (demux_ts_t *this) {
+ int i, count = 0, tracks = 0, spus = 0;
+ /* densify media table */
+ for (i = 0; i < this->media_num; i++) {
+ demux_ts_media *m = &this->media[i];
+ int type = m->type & BUF_MAJOR_MASK;
+ int chan = m->type & 0xff;
+ if (m->keep) {
+ m->keep = 0;
+ if (type == BUF_VIDEO_BASE) {
+ /* adjust single video link */
+ this->videoMedia = count;
+ } else if (type == BUF_AUDIO_BASE) {
+ /* densify audio track table */
+ this->audio_tracks[chan].media_index = count;
+ if (chan > tracks) {
+ m->type = (m->type & ~0xff) | tracks;
+ this->audio_tracks[tracks] = this->audio_tracks[chan];
+ }
+ tracks++;
+ } else if (type == BUF_SPU_BASE) {
+ /* spu language table has already been rebuilt from scratch.
+ Adjust backlinks only */
+ while ((spus < this->spu_langs_count) && (this->spu_langs[spus].pid == m->pid)) {
+ this->spu_langs[spus].media_index = count;
+ spus++;
+ }
+ }
+ if (i > count) {
+ this->media[count] = *m;
+ m->buf = NULL;
+ m->pid = INVALID_PID;
+ }
+ count++;
+ } else {
+ /* drop this no longer needed media descriptor */
+#ifdef LOG_DYNAMIC_PMT
+ char *name = "";
+ if (type == BUF_VIDEO_BASE) name = "video";
+ else if (type == BUF_AUDIO_BASE) name = "audio";
+ else if (type == BUF_SPU_BASE) name = "subtitle";
+ printf ("demux_ts: dropped %s pid %d\n", name, m->pid);
+#endif
+ if (m->buf) {
+ m->buf->free_buffer (m->buf);
+ m->buf = NULL;
+ }
+ m->pid = INVALID_PID;
+ }
+ }
+ if ((tracks < this->audio_tracks_count) && this->audio_fifo) {
+ /* at least 1 audio track removed, tell audio decoder loop */
+ reset_track_map(this->audio_fifo);
+#ifdef LOG_DYNAMIC_PMT
+ printf ("demux_ts: new audio track map\n");
+#endif
+ }
+#ifdef LOG_DYNAMIC_PMT
+ printf ("demux_ts: using %d pids, %d audio %d subtitle channels\n", count, tracks, spus);
+#endif
+ /* adjust table sizes */
+ this->media_num = count;
+ this->audio_tracks_count = tracks;
+ /* should really have no effect */
+ this->spu_langs_count = spus;
+}
+
+static void demux_ts_dynamic_pmt_clear (demux_ts_t *this) {
+ unsigned int i;
+ for (i = 0; i < this->media_num; i++) {
+ if (this->media[i].buf) {
+ this->media[i].buf->free_buffer (this->media[i].buf);
+ this->media[i].buf = NULL;
+ }
+ }
+ this->media_num = 0;
+
+ this->videoPid = INVALID_PID;
+ this->audio_tracks_count = 0;
+ this->spu_pid = INVALID_PID;
+ this->spu_langs_count = 0;
+
+ this->pcr_pid = INVALID_PID;
+
+ this->last_pmt_crc = 0;
+}
+
+
static void demux_ts_tbre_reset (demux_ts_t *this) {
if (this->tbre_time <= TBRE_TIME) {
this->tbre_pid = INVALID_PID;
@@ -566,6 +730,9 @@ static void demux_ts_update_spu_channel(demux_ts_t *this)
this->spu_pid = lang->pid;
this->spu_media = lang->media_index;
+ /* multiple spu langs can share same media descriptor */
+ this->media[lang->media_index].type =
+ (this->media[lang->media_index].type & ~0xff) | this->current_spu_channel;
#ifdef TS_LOG
printf("demux_ts: DVBSUB: selecting lang: %s page %ld %ld\n",
lang->desc.lang, lang->desc.comp_page_id, lang->desc.aux_page_id);
@@ -768,11 +935,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
/* force PMT reparsing when pmt_pid changes */
if (this->pmt_pid[program_count] != pmt_pid) {
this->pmt_pid[program_count] = pmt_pid;
- this->audio_tracks_count = 0;
- this->last_pmt_crc = 0;
- this->videoPid = INVALID_PID;
- this->spu_pid = INVALID_PID;
- this->pcr_pid = INVALID_PID;
+ demux_ts_dynamic_pmt_clear (this);
if (this->pmt[program_count] != NULL) {
free(this->pmt[program_count]);
@@ -823,14 +986,13 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0 ;
}
- /* packet_len = p[4] << 8 | p[5]; */
stream_id = p[3];
- header_len = p[8];
+ header_len = p[8] + 9;
/* sometimes corruption on header_len causes segfault in memcpy below */
- if (header_len + 9 > packet_len) {
+ if (header_len > packet_len) {
xprintf (xine, XINE_VERBOSITY_DEBUG,
- "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len);
+ "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len - 9);
return 0;
}
@@ -841,7 +1003,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
if (p[7] & 0x80) { /* pts avail */
- if (header_len < 5) {
+ if (header_len < 14) {
return 0;
}
@@ -869,22 +1031,21 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
m->pts = pts;
- p += header_len + 9;
- packet_len -= header_len + 9;
+ m->pes_bytes_left = (int)(p[4] << 8 | p[5]) - header_len + 6;
+ lprintf("PES packet payload left: %d bytes\n", m->pes_bytes_left);
+
+ p += header_len;
+ packet_len -= header_len;
if (m->descriptor_tag == STREAM_VIDEO_VC1) {
- m->size = packet_len;
m->type = BUF_VIDEO_VC1;
- return 1;
+ return header_len;
}
if (m->descriptor_tag == HDMV_SPU_BITMAP) {
- long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
-
- m->size = packet_len;
m->type |= BUF_SPU_HDMV;
- m->buf->decoder_info[2] = payload_len;
- return 1;
+ m->buf->decoder_info[2] = m->pes_bytes_left;
+ return header_len;
} else
@@ -901,27 +1062,25 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
* these "raw" streams may begin with a byte that looks like a stream type.
* For audio streams, m->type already contains the stream no.
*/
- if(m->descriptor_tag == HDMV_AUDIO_84_EAC3) {
- m->size = packet_len;
+ if(m->descriptor_tag == HDMV_AUDIO_84_EAC3 ||
+ m->descriptor_tag == STREAM_AUDIO_EAC3) {
m->type |= BUF_AUDIO_EAC3;
- return 1;
+ return header_len;
} else if(m->descriptor_tag == STREAM_AUDIO_AC3) { /* ac3 - raw */
- m->size = packet_len;
m->type |= BUF_AUDIO_A52;
- return 1;
+ return header_len;
} else if (m->descriptor_tag == HDMV_AUDIO_83_TRUEHD) {
/* TODO: separate AC3 and TrueHD streams ... */
- m->size = packet_len;
m->type |= BUF_AUDIO_A52;
- return 1;
+ return header_len;
- } else if (m->descriptor_tag == HDMV_AUDIO_82_DTS ||
+ } else if (m->descriptor_tag == STREAM_AUDIO_DTS ||
+ m->descriptor_tag == HDMV_AUDIO_82_DTS ||
m->descriptor_tag == HDMV_AUDIO_86_DTS_HD_MA ) {
- m->size = packet_len;
m->type |= BUF_AUDIO_DTS;
- return 1;
+ return header_len;
} else if (packet_len < 2) {
return 0;
@@ -932,45 +1091,39 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0;
}
- m->size = packet_len - 4;
m->type |= BUF_AUDIO_LPCM_BE;
m->buf->decoder_flags |= BUF_FLAG_SPECIAL;
m->buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG;
m->buf->decoder_info[2] = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
- return 1;
+ return header_len + 4;
} else if (m->descriptor_tag == ISO_13818_PES_PRIVATE
&& p[0] == 0x20 && p[1] == 0x00) {
/* DVBSUB */
- long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
-
- m->size = packet_len;
m->type |= BUF_SPU_DVB;
- m->buf->decoder_info[2] = payload_len;
- return 1;
+ m->buf->decoder_info[2] = m->pes_bytes_left;
+ return header_len;
} else if (p[0] == 0x0B && p[1] == 0x77) { /* ac3 - syncword */
- m->size = packet_len;
m->type |= BUF_AUDIO_A52;
- return 1;
+ return header_len;
} else if ((p[0] & 0xE0) == 0x20) {
spu_id = (p[0] & 0x1f);
- m->size = packet_len-1;
m->type = BUF_SPU_DVD + spu_id;
- return 1;
+ return header_len + 1;
+
} else if ((p[0] & 0xF0) == 0x80) {
if (packet_len < 4) {
return 0;
}
- m->size = packet_len - 4;
m->type |= BUF_AUDIO_A52;
- return 1;
+ return header_len + 4;
#if 0
/* commented out: does not set PCM type. Decoder can't handle raw PCM stream without configuration. */
@@ -989,15 +1142,13 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
return 0;
}
- m->size = packet_len-pcm_offset;
m->type |= BUF_AUDIO_LPCM_BE;
- return 1;
+ return header_len + pcm_offset;
#endif
}
} else if ((stream_id & 0xf0) == 0xe0) {
- m->size = packet_len;
switch (m->descriptor_tag) {
case ISO_11172_VIDEO:
case ISO_13818_VIDEO:
@@ -1018,11 +1169,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
m->type = BUF_VIDEO_MPEG;
break;
}
- return 1;
+ return header_len;
} else if ((stream_id & 0xe0) == 0xc0) {
- m->size = packet_len;
switch (m->descriptor_tag) {
case ISO_11172_AUDIO:
case ISO_13818_AUDIO:
@@ -1042,7 +1192,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m,
m->type |= BUF_AUDIO_MPEG;
break;
}
- return 1;
+ return header_len;
} else {
#ifdef TS_LOG
@@ -1103,7 +1253,9 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
/* allocate the buffer here, as pes_header needs a valid buf for dvbsubs */
m->buf = m->fifo->buffer_pool_alloc(m->fifo);
- if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len)) {
+ int pes_header_len = demux_ts_parse_pes_header(this->stream->xine, m, ts, len);
+
+ if (pes_header_len <= 0) {
m->buf->free_buffer(m->buf);
m->buf = NULL;
@@ -1113,8 +1265,10 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
} else {
m->corrupted_pes = 0;
- memcpy(m->buf->mem, ts+len-m->size, m->size);
- m->buf->size = m->size;
+
+ /* skip PES header */
+ ts += pes_header_len;
+ len -= pes_header_len;
update_extra_info(this, m);
@@ -1124,41 +1278,29 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
if (m->pid == this->tbre_pid)
demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PTS, m->pts);
}
+ }
- } else if (!m->corrupted_pes) { /* no pus -- PES packet continuation */
+ if (!m->corrupted_pes) {
- if ((m->buf->size + len) > MAX_PES_BUF_SIZE) {
+ if ((m->buf->size + len) > m->buf->max_size) {
+ m->pes_bytes_left -= m->buf->size;
demux_ts_send_buffer(m, 0);
m->buf = m->fifo->buffer_pool_alloc(m->fifo);
}
+
memcpy(m->buf->mem + m->buf->size, ts, len);
m->buf->size += len;
- }
-}
-/*
- * Create a buffer for a PES stream.
- */
-static void demux_ts_pes_new(demux_ts_t*this,
- unsigned int mediaIndex,
- unsigned int pid,
- fifo_buffer_t *fifo,
- uint16_t descriptor) {
-
- demux_ts_media *m = &this->media[mediaIndex];
-
- /* new PID seen - initialise stuff */
- m->pid = pid;
- m->fifo = fifo;
-
- if (m->buf != NULL) m->buf->free_buffer(m->buf);
- m->buf = NULL;
- m->counter = INVALID_CC;
- m->descriptor_tag = descriptor;
- m->corrupted_pes = 1;
+ if (m->pes_bytes_left > 0 && m->buf->size >= m->pes_bytes_left) {
+ /* PES payload complete */
+ m->pes_bytes_left -= m->buf->size;
+ demux_ts_flush_media(m);
+ /* skip rest data - there shouldn't be any */
+ m->corrupted_pes = 1;
+ }
+ }
}
-
/* Find the first ISO 639 language descriptor (tag 10) and
* store the 3-char code in dest, nullterminated. If no
* code is found, zero out dest.
@@ -1268,6 +1410,7 @@ static void demux_ts_parse_pmt (demux_ts_t *this,
uint8_t *ptr = NULL;
unsigned char len;
unsigned int offset=0;
+ int mi;
/*
* A new section should start with the payload unit start
@@ -1414,10 +1557,12 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
* PMT has changed (e.g. an IPTV streamer that's just changed its source),
* we'll get new PIDs that we should follow.
*/
- this->audio_tracks_count = 0;
this->videoPid = INVALID_PID;
this->spu_pid = INVALID_PID;
+ this->spu_langs_count = 0;
+ reset_track_map(this->video_fifo);
+
/*
* ES definitions start here...we are going to learn upto one video
* PID and one audio PID.
@@ -1443,7 +1588,6 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
/*
* Extract the elementary streams.
*/
- this->spu_langs_count = 0;
while (section_length > 0) {
unsigned int stream_info_length;
@@ -1470,9 +1614,12 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT video pid 0x%.4x type %2.2x\n", pid, stream[0]);
#endif
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo,stream[0]);
- this->videoMedia = this->media_num;
- this->videoPid = pid;
+
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_VIDEO_BASE, stream[0]);
+ if (mi >= 0) {
+ this->videoMedia = mi;
+ this->videoPid = pid;
+ }
}
break;
@@ -1481,18 +1628,17 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
case ISO_13818_PART7_AUDIO:
case ISO_14496_PART3_AUDIO:
if (this->audio_tracks_count < MAX_AUDIO_TRACKS) {
- if (apid_check(this, pid) < 0) {
+
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE, stream[0]);
+ if (mi >= 0) {
#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
+ printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
#endif
- demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo,stream[0]);
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
+ demux_ts_get_lang_desc (this,
+ this->audio_tracks[this->media[mi].type & 0xff].lang,
+ stream + 5, stream_info_length);
}
+
}
break;
case ISO_13818_PRIVATE:
@@ -1511,28 +1657,23 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
break;
case ISO_13818_PES_PRIVATE:
for (i = 5; i < coded_length; i += stream[i+1] + 2) {
- if (((stream[i] == DESCRIPTOR_AC3) || (stream[i] == DESCRIPTOR_EAC3)) &&
- (this->audio_tracks_count < MAX_AUDIO_TRACKS)) {
- if (apid_check(this, pid) < 0) {
+
+ if ((stream[i] == DESCRIPTOR_AC3) || (stream[i] == DESCRIPTOR_EAC3) || (stream[i] == DESCRIPTOR_DTS)) {
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE,
+ stream[i] == DESCRIPTOR_AC3 ? STREAM_AUDIO_AC3 :
+ stream[i] == DESCRIPTOR_DTS ? STREAM_AUDIO_DTS :
+ STREAM_AUDIO_EAC3);
+ if (mi >= 0) {
#ifdef TS_PMT_LOG
printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
#endif
- if (stream[i] == DESCRIPTOR_AC3)
- demux_ts_pes_new(this, this->media_num, pid,
- this->audio_fifo, STREAM_AUDIO_AC3);
- else
- demux_ts_pes_new(this, this->media_num, pid,
- this->audio_fifo, HDMV_AUDIO_84_EAC3);
-
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
+ demux_ts_get_lang_desc (this,
+ this->audio_tracks[this->media[mi].type & 0xff].lang,
+ stream + 5, stream_info_length);
break;
}
}
+
/* Teletext */
else if (stream[i] == DESCRIPTOR_TELETEXT)
{
@@ -1550,6 +1691,10 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
else if (stream[i] == DESCRIPTOR_DVBSUB)
{
int pos;
+
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_SPU_BASE, stream[0]);
+ if (mi < 0) break;
+
for (pos = i + 2;
pos + 8 <= i + 2 + stream[i + 1]
&& this->spu_langs_count < MAX_SPU_LANGS;
@@ -1567,9 +1712,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
lang->desc.aux_page_id =
(stream[pos + 6] << 8) | stream[pos + 7];
lang->pid = pid;
- lang->media_index = this->media_num;
- this->media[this->media_num].type = no;
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
+ lang->media_index = mi;
demux_send_special_spu_buf( this, BUF_SPU_DVB, no );
#ifdef TS_LOG
printf("demux_ts: DVBSUB: pid 0x%.4x: %s page %ld %ld type %2.2x\n",
@@ -1604,15 +1747,17 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
break;
}
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_SPU_BASE, stream[0]);
+ if (mi < 0) break;
+
+
demux_ts_spu_lang *lang = &this->spu_langs[this->spu_langs_count];
memset(lang->desc.lang, 0, sizeof(lang->desc.lang));
/*memcpy(lang->desc.lang, &stream[pos], 3);*/
/*lang->desc.lang[3] = 0;*/
lang->pid = pid;
- lang->media_index = this->media_num;
- this->media[this->media_num].type = this->spu_langs_count;
- demux_ts_pes_new(this, this->media_num, pid, this->video_fifo, stream[0]);
+ lang->media_index = mi;
demux_send_special_spu_buf( this, BUF_SPU_HDMV, this->spu_langs_count );
this->spu_langs_count++;
#ifdef TS_PMT_LOG
@@ -1631,43 +1776,43 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num
* if is does, we tag this as an audio stream.
* FIXME: This will need expanding if we ever see a DTS or other media format here.
*/
- if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) {
- if (apid_check(this,pid) < 0) {
- uint32_t format_identifier=0;
- demux_ts_get_reg_desc(this, &format_identifier,
- stream + 5, stream_info_length);
- /* If no format identifier, assume A52 */
- if (( format_identifier == 0x41432d33) ||
- ( format_identifier == 0) ||
- ((format_identifier == 0x48444d56 || this->hdmv>0) && stream[0] == HDMV_AUDIO_80_PCM) /* BluRay PCM */) {
-
- demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, stream[0]);
- this->audio_tracks[this->audio_tracks_count].pid = pid;
- this->audio_tracks[this->audio_tracks_count].media_index = this->media_num;
- this->media[this->media_num].type = this->audio_tracks_count;
- demux_ts_get_lang_desc(this, this->audio_tracks[this->audio_tracks_count].lang,
- stream + 5, stream_info_length);
- this->audio_tracks_count++;
- break;
- }
+ if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) {
+
+ uint32_t format_identifier=0;
+ demux_ts_get_reg_desc(this, &format_identifier, stream + 5, stream_info_length);
+ /* If no format identifier, assume A52 */
+ if (( format_identifier == 0x41432d33) ||
+ ( format_identifier == 0) ||
+ ((format_identifier == 0x48444d56 || this->hdmv>0) && stream[0] == HDMV_AUDIO_80_PCM) /* BluRay PCM */) {
+
+ mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE, stream[0]);
+ if (mi >= 0) {
+ demux_ts_get_lang_desc (this,
+ this->audio_tracks[this->media[mi].type & 0xff].lang,
+ stream + 5, stream_info_length);
+#ifdef TS_PMT_LOG
+ printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]);
+#endif
+ break;
+ }
}
- } else {
+ }
#ifdef TS_PMT_LOG
- printf ("demux_ts: PMT unknown stream_type: 0x%.2x pid: 0x%.4x\n",
- stream[0], pid);
+ printf ("demux_ts: PMT unknown stream_type: 0x%.2x pid: 0x%.4x\n",
+ stream[0], pid);
- for (i = 5; i < coded_length; i++)
- printf ("%.2x ", stream[i]);
- printf ("\n");
+ for (i = 5; i < coded_length; i++)
+ printf ("%.2x ", stream[i]);
+ printf ("\n");
#endif
- }
break;
}
- this->media_num++;
stream += coded_length;
section_length -= coded_length;
}
+ demux_ts_dynamic_pmt_clean (this);
+
/*
* Get the current PCR PID.
*/
@@ -2335,23 +2480,36 @@ static int demux_ts_get_optional_data(demux_plugin_t *this_gen,
{
case DEMUX_OPTIONAL_DATA_AUDIOLANG:
if ((channel >= 0) && (channel < this->audio_tracks_count)) {
- if(this->audio_tracks[channel].lang)
+ if (this->audio_tracks[channel].lang[0]) {
strcpy(str, this->audio_tracks[channel].lang);
- else
- sprintf(str, "%3i", _x_get_audio_channel(this->stream));
+ } else {
+ /* input plugin may know the language */
+ if (this->input->get_capabilities(this->input) & INPUT_CAP_AUDIOLANG)
+ return DEMUX_OPTIONAL_UNSUPPORTED;
+ sprintf(str, "%3i", channel);
+ }
+ return DEMUX_OPTIONAL_SUCCESS;
}
else {
- snprintf(str, XINE_LANG_MAX, "%3i", _x_get_audio_channel(this->stream));
+ strcpy(str, "none");
}
- return DEMUX_OPTIONAL_SUCCESS;
+ return DEMUX_OPTIONAL_UNSUPPORTED;
case DEMUX_OPTIONAL_DATA_SPULANG:
if (channel>=0 && channel<this->spu_langs_count) {
- memcpy(str, this->spu_langs[channel].desc.lang, 3);
- str[3] = 0;}
- else
+ if (this->spu_langs[channel].desc.lang[0]) {
+ strcpy(str, this->spu_langs[channel].desc.lang);
+ } else {
+ /* input plugin may know the language */
+ if (this->input->get_capabilities(this->input) & INPUT_CAP_SPULANG)
+ return DEMUX_OPTIONAL_UNSUPPORTED;
+ sprintf(str, "%3i", channel);
+ }
+ return DEMUX_OPTIONAL_SUCCESS;
+ } else {
strcpy(str, "none");
- return DEMUX_OPTIONAL_SUCCESS;
+ }
+ return DEMUX_OPTIONAL_UNSUPPORTED;
default:
return DEMUX_OPTIONAL_UNSUPPORTED;
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 943be4195..da96bfa06 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -34,11 +34,11 @@ endif
if ENABLE_V4L
in_v4l = xineplug_inp_v4l.la
-in_pvr = xineplug_inp_pvr.la
endif
if ENABLE_V4L2
in_v4l2 = xineplug_inp_v4l2.la
+in_pvr = xineplug_inp_pvr.la
endif
if ENABLE_GNOME_VFS
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index 824b97fbb..08229874c 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -210,7 +210,7 @@ typedef struct {
int mrls_allocated_entries;
xine_mrl_t **mrls;
- char *autoplaylist[MAX_TRACKS];
+ char **autoplaylist;
} cdda_input_class_t;
@@ -2436,6 +2436,21 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
return 1;
}
+static void free_autoplay_list(cdda_input_class_t *this)
+{
+ /* free old playlist */
+ if (this->autoplaylist) {
+ unsigned int i;
+ for( i = 0; this->autoplaylist[i]; i++ ) {
+ free( this->autoplaylist[i] );
+ this->autoplaylist[i] = NULL;
+ }
+
+ free(this->autoplaylist);
+ this->autoplaylist = NULL;
+ }
+}
+
static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
int *num_files) {
@@ -2447,11 +2462,7 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
lprintf("cdda_class_get_autoplay_list for >%s<\n", this->cdda_device);
- /* free old playlist */
- for( i = 0; this->autoplaylist[i]; i++ ) {
- free( this->autoplaylist[i] );
- this->autoplaylist[i] = NULL;
- }
+ free_autoplay_list(this);
/* get the CD TOC */
toc = init_cdrom_toc();
@@ -2509,6 +2520,8 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
num_tracks--;
if (num_tracks >= MAX_TRACKS-1)
num_tracks = MAX_TRACKS - 2;
+
+ this->autoplaylist = calloc(num_tracks + 2, sizeof(char *));
for ( i = 0; i <= num_tracks; i++ )
this->autoplaylist[i] = _x_asprintf("cdda:/%d",i+toc->first_track);
@@ -2624,7 +2637,14 @@ static void cdda_class_dispose (input_class_t *this_gen) {
config->unregister_callback(config, "media.audio_cd.drive_slowdown");
#endif
+ free_autoplay_list(this);
+
+ while (this->mrls_allocated_entries) {
+ MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
+ free(this->mrls[this->mrls_allocated_entries--]);
+ }
free (this->mrls);
+
free (this);
}
diff --git a/src/input/input_file.c b/src/input/input_file.c
index c2ecd3c0b..796c789d6 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -841,7 +841,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
- memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
+ MRL_ZERO(this->mrls[num_files]);
MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
@@ -859,7 +859,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
- memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
+ MRL_ZERO(this->mrls[num_files]);
MRL_DUPLICATE(&hide_files[i], this->mrls[num_files]);
@@ -877,7 +877,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
- memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
+ MRL_ZERO(this->mrls[num_files]);
MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
@@ -945,7 +945,12 @@ static void file_class_dispose (input_class_t *this_gen) {
config->unregister_callback(config, "media.files.origin_path");
+ while(this->mrls_allocated_entries) {
+ MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
+ free(this->mrls[this->mrls_allocated_entries--]);
+ }
free (this->mrls);
+
free (this);
}
diff --git a/src/input/input_net.c b/src/input/input_net.c
index cd4a8c901..801093e96 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -113,7 +113,10 @@ typedef struct {
static int host_connect_attempt_ipv4(struct in_addr ia, int port, xine_t *xine) {
int s;
- struct sockaddr_in sin;
+ union {
+ struct sockaddr_in in;
+ struct sockaddr sa;
+ } sa;
s = xine_socket_cloexec(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s==-1) {
@@ -122,14 +125,14 @@ static int host_connect_attempt_ipv4(struct in_addr ia, int port, xine_t *xine)
return -1;
}
- sin.sin_family = AF_INET;
- sin.sin_addr = ia;
- sin.sin_port = htons(port);
+ sa.in.sin_family = AF_INET;
+ sa.in.sin_addr = ia;
+ sa.in.sin_port = htons(port);
#ifndef WIN32
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS)
+ if (connect(s, &sa.sa, sizeof(sa.in))==-1 && errno != EINPROGRESS)
#else
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && WSAGetLastError() != WSAEINPROGRESS)
+ if (connect(s, &sa.sa, sizeof(sa.in))==-1 && WSAGetLastError() != WSAEINPROGRESS)
#endif
{
xine_log(xine, XINE_LOG_MSG,
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c
index 5e66bee82..0503316da 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -98,7 +98,13 @@
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
-#include <linux/videodev2.h>
+#ifdef HAVE_SYS_VIDEOIO_H
+# include <sys/videoio.h>
+#elif defined(HAVE_SYS_VIDEODEV2_H)
+# include <sys/videodev2.h>
+#else
+# include <linux/videodev2.h>
+#endif
#define XINE_ENABLE_EXPERIMENTAL_FEATURES
diff --git a/src/input/input_smb.c b/src/input/input_smb.c
index b2211e2ae..f3c2c035d 100644
--- a/src/input/input_smb.c
+++ b/src/input/input_smb.c
@@ -345,7 +345,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
- memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
+ MRL_ZERO(this->mrls[num_files]);
MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
@@ -362,7 +362,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
- memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
+ MRL_ZERO(this->mrls[num_files]);
MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
@@ -440,6 +440,20 @@ smb_plugin_open (input_plugin_t *this_gen )
return 1;
}
+static void
+smb_class_dispose (input_class_t *this_gen)
+{
+ smb_input_class_t *this = (smb_input_class_t *) this_gen;
+
+ while(this->mrls_allocated_entries) {
+ MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
+ free(this->mrls[this->mrls_allocated_entries--]);
+ }
+ free(this->mrls);
+
+ free (this);
+}
+
static input_plugin_t *
smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
const char *mrl)
@@ -498,7 +512,7 @@ static void
this->input_class.description = N_("CIFS/SMB input plugin based on libsmbclient");
this->input_class.get_dir = smb_class_get_dir;
this->input_class.get_autoplay_list = NULL;
- this->input_class.dispose = default_input_class_dispose;
+ this->input_class.dispose = smb_class_dispose;
this->input_class.eject_media = NULL;
_exit_error:
diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c
index d50a6a8c4..87054bfaa 100644
--- a/src/input/net_buf_ctrl.c
+++ b/src/input/net_buf_ctrl.c
@@ -158,8 +158,8 @@ static void dvbspeed_init (nbc_t *this) {
#endif
}
if (xine_config_lookup_entry (xine, "engine.buffers.video_num_buffers",
- &entry) && (entry.num_value < 1800)) {
- config->update_num (config, "engine.buffers.video_num_buffers", 1800);
+ &entry) && (entry.num_value < 800)) {
+ config->update_num (config, "engine.buffers.video_num_buffers", 800);
#ifdef LOG_DVBSPEED
printf ("net_buf_ctrl: enlarged video fifo to 1800 buffers\n");
#endif
diff --git a/src/spu_dec/spudvb_decoder.c b/src/spu_dec/spudvb_decoder.c
index 860d7cc35..8cdba1baa 100644
--- a/src/spu_dec/spudvb_decoder.c
+++ b/src/spu_dec/spudvb_decoder.c
@@ -87,6 +87,8 @@ typedef struct {
typedef struct dvb_spu_class_s {
spu_decoder_class_t class;
xine_t *xine;
+
+ int ignore_pts;
} dvb_spu_class_t;
typedef struct dvb_spu_decoder_s {
@@ -105,9 +107,8 @@ typedef struct dvb_spu_decoder_s {
char *pes_pkt_wrptr;
unsigned int pes_pkt_size;
- uint64_t pts;
- uint64_t vpts;
- uint64_t end_vpts;
+ int64_t vpts;
+ int64_t end_vpts;
pthread_t dvbsub_timer_thread;
struct timespec dvbsub_hide_timeout;
@@ -896,7 +897,7 @@ static void draw_subtitles (dvb_spu_decoder_t * this)
}
pthread_mutex_lock(&this->dvbsub_osd_mutex);
- lprintf("this->vpts=%llu\n",this->vpts);
+ lprintf("this->vpts=%"PRId64"\n",this->vpts);
for ( r=0; r<MAX_REGIONS; r++ ) {
lprintf("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 );
if ( this->dvbsub->page.regions[r].is_visible && this->dvbsub->regions[r].osd && !this->dvbsub->regions[r].empty ) {
@@ -949,27 +950,29 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
}
return;
}
- else {
- if (buf->decoder_info[2]) {
- memset (this->pes_pkt, 0xff, 64*1024);
- this->pes_pkt_wrptr = this->pes_pkt;
- this->pes_pkt_size = buf->decoder_info[2];
- this->pts = buf->pts;
- xine_fast_memcpy (this->pes_pkt, buf->content, buf->size);
+ /* accumulate data */
+ if (buf->decoder_info[2]) {
+ memset (this->pes_pkt, 0xff, 64*1024);
+ this->pes_pkt_wrptr = this->pes_pkt;
+ this->pes_pkt_size = buf->decoder_info[2];
+
+ xine_fast_memcpy (this->pes_pkt, buf->content, buf->size);
+ this->pes_pkt_wrptr += buf->size;
+
+ this->vpts = 0;
+ }
+ else {
+ if (this->pes_pkt && (this->pes_pkt_wrptr != this->pes_pkt)) {
+ xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size);
this->pes_pkt_wrptr += buf->size;
}
- else {
- if (this->pes_pkt && (this->pes_pkt_wrptr != this->pes_pkt)) {
- xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size);
- this->pes_pkt_wrptr += buf->size;
- }
- }
}
+
/* don't ask metronom for a vpts but rather do the calculation
* because buf->pts could be too far in future and metronom won't accept
* further backwards pts (see metronom_got_spu_packet) */
- if (buf->pts) {
+ if (!this->class->ignore_pts && buf->pts > 0) {
metronom_t *metronom = this->stream->metronom;
int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET );
int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET );
@@ -977,7 +980,7 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
metronom_clock_t *clock = this->stream->xine->clock;
int64_t curvpts = clock->get_current_time( clock );
/* if buf->pts is unreliable, show page asap (better than nothing) */
- lprintf("spu_vpts=%lld - current_vpts=%lld\n", vpts, curvpts);
+ lprintf("spu_vpts=%"PRId64" - current_vpts=%"PRId64"\n", vpts, curvpts);
if ( vpts<=curvpts || (vpts-curvpts)>(5*90000) )
this->vpts = 0;
else
@@ -985,7 +988,7 @@ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
}
/* completely ignore pts since it makes a lot of problems with various providers */
- this->vpts = 0;
+ /* this->vpts = 0; */
/* process the pes section */
@@ -1175,6 +1178,15 @@ static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen
return (spu_decoder_t *) this;
}
+static void dvb_spu_decoder_class_dispose (spu_decoder_class_t * this_gen)
+{
+ dvb_spu_class_t *this = (dvb_spu_class_t *) this_gen;
+
+ this->xine->config->unregister_callback(this->xine->config, "subtitles.dvb.ignore_pts");
+
+ free (this);
+}
+
static void *init_spu_decoder_plugin (xine_t * xine, void *data)
{
@@ -1184,7 +1196,7 @@ static void *init_spu_decoder_plugin (xine_t * xine, void *data)
this->class.open_plugin = dvb_spu_class_open_plugin;
this->class.identifier = "spudvb";
this->class.description = N_("DVB subtitle decoder plugin");
- this->class.dispose = default_spu_decoder_class_dispose;
+ this->class.dispose = dvb_spu_decoder_class_dispose;
this->xine = xine;
diff --git a/src/video_dec/image.c b/src/video_dec/image.c
index cbbb9d722..e91588702 100644
--- a/src/video_dec/image.c
+++ b/src/video_dec/image.c
@@ -54,6 +54,17 @@
#include <xine/xineutils.h>
#include "bswap.h"
+#ifdef HAVE_GRAPHICSMAGICK
+# define MAGICK_VERSION 0x670
+#else
+# if !defined(MagickLibVersion) || MagickLibVersion < 0x671
+# define MAGICK_VERSION 0x670
+#else
+# define MAGICK_VERSION MagickLibVersion
+# endif
+#endif
+
+
typedef struct {
video_decoder_class_t decoder_class;
@@ -101,14 +112,23 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
/*
* this->image -> rgb data
*/
+#if MAGICK_VERSION < 0x671
InitializeMagick(NULL);
+#else
+ MagickWandGenesis();
+#endif
wand = NewMagickWand();
status = MagickReadImageBlob(wand, this->image, this->index);
+
this->index = 0;
if (!status) {
DestroyMagickWand(wand);
+#if MAGICK_VERSION < 0x671
DestroyMagick();
+#else
+ MagickWandTerminus();
+#endif
lprintf("error loading image\n");
return;
}
@@ -116,9 +136,15 @@ static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
width = MagickGetImageWidth(wand) & ~1; /* must be even for init_yuv_planes */
height = MagickGetImageHeight(wand);
img_buf = malloc(width * height * 3);
+#if MAGICK_VERSION < 0x671
MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf);
DestroyMagickWand(wand);
DestroyMagick();
+#else
+ MagickExportImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf);
+ DestroyMagickWand(wand);
+ MagickWandTerminus();
+#endif
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height);
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index 55661c381..31ee4443a 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.c
@@ -1189,6 +1189,8 @@ static const audio_db_t audio_db[] = {
},
{
{
+ ME_FOURCC('E', 'A', 'C', '3'),
+ ME_FOURCC('e', 'c', '-', '3'),
0
},
BUF_AUDIO_EAC3,
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index 0eada28b4..924fbe02a 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -1035,7 +1035,9 @@ void xine_config_save (xine_t *xine, const char *filename) {
buf = (char *) malloc(config_stat.st_size + 1);
if((rlen = fread(buf, 1, config_stat.st_size, f_config)) && ((off_t)rlen == config_stat.st_size)) {
- (void) fwrite(buf, 1, rlen, f_backup);
+ if (rlen != fwrite(buf, 1, rlen, f_backup)) {
+ lprintf("backing up configfile to %s failed\n", temp);
+ }
}
free(buf);
diff --git a/src/xine-engine/io_helper.c b/src/xine-engine/io_helper.c
index 399cb25a4..1336fc790 100644
--- a/src/xine-engine/io_helper.c
+++ b/src/xine-engine/io_helper.c
@@ -87,17 +87,19 @@ static int _x_io_tcp_connect_ipv4(xine_stream_t *stream, const char *host, int p
for (i = 0; h->h_addr_list[i]; i++) {
struct in_addr ia;
- struct sockaddr_in sin;
-
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+ } saddr;
memcpy (&ia, h->h_addr_list[i], 4);
- sin.sin_family = AF_INET;
- sin.sin_addr = ia;
- sin.sin_port = htons(port);
+ saddr.in.sin_family = AF_INET;
+ saddr.in.sin_addr = ia;
+ saddr.in.sin_port = htons(port);
#ifndef WIN32
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS) {
+ if (connect(s, &saddr.sa, sizeof(saddr.in))==-1 && errno != EINPROGRESS) {
#else
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && WSAGetLastError() != WSAEWOULDBLOCK) {
+ if (connect(s, &saddr.sa, sizeof(saddr.in))==-1 && WSAGetLastError() != WSAEWOULDBLOCK) {
if (stream)
xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: WSAGetLastError() = %d\n", WSAGetLastError());
#endif /* WIN32 */
diff --git a/src/xine-utils/memcpy.c b/src/xine-utils/memcpy.c
index cea2b5b0b..515919a41 100644
--- a/src/xine-utils/memcpy.c
+++ b/src/xine-utils/memcpy.c
@@ -1,4 +1,4 @@
-/*
+;/*
* Copyright (C) 2001-2004 the xine project
*
* This file is part of xine, a free video player.
@@ -403,11 +403,23 @@ static const struct {
{ "ppcasm", ppcasm_memcpy, 0 },
{ "ppcasm_cached", ppcasm_cacheable_memcpy, MM_ACCEL_PPC_CACHE32 },
#endif /* ARCH_PPC && !HOST_OS_DARWIN */
+ { "", NULL, 0 }
};
static uint64_t memcpy_timing[sizeof(memcpy_method)/sizeof(memcpy_method[0])] = { 0, };
-#if (defined(ARCH_X86) || defined(ARCH_X86_64)) && defined(HAVE_SYS_TIMES_H)
+#ifdef HAVE_POSIX_TIMERS
+/* Prefer clock_gettime() where available. */
+static int64_t _x_gettime(void)
+{
+ struct timespec tm;
+ return (clock_gettime (CLOCK_THREAD_CPUTIME_ID, &tm) == -1)
+ ? times (NULL)
+ : (int64_t)tm.tv_sec * 1e9 + tm.tv_nsec;
+}
+# define rdtsc(x) _x_gettime()
+
+#elif (defined(ARCH_X86) || defined(ARCH_X86_64)) && defined(HAVE_SYS_TIMES_H)
static int64_t rdtsc(int config_flags)
{
int64_t x;
@@ -510,7 +522,13 @@ void xine_probe_fast_memcpy(xine_t *xine)
memset(buf1,0,BUFSIZE);
memset(buf2,0,BUFSIZE);
- for(i = 1; i < sizeof(memcpy_method)/sizeof(memcpy_method[0]); i++)
+ /* some initial activity to ensure that we're not running slowly :-) */
+ for(j=0;j<50;j++) {
+ memcpy_method[1].function(buf2,buf1,BUFSIZE);
+ memcpy_method[1].function(buf1,buf2,BUFSIZE);
+ }
+
+ for(i=1; memcpy_method[i].name[0]; i++)
{
if( (config_flags & memcpy_method[i].cpu_require) !=
memcpy_method[i].cpu_require )