#include "libzmpeg3.h" zatrack_t:: atrack_t(zmpeg3_t *zsrc, int custom_id, int format, demuxer_t *demux, int no) { channels = zsrc->channel_counts ? zsrc->channel_counts[no] : 0; sample_rate = 0; total_samples = 0; demuxer = new demuxer_t(zsrc, this, 0, custom_id); if( zsrc->seekable ) { demux->copy_titles(demuxer); } current_position = 0; nudge = 0; number = no; pid = custom_id; pts_origin = -1.; reset_pts(); if( zsrc->sample_offsets ) { /* Copy pointers */ sample_offsets = zsrc->sample_offsets[number]; total_sample_offsets = zsrc->total_sample_offsets[number]; total_samples = zsrc->total_samples[number]; demuxer->stream_end = zsrc->audio_eof[number]; nudge = zsrc->nudging[number]; } } zatrack_t *zmpeg3_t:: new_atrack_t(int custom_id, int format, demuxer_t *demux, int number) { atrack_t *new_atrack = new atrack_t(this,custom_id,format,demux,number); new_atrack->audio = new_audio_t(new_atrack, format); if( !new_atrack->audio ) { /* Failed */ delete new_atrack; new_atrack = 0; } return new_atrack; } zatrack_t:: ~atrack_t() { if( audio ) delete audio; if( demuxer ) delete demuxer; if( sample_offsets && private_offsets ) { delete [] sample_offsets; } } void zatrack_t:: extend_sample_offsets() { if( sample_offsets_allocated <= total_sample_offsets ) { long new_allocation = ZMAX(2*total_sample_offsets, 1024); int64_t *new_offsets = new int64_t[new_allocation]; for( int i=0; iaudio_position(); if( pts_starttime < 0. && sample_rate > 0 ) { pts_starttime = pts; pts_offset = audio_pos / (double)sample_rate; if( pts_origin < 0. ) pts_origin = pts - pts_offset; } else if( pts < pts_starttime ) { // check for pts rollover if( pts_starttime-pts > 0x100000000ll / 90000 ) pts += 0x200000000ll / 90000; } double atime = pts_audio_time(pts); if( atime > audio_time ) { pts_position = audio_pos; audio_time = atime; //zmsgs("track %02x audio_time=%f\n", pid, audio_time); } } double zatrack_t::get_audio_time() { double atime = audio_time; if( atime >= 0 && sample_rate > 0 ) { int64_t audio_pos = audio->audio_position(); atime += (audio_pos-pts_position) / (double)sample_rate; } return atime; } void zatrack_t:: reset_pts() { askip = 0; demuxer->pes_audio_time = -1.; pts_starttime = demuxer->src->pts_padding >= 0 ? -1. : 0.; audio_time = -1.; frame_pts = -1.; pts_position = 0; pts_offset = 0; } int64_t zatrack_t::apparent_position() { int64_t pos = demuxer->absolute_position(); int l = -1; int r = total_sample_offsets; while( (r-l) > 1 ) { int m = (r+l) >> 1; int64_t mpos = sample_offsets[m]; if( pos == mpos ) return m; if( pos > mpos ) l = m; else r = m; } int64_t result = (int64_t)l * AUDIO_CHUNKSIZE; if( r < total_sample_offsets ) result += (AUDIO_CHUNKSIZE * (pos - sample_offsets[l])) / (sample_offsets[r] - sample_offsets[l]); return result; }