summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-01-16 22:25:53 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-01-16 22:25:53 +0000
commit55f9a4782bea7a85936b9b2ef3a5a3ddb6fbcde2 (patch)
treef9fe91793d7f31660e6a10d87e3c139c518777e1 /src
parent68382d7610afa761e03aa64f0dfb5027f227be6c (diff)
downloadxine-lib-55f9a4782bea7a85936b9b2ef3a5a3ddb6fbcde2.tar.gz
xine-lib-55f9a4782bea7a85936b9b2ef3a5a3ddb6fbcde2.tar.bz2
- fix PVA buffer leaking problems
- add generic mpeg-like wrap detection code to TS and PVA demuxers - now scr/pcr based wrap detection is used nowhere in xine, it's simply not reliable and caused too many problems (including recent freezing in demux_ts) CVS patchset: 3938 CVS date: 2003/01/16 22:25:53
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_mpeg.c29
-rw-r--r--src/demuxers/demux_pva.c61
-rw-r--r--src/demuxers/demux_ts.c70
3 files changed, 79 insertions, 81 deletions
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index a226a9bae..dea0f3eca 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_mpeg.c,v 1.104 2003/01/10 21:11:00 miguelfreitas Exp $
+ * $Id: demux_mpeg.c,v 1.105 2003/01/16 22:25:53 miguelfreitas Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -638,33 +638,6 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
buf = read_bytes (this, 3) ;
}
- /* discontinuity ? */
-#if 0
- /* scr-wrap detection disabled due bad streams */
- if( scr && !this->preview_mode )
- {
- int64_t scr_diff = scr - this->last_scr;
-
- if (abs(scr_diff) > 60000 && !this->send_newpts) {
-
- buf_element_t *buf;
-
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->video_fifo->put (this->video_fifo, buf);
-
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
- }
- this->last_scr = scr;
- }
-#endif
-
/* system header */
buf = read_bytes (this, 4) ;
diff --git a/src/demuxers/demux_pva.c b/src/demuxers/demux_pva.c
index ae324eeee..5d558b060 100644
--- a/src/demuxers/demux_pva.c
+++ b/src/demuxers/demux_pva.c
@@ -21,7 +21,7 @@
* For more information regarding the PVA file format, refer to this PDF:
* http://www.technotrend.de/download/av_format_v1.pdf
*
- * $Id: demux_pva.c,v 1.3 2003/01/10 11:57:17 miguelfreitas Exp $
+ * $Id: demux_pva.c,v 1.4 2003/01/16 22:25:54 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -43,6 +43,11 @@
#define PVA_PREAMBLE_SIZE 8
+#define WRAP_THRESHOLD 120000
+
+#define PTS_AUDIO 0
+#define PTS_VIDEO 1
+
typedef struct {
demux_plugin_t demux_plugin;
@@ -60,6 +65,10 @@ typedef struct {
int thread_running;
pthread_mutex_t mutex;
int send_end_buffers;
+
+ int send_newpts;
+ int buf_flag_seek;
+ int64_t last_pts[2];
off_t data_start;
off_t data_size;
@@ -80,6 +89,35 @@ typedef struct {
} demux_pva_class_t;
+/* redefine abs as macro to handle 64-bit diffs.
+ i guess llabs may not be available everywhere */
+#define abs(x) ( ((x)<0) ? -(x) : (x) )
+
+static void check_newpts( demux_pva_t *this, int64_t pts, int video )
+{
+ int64_t diff;
+
+ diff = pts - this->last_pts[video];
+
+ if( pts &&
+ (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
+
+ if (this->buf_flag_seek) {
+ xine_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
+ this->buf_flag_seek = 0;
+ } else {
+ xine_demux_control_newpts(this->stream, pts, 0);
+ }
+ this->send_newpts = 0;
+ this->last_pts[1-video] = 0;
+ }
+
+ if( pts )
+ this->last_pts[video] = pts;
+}
+
+
+
/* returns 1 if the PVA file was opened successfully, 0 otherwise */
static int open_pva_file(demux_pva_t *this) {
@@ -115,10 +153,13 @@ static int demux_pva_send_chunk(demux_plugin_t *this_gen) {
unsigned char preamble[PVA_PREAMBLE_SIZE];
unsigned char pts_buf[4];
off_t current_file_pos;
+ int64_t pts;
if (this->input->read(this->input, preamble, PVA_PREAMBLE_SIZE) !=
- PVA_PREAMBLE_SIZE)
- return 0;
+ PVA_PREAMBLE_SIZE) {
+ this->status = DEMUX_FINISHED;
+ return this->status;
+ }
/* make sure the signature is there */
if ((preamble[0] != 'A') || (preamble[1] != 'V')) {
@@ -132,25 +173,26 @@ static int demux_pva_send_chunk(demux_plugin_t *this_gen) {
this->data_start;
if (preamble[2] == 1) {
-
+
/* video */
- buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
/* load the pts if it is the first thing in the chunk */
if (preamble[5] & 0x10) {
if (this->input->read(this->input, pts_buf, 4) != 4) {
- buf->free_buffer(buf);
this->status = DEMUX_FINISHED;
return this->status;
}
chunk_size -= 4;
- buf->pts = BE_32(&pts_buf[0]);
+ pts = BE_32(&pts_buf[0]);
+ check_newpts( this, pts, PTS_VIDEO );
} else
- buf->pts = 0;
+ pts = 0;
while (chunk_size) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_VIDEO_MPEG;
+ buf->pts = pts;
+ pts = 0;
buf->extra_info->input_pos = current_file_pos;
buf->extra_info->input_length = this->data_size;
buf->extra_info->input_time = buf->pts / 90;
@@ -251,8 +293,7 @@ static int demux_pva_seek (demux_plugin_t *this_gen,
/* if thread is not running, initialize demuxer */
if( !this->stream->demux_thread_running ) {
- /* send new pts */
- xine_demux_control_newpts(this->stream, 0, 0);
+ this->send_newpts = 1;
this->status = DEMUX_OK;
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index aae2d337d..a3ad4da07 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_ts.c,v 1.75 2003/01/10 21:11:10 miguelfreitas Exp $
+ * $Id: demux_ts.c,v 1.76 2003/01/16 22:25:54 miguelfreitas Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -188,6 +188,11 @@
#define ISO13522_STREAM 0xF3
#define PROG_STREAM_DIR 0xFF
+#define WRAP_THRESHOLD 120000
+
+#define PTS_AUDIO 0
+#define PTS_VIDEO 1
+
/*
**
** DATA STRUCTURES
@@ -255,8 +260,6 @@ typedef struct {
*/
unsigned int programNumber;
unsigned int pcrPid;
- int64_t PCR;
- int64_t last_PCR;
unsigned int pid;
unsigned int pid_count;
unsigned int videoPid;
@@ -266,7 +269,7 @@ typedef struct {
char audioLang[4];
int send_end_buffers;
- int ignore_scr_discont;
+ int64_t last_pts[2];
int send_newpts;
int buf_flag_seek;
@@ -321,14 +324,23 @@ static uint32_t demux_ts_compute_crc32(demux_ts_t*this, uint8_t *data,
return crc32;
}
-static void check_newpts( demux_ts_t*this, int64_t pts ) {
+/* redefine abs as macro to handle 64-bit diffs.
+ i guess llabs may not be available everywhere */
+#define abs(x) ( ((x)<0) ? -(x) : (x) )
+
+static void check_newpts( demux_ts_t *this, int64_t pts, int video )
+{
+ int64_t diff;
#ifdef TS_LOG
printf ("demux_ts: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n",
pts, this->send_newpts, this->buf_flag_seek);
#endif
-
- if (this->send_newpts && pts) {
+
+ diff = pts - this->last_pts[video];
+
+ if( pts &&
+ (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
if (this->buf_flag_seek) {
xine_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK);
@@ -337,8 +349,11 @@ static void check_newpts( demux_ts_t*this, int64_t pts ) {
xine_demux_control_newpts(this->stream, pts, 0);
}
this->send_newpts = 0;
- this->ignore_scr_discont = 1;
+ this->last_pts[1-video] = 0;
}
+
+ if( pts )
+ this->last_pts[video] = pts;
}
@@ -765,7 +780,6 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
} else {
- check_newpts(this, m->pts);
m->corrupted_pes = 0;
m->buf = m->fifo->buffer_pool_alloc(m->fifo);
memcpy(m->buf->mem, ts+len-m->size, m->size);
@@ -1455,35 +1469,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
if( adaptation_field_control & 0x2 ){
uint32_t adaptation_field_length = originalPkt[4];
if (adaptation_field_length > 0) {
- this->PCR = demux_ts_adaptation_field_parse (originalPkt+5,
- adaptation_field_length);
-
- if (pid == this->pcrPid && this->PCR) {
- int64_t scr_diff = this->PCR - this->last_PCR;
-
- /* note: comparing (abs(scr_diff) > 90000) isn't reliable
- * below because abs() give inconsistent results on int64_t
- * types */
- if ( (scr_diff > 90000 || scr_diff < -90000) && !this->send_newpts &&
- !this->ignore_scr_discont ) {
-
- buf_element_t *buf;
-
- buf = this->video_fifo->buffer_pool_alloc(this->video_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->video_fifo->put (this->video_fifo, buf);
-
- if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->audio_fifo->put (this->audio_fifo, buf);
- }
- }
- this->last_PCR = this->PCR;
- this->ignore_scr_discont = 0;
- }
+ demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length);
}
/*
* Skip adaptation header.
@@ -1516,7 +1502,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
demux_ts_pes_new(this, this->media_num++, pid, this->video_fifo, t);
}
} else if (t == PRIVATE_STREAM1 ||
- t >= AUDIO_STREAM_S && t <= AUDIO_STREAM_E) {
+ (t >= AUDIO_STREAM_S && t <= AUDIO_STREAM_E)) {
if ( this->audioPid == INVALID_PID) {
printf ("demux_ts: auto-detected audio pid %d\n",
@@ -1543,6 +1529,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
#ifdef TS_LOG
printf ("demux_ts: Video pid: %.4x\n", pid);
#endif
+ check_newpts(this, this->media[this->videoMedia].pts, PTS_VIDEO);
demux_ts_buffer_pes (this, originalPkt+data_offset, this->videoMedia,
payload_unit_start_indicator, continuity_counter,
data_len);
@@ -1552,6 +1539,7 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
#ifdef TS_LOG
printf ("demux_ts: Audio pid: %.4x\n", pid);
#endif
+ check_newpts(this, this->media[this->audioMedia].pts, PTS_AUDIO);
demux_ts_buffer_pes (this, originalPkt+data_offset, this->audioMedia,
payload_unit_start_indicator, continuity_counter,
data_len);
@@ -1693,14 +1681,12 @@ static void demux_ts_send_headers (demux_plugin_t *this_gen) {
this->input->seek (this->input, 0, SEEK_SET);
this->send_newpts = 1;
- this->ignore_scr_discont = 0;
demux_ts_build_crc32_table (this);
this->status = DEMUX_OK ;
this->send_end_buffers = 1;
- this->last_PCR = 0;
this->scrambled_npids = 0;
/* DVBSUB */
@@ -1729,7 +1715,6 @@ static int demux_ts_seek (demux_plugin_t *this_gen,
}
this->send_newpts = 1;
- this->ignore_scr_discont = 0;
for (i=0; i<MAX_PIDS; i++) {
demux_ts_media *m = &this->media[i];
@@ -1967,7 +1952,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->programNumber = INVALID_PROGRAM;
this->pcrPid = INVALID_PID;
- this->PCR = 0;
this->scrambled_npids = 0;
this->videoPid = INVALID_PID;
this->audioPid = INVALID_PID;