mirror of https://github.com/mpv-player/mpv
interpolate real fps of dvr-ms files using the extended stream properties.
Patch by John Donaghy - johnfdonaghy gmail com git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19967 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8e6272e832
commit
bd40e0ea1d
|
@ -222,9 +222,11 @@ struct asf_priv {
|
|||
unsigned packetsize;
|
||||
double packetrate;
|
||||
unsigned movielength;
|
||||
double avg_vid_frame_time;
|
||||
int asf_is_dvr_ms;
|
||||
uint32_t asf_frame_state;
|
||||
int asf_frame_start_found;
|
||||
double dvr_last_vid_pts;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -166,6 +166,43 @@ static int find_backwards_asf_guid(char *buf, const char *guid, int cur_pos)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int get_ext_stream_properties(char *buf, int buf_len, int stream_num, double* avg_frame_time)
|
||||
{
|
||||
// this function currently only gets the average frame time if available
|
||||
|
||||
int pos=0;
|
||||
uint8_t *buffer = &buf[0];
|
||||
uint64_t avg_ft;
|
||||
|
||||
while ((pos = find_asf_guid(buf, asf_ext_stream_header, pos, buf_len)) >= 0) {
|
||||
int this_stream_num, stnamect, payct, i, objlen;
|
||||
buffer = &buf[pos];
|
||||
|
||||
// the following info is available
|
||||
// some of it may be useful but we're skipping it for now
|
||||
// starttime(8 bytes), endtime(8),
|
||||
// leak-datarate(4), bucket-datasize(4), init-bucket-fullness(4),
|
||||
// alt-leak-datarate(4), alt-bucket-datasize(4), alt-init-bucket-fullness(4),
|
||||
// max-object-size(4),
|
||||
// flags(4) (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)
|
||||
|
||||
buffer +=8+8+4+4+4+4+4+4+4+4;
|
||||
this_stream_num=le2me_16(*(uint16_t*)buffer);buffer+=2;
|
||||
|
||||
if (this_stream_num == stream_num) {
|
||||
buffer+=2; //skip stream-language-id-index
|
||||
avg_ft = le2me_64(*(uint64_t*)buffer); // provided in 100ns units
|
||||
*avg_frame_time = avg_ft/10000000.0f;
|
||||
|
||||
// after this are values for stream-name-count and
|
||||
// payload-extension-system-count
|
||||
// followed by associated info for each
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asf_init_audio_stream(demuxer_t *demuxer,struct asf_priv* asf, sh_audio_t* sh_audio, ASF_stream_header_t *streamh, int *ppos, uint8_t** buf, char *hdr, unsigned int hdr_len)
|
||||
{
|
||||
uint8_t *buffer = *buf;
|
||||
|
@ -305,7 +342,17 @@ int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf){
|
|||
asf->asf_frame_state=-1;
|
||||
asf->asf_frame_start_found=0;
|
||||
asf->asf_is_dvr_ms=1;
|
||||
asf->dvr_last_vid_pts=0.0;
|
||||
} else asf->asf_is_dvr_ms=0;
|
||||
if (get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, &asf->avg_vid_frame_time)) {
|
||||
sh_video->frametime=(float)asf->avg_vid_frame_time;
|
||||
sh_video->fps=1.0f/sh_video->frametime;
|
||||
} else {
|
||||
asf->avg_vid_frame_time=0.0; // only used for dvr-ms when > 0.0
|
||||
sh_video->fps=1000.0f;
|
||||
sh_video->frametime=0.001f;
|
||||
}
|
||||
|
||||
if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V);
|
||||
//asf_video_id=streamh.stream_no & 0x7F;
|
||||
//if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F;
|
||||
|
|
|
@ -197,6 +197,15 @@ static int demux_asf_read_packet(demuxer_t *demux,unsigned char *data,int len,in
|
|||
len -= frame_end_pos;
|
||||
}
|
||||
close_seg = 1;
|
||||
if (asf->avg_vid_frame_time > 0.0 ) {
|
||||
// correct the pts for the packet
|
||||
// because dvr-ms files do not contain accurate
|
||||
// pts values but we can deduce them using
|
||||
// the average frame time
|
||||
if (asf->dvr_last_vid_pts > 0.0)
|
||||
dp->pts=asf->dvr_last_vid_pts+asf->avg_vid_frame_time;
|
||||
asf->dvr_last_vid_pts = dp->pts;
|
||||
}
|
||||
} else seq = ds->asf_seq;
|
||||
} else close_seg = ds->asf_seq!=seq;
|
||||
|
||||
|
@ -487,6 +496,8 @@ static void demux_seek_asf(demuxer_t *demuxer,float rel_seek_secs,float audio_de
|
|||
// printf("\r -- asf: newpos=%d -- \n",newpos);
|
||||
stream_seek(demuxer->stream,newpos);
|
||||
|
||||
if (asf->asf_is_dvr_ms) asf->dvr_last_vid_pts = 0.0f;
|
||||
|
||||
if (d_video->id >= 0)
|
||||
ds_fill_buffer(d_video);
|
||||
if(sh_audio){
|
||||
|
@ -556,7 +567,7 @@ static demuxer_t* demux_open_asf(demuxer_t* demuxer)
|
|||
//printf("ASF: missing video stream!? contact the author, it may be a bug :(\n");
|
||||
} else {
|
||||
sh_video=demuxer->video->sh;sh_video->ds=demuxer->video;
|
||||
sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms
|
||||
//sh_video->fps=1000.0f; sh_video->frametime=0.001f; // 1ms - now set when reading asf header
|
||||
//sh_video->i_bps=10*asf->packetsize; // FIXME!
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue