summaryrefslogtreecommitdiff
path: root/src/demuxers
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers')
-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
11 files changed, 804 insertions, 858 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);