summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_asf.c41
-rw-r--r--src/demuxers/demux_avi.c123
-rw-r--r--src/demuxers/demux_cda.c3
-rw-r--r--src/demuxers/demux_elem.c4
-rw-r--r--src/demuxers/demux_mpeg.c61
-rw-r--r--src/demuxers/demux_mpeg_block.c34
-rw-r--r--src/demuxers/demux_mpgaudio.c4
-rw-r--r--src/demuxers/demux_ogg.c3
-rw-r--r--src/demuxers/demux_pes.c5
-rw-r--r--src/demuxers/demux_qt.c1378
-rw-r--r--src/demuxers/demux_ts.c6
-rw-r--r--src/dxr3/dxr3_decoder.c8
-rw-r--r--src/liba52/xine_decoder.c10
-rw-r--r--src/libdivx4/xine_decoder.c21
-rw-r--r--src/libdts/xine_decoder.c4
-rw-r--r--src/libffmpeg/xine_decoder.c22
-rw-r--r--src/liblpcm/xine_decoder.c11
-rw-r--r--src/libmad/xine_decoder.c24
-rw-r--r--src/libmpeg2/decode.c7
-rw-r--r--src/libmpeg2/mpeg2.h5
-rw-r--r--src/libmpeg2/xine_decoder.c6
-rw-r--r--src/libspucc/cc_decoder.c26
-rw-r--r--src/libspucc/cc_decoder.h5
-rw-r--r--src/libspucc/xine_decoder.c9
-rw-r--r--src/libspudec/xine_decoder.c8
-rw-r--r--src/libsputext/xine_decoder.c6
-rw-r--r--src/libw32dll/w32codec.c24
-rw-r--r--src/xine-engine/audio_decoder.c12
-rw-r--r--src/xine-engine/audio_out.c4
-rw-r--r--src/xine-engine/audio_out.h3
-rw-r--r--src/xine-engine/buffer.h28
-rw-r--r--src/xine-engine/buffer_types.c11
-rw-r--r--src/xine-engine/metronom.c346
-rw-r--r--src/xine-engine/metronom.h37
-rw-r--r--src/xine-engine/video_decoder.c8
-rw-r--r--src/xine-engine/xine.c4
36 files changed, 1051 insertions, 1260 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index a61102349..770aa36c7 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.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_asf.c,v 1.23 2002/02/17 17:32:49 guenter Exp $
+ * $Id: demux_asf.c,v 1.24 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for asf streams
*
@@ -345,7 +345,7 @@ static void asf_send_audio_header (demux_asf_t *this, int stream_id) {
buf->size = this->wavex_size;
buf->type = this->streams[this->num_streams].buf_type;
- buf->decoder_info[0] = 0; /* first package, containing wavex */
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[1] = wavex->nSamplesPerSec;
buf->decoder_info[2] = wavex->wBitsPerSample;
buf->decoder_info[3] = wavex->nChannels;
@@ -390,7 +390,7 @@ static void asf_send_video_header (demux_asf_t *this, int stream_id) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->content = buf->mem;
- buf->decoder_info[0] = 0; /* first package, containing bih */
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[1] = 3000; /* FIXME ? */
memcpy (buf->content, &this->bih, this->bih_size);
buf->size = this->bih_size;
@@ -591,12 +591,16 @@ static int asf_get_packet(demux_asf_t *this) {
this->packet_flags = get_byte(this);
this->segtype = get_byte(this);
this->packet_padsize = 0;
-
- if (this->packet_flags & 0x40) {
- get_le16(this);
- printf ("demux_asf: absolute size ignored\n");
- hdr_size += 2;
+
+ /* FIXME: really not necessary?
+ patch submitted by Andrei Lahun <Uman@editec-lotteries.com>
+
+ if (this->packet_flags & 0x40) {
+ get_le16(this);
+ printf ("demux_asf: absolute size ignored\n");
+ hdr_size += 2;
}
+ */
if (this->packet_flags & 0x10) {
this->packet_padsize = get_le16(this);
@@ -684,7 +688,6 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream,
buf->input_time = 0 ;
}
buf->pts = timestamp * 90;
- buf->scr = timestamp * 90;
buf->type = stream->buf_type;
buf->size = bufsize;
timestamp = 0;
@@ -694,10 +697,10 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream,
/* test if whole packet read */
if (stream->frag_offset == payload_size) {
- buf->decoder_info[0] = 2;
+ buf->decoder_flags = BUF_FLAG_FRAME_END;
stream->frag_offset = 0;
} else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
stream->fifo->put (stream->fifo, buf);
}
@@ -758,7 +761,6 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream,
buf->pts = stream->timestamp * 90 + stream->ts_per_kbyte *
(p-stream->buffer) / 1024;
- buf->scr = buf->pts;
buf->type = stream->buf_type;
buf->size = bufsize;
@@ -767,10 +769,10 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream,
/* test if whole packet read */
if ( !stream->frag_offset )
- buf->decoder_info[0] = 2;
+ buf->decoder_flags = BUF_FLAG_FRAME_END ;
else
- buf->decoder_info[0] = 1;
-
+ buf->decoder_flags = 0;
+
stream->fifo->put (stream->fifo, buf);
}
}
@@ -1009,13 +1011,13 @@ static void *demux_asf_loop (void *this_gen) {
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM; /* stream finished */
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_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM; /* stream finished */
this->audio_fifo->put (this->audio_fifo, buf);
}
@@ -1057,14 +1059,13 @@ static void demux_asf_stop (demux_plugin_t *this_gen) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 1; /* forced */
-
+ buf->decoder_flags = BUF_FLAG_END_USER;
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_END;
- buf->decoder_info[0] = 1; /* forced */
+ buf->decoder_flags = BUF_FLAG_END_USER;
this->audio_fifo->put (this->audio_fifo, buf);
}
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
index eb31c2245..3abe24e1b 100644
--- a/src/demuxers/demux_avi.c
+++ b/src/demuxers/demux_avi.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000, 2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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_avi.c,v 1.64 2002/02/17 17:32:49 guenter Exp $
+ * $Id: demux_avi.c,v 1.65 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for avi streams
*
@@ -614,64 +614,66 @@ static void AVI_seek_start(avi_t *AVI)
}
static long AVI_read_audio(demux_avi_t *this, avi_t *AVI, char *audbuf,
- long bytes, int *bFrameDone)
-{
+ long bytes, int *buf_flags) {
+
long nr, pos, left, todo;
- if(!AVI->audio_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+ if(!AVI->audio_index) {
+ this->AVI_errno = AVI_ERR_NO_IDX; return -1;
+ }
nr = 0; /* total number of bytes read */
/* printf ("avi audio package len: %d\n", AVI->audio_index[AVI->audio_posc].len); */
- while(bytes>0)
- {
+ while(bytes>0) {
+ left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
+ if(left==0) {
+ AVI->audio_posc++;
+ AVI->audio_posb = 0;
+ if (nr>0) {
+ *buf_flags = BUF_FLAG_FRAME_END;
+ return nr;
+ }
left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
- if(left==0)
- {
- AVI->audio_posc++;
- AVI->audio_posb = 0;
- if (nr>0) {
- *bFrameDone = 2;
- return nr;
- }
- left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
- }
- if(bytes<left)
- todo = bytes;
- else
- todo = left;
- pos = AVI->audio_index[AVI->audio_posc].pos + AVI->audio_posb;
- /* printf ("demux_avi: read audio from %d\n", pos); */
- if (this->input->seek (this->input, pos, SEEK_SET)<0)
- return -1;
- if (this->input->read(this->input, audbuf+nr,todo) != todo)
- {
- this->AVI_errno = AVI_ERR_READ;
- *bFrameDone = 1;
- return -1;
- }
- bytes -= todo;
- nr += todo;
- AVI->audio_posb += todo;
}
+ if(bytes<left)
+ todo = bytes;
+ else
+ todo = left;
+ pos = AVI->audio_index[AVI->audio_posc].pos + AVI->audio_posb;
+ /* printf ("demux_avi: read audio from %d\n", pos); */
+ if (this->input->seek (this->input, pos, SEEK_SET)<0)
+ return -1;
+ if (this->input->read(this->input, audbuf+nr,todo) != todo) {
+ this->AVI_errno = AVI_ERR_READ;
+ *buf_flags = 0;
+ return -1;
+ }
+ bytes -= todo;
+ nr += todo;
+ AVI->audio_posb += todo;
+ }
left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
if (left==0)
- *bFrameDone = 2;
+ *buf_flags = BUF_FLAG_FRAME_END;
else
- *bFrameDone = 1;
+ *buf_flags = 0;
return nr;
}
static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf,
- long bytes, int *frame_done) {
+ long bytes, int *buf_flags) {
long nr, pos, left, todo;
- if(!AVI->video_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+ if (!AVI->video_index) {
+ this->AVI_errno = AVI_ERR_NO_IDX;
+ return -1;
+ }
nr = 0; /* total number of bytes read */
@@ -683,7 +685,7 @@ static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf,
AVI->video_posf++;
AVI->video_posb = 0;
if (nr>0) {
- *frame_done = 2;
+ *buf_flags = BUF_FLAG_FRAME_END;
return nr;
}
left = AVI->video_index[AVI->video_posf].len - AVI->video_posb;
@@ -698,7 +700,7 @@ static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf,
return -1;
if (this->input->read(this->input, vidbuf+nr,todo) != todo) {
this->AVI_errno = AVI_ERR_READ;
- *frame_done = 1;
+ *buf_flags = 0;
return -1;
}
bytes -= todo;
@@ -708,9 +710,9 @@ static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf,
left = AVI->video_index[AVI->video_posf].len - AVI->video_posb;
if (left==0)
- *frame_done = 2;
+ *buf_flags = BUF_FLAG_FRAME_END;
else
- *frame_done = 1;
+ *buf_flags = 0;
return nr;
}
@@ -752,8 +754,7 @@ static int demux_avi_next (demux_avi_t *this) {
/* read audio */
buf->pts = audio_pts;
- buf->scr = audio_pts;
- buf->size = AVI_read_audio (this, this->avi, buf->mem, 2048, &buf->decoder_info[0]);
+ buf->size = AVI_read_audio (this, this->avi, buf->mem, 2048, &buf->decoder_flags);
if (buf->size<0) {
buf->free_buffer (buf);
@@ -764,9 +765,9 @@ static int demux_avi_next (demux_avi_t *this) {
buf->input_time = 0;
buf->type = this->avi->audio_type;
- buf->decoder_info[1] = this->avi->a_rate; /* Audio Rate */
- buf->decoder_info[2] = this->avi->a_bits; /* Audio bits */
- buf->decoder_info[3] = this->avi->a_chans; /* Audio channels */
+ buf->decoder_info[1] = this->avi->a_rate; /* audio rate */
+ buf->decoder_info[2] = this->avi->a_bits; /* audio bits */
+ buf->decoder_info[3] = this->avi->a_chans; /* audio channels */
if(this->audio_fifo) {
this->audio_fifo->put (this->audio_fifo, buf);
@@ -779,8 +780,7 @@ static int demux_avi_next (demux_avi_t *this) {
/* read video */
buf->pts = video_pts;
- buf->scr = video_pts;
- buf->size = AVI_read_video (this, this->avi, buf->mem, 2048, &buf->decoder_info[0]);
+ buf->size = AVI_read_video (this, this->avi, buf->mem, 2048, &buf->decoder_flags);
buf->type = this->avi->video_type;
buf->input_time = video_pts / 90000;
@@ -999,18 +999,32 @@ static void demux_avi_start (demux_plugin_t *this_gen,
*/
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
- buf->type = BUF_CONTROL_START;
+ buf->type = BUF_CONTROL_START;
+ buf->decoder_flags = 0;
+ 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_START;
+ buf->decoder_flags = 0;
+ this->audio_fifo->put (this->audio_fifo, buf);
+ }
+
+ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->disc_off = video_pts;
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_START;
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->disc_off = video_pts;
this->audio_fifo->put (this->audio_fifo, buf);
}
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->content = buf->mem;
- buf->decoder_info[0] = 0; /* first package, containing bih */
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[1] = this->video_step;
memcpy (buf->content, &this->avi->bih, sizeof (this->avi->bih));
buf->size = sizeof (this->avi->bih);
@@ -1032,6 +1046,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
if(this->audio_fifo) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->content = buf->mem;
+ buf->decoder_flags = BUF_FLAG_HEADER;
memcpy (buf->content, &this->avi->wavex,
sizeof (this->avi->wavex));
buf->size = sizeof (this->avi->wavex);
@@ -1054,7 +1069,7 @@ static void demux_avi_start (demux_plugin_t *this_gen,
buf->type = BUF_SPU_TEXT;
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[1] = this->avi->width;
buf->decoder_info[2] = this->avi->height;
diff --git a/src/demuxers/demux_cda.c b/src/demuxers/demux_cda.c
index 55e8b5be5..94d5098da 100644
--- a/src/demuxers/demux_cda.c
+++ b/src/demuxers/demux_cda.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_cda.c,v 1.8 2002/02/17 17:32:49 guenter Exp $
+ * $Id: demux_cda.c,v 1.9 2002/03/11 12:31:24 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -74,7 +74,6 @@ static int demux_cda_next (demux_cda_t *this) {
len = this->input->get_length(this->input);
buf->pts = 0;
- buf->scr = 0;
buf->input_pos = pos;
buf->input_time = buf->input_pos / this->blocksize;
buf->type = BUF_CONTROL_NOP; /* Fake */
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
index e48182520..5c3cf35c0 100644
--- a/src/demuxers/demux_elem.c
+++ b/src/demuxers/demux_elem.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_elem.c,v 1.34 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_elem.c,v 1.35 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for elementary mpeg streams
*
@@ -89,7 +89,7 @@ static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) {
buf->decoder_info[0] = 1;
buf->pts = 0;
- buf->scr = 0;
+ /*buf->scr = 0;*/
buf->input_pos = this->input->get_current_pos(this->input);
buf->type = BUF_VIDEO_MPEG;
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index 6a4bfd4a1..197828ef1 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000, 2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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.50 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_mpeg.c,v 1.51 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -71,9 +71,9 @@ typedef struct demux_mpeg_s {
int send_end_buffers;
- uint32_t last_scr;
+ int64_t last_scr;
-} demux_mpeg_t ;
+} demux_mpeg_t;
static uint32_t read_bytes (demux_mpeg_t *this, int n) {
@@ -113,10 +113,11 @@ static uint32_t read_bytes (demux_mpeg_t *this, int n) {
return res;
}
-static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr) {
+static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) {
int len, i;
- uint32_t w, flags, header_len, pts;
+ uint32_t w, flags, header_len;
+ int64_t pts;
buf_element_t *buf = NULL;
len = read_bytes(this, 2);
@@ -165,11 +166,11 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
buf->type = BUF_AUDIO_A52 + track;
buf->pts = pts;
- buf->scr = scr;
+ /* buf->scr = scr;*/
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos (this->input);
@@ -215,11 +216,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
buf->type = BUF_AUDIO_MPEG + track;
buf->pts = pts;
- buf->scr = scr;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos(this->input);
if(this->audio_fifo)
@@ -260,11 +260,10 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
buf->type = BUF_VIDEO_MPEG;
buf->pts = pts;
- buf->scr = scr;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos(this->input);
this->video_fifo->put (this->video_fifo, buf);
@@ -277,12 +276,12 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
-static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, uint32_t scr) {
+static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr) {
int len;
uint32_t w;
int i;
- int pts;
+ int64_t pts;
buf_element_t *buf = NULL;
len = read_bytes(this, 2);
@@ -372,11 +371,10 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
buf->type = BUF_AUDIO_MPEG + track ;
buf->pts = pts;
- buf->scr = scr;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos(this->input);
if (this->rate)
buf->input_time = buf->input_pos / (this->rate * 50);
@@ -395,11 +393,10 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, uint32_t scr)
}
buf->type = BUF_VIDEO_MPEG;
buf->pts = pts;
- buf->scr = scr;
if (this->preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos(this->input);
if (this->rate)
buf->input_time = buf->input_pos / (this->rate * 50);
@@ -420,7 +417,7 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
uint32_t buf ;
int mpeg_version;
- uint32_t scr;
+ int64_t scr;
buf = read_bytes (this, 1);
@@ -489,20 +486,20 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
/* discontinuity ? */
{
- int32_t scr_diff = scr - this->last_scr;
+ int64_t scr_diff = scr - this->last_scr;
if (abs(scr_diff) > 60000) {
buf_element_t *buf;
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->scr = scr;
+ 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->scr = scr;
+ buf->disc_off = scr_diff;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -632,13 +629,13 @@ static void *demux_mpeg_loop (void *this_gen) {
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM;
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_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -680,13 +677,13 @@ static void demux_mpeg_stop (demux_plugin_t *this_gen) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 1; /* forced */
+ buf->decoder_flags = BUF_FLAG_END_USER; /* user finished */
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_END;
- buf->decoder_info[0] = 1; /* forced */
+ buf->decoder_flags = BUF_FLAG_END_USER; /* user finished */
this->audio_fifo->put (this->audio_fifo, buf);
}
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index a3519c6aa..9bebd56ba 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.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_block.c,v 1.77 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_mpeg_block.c,v 1.78 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for mpeg 1/2 program streams
*
@@ -74,7 +74,7 @@ typedef struct demux_mpeg_block_s {
uint8_t *scratch;
- uint32_t last_scr;
+ int64_t last_scr;
} demux_mpeg_block_t ;
@@ -84,10 +84,10 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
uint8_t *p;
int bMpeg1=0;
uint32_t header_len;
- uint32_t PTS;
+ int64_t PTS;
uint32_t packet_len;
uint32_t stream_id;
- uint32_t scr = this->last_scr;
+ int64_t scr = this->last_scr;
buf = this->input->read_block (this->input, this->video_fifo, this->blocksize);
@@ -149,7 +149,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
if (this->audio_fifo) {
cbuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
cbuf->type = buf->type;
- cbuf->decoder_info[0] = buf->decoder_info[0];
+ cbuf->decoder_flags = buf->decoder_flags;
this->audio_fifo->put (this->audio_fifo, cbuf);
}
@@ -158,9 +158,9 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
p = buf->content; /* len = this->mnBlocksize; */
if (preview_mode)
- buf->decoder_info[0] = 0;
+ buf->decoder_flags = BUF_FLAG_PREVIEW;
else
- buf->decoder_info[0] = 1;
+ buf->decoder_flags = 0;
buf->input_pos = this->input->get_current_pos (this->input);
@@ -182,7 +182,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr |= (p[6] & 0xFF) << 7;
scr |= (p[7] & 0xFE) >> 1;
- buf->scr = scr;
+ /* buf->scr = scr; */
/* mux_rate */
@@ -214,7 +214,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
*/
- buf->scr = scr;
+ /* buf->scr = scr; */
/* mux_rate */
@@ -259,7 +259,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
/* discontinuity ? */
{
- int32_t scr_diff = scr - this->last_scr;
+ int64_t scr_diff = scr - this->last_scr;
#ifdef LOG
printf ("demux_mpeg_block: scr %d last_scr %d diff %d\n",
@@ -276,13 +276,13 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->scr = scr;
+ 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->scr = scr;
+ buf->disc_off = scr_diff;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
@@ -565,13 +565,13 @@ static void *demux_mpeg_block_loop (void *this_gen) {
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM;
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_END;
- buf->decoder_info[0] = 0; /* stream finished */
+ buf->decoder_flags = BUF_FLAG_END_STREAM;
this->audio_fifo->put (this->audio_fifo, buf);
}
@@ -591,7 +591,7 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) {
int is_mpeg1=0;
off_t pos, last_pos;
off_t step;
- uint32_t PTS, last_PTS;
+ int64_t PTS, last_PTS;
int rate;
int count;
int stream_id;
@@ -748,14 +748,14 @@ static void demux_mpeg_block_stop (demux_plugin_t *this_gen) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
- buf->decoder_info[0] = 1; /* forced */
+ buf->decoder_flags = BUF_FLAG_END_USER;
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_END;
- buf->decoder_info[0] = 1; /* forced */
+ buf->decoder_flags = BUF_FLAG_END_USER;
this->audio_fifo->put (this->audio_fifo, buf);
}
}
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
index f5860a87b..bd609df4d 100644
--- a/src/demuxers/demux_mpgaudio.c
+++ b/src/demuxers/demux_mpgaudio.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_mpgaudio.c,v 1.35 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_mpgaudio.c,v 1.36 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for mpeg audio (i.e. mp3) streams
*
@@ -189,7 +189,7 @@ static int demux_mpgaudio_next (demux_mpgaudio_t *this) {
}
buf->pts = 0;
- buf->scr = 0;
+ /*buf->scr = 0;*/
buf->input_pos = this->input->get_current_pos(this->input);
buf->input_time = buf->input_pos * this->stream_length /
this->input->get_length(this->input);
diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c
index 941c4512b..f5aeb8487 100644
--- a/src/demuxers/demux_ogg.c
+++ b/src/demuxers/demux_ogg.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_ogg.c,v 1.15 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_ogg.c,v 1.16 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for ogg streams
*
@@ -174,7 +174,6 @@ static void demux_ogg_send_package (demux_ogg_t *this, int is_content) {
}
buf->pts = 0; /* FIXME */
- buf->scr = 0; /* FIXME */
buf->size = op.bytes;
buf->decoder_info[0] = is_content;
diff --git a/src/demuxers/demux_pes.c b/src/demuxers/demux_pes.c
index b8dc3cd55..ef20f8b33 100644
--- a/src/demuxers/demux_pes.c
+++ b/src/demuxers/demux_pes.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_pes.c,v 1.19 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_pes.c,v 1.20 2002/03/11 12:31:24 guenter Exp $
*
* demultiplexer for mpeg 2 PES (Packetized Elementary Streams)
* reads streams of variable blocksizes
@@ -163,7 +163,6 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
}
buf->type = BUF_AUDIO_A52 + track;
buf->pts = pts;
- buf->scr = pts; /* FIMXE! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -209,7 +208,6 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
}
buf->type = BUF_AUDIO_MPEG + track;
buf->pts = pts;
- buf->scr = pts; /* FIXME ! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
@@ -255,7 +253,6 @@ static void parse_mpeg2_packet (demux_pes_t *this, int nID) {
}
buf->type = BUF_VIDEO_MPEG;
buf->pts = pts;
- buf->scr = pts; /* FIXME! */
if (this->preview_mode)
buf->decoder_info[0] = 0;
else
diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c
index a18fd831a..3e815d5c5 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -17,9 +17,9 @@
* 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_qt.c,v 1.22 2002/03/01 09:29:50 guenter Exp $
+ * $Id: demux_qt.c,v 1.23 2002/03/11 12:31:24 guenter Exp $
*
- * demultiplexer for quicktime streams, based on:
+ * demultiplexer for mpeg-4 system (aka quicktime) streams, based on:
*
* openquicktime.c
*
@@ -54,7 +54,14 @@
#include "libw32dll/wine/vfw.h"
#include "libw32dll/wine/mmreg.h"
-#define VALID_ENDS "mov"
+
+#define LOG
+
+
+#define DBG_QT
+
+
+#define VALID_ENDS "mov,mp4"
/* OpenQuicktime Codec Parameter Types */
#define QUICKTIME_UNKNOWN_PARAMETER -1
@@ -70,6 +77,10 @@
typedef int64_t longest;
typedef uint64_t ulongest;
+#ifdef DBG_QT
+int debug_fh;
+#endif
+
/*
typedef __s64 longest;
typedef __u64 ulongest;
@@ -191,6 +202,7 @@ typedef struct {
typedef struct {
long sample_count;
long sample_duration;
+ int64_t pts;
} quicktime_stts_table_t;
typedef struct {
@@ -513,6 +525,17 @@ typedef struct quicktime_struc {
} quicktime_t;
+typedef struct {
+ int64_t pts;
+ off_t offset;
+ int first_sample;
+ int last_sample;
+ int32_t type;
+ quicktime_trak_t *track;
+} qt_idx_t;
+
+#define MAX_QT_INDEX 200000
+
typedef struct demux_qt_s {
demux_plugin_t demux_plugin;
@@ -531,6 +554,8 @@ typedef struct demux_qt_s {
int send_end_buffers;
quicktime_t *qt;
+ qt_idx_t index[MAX_QT_INDEX];
+ int num_index_entries;
int has_audio; /* 1 if this qt stream has audio */
@@ -555,171 +580,163 @@ typedef struct demux_qt_s {
/* Disk I/O */
-static longest quicktime_ftell(quicktime_t *file)
-{
+static longest quicktime_ftell(quicktime_t *file) {
return file->ftell_position;
}
-static int quicktime_fseek(quicktime_t *file, longest offset)
-{
+static int quicktime_fseek(quicktime_t *file, longest offset) {
file->ftell_position = offset;
- if(offset > file->total_length || offset < 0) return 1;
- if (file->input->seek(file->input, file->ftell_position, SEEK_SET))
- {
- // perror("quicktime_read_data FSEEK");
- return 1;
- }
+ if(offset > file->total_length || offset < 0)
+ return 1;
+ if (file->input->seek(file->input, file->ftell_position, SEEK_SET)) {
+ /* perror("quicktime_read_data FSEEK"); */
+ return 1;
+ }
return 0;
}
/* Read entire buffer from the preload buffer */
-static int quicktime_read_preload(quicktime_t *file, char *data, longest size)
-{
+static int quicktime_read_preload(quicktime_t *file, char *data, longest size) {
longest selection_start = file->file_position;
longest selection_end = file->file_position + size;
longest fragment_start, fragment_len;
fragment_start = file->preload_ptr + (selection_start - file->preload_start);
- while(fragment_start < 0) fragment_start += file->preload_size;
- while(fragment_start >= file->preload_size) fragment_start -= file->preload_size;
+ while(fragment_start < 0)
+ fragment_start += file->preload_size;
+ while(fragment_start >= file->preload_size)
+ fragment_start -= file->preload_size;
// gcc 2.96 fails here
- while(selection_start < selection_end)
- {
- fragment_len = selection_end - selection_start;
- if(fragment_start + fragment_len > file->preload_size)
- fragment_len = file->preload_size - fragment_start;
-
- memcpy(data, file->preload_buffer + fragment_start, fragment_len);
- fragment_start += fragment_len;
- data = data + fragment_len;
-
- if(fragment_start >= file->preload_size) fragment_start = (longest)0;
- selection_start += fragment_len;
- }
+ while (selection_start < selection_end) {
+ fragment_len = selection_end - selection_start;
+ if (fragment_start + fragment_len > file->preload_size)
+ fragment_len = file->preload_size - fragment_start;
+
+ memcpy (data, file->preload_buffer + fragment_start, fragment_len);
+ fragment_start += fragment_len;
+ data = data + fragment_len;
+
+ if (fragment_start >= file->preload_size)
+ fragment_start = (longest)0;
+ selection_start += fragment_len;
+ }
return 0;
}
-static int quicktime_read_data(quicktime_t *file, char *data, longest size)
-{
+static int quicktime_read_data(quicktime_t *file, char *data, longest size) {
+
int result = 1;
- if(file->decompressed_buffer)
- {
- if(file->decompressed_position < file->decompressed_buffer_size)
- {
- memcpy(data,
- file->decompressed_buffer+file->decompressed_position,
- size);
- file->decompressed_position+=size;
- return result;
- }
- else
- {
- //printf("Deleting Decompressed buffer\n");
- file->decompressed_position = 0;
- file->decompressed_buffer_size=0;
- free(file->decompressed_buffer);
- file->decompressed_buffer = NULL;
- }
+
+ if (file->decompressed_buffer) {
+
+ if (file->decompressed_position < file->decompressed_buffer_size) {
+ memcpy(data,
+ file->decompressed_buffer+file->decompressed_position,
+ size);
+ file->decompressed_position+=size;
+ return result;
+
+ } else {
+
+ //printf("Deleting Decompressed buffer\n");
+ file->decompressed_position = 0;
+ file->decompressed_buffer_size=0;
+ free(file->decompressed_buffer);
+ file->decompressed_buffer = NULL;
}
+ }
- if(!file->preload_size)
- {
- //printf("quicktime_read_data 0x%llx\n", file->file_position);
+ if (!file->preload_size) {
+ //printf("quicktime_read_data 0x%llx\n", file->file_position);
+ file->quicktime_fseek(file, file->file_position);
+ /* result = fread(data, size, 1, (FILE*)file->stream); */
+ result = file->input->read(file->input, data, size);
+ file->ftell_position += size;
+
+ } else {
+
+ longest selection_start = file->file_position;
+ longest selection_end = file->file_position + size;
+ longest fragment_start, fragment_len;
+
+ if(selection_end - selection_start > file->preload_size) {
+ /* Size is larger than preload size. Should never happen. */
+ //printf("read data 1\n");
file->quicktime_fseek(file, file->file_position);
/* result = fread(data, size, 1, (FILE*)file->stream); */
result = file->input->read(file->input, data, size);
file->ftell_position += size;
- }
- else
- {
- longest selection_start = file->file_position;
- longest selection_end = file->file_position + size;
- longest fragment_start, fragment_len;
- if(selection_end - selection_start > file->preload_size)
- {
- /* Size is larger than preload size. Should never happen. */
- //printf("read data 1\n");
- file->quicktime_fseek(file, file->file_position);
- /* result = fread(data, size, 1, (FILE*)file->stream); */
- result = file->input->read(file->input, data, size);
- file->ftell_position += size;
- }
- else
- if(selection_start >= file->preload_start &&
- selection_start < file->preload_end &&
- selection_end <= file->preload_end &&
- selection_end > file->preload_start)
- {
- /* Entire range is in buffer */
- //printf("read data 2\n");
- quicktime_read_preload(file, data, size);
- }
- else
- if(selection_end > file->preload_end &&
- selection_end - file->preload_size < file->preload_end)
- {
- /* Range is after buffer */
- /* Move the preload start to within one preload length of the selection_end */
- //printf("read data 3\n");
- while(selection_end - file->preload_start > file->preload_size)
- {
- fragment_len = selection_end - file->preload_start - file->preload_size;
- if(file->preload_ptr + fragment_len > file->preload_size)
- fragment_len = file->preload_size - file->preload_ptr;
- file->preload_start += fragment_len;
- file->preload_ptr += fragment_len;
- if(file->preload_ptr >= file->preload_size) file->preload_ptr = 0;
- }
-
- /* Append sequential data after the preload end to the new end */
- fragment_start = file->preload_ptr + file->preload_end - file->preload_start;
- while(fragment_start >= file->preload_size) fragment_start -= file->preload_size;
-
- while(file->preload_end < selection_end)
- {
- fragment_len = selection_end - file->preload_end;
- if(fragment_start + fragment_len > file->preload_size) fragment_len = file->preload_size - fragment_start;
- file->quicktime_fseek(file, file->preload_end);
- /* result = fread(&(file->preload_buffer[fragment_start]), fragment_len, 1, (FILE*)file->stream); */
- result = file->input->read (file->input,
- &(file->preload_buffer[fragment_start]),
- fragment_len);
- file->ftell_position += fragment_len;
- file->preload_end += fragment_len;
- fragment_start += fragment_len;
- if(fragment_start >= file->preload_size) fragment_start = 0;
- }
-
- quicktime_read_preload(file, data, size);
- }
- else
- {
- //printf("quicktime_read_data 4 selection_start %lld selection_end %lld preload_start %lld\n", selection_start, selection_end, file->preload_start);
- /* Range is before buffer or over a preload_size away from the end of the buffer. */
- /* Replace entire preload buffer with range. */
- file->quicktime_fseek(file, file->file_position);
- /* result = fread(file->preload_buffer, size, 1, (FILE*)file->stream); */
- result = file->input->read(file->input, file->preload_buffer, size);
- file->ftell_position += size;
- file->preload_start = file->file_position;
- file->preload_end = file->file_position + size;
- file->preload_ptr = 0;
- //printf("quicktime_read_data 5\n");
- quicktime_read_preload(file, data, size);
- //printf("quicktime_read_data 6\n");
- }
+ } else if (selection_start >= file->preload_start
+ && selection_start < file->preload_end
+ && selection_end <= file->preload_end
+ && selection_end > file->preload_start) {
+ /* Entire range is in buffer */
+ //printf("read data 2\n");
+ quicktime_read_preload(file, data, size);
+
+ } else if (selection_end > file->preload_end
+ && selection_end - file->preload_size < file->preload_end) {
+ /* Range is after buffer */
+ /* Move the preload start to within one preload length of the selection_end */
+ //printf("read data 3\n");
+ while (selection_end - file->preload_start > file->preload_size) {
+ fragment_len = selection_end - file->preload_start - file->preload_size;
+ if (file->preload_ptr + fragment_len > file->preload_size)
+ fragment_len = file->preload_size - file->preload_ptr;
+ file->preload_start += fragment_len;
+ file->preload_ptr += fragment_len;
+ if (file->preload_ptr >= file->preload_size)
+ file->preload_ptr = 0;
+ }
+
+ /* Append sequential data after the preload end to the new end */
+ fragment_start = file->preload_ptr + file->preload_end - file->preload_start;
+ while (fragment_start >= file->preload_size)
+ fragment_start -= file->preload_size;
+
+ while (file->preload_end < selection_end) {
+ fragment_len = selection_end - file->preload_end;
+ if (fragment_start + fragment_len > file->preload_size)
+ fragment_len = file->preload_size - fragment_start;
+ file->quicktime_fseek(file, file->preload_end);
+ /* result = fread(&(file->preload_buffer[fragment_start]), fragment_len, 1, (FILE*)file->stream); */
+ result = file->input->read (file->input,
+ &(file->preload_buffer[fragment_start]),
+ fragment_len);
+ file->ftell_position += fragment_len;
+ file->preload_end += fragment_len;
+ fragment_start += fragment_len;
+ if (fragment_start >= file->preload_size)
+ fragment_start = 0;
+ }
+
+ quicktime_read_preload(file, data, size);
+ } else {
+ //printf("quicktime_read_data 4 selection_start %lld selection_end %lld preload_start %lld\n", selection_start, selection_end, file->preload_start);
+ /* Range is before buffer or over a preload_size away from the end of the buffer. */
+ /* Replace entire preload buffer with range. */
+ file->quicktime_fseek(file, file->file_position);
+ /* result = fread(file->preload_buffer, size, 1, (FILE*)file->stream); */
+ result = file->input->read(file->input, file->preload_buffer, size);
+ file->ftell_position += size;
+ file->preload_start = file->file_position;
+ file->preload_end = file->file_position + size;
+ file->preload_ptr = 0;
+ //printf("quicktime_read_data 5\n");
+ quicktime_read_preload(file, data, size);
+ //printf("quicktime_read_data 6\n");
}
+ }
//printf("quicktime_read_data 1 %lld %lld\n", file->file_position, size);
file->file_position += size;
return result;
}
-static longest quicktime_position(quicktime_t *file)
-{
+static longest quicktime_position(quicktime_t *file) {
if (file->decompressed_buffer) {
return file->decompressed_position;
@@ -866,10 +883,9 @@ static void quicktime_read_char32(quicktime_t *file, char *string)
file->quicktime_read_data(file, string, 4);
}
-static int quicktime_set_position(quicktime_t *file, longest position)
-{
+static int quicktime_set_position(quicktime_t *file, longest position) {
//if(file->wr) printf("quicktime_set_position 0x%llx\n", position);
- if(file->decompressed_buffer)
+ if (file->decompressed_buffer)
file->decompressed_position = position;
else
file->file_position = position;
@@ -877,8 +893,8 @@ static int quicktime_set_position(quicktime_t *file, longest position)
return 0;
}
-static void quicktime_copy_char32(char *output, char *input)
-{
+static void quicktime_copy_char32(char *output, char *input) {
+
*output++ = *input++;
*output++ = *input++;
*output++ = *input++;
@@ -886,15 +902,15 @@ static void quicktime_copy_char32(char *output, char *input)
}
-static unsigned long quicktime_current_time(void)
-{
+static unsigned long quicktime_current_time(void) {
+
time_t t;
time (&t);
return (t+(66*31536000)+1468800);
}
-static int quicktime_match_32(char *input, char *output)
-{
+static int quicktime_match_32(char *input, char *output) {
+
if(input[0] == output[0] &&
input[1] == output[1] &&
input[2] == output[2] &&
@@ -904,8 +920,8 @@ static int quicktime_match_32(char *input, char *output)
return 0;
}
-static void quicktime_read_pascal(quicktime_t *file, char *data)
-{
+static void quicktime_read_pascal(quicktime_t *file, char *data) {
+
char len = quicktime_read_char(file);
file->quicktime_read_data(file, data, len);
data[(int) len] = 0;
@@ -913,29 +929,28 @@ static void quicktime_read_pascal(quicktime_t *file, char *data)
/* matrix.c */
-static void quicktime_matrix_init(quicktime_matrix_t *matrix)
-{
+static void quicktime_matrix_init(quicktime_matrix_t *matrix) {
+
int i;
- for(i = 0; i < 9; i++) matrix->values[i] = 0;
+ for (i = 0; i < 9; i++)
+ matrix->values[i] = 0;
+
matrix->values[0] = matrix->values[4] = 1;
matrix->values[8] = 16384;
}
-static void quicktime_matrix_delete(quicktime_matrix_t *matrix)
-{
+static void quicktime_matrix_delete(quicktime_matrix_t *matrix) {
}
-static void quicktime_read_matrix(quicktime_t *file, quicktime_matrix_t *matrix)
-{
+static void quicktime_read_matrix(quicktime_t *file,
+ quicktime_matrix_t *matrix) {
int i = 0;
- for(i = 0; i < 9; i++)
- {
- matrix->values[i] = quicktime_read_fixed32(file);
- }
+ for(i = 0; i < 9; i++) {
+ matrix->values[i] = quicktime_read_fixed32(file);
+ }
}
-static int quicktime_get_timescale(float frame_rate)
-{
+static int quicktime_get_timescale(float frame_rate) {
int timescale = 600;
/* Encode the 29.97, 23.976, 59.94 framerates */
if(frame_rate - (int)frame_rate != 0)
@@ -950,9 +965,10 @@ static int quicktime_get_timescale(float frame_rate)
/* mvhd.c */
-static int quicktime_mvhd_init(quicktime_mvhd_t *mvhd)
-{
+static int quicktime_mvhd_init(quicktime_mvhd_t *mvhd) {
+
int i;
+
mvhd->version = 0;
mvhd->flags = 0;
mvhd->creation_time = quicktime_current_time();
@@ -961,7 +977,8 @@ static int quicktime_mvhd_init(quicktime_mvhd_t *mvhd)
mvhd->duration = 0;
mvhd->preferred_rate = 1.0;
mvhd->preferred_volume = 0.996094;
- for(i = 0; i < 10; i++) mvhd->reserved[i] = 0;
+ for(i = 0; i < 10; i++)
+ mvhd->reserved[i] = 0;
quicktime_matrix_init(&(mvhd->matrix));
mvhd->preview_time = 0;
mvhd->preview_duration = 0;
@@ -973,13 +990,11 @@ static int quicktime_mvhd_init(quicktime_mvhd_t *mvhd)
return 0;
}
-static int quicktime_mvhd_delete(quicktime_mvhd_t *mvhd)
-{
+static int quicktime_mvhd_delete(quicktime_mvhd_t *mvhd) {
return 0;
}
-static void quicktime_read_mvhd(quicktime_t *file, quicktime_mvhd_t *mvhd)
-{
+static void quicktime_read_mvhd(quicktime_t *file, quicktime_mvhd_t *mvhd) {
mvhd->version = quicktime_read_char(file);
mvhd->flags = quicktime_read_int24(file);
mvhd->creation_time = quicktime_read_int32(file);
@@ -2009,24 +2024,20 @@ static void quicktime_read_stsd(quicktime_t *file, quicktime_minf_t *minf, quick
/* stts.c */
-static void quicktime_stts_init(quicktime_stts_t *stts)
-{
+static void quicktime_stts_init(quicktime_stts_t *stts) {
stts->version = 0;
stts->flags = 0;
stts->total_entries = 0;
}
-static void quicktime_stts_init_table(quicktime_stts_t *stts)
-{
- if(!stts->total_entries)
- {
- stts->total_entries = 1;
- stts->table = (quicktime_stts_table_t*)malloc(sizeof(quicktime_stts_table_t) * stts->total_entries);
- }
+static void quicktime_stts_init_table(quicktime_stts_t *stts) {
+ if(!stts->total_entries) {
+ stts->total_entries = 1;
+ stts->table = (quicktime_stts_table_t*)malloc(sizeof(quicktime_stts_table_t) * stts->total_entries);
+ }
}
-static void quicktime_stts_init_video(quicktime_t *file, quicktime_stts_t *stts, int time_scale, float frame_rate)
-{
+static void quicktime_stts_init_video(quicktime_t *file, quicktime_stts_t *stts, int time_scale, float frame_rate) {
quicktime_stts_table_t *table;
quicktime_stts_init_table(stts);
table = &(stts->table[0]);
@@ -2036,8 +2047,7 @@ static void quicktime_stts_init_video(quicktime_t *file, quicktime_stts_t *stts,
//printf("quicktime_stts_init_video %ld %f\n", time_scale, (double)frame_rate);
}
-static void quicktime_stts_init_audio(quicktime_t *file, quicktime_stts_t *stts, int sample_rate)
-{
+static void quicktime_stts_init_audio(quicktime_t *file, quicktime_stts_t *stts, int sample_rate) {
quicktime_stts_table_t *table;
quicktime_stts_init_table(stts);
table = &(stts->table[0]);
@@ -2046,49 +2056,47 @@ static void quicktime_stts_init_audio(quicktime_t *file, quicktime_stts_t *stts,
table->sample_duration = 1;
}
-static void quicktime_stts_delete(quicktime_stts_t *stts)
-{
+static void quicktime_stts_delete(quicktime_stts_t *stts) {
if(stts->total_entries) free(stts->table);
stts->total_entries = 0;
}
-static void quicktime_read_stts(quicktime_t *file, quicktime_stts_t *stts)
-{
+static void quicktime_read_stts(quicktime_t *file,
+ quicktime_stts_t *stts,
+ long time_scale) {
int i;
+
stts->version = quicktime_read_char(file);
stts->flags = quicktime_read_int24(file);
stts->total_entries = quicktime_read_int32(file);
stts->table = (quicktime_stts_table_t*)malloc(sizeof(quicktime_stts_table_t) * stts->total_entries);
- for(i = 0; i < stts->total_entries; i++)
- {
- stts->table[i].sample_count = quicktime_read_int32(file);
- stts->table[i].sample_duration = quicktime_read_int32(file);
- }
+ printf ("demux_qt: reading stts... (time scale is %ld units/sec)\n",
+ time_scale);
+ for(i = 0; i < stts->total_entries; i++) {
+ stts->table[i].sample_count = quicktime_read_int32(file);
+ stts->table[i].sample_duration = quicktime_read_int32(file);
+ }
}
/* stsc.c */
-static void quicktime_stsc_init(quicktime_stsc_t *stsc)
-{
+static void quicktime_stsc_init(quicktime_stsc_t *stsc) {
stsc->version = 0;
stsc->flags = 0;
stsc->total_entries = 0;
stsc->entries_allocated = 0;
}
-static void quicktime_stsc_init_table(quicktime_t *file, quicktime_stsc_t *stsc)
-{
- if(!stsc->entries_allocated)
- {
- stsc->total_entries = 0;
- stsc->entries_allocated = 2000;
- stsc->table = (quicktime_stsc_table_t*)calloc(1, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
- }
+static void quicktime_stsc_init_table(quicktime_t *file, quicktime_stsc_t *stsc) {
+ if(!stsc->entries_allocated) {
+ stsc->total_entries = 0;
+ stsc->entries_allocated = 2000;
+ stsc->table = (quicktime_stsc_table_t*)calloc(1, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
+ }
}
-static void quicktime_stsc_init_video(quicktime_t *file, quicktime_stsc_t *stsc)
-{
+static void quicktime_stsc_init_video(quicktime_t *file, quicktime_stsc_t *stsc) {
quicktime_stsc_table_t *table;
quicktime_stsc_init_table(file, stsc);
table = &(stsc->table[0]);
@@ -2097,8 +2105,7 @@ static void quicktime_stsc_init_video(quicktime_t *file, quicktime_stsc_t *stsc)
table->id = 1;
}
-static void quicktime_stsc_init_audio(quicktime_t *file, quicktime_stsc_t *stsc, int sample_rate)
-{
+static void quicktime_stsc_init_audio(quicktime_t *file, quicktime_stsc_t *stsc, int sample_rate) {
quicktime_stsc_table_t *table;
quicktime_stsc_init_table(file, stsc);
table = &(stsc->table[0]);
@@ -2107,9 +2114,9 @@ static void quicktime_stsc_init_audio(quicktime_t *file, quicktime_stsc_t *stsc,
table->id = 1;
}
-static void quicktime_stsc_delete(quicktime_stsc_t *stsc)
-{
- if(stsc->total_entries) free(stsc->table);
+static void quicktime_stsc_delete(quicktime_stsc_t *stsc) {
+ if(stsc->total_entries)
+ free(stsc->table);
stsc->total_entries = 0;
}
@@ -2122,29 +2129,27 @@ static void quicktime_read_stsc(quicktime_t *file, quicktime_stsc_t *stsc)
stsc->entries_allocated = stsc->total_entries;
stsc->table = (quicktime_stsc_table_t*)malloc(sizeof(quicktime_stsc_table_t) * stsc->total_entries);
- for(i = 0; i < stsc->total_entries; i++)
- {
- stsc->table[i].chunk = quicktime_read_int32(file);
- stsc->table[i].samples = quicktime_read_int32(file);
- stsc->table[i].id = quicktime_read_int32(file);
- }
+ for(i = 0; i < stsc->total_entries; i++) {
+ stsc->table[i].chunk = quicktime_read_int32(file);
+ stsc->table[i].samples = quicktime_read_int32(file);
+ stsc->table[i].id = quicktime_read_int32(file);
+ }
}
-static int quicktime_update_stsc(quicktime_stsc_t *stsc, long chunk, long samples)
-{
+static int quicktime_update_stsc(quicktime_stsc_t *stsc, long chunk, long samples) {
/* long i; */
- if(chunk > stsc->entries_allocated)
- {
- stsc->entries_allocated = chunk * 2;
- stsc->table =(quicktime_stsc_table_t*)realloc(stsc->table, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
- }
+ if (chunk > stsc->entries_allocated) {
+ stsc->entries_allocated = chunk * 2;
+ stsc->table =(quicktime_stsc_table_t*)realloc(stsc->table, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
+ }
stsc->table[chunk - 1].samples = samples;
stsc->table[chunk - 1].chunk = chunk;
stsc->table[chunk - 1].id = 1;
- if(chunk > stsc->total_entries) stsc->total_entries = chunk;
+ if (chunk > stsc->total_entries)
+ stsc->total_entries = chunk;
return 0;
}
@@ -2158,8 +2163,7 @@ static int quicktime_update_stsc(quicktime_stsc_t *stsc, long chunk, long sample
/* stsz.c */
-static void quicktime_stsz_init(quicktime_stsz_t *stsz)
-{
+static void quicktime_stsz_init(quicktime_stsz_t *stsz) {
stsz->version = 0;
stsz->flags = 0;
stsz->sample_size = 0;
@@ -2167,48 +2171,42 @@ static void quicktime_stsz_init(quicktime_stsz_t *stsz)
stsz->entries_allocated = 0;
}
-static void quicktime_stsz_init_video(quicktime_t *file, quicktime_stsz_t *stsz)
-{
+static void quicktime_stsz_init_video(quicktime_t *file, quicktime_stsz_t *stsz) {
stsz->sample_size = 0;
- if(!stsz->entries_allocated)
- {
- stsz->entries_allocated = 2000;
- stsz->total_entries = 0;
- stsz->table = (quicktime_stsz_table_t*)malloc(sizeof(quicktime_stsz_table_t) * stsz->entries_allocated);
- }
+ if(!stsz->entries_allocated) {
+ stsz->entries_allocated = 2000;
+ stsz->total_entries = 0;
+ stsz->table = (quicktime_stsz_table_t*)malloc(sizeof(quicktime_stsz_table_t) * stsz->entries_allocated);
+ }
}
-static void quicktime_stsz_init_audio(quicktime_t *file, quicktime_stsz_t *stsz, int channels, int bits)
-{
+static void quicktime_stsz_init_audio(quicktime_t *file, quicktime_stsz_t *stsz, int channels, int bits) {
/*stsz->sample_size = channels * bits / 8; */
stsz->sample_size = 1; /* ? */
stsz->total_entries = 0; /* set this when closing */
stsz->entries_allocated = 0;
}
-static void quicktime_stsz_delete(quicktime_stsz_t *stsz)
-{
- if(!stsz->sample_size && stsz->total_entries) free(stsz->table);
+static void quicktime_stsz_delete(quicktime_stsz_t *stsz) {
+ if(!stsz->sample_size && stsz->total_entries)
+ free(stsz->table);
stsz->total_entries = 0;
stsz->entries_allocated = 0;
}
-static void quicktime_read_stsz(quicktime_t *file, quicktime_stsz_t *stsz)
-{
+static void quicktime_read_stsz(quicktime_t *file, quicktime_stsz_t *stsz) {
long i;
stsz->version = quicktime_read_char(file);
stsz->flags = quicktime_read_int24(file);
stsz->sample_size = quicktime_read_int32(file);
stsz->total_entries = quicktime_read_int32(file);
stsz->entries_allocated = stsz->total_entries;
- if(!stsz->sample_size)
- {
- stsz->table = (quicktime_stsz_table_t*)malloc(sizeof(quicktime_stsz_table_t) * stsz->entries_allocated);
- for(i = 0; i < stsz->total_entries; i++)
- {
- stsz->table[i].size = quicktime_read_int32(file);
- }
+ if(!stsz->sample_size) {
+ stsz->table = (quicktime_stsz_table_t*)malloc(sizeof(quicktime_stsz_table_t) * stsz->entries_allocated);
+ for(i = 0; i < stsz->total_entries; i++) {
+ stsz->table[i].size = quicktime_read_int32(file);
}
+ }
}
static void quicktime_update_stsz(quicktime_stsz_t *stsz, long sample, long sample_size)
@@ -2390,44 +2388,35 @@ static void quicktime_stbl_delete(quicktime_stbl_t *stbl)
quicktime_stco_delete(&(stbl->stco));
}
-static int quicktime_read_stbl(quicktime_t *file, quicktime_minf_t *minf, quicktime_stbl_t *stbl, quicktime_atom_t *parent_atom)
-{
+static int quicktime_read_stbl(quicktime_t *file, quicktime_minf_t *minf, long time_scale,
+ quicktime_stbl_t *stbl, quicktime_atom_t *parent_atom) {
quicktime_atom_t leaf_atom;
- do
- {
- quicktime_atom_read_header(file, &leaf_atom);
+ do {
+ quicktime_atom_read_header(file, &leaf_atom);
- //printf("quicktime_read_stbl 1\n");
- /* mandatory */
- if(quicktime_atom_is(&leaf_atom, "stsd"))
- {
- //printf("STSD start %lld end %lld", leaf_atom.start, leaf_atom.end);
- quicktime_read_stsd(file, minf, &(stbl->stsd));
- /* Some codecs store extra information at the end of this */
- quicktime_atom_skip(file, &leaf_atom);
- }
- else
- if(quicktime_atom_is(&leaf_atom, "stts"))
- { quicktime_read_stts(file, &(stbl->stts)); }
- else
- if(quicktime_atom_is(&leaf_atom, "stss"))
- { quicktime_read_stss(file, &(stbl->stss)); }
- else
- if(quicktime_atom_is(&leaf_atom, "stsc"))
- { quicktime_read_stsc(file, &(stbl->stsc)); }
- else
- if(quicktime_atom_is(&leaf_atom, "stsz"))
- { quicktime_read_stsz(file, &(stbl->stsz)); }
- else
- if(quicktime_atom_is(&leaf_atom, "co64"))
- { quicktime_read_stco64(file, &(stbl->stco)); }
- else
- if(quicktime_atom_is(&leaf_atom, "stco"))
- { quicktime_read_stco(file, &(stbl->stco)); }
- else
- quicktime_atom_skip(file, &leaf_atom);
- }while(quicktime_position(file) < parent_atom->end);
+ //printf("quicktime_read_stbl 1\n");
+ /* mandatory */
+ if(quicktime_atom_is(&leaf_atom, "stsd")) {
+ //printf("STSD start %lld end %lld", leaf_atom.start, leaf_atom.end);
+ quicktime_read_stsd(file, minf, &(stbl->stsd));
+ /* Some codecs store extra information at the end of this */
+ quicktime_atom_skip(file, &leaf_atom);
+ } else if(quicktime_atom_is(&leaf_atom, "stts")) {
+ quicktime_read_stts(file, &(stbl->stts), time_scale);
+ } else if(quicktime_atom_is(&leaf_atom, "stss")) {
+ quicktime_read_stss(file, &(stbl->stss));
+ } else if(quicktime_atom_is(&leaf_atom, "stsc")) {
+ quicktime_read_stsc(file, &(stbl->stsc));
+ } else if(quicktime_atom_is(&leaf_atom, "stsz")) {
+ quicktime_read_stsz(file, &(stbl->stsz));
+ } else if(quicktime_atom_is(&leaf_atom, "co64")) {
+ quicktime_read_stco64(file, &(stbl->stco));
+ } else if(quicktime_atom_is(&leaf_atom, "stco")) {
+ quicktime_read_stco(file, &(stbl->stco));
+ } else
+ quicktime_atom_skip(file, &leaf_atom);
+ } while (quicktime_position(file) < parent_atom->end);
return 0;
}
@@ -2488,37 +2477,30 @@ static void quicktime_minf_delete(quicktime_minf_t *minf)
quicktime_hdlr_delete(&(minf->hdlr));
}
-static int quicktime_read_minf(quicktime_t *file, quicktime_minf_t *minf, quicktime_atom_t *parent_atom)
-{
+static int quicktime_read_minf(quicktime_t *file, quicktime_minf_t *minf,
+ long time_scale,
+ quicktime_atom_t *parent_atom) {
quicktime_atom_t leaf_atom;
- do
- {
- quicktime_atom_read_header(file, &leaf_atom);
- //printf("quicktime_read_minf 1\n");
-
- /* mandatory */
- if(quicktime_atom_is(&leaf_atom, "vmhd"))
- { minf->is_video = 1; quicktime_read_vmhd(file, &(minf->vmhd)); }
- else
- if(quicktime_atom_is(&leaf_atom, "smhd"))
- { minf->is_audio = 1; quicktime_read_smhd(file, &(minf->smhd)); }
- else
- if(quicktime_atom_is(&leaf_atom, "hdlr"))
- {
- quicktime_read_hdlr(file, &(minf->hdlr));
- /* Main Actor doesn't write component name */
- quicktime_atom_skip(file, &leaf_atom);
- }
- else
- if(quicktime_atom_is(&leaf_atom, "dinf"))
- { quicktime_read_dinf(file, &(minf->dinf), &leaf_atom); }
- else
- if(quicktime_atom_is(&leaf_atom, "stbl"))
- { quicktime_read_stbl(file, minf, &(minf->stbl), &leaf_atom); }
- else
- quicktime_atom_skip(file, &leaf_atom);
- }while(quicktime_position(file) < parent_atom->end);
+ do {
+ quicktime_atom_read_header(file, &leaf_atom);
+ //printf("quicktime_read_minf 1\n");
+
+ /* mandatory */
+ if (quicktime_atom_is(&leaf_atom, "vmhd")) {
+ minf->is_video = 1; quicktime_read_vmhd(file, &(minf->vmhd));
+ } else if (quicktime_atom_is(&leaf_atom, "smhd")) {
+ minf->is_audio = 1; quicktime_read_smhd(file, &(minf->smhd));
+ } else if (quicktime_atom_is(&leaf_atom, "hdlr")) {
+ quicktime_read_hdlr(file, &(minf->hdlr));
+ /* Main Actor doesn't write component name */
+ quicktime_atom_skip(file, &leaf_atom);
+ } else if (quicktime_atom_is(&leaf_atom, "dinf")) { quicktime_read_dinf(file, &(minf->dinf), &leaf_atom);
+ } else if (quicktime_atom_is(&leaf_atom, "stbl")){
+ quicktime_read_stbl(file, minf, time_scale, &(minf->stbl), &leaf_atom);
+ } else
+ quicktime_atom_skip(file, &leaf_atom);
+ } while (quicktime_position(file) < parent_atom->end);
return 0;
}
@@ -2568,31 +2550,27 @@ static void quicktime_mdia_delete(quicktime_mdia_t *mdia)
quicktime_minf_delete(&(mdia->minf));
}
-static int quicktime_read_mdia(quicktime_t *file, quicktime_mdia_t *mdia, quicktime_atom_t *trak_atom)
-{
+static int quicktime_read_mdia(quicktime_t *file, quicktime_mdia_t *mdia,
+ quicktime_atom_t *trak_atom) {
+
quicktime_atom_t leaf_atom;
- do
- {
- quicktime_atom_read_header(file, &leaf_atom);
- //printf("quicktime_read_mdia 0x%llx\n", quicktime_position(file));
-
- /* mandatory */
- if(quicktime_atom_is(&leaf_atom, "mdhd"))
- { quicktime_read_mdhd(file, &(mdia->mdhd)); }
- else
- if(quicktime_atom_is(&leaf_atom, "hdlr"))
- {
- quicktime_read_hdlr(file, &(mdia->hdlr));
- /* Main Actor doesn't write component name */
- quicktime_atom_skip(file, &leaf_atom);
- }
- else
- if(quicktime_atom_is(&leaf_atom, "minf"))
- { quicktime_read_minf(file, &(mdia->minf), &leaf_atom); }
- else
- quicktime_atom_skip(file, &leaf_atom);
- }while(quicktime_position(file) < trak_atom->end);
+ do {
+ quicktime_atom_read_header(file, &leaf_atom);
+ //printf("quicktime_read_mdia 0x%llx\n", quicktime_position(file));
+
+ /* mandatory */
+ if(quicktime_atom_is(&leaf_atom, "mdhd")) {
+ quicktime_read_mdhd(file, &(mdia->mdhd));
+ } else if(quicktime_atom_is(&leaf_atom, "hdlr")) {
+ quicktime_read_hdlr(file, &(mdia->hdlr));
+ /* Main Actor doesn't write component name */
+ quicktime_atom_skip(file, &leaf_atom);
+ } else if(quicktime_atom_is(&leaf_atom, "minf")) {
+ quicktime_read_minf(file, &(mdia->minf), mdia->mdhd.time_scale, &leaf_atom);
+ } else
+ quicktime_atom_skip(file, &leaf_atom);
+ } while (quicktime_position(file) < trak_atom->end);
return 0;
@@ -2817,9 +2795,9 @@ static long quicktime_track_samples(quicktime_t *file, quicktime_trak_t *trak)
}
static int quicktime_chunk_of_sample(longest *chunk_sample,
- longest *chunk,
- quicktime_trak_t *trak,
- long sample)
+ longest *chunk,
+ quicktime_trak_t *trak,
+ long sample)
{
quicktime_stsc_table_t *table = trak->mdia.minf.stbl.stsc.table;
long total_entries = trak->mdia.minf.stbl.stsc.total_entries;
@@ -2831,12 +2809,11 @@ static int quicktime_chunk_of_sample(longest *chunk_sample,
chunk1samples = 0;
chunk2entry = 0;
- if(!total_entries)
- {
- *chunk_sample = 0;
- *chunk = 0;
- return 0;
- }
+ if(!total_entries) {
+ *chunk_sample = 0;
+ *chunk = 0;
+ return 0;
+ }
do
{
@@ -2864,7 +2841,7 @@ static int quicktime_chunk_of_sample(longest *chunk_sample,
else
sample_duration = 1; // this way nothing is broken ... I hope
- chunk1samples = table[chunk2entry].samples * sample_duration;
+ chunk1samples = table[chunk2entry].samples * sample_duration;
chunk1 = chunk2;
if(chunk2entry < total_entries)
@@ -2986,18 +2963,15 @@ static longest quicktime_sample_range_size(quicktime_trak_t *trak,
return total;
}
-static longest quicktime_sample_to_offset(quicktime_trak_t *trak, long sample)
-{
+static longest quicktime_sample_to_offset(quicktime_trak_t *trak, long sample) {
longest chunk, chunk_sample, chunk_offset1, chunk_offset2;
quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, sample);
- // printf("\tBEFORE quicktime_chunk_to_offset chunk %lld, chunk_sample %lld\n", chunk, chunk_sample);
+ printf("demux_qt: quicktime_sample_to_offset chunk %lld, chunk_sample %lld, sample %ld\n",
+ chunk, chunk_sample, sample);
+
chunk_offset1 = quicktime_chunk_to_offset(trak, chunk);
- // printf("\tAFTER quicktime_chunk_to_offset %lld\n", chunk_offset1);
chunk_offset2 = chunk_offset1 + quicktime_sample_range_size(trak, chunk_sample, sample);
- // printf("\tAFTER AFTER %lld\n", chunk_offset2);
- //printf("quicktime_sample_to_offset chunk %lld sample %lld chunk_offset %lld chunk_sample %lld chunk_offset + samples %lld\n",
- // chunk, sample, chunk_offset1, chunk_sample, chunk_offset2);
return chunk_offset2;
}
@@ -3044,17 +3018,15 @@ static int quicktime_update_tables(quicktime_t *file,
#endif
static int quicktime_trak_duration(quicktime_trak_t *trak,
- long *duration,
- long *timescale)
-{
+ long *duration,
+ long *timescale) {
quicktime_stts_t *stts = &(trak->mdia.minf.stbl.stts);
int i;
*duration = 0;
- for(i = 0; i < stts->total_entries; i++)
- {
- *duration += stts->table[i].sample_duration * stts->table[i].sample_count;
- }
+ for(i = 0; i < stts->total_entries; i++) {
+ *duration += stts->table[i].sample_duration * stts->table[i].sample_count;
+ }
*timescale = trak->mdia.mdhd.time_scale;
return 0;
@@ -3377,76 +3349,68 @@ static int quicktime_set_audio_position(quicktime_t *file, longest sample, int t
longest offset, chunk_sample, chunk;
quicktime_trak_t *trak;
- if(file->total_atracks)
- {
- trak = file->atracks[track].track;
- file->atracks[track].current_position = sample;
- // printf("BEFORE quicktime_chunk_of_sample track %d sample %li\n", track, sample);
- quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, sample);
- file->atracks[track].current_chunk = chunk;
- // printf("AFTER quicktime_chunk_of_sample chunk %d chunk_sample %d\n", chunk, chunk_sample);
- offset = quicktime_sample_to_offset(trak, sample);
- // printf("AFTER quicktime_sample_to_offset offset %li\n", offset);
- quicktime_set_position(file, offset);
- }
+ if(file->total_atracks) {
+ trak = file->atracks[track].track;
+ file->atracks[track].current_position = sample;
+ // printf("BEFORE quicktime_chunk_of_sample track %d sample %li\n", track, sample);
+ quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, sample);
+ file->atracks[track].current_chunk = chunk;
+ // printf("AFTER quicktime_chunk_of_sample chunk %d chunk_sample %d\n", chunk, chunk_sample);
+ offset = quicktime_sample_to_offset(trak, sample);
+ // printf("AFTER quicktime_sample_to_offset offset %li\n", offset);
+ quicktime_set_position(file, offset);
+ }
return 0;
}
-static int quicktime_set_video_position(quicktime_t *file, longest frame, int track)
-{
+static int quicktime_set_video_position(quicktime_t *file, longest frame,
+ int track) {
longest offset, chunk_sample, chunk;
quicktime_trak_t *trak;
- if(file->total_vtracks)
- {
- trak = file->vtracks[track].track;
- file->vtracks[track].current_position = frame;
- quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, frame);
- file->vtracks[track].current_chunk = chunk;
- offset = quicktime_sample_to_offset(trak, frame);
- quicktime_set_position(file, offset);
- }
+ if(file->total_vtracks) {
+ trak = file->vtracks[track].track;
+ file->vtracks[track].current_position = frame;
+ quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, frame);
+ file->vtracks[track].current_chunk = chunk;
+ offset = quicktime_sample_to_offset(trak, frame);
+ quicktime_set_position(file, offset);
+ }
return 0;
}
-static int quicktime_audio_tracks(quicktime_t *file)
-{
+static int quicktime_audio_tracks(quicktime_t *file) {
int i, result = 0;
quicktime_minf_t *minf;
- for(i = 0; i < file->moov.total_tracks; i++)
- {
- minf = &(file->moov.trak[i]->mdia.minf);
- if(minf->is_audio)
- result++;
- }
+ for(i = 0; i < file->moov.total_tracks; i++) {
+ minf = &(file->moov.trak[i]->mdia.minf);
+ if(minf->is_audio)
+ result++;
+ }
return result;
}
-static int quicktime_has_audio(quicktime_t *file)
-{
- if(quicktime_audio_tracks(file)) return 1;
+static int quicktime_has_audio(quicktime_t *file) {
+ if(quicktime_audio_tracks(file))
+ return 1;
return 0;
}
-static long quicktime_sample_rate(quicktime_t *file, int track)
-{
-/* return 8000;*/
+static long quicktime_sample_rate(quicktime_t *file, int track) {
if(file->total_atracks)
return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].sample_rate;
return 0;
}
-static int quicktime_audio_bits(quicktime_t *file, int track)
-{
+static int quicktime_audio_bits(quicktime_t *file, int track) {
if(file->total_atracks)
return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].sample_size;
return 0;
}
-static char* quicktime_audio_compressor(quicktime_t *file, int track)
-{
+static char* quicktime_audio_compressor(quicktime_t *file, int track) {
if (track < file->total_atracks)
return file->atracks[track].track->mdia.minf.stbl.stsd.table[0].format;
/*
@@ -3456,74 +3420,66 @@ static char* quicktime_audio_compressor(quicktime_t *file, int track)
return "NONE";
}
-static int quicktime_track_channels(quicktime_t *file, int track)
-{
+static int quicktime_track_channels(quicktime_t *file, int track) {
if(track < file->total_atracks)
return file->atracks[track].channels;
return 0;
}
-static int quicktime_channel_location(quicktime_t *file, int *quicktime_track, int *quicktime_channel, int channel)
-{
+static int quicktime_channel_location(quicktime_t *file, int *quicktime_track,
+ int *quicktime_channel, int channel) {
int current_channel = 0, current_track = 0;
*quicktime_channel = 0;
*quicktime_track = 0;
- for(current_channel = 0, current_track = 0; current_track < file->total_atracks; )
- {
- if(channel >= current_channel)
- {
- *quicktime_channel = channel - current_channel;
- *quicktime_track = current_track;
- }
-
- current_channel += file->atracks[current_track].channels;
- current_track++;
+ for(current_channel = 0, current_track = 0; current_track < file->total_atracks; ) {
+ if(channel >= current_channel) {
+ *quicktime_channel = channel - current_channel;
+ *quicktime_track = current_track;
}
+
+ current_channel += file->atracks[current_track].channels;
+ current_track++;
+ }
return 0;
}
-static int quicktime_video_tracks(quicktime_t *file)
-{
+static int quicktime_video_tracks(quicktime_t *file) {
int i, result = 0;
- for(i = 0; i < file->moov.total_tracks; i++)
- {
- if(file->moov.trak[i]->mdia.minf.is_video) result++;
- }
+ for(i = 0; i < file->moov.total_tracks; i++) {
+ if(file->moov.trak[i]->mdia.minf.is_video)
+ result++;
+ }
return result;
}
-static int quicktime_has_video(quicktime_t *file)
-{
- if(quicktime_video_tracks(file)) return 1;
+static int quicktime_has_video(quicktime_t *file) {
+ if (quicktime_video_tracks(file))
+ return 1;
return 0;
}
-static int quicktime_video_width(quicktime_t *file, int track)
-{
+static int quicktime_video_width(quicktime_t *file, int track) {
if(file->total_vtracks)
return file->vtracks[track].track->tkhd.track_width;
return 0;
}
-static int quicktime_video_height(quicktime_t *file, int track)
-{
+static int quicktime_video_height(quicktime_t *file, int track) {
if(file->total_vtracks)
return file->vtracks[track].track->tkhd.track_height;
return 0;
}
-static int quicktime_video_depth(quicktime_t *file, int track)
-{
+static int quicktime_video_depth(quicktime_t *file, int track) {
if(file->total_vtracks)
return file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].depth;
return 0;
}
-static float quicktime_frame_rate(quicktime_t *file, int track)
-{
+static float quicktime_frame_rate(quicktime_t *file, int track) {
if(file->total_vtracks > track)
return (float)file->vtracks[track].track->mdia.mdhd.time_scale /
file->vtracks[track].track->mdia.minf.stbl.stts.table[0].sample_duration;
@@ -3531,209 +3487,21 @@ static float quicktime_frame_rate(quicktime_t *file, int track)
return 0;
}
-static char* quicktime_video_compressor(quicktime_t *file, int track)
-{
+static char* quicktime_video_compressor(quicktime_t *file, int track) {
return file->vtracks[track].track->mdia.minf.stbl.stsd.table[0].format;
}
-static long quicktime_read_audio(quicktime_t *file, char *audio_buffer, long samples, int track)
-{
- longest chunk_sample, chunk;
- int result = 1;
- quicktime_trak_t *trak = file->atracks[track].track;
- longest fragment_len, chunk_end;
- longest position = file->atracks[track].current_position;
- longest end = position + samples;
- longest bytes, total_bytes = 0;
- longest buffer_offset;
-
- quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, position);
- buffer_offset = 0;
-
- while(position < end && result)
- {
- quicktime_set_audio_position(file, position, track);
- fragment_len = quicktime_chunk_samples(trak, chunk);
- chunk_end = chunk_sample + fragment_len;
- fragment_len -= position - chunk_sample;
- if(position + fragment_len > chunk_end) fragment_len = chunk_end - position;
- if(position + fragment_len > end) fragment_len = end - position;
-
- bytes = quicktime_samples_to_bytes(trak, fragment_len);
- result = file->quicktime_read_data(file, &audio_buffer[buffer_offset], bytes);
-
- total_bytes += bytes;
- position += fragment_len;
- chunk_sample = position;
- buffer_offset += bytes;
- chunk++;
- }
-
- file->atracks[track].current_position = position;
- if(!result) return 0;
- return total_bytes;
-}
-
-static int quicktime_read_chunk(quicktime_t *file, char *output, int track, longest chunk, longest byte_start, longest byte_len)
-{
- quicktime_set_position(file, quicktime_chunk_to_offset(file->atracks[track].track, chunk) + byte_start);
- if(file->quicktime_read_data(file, output, byte_len)) return 0;
- else
- return 1;
-}
-
-static long quicktime_frame_size(quicktime_t *file, long frame, int track)
-{
- long bytes = 0;
- quicktime_trak_t *trak = file->vtracks[track].track;
-
- if(trak->mdia.minf.stbl.stsz.sample_size)
- {
- bytes = trak->mdia.minf.stbl.stsz.sample_size;
- }
- else
- {
- long total_frames = quicktime_track_samples(file, trak);
- if(frame < 0) frame = 0;
- else
- if(frame > total_frames - 1) frame = total_frames - 1;
- bytes = trak->mdia.minf.stbl.stsz.table[frame].size;
- }
-
-
- return bytes;
-}
-
-#if 0
-static longest quicktime_read_next_packet(quicktime_t *file, unsigned char *outbuf, int *isVideo, int *thetrak)
-{
- longest packet_start;
- longest min_video_delta = 100000000000;
- longest min_audio_delta = 100000000000;
- longest min_video_start=0;
- longest min_audio_start=0;
- longest current_position = quicktime_position(file);
- long packet = 0;
- long min_audio_packet=0;
- long min_video_packet=0;
- int trak = 0;
- int min_audio_trak=0;
- int min_video_trak=0;
-
-
- for(trak = 0; trak < file->total_vtracks; trak++) {
- packet = quicktime_offset_to_chunk(&packet_start, file->vtracks[trak].track, current_position);
- /* printf("video_packet %d, video position %li\n", packet, packet_start); */
- if(current_position - packet_start < min_video_delta) {
- min_video_delta = current_position - packet_start;
- min_video_trak = trak;
- min_video_packet = packet;
- min_video_start = packet_start;
- }
- }
-
- for(trak = 0; trak < file->total_atracks; trak++) {
- packet = quicktime_offset_to_chunk(&packet_start, file->atracks[trak].track, current_position);
- /* printf("audio packet %d, audio position %li ", packet, packet_start); */
- if(current_position - packet_start < min_audio_delta) {
- min_audio_delta = current_position - packet_start;
- min_audio_trak = trak;
- min_audio_packet = packet;
- min_audio_start = packet_start;
- }
- }
- if(min_audio_delta < min_video_delta) {
- longest chunksize = file->atracks[min_audio_trak].track->mdia.minf.stbl.stsz.table[min_audio_packet-1].size;
- /* printf("audio chunksize %li min_audio_start %li\n", chunksize, min_audio_start); */
- *thetrak = min_audio_trak;
- *isVideo = 0;
- file->quicktime_fseek(file, min_audio_start);
- file->quicktime_read_data(file,(char*)outbuf, chunksize);
- return chunksize;
- } else {
- longest chunksize = file->vtracks[min_video_trak].track->mdia.minf.stbl.stsz.table[min_video_packet-1].size;
- /* printf("video chunksize %li\n", chunksize); */
- *thetrak = min_video_trak;
- *isVideo = 1;
- file->quicktime_fseek(file, min_video_start);
- file->quicktime_read_data(file,(char*)outbuf, chunksize);
- return chunksize;
-
- }
-
- return 0;
-}
-#endif
-
-static long quicktime_read_frame(quicktime_t *file, unsigned char *video_buffer, int track)
-{
- longest bytes;
- int result = 0;
-
- /* quicktime_trak_t *trak = file->vtracks[track].track; */
- bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);
-
- quicktime_set_video_position(file, file->vtracks[track].current_position, track);
- result = file->quicktime_read_data(file, (char*)video_buffer, bytes);
- file->vtracks[track].current_position++;
-
- if(!result) return 0;
- return bytes;
-}
-
-/* return -1 if there is NO keyframe after */
-static long quicktime_get_keyframe_after(quicktime_t *file, long frame, int track)
-{
- quicktime_trak_t *trak = file->vtracks[track].track;
- quicktime_stss_t *stss = &trak->mdia.minf.stbl.stss;
- int lo, hi;
-
- lo = 0;
- hi = stss->total_entries-1;
- if (stss->table[lo].sample-1>=frame) return stss->table[lo].sample-1;
- if (stss->table[hi].sample-1< frame) return -1;
- while (hi>lo+1) {
- /* here: stss->table[lo].sample-1<frame
- stss->table[hi].sample-1>=frame */
- int med = (lo+hi)/2;
- if (stss->table[med].sample-1<frame) lo = med; else hi = med;
- }
- /* here: hi=lo+1 */
- return stss->table[hi].sample-1;
-}
-
-
-static int quicktime_read_frame_init(quicktime_t *file, int track)
-{
- /* quicktime_trak_t *trak = file->vtracks[track].track; */
- quicktime_set_video_position(file, file->vtracks[track].current_position, track);
- if(quicktime_ftell(file) != file->file_position)
- {
- file->input->seek (file->input, file->file_position, SEEK_SET);
- file->ftell_position = file->file_position;
- }
- return 0;
-}
-
-static int quicktime_read_frame_end(quicktime_t *file, int track)
-{
- file->file_position = quicktime_ftell(file);
- file->vtracks[track].current_position++;
- return 0;
-}
-
-static int quicktime_init_video_map(quicktime_t *file, quicktime_video_map_t *vtrack, quicktime_trak_t *trak)
-{
+static int quicktime_init_video_map(quicktime_t *file, quicktime_video_map_t *vtrack,
+ quicktime_trak_t *trak) {
vtrack->track = trak;
vtrack->current_position = 0;
vtrack->current_chunk = 1;
return 0;
}
-static int quicktime_delete_video_map(quicktime_t *file, quicktime_video_map_t *vtrack)
-{
+static int quicktime_delete_video_map(quicktime_t *file, quicktime_video_map_t *vtrack) {
return 0;
}
@@ -3746,17 +3514,15 @@ static int quicktime_init_audio_map(quicktime_t *file, quicktime_audio_map_t *at
return 0;
}
-static int quicktime_delete_audio_map(quicktime_t *file, quicktime_audio_map_t *atrack)
-{
+static int quicktime_delete_audio_map(quicktime_t *file, quicktime_audio_map_t *atrack) {
return 0;
}
-static void quicktime_mdat_delete(quicktime_mdat_t *mdat)
-{
+static void quicktime_mdat_delete(quicktime_mdat_t *mdat) {
}
-static void quicktime_read_mdat(quicktime_t *file, quicktime_mdat_t *mdat, quicktime_atom_t *parent_atom, xine_t *xine)
-{
+static void quicktime_read_mdat(quicktime_t *file, quicktime_mdat_t *mdat,
+ quicktime_atom_t *parent_atom, xine_t *xine) {
mdat->atom.size = parent_atom->size;
mdat->atom.start = parent_atom->start;
quicktime_atom_skip(file, parent_atom);
@@ -3824,8 +3590,7 @@ static int quicktime_read_info(quicktime_t *file, xine_t *xine) {
/* ============================= Initialization functions */
-static int quicktime_init(quicktime_t *file)
-{
+static int quicktime_init(quicktime_t *file) {
memset(file, sizeof(quicktime_t), 0);
@@ -3836,8 +3601,7 @@ static int quicktime_init(quicktime_t *file)
return 0;
}
-static int quicktime_delete(quicktime_t *file)
-{
+static int quicktime_delete(quicktime_t *file) {
int i;
if(file->total_atracks) {
@@ -3922,8 +3686,7 @@ static void quicktime_close(quicktime_t *file)
free(file);
}
-static quicktime_t* quicktime_open(input_plugin_t *input, xine_t *xine)
-{
+static quicktime_t* quicktime_open(input_plugin_t *input, xine_t *xine) {
quicktime_t *new_file = calloc(1, sizeof(quicktime_t));
quicktime_init(new_file);
@@ -3952,131 +3715,112 @@ static quicktime_t* quicktime_open(input_plugin_t *input, xine_t *xine)
return new_file;
}
-
/*
* now for the xine-specific demuxer stuff
*/
-static void *demux_qt_loop (void *this_gen) {
+static off_t demux_qt_get_sample_size (quicktime_trak_t *trak, int sample_num) {
- buf_element_t *buf = NULL;
- demux_qt_t *this = (demux_qt_t *) this_gen;
- uint32_t audio_pts, video_pts, frame_num, audio_pos;
+ quicktime_stsz_t *stsz;
- /* printf ("demux_qt: demux loop starting...\n"); */
+ stsz = &trak->mdia.minf.stbl.stsz;
- do {
+ if (stsz->sample_size)
+ return stsz->sample_size;
+
+ return stsz->table[sample_num].size;
+}
- if (this->has_audio) {
- audio_pos = quicktime_audio_position (this->qt, 0);
+static void *demux_qt_loop (void *this_gen) {
- if ( (audio_pos + 256) > quicktime_audio_length (this->qt, 0)) {
- this->status = DEMUX_FINISHED;
- break;
- }
- }
+ buf_element_t *buf = NULL;
+ demux_qt_t *this = (demux_qt_t *) this_gen;
+ int idx;
+ off_t offset, size, todo;
+ fifo_buffer_t *fifo;
+ int64_t pts;
+ uint32_t flags;
+
+#ifdef LOG
+ printf ("demux_qt: demux loop starting...\n");
+#endif
- /*
- printf ("audio pos:%d < %d\n",
- audio_pos, quicktime_audio_length (this->qt, 0));
- */
+ idx = 0;
+
+ do {
- audio_pts = quicktime_audio_position (this->qt, 0) * this->audio_factor ;
+ int is_audio, sample_num;
- frame_num = quicktime_video_position (this->qt, 0);
- if ( frame_num == quicktime_video_length (this->qt, 0) ) {
- this->status = DEMUX_FINISHED;
+ if (idx >= this->num_index_entries)
break;
- }
- /*
- printf ("video pos:%d < %d\n",
- frame_num, quicktime_video_length (this->qt, 0));
- */
+ is_audio = (this->index[idx].type & BUF_MAJOR_MASK) == BUF_AUDIO_BASE;
- video_pts = frame_num * this->video_step ;
+ if (is_audio)
+ fifo = this->audio_fifo;
+ else
+ fifo = this->video_fifo;
- if ( this->has_audio && this->audio_fifo && (audio_pts < video_pts)) {
+ offset = this->index[idx].offset;
+ pts = this->index[idx].pts;
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
-
- buf->content = buf->mem;
-
- if ( !(buf->size = quicktime_read_audio (this->qt, buf->content, 256, 0)) ) {
- this->status = DEMUX_FINISHED;
- buf->free_buffer (buf);
- } else {
+ for (sample_num = this->index[idx].first_sample; sample_num <= this->index[idx].last_sample; sample_num++) {
- /* int count; */
-
- buf->pts = audio_pts;
- buf->scr = audio_pts;
- buf->type = this->audio_type;
- buf->decoder_info[0] = 1;
- buf->input_time = 0;
- buf->input_pos = 0;
-
- /*
- for (count=0; count<buf->size; count++){
-
- printf ("%02x ", buf->content[count]);
- if ( !(count % 8) )
- printf (" ");
- if ( !(count % 16) )
- printf ("\n");
- }
- */
+ todo = demux_qt_get_sample_size (this->index[idx].track, sample_num);
- this->audio_fifo->put (this->audio_fifo, buf);
- }
+#ifdef LOG
+ printf ("demux_qt: [idx:%04d type:%08x len:%08lld ] ---------------------------\n",
+ idx, this->index[idx].type, todo);
+#endif
- } else {
+ flags = BUF_FLAG_FRAME_START;
+ while (todo) {
- int size;/* = quicktime_frame_size (this->qt, frame_num, 0); */
+ buf = fifo->buffer_pool_alloc (fifo);
- if (! (size=quicktime_read_frame (this->qt, this->scratch, 0)))
- this->status = DEMUX_FINISHED;
- else {
- int pos=0;
+ if (todo>buf->max_size)
+ size = buf->max_size;
+ else
+ size = todo;
+ todo -= size;
- while (size>0) {
- int copy_bytes;
+ quicktime_set_position (this->qt, offset);
+
+ buf->size = this->qt->quicktime_read_data (this->qt, buf->mem, size);
+#ifdef LOG
+ printf ("demux_qt: generated buffer of %d bytes \n", buf->size);
+#endif
+
+ buf->content = buf->mem;
- buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
+#ifdef DBG_QT
+ if (is_audio)
+ write (debug_fh, buf->mem, buf->size);
+#endif
- if (size>buf->max_size) {
- copy_bytes = buf->max_size;
- buf->decoder_info[0] = 1;
- } else {
- copy_bytes = size;
- buf->decoder_info[0] = 2;
- }
+ buf->type = this->index[idx].type;
+ buf->pts = pts;
+ buf->input_pos = this->qt->file_position;
+ if (todo)
+ buf->decoder_flags = flags;
+ else
+ buf->decoder_flags = flags | BUF_FLAG_FRAME_END;
- memcpy (buf->mem, &this->scratch[pos], copy_bytes);
- buf->content = buf->mem;
- buf->size = copy_bytes;
- buf->pts = video_pts;
- buf->scr = video_pts;
- buf->type = this->video_type;
- buf->input_time = video_pts / 90000;
- buf->input_pos = this->input->get_current_pos(this->input);
-
- this->video_fifo->put (this->video_fifo, buf);
+ fifo->put (fifo, buf);
- pos += copy_bytes;
- size -= copy_bytes;
- }
+ pts = 0;
+ flags = 0;
+ offset += size;
}
+
}
+ idx++;
} while (this->status == DEMUX_OK) ;
-
- /*
printf ("demux_qt: demux loop finished (status: %d)\n",
this->status);
- */
this->status = DEMUX_FINISHED;
@@ -4104,7 +3848,11 @@ static void demux_qt_close (demux_plugin_t *this_gen) {
demux_qt_t *this = (demux_qt_t *) this_gen;
free (this);
-
+
+#ifdef DBG_QT
+ close (debug_fh);
+#endif
+
}
static void demux_qt_stop (demux_plugin_t *this_gen) {
@@ -4203,6 +3951,8 @@ static int demux_qt_detect_compressors (demux_qt_t *this) {
this->wavex.wFormatTag = WAVE_FORMAT_ADPCM;
} else if (!strncasecmp (audio, ".mp3", 4)) {
this->audio_type = BUF_AUDIO_MPEG;
+ } else if (!strncasecmp (audio, "mp4a", 4)) {
+ this->audio_type = BUF_AUDIO_AAC;
} else {
printf ("demux_qt: unknown audio codec >%s<\n",
audio);
@@ -4212,6 +3962,180 @@ static int demux_qt_detect_compressors (demux_qt_t *this) {
return 1;
}
+static void demux_qt_add_index_entry (demux_qt_t *this, off_t offset,
+ int first_sample, int last_sample,
+ int64_t pts, int32_t type,
+ quicktime_trak_t *track) {
+
+ int i,j;
+
+ /*
+ * insertion sort
+ */
+
+ for (i=0; i<this->num_index_entries; i++) {
+ if (this->index[i].pts >= pts)
+ break;
+ }
+
+ for (j=this->num_index_entries; j>i; j--)
+ this->index[j] = this->index[j-1];
+
+ this->index[i].pts = pts;
+ this->index[i].offset = offset;
+ this->index[i].first_sample = first_sample;
+ this->index[i].last_sample = last_sample;
+ this->index[i].type = type;
+ this->index[i].track = track;
+
+ this->num_index_entries++;
+}
+
+static void demux_qt_index_trak (demux_qt_t *this, quicktime_trak_t *trak, uint32_t type) {
+
+ quicktime_stsz_t *stsz;
+ quicktime_stsc_t *stsc;
+ quicktime_stco_t *stco;
+ quicktime_stts_t *stts;
+ long time_scale;
+ int stsc_entry, stsc_first, stsc_cur, stsc_next;
+ int stsc_samples, stsc_last_sample, stsc_first_sample;
+ int stts_entry, stts_first_sample, stts_last_sample;
+ int64_t stts_duration, stts_pts, pts;
+ off_t chunk_offset;
+
+ stts = &trak->mdia.minf.stbl.stts;
+ stsz = &trak->mdia.minf.stbl.stsz;
+ stsc = &trak->mdia.minf.stbl.stsc;
+ stco = &trak->mdia.minf.stbl.stco;
+ time_scale = trak->mdia.mdhd.time_scale;
+ pts = 0;
+
+ /*
+ * generate one entry per chunk
+ */
+
+ /* chunk-tracking */
+
+ stsc_entry = 0;
+ stsc_first = stsc->table[stsc_entry].chunk;
+ stsc_cur = stsc_first;
+
+ if (stsc->total_entries>(stsc_entry+1))
+ stsc_next = stsc->table[stsc_entry+1].chunk;
+ else
+ stsc_next = 1000000;
+
+ stsc_samples = stsc->table[stsc_entry].samples;
+ stsc_last_sample = stsc_samples-1;
+ stsc_first_sample = 0;
+
+ /* time-to-sample tracking */
+
+ stts_entry = 0;
+ stts_first_sample = 0;
+ stts_last_sample = stts->table[stts_entry].sample_count-1;
+ stts_duration = stts->table[stts_entry].sample_duration * 90000 / time_scale;
+ stts_pts = 0;
+
+ while (stsc_cur < stco->total_entries) {
+
+ printf ("demux_qt: chunk # is %d...\n", stsc_cur);
+
+ chunk_offset = stco->table[stsc_cur-1].offset;
+
+ /*
+ * add index entry
+ */
+
+#ifdef LOG
+ printf ("demux_qt: index entry, sample_num=%d, offset = %lld, sample %d-%d, pts = %lld\n",
+ stsc_first_sample, chunk_offset, stsc_first_sample, stsc_last_sample, pts);
+#endif
+
+ demux_qt_add_index_entry (this, chunk_offset, stsc_first_sample, stsc_last_sample, pts, type,
+ trak);
+
+ /*
+ * next chunk
+ */
+
+ stsc_cur ++;
+
+ /*
+ * offset of chunk / sample
+ */
+
+ while (stsc_cur >= stsc_next) {
+
+ stsc_entry++;
+
+ stsc_first = stsc->table[stsc_entry].chunk;
+
+ if (stsc->total_entries>(stsc_entry+1))
+ stsc_next = stsc->table[stsc_entry+1].chunk;
+ else
+ stsc_next = 1000000;
+
+ stsc_samples = stsc->table[stsc_entry].samples;
+ }
+
+ stsc_first_sample = stsc_last_sample + 1;
+ stsc_last_sample = stsc_first_sample + stsc_samples - 1;
+
+ printf ("demux_qt: chunk offset is %lld...\n", chunk_offset);
+
+
+ /*
+ * find out about pts of sample
+ */
+
+ while (stsc_first_sample > stts_last_sample) {
+
+ stts_pts += stts_duration * stts->table[stts_entry].sample_count;
+ stts_entry++;
+ stts_first_sample = stts_last_sample+1;
+ stts_last_sample += stts->table[stts_entry].sample_count;
+ stts_duration = stts->table[stts_entry].sample_duration * 90000 / time_scale;
+ }
+
+ pts = stts_pts + (stsc_first_sample - stts_first_sample) * stts_duration;
+
+ }
+
+}
+
+static void demux_qt_create_index (demux_qt_t *this) {
+
+ int track_num;
+ quicktime_trak_t *trak;
+
+ this->num_index_entries = 0;
+
+ /* video */
+
+ printf ("demux_qt: generating index, video entries...\n");
+
+ for (track_num = 0; track_num<this->qt->total_vtracks; track_num++) {
+
+ trak = this->qt->vtracks[track_num].track;
+
+ demux_qt_index_trak (this, trak, this->video_type | track_num);
+ }
+
+ /* audio */
+
+ printf ("demux_qt: generating index, audio entries...\n");
+
+ for (track_num = 0; track_num<this->qt->total_atracks; track_num++) {
+
+ trak = this->qt->atracks[track_num].track;
+
+ demux_qt_index_trak (this, trak, this->audio_type | track_num);
+ }
+ printf ("demux_qt: index generation done.\n");
+}
+
static void demux_qt_start (demux_plugin_t *this_gen,
fifo_buffer_t *video_fifo,
fifo_buffer_t *audio_fifo,
@@ -4225,6 +4149,10 @@ static void demux_qt_start (demux_plugin_t *this_gen,
this->audio_fifo = audio_fifo;
this->send_end_buffers = 1;
+#ifdef DBG_QT
+ debug_fh = open ("/tmp/t.mp3", O_CREAT | O_WRONLY | O_TRUNC, 0644);
+#endif
+
/*
* init quicktime parser
*/
@@ -4249,6 +4177,12 @@ static void demux_qt_start (demux_plugin_t *this_gen,
return;
}
+ /*
+ * generate index
+ */
+
+ demux_qt_create_index (this);
+
/*
* send start buffer
*/
@@ -4286,6 +4220,7 @@ static void demux_qt_start (demux_plugin_t *this_gen,
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->content = buf->mem;
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[0] = 0; /* first package, containing bih */
buf->decoder_info[1] = this->video_step;
memcpy (buf->content, &this->bih, sizeof (this->bih));
@@ -4295,6 +4230,8 @@ static void demux_qt_start (demux_plugin_t *this_gen,
this->video_fifo->put (this->video_fifo, buf);
+ printf ("demux_qt: sent buffer %08x\n", buf);
+
if(this->audio_fifo) {
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->content = buf->mem;
@@ -4302,6 +4239,7 @@ static void demux_qt_start (demux_plugin_t *this_gen,
sizeof (this->wavex));
buf->size = sizeof (this->wavex);
buf->type = this->audio_type;
+ buf->decoder_flags = BUF_FLAG_HEADER;
buf->decoder_info[0] = 0; /* first package, containing wavex */
buf->decoder_info[1] = quicktime_sample_rate (this->qt, 0);
buf->decoder_info[2] = quicktime_audio_bits (this->qt, 0);
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 6fea5bdac..ad8d31e39 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.37 2002/02/17 17:32:50 guenter Exp $
+ * $Id: demux_ts.c,v 1.38 2002/03/11 12:31:24 guenter Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -545,7 +545,7 @@ static void demux_ts_buffer_pes(demux_ts *this, unsigned char *ts,
buf->size = m->size;
buf->type = m->type;
buf->pts = m->PTS;
- buf->scr = this->PCR;
+ /* buf->scr = this->PCR; */
buf->decoder_info[0] = 1;
m->fifo->put (m->fifo, buf);
}
@@ -557,7 +557,7 @@ static void demux_ts_buffer_pes(demux_ts *this, unsigned char *ts,
buf->size = len;
buf->type = m->type;
buf->pts = 0;
- buf->scr = 0;
+ /* buf->scr = 0; */
buf->input_pos = this->input->get_current_pos(this->input);
buf->decoder_info[0] = 1;
m->fifo->put (m->fifo, buf);
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c
index 651f6c8eb..cd7c26ee0 100644
--- a/src/dxr3/dxr3_decoder.c
+++ b/src/dxr3/dxr3_decoder.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: dxr3_decoder.c,v 1.64 2002/03/10 21:16:16 miguelfreitas Exp $
+ * $Id: dxr3_decoder.c,v 1.65 2002/03/11 12:31:25 guenter Exp $
*
* dxr3 video and spu decoder plugin. Accepts the video and spu data
* from XINE and sends it directly to the corresponding dxr3 devices.
@@ -972,7 +972,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf)
return;
}
/* Is this also needed for subpicture? */
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
#if LOG_SPU
printf ("dxr3_spu: Dropping SPU channel %d. Preview data\n", stream_id);
#endif
diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c
index 0dbf203e3..530a2c9eb 100644
--- a/src/liba52/xine_decoder.c
+++ b/src/liba52/xine_decoder.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: xine_decoder.c,v 1.17 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.18 2002/03/11 12:31:25 guenter Exp $
*
* stuff needed to turn liba52 into a xine decoder plugin
*/
@@ -265,7 +265,7 @@ static inline void float_to_int (float * _f, int16_t * s16, int num_channels) {
}
}
-static void a52dec_decode_frame (a52dec_decoder_t *this, uint32_t pts, uint32_t scr) {
+static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts) {
int output_mode = AO_CAP_MODE_STEREO;
@@ -380,7 +380,6 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, uint32_t pts, uint32_t
buf->num_frames = 256*6;
buf->vpts = pts;
- buf->scr = scr;
this->audio_out->put_buffer (this->audio_out, buf);
@@ -431,7 +430,6 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, uint32_t pts, uint32_t
buf->num_frames = 1536;
buf->vpts = pts;
- buf->scr = scr;
this->audio_out->put_buffer (this->audio_out, buf);
@@ -447,7 +445,7 @@ void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
uint8_t *end = buf->content + buf->size;
uint8_t byte;
- if (buf->decoder_info[0] == 0)
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW)
return;
/*
@@ -464,7 +462,7 @@ void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
while (current != end) {
if ( (this->sync_todo == 0) && (this->frame_todo == 0) ) {
- a52dec_decode_frame (this, this->pts, buf->scr);
+ a52dec_decode_frame (this, this->pts);
#ifdef DEBUG_A52
write (a52file, this->frame_buffer, this->frame_length);
#endif
diff --git a/src/libdivx4/xine_decoder.c b/src/libdivx4/xine_decoder.c
index 71f97efa7..d5bdaca64 100644
--- a/src/libdivx4/xine_decoder.c
+++ b/src/libdivx4/xine_decoder.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: xine_decoder.c,v 1.18 2002/02/24 17:09:54 f1rmb Exp $
+ * $Id: xine_decoder.c,v 1.19 2002/03/11 12:31:25 guenter Exp $
*
* xine decoder plugin using divx4
*
@@ -60,6 +60,8 @@
#if CATCH_SIGSEGV
#include <signal.h>
+#define LOG
+
/* to be able to restore the old handler */
void (*old_handler)(int);
@@ -333,7 +335,7 @@ static int divx4_can_handle (video_decoder_t *this_gen, int buf_type) {
/* divx4 currently does not support MSMPEG4 v1/v2 */
return ( (buf_type == BUF_VIDEO_MSMPEG4_V3 && this->can_handle_311) ||
/* buf_type == BUF_VIDEO_MSMPEG4_V12 || */
- buf_type == BUF_VIDEO_MPEG4);
+ buf_type == BUF_VIDEO_MPEG4 || buf_type == BUF_VIDEO_3IVX);
}
/* copied verbatim from ffmpeg plugin */
@@ -356,8 +358,17 @@ static void divx4_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
divx4_decoder_t *this = (divx4_decoder_t *) this_gen;
- if (buf->decoder_info[0] == 0) { /* need to initialize */
+#ifdef LOG
+ printf ("divx4: decoding buffer %08x, flags = %08x\n", buf, buf->decoder_flags);
+#endif
+
+ if (buf->decoder_flags & BUF_FLAG_HEADER) { /* need to initialize */
/* only proceed if version is good and initialization succeeded */
+
+#ifdef LOG
+ printf ("divx4: get_version...\n");
+#endif
+
divx4_get_version(this);
this->decoder_ok = ( divx4_check_version(this) &&
divx4_init_decoder(this, buf) );
@@ -391,7 +402,7 @@ static void divx4_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size);
this->size += buf->size;
- if (buf->decoder_info[0] == 2) { /* need to decode a frame */
+ if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* need to decode a frame */
/* allocate image (taken from ffmpeg plugin) */
img = this->video_out->get_frame (this->video_out, this->biWidth,
this->biHeight, XINE_ASPECT_RATIO_DONT_TOUCH,
@@ -525,7 +536,7 @@ video_decoder_t *init_video_decoder_plugin (int iface_version, xine_t *xine) {
"use divx4 plugin for msmpeg4v3 streams",
NULL, NULL, NULL);
this->size = 0;
- /* allow override of version checking by user */
+ /* allow override of version checking by user */
this->version = cfg->register_num(cfg, "codec.divx4_forceversion", 0,
"Divx version to check for (set to 0 (default) if unsure)",
NULL, NULL, NULL);
diff --git a/src/libdts/xine_decoder.c b/src/libdts/xine_decoder.c
index 89b8cf1d2..b45dcf5c8 100644
--- a/src/libdts/xine_decoder.c
+++ b/src/libdts/xine_decoder.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: xine_decoder.c,v 1.14 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.15 2002/03/11 12:31:25 guenter Exp $
*
* 04-09-2001 DTS passtrough (C) Joachim Koenig
* 09-12-2001 DTS passthrough inprovements (C) James Courtier-Dutton
@@ -124,10 +124,8 @@ void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
/* printf("DTS first access unit=%u\n",audio_buffer->first_access_unit); */
if (n == first_access_unit) {
audio_buffer->vpts = buf->pts;
- audio_buffer->scr = buf->scr;
} else {
audio_buffer->vpts = 0;
- audio_buffer->scr = 0;
}
data_out=(uint8_t *) audio_buffer->mem;
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
index 609a60ee7..d1cc5f602 100644
--- a/src/libffmpeg/xine_decoder.c
+++ b/src/libffmpeg/xine_decoder.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2001 the xine project
+ * Copyright (C) 2001-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: xine_decoder.c,v 1.26 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.27 2002/03/11 12:31:25 guenter Exp $
*
* xine decoder plugin using ffmpeg
*
@@ -42,6 +42,10 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/dsputil.h"
+/*
+#define LOG
+*/
+
/* now this is ripped of wine's vfw.h */
typedef struct {
long biSize;
@@ -129,12 +133,12 @@ static void ff_init (video_decoder_t *this_gen, vo_instance_t *video_out) {
static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
ff_decoder_t *this = (ff_decoder_t *) this_gen;
- /*
- printf ("ffmpeg: processing packet type = %08x, buf : %d, buf->decoder_info[0]=%d\n",
- buf->type, buf, buf->decoder_info[0]);
- */
+#ifdef LOG
+ printf ("ffmpeg: processing packet type = %08x, buf : %d, buf->decoder_flags=%08x\n",
+ buf->type, buf, buf->decoder_flags);
+#endif
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
AVCodec *codec = NULL;
int codec_type;
@@ -226,7 +230,7 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
this->size += buf->size;
- if (buf->decoder_info[0] == 2) {
+ if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
vo_frame_t *img;
int got_picture, len, y;
diff --git a/src/liblpcm/xine_decoder.c b/src/liblpcm/xine_decoder.c
index dbff95cda..07c3f8edd 100644
--- a/src/liblpcm/xine_decoder.c
+++ b/src/liblpcm/xine_decoder.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: xine_decoder.c,v 1.19 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.20 2002/03/11 12:31:25 guenter Exp $
*
* 31-8-2001 Added LPCM rate sensing.
* (c) 2001 James Courtier-Dutton James@superbug.demon.co.uk
@@ -89,7 +89,7 @@ void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
int stream_be;
audio_buffer_t *audio_buffer;
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
this->rate=buf->decoder_info[1];
this->bits_per_sample=buf->decoder_info[2] ;
this->number_of_channels=buf->decoder_info[3] ;
@@ -100,7 +100,7 @@ void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
if (!this->output_open) {
/*
* with dvdnav we do not get a preview buffer with audio format
- * information (buf->decoder_info[0] == 0).
+ * information (buf->decoder_flags & BUF_FLAG_PREVIEW).
* grab the audio format from the first audio data buffer, in case
* the audio format is not yet known.
*/
@@ -130,7 +130,6 @@ void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
memcpy (audio_buffer->mem, sample_buffer, buf->size);
audio_buffer->vpts = buf->pts;
- audio_buffer->scr = buf->scr;
audio_buffer->num_frames = (((buf->size*8)/this->number_of_channels)/this->bits_per_sample);
this->audio_out->put_buffer (this->audio_out, audio_buffer);
diff --git a/src/libmad/xine_decoder.c b/src/libmad/xine_decoder.c
index 854057761..15689a2c0 100644
--- a/src/libmad/xine_decoder.c
+++ b/src/libmad/xine_decoder.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: xine_decoder.c,v 1.13 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.14 2002/03/11 12:31:25 guenter Exp $
*
* stuff needed to turn libmad into a xine decoder plugin
*/
@@ -32,6 +32,10 @@
#include "synth.h"
#include "xineutils.h"
+/*
+#define LOG
+*/
+
#define INPUT_BUF_SIZE 16384
typedef struct mad_decoder_s {
@@ -82,7 +86,9 @@ static void mad_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) {
mad_stream_init (&this->stream);
mad_frame_init (&this->frame);
- /* printf ("libmad: init\n"); */
+#ifdef LOG
+ printf ("libmad: init\n");
+#endif
}
@@ -123,9 +129,10 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
mad_decoder_t *this = (mad_decoder_t *) this_gen;
- /*
+
+#ifdef LOG
printf ("libmad: decode data, decoder_info[0]: %d\n", buf->decoder_info[0]);
- */
+#endif
if (buf->size>(INPUT_BUF_SIZE-this->bytes_in_buffer)) {
printf ("libmad: ALERT input buffer too small (%d bytes, %d avail)!\n",
@@ -133,7 +140,7 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
buf->size = INPUT_BUF_SIZE-this->bytes_in_buffer;
}
- if (buf->decoder_info[0] >0) {
+ if ((buf->decoder_flags & BUF_FLAG_HEADER) == 0) {
xine_fast_memcpy (&this->buffer[this->bytes_in_buffer],
buf->content, buf->size);
@@ -177,9 +184,11 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
|| (this->output_sampling_rate != this->frame.header.samplerate)
|| (this->output_mode != mode)) {
+#ifdef LOG
printf ("libmad: audio sample rate %d mode %08x\n",
this->frame.header.samplerate,
mode);
+#endif
if (this->output_open) {
this->audio_out->close (this->audio_out);
@@ -226,14 +235,15 @@ static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
audio_buffer->num_frames = pcm->length;
audio_buffer->vpts = buf->pts;
- audio_buffer->scr = buf->scr;
this->audio_out->put_buffer (this->audio_out, audio_buffer);
buf->pts = 0;
}
- /* printf ("libmad: decode worked\n"); */
+#ifdef LOG
+ printf ("libmad: decode worked\n");
+#endif
}
}
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 68db8b3d5..a8099ef64 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -345,7 +345,6 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame->bad_frame = 1;
picture->current_frame->drawn = 0;
picture->current_frame->pts = mpeg2dec->pts;
- picture->current_frame->scr = mpeg2dec->scr;
picture->current_frame->top_field_first = picture->top_field_first;
picture->current_frame->repeat_first_field = picture->repeat_first_field;
@@ -418,7 +417,7 @@ static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec,
}
int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end,
- uint32_t pts, uint32_t scr)
+ uint64_t pts)
{
int ret;
uint8_t code;
@@ -435,8 +434,6 @@ int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end,
if (pts)
mpeg2dec->pts = pts;
- mpeg2dec->scr = scr;
-
while (current != end) {
code = mpeg2dec->code;
current = copy_chunk (mpeg2dec, current, end);
@@ -521,7 +518,6 @@ void mpeg2_close (mpeg2dec_t * mpeg2dec)
if (picture->backward_reference_frame) {
printf ("libmpeg2: blasting out backward reference frame on close\n");
picture->backward_reference_frame->pts = 0;
- picture->backward_reference_frame->scr = mpeg2dec->scr;
get_frame_duration(mpeg2dec, picture->backward_reference_frame);
if( !picture->backward_reference_frame->drawn)
picture->backward_reference_frame->draw (picture->backward_reference_frame);
@@ -615,7 +611,6 @@ static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer)
event.buffer = &buffer[2];
event.buf_len = end - &buffer[2];
event.pts = mpeg2dec->pts;
- event.scr = mpeg2dec->scr;
xine_send_event(mpeg2dec->xine, &event.event);
}
}
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
index c2ee5f6ec..a0efeaac5 100644
--- a/src/libmpeg2/mpeg2.h
+++ b/src/libmpeg2/mpeg2.h
@@ -43,7 +43,8 @@ typedef struct mpeg2dec_s {
/* last start code ? */
uint8_t code;
- uint32_t pts, scr;
+ int64_t pts;
+ uint32_t last_repeat_first_field;
xine_t *xine;
} mpeg2dec_t ;
@@ -57,7 +58,7 @@ void mpeg2_close (mpeg2dec_t * mpeg2dec);
int mpeg2_decode_data (mpeg2dec_t * mpeg2dec,
uint8_t * data_start, uint8_t * data_end,
- uint32_t pts, uint32_t scr);
+ uint64_t pts);
void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec,
uint8_t * data_start, uint8_t * data_end);
diff --git a/src/libmpeg2/xine_decoder.c b/src/libmpeg2/xine_decoder.c
index 91274771a..d3fadcf7f 100644
--- a/src/libmpeg2/xine_decoder.c
+++ b/src/libmpeg2/xine_decoder.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: xine_decoder.c,v 1.23 2002/02/17 17:32:50 guenter Exp $
+ * $Id: xine_decoder.c,v 1.24 2002/03/11 12:31:26 guenter Exp $
*
* stuff needed to turn libmpeg2 into a xine decoder plugin
*/
@@ -81,12 +81,12 @@ static void mpeg2dec_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
pthread_mutex_lock (&this->lock);
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
mpeg2_find_sequence_header (&this->mpeg2, buf->content, buf->content + buf->size);
} else {
mpeg2_decode_data (&this->mpeg2, buf->content, buf->content + buf->size,
- buf->pts, buf->scr);
+ buf->pts);
}
pthread_mutex_unlock (&this->lock);
diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c
index 13230a8a2..d902a38fb 100644
--- a/src/libspucc/cc_decoder.c
+++ b/src/libspucc/cc_decoder.c
@@ -20,7 +20,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: cc_decoder.c,v 1.6 2002/01/08 20:38:05 cvogler Exp $
+ * $Id: cc_decoder.c,v 1.7 2002/03/11 12:31:26 guenter Exp $
*
* stuff needed to provide closed captioning decoding and display
*
@@ -315,8 +315,7 @@ struct cc_decoder_s {
uint32_t lastcode;
/* The PTS and SCR at which the captioning chunk started */
- uint32_t pts;
- uint32_t scr;
+ int64_t pts;
/* holds the NTSC frame offset to last known pts/scr */
uint32_t f_offset;
@@ -757,11 +756,11 @@ static void ccmem_exit(cc_memory_t *this)
/*----------------- cc_renderer_t methods -------------------------------*/
-static uint32_t cc_renderer_calc_vpts(cc_renderer_t *this, uint32_t pts,
- uint32_t scr, uint32_t ntsc_frame_offset)
+static uint32_t cc_renderer_calc_vpts(cc_renderer_t *this, int64_t pts,
+ uint32_t ntsc_frame_offset)
{
metronom_t *metronom = this->metronom;
- uint32_t vpts = metronom->got_spu_packet(metronom, pts, 0, scr);
+ uint32_t vpts = metronom->got_spu_packet(metronom, pts, 0);
return vpts + ntsc_frame_offset * NTSC_FRAME_DURATION;
}
@@ -773,7 +772,7 @@ static int cc_renderer_on_display(cc_renderer_t *this)
}
-static void cc_renderer_hide_caption(cc_renderer_t *this, uint32_t vpts)
+static void cc_renderer_hide_caption(cc_renderer_t *this, int64_t vpts)
{
if (this->displayed) {
this->osd_renderer->hide(this->cap_display, vpts);
@@ -783,7 +782,7 @@ static void cc_renderer_hide_caption(cc_renderer_t *this, uint32_t vpts)
static void cc_renderer_show_caption(cc_renderer_t *this, cc_buffer_t *buf,
- uint32_t vpts)
+ int64_t vpts)
{
#ifdef LOG_DEBUG
printf("spucc: cc_renderer: show\n");
@@ -960,8 +959,8 @@ static void cc_hide_displayed(cc_decoder_t *this)
#endif
if (cc_renderer_on_display(this->cc_cfg->renderer)) {
- uint32_t vpts = cc_renderer_calc_vpts(this->cc_cfg->renderer, this->pts,
- this->scr, this->f_offset);
+ int64_t vpts = cc_renderer_calc_vpts(this->cc_cfg->renderer, this->pts,
+ this->f_offset);
cc_renderer_hide_caption(this->cc_cfg->renderer, vpts);
}
}
@@ -975,7 +974,7 @@ static void cc_show_displayed(cc_decoder_t *this)
if (cc_onscreen_displayable(this)) {
uint32_t vpts = cc_renderer_calc_vpts(this->cc_cfg->renderer, this->pts,
- this->scr, this->f_offset);
+ this->f_offset);
#ifdef LOG_DEBUG
printf("cc_decoder: cc_show_displayed: showing caption %u at vpts %u\n", this->capid, vpts);
#endif
@@ -1231,7 +1230,7 @@ static void cc_decode_EIA608(cc_decoder_t *this, uint16_t data)
void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len,
- uint32_t pts, uint32_t scr)
+ int64_t pts)
{
/* The first number may denote a channel number. I don't have the
* EIA-708 standard, so it is hard to say.
@@ -1259,7 +1258,6 @@ void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len,
this->f_offset = 0;
this->pts = pts;
- this->scr = scr;
while (curbytes < buf_len) {
cc_code = *current++;
@@ -1324,7 +1322,7 @@ cc_decoder_t *cc_decoder_open(cc_config_t *cc_cfg)
this->lastcode = 0;
this->capid = 0;
- this->pts = this->scr = this->f_offset = 0;
+ this->pts = this->f_offset = 0;
#ifdef LOG_DEBUG
printf("spucc: cc_decoder_open\n");
diff --git a/src/libspucc/cc_decoder.h b/src/libspucc/cc_decoder.h
index b054d8bd4..c741caff7 100644
--- a/src/libspucc/cc_decoder.h
+++ b/src/libspucc/cc_decoder.h
@@ -20,7 +20,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: cc_decoder.h,v 1.3 2002/01/07 23:04:26 cvogler Exp $
+ * $Id: cc_decoder.h,v 1.4 2002/03/11 12:31:26 guenter Exp $
*
* stuff needed to provide closed captioning decoding and display
*
@@ -56,7 +56,7 @@ void cc_decoder_close(cc_decoder_t *this_obj);
void cc_decoder_init(void);
void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len,
- uint32_t pts, uint32_t scr);
+ int64_t pts);
/* Instantiates a new closed captioning renderer. */
cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer,
@@ -69,3 +69,4 @@ void cc_renderer_close(cc_renderer_t *this_obj);
/* Updates the renderer configuration variables */
void cc_renderer_update_cfg(cc_renderer_t *this_obj, int video_width,
int video_height);
+
diff --git a/src/libspucc/xine_decoder.c b/src/libspucc/xine_decoder.c
index cfde5387b..e0db0f2bf 100644
--- a/src/libspucc/xine_decoder.c
+++ b/src/libspucc/xine_decoder.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: xine_decoder.c,v 1.4 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.5 2002/03/11 12:31:26 guenter Exp $
*
* closed caption spu decoder. receive data by events.
*
@@ -267,7 +267,7 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) {
static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spucc_decoder_t *this = (spucc_decoder_t *) this_gen;
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW) {
} else {
pthread_mutex_lock(&this->cc_mutex);
if (this->cc_cfg.cc_enabled) {
@@ -276,7 +276,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if(this->cc_cfg.can_cc) {
decode_cc(this->ccdec, buf->content, buf->size,
- buf->pts, buf->scr);
+ buf->pts);
}
}
pthread_mutex_unlock(&this->cc_mutex);
@@ -321,8 +321,7 @@ static void spudec_event_listener(void *this_gen, xine_event_t *event_gen) {
spucc_do_init (this, NULL);
if (this->cc_cfg.can_cc) {
decode_cc(this->ccdec, closed_caption->buffer,
- closed_caption->buf_len, closed_caption->pts,
- closed_caption->scr);
+ closed_caption->buf_len, closed_caption->pts);
}
}
pthread_mutex_unlock(&this->cc_mutex);
diff --git a/src/libspudec/xine_decoder.c b/src/libspudec/xine_decoder.c
index ee824d9d1..98f8947b5 100644
--- a/src/libspudec/xine_decoder.c
+++ b/src/libspudec/xine_decoder.c
@@ -19,7 +19,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: xine_decoder.c,v 1.56 2002/02/09 07:13:23 guenter Exp $
+ * $Id: xine_decoder.c,v 1.57 2002/03/11 12:31:26 guenter Exp $
*
* stuff needed to turn libspu into a xine decoder plugin
*/
@@ -430,7 +430,7 @@ static void spudec_decode_nav(spudec_decoder_t *this, buf_element_t *buf) {
it yet and we cannot provide correct vpts values. use current_time
instead as an aproximation.
*/
- this->event.vpts = metronom->got_spu_packet(metronom, pci->pci_gi.vobu_s_ptm, 0, 0);
+ this->event.vpts = metronom->got_spu_packet(metronom, pci->pci_gi.vobu_s_ptm, 0);
ovl_instance->add_event(ovl_instance, (void *)&this->event);
} else {
printf("libspudec: No video_overlay handles left for menu\n");
@@ -481,7 +481,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
}
- if (buf->decoder_info[0] == 0) /* skip preview data */
+ if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */
return;
if ( this->spu_stream_state[stream_id].stream_filter == 0)
@@ -489,7 +489,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if (buf->pts) {
metronom_t *metronom = this->xine->metronom;
- uint32_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0, buf->scr);
+ uint32_t vpts = metronom->got_spu_packet(metronom, buf->pts, 0);
if (vpts < this->buf_pts) {
/* FIXME: Don't do this yet,
diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c
index df1b1bdf4..4a941bc26 100644
--- a/src/libsputext/xine_decoder.c
+++ b/src/libsputext/xine_decoder.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: xine_decoder.c,v 1.15 2002/02/27 19:10:37 jkeil Exp $
+ * $Id: xine_decoder.c,v 1.16 2002/03/11 12:31:26 guenter Exp $
*
* code based on mplayer module:
*
@@ -857,7 +857,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
*/
pts_factor = 3000;
- pts += this->xine->metronom->video_wrap_offset;
+ pts += this->xine->metronom->vpts_offset;
pts_end = pts + (subtitle->end - subtitle->start) * pts_factor;
@@ -888,7 +888,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
if (subtitle->start > (start_tenth+20))
return;
- pts += this->xine->metronom->video_wrap_offset;
+ pts += this->xine->metronom->vpts_offset;
pts_end = pts + (subtitle->end - subtitle->start)*900;
}
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index 3c9dacd51..352f43ac1 100644
--- a/src/libw32dll/w32codec.c
+++ b/src/libw32dll/w32codec.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: w32codec.c,v 1.63 2002/02/09 07:13:24 guenter Exp $
+ * $Id: w32codec.c,v 1.64 2002/03/11 12:31:26 guenter Exp $
*
* routines for using w32 codecs
* DirectShow support by Miguel Freitas (Nov/2001)
@@ -128,7 +128,6 @@ typedef struct w32a_decoder_s {
unsigned char *buf;
int size;
int64_t pts;
- int64_t scr;
/* these are used for pts estimation */
int64_t lastpts, sumpts, sumsize;
@@ -575,7 +574,7 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
buf->decoder_info[0]=%d\n",
buf->type, buf, buf->decoder_info[0]);
*/
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
if ( buf->type & 0xff )
return;
@@ -618,7 +617,7 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
this->size += buf->size;
- if (buf->decoder_info[0] == 2) {
+ if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
HRESULT ret;
vo_frame_t *img;
@@ -719,7 +718,6 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
}
img->pts = buf->pts;
- img->scr = buf->scr;
if(ret || this->skipframes) {
if( !this->skipframes )
printf("w32codec: Error decompressing frame, err=%ld\n", (long)ret);
@@ -977,8 +975,7 @@ static void w32a_decode_audio (w32a_decoder_t *this,
unsigned char *data,
uint32_t size,
int frame_end,
- int64_t pts,
- int64_t scr) {
+ int64_t pts) {
static ACMSTREAMHEADER ash;
HRESULT hr;
@@ -989,10 +986,9 @@ static void w32a_decode_audio (w32a_decoder_t *this,
issues with some streams.
*/
- /* buffer empty -> take pts/scr from package */
+ /* buffer empty -> take pts from package */
if( !this->size ) {
this->pts = pts;
- this->scr = scr;
/*
printf("w32codec: resync pts (%d)\n",this->pts);
*/
@@ -1006,7 +1002,6 @@ static void w32a_decode_audio (w32a_decoder_t *this,
/* force resync every 4 seconds */
if( this->sumpts >= 4 * 90000 && pts ) {
this->pts = pts - this->size * this->sumpts / this->sumsize;
- this->scr = scr - this->size * this->sumpts / this->sumsize;
/*
printf("w32codec: estimated resync pts (%d)\n",this->pts);
*/
@@ -1090,11 +1085,10 @@ static void w32a_decode_audio (w32a_decoder_t *this,
*/
audio_buffer->num_frames = bufsize / (this->num_channels*2);
audio_buffer->vpts = this->pts;
- audio_buffer->scr = this->scr;
this->audio_out->put_buffer (this->audio_out, audio_buffer);
- this->pts = this->scr = 0;
+ this->pts = 0;
DstLengthUsed -= bufsize;
p += bufsize;
}
@@ -1119,7 +1113,7 @@ static void w32a_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
w32a_decoder_t *this = (w32a_decoder_t *) this_gen;
- if (buf->decoder_info[0] == 0) {
+ if (buf->decoder_flags & BUF_FLAG_HEADER) {
/* init package containing bih */
this->decoder_ok = w32a_init_audio (this, (WAVEFORMATEX *)buf->content, buf->type);
@@ -1128,8 +1122,8 @@ static void w32a_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
return;
w32a_decode_audio (this, buf->content, buf->size,
- buf->decoder_info[0]==2,
- buf->pts, buf->scr);
+ buf->decoder_flags & BUF_FLAG_FRAME_END,
+ buf->pts);
}
}
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index f329db056..2e4c9f5c8 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: audio_decoder.c,v 1.63 2002/03/10 21:43:30 miguelfreitas Exp $
+ * $Id: audio_decoder.c,v 1.64 2002/03/11 12:31:26 guenter Exp $
*
*
* functions that implement audio decoding
@@ -84,7 +84,7 @@ void *audio_decoder_loop (void *this_gen) {
this->audio_finished = 0;
pthread_mutex_unlock (&this->finished_lock);
- this->metronom->expect_audio_discontinuity (this->metronom);
+ this->metronom->audio_stream_start (this->metronom);
break;
@@ -98,7 +98,7 @@ void *audio_decoder_loop (void *this_gen) {
pthread_mutex_lock (&this->finished_lock);
- if (!this->audio_finished && (buf->decoder_info[0]==0)) {
+ if (!this->audio_finished && (buf->decoder_flags==BUF_FLAG_END_USER)) {
this->audio_finished = 1;
if (this->video_finished) {
@@ -131,7 +131,7 @@ void *audio_decoder_loop (void *this_gen) {
case BUF_CONTROL_DISCONTINUITY:
printf ("audio_decoder: discontinuity ahead\n");
- this->metronom->expect_audio_discontinuity (this->metronom);
+ this->metronom->expect_audio_discontinuity (this->metronom, buf->disc_off);
break;
case BUF_CONTROL_AUDIO_CHANNEL:
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 2c0bd80d4..56f777469 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.43 2002/03/01 09:29:50 guenter Exp $
+ * $Id: audio_out.c,v 1.44 2002/03/11 12:31:26 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -474,7 +474,7 @@ static void ao_put_buffer (ao_instance_t *this, audio_buffer_t *buf) {
pts = buf->vpts;
buf->vpts = this->metronom->got_audio_samples (this->metronom, pts,
- buf->num_frames, buf->scr);
+ buf->num_frames);
#ifdef LOG
printf ("audio_out: got buffer, pts=%lld, vpts=%lld\n",
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index d864be464..dd820a6f4 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -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: audio_out.h,v 1.24 2002/02/17 17:32:50 guenter Exp $
+ * $Id: audio_out.h,v 1.25 2002/03/11 12:31:26 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -137,7 +137,6 @@ struct audio_buffer_s {
int num_frames;
int64_t vpts;
- int64_t scr;
uint32_t frame_header_count;
uint32_t first_access_unit;
};
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index 995249a43..5444d78d5 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000-2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: buffer.h,v 1.34 2002/03/01 09:29:50 guenter Exp $
+ * $Id: buffer.h,v 1.35 2002/03/11 12:31:26 guenter Exp $
*
*
* contents:
@@ -98,6 +98,7 @@ extern "C" {
#define BUF_VIDEO_REAL 0x02170000
#define BUF_VIDEO_VP31 0x02180000
#define BUF_VIDEO_H263 0x02190000
+#define BUF_VIDEO_3IVX 0x021A0000
/* audio buffer types: (please keep in sync with buffer_types.c) */
@@ -139,15 +140,18 @@ struct buf_element_s {
buf_element_t *next;
unsigned char *mem;
- unsigned char *content; /* start of raw content in pMem (without header etc) */
+ unsigned char *content; /* start of raw content in mem (without header etc) */
- int32_t size ; /* size of _content_ */
- int32_t max_size;
+ int32_t size ; /* size of _content_ */
+ int32_t max_size; /* size of pre-allocated memory pointed to by "mem" */
uint32_t type;
- int64_t pts; /* presentation time stamp, used for a/v sync */
- int64_t scr; /* system clock reference, used for discont. detection */
+ int64_t pts; /* presentation time stamp, used for a/v sync */
+ int64_t disc_off; /* discontinuity offset */
off_t input_pos; /* remember where this buf came from in the input source */
int input_time;/* time offset in seconds from beginning of stream */
+
+ uint32_t decoder_flags; /* stuff like keyframe, is_header ... see below */
+
uint32_t decoder_info[4]; /* additional decoder flags and other dec-spec. stuff */
void (*free_buffer) (buf_element_t *buf);
@@ -157,6 +161,14 @@ struct buf_element_s {
} ;
+#define BUF_FLAG_KEYFRAME 0x0001
+#define BUF_FLAG_FRAME_START 0x0002
+#define BUF_FLAG_FRAME_END 0x0004
+#define BUF_FLAG_HEADER 0x0008
+#define BUF_FLAG_PREVIEW 0x0010
+#define BUF_FLAG_END_USER 0x0020
+#define BUF_FLAG_END_STREAM 0x0040
+
typedef struct fifo_buffer_s fifo_buffer_t;
struct fifo_buffer_s
{
diff --git a/src/xine-engine/buffer_types.c b/src/xine-engine/buffer_types.c
index f9b66892f..fab61fa2f 100644
--- a/src/xine-engine/buffer_types.c
+++ b/src/xine-engine/buffer_types.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: buffer_types.c,v 1.10 2002/02/09 07:13:24 guenter Exp $
+ * $Id: buffer_types.c,v 1.11 2002/03/11 12:31:26 guenter Exp $
*
*
* contents:
@@ -123,7 +123,6 @@ static video_db_t video_db[] = {
mmioFOURCC('d', 'i', 'v', '5'),
mmioFOURCC('D', 'I', 'V', '6'),
mmioFOURCC('d', 'i', 'v', '6'),
- mmioFOURCC('3', 'I', 'V', '1'),
mmioFOURCC('A', 'P', '4', '1'),
mmioFOURCC('M', 'P', 'G', '3'),
0
@@ -133,6 +132,14 @@ static video_db_t video_db[] = {
},
{
{
+ mmioFOURCC('3', 'I', 'V', '1'),
+ 0
+ },
+ BUF_VIDEO_3IVX,
+ "3ivx MPEG-4"
+},
+{
+ {
mmioFOURCC('d', 'm', 'b', '1'),
mmioFOURCC('M', 'J', 'P', 'G'),
mmioFOURCC('m', 'j', 'p', 'a'),
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index b578ea5cf..e54bbca1c 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: metronom.c,v 1.64 2002/03/10 21:16:15 miguelfreitas Exp $
+ * $Id: metronom.c,v 1.65 2002/03/11 12:31:26 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -253,7 +253,7 @@ static void metronom_set_audio_rate (metronom_t *this, int64_t pts_per_smpls) {
}
static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts,
- int64_t duration, int64_t scr ) {
+ int64_t duration) {
int64_t vpts;
pthread_mutex_lock (&this->lock);
@@ -265,47 +265,30 @@ static int64_t metronom_got_spu_packet (metronom_t *this, int64_t pts,
this->spu_vpts=this->spu_vpts;
}
- /*
- It happens with the dxr3 that got_spu_packet is called before
- got_video_frame. Since video_wrap_offset is zero until then,
- the return value would be wrong. In this case zero is returned.
-
- Also this->video_discontinuity means that scr discontinuity was
- detected but this->video_wrap_offset not updated (would give
- wrong values too).
- */
- if ( this->video_discontinuity ) {
- /* we can safely use audio_wrap_offset if already updated */
- if( !this->audio_discontinuity ) {
- vpts = pts + this->audio_wrap_offset;
- } else {
- vpts = 0;
- }
- } else {
- vpts = pts + this->video_wrap_offset;
+ if ( !this->in_discontinuity ) {
+ vpts = pts + this->vpts_offset;
+ } else {
+ vpts = 0;
}
pthread_mutex_unlock (&this->lock);
return vpts;
}
-static void metronom_expect_video_discontinuity (metronom_t *this, int starting) {
+static void metronom_handle_video_discontinuity (metronom_t *this, int is_stream_start,
+ int64_t disc_off) {
pthread_mutex_lock (&this->lock);
- this->video_starting = starting;
-
- this->video_discontinuity = 10;
-
this->video_discontinuity_count++;
pthread_cond_signal (&this->video_discontinuity_reached);
printf ("metronom: video discontinuity #%d\n",
this->video_discontinuity_count);
- if( this->have_audio ) {
- while ( this->audio_discontinuity_count <
- this->video_discontinuity_count ) {
+ if (this->have_audio) {
+ while (this->audio_discontinuity_count <
+ this->video_discontinuity_count) {
printf ("metronom: waiting for audio discontinuity #%d\n",
this->video_discontinuity_count);
@@ -313,145 +296,89 @@ static void metronom_expect_video_discontinuity (metronom_t *this, int starting)
pthread_cond_wait (&this->audio_discontinuity_reached, &this->lock);
}
- if ( this->video_vpts < this->audio_vpts ) {
+ if (this->video_vpts < this->audio_vpts) {
this->video_vpts = this->audio_vpts;
printf ("metronom: video vpts adjusted to %lld\n", this->video_vpts);
}
}
-
+
+ if (this->in_discontinuity)
+ this->vpts_offset = this->next_vpts_offset;
+
+ if (is_stream_start) {
+ this->vpts_offset = this->video_vpts;
+ } else {
+ this->next_vpts_offset = this->vpts_offset - disc_off;
+ this->in_discontinuity = 30;
+ }
pthread_mutex_unlock (&this->lock);
}
+static void metronom_video_stream_start (metronom_t *this) {
+ metronom_handle_video_discontinuity (this, 1, 0);
+}
+
+static void metronom_expect_video_discontinuity (metronom_t *this, int64_t disc_off) {
+ metronom_handle_video_discontinuity (this, 0, disc_off);
+}
+
static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
int64_t vpts;
int64_t pts = img->pts;
int64_t duration = img->duration;
- int pts_discontinuity = 0;
pthread_mutex_lock (&this->lock);
-
- /* check for pts discontinuities against the predicted pts value */
- if (pts && this->last_video_pts) {
-
- int64_t diff, predicted_pts;
-
- predicted_pts = this->last_video_pts + duration;
-
- diff = pts - predicted_pts;
-
-#ifdef LOG
- printf ("metronom: got video pts %lld, predicted %lld (= %lld + %lld) => diff %lld\n",
- pts, predicted_pts, this->last_video_pts, duration, diff);
-#endif
-
- if ( abs (diff) > WRAP_THRESHOLD ) {
- pts_discontinuity = 1;
-
-#ifdef LOG
- printf ("metronom: this is a video discontinuity\n");
-#endif
+ if (this->in_discontinuity) {
+ this->in_discontinuity--;
- /*
- * ignore discontinuities created by frame reordering around
- * the REAL discontinuity. :)
- */
- if( !this->video_discontinuity ) {
- pts = 0;
-#ifdef LOG
- printf ("metronom: not expecting a video discontinuity => ignored\n");
-#endif
- }
- }
+ if (!this->in_discontinuity)
+ this->vpts_offset = this->next_vpts_offset;
+ else
+ pts = 0; /* ignore pts during discontinuities */
}
if (pts) {
+ int64_t diff;
+
/*
- * check if there was any pending SCR discontinuity (video_discontinuity
- * is set from the decoder loop) together with pts discont.
+ * compare predicted (this->video_vpts) and given (pts+vpts_offset)
+ * pts values - hopefully they will be the same
+ * if not, for small diffs try to interpolate
+ * for big diffs: jump
*/
- if ( this->video_discontinuity &&
- (pts_discontinuity || this->video_starting) ) {
- this->video_starting = 0;
- this->video_discontinuity = 0;
- this->wrap_diff_counter = 0;
-
- this->video_wrap_offset = this->video_vpts - pts;
-
- vpts = pts + this->video_wrap_offset;
-
- printf ("metronom: video pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n",
- pts, this->video_wrap_offset, vpts);
-
- } else {
-
- int64_t diff;
-
- /*
- * audio and video wrap are not allowed to differ for too long
- */
-
- if ( this->have_audio
- && (this->video_wrap_offset != this->audio_wrap_offset) ){
+
+ vpts = pts + this->vpts_offset;
- this->wrap_diff_counter++;
-
- if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) {
-
- printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)",
- this->video_wrap_offset, this->audio_wrap_offset);
-
- if (this->video_wrap_offset > this->audio_wrap_offset)
- this->audio_wrap_offset = this->video_wrap_offset;
- else
- this->video_wrap_offset = this->audio_wrap_offset;
-
- printf (" to %lld\n", this->video_wrap_offset);
-
- this->wrap_diff_counter = 0;
- }
- }
-
- /*
- * compare predicted (this->video_vpts) and given (pts+wrap_offset)
- * pts values - hopefully they will be the same
- * if not, for small diffs try to interpolate
- * for big diffs: jump
- */
-
- vpts = pts + this->video_wrap_offset;
-
- diff = this->video_vpts - vpts;
+ diff = this->video_vpts - vpts;
#ifdef LOG
- printf ("metronom: video diff is %lld (predicted %lld, given %lld)\n",
- diff, this->video_vpts, vpts);
+ printf ("metronom: video diff is %lld (predicted %lld, given %lld)\n",
+ diff, this->video_vpts, vpts);
#endif
- if (abs (diff) > VIDEO_DRIFT_TOLERANCE) {
+ if (abs (diff) > VIDEO_DRIFT_TOLERANCE) {
- this->video_vpts = vpts;
- this->video_drift = 0;
+ this->video_vpts = vpts;
+ this->video_drift = 0;
#ifdef LOG
- printf ("metronom: video jump, ignoring predicted vpts\n");
+ printf ("metronom: video jump\n");
#endif
- } else if (diff) {
+ } else if (diff) {
- this->video_drift = diff / 30;
+ this->video_drift = diff;
#ifdef LOG
- printf ("metronom: video drift, compensation will be %lld pts/frame\n",
- this->video_drift);
+ printf ("metronom: video drift, drift is %lld\n", this->video_drift);
#endif
- }
}
-
- this->last_video_pts = pts;
- } else
- this->last_video_pts = this->video_vpts - this->video_wrap_offset;
+ }
+
+ this->video_vpts -= this->video_drift / 30;
+ this->video_drift -= this->video_drift / 30;
img->vpts = this->video_vpts + this->av_offset;
@@ -459,18 +386,16 @@ static void metronom_got_video_frame (metronom_t *this, vo_frame_t *img) {
printf ("metronom: video vpts for %10lld : %10lld (duration:%lld)\n",
pts, this->video_vpts, duration);
#endif
-
- this->video_vpts += duration - this->video_drift;
- img->duration -= this->video_drift;
+
+ this->video_vpts += duration;
pthread_mutex_unlock (&this->lock);
}
-static void metronom_expect_audio_discontinuity (metronom_t *this) {
+static void metronom_expect_audio_discontinuity (metronom_t *this, int64_t disc_off) {
pthread_mutex_lock (&this->lock);
- this->audio_discontinuity = 10;
this->audio_discontinuity_count++;
pthread_cond_signal (&this->audio_discontinuity_reached);
@@ -487,120 +412,40 @@ static void metronom_expect_audio_discontinuity (metronom_t *this) {
}
if ( this->audio_vpts < this->video_vpts ) {
- this->audio_vpts = this->video_vpts;
+ this->audio_vpts = this->video_vpts;
printf ("metronom: audio vpts adjusted to %lld\n", this->audio_vpts);
}
-
- /* this->num_audio_samples_guessed = 1; */
- /* this->last_audio_pts = this->audio_vpts - this->audio_wrap_offset; */
+
+ /* next_vpts_offset, in_discontinuity is handled in expect_video_discontinuity */
pthread_mutex_unlock (&this->lock);
}
+static void metronom_audio_stream_start (metronom_t *this) {
+ metronom_expect_audio_discontinuity (this, 0);
+}
static int64_t metronom_got_audio_samples (metronom_t *this, int64_t pts,
- int nsamples, int64_t scr) {
+ int nsamples) {
int64_t vpts;
#ifdef LOG
- printf ("metronom: got %d audio samples, pts is %lld, last_pts is %lld, diff = %lld\n",
- nsamples, pts, this->last_audio_pts, pts - this->last_audio_pts);
- printf ("metronom: audio wrap offset is %lld\n", this->audio_wrap_offset);
+ printf ("metronom: got %d audio samples, pts is %lld\n", nsamples, pts);
#endif
pthread_mutex_lock (&this->lock);
-#if 0
- if (this->audio_discontinuity && this->video_discontinuity) {
-
- /* this is needed to take care of still frame with no audio
- were vpts are not updated.
- we can only do it here because audio and video decoder threads
- have just been synced */
- if ( this->audio_vpts < metronom_get_current_time(this) ) {
- this->audio_vpts = metronom_get_current_time(this) + PREBUFFER_PTS_OFFSET;
- this->video_vpts = this->audio_vpts;
- printf ("metronom: audio/video vpts too old, adjusted to %lld\n",
- this->audio_vpts);
- }
- }
-#endif
-
+ if (this->in_discontinuity)
+ pts = 0; /* ignore pts during discontinuities */
+
if (pts) {
-
- /*
- * discontinuity ?
- */
- if ( this->audio_discontinuity ) {
- this->audio_discontinuity = 0;
- this->wrap_diff_counter = 0;
-
- this->audio_wrap_offset = this->audio_vpts - pts ;
-
- /*
- * this->num_audio_samples_guessed
- * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM ;
- */
-
- vpts = pts + this->audio_wrap_offset;
-
- printf ("metronom: audio pts discontinuity/start, pts is %lld, wrap_offset is %lld, vpts is %lld\n",
- pts, this->audio_wrap_offset, vpts);
-
-
- } else {
-
- /*
- * audio and video wrap are not allowed to differ
- * for too long
- */
-
- if ( this->video_wrap_offset != this->audio_wrap_offset ) {
- this->wrap_diff_counter++;
-
- if (this->wrap_diff_counter > MAX_NUM_WRAP_DIFF) {
-
- printf ("metronom: forcing video_wrap (%lld) and audio wrap (%lld)",
- this->video_wrap_offset, this->audio_wrap_offset);
-
- if (this->video_wrap_offset > this->audio_wrap_offset)
- this->audio_wrap_offset = this->video_wrap_offset;
- else
- this->video_wrap_offset = this->audio_wrap_offset;
-
- printf ("to %lld\n", this->video_wrap_offset);
-
- this->wrap_diff_counter = 0;
- }
- }
-
- vpts = pts + this->audio_wrap_offset;
-
- /*
- * calc delta to compensate wrong samplerates
- */
-
- if (this->last_audio_pts && (pts>this->last_audio_pts)) {
- int32_t vpts_diff;
-
- vpts_diff = vpts - this->audio_vpts;
-
- this->audio_pts_delta += vpts_diff*AUDIO_SAMPLE_NUM / (this->num_audio_samples_guessed);
-
- if (abs(this->audio_pts_delta) >= MAX_AUDIO_DELTA)
- this->audio_pts_delta = 0;
- }
- }
-
- this->num_audio_samples_guessed = 0;
- this->last_audio_pts = pts;
- this->audio_vpts = vpts;
+ vpts = pts + this->vpts_offset;
+ this->audio_vpts = vpts;
} else
vpts = this->audio_vpts;
- this->audio_vpts += nsamples * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM;
- this->num_audio_samples_guessed += nsamples;
+ this->audio_vpts += nsamples * this->pts_per_smpls / AUDIO_SAMPLE_NUM;
#ifdef LOG
printf ("metronom: audio vpts for %10lld : %10lld\n", pts, vpts);
@@ -734,6 +579,8 @@ metronom_t * metronom_init (int have_audio, void *xine) {
this->got_video_frame = metronom_got_video_frame;
this->got_audio_samples = metronom_got_audio_samples;
this->got_spu_packet = metronom_got_spu_packet;
+ this->audio_stream_start = metronom_audio_stream_start;
+ this->video_stream_start = metronom_video_stream_start;
this->expect_audio_discontinuity = metronom_expect_audio_discontinuity;
this->expect_video_discontinuity = metronom_expect_video_discontinuity;
this->set_av_offset = metronom_set_av_offset;
@@ -759,47 +606,26 @@ metronom_t * metronom_init (int have_audio, void *xine) {
printf ("metronom: cannot create sync thread (%s)\n",
strerror(err));
- pthread_cond_init (&this->video_discontinuity_reached, NULL);
- pthread_cond_init (&this->audio_discontinuity_reached, NULL);
-
- this->av_offset = 0;
-
+ this->av_offset = 0;
+ this->in_discontinuity = 0;
+ this->vpts_offset = 0;
+ this->next_vpts_offset = 0;
/* initialize video stuff */
- this->have_audio = have_audio;
this->video_vpts = PREBUFFER_PTS_OFFSET;
-
- this->last_video_pts = 0;
this->video_drift = 0;
-
- this->video_wrap_offset = PREBUFFER_PTS_OFFSET;
- this->wrap_diff_counter = 0;
-
- this->video_discontinuity = 0;
this->video_discontinuity_count = 0;
+ pthread_cond_init (&this->video_discontinuity_reached, NULL);
/* initialize audio stuff */
+ this->have_audio = have_audio;
this->audio_vpts = PREBUFFER_PTS_OFFSET;
-
- this->audio_pts_delta = 0;
-
- this->num_audio_samples_guessed = 1;
- this->last_audio_pts = 0;
-
- this->audio_wrap_offset = PREBUFFER_PTS_OFFSET;
- this->wrap_diff_counter = 0;
-
- this->audio_discontinuity = 0;
this->audio_discontinuity_count = 0;
+ pthread_cond_init (&this->audio_discontinuity_reached, NULL);
+
return this;
}
-
-
-
-
-
-
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
index dd0cd703d..5ad28dcb2 100644
--- a/src/xine-engine/metronom.h
+++ b/src/xine-engine/metronom.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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: metronom.h,v 1.20 2002/03/10 21:16:15 miguelfreitas Exp $
+ * $Id: metronom.h,v 1.21 2002/03/11 12:31:26 guenter Exp $
*
* metronom: general pts => virtual calculation/assoc
*
@@ -58,8 +58,7 @@ typedef struct scr_plugin_s scr_plugin_t;
struct metronom_s {
/*
- * Pointer to current xine object. We use a void pointer to avoid type declaration clash.
- * Ugly but working.
+ * pointer to current xine object. a void pointer is used to avoid type declaration clash.
*/
void *xine;
@@ -90,7 +89,6 @@ struct metronom_s {
*
* parameter pts : pts for audio data if known, 0 otherwise
* nsamples : number of samples delivered
- * scr : system clock reference, may be 0 or == pts if unknown
*
* return value: virtual pts for audio data
*
@@ -100,21 +98,19 @@ struct metronom_s {
*/
int64_t (*got_audio_samples) (metronom_t *this, int64_t pts,
- int nsamples, int64_t scr);
+ int nsamples);
/*
* called by SPU decoder whenever a packet is delivered to it
*
* parameter pts : pts for SPU packet if known, 0 otherwise
- * scr : system clock reference, may be 0 or == pts if unknown
*
* return value: virtual pts for SPU packet
* (this is the only pts to vpts function that cannot update the wrap_offset
* due to the lack of regularity on spu packets)
*/
- int64_t (*got_spu_packet) (metronom_t *this, int64_t pts, int64_t duration,
- int64_t scr);
+ int64_t (*got_spu_packet) (metronom_t *this, int64_t pts, int64_t duration);
/*
* tell metronom about discontinuities.
@@ -136,8 +132,11 @@ struct metronom_s {
* whenever we get a new pts we can calculate the new xxx_wrap_offset)
*
*/
- void (*expect_audio_discontinuity) (metronom_t *this);
- void (*expect_video_discontinuity) (metronom_t *this, int starting);
+ void (*expect_audio_discontinuity) (metronom_t *this, int64_t disc_off);
+ void (*expect_video_discontinuity) (metronom_t *this, int64_t disc_off);
+
+ void (*audio_stream_start) (metronom_t *this);
+ void (*video_stream_start) (metronom_t *this);
/*
* manually correct audio <-> video sync
@@ -203,21 +202,16 @@ struct metronom_s {
int64_t pts_per_smpls;
- int64_t audio_pts_delta;
-
int64_t video_vpts;
int64_t spu_vpts;
int64_t audio_vpts;
- int64_t video_wrap_offset;
- int64_t audio_wrap_offset;
- int wrap_diff_counter;
+ int64_t vpts_offset;
+ int64_t next_vpts_offset;
- int64_t last_video_pts;
- int64_t video_drift;
+ int in_discontinuity;
- int64_t last_audio_pts;
- int num_audio_samples_guessed;
+ int64_t video_drift;
int64_t av_offset;
@@ -228,10 +222,7 @@ struct metronom_s {
pthread_mutex_t lock;
int have_audio;
- int video_starting;
- int video_discontinuity;
int video_discontinuity_count;
- int audio_discontinuity;
int audio_discontinuity_count;
pthread_cond_t video_discontinuity_reached;
pthread_cond_t audio_discontinuity_reached;
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
index d5b1f9d4c..cd8e14142 100644
--- a/src/xine-engine/video_decoder.c
+++ b/src/xine-engine/video_decoder.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: video_decoder.c,v 1.75 2002/03/10 21:16:14 miguelfreitas Exp $
+ * $Id: video_decoder.c,v 1.76 2002/03/11 12:31:26 guenter Exp $
*
*/
@@ -106,7 +106,7 @@ void *video_decoder_loop (void *this_gen) {
pthread_mutex_unlock (&this->finished_lock);
- this->metronom->expect_video_discontinuity (this->metronom, 1);
+ this->metronom->video_stream_start (this->metronom);
break;
@@ -155,7 +155,7 @@ void *video_decoder_loop (void *this_gen) {
pthread_mutex_lock (&this->finished_lock);
this->spu_finished = 1;
- if (!this->video_finished && (buf->decoder_info[0]==0)) {
+ if (!this->video_finished && (buf->decoder_flags==BUF_FLAG_END_STREAM)) {
this->video_finished = 1;
@@ -186,7 +186,7 @@ void *video_decoder_loop (void *this_gen) {
this->video_in_discontinuity = 1;
- this->metronom->expect_video_discontinuity (this->metronom, 0);
+ this->metronom->expect_video_discontinuity (this->metronom, buf->disc_off);
this->video_in_discontinuity = 0;
break;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 1e8216a5f..691700e91 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.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: xine.c,v 1.105 2002/03/01 09:29:50 guenter Exp $
+ * $Id: xine.c,v 1.106 2002/03/11 12:31:26 guenter Exp $
*
* top-level xine functions
*
@@ -892,6 +892,8 @@ void xine_log (xine_t *this, int buf, const char *format, ...) {
this->log_buffers[buf]->scratch_printf (this->log_buffers[buf], format, argp);
+ vprintf (format, argp);
+
va_end (argp);
}