summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-01-09 17:09:21 +0000
committeralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-01-09 17:09:21 +0000
commit3cddcd1be8d1c00df8a9d7e857650e51fed190ce (patch)
treea26bdb8aaead9a3ffdf966d7e5427efd24b69577
parentd136021db35750f6eadda605290cba4e0919b7e7 (diff)
downloadmpv-3cddcd1be8d1c00df8a9d7e857650e51fed190ce.tar.bz2
mpv-3cddcd1be8d1c00df8a9d7e857650e51fed190ce.tar.xz
seek patch by Panagoitis Issaris
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4066 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--libmpdemux/demux_nuv.c139
-rw-r--r--libmpdemux/demuxer.c4
2 files changed, 136 insertions, 7 deletions
diff --git a/libmpdemux/demux_nuv.c b/libmpdemux/demux_nuv.c
index d6b28abc15..40897a55f0 100644
--- a/libmpdemux/demux_nuv.c
+++ b/libmpdemux/demux_nuv.c
@@ -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 @@ struct nuv_signature
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 @@ int demux_nuv_fill_buffer ( demuxer_t *demuxer )
{
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 @@ int demux_nuv_fill_buffer ( demuxer_t *demuxer )
(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 @@ demuxer_t* demux_open_nuv ( demuxer_t* demuxer )
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 @@ demuxer_t* demux_open_nuv ( demuxer_t* demuxer )
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 @@ demuxer_t* demux_open_nuv ( demuxer_t* demuxer )
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;
}
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index f89d92f4b3..e0bc7bdda2 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -660,6 +660,7 @@ int demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,int flags);
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 @@ switch(demuxer->file_format){
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)