# HG changeset patch # User alex # Date 1010596161 0 # Node ID 763a0e7e0521150ee4ddd778d9156903cd84a873 # Parent 3c747168eb6e2bb95a1bbbefb0c14e1396dfc711 seek patch by Panagoitis Issaris diff -r 3c747168eb6e -r 763a0e7e0521 libmpdemux/demux_nuv.c --- 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; } diff -r 3c747168eb6e -r 763a0e7e0521 libmpdemux/demuxer.c --- 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)