X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Flibzmpeg3%2Fvtrack.C;fp=cinelerra-5.1%2Flibzmpeg3%2Fvtrack.C;h=67369bfe39351a9a973f551b7ca9b59ceefae2f1;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/libzmpeg3/vtrack.C b/cinelerra-5.1/libzmpeg3/vtrack.C new file mode 100644 index 00000000..67369bfe --- /dev/null +++ b/cinelerra-5.1/libzmpeg3/vtrack.C @@ -0,0 +1,179 @@ +#include "libzmpeg3.h" + +zvtrack_t:: +vtrack_t(zmpeg3_t *zsrc, int custom_id, demuxer_t *demux, int no) +{ + demuxer = new demuxer_t(zsrc, 0, this, custom_id); + frame_cache = new cache_t(); + if( zsrc->seekable ) { + demux->copy_titles(demuxer); + } + + current_position = 0; + number = no; + pid = custom_id; + pts_origin = -1.; + reset_pts(); + +// Copy pointers + if( zsrc->frame_offsets ) { + frame_offsets = zsrc->frame_offsets[number]; + total_frame_offsets = zsrc->total_frame_offsets[number]; + keyframe_numbers = zsrc->keyframe_numbers[number]; + total_keyframe_numbers = zsrc->total_keyframe_numbers[number]; + demuxer->stream_end = zsrc->video_eof[number]; + } +} + +zvtrack_t *zmpeg3_t:: +new_vtrack_t(int custom_id, demuxer_t *demux, int number) +{ + vtrack_t *new_vtrack = new vtrack_t(this,custom_id,demux,number); + +/* Get information about the track here. */ + new_vtrack->video = new_video_t(new_vtrack); + + if( !new_vtrack->video ) { /* Failed */ + delete new_vtrack; + new_vtrack = 0; + } + + return new_vtrack; +} + +zvtrack_t:: +~vtrack_t() +{ + if( video ) delete video; + if( demuxer ) delete demuxer; + if( private_offsets ) { + if( frame_offsets_allocated ) delete [] frame_offsets; + if( keyframe_numbers_allocated ) delete [] keyframe_numbers; + } + delete frame_cache; +} + +void zvtrack_t:: +extend_frame_offsets() +{ + if( frame_offsets_allocated <= total_frame_offsets ) { + long new_allocation = ZMAX(2*total_frame_offsets, 1024); + int64_t *new_offsets = new int64_t[new_allocation]; + for( int i=0; i 1 ) { + int m = (r+l) >> 1; + int mframe = keyframe_numbers[m]; + if( frame == mframe ) return m; + if( frame > mframe ) l = m; + else r = m; + } + return l; +} + +void zvtrack_t::update_video_time() +{ + double pts = frame_pts; + if( video->is_refframe() ) { + pts = refframe_pts; + refframe_pts = frame_pts; + } + frame_pts = -1.; + if( pts < 0 ) return; + if( pts_starttime < 0 && frame_rate > 0 ) { + pts_starttime = pts; + pts_offset = (double)video->framenum / frame_rate; + if( pts_origin < 0. ) pts_origin = pts_starttime - pts_offset; + } + else if( pts < pts_starttime ) { // check for pts rollover + if( pts_starttime-pts > 0x100000000ll / 90000 ) + pts += 0x200000000ll / 90000; + } + /* update track time */ + double vtime = pts_video_time(pts); + if( vtime > video_time ) { + video_time = vtime; + pts_position = video->framenum; +//zmsgs("track %02x video_time=%f\n",track->pid, vtime); + } +} + +double zvtrack_t::get_video_time() +{ + double vtime = video_time; + if( vtime >= 0 && frame_rate > 0 ) { + vtime += (video->framenum - pts_position) / frame_rate; + } + return vtime; +} + +void zvtrack_t:: +reset_pts() +{ + vskip = 0; + demuxer->pes_video_time = -1.; + pts_starttime = demuxer->src->pts_padding >= 0 ? -1. : 0.; + video_time = -1.; + refframe_pts = -1.; + frame_pts = -1.; + pts_position = 0; + pts_offset = 0; +} + +int zvtrack_t::apparent_position() +{ + if( !frame_offsets ) return 0; + int64_t pos = demuxer->absolute_position(); + int l = -1; + int r = total_frame_offsets; + while( (r-l) > 1 ) { + int m = (r+l) >> 1; + int64_t mpos = frame_offsets[m]; + if( pos == mpos ) return m; + if( pos > mpos ) l = m; + else r = m; + } + return l; +} +