From 8484f697b1ed8e4d45b4a4549319e34668707d73 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 22 Jul 2011 16:53:53 +0300 Subject: demux_ts: Removed unused and write-only variables --- src/demuxers/demux_ts.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index ed360ab38..cd211ae3c 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -271,7 +271,6 @@ typedef struct { buf_element_t *buf; unsigned int counter; uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */ - int64_t packet_count; int corrupted_pes; uint32_t buffered_bytes; @@ -316,7 +315,6 @@ typedef struct { int pkt_size; /* TS packet size */ int pkt_offset; /* TS packet offset */ - int blockSize; int rate; int media_num; demux_ts_media media[MAX_PIDS]; @@ -331,17 +329,12 @@ typedef struct { * and audio PIDs, we keep the index of the corresponding entry * inthe media[] array. */ - unsigned int programNumber; - unsigned int pcrPid; - unsigned int pid; - unsigned int pid_count; unsigned int videoPid; unsigned int videoMedia; demux_ts_audio_track audio_tracks[MAX_AUDIO_TRACKS]; int audio_tracks_count; - int send_end_buffers; int64_t last_pts[2]; int send_newpts; int buf_flag_seek; @@ -1600,6 +1593,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num section_length -= coded_length; } +#if 0 /* * Get the current PCR PID. */ @@ -1615,6 +1609,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num #endif this->pcrPid = pid; } +#endif if ( this->stream->spu_channel>=0 && this->spu_langs_count>0 ) demux_ts_update_spu_channel( this ); @@ -2146,7 +2141,6 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) { this->status = DEMUX_OK ; - this->send_end_buffers = 1; this->scrambled_npids = 0; /* DVBSUB */ @@ -2363,7 +2357,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this = calloc(1, sizeof(*this)); this->stream = stream; this->input = input; - this->blockSize = PKT_SIZE; this->demux_plugin.send_headers = demux_ts_send_headers; this->demux_plugin.send_chunk = demux_ts_send_chunk; @@ -2390,8 +2383,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->pmt_write_ptr[i] = NULL; } - this->programNumber = INVALID_PROGRAM; - this->pcrPid = INVALID_PID; this->scrambled_npids = 0; this->videoPid = INVALID_PID; this->audio_tracks_count = 0; -- cgit v1.2.3 From 48f14a96cbf10a770a5913fc851133ea4b3ea90e Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 15 Jul 2011 09:47:58 +0300 Subject: Removed unused parameter --- src/demuxers/demux_ts.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index cd211ae3c..a8daf5c63 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -691,8 +691,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, } static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, - uint8_t *buf, int packet_len, - xine_stream_t *stream) { + uint8_t *buf, int packet_len) { unsigned char *p; uint32_t header_len; @@ -1006,7 +1005,7 @@ 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, this->stream)) { + if (!demux_ts_parse_pes_header(this->stream->xine, m, ts, len)) { m->buf->free_buffer(m->buf); m->buf = NULL; -- cgit v1.2.3 From d39ee63a87e9a6140078911aa1cbbcc8f4acdcb4 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 15 Jul 2011 09:52:29 +0300 Subject: Factorized known audio pid search code --- src/demuxers/demux_ts.c | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index a8daf5c63..c27ddd01d 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1136,6 +1136,15 @@ static inline int ts_payloadsize(unsigned char * tsp) return 184; } +/* check if an apid is in the list of known apids */ +static int apid_check(demux_ts_t*this, unsigned int pid) { + int i; + for (i = 0; i < this->audio_tracks_count; i++) { + if (this->audio_tracks[i].pid == pid) + return i; + } + return -1; +} /* * NAME demux_ts_parse_pmt @@ -1385,14 +1394,7 @@ 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) { - int i, found = 0; - for(i = 0; i < this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) { - found = 1; - break; - } - } - if(!found) { + if (apid_check(this, pid) < 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif @@ -1423,14 +1425,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num case ISO_13818_PES_PRIVATE: for (i = 5; i < coded_length; i += stream[i+1] + 2) { if (((stream[i] == 0x6a) || (stream[i] == 0x7a)) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { - int j, found = 0; - for(j = 0; j < this->audio_tracks_count; j++) { - if(this->audio_tracks[j].pid == pid) { - found = 1; - break; - } - } - if (!found) { + if (apid_check(this, pid) < 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif @@ -1549,14 +1544,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num * 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) ) { - int i, found = 0; - for(i = 0; i < this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) { - found = 1; - break; - } - } - if(!found) { + if (apid_check(this,pid) < 0) { uint32_t format_identifier=0; demux_ts_get_reg_desc(this, &format_identifier, stream + 5, stream_info_length); @@ -1847,16 +1835,6 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, return PCR; } -/* check if an apid is in the list of known apids */ -static int apid_check(demux_ts_t*this, unsigned int pid) { - int i; - for(i=0; iaudio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) - return i; - } - return -1; -} - /* transport stream packet layer */ static void demux_ts_parse_packet (demux_ts_t*this) { -- cgit v1.2.3 From 315a7046cdcbe7b60e79665ea8def2c6c74d59b9 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 18 Jul 2011 22:32:30 +0300 Subject: Removed unneeded check --- src/demuxers/demux_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index c27ddd01d..2b56721bc 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1191,7 +1191,7 @@ static void demux_ts_parse_pmt (demux_ts_t *this, pkt+=pkt[4]; /* pointer to start of section */ offset=1; - if (this->pmt[program_count] != NULL) free(this->pmt[program_count]); + free(this->pmt[program_count]); this->pmt[program_count] = (uint8_t *) calloc(4096, sizeof(unsigned char)); this->pmt_write_ptr[program_count] = this->pmt[program_count]; -- cgit v1.2.3 From 431685cc1f92b11a84101963a38079a598abeacc Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 1 Aug 2011 21:53:37 +0300 Subject: demux_ts: removed unneeded check ((stream_id & 0xf0) == 0xe0 implies stream_id >= 0xbc) --- src/demuxers/demux_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 2b56721bc..49a7e0bd4 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -875,7 +875,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 1; } - } else if ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) { + } else if ((stream_id & 0xf0) == 0xe0) { m->content = p; m->size = packet_len; -- cgit v1.2.3 From 240d3b758cbb5d31523fa592a797732203835f6d Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Sat, 16 Jul 2011 13:00:26 +0300 Subject: demux_ts: Fixed reading outside of buffer. Checking if pes header length == 6 is not enough ; anything less than 9 is invalid (header length byte at [8] can't be used if it is outside of buffer). Moved check to beginning of parse_pes_header() to avoid reading outside of buffer. --- src/demuxers/demux_ts.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 49a7e0bd4..f46c5d4f2 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -699,6 +699,12 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, uint32_t stream_id; int pkt_len; + if (packet_len < 9) { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "demux_ts: too short PES packet header (%d bytes)\n", packet_len); + return 0; + } + p = buf; pkt_len = packet_len; @@ -714,13 +720,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, /* packet_len = p[4] << 8 | p[5]; */ stream_id = p[3]; - if (packet_len==0) - { - xprintf (xine, XINE_VERBOSITY_DEBUG, - "demux_ts: error pes length 0\n"); - return 0; - } - #ifdef TS_LOG printf ("demux_ts: packet stream id: %.2x len: %d (%x)\n", stream_id, packet_len, packet_len); -- cgit v1.2.3 From efd03cf91cbdf69178f7cc0c4817832302d3d95d Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Sat, 16 Jul 2011 13:30:34 +0300 Subject: demux_ts: Fixed reading outside of buffer: check header length before parsing pts. --- src/demuxers/demux_ts.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index f46c5d4f2..d6d2a0cbe 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -719,6 +719,14 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, packet_len -= 6; /* packet_len = p[4] << 8 | p[5]; */ stream_id = p[3]; + header_len = p[8]; + + /* sometimes corruption on header_len causes segfault in memcpy below */ + if (header_len + 9 > pkt_len) { + xprintf (xine, XINE_VERBOSITY_DEBUG, + "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len); + return 0; + } #ifdef TS_LOG printf ("demux_ts: packet stream id: %.2x len: %d (%x)\n", @@ -727,6 +735,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, if (p[7] & 0x80) { /* pts avail */ + if (header_len < 5) { + return 0; + } + pts = (int64_t)(p[ 9] & 0x0E) << 29 ; pts |= p[10] << 22 ; pts |= (p[11] & 0xFE) << 14 ; @@ -751,15 +763,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->pts = pts; - header_len = p[8]; - - /* sometimes corruption on header_len causes segfault in memcpy below */ - if (header_len + 9 > pkt_len) { - xprintf (xine, XINE_VERBOSITY_DEBUG, - "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len); - return 0; - } - p += header_len + 9; packet_len -= header_len + 3; -- cgit v1.2.3 From d2a56a22ce0bf95354636acd9412b177fafd0917 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Sat, 16 Jul 2011 13:35:33 +0300 Subject: parse_pes_header(): eliminated local variable by simplifying the code that skips pes header --- src/demuxers/demux_ts.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index d6d2a0cbe..0fd3a1299 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -697,7 +697,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, uint32_t header_len; int64_t pts; uint32_t stream_id; - int pkt_len; if (packet_len < 9) { xprintf (xine, XINE_VERBOSITY_DEBUG, @@ -706,7 +705,6 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, } p = buf; - pkt_len = packet_len; /* we should have a PES packet here */ @@ -716,13 +714,12 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 0 ; } - packet_len -= 6; /* packet_len = p[4] << 8 | p[5]; */ stream_id = p[3]; header_len = p[8]; /* sometimes corruption on header_len causes segfault in memcpy below */ - if (header_len + 9 > pkt_len) { + if (header_len + 9 > packet_len) { xprintf (xine, XINE_VERBOSITY_DEBUG, "demux_ts: illegal value for PES_header_data_length (0x%x)\n", header_len); return 0; @@ -764,7 +761,7 @@ 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 + 3; + packet_len -= header_len + 9; if (m->descriptor_tag == STREAM_VIDEO_VC1) { m->content = p; -- cgit v1.2.3 From 0642ef94edb64507d80071803908a2c318052e32 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 22 Jul 2011 17:03:47 +0300 Subject: demux_ts: Added buffer size checks. Make sure buffer size is not set to negative value (that results writing out of buffer when buffering payload). Check buffer size before checking substream header bytes. --- src/demuxers/demux_ts.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 0fd3a1299..4affa3b2c 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -801,7 +801,7 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 1; } else if((m->descriptor_tag == STREAM_AUDIO_AC3) || /* ac3 - raw */ - (p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */ + (packet_len > 1 && p[0] == 0x0B && p[1] == 0x77)) { /* ac3 - syncword */ m->content = p; m->size = packet_len; m->type |= BUF_AUDIO_A52; @@ -821,8 +821,15 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->type |= BUF_AUDIO_DTS; return 1; + } else if (packet_len < 2) { + return 0; + } else if (m->descriptor_tag == HDMV_AUDIO_80_PCM) { + if (packet_len < 4) { + return 0; + } + m->content = p + 4; m->size = packet_len - 4; m->type |= BUF_AUDIO_LPCM_BE; @@ -852,6 +859,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, return 1; } else if ((p[0] & 0xF0) == 0x80) { + if (packet_len < 4) { + return 0; + } + m->content = p+4; m->size = packet_len - 4; m->type |= BUF_AUDIO_A52; @@ -868,6 +879,10 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, } } + if (packet_len < pcm_offset) { + return 0; + } + m->content = p+pcm_offset; m->size = packet_len-pcm_offset; m->type |= BUF_AUDIO_LPCM_BE; -- cgit v1.2.3 From c59f362c07750c0497973b47ee96a6ef632cd533 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 18 Jul 2011 22:36:15 +0300 Subject: Fixed writing outside of buffer when there are more than MAX_PIDS scrambled pids. --- src/demuxers/demux_ts.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 4affa3b2c..52b07a437 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1917,8 +1917,10 @@ static void demux_ts_parse_packet (demux_ts_t*this) { for (i=0; i < this->scrambled_npids; i++) { if (this->scrambled_pids[i] == pid) return; } - this->scrambled_pids[this->scrambled_npids] = pid; - this->scrambled_npids++; + if (this->scrambled_npids < MAX_PIDS) { + this->scrambled_pids[this->scrambled_npids] = pid; + this->scrambled_npids++; + } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID 0x%.4x is scrambled!\n", pid); return; -- cgit v1.2.3 From dc086c7f3808b2da888f2e496edd7fef69b038c0 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 2 Aug 2011 15:42:21 +0300 Subject: demux_ts: added buffer size checks to adaptation field parsing --- src/demuxers/demux_ts.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 52b07a437..d5af1615e 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1806,6 +1806,9 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, } #endif if(PCR_flag) { + if (adaptation_field_length < offset + 6) + return 0; + PCR = (((int64_t) data[offset]) & 0xFF) << 25; PCR += (int64_t) ((data[offset+1] & 0xFF) << 17); PCR += (int64_t) ((data[offset+2] & 0xFF) << 9); @@ -1820,6 +1823,9 @@ static int64_t demux_ts_adaptation_field_parse(uint8_t *data, offset+=6; } if(OPCR_flag) { + if (adaptation_field_length < offset + 6) + return PCR; + OPCR = data[offset] << 25; OPCR |= data[offset+1] << 17; OPCR |= data[offset+2] << 9; -- cgit v1.2.3 From 698ade058a0c21fcd62c27e6c9ee79630206b6a5 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 18 Jul 2011 22:31:39 +0300 Subject: demux_ts: added m2ts and mts file extensions --- src/demuxers/demux_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index d5af1615e..ce2755ee0 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -2422,7 +2422,7 @@ static const char *get_identifier (demux_class_t *this_gen) { } static const char *get_extensions (demux_class_t *this_gen) { - return "ts m2t trp"; + return "ts m2t trp m2ts mts"; } static const char *get_mimetypes (demux_class_t *this_gen) { -- cgit v1.2.3 From 1a9361785cdde74feff211fc48a783ba154bc958 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Tue, 23 Aug 2011 08:59:56 -0700 Subject: Logic error with AC3 demuxer This is a small mistake, but I'm fairly sure the index should be "j" and not "i". --- src/demuxers/demux_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index f31578073..cde28adfb 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1438,7 +1438,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num if (((stream[i] == 0x6a) || (stream[i] == 0x7a)) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { int j, found = 0; for(j = 0; j < this->audio_tracks_count; j++) { - if(this->audio_tracks[i].pid == pid) { + if(this->audio_tracks[j].pid == pid) { found = 1; break; } -- cgit v1.2.3 From 5306a37c61291161102d4834491b16211d8c6b28 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Sun, 14 Aug 2011 14:51:04 +0300 Subject: Fixed multithreaded decoding with lavc >= 52.112.0. avcodec_thread_init() was deprecated in lavc 52.112.0 (2011-02-09) --- src/combined/ffmpeg/ff_video_decoder.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index a9c383c48..d1c2fcb5b 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -66,6 +66,10 @@ # define pp_mode pp_mode_t #endif +#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 112) +# define DEPRECATED_AVCODEC_THREAD_INIT 1 +#endif + /* reordered_opaque appeared in libavcodec 51.68.0 */ #define AVCODEC_HAS_REORDERED_OPAQUE #if LIBAVCODEC_VERSION_INT < 0x334400 @@ -365,7 +369,10 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) if (this->class->thread_count > 1) { if (this->codec->id != CODEC_ID_SVQ3 - && avcodec_thread_init(this->context, this->class->thread_count) != -1) +#ifndef DEPRECATED_AVCODEC_THREAD_INIT + && avcodec_thread_init(this->context, this->class->thread_count) != -1 +#endif + ) this->context->thread_count = this->class->thread_count; } -- cgit v1.2.3 From 7512f3a88f47b32e196f75920480a2d733c9ae61 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 9 Aug 2011 16:05:27 +0300 Subject: ffmpeg VC-1: scan for extradata (sequence header) from preview buffers --- src/combined/ffmpeg/ff_video_decoder.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index d1c2fcb5b..2c2a08cc1 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -878,6 +878,10 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b } if (this->decoder_init_mode && !this->is_mpeg12) { + + if (!ff_check_extradata(this, codec_type, buf)) + return; + init_video_codec(this, codec_type); init_postprocess(this); this->decoder_init_mode = 0; -- cgit v1.2.3 From d211575f64577027568ff85497eb357f878401fb Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 9 Aug 2011 16:04:31 +0300 Subject: Cosmetics: reordered functions --- src/combined/ffmpeg/ff_video_decoder.c | 86 +++++++++++++++++----------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 2c2a08cc1..92fee481f 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -862,6 +862,49 @@ static void ff_check_bufsize (ff_video_decoder_t *this, int size) { } } +static int ff_vc1_find_header(ff_video_decoder_t *this, buf_element_t *buf) +{ + uint8_t *p = buf->content; + + if (!p[0] && !p[1] && p[2] == 1 && p[3] == 0x0f) { + int i; + + this->context->extradata = calloc(1, buf->size); + this->context->extradata_size = 0; + + for (i = 0; i < buf->size && i < 128; i++) { + if (!p[i] && !p[i+1] && p[i+2]) { + lprintf("00 00 01 %02x at %d\n", p[i+3], i); + if (p[i+3] != 0x0e && p[i+3] != 0x0f) + break; + } + this->context->extradata[i] = p[i]; + this->context->extradata_size++; + } + + lprintf("ff_video_decoder: found VC1 sequence header\n"); + return 1; + } + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "ffmpeg_video_dec: VC1 extradata missing !\n"); + return 0; +} + +static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, buf_element_t *buf) +{ + if (this->context && this->context->extradata) + return 1; + + switch (codec_type) { + case BUF_VIDEO_VC1: + return ff_vc1_find_header(this, buf); + default:; + } + + return 1; +} + static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type; @@ -1223,49 +1266,6 @@ static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts) } #endif /* AVCODEC_HAS_REORDERED_OPAQUE */ -static int ff_vc1_find_header(ff_video_decoder_t *this, buf_element_t *buf) -{ - uint8_t *p = buf->content; - - if (!p[0] && !p[1] && p[2] == 1 && p[3] == 0x0f) { - int i; - - this->context->extradata = calloc(1, buf->size); - this->context->extradata_size = 0; - - for (i = 0; i < buf->size && i < 128; i++) { - if (!p[i] && !p[i+1] && p[i+2]) { - lprintf("00 00 01 %02x at %d\n", p[i+3], i); - if (p[i+3] != 0x0e && p[i+3] != 0x0f) - break; - } - this->context->extradata[i] = p[i]; - this->context->extradata_size++; - } - - lprintf("ff_video_decoder: found VC1 sequence header\n"); - return 1; - } - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "ffmpeg_video_dec: VC1 extradata missing !\n"); - return 0; -} - -static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, buf_element_t *buf) -{ - if (this->context && this->context->extradata) - return 1; - - switch (codec_type) { - case BUF_VIDEO_VC1: - return ff_vc1_find_header(this, buf); - default:; - } - - return 1; -} - static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { uint8_t *chunk_buf = this->buf; AVRational avr00 = {0, 1}; -- cgit v1.2.3 From 80cbcb6136ca8a4b93c8dd652e8349c7f9ac9dd4 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 29 Aug 2011 09:33:16 +0100 Subject: Add AAC LATM support from FFmpeg 0.7+ I've now tested this patch on Fedora 15 (FFmpeg 0.7) and Fedora 14 (FFmpeg 0.6), and am happy to report that it works fine on F15 and doesn't break xine-lib on F14. On F14, it also has the happy side effect of no longer trying to decode an LATM AAC stream with the xineplug_decode_faad.so plugin. (Which was something which never ended well anyway.) --- configure.ac | 2 +- src/combined/ffmpeg/xine_audio.list | 1 + src/demuxers/demux_ts.c | 5 ++++- src/xine-engine/buffer.h | 1 + src/xine-engine/buffer_types.c | 8 ++++++++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 98b515bd7..8367a68af 100644 --- a/configure.ac +++ b/configure.ac @@ -412,7 +412,7 @@ for ucname in $ffmpeg_uncommon_codecs; do done dnl popular ffmpeg codecs -ffmpeg_popular_codecs="CINEPAK FLASHSV H261 H263 H263I H264 INDEO2 INDEO3 MJPEG MJPEGB MPEG1VIDEO MPEG2VIDEO MPEG4 MPEGVIDEO MSMPEG4V1 MSMPEG4V2 MSMPEG4V3 MSRLE MSVIDEO1 QTRLE RV10 RV20 SVQ1 SVQ3 VC1 VP3 VP5 VP6 VP6F WMV1 WMV2 WMV3 COOK DTS EAC3 FLAC MP2 MP3 QDM2 RA_144 RA_288 WAVPACK WMAV1 WMAV2 WMAPRO ADPCM_SWF" +ffmpeg_popular_codecs="CINEPAK FLASHSV H261 H263 H263I H264 INDEO2 INDEO3 MJPEG MJPEGB MPEG1VIDEO MPEG2VIDEO MPEG4 MPEGVIDEO MSMPEG4V1 MSMPEG4V2 MSMPEG4V3 MSRLE MSVIDEO1 QTRLE RV10 RV20 SVQ1 SVQ3 VC1 VP3 VP5 VP6 VP6F WMV1 WMV2 WMV3 COOK DTS EAC3 AAC_LATM FLAC MP2 MP3 QDM2 RA_144 RA_288 WAVPACK WMAV1 WMAV2 WMAPRO ADPCM_SWF" for ucname in $ffmpeg_popular_codecs; do config_name="CONFIG_${ucname}_DECODER" diff --git a/src/combined/ffmpeg/xine_audio.list b/src/combined/ffmpeg/xine_audio.list index 5daa4d8b0..0ebbfbda6 100644 --- a/src/combined/ffmpeg/xine_audio.list +++ b/src/combined/ffmpeg/xine_audio.list @@ -42,6 +42,7 @@ WAVPACK WAVPACK WavPack AMR_NB AMR_NB AMR narrow band AMR_WB AMR_WB AMR wide band EAC3 EAC3 E-AC-3 +AAC_LATM AAC_LATM AAC LATM # disabled codecs (ref. configure.ac) ! AAC diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index cde28adfb..1f0640147 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -921,10 +921,13 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, m->type |= BUF_AUDIO_MPEG; break; case ISO_13818_PART7_AUDIO: - case ISO_14496_PART3_AUDIO: lprintf ("demux_ts: found AAC audio track.\n"); m->type |= BUF_AUDIO_AAC; break; + case ISO_14496_PART3_AUDIO: + lprintf ("demux_ts: found AAC LATM audio track.\n"); + m->type |= BUF_AUDIO_AAC_LATM; + break; default: lprintf ("demux_ts: unknown audio type: %d, defaulting to MPEG.\n", m->descriptor_tag); m->type |= BUF_AUDIO_MPEG; diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index 9198ff103..8f5d1152e 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -262,6 +262,7 @@ extern "C" { #define BUF_AUDIO_AMR_NB 0x033F0000 #define BUF_AUDIO_AMR_WB 0x03400000 #define BUF_AUDIO_EAC3 0x03410000 +#define BUF_AUDIO_AAC_LATM 0x03420000 /* spu buffer types: */ diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c index 050043c64..913b29115 100644 --- a/src/xine-engine/buffer_types.c +++ b/src/xine-engine/buffer_types.c @@ -1192,6 +1192,14 @@ static const audio_db_t audio_db[] = { BUF_AUDIO_EAC3, "E-AC-3" }, +{ + { + ME_FOURCC('M', 'P', '4', 'L'), + 0 + }, + BUF_AUDIO_AAC_LATM, + "AAC LATM" +}, { { 0 }, 0, "last entry" } }; -- cgit v1.2.3 From b6ba1791153075a7f196583dde1f4e8153ec1098 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Fri, 26 Aug 2011 14:15:23 +0200 Subject: DVB sync The problem When watching live DVB, data is delivered strictly at the broadcasters speed. We cannot change it through server commands. Our local systems clock usually runs slightly faster or slower than that, causing a/v fifos to run empty or full after a few minutes. Standard network buffering control only handles the first case by pausing the engine (not nice). The latter case ends up in severe stuttering and an a/v lag of several seconds (annoying). I tried quite a few differnt algorithms, and this one made it: a 3 point controller. There is a target buffer fill window with a center and some tolerated width: Minimum: definition: 1 second safety: clamped to 38% of fio size action: switch playback speed to 99.5% Center: definition: 2 seconds safety: clamped to 73% fifo size action: switch to normal playback speed Maximum: definition: 3 seconds safety: clamped to 98% fifo fill action: switch playback speed to 100.5% If the usual dvb audio to video muxing delay is more than 1 second, center time is increased. On low bitrate radio, window width is increased. Real TVs do adjust playback audio sampling rate to follow delivery speed. Some PC sound cards can do that, too. It could be implemented transparently (although I don't know yet how). This comes quite close, resampling audio to stretch. That half percent is large enough to cover clock deviation, and it is small enough not to cause audible pitch bending. Speed control consists of adjusting SCR and telling audio out. Doing just the first will cause metronom to drop and/or insert whole audio frames, not nice with music. BTW. this one needs demux_ts to send BUF_FLAG_FRAME_START. --- src/input/net_buf_ctrl.c | 370 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 289 insertions(+), 81 deletions(-) diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c index ba17423fb..30db0e6e4 100644 --- a/src/input/net_buf_ctrl.c +++ b/src/input/net_buf_ctrl.c @@ -36,6 +36,8 @@ */ +#define LOG_DVBSPEED + #include "net_buf_ctrl.h" #define DEFAULT_HIGH_WATER_MARK 5000 /* in 1/1000 s */ @@ -79,6 +81,18 @@ struct nbc_s { int audio_in_disc; pthread_mutex_t mutex; + + /* follow live dvb delivery speed. + 0 = fix disabled + 1 = play at normal speed + 2 = play 0.5% slower to fill video fifo + 3 = play 0.5% faster to empty video fifo + 4..6 = same as 1..3 but watch audio fifo instead + 7 = pause */ + int dvbspeed; + int dvbs_center, dvbs_width, dvbs_audio_fill, dvbs_video_fill; + int64_t dvbs_audio_in, dvbs_audio_out; + int64_t dvbs_video_in, dvbs_video_out; }; static void report_progress (xine_stream_t *stream, int p) { @@ -116,6 +130,190 @@ void nbc_check_buffers (nbc_t *this) { /* Deprecated */ } +static void dvbspeed_init (nbc_t *this) { + const char *mrl; + if (this->stream && this->stream->input_plugin) { + mrl = this->stream->input_plugin->get_mrl (this->stream->input_plugin); + if (mrl) { + /* detect Kaffeine: fifo://~/.kde4/share/apps/kaffeine/dvbpipe.m2t */ + if ((strcasestr (mrl, "/dvbpipe.")) || + ((!strncasecmp (mrl, "dvb", 3)) && + ((mrl[3] == ':') || (mrl[3] && (mrl[4] == ':'))))) { + this->dvbs_center = 2 * 90000; + this->dvbs_width = 90000; + this->dvbs_audio_in = this->dvbs_audio_out = this->dvbs_audio_fill = 0; + this->dvbs_video_in = this->dvbs_video_out = this->dvbs_video_fill = 0; + this->dvbspeed = 7; +#ifdef LOG_DVBSPEED + /* I'm using plain printf because kaffeine sets verbosity to 0 */ + printf ("net_buf_ctrl: dvbspeed mode\n"); +#endif +#if 1 + /* somewhat rude but saves user a lot of frustration */ + if (this->stream) { + xine_t *xine = this->stream->xine; + config_values_t *config = xine->config; + xine_cfg_entry_t entry; + if (xine_config_lookup_entry (xine, "audio.synchronization.slow_fast_audio", + &entry) && (entry.num_value == 0)) { + config->update_num (config, "audio.synchronization.slow_fast_audio", 1); +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: slow/fast audio playback enabled\n"); +#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); +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: enlarged video fifo to 1800 buffers\n"); +#endif + } + } +#endif + } + } + } +} + +static void dvbspeed_close (nbc_t *this) { + if (((0xec >> this->dvbspeed) & 1) && this->stream) + _x_set_fine_speed (this->stream, XINE_FINE_SPEED_NORMAL); +#ifdef LOG_DVBSPEED + if (this->dvbspeed) printf ("net_buf_ctrl: dvbspeed OFF\n"); +#endif + this->dvbspeed = 0; +} + +static void dvbspeed_put (nbc_t *this, fifo_buffer_t * fifo, buf_element_t *b) { + int64_t diff, *last; + int *fill; + int used, mode; + const char *name; + /* select vars */ + if (fifo == this->video_fifo) { + last = &this->dvbs_video_in; + fill = &this->dvbs_video_fill; + mode = 0x71; + name = "video"; + } else if (fifo == this->audio_fifo) { + last = &this->dvbs_audio_in; + fill = &this->dvbs_audio_fill; + mode = 0x0f; + name = "audio"; + } else return; + /* update fifo fill time */ + if (b->pts && (b->decoder_flags & BUF_FLAG_FRAME_START)) { + if (*last) { + diff = b->pts - *last; + if ((diff > -220000) && (diff < 220000)) *fill += diff; + } + *last = b->pts; + } + /* take actions */ + if ((mode >> this->dvbspeed) & 1) return; + used = fifo->fifo_size; + switch (this->dvbspeed) { + case 1: + case 4: + if ((*fill > this->dvbs_center + this->dvbs_width) || + (100 * used > 98 * fifo->buffer_pool_capacity)) { + _x_set_fine_speed (this->stream, XINE_FINE_SPEED_NORMAL * 201 / 200); + this->dvbspeed += 2; +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: dvbspeed 100.5%% @ %s %d ms %d buffers\n", + name, (int)*fill / 90, used); +#endif + } + break; + case 7: + if (_x_get_fine_speed (this->stream)) { + /* Pause on first a/v buffer. Decoder headers went through at this time + already, and xine_play is done waiting for that */ + _x_set_fine_speed (this->stream, 0); +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: prebuffering...\n"); +#endif + break; + } + /* DVB streams usually mux video > 0.5 seconds earlier than audio + to give slow TVs time to decode and present in sync. Take care + of unusual high delays of some DVB-T streams */ + if (this->dvbs_audio_in && this->dvbs_video_in) { + int64_t d = this->dvbs_video_in - this->dvbs_audio_in + 110000; + if ((d < 3 * 90000) && (d > this->dvbs_center)) this->dvbs_center = d; + } + /* fall through */ + case 2: + case 5: + if ((*fill > this->dvbs_center) || (100 * used > 73 * fifo->buffer_pool_capacity)) { + _x_set_fine_speed (this->stream, XINE_FINE_SPEED_NORMAL); + this->dvbspeed = (mode & 0x10) ? 1 : 4; +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: dvbspeed 100%% @ %s %d ms %d buffers\n", + name, (int)*fill / 90, used); +#endif + /* dont let low bitrate radio switch speed too often */ + if (used < 30) this->dvbs_width = 135000; + } + break; + } +} + +static void dvbspeed_get (nbc_t *this, fifo_buffer_t * fifo, buf_element_t *b) { + int64_t diff, *last; + int *fill; + int used, mode; + const char *name; + /* select vars */ + if (fifo == this->video_fifo) { + last = &this->dvbs_video_out; + fill = &this->dvbs_video_fill; + mode = 0x71; + name = "video"; + } else if (fifo == this->audio_fifo) { + last = &this->dvbs_audio_out; + fill = &this->dvbs_audio_fill; + mode = 0x0f; + name = "audio"; + } else return; + /* update fifo fill time */ + if (b->pts && (b->decoder_flags & BUF_FLAG_FRAME_START)) { + if (*last) { + diff = b->pts - *last; + if ((diff > -220000) && (diff < 220000)) *fill -= diff; + } + *last = b->pts; + } + /* take actions */ + used = fifo->fifo_size; + if (((mode >> this->dvbspeed) & 1) || !*fill) return; + switch (this->dvbspeed) { + case 1: + case 4: + if ((*fill < this->dvbs_center - this->dvbs_width) && + (100 * used < 38 * fifo->buffer_pool_capacity)) { + _x_set_fine_speed (this->stream, XINE_FINE_SPEED_NORMAL * 199 / 200); + this->dvbspeed += 1; +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: dvbspeed 99.5%% @ %s %d ms %d buffers\n", + name, (int)*fill / 90, used); +#endif + } + break; + case 3: + case 6: + if ((*fill < this->dvbs_center) && (100 * used < 73 * fifo->buffer_pool_capacity)) { + _x_set_fine_speed (this->stream, XINE_FINE_SPEED_NORMAL); + this->dvbspeed -= 2; +#ifdef LOG_DVBSPEED + printf ("net_buf_ctrl: dvbspeed 100%% @ %s %d ms %d buffers\n", + name, (int)*fill / 90, used); +#endif + } + break; + } +} + static void display_stats (nbc_t *this) { static const char buffering[2][4] = {" ", "buf"}; static const char enabled[2][4] = {"off", "on "}; @@ -308,69 +506,73 @@ static void nbc_put_cb (fifo_buffer_t *fifo, if (this->enabled) { - nbc_compute_fifo_length(this, fifo, buf, FIFO_PUT); - - if (this->buffering) { - - has_video = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO); - has_audio = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO); - /* restart playing if high_water_mark is reached by all fifos - * do not restart if has_video and has_audio are false to avoid - * a yoyo effect at the beginning of the stream when these values - * are not yet known. - * - * be sure that the next buffer_pool_alloc() call will not deadlock, - * we need at least 2 buffers (see buffer.c) - */ - if ((((!has_video) || (this->video_fifo_length > this->high_water_mark)) && - ((!has_audio) || (this->audio_fifo_length > this->high_water_mark)) && - (has_video || has_audio))) { + if (this->dvbspeed) + dvbspeed_put (this, fifo, buf); + else { + nbc_compute_fifo_length(this, fifo, buf, FIFO_PUT); + + if (this->buffering) { + + has_video = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO); + has_audio = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO); + /* restart playing if high_water_mark is reached by all fifos + * do not restart if has_video and has_audio are false to avoid + * a yoyo effect at the beginning of the stream when these values + * are not yet known. + * + * be sure that the next buffer_pool_alloc() call will not deadlock, + * we need at least 2 buffers (see buffer.c) + */ + if ((((!has_video) || (this->video_fifo_length > this->high_water_mark)) && + ((!has_audio) || (this->audio_fifo_length > this->high_water_mark)) && + (has_video || has_audio))) { - this->progress = 100; - report_progress (this->stream, 100); - this->buffering = 0; + this->progress = 100; + report_progress (this->stream, 100); + this->buffering = 0; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: nbc_put_cb: stops buffering\n"); + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: nbc_put_cb: stops buffering\n"); - nbc_set_speed_normal(this); + nbc_set_speed_normal(this); - this->high_water_mark += this->high_water_mark / 2; + this->high_water_mark += this->high_water_mark / 2; - } else { - /* compute the buffering progress - * 50%: video - * 50%: audio */ - video_p = ((this->video_fifo_length * 50) / this->high_water_mark); - if (video_p > 50) video_p = 50; - audio_p = ((this->audio_fifo_length * 50) / this->high_water_mark); - if (audio_p > 50) audio_p = 50; - - if ((has_video) && (has_audio)) { - progress = video_p + audio_p; - } else if (has_video) { - progress = 2 * video_p; } else { - progress = 2 * audio_p; - } - - /* if the progress can't be computed using the fifo length, - use the number of buffers */ - if (!progress) { - video_p = this->video_fifo_fill; - audio_p = this->audio_fifo_fill; - progress = (video_p > audio_p) ? video_p : audio_p; - } - - if (progress > this->progress) { - report_progress (this->stream, progress); - this->progress = progress; + /* compute the buffering progress + * 50%: video + * 50%: audio */ + video_p = ((this->video_fifo_length * 50) / this->high_water_mark); + if (video_p > 50) video_p = 50; + audio_p = ((this->audio_fifo_length * 50) / this->high_water_mark); + if (audio_p > 50) audio_p = 50; + + if ((has_video) && (has_audio)) { + progress = video_p + audio_p; + } else if (has_video) { + progress = 2 * video_p; + } else { + progress = 2 * audio_p; + } + + /* if the progress can't be computed using the fifo length, + use the number of buffers */ + if (!progress) { + video_p = this->video_fifo_fill; + audio_p = this->audio_fifo_fill; + progress = (video_p > audio_p) ? video_p : audio_p; + } + + if (progress > this->progress) { + report_progress (this->stream, progress); + this->progress = progress; + } } } - } - if(this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) - display_stats(this); + if(this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + display_stats(this); - report_stats(this, 0); + report_stats(this, 0); + } } } else { @@ -388,7 +590,8 @@ static void nbc_put_cb (fifo_buffer_t *fifo, this->audio_last_pts = 0; this->video_fifo_length = 0; this->audio_fifo_length = 0; - nbc_set_speed_pause(this); + dvbspeed_init (this); + if (!this->dvbspeed) nbc_set_speed_pause(this); this->progress = 0; report_progress (this->stream, progress); } @@ -402,6 +605,7 @@ static void nbc_put_cb (fifo_buffer_t *fifo, case BUF_CONTROL_END: case BUF_CONTROL_QUIT: lprintf("BUF_CONTROL_END\n"); + dvbspeed_close (this); if (this->enabled) { /* end of stream : * - disable the nbc @@ -462,36 +666,40 @@ static void nbc_get_cb (fifo_buffer_t *fifo, if (this->enabled) { - nbc_compute_fifo_length(this, fifo, buf, FIFO_GET); - - if (!this->buffering) { - /* start buffering if one fifo is empty - */ - int has_video = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO); - int has_audio = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO); - if (((this->video_fifo_length == 0) && has_video) || - ((this->audio_fifo_length == 0) && has_audio)) { - /* do not pause if a fifo is full to avoid yoyo (play-pause-play-pause) */ - if ((this->video_fifo_free > FULL_FIFO_MARK) && - (this->audio_fifo_free > FULL_FIFO_MARK)) { - this->buffering = 1; - this->progress = 0; - report_progress (this->stream, 0); - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "\nnet_buf_ctrl: nbc_get_cb: starts buffering, vid: %d, aud: %d\n", - this->video_fifo_fill, this->audio_fifo_fill); - nbc_set_speed_pause(this); + if (this->dvbspeed) + dvbspeed_get (this, fifo, buf); + else { + nbc_compute_fifo_length(this, fifo, buf, FIFO_GET); + + if (!this->buffering) { + /* start buffering if one fifo is empty + */ + int has_video = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO); + int has_audio = _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO); + if (((this->video_fifo_length == 0) && has_video) || + ((this->audio_fifo_length == 0) && has_audio)) { + /* do not pause if a fifo is full to avoid yoyo (play-pause-play-pause) */ + if ((this->video_fifo_free > FULL_FIFO_MARK) && + (this->audio_fifo_free > FULL_FIFO_MARK)) { + this->buffering = 1; + this->progress = 0; + report_progress (this->stream, 0); + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "\nnet_buf_ctrl: nbc_get_cb: starts buffering, vid: %d, aud: %d\n", + this->video_fifo_fill, this->audio_fifo_fill); + nbc_set_speed_pause(this); + } } + } else { + nbc_set_speed_pause(this); } - } else { - nbc_set_speed_pause(this); - } - if(this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) - display_stats(this); + if(this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) + display_stats(this); - report_stats(this, 1); + report_stats(this, 1); + } } } else { /* discontinuity management */ -- cgit v1.2.3 From daddbbb2125ba5ae6dd80ff0d0adcd147fce0eb5 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 5 Sep 2011 01:28:28 +0100 Subject: No longer require libarts. --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 0ef30fcdb..5996c619c 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,7 @@ Build-Depends: debhelper (>= 5.0.1), binutils (>= 2.12.90.0.9), pkg-config, libasound2-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], libcam-dev [kfreebsd-i386 kfreebsd-amd64], libaa1-dev, libcaca-dev, libmodplug-dev, - libjack-jackd2-dev | libjack0.100.0-dev, libpulse-dev, libartsc0-dev, + libjack-jackd2-dev | libjack0.100.0-dev, libpulse-dev, graphicsmagick-libmagick-dev-compat | libmagick9-dev | libmagick-dev | libmagickwand-dev, libpng12-dev, libfreetype6-dev, libogg-dev, libvorbis-dev, libtheora-dev, -- cgit v1.2.3 From ebfebb80c45a283ebaeb09a1ac136810307c5e34 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:07:08 +0100 Subject: Tidy up flags usage. --- src/combined/ffmpeg/ff_video_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index 92fee481f..df57fd5f2 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -1274,7 +1274,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { if (!this->decoder_ok) { if (this->decoder_init_mode) { - int codec_type = buf->type & 0xFFFF0000; + int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); if (!ff_check_extradata(this, codec_type, buf)) return; -- cgit v1.2.3 From 965ea6e948e8648433c507b11f2fa36d20758ee1 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:10:54 +0100 Subject: Optimise flags usage. --- src/combined/ffmpeg/ff_audio_decoder.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 14a908d2f..5ff0ce70e 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -128,10 +128,9 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) int out; audio_buffer_t *audio_buffer; int bytes_to_send; - unsigned int codec_type = buf->type & 0xFFFF0000; + unsigned int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_SPECIAL) ) { + if ( (buf->decoder_flags & (BUF_FLAG_HEADER | BUF_FLAG_SPECIAL)) == BUF_FLAG_HEADER ) { /* accumulate init data */ ff_audio_ensure_buffer_size(this, this->size + buf->size); -- cgit v1.2.3 From 72d45226cc4b327d61c620cf3c5c8c22e23c9e1f Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:11:41 +0100 Subject: Use xine's fast memcpy function instead of standard library one. --- src/combined/ffmpeg/ff_audio_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 5ff0ce70e..68380c124 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -134,7 +134,7 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) /* accumulate init data */ ff_audio_ensure_buffer_size(this, this->size + buf->size); - memcpy(this->buf + this->size, buf->content, buf->size); + xine_fast_memcpy(this->buf + this->size, buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { -- cgit v1.2.3 From 7f5d3fdfb80831aad2949e8975f70d35b4c0752e Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:13:57 +0100 Subject: Pad end of audio data buffer with zeros, as instructed by the API documentation. --- src/combined/ffmpeg/ff_audio_decoder.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 68380c124..321d0e8f4 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -115,7 +115,7 @@ static void *realloc16 (void *m, size_t s) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); - this->buf = realloc16 (this->buf, this->bufsize); + this->buf = realloc16 (this->buf, this->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); } } @@ -355,6 +355,10 @@ static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ offset = 0; + + /* pad input data */ + memset(&this->buf[this->size], 0, FF_INPUT_BUFFER_PADDING_SIZE); + while (this->size>0) { decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; #if AVAUDIO > 2 -- cgit v1.2.3 From de65e355ef7f33091ae14854120574b5509941db Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:21:52 +0100 Subject: Not every audio packet can be used to determine the sample rate and number of audio channels. So we must keep discarding packets that cannot be used to initialise the codec until we receive one that can be. --- src/combined/ffmpeg/ff_audio_decoder.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/combined/ffmpeg/ff_audio_decoder.c b/src/combined/ffmpeg/ff_audio_decoder.c index 321d0e8f4..7fd5af865 100644 --- a/src/combined/ffmpeg/ff_audio_decoder.c +++ b/src/combined/ffmpeg/ff_audio_decoder.c @@ -321,27 +321,36 @@ 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) { + int ret; + decode_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; #if AVAUDIO > 2 av_init_packet (&avpkt); avpkt.data = (uint8_t *)&this->buf[0]; avpkt.size = this->size; avpkt.flags = AV_PKT_FLAG_KEY; - avcodec_decode_audio3 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, &avpkt); + ret = avcodec_decode_audio3 (this->context, + (int16_t *)this->decode_buffer, + &decode_buffer_size, &avpkt); #else - avcodec_decode_audio2 (this->context, - (int16_t *)this->decode_buffer, - &decode_buffer_size, - &this->buf[0], - this->size); + ret = avcodec_decode_audio2 (this->context, + (int16_t *)this->decode_buffer, + &decode_buffer_size, + &this->buf[0], + this->size); #endif this->audio_bits = this->context->bits_per_sample; this->audio_sample_rate = this->context->sample_rate; this->audio_channels = this->context->channels; - if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) + if (!this->audio_bits || !this->audio_sample_rate || !this->audio_channels) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("ffmpeg_audio_dec: cannot read codec parameters from packet (error=%d)\n"), ret); + + /* We can't use this packet, so we must discard it + * and wait for another one. */ + this->size = 0; return; + } } this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, this->audio_bits, this->audio_sample_rate, -- cgit v1.2.3 From d64df7d5b79b965ffd546d8e45553e1cb9efe2b3 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:26:02 +0100 Subject: Ensure that the stream reference inside each event queue is counted, and that each stream object is removed from its parent xine object's list before it starts destroying itself. --- src/xine-engine/events.c | 4 ++++ src/xine-engine/xine.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index 04a599c50..a5680476f 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -111,6 +111,8 @@ xine_event_queue_t *xine_event_new_queue (xine_stream_t *stream) { xine_event_queue_t *queue; + _x_refcounter_inc(stream->refcounter); + queue = malloc (sizeof (xine_event_queue_t)); pthread_mutex_init (&queue->lock, NULL); @@ -186,6 +188,8 @@ void xine_event_dispose_queue (xine_event_queue_t *queue) { free (queue->listener_thread); } + _x_refcounter_dec(stream->refcounter); + /* * clean up pending events */ diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index fad1785b4..78d144b1f 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -1474,6 +1474,14 @@ static void xine_dispose_internal (xine_stream_t *stream) { xine_list_iterator_t *ite; lprintf("stream: %p\n", stream); + + pthread_mutex_lock(&stream->xine->streams_lock); + ite = xine_list_find(stream->xine->streams, stream); + if (ite) { + xine_list_remove(stream->xine->streams, ite); + } + pthread_mutex_unlock(&stream->xine->streams_lock); + pthread_mutex_destroy (&stream->info_mutex); pthread_mutex_destroy (&stream->meta_mutex); pthread_mutex_destroy (&stream->frontend_lock); @@ -1491,13 +1499,6 @@ static void xine_dispose_internal (xine_stream_t *stream) { xine_list_delete(stream->event_queues); - pthread_mutex_lock(&stream->xine->streams_lock); - ite = xine_list_find(stream->xine->streams, stream); - if (ite) { - xine_list_remove(stream->xine->streams, ite); - } - pthread_mutex_unlock(&stream->xine->streams_lock); - _x_refcounter_dispose(stream->refcounter); free (stream->current_extra_info); @@ -1535,6 +1536,7 @@ void xine_dispose (xine_stream_t *stream) { if (stream->osd_renderer) stream->osd_renderer->close( stream->osd_renderer ); + /* Remove the reference that the stream was created with. */ _x_refcounter_dec(stream->refcounter); } -- cgit v1.2.3 From c64cc8e73de41316ca83a3135b6e9df34b89da71 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 10 Sep 2011 21:57:45 +0100 Subject: Remove the attempt to auto-detect audio/video streams from the MPEG-TS. The only way to identify which codec a stream is using is to wait for a PMT, at which time we know all the PIDs anyway. The codec ID is in no way related to (0x100 + stream ID), which is what this code was trying to do. Such a codec ID just hits the default path of "Unknown, using MPEG instead". --- src/demuxers/demux_ts.c | 82 +++++-------------------------------------------- 1 file changed, 7 insertions(+), 75 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 1f0640147..ed360ab38 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -274,7 +274,6 @@ typedef struct { int64_t packet_count; int corrupted_pes; uint32_t buffered_bytes; - int autodetected; } demux_ts_media; @@ -1018,16 +1017,9 @@ 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 && 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, - "demux_ts: PID 0x%.4x: corrupted pes encountered\n", m->pid); - } + m->corrupted_pes++; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_ts: PID 0x%.4x: corrupted pes encountered\n", m->pid); } else { m->corrupted_pes = 0; @@ -1987,69 +1979,10 @@ static void demux_ts_parse_packet (demux_ts_t*this) { program_count++; } - if (payload_unit_start_indicator && this->media_num < MAX_PIDS){ - int pes_stream_id; - if (pid == 0) { - demux_ts_parse_pat (this, originalPkt, originalPkt+data_offset-4, - payload_unit_start_indicator); - return; - } - program_count = 0; - pes_stream_id = originalPkt[data_offset+3]; - -#ifdef TS_HEADER_LOG - printf("demux_ts:ts_pes_header:stream_id=0x%.2x\n",pes_stream_id); -#endif - - if ( (pes_stream_id >= VIDEO_STREAM_S) && (pes_stream_id <= VIDEO_STREAM_E) ) { - if ( this->videoPid == INVALID_PID) { - int i, found = 0; - for(i = 0; i < this->media_num; i++) { - if (this->media[i].pid == pid) { - found = 1; - break; - } - } - - if (found && (this->media[i].corrupted_pes == 0)) { - this->videoPid = pid; - this->videoMedia = i; - } 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); - } - - if (this->videoPid != INVALID_PID) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_ts: auto-detected video pid 0x%.4x\n", pid); - } - } - } else if ( (pes_stream_id >= AUDIO_STREAM_S) && (pes_stream_id <= AUDIO_STREAM_E) ) { - if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { - int i, found = 0; - for(i = 0; i < this->audio_tracks_count; i++) { - if(this->audio_tracks[i].pid == pid) { - found = 1; - break; - } - } - if(!found) { -#ifdef TS_PMT_LOG - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_ts: auto-detected audio pid 0x%.4x\n", pid); -#endif - /* store PID, index and stream no. */ - this->audio_tracks[this->audio_tracks_count].pid = pid; - this->audio_tracks[this->audio_tracks_count].media_index = this->media_num; - this->media[this->media_num].type = this->audio_tracks_count; - demux_ts_pes_new(this, this->media_num++, pid, - this->audio_fifo, 0x100 + pes_stream_id); - this->audio_tracks_count++; - } - } - } + if (payload_unit_start_indicator && (this->media_num < MAX_PIDS) && (pid == 0)) { + demux_ts_parse_pat(this, originalPkt, originalPkt+data_offset-4, + payload_unit_start_indicator); + return; } if (data_len > PKT_SIZE) { @@ -2448,7 +2381,6 @@ 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++) { -- cgit v1.2.3 From 7a51ac9f855d90160076ea8aac125fcb41b605c6 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 12 Sep 2011 20:11:06 +0100 Subject: Count preview frames separately for all audio and video streams. Otherwise we risk not marking the first audio frame in each stream with BUF_FLAG_HEADER. This is the final fix for https://bugs.xine-project.org/show_bug.cgi?id=403 --- src/demuxers/demux_ts.c | 63 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index ed360ab38..3c758437d 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -270,6 +270,7 @@ typedef struct { int64_t pts; buf_element_t *buf; unsigned int counter; + unsigned int numPreview; uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */ int64_t packet_count; int corrupted_pes; @@ -369,8 +370,6 @@ typedef struct { uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */ - int numPreview; - } demux_ts_t; typedef struct { @@ -944,6 +943,14 @@ static int demux_ts_parse_pes_header (xine_t *xine, demux_ts_media *m, } +/* + * Track how many of these types of packets we have seen in this stream. + */ +static inline unsigned get_preview_frame_number(unsigned *numPreview, unsigned limit) { + unsigned preview = *numPreview; + return (preview < limit) ? ++(*numPreview) : preview; +} + /* * buffer arriving pes data */ @@ -974,26 +981,47 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, m->counter++; if (pus) { /* new PES packet */ - if (m->buffered_bytes) { + unsigned previewLimit = 0; + m->buf->content = m->buf->mem; m->buf->size = m->buffered_bytes; m->buf->type = m->type; - if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) { - m->buf->decoder_flags |= BUF_FLAG_SPECIAL; - m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; - m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; + + switch (m->type & BUF_MAJOR_MASK) { + case BUF_SPU_BASE: + if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) { + m->buf->decoder_flags |= BUF_FLAG_SPECIAL; + m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; + m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; + } + break; + + case BUF_VIDEO_BASE: + previewLimit = 5; + break; + + case BUF_AUDIO_BASE: + previewLimit = 2; + break; + + default: + break; } - else { - if (this->numPreview<5) - ++this->numPreview; - if ( this->numPreview==1 ) - m->buf->decoder_flags=BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; - else if ( this->numPreview<5 ) - m->buf->decoder_flags=BUF_FLAG_PREVIEW; - else - m->buf->decoder_flags |= BUF_FLAG_FRAME_END; + + if (previewLimit != 0) { + unsigned numPreview; + + numPreview = get_preview_frame_number(&m->numPreview, previewLimit); + + if (numPreview == 1) + m->buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; + else if (numPreview < previewLimit) + m->buf->decoder_flags = BUF_FLAG_PREVIEW; + else + m->buf->decoder_flags |= BUF_FLAG_FRAME_END; } + m->buf->pts = m->pts; m->buf->decoder_info[0] = 1; @@ -1074,6 +1102,7 @@ static void demux_ts_pes_new(demux_ts_t*this, if (m->buf != NULL) m->buf->free_buffer(m->buf); m->buf = NULL; m->counter = INVALID_CC; + m->numPreview = 0; m->descriptor_tag = descriptor; m->corrupted_pes = 1; m->buffered_bytes = 0; @@ -2414,8 +2443,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->pkt_offset = (hdmv > 0) ? 4 : 0; this->pkt_size = PKT_SIZE + this->pkt_offset; - this->numPreview=0; - return &this->demux_plugin; } -- cgit v1.2.3 From dc76c437f16a4de6e1eb269749a5502cf5be6629 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sun, 11 Sep 2011 20:24:21 +0100 Subject: demux_ts_buffer_pes() is called for video, audio and DVBSUB packets only. So why does it try to handle SPU_DVD packets? DVB subtitles don't seem to work yet anyway. --- src/demuxers/demux_ts.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 3c758437d..1a8ae8f57 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -990,10 +990,8 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, switch (m->type & BUF_MAJOR_MASK) { case BUF_SPU_BASE: - if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) { - m->buf->decoder_flags |= BUF_FLAG_SPECIAL; - m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; - m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; + if( (m->buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB ) { + /* TODO: DVBSUB handling needed? */ } break; -- cgit v1.2.3 From 51b8690e53ba175c585634df6ce6df9fdda65343 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sun, 11 Sep 2011 22:40:18 +0100 Subject: Update parsing of program numbers from PATs. The order of programs is assumed not to change among otherwise identical PATs. (Not an unreasonable assumption). --- src/demuxers/demux_ts.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 1a8ae8f57..797b58e07 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -646,7 +646,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, */ program_count = 0; for (program = pkt + 13; - program < pkt + 13 + section_length - 9; + (program < pkt + 13 + section_length - 9) && (program_count < MAX_PMTS); program += 4) { program_number = ((unsigned int)program[0] << 8) | program[1]; pmt_pid = (((unsigned int)program[2] & 0x1f) << 8) | program[3]; @@ -658,18 +658,14 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, continue; /* - * If we have yet to learn our program number, then learn it, - * use this loop to eventually add support for dynamically changing - * PATs. + * Add the program number to the table if we haven't already + * seen it. The order of the program numbers is assumed not + * to change between otherwise identical PATs. */ - program_count = 0; - - while ((this->program_number[program_count] != INVALID_PROGRAM) && - (this->program_number[program_count] != program_number) && - (program_count+1 < MAX_PMTS ) ) { - program_count++; + if (this->program_number[program_count] != program_number) { + this->program_number[program_count] = program_number; + this->pmt_pid[program_count] = INVALID_PID; } - this->program_number[program_count] = program_number; /* force PMT reparsing when pmt_pid changes */ if (this->pmt_pid[program_count] != pmt_pid) { @@ -693,6 +689,14 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt, this->program_number[program_count], this->pmt_pid[program_count]); #endif + + ++program_count; + } + + /* Add "end of table" markers. */ + if (program_count < MAX_PMTS) { + this->program_number[program_count] = INVALID_PROGRAM; + this->pmt_pid[program_count] = INVALID_PID; } } -- cgit v1.2.3 From 5c65559286bd49e9d329b08737ace4626be2a275 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 12 Sep 2011 12:43:25 +0300 Subject: Require automake 1.9. libtool 2.4 does not work with automake-1.8: Running aclocal: aclocal: macro `_LT_DECL_SED' required but not defined aclocal: macro `_LT_FUNC_STRIPNAME_CNF' required but not defined --- autogen.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autogen.sh b/autogen.sh index 0ec876910..9265c9af7 100755 --- a/autogen.sh +++ b/autogen.sh @@ -25,9 +25,9 @@ PROG=xine-lib # Minimum value required to build -WANT_AUTOMAKE_1_8=1 export WANT_AUTOMAKE_1_8 -WANT_AUTOMAKE=1.8 export WANT_AUTOMAKE -AUTOMAKE_MIN=1.8.0 +WANT_AUTOMAKE_1_9=1 export WANT_AUTOMAKE_1_9 +WANT_AUTOMAKE=1.9 export WANT_AUTOMAKE +AUTOMAKE_MIN=1.9.0 AUTOCONF_MIN=2.59 LIBTOOL_MIN=1.4.0 -- cgit v1.2.3 From 11b8b9c11c4c5a662482bd7e7e9ac08f02d9ced5 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 12 Sep 2011 13:53:41 +0300 Subject: Use AC_LANG_SOURCE --- configure.ac | 16 ++++++++-------- m4/attributes.m4 | 10 +++++----- m4/directx.m4 | 4 ++-- m4/dl.m4 | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 8367a68af..35bdd954b 100644 --- a/configure.ac +++ b/configure.ac @@ -1859,7 +1859,7 @@ if test "x$enable_vcd" = "xyes"; then AC_MSG_CHECKING([bitfield ordering in structs]) dnl basic compile test for all platforms - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ int main() { struct { char bit_0:1, bit_12:2, bit_345:3, bit_67:2; } #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) @@ -1869,11 +1869,11 @@ int main() { switch (0) case 0: case sizeof(bf) == 1:; return 0; } -], [], AC_MSG_ERROR([compiler doesn't support bitfield structs])) +])], [], AC_MSG_ERROR([compiler doesn't support bitfield structs])) dnl run test - AC_RUN_IFELSE([ + AC_RUN_IFELSE([AC_LANG_SOURCE([ int main() { struct { char bit_0:1, bit_12:2, bit_345:3, bit_67:2; } #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) @@ -1882,8 +1882,8 @@ int main() { bf = { 1,1,1,1 }; if (sizeof (bf) != 1) return 1; return *((unsigned char*) &bf) != 0x4b; } -], bf_lsbf=1, [ - AC_RUN_IFELSE([ +])], bf_lsbf=1, [ + AC_RUN_IFELSE([AC_LANG_SOURCE([ int main() { struct { char bit_0:1, bit_12:2, bit_345:3, bit_67:2; } #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) @@ -1892,7 +1892,7 @@ int main() { bf = { 1,1,1,1 }; if (sizeof (bf) != 1) return 1; return *((unsigned char*) &bf) != 0xa5; } -], bf_lsbf=0, AC_MSG_ERROR([unsupported bitfield ordering])) +])], bf_lsbf=0, AC_MSG_ERROR([unsupported bitfield ordering])) ], [case "$host" in *-*-mingw32* | *-*-cygwin*) @@ -2248,10 +2248,10 @@ AC_CHECK_HEADERS(assert.h byteswap.h malloc.h execinfo.h ucontext.h sys/mman.h s AC_REPLACE_FUNCS(asprintf basename gettimeofday setenv strcasestr strndup strpbrk strsep strtok_r timegm unsetenv memmem) AC_LIBSOURCE(hstrerror.c) -AC_LINK_IFELSE([#include +AC_LINK_IFELSE([AC_LANG_SOURCE([#include int main(void) { hstrerror(0); -}], ac_cv_function_system_hstrerror="yes") +}])], ac_cv_function_system_hstrerror="yes") AC_CHECK_LIB([resolv], [hstrerror], [ ac_cv_function_system_hstrerror="yes" NET_LIBS="-lresolv $NET_LIBS" diff --git a/m4/attributes.m4 b/m4/attributes.m4 index 4f0442865..3d9c256a0 100644 --- a/m4/attributes.m4 +++ b/m4/attributes.m4 @@ -39,7 +39,7 @@ AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" - AC_COMPILE_IFELSE([int a;], + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) CFLAGS="$ac_save_CFLAGS" @@ -89,7 +89,7 @@ AC_DEFUN([CC_CHECK_LDFLAGS], [ AS_TR_SH([cc_cv_ldflags_$1]), [ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $1" - AC_LINK_IFELSE([int main() { return 1; }], + AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) LDFLAGS="$ac_save_LDFLAGS" @@ -154,7 +154,7 @@ AC_DEFUN([CC_CHECK_ATTRIBUTE], [ AS_TR_SH([cc_cv_attribute_$1]), [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" - AC_COMPILE_IFELSE([$3], + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) CFLAGS="$ac_save_CFLAGS" @@ -302,11 +302,11 @@ AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" for cc_attribute_align_try in 64 32 16 8 4 2; do - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ int main() { static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; return c; - }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) done CFLAGS="$ac_save_CFLAGS" ]) diff --git a/m4/directx.m4 b/m4/directx.m4 index 743403c72..d64c13fc4 100644 --- a/m4/directx.m4 +++ b/m4/directx.m4 @@ -28,7 +28,7 @@ ac_save_CPPFLAGS="$CPPFLAGS" ac_save_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $DIRECTX_CPPFLAGS" LIBS="$LIBS $DIRECTX_VIDEO_LIBS $DIRECTX_AUDIO_LIBS" -AC_COMPILE_IFELSE( +AC_COMPILE_IFELSE([AC_LANG_SOURCE( [ #include @@ -42,7 +42,7 @@ int main() { return 0; } - ], + ])], [have_directx=yes AC_DEFINE(HAVE_DIRECTX,1,[Define this if you have DirectX])],,) CPPFLAGS=$ac_save_CPPFLAGS diff --git a/m4/dl.m4 b/m4/dl.m4 index 0b6b72311..87d16c17f 100644 --- a/m4/dl.m4 +++ b/m4/dl.m4 @@ -23,7 +23,7 @@ AC_DEFUN([AM_DL], [ ac_save_LIBS="$LIBS" CPPFLAGS="-I${srcdir}/win32/include $CPPFLAGS" LIBS="$LIBS -lkernel32" - AC_COMPILE_IFELSE([ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #include @@ -31,7 +31,7 @@ int main() { dlopen(NULL, 0); return 0; } -], +])], [DYNAMIC_LD_LIBS=-lkernel32 have_dl=yes AC_MSG_RESULT(yes)], -- cgit v1.2.3 From bccc0e0c620bea3e1a6ed502c7d53799ac35c180 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 16 Sep 2011 10:57:05 +0300 Subject: Splitted ff_init_mpeg12_mode() from ff_handle_preview_buffer() --- src/combined/ffmpeg/ff_video_decoder.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index df57fd5f2..eff673822 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -905,6 +905,16 @@ static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, return 1; } +static void ff_init_mpeg12_mode(ff_video_decoder_t *this) +{ + this->is_mpeg12 = 1; + if ( this->mpeg_parser == NULL ) { + this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); + mpeg_parser_init(this->mpeg_parser); + this->decoder_init_mode = 0; + } +} + static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type; @@ -912,12 +922,7 @@ static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *b codec_type = buf->type & 0xFFFF0000; if (codec_type == BUF_VIDEO_MPEG) { - this->is_mpeg12 = 1; - if ( this->mpeg_parser == NULL ) { - this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); - mpeg_parser_init(this->mpeg_parser); - this->decoder_init_mode = 0; - } + ff_init_mpeg12_mode(this); } if (this->decoder_init_mode && !this->is_mpeg12) { -- cgit v1.2.3 From 752c9d69932238731394c2b86c458b3213d85b97 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Fri, 16 Sep 2011 10:59:02 +0300 Subject: ffmpeg video: do not require preview buffers for mpeg1/2 --- src/combined/ffmpeg/ff_video_decoder.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index eff673822..f9822723c 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -1095,6 +1095,11 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu lprintf("handle_mpeg12_buffer\n"); + if (!this->is_mpeg12) { + /* initialize mpeg parser */ + ff_init_mpeg12_mode(this); + } + while ((size > 0) || (flush == 1)) { uint8_t *current; @@ -1617,7 +1622,7 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { if (buf->pts) this->pts = buf->pts; - if (this->is_mpeg12) { + if ((buf->type & 0xFFFF0000) == BUF_VIDEO_MPEG) { ff_handle_mpeg12_buffer(this, buf); } else { ff_handle_buffer(this, buf); -- cgit v1.2.3