mirror of
https://github.com/mpv-player/mpv
synced 2025-01-02 04:42:10 +00:00
seek patch by Panagoitis Issaris
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4066 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
d136021db3
commit
3cddcd1be8
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user