summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Stembridge <jstembridge@users.sourceforge.net>2003-05-25 20:24:19 +0000
committerJames Stembridge <jstembridge@users.sourceforge.net>2003-05-25 20:24:19 +0000
commit8514c2d873c59ff075ed581b4be5798cf1588c97 (patch)
treec0581a222318d4d6fccf7e1a32a705026ddd29c1
parent88a8ede498eb1c45d88a149fa448d4b3c73041d8 (diff)
downloadxine-lib-8514c2d873c59ff075ed581b4be5798cf1588c97.tar.gz
xine-lib-8514c2d873c59ff075ed581b4be5798cf1588c97.tar.bz2
add support for seeking
CVS patchset: 4937 CVS date: 2003/05/25 20:24:19
-rw-r--r--src/demuxers/demux_real.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 8e8bd5164..be6f38874 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -28,7 +28,7 @@
*
* Based on FFmpeg's libav/rm.c.
*
- * $Id: demux_real.c,v 1.51 2003/05/25 14:53:27 jstembridge Exp $
+ * $Id: demux_real.c,v 1.52 2003/05/25 20:24:19 jstembridge Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -85,9 +85,9 @@ typedef struct {
} real_packet;
typedef struct {
- int timestamp;
- int offset;
- int packetno;
+ unsigned int timestamp;
+ unsigned int offset;
+ unsigned int packetno;
} real_index_entry_t;
typedef struct {
@@ -119,6 +119,7 @@ typedef struct {
uint32_t audio_buf_type;
real_index_entry_t *audio_index;
int audio_index_entries;
+ int audio_need_keyframe;
unsigned int current_data_chunk_packet_count;
unsigned int next_data_chunk_offset;
@@ -221,7 +222,11 @@ static void real_parse_index(demux_real_t *this) {
this->input->seek(this->input, next_index_chunk, SEEK_SET);
/* Read index chunk header */
- this->input->read(this->input, index_chunk_header, INDEX_CHUNK_HEADER_SIZE);
+ if(this->input->read(this->input, index_chunk_header, INDEX_CHUNK_HEADER_SIZE)
+ != INDEX_CHUNK_HEADER_SIZE) {
+ printf("demux_real: index chunk header not read\n");
+ break;
+ }
/* Check chunk is actually an index chunk */
if(BE_32(&index_chunk_header[0]) == INDX_TAG) {
@@ -267,7 +272,13 @@ static void real_parse_index(demux_real_t *this) {
/* Read index */
for(i = 0; i < entries; i++) {
- this->input->read(this->input, index_record, INDEX_RECORD_SIZE);
+ if(this->input->read(this->input, index_record, INDEX_RECORD_SIZE)
+ != INDEX_RECORD_SIZE) {
+ printf("demux_real: index record not read\n");
+ free(*index);
+ *index = NULL;
+ break;
+ }
(*index)[i].timestamp = BE_32(&index_record[2]);
(*index)[i].offset = BE_32(&index_record[6]);
@@ -696,10 +707,9 @@ static void real_parse_headers (demux_real_t *this) {
}
}
-#if 0
+
if((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0)
real_parse_index(this);
-#endif
}
@@ -1041,6 +1051,11 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
printf ("demux_real: audio chunk detected.\n");
#endif
+ if(this->audio_need_keyframe && !keyframe)
+ goto discard;
+ else
+ this->audio_need_keyframe = 0;
+
buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
buf->content = buf->mem;
@@ -1074,6 +1089,7 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) {
#ifdef LOG
printf ("demux_real: chunk not detected; discarding.\n");
#endif
+discard:
this->input->seek(this->input, size, SEEK_CUR);
}
@@ -1160,16 +1176,47 @@ static void demux_real_send_headers(demux_plugin_t *this_gen) {
static int demux_real_seek (demux_plugin_t *this_gen,
off_t start_pos, int start_time) {
- demux_real_t *this = (demux_real_t *) this_gen;
-
- /* if thread is not running, initialize demuxer */
- if( !this->stream->demux_thread_running ) {
-
- /* send new pts */
-/* xine_demux_control_newpts(this->stream, 0, 0);
-*/
-
- this->status = DEMUX_OK;
+ demux_real_t *this = (demux_real_t *) this_gen;
+ real_index_entry_t *index, *other_index;
+ int i = 0, entries;
+
+ if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) &&
+ (this->audio_index || this->video_index)) {
+
+ /* video index has priority over audio index */
+ if(this->video_index) {
+ index = this->video_index;
+ entries = this->video_index_entries;
+ other_index = this->audio_index;
+
+ /* when seeking by video index the first audio chunk won't necesserily
+ * be a keyframe which would upset the decoder */
+ this->audio_need_keyframe = 1;
+ } else {
+ index = this->audio_index;
+ entries = this->audio_index_entries;
+ other_index = this->video_index;
+ }
+
+ if(start_pos) {
+ while((index[i+1].offset < start_pos) && (i < entries - 1))
+ i++;
+ } else if(start_time) {
+ start_time *= 1000;
+ while((index[i+1].timestamp < start_time) && (i < entries - 1))
+ i++;
+ }
+
+ /* make sure we don't skip past audio/video at start of file */
+ if((i == 0) && other_index && (other_index[0].offset < index[0].offset))
+ index = other_index;
+
+ this->input->seek(this->input, index[i].offset, SEEK_SET);
+
+ if(this->stream->demux_thread_running) {
+ this->buf_flag_seek = 1;
+ xine_demux_flush_engine(this->stream);
+ }
}
this->send_newpts = 1;