#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; }