changeset 4065:763a0e7e0521

seek patch by Panagoitis Issaris
author alex
date Wed, 09 Jan 2002 17:09:21 +0000
parents 3c747168eb6e
children b57295270712
files libmpdemux/demux_nuv.c libmpdemux/demuxer.c
diffstat 2 files changed, 136 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_nuv.c	Wed Jan 09 16:35:24 2002 +0000
+++ b/libmpdemux/demux_nuv.c	Wed Jan 09 17:09:21 2002 +0000
@@ -17,8 +17,6 @@
 #include "demuxer.h"
 #include "stheader.h"
 #include "nuppelvideo.h" 
-//#include "RTjpegN.h"
-//#include "minilzo.h"
 
 
 struct nuv_signature
@@ -27,9 +25,113 @@
 	char version[5];    /* "0.05" + \0 */
 };
 
+typedef struct _nuv_position_t nuv_position_t;
 
+struct _nuv_position_t 
+{
+	off_t offset;
+	float time;
+	int frame;
+	nuv_position_t* next;
+};
+
+typedef struct _nuv_info_t 
+{
+	int current_audio_frame;
+	int current_video_frame;
+	nuv_position_t *index_list;
+	nuv_position_t *current_position;
+} nuv_priv_t;
+
+
+/**
+ * Seek to a position relative to the current position, indicated in time.
+ */
 void demux_seek_nuv ( demuxer_t *demuxer, float rel_seek_secs, int flags )
 {
+#define MAX_TIME 1000000
+	nuv_priv_t* priv = demuxer->priv;
+	struct rtframeheader rtjpeg_frameheader;
+	int orig_pos;
+	int curr_pos;
+	float current_time = 0;
+	float start_time = MAX_TIME;
+	float target_time = start_time + rel_seek_secs * 1000; /* target_time, start_time are ms, rel_seek_secs s */
+
+	orig_pos = stream_tell ( demuxer->stream );
+
+	if ( rel_seek_secs > 0 )
+	{
+		/* Seeking forward */
+
+
+		while(current_time < target_time )
+		{	
+			if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader))
+				return; /* EOF */
+
+			if ( rtjpeg_frameheader.frametype == 'V' ) 
+			{
+				priv->current_position->next = (nuv_position_t*) malloc ( sizeof ( nuv_position_t ) );
+				priv->current_position = priv->current_position->next;
+				priv->current_position->frame = priv->current_video_frame++;
+				priv->current_position->time = rtjpeg_frameheader.timecode;
+				priv->current_position->offset = orig_pos;
+				priv->current_position->next = NULL;
+
+				if ( start_time == MAX_TIME )
+				{
+					start_time = rtjpeg_frameheader.timecode;
+					/* Recalculate target time with real start time */
+					target_time = start_time + rel_seek_secs*1000;
+				}
+
+				current_time = rtjpeg_frameheader.timecode;
+
+				curr_pos = stream_tell ( demuxer->stream );
+				stream_seek ( demuxer->stream, curr_pos + rtjpeg_frameheader.packetlength );
+
+				/* Adjust current sequence pointer */
+			}
+			else if ( rtjpeg_frameheader.frametype == 'A' )
+			{	
+				if ( start_time == MAX_TIME )
+				{
+					start_time = rtjpeg_frameheader.timecode;
+					/* Recalculate target time with real start time */
+					target_time = start_time + rel_seek_secs * 1000;
+				}
+				current_time = rtjpeg_frameheader.timecode;
+
+
+				curr_pos = stream_tell ( demuxer->stream );
+				stream_seek ( demuxer->stream, curr_pos + rtjpeg_frameheader.packetlength );
+			}
+		}
+	}
+	else
+	{
+		/* Seeking backward */
+		nuv_position_t* p;
+		start_time = priv->current_position->time;
+
+		/* Recalculate target time with real start time */
+		target_time = start_time + rel_seek_secs * 1000;
+
+
+		if(target_time < 0)
+			target_time = 0;
+
+		// Search the target time in the index list, get the offset
+		// and go to that offset.
+		p = priv->index_list;
+		while ( ( p->next != NULL ) && ( p->time < target_time ) )
+		{
+			p = p->next;
+		}
+		stream_seek ( demuxer->stream, p->offset );
+		priv->current_video_frame = p->frame;
+	}
 }
 
 
@@ -37,6 +139,7 @@
 {
 	struct rtframeheader rtjpeg_frameheader;
 	int orig_pos;
+	nuv_priv_t* priv = demuxer->priv;
 
 	orig_pos = stream_tell ( demuxer->stream );
 	if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader))
@@ -58,16 +161,28 @@
 	    (rtjpeg_frameheader.comptype == 'R')) ||
 	    (rtjpeg_frameheader.frametype == 'V'))
 	{
+	    if ( rtjpeg_frameheader.frametype == 'V' )
+	    {
+		priv->current_video_frame++;
+		priv->current_position->next = (nuv_position_t*) malloc(sizeof(nuv_position_t));
+		priv->current_position = priv->current_position->next;
+		priv->current_position->frame = priv->current_video_frame;
+		priv->current_position->time = rtjpeg_frameheader.timecode;
+		priv->current_position->offset = orig_pos;
+		priv->current_position->next = NULL;
+	    }
 	    /* put RTjpeg tables, Video info to video buffer */
 	    stream_seek ( demuxer->stream, orig_pos );
 	    ds_read_packet ( demuxer->video, demuxer->stream, rtjpeg_frameheader.packetlength + 12, 
-		rtjpeg_frameheader.timecode / 1000, orig_pos, 0 );
-	}
-	
+		    rtjpeg_frameheader.timecode / 1000, orig_pos, 0 );
+
+
+	} else
 	/* copy PCM only */
 	if (demuxer->audio && (rtjpeg_frameheader.frametype == 'A') &&
 	    (rtjpeg_frameheader.comptype == '0'))
 	{
+	    priv->current_audio_frame++;
 	    /* put Audio to audio buffer */
 	    ds_read_packet ( demuxer->audio, demuxer->stream, rtjpeg_frameheader.packetlength, 
 		rtjpeg_frameheader.timecode / 1000, orig_pos + 12, 0 );
@@ -85,6 +200,11 @@
 	struct rtframeheader rtjpeg_frameheader;
 	unsigned long int tbls[128];
 	int bytes_read;
+	nuv_priv_t* priv = (nuv_priv_t*) malloc ( sizeof ( nuv_priv_t) );
+	demuxer->priv = priv;
+	priv->current_audio_frame = 0;
+	priv->current_video_frame = 0;
+
 
 	/* Go to the start */
 	stream_reset(demuxer->stream);
@@ -131,7 +251,6 @@
 	sh_video->fps = rtjpeg_fileheader.fps;
 	sh_video->frametime = 1 / sh_video->fps;
 
-#if 1
 	if (rtjpeg_fileheader.audioblocks != 0)
 	{
 	    sh_audio = new_sh_audio(demuxer, 0);
@@ -152,7 +271,13 @@
 	    sh_audio->wf->nBlockAlign = sh_audio->channels * 2;
 	    sh_audio->wf->cbSize = 0;
 	}
-#endif
+
+	priv->index_list = (nuv_position_t*) malloc(sizeof(nuv_position_t));
+	priv->index_list->frame = 0;
+	priv->index_list->time = 0;
+	priv->index_list->offset = stream_tell ( demuxer->stream );
+	priv->index_list->next = NULL;
+	priv->current_position = priv->index_list;
 
 	return demuxer;
 }
--- a/libmpdemux/demuxer.c	Wed Jan 09 16:35:24 2002 +0000
+++ b/libmpdemux/demuxer.c	Wed Jan 09 17:09:21 2002 +0000
@@ -660,6 +660,7 @@
 int demux_seek_mpg(demuxer_t *demuxer,float rel_seek_secs,int flags);
 int demux_seek_y4m(demuxer_t *demuxer,float rel_seek_secs,int flags);
 int demux_seek_fli(demuxer_t *demuxer,float rel_seek_secs,int flags);
+int demux_seek_nuv(demuxer_t *demuxer,float rel_seek_secs,int flags);
 void demux_seek_mov(demuxer_t *demuxer,float pts,int flags);
 
 int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
@@ -715,6 +716,9 @@
 
   case DEMUXER_TYPE_FLI:
       demux_seek_fli(demuxer,rel_seek_secs,flags);  break;
+  case DEMUXER_TYPE_NUV:
+      demux_seek_nuv(demuxer,rel_seek_secs,flags);  break;
+
 
 } // switch(demuxer->file_format)