diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/audio_dec/xine_a52_decoder.c | 6 | ||||
-rw-r--r-- | src/combined/ffmpeg/ff_audio_decoder.c | 6 | ||||
-rw-r--r-- | src/demuxers/demux_ts.c | 460 | ||||
-rw-r--r-- | src/input/Makefile.am | 2 | ||||
-rw-r--r-- | src/input/input_cdda.c | 32 | ||||
-rw-r--r-- | src/input/input_file.c | 11 | ||||
-rw-r--r-- | src/input/input_net.c | 15 | ||||
-rw-r--r-- | src/input/input_pvr.c | 8 | ||||
-rw-r--r-- | src/input/input_smb.c | 20 | ||||
-rw-r--r-- | src/input/net_buf_ctrl.c | 4 | ||||
-rw-r--r-- | src/spu_dec/spudvb_decoder.c | 54 | ||||
-rw-r--r-- | src/video_dec/image.c | 26 | ||||
-rw-r--r-- | src/xine-engine/buffer_types.c | 2 | ||||
-rw-r--r-- | src/xine-engine/configfile.c | 4 | ||||
-rw-r--r-- | src/xine-engine/io_helper.c | 16 | ||||
-rw-r--r-- | src/xine-utils/memcpy.c | 24 |
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 ) |