Ticket #850: audiotimecode_v2.patch
File audiotimecode_v2.patch, 8.0 KB (added by , 18 years ago) |
---|
-
libs/libmyth/audiooutputbase.h
47 47 // Wait for all data to finish playing 48 48 virtual void Drain(void); 49 49 50 virtual intGetAudiotime(void);50 virtual long long GetAudiotime(void); 51 51 52 52 // Send output events showing current progress 53 53 virtual void Status(void); … … 130 130 131 131 bool blocking; // do AddSamples calls block? 132 132 133 int lastaudiolen;134 135 133 pthread_t output_audio; 136 134 pthread_mutex_t audio_buflock; /* adjustments to audiotimecode, waud, and 137 135 raud can only be made while holding this … … 142 140 143 141 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 144 142 'audiotime' and 'audiotime_updated' */ 145 int audiotime; // timecode of audio leaving the soundcard (same units as146 //timecodes) ...143 long long audiotime; // timecode of audio leaving the soundcard 144 // (same units as timecodes) ... 147 145 struct timeval audiotime_updated; // ... which was last updated at this time 148 146 149 147 /* Audio circular buffer */ 150 148 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 151 149 int raud, waud; /* read and write positions */ 152 int audbuf_timecode; /* timecode of audio most recently placed into153 buffer */154 150 151 long long specified_timecode; // timecode specified 152 long long soundcard_position; // position of data sent to soundcard (bytes) 153 // (relative to specified_timecode) 154 155 155 int numlowbuffer; 156 156 157 157 QMutex killAudioLock; -
libs/libmyth/audiooutputbase.cpp
113 113 pthread_mutex_lock(&audio_buflock); 114 114 pthread_mutex_lock(&avsync_lock); 115 115 116 lastaudiolen = 0;117 116 waud = raud = 0; 118 117 audio_actually_paused = false; 119 118 … … 157 156 if (!gContext->GetNumSetting("AggressiveSoundcardBuffer", 0)) 158 157 audio_buffer_unused = 0; 159 158 160 audbuf_timecode = 0; 159 soundcard_position = 0; 160 specified_timecode = 0; 161 161 audiotime = 0; 162 162 effdsp = audio_samplerate * 100; 163 163 gettimeofday(&audiotime_updated, NULL); … … 260 260 pthread_mutex_lock(&avsync_lock); 261 261 262 262 raud = waud = 0; 263 audbuf_timecode = 0; 263 soundcard_position = 0; 264 specified_timecode = 0; 264 265 audiotime = 0; 265 266 current_seconds = -1; 266 267 was_paused = !pauseaudio; … … 277 278 void AudioOutputBase::SetTimecode(long long timecode) 278 279 { 279 280 pthread_mutex_lock(&audio_buflock); 280 audbuf_timecode = timecode; 281 specified_timecode = timecode; 282 soundcard_position = -audiolen(false); 283 284 if (pSoundStretch) 285 { 286 // add the effect of unprocessed samples in time stretch algo 287 soundcard_position += (long long)((pSoundStretch->numUnprocessedSamples() * 288 audio_bytes_per_sample) / audio_stretchfactor); 289 } 281 290 pthread_mutex_unlock(&audio_buflock); 282 291 } 283 292 … … 320 329 be is AUDBUFSIZE - 1. */ 321 330 } 322 331 323 intAudioOutputBase::GetAudiotime(void)332 long long AudioOutputBase::GetAudiotime(void) 324 333 { 325 334 /* Returns the current timecode of audio leaving the soundcard, based 326 335 on the 'audiotime' computed earlier, and the delay since it was computed. … … 330 339 The reason is that computing 'audiotime' requires acquiring the audio 331 340 lock, which the video thread should not do. So, we call 'SetAudioTime()' 332 341 from the audio thread, and then call this from the video thread. */ 333 intret;342 long long ret; 334 343 struct timeval now; 335 344 336 345 if (audiotime == 0) … … 342 351 343 352 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 344 353 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 345 ret = ( int)(ret * audio_stretchfactor);354 ret = (long long)(ret * audio_stretchfactor); 346 355 347 356 ret += audiotime; 348 357 … … 352 361 353 362 void AudioOutputBase::SetAudiotime(void) 354 363 { 355 if (audbuf_timecode == 0) 356 return; 364 int soundcard_buffer; 357 365 358 int soundcard_buffer = 0;359 int totalbuffer;360 361 366 /* We want to calculate 'audiotime', which is the timestamp of the audio 362 367 which is leaving the sound card at this instant. 363 368 … … 370 375 written into the buffer. 371 376 372 377 'totalbuffer' is the total # of bytes in our audio buffer, and the 373 sound card's bu ffer.378 sound card's bulong longffer. 374 379 375 380 'ms/byte' is given by '25000/effdsp'... 376 381 */ 377 382 378 383 pthread_mutex_lock(&audio_buflock); 379 384 pthread_mutex_lock(&avsync_lock); 380 385 381 386 soundcard_buffer = getBufferedOnSoundcard(); // bytes 382 totalbuffer = audiolen(false) + soundcard_buffer; 383 384 // include algorithmic latencies 385 if (pSoundStretch) 386 { 387 // add the effect of unprocessed samples in time stretch algo 388 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 389 audio_bytes_per_sample) / audio_stretchfactor); 390 } 391 392 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 393 (audio_bytes_per_sample * effdspstretched)); 394 387 388 audiotime = specified_timecode + (100000 * (soundcard_position - soundcard_buffer)) / 389 (audio_bytes_per_sample * effdspstretched); 390 395 391 gettimeofday(&audiotime_updated, NULL); 396 392 397 393 pthread_mutex_unlock(&avsync_lock); … … 539 535 540 536 len = WaitForFreeSpace(samples); 541 537 538 if (timecode >= 0) 539 { 540 specified_timecode = timecode; 541 soundcard_position = -audiolen(false); 542 543 if (pSoundStretch) 544 { 545 // add the effect of unprocessed samples in time stretch algo 546 soundcard_position -= (long long)((pSoundStretch->numUnprocessedSamples() * 547 audio_bytes_per_sample) / audio_stretchfactor); 548 } 549 } 550 else 551 { 552 timecode = specified_timecode + (100000 * (soundcard_position + audiolen(false))) / 553 (audio_bytes_per_sample * effdsp); 554 } 555 542 556 if (interleaved) 543 557 { 544 558 char *mybuf = (char*)buffer; … … 621 635 } 622 636 623 637 waud = org_waud; 624 lastaudiolen = audiolen(false);625 638 626 if (timecode < 0)627 timecode = audbuf_timecode; // add to current timecode628 629 /* we want the time at the end -- but the file format stores630 time at the start of the chunk. */631 // even with timestretch, timecode is still calculated from original632 // sample count633 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);634 639 if (interleaved) 635 640 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits); 636 641 … … 817 822 818 823 /* update raud */ 819 824 raud = (raud + fragment_size) % AUDBUFSIZE; 825 soundcard_position += fragment_size; 820 826 VERBOSE(VB_AUDIO, "Broadcasting free space avail"); 821 827 pthread_cond_broadcast(&audio_bufsig); 822 828 -
libs/libmyth/audiooutput.h
51 51 // Wait for all data to finish playing 52 52 virtual void Drain(void) = 0; 53 53 54 virtual intGetAudiotime(void) = 0;54 virtual long long GetAudiotime(void) = 0; 55 55 56 56 virtual void SetSourceBitrate(int ) { } 57 57 -
programs/mythtranscode/transcode.cpp
137 137 return; 138 138 } 139 139 140 virtual intGetAudiotime(void)140 virtual long long GetAudiotime(void) 141 141 { 142 142 return last_audiotime; 143 143 }