[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