diff options
Diffstat (limited to 'libmpdemux')
-rw-r--r-- | libmpdemux/asf.h | 2 | ||||
-rw-r--r-- | libmpdemux/asfheader.c | 47 | ||||
-rw-r--r-- | libmpdemux/demux_asf.c | 13 |
3 files changed, 61 insertions, 1 deletions
diff --git a/libmpdemux/asf.h b/libmpdemux/asf.h index 01f9b25857..893ea2dcb7 100644 --- a/libmpdemux/asf.h +++ b/libmpdemux/asf.h @@ -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 diff --git a/libmpdemux/asfheader.c b/libmpdemux/asfheader.c index 19fad523ca..9644e0286d 100644 --- a/libmpdemux/asfheader.c +++ b/libmpdemux/asfheader.c @@ -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; diff --git a/libmpdemux/demux_asf.c b/libmpdemux/demux_asf.c index 85a0176b47..d14cdb5612 100644 --- a/libmpdemux/demux_asf.c +++ b/libmpdemux/demux_asf.c @@ -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! } } |