changeset 3882:c5cefeb78c40

added read_index_chunk, fixed audio_header parser for version5
author alex
date Sun, 30 Dec 2001 00:38:22 +0000
parents 38718a1c0322
children 8821d4ab94cd
files libmpdemux/demux_real.c
diffstat 1 files changed, 149 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_real.c	Sat Dec 29 23:34:53 2001 +0000
+++ b/libmpdemux/demux_real.c	Sun Dec 30 00:38:22 2001 +0000
@@ -49,8 +49,15 @@
 #define MAX_STREAMS 10
 
 typedef struct {
-    int		data_chunk_offset; /* i think for seeking */
+    /* for seeking */
+    int		index_chunk_offset;
+    int		*index_table[MAX_STREAMS];
+    int		index_table_size[MAX_STREAMS];
+    int		data_chunk_offset;
     int		num_of_packets;
+    int		current_packet;
+    
+    /* stream id table */
     int		last_a_stream;
     int 	a_streams[MAX_STREAMS];
     int		last_v_stream;
@@ -66,15 +73,12 @@
 	len = stream_read_char(demuxer->stream);
     else
 	len = stream_read_word(demuxer->stream);
-#if 1
-    q = buf;
-    for (i = 0; i < len; i++)
-	if (i < (buf_size - 1))
-	    *q++ = stream_read_char(demuxer->stream);
-    *q = 0;
-#else
-    stream_read(demuxer->stream, buf, buf_size);
-#endif
+
+    stream_read(demuxer->stream, buf, (len > buf_size) ? buf_size : len);
+    if (len > buf_size)
+	stream_skip(demuxer->stream, len-buf_size);
+
+    printf("read_str: %d bytes read\n", len);
 }
 
 static void skip_str(int isbyte, demuxer_t *demuxer)
@@ -91,6 +95,62 @@
     printf("skip_str: %d bytes skipped\n", len);
 }
 
+static void parse_index_chunk(demuxer_t *demuxer)
+{
+    real_priv_t *priv = demuxer->priv;
+    int origpos = stream_tell(demuxer->stream);
+    int i, entries;
+    int stream_id = 0;
+
+    printf("Building index table from index chunk (%d)\n",
+	priv->index_chunk_offset);
+    
+    stream_seek(demuxer->stream, priv->index_chunk_offset);
+
+    stream_skip(demuxer->stream, 4); /* INDX */
+
+read_index:
+    if (stream_id > MAX_STREAMS)
+	goto end;
+
+    stream_skip(demuxer->stream, 8); /* unknown */
+    entries = stream_read_word(demuxer->stream);
+    printf("entries: %d\n", entries);
+    if (entries <= 0)
+	goto end;
+    stream_skip(demuxer->stream, 12); /* unknown */
+
+//    stream_skip(demuxer->stream, 22); /* unknown bytes */
+
+    priv->index_table_size[stream_id] = entries;
+    priv->index_table[stream_id] = malloc(priv->index_table_size[stream_id] * sizeof(int));
+    
+    for (i = 0; i < entries; i++)
+    {
+	priv->index_table[stream_id][i] = stream_read_dword(demuxer->stream);
+	stream_skip(demuxer->stream, 10); /* unknown bytes */
+	/* [position(dword)][unk1(word)][unused(dword)][unk2(word)] */
+	printf("Index table: Stream#%d: entry: %d: pos: %d\n",
+	    stream_id, i, priv->index_table[stream_id][i]);
+    }
+    demuxer->seekable = 1; /* got index, we're able to seek */
+
+//    stream_seek(demuxer->stream, stream_tell(demuxer->stream)-7);
+    /* search next index table for other stream */
+    i = stream_read_word(demuxer->stream);
+    printf("pos: %d, next tag: %.4s\n", stream_tell(demuxer->stream), &i);
+    if (i == MKTAG('I', 'N', 'D', 'X'))
+    {
+	stream_id++;
+	goto read_index;
+    }
+
+end:
+    if (entries == -256)
+	stream_reset(demuxer->stream);
+    stream_seek(demuxer->stream, origpos);
+}
+
 int real_check_file(demuxer_t* demuxer)
 {
     real_priv_t *priv;
@@ -127,7 +187,9 @@
 //    printf("num_of_packets: %d\n", priv->num_of_packets);
 
 loop:
-    if (priv->num_of_packets == 0)
+    if ((priv->num_of_packets == 0) && (priv->num_of_packets != -10))
+	return 0; /* EOF */
+    if (priv->current_packet > priv->num_of_packets)
 	return 0; /* EOF */
     stream_skip(demuxer->stream, 2); /* version */
     len = stream_read_word(demuxer->stream);
@@ -147,10 +209,12 @@
     /* flags:		*/
     /* 	0x2 - keyframe	*/
 
-//    printf("packet#%d: len: %d, stream_id: %d, timestamp: %d, flags: %x\n",
-//	priv->num_of_packets, len, stream_id, timestamp, flags);
+//    printf("packet#%d: pos: %d, len: %d, stream_id: %d, timestamp: %d, flags: %x\n",
+//	priv->current_packet, stream_tell(demuxer->stream)-12, len, stream_id, timestamp, flags);
 
-    priv->num_of_packets--;
+//    if (priv->num_of_packets != -10)
+//	priv->num_of_packets--;
+    priv->current_packet++;
     len -= 12;    
 
     /* check if stream_id is audio stream */
@@ -228,7 +292,9 @@
 		stream_skip(demuxer->stream, 4); /* nb packets */
 		stream_skip(demuxer->stream, 4); /* duration */
 		stream_skip(demuxer->stream, 4); /* preroll */
-		stream_skip(demuxer->stream, 4); /* index offset */
+//		stream_skip(demuxer->stream, 4); /* index offset */
+		priv->index_chunk_offset = stream_read_dword(demuxer->stream);
+		printf("Index chunk offset: 0x%x\n", priv->index_chunk_offset);
 //		stream_skip(demuxer->stream, 4); /* data offset */
 		priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;
 		printf("Data chunk offset: 0x%x\n", priv->data_chunk_offset);
@@ -270,6 +336,7 @@
 		{
 		    buf = malloc(len+1);
 		    stream_read(demuxer->stream, buf, len);
+		    buf[len] = 0;
 		    demux_info_add(demuxer, "author", buf);
 		    free(buf);
 		}
@@ -279,6 +346,7 @@
 		{
 		    buf = malloc(len+1);
 		    stream_read(demuxer->stream, buf, len);
+		    buf[len] = 0;
 		    demux_info_add(demuxer, "copyright", buf);
 		    free(buf);
 		}
@@ -288,6 +356,7 @@
 		{
 		    buf = malloc(len+1);
 	    	    stream_read(demuxer->stream, buf, len);
+		    buf[len] = 0;
 		    demux_info_add(demuxer, "comment", buf);
 		    free(buf);
 		}
@@ -330,9 +399,12 @@
 		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id);
 		    char buf[128]; /* for codec name */
 		    int frame_size;
+		    int version;
 
 		    printf("Found audio stream!\n");
-		    stream_skip(demuxer->stream, 2); /* version (4 or 5) */
+		    version = stream_read_word(demuxer->stream);
+		    printf("version: %d\n", version);
+//		    stream_skip(demuxer->stream, 2); /* version (4 or 5) */
 		    stream_skip(demuxer->stream, 2);
 		    stream_skip(demuxer->stream, 4); /* .ra4 or .ra5 */
 		    stream_skip(demuxer->stream, 4);
@@ -348,23 +420,32 @@
 		    frame_size = stream_read_word(demuxer->stream);
 		    printf("frame_size: %d\n", frame_size);
 		    stream_skip(demuxer->stream, 4);
+		    
+		    if (version == 5)
+			stream_skip(demuxer->stream, 6);
 
 		    sh->samplerate = stream_read_word(demuxer->stream);
 		    stream_skip(demuxer->stream, 4);
 		    sh->channels = stream_read_word(demuxer->stream);
 		    printf("samplerate: %d, channels: %d\n",
 			sh->samplerate, sh->channels);
-		
-		    /* Desc #1 */
-		    skip_str(1, demuxer);
-		    /* Desc #2 */
-		    get_str(1, demuxer, buf, sizeof(buf));
+
+		    if (version == 5)
+		    {
+			stream_skip(demuxer->stream, 4);
+			stream_read(demuxer->stream, buf, 4);
+		    }
+		    else
+		    {		
+			/* Desc #1 */
+			skip_str(1, demuxer);
+			/* Desc #2 */
+			get_str(1, demuxer, buf, sizeof(buf));
+		    }
 
 		    tmp = 1; /* supported audio codec */
 		    switch (MKTAG(buf[0], buf[1], buf[2], buf[3]))
 		    {
-			case MKTAG('a', 't', 'r', 'c'):
-			    break;
 			case MKTAG('d', 'n', 'e', 't'):
 			    printf("Audio: DNET -> AC3\n");
 			    sh->format = 0x2000;
@@ -377,6 +458,7 @@
 			    printf("Audio: Real's GeneralCooker (unsupported)\n");
 			    tmp = 0;
 			    break;
+			case MKTAG('a', 't', 'r', 'c'):
 			default:
 			    printf("Audio: Unknown (%s)\n", buf);
 			    tmp = 0;
@@ -445,6 +527,7 @@
 
 		    /* h263 hack */
 		    tmp = stream_read_dword(demuxer->stream);
+		    printf("H.263 ID: %x\n", tmp);
 		    switch (tmp)
 		    {
 			case 0x10000000:
@@ -500,9 +583,15 @@
 
     printf("Packets in file: %d\n", priv->num_of_packets);
 
+    if (priv->num_of_packets == 0)
+	priv->num_of_packets = -10;
+
     /* disable seeking */
     demuxer->seekable = 0;
 
+    if (priv->index_chunk_offset && (index_mode == 1) || (index_mode == 2))
+	parse_index_chunk(demuxer);
+
 fail:
     return;
 }
@@ -516,3 +605,40 @@
 
     return;
 }
+
+#if 0
+/* will complete it later - please upload RV10 samples WITH INDEX CHUNK */
+int demux_seek_real(demuxer_t *demuxer, float rel_seek_secs, int flags)
+{
+    real_priv_t *priv = demuxer->priv;
+    demux_stream_t *d_audio = demuxer->audio;
+    demux_stream_t *d_video = demuxer->video;
+    sh_audio_t *sh_audio = d_audio->sh;
+    sh_video_t *sh_video = d_video->sh;
+    int rel_seek_frames = sh->fps*rel_seek_secs;
+    int video_chunk_pos = d_video->pos;
+    int stream_id = 0;
+
+#if 0
+    if (flags & 1)
+	/* seek absolute */
+	video_chunk_pos = 0;
+
+    if (flags & 2)
+    {
+	int total = sh_video->video.dwLength;
+	
+	rel_seek_frames 
+    }
+#endif
+
+    if (rel_seek_frames > 0)
+    {
+	/* seek forward */
+	for (i = 0; i < index_table_size[stream_id]; i++)
+	{
+	    if (index_table[stream_id][i] 
+	}
+    }
+}
+#endif