[MPlayer-dev-eng] [PATCH] demux_nuv seek fixes

Eric Lammerts mplayer-deveng at lists.lammerts.org
Sun Nov 5 22:23:56 CET 2006


Hi,
I found two problems with the nuv demuxer:
- it seeks to non-keyframes
- seeking forward builds up an incorrect index

Example of the latter:
- play movie
- seek forward 600s
- seek backward 60s -> now you don't go back 60s, you go back to
    the point where you did the seek forward.

This patch fixed both problems. Tested only with MPEG-4 recordings 
made using MythTV 0.19 and a Plextor TV402U.

Eric

Index: libmpdemux/demux_nuv.c
===================================================================
--- libmpdemux/demux_nuv.c	(revision 20714)
+++ libmpdemux/demux_nuv.c	(working copy)
@@ -70,31 +70,36 @@
   	struct rtframeheader rtjpeg_frameheader;
   	off_t orig_pos;
   	off_t 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 )
+		for(;;)
   		{ 
+			orig_pos = stream_tell ( demuxer->stream );
   			if (stream_read ( demuxer->stream, (char*)& rtjpeg_frameheader, sizeof ( rtjpeg_frameheader ) ) < sizeof(rtjpeg_frameheader))
   				return; /* EOF */
   			le2me_rtframeheader(&rtjpeg_frameheader);

   			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(rtjpeg_frameheader.keyframe == 0) {
+					if(rtjpeg_frameheader.timecode >= target_time) {
+						stream_seek(demuxer->stream, stream_tell(demuxer->stream) - sizeof(rtjpeg_frameheader));
+						break;
+					}
+					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 )
   				{
@@ -103,8 +108,6 @@
   					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 );

@@ -118,7 +121,6 @@
   					/* 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 );
@@ -187,7 +189,7 @@
   	    (rtjpeg_frameheader.comptype == 'R')) ||
   	    (rtjpeg_frameheader.frametype == 'V'))
   	{
-	    if ( rtjpeg_frameheader.frametype == 'V' )
+	    if ( rtjpeg_frameheader.frametype == 'V' && rtjpeg_frameheader.keyframe == 0 )
   	    {
   		priv->current_video_frame++;
   		priv->current_position->next = (nuv_position_t*) malloc(sizeof(nuv_position_t));




More information about the MPlayer-dev-eng mailing list