Ticket #850: audiotimecode.patch

File audiotimecode.patch, 7.5 KB (added by mythtv@…, 18 years ago)

audio timecode patch

  • audiooutputbase.h

     
    4747    // Wait for all data to finish playing
    4848    virtual void Drain(void);
    4949 
    50     virtual int GetAudiotime(void);
     50    virtual long long GetAudiotime(void);
    5151
    5252    // Send output events showing current progress
    5353    virtual void Status(void);
     
    130130
    131131    bool blocking; // do AddSamples calls block?
    132132
    133     int lastaudiolen;
    134 
    135133    pthread_t output_audio;
    136134    pthread_mutex_t audio_buflock; /* adjustments to audiotimecode, waud, and
    137135                                      raud can only be made while holding this
     
    142140
    143141    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    144142                                    'audiotime' and 'audiotime_updated' */
    145     int audiotime; // timecode of audio leaving the soundcard (same units as
    146                    //                                          timecodes) ...
     143    long long audiotime; // timecode of audio leaving the soundcard
     144                         // (same units as timecodes) ...
    147145    struct timeval audiotime_updated; // ... which was last updated at this time
    148146
    149147    /* Audio circular buffer */
    150148    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    151149    int raud, waud;     /* read and write positions */
    152     int audbuf_timecode;    /* timecode of audio most recently placed into
    153                    buffer */
    154150
     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
    155155    int numlowbuffer;
    156156
    157157    QMutex killAudioLock;
  • audiooutputbase.cpp

     
    113113    pthread_mutex_lock(&audio_buflock);
    114114    pthread_mutex_lock(&avsync_lock);
    115115
    116     lastaudiolen = 0;
    117116    waud = raud = 0;
    118117    audio_actually_paused = false;
    119118   
     
    157156    if (!gContext->GetNumSetting("AggressiveSoundcardBuffer", 0))
    158157        audio_buffer_unused = 0;
    159158
    160     audbuf_timecode = 0;
     159    soundcard_position = 0;
     160    specified_timecode = 0;
    161161    audiotime = 0;
    162162    effdsp = audio_samplerate * 100;
    163163    gettimeofday(&audiotime_updated, NULL);
     
    260260    pthread_mutex_lock(&avsync_lock);
    261261
    262262    raud = waud = 0;
    263     audbuf_timecode = 0;
     263    soundcard_position = 0;
     264    specified_timecode = 0;
    264265    audiotime = 0;
    265266    current_seconds = -1;
    266267    was_paused = !pauseaudio;
     
    277278void AudioOutputBase::SetTimecode(long long timecode)
    278279{
    279280    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    }
    281290    pthread_mutex_unlock(&audio_buflock);
    282291}
    283292
     
    320329       be is AUDBUFSIZE - 1. */
    321330}
    322331
    323 int AudioOutputBase::GetAudiotime(void)
     332long long AudioOutputBase::GetAudiotime(void)
    324333{
    325334    /* Returns the current timecode of audio leaving the soundcard, based
    326335       on the 'audiotime' computed earlier, and the delay since it was computed.
     
    330339       The reason is that computing 'audiotime' requires acquiring the audio
    331340       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    332341       from the audio thread, and then call this from the video thread. */
    333     int ret;
     342    long long ret;
    334343    struct timeval now;
    335344
    336345    if (audiotime == 0)
     
    342351
    343352    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    344353    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    345     ret = (int)(ret * audio_stretchfactor);
     354    ret = (long long)(ret * audio_stretchfactor);
    346355
    347356    ret += audiotime;
    348357
     
    352361
    353362void AudioOutputBase::SetAudiotime(void)
    354363{
    355     if (audbuf_timecode == 0)
    356         return;
     364    int soundcard_buffer;
    357365
    358     int soundcard_buffer = 0;
    359     int totalbuffer;
    360 
    361366    /* We want to calculate 'audiotime', which is the timestamp of the audio
    362367       which is leaving the sound card at this instant.
    363368
     
    370375       written into the buffer.
    371376
    372377       'totalbuffer' is the total # of bytes in our audio buffer, and the
    373        sound card's buffer.
     378       sound card's bulong longffer.
    374379
    375380       'ms/byte' is given by '25000/effdsp'...
    376381     */
    377382
    378383    pthread_mutex_lock(&audio_buflock);
    379384    pthread_mutex_lock(&avsync_lock);
    380  
     385
    381386    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
    395391    gettimeofday(&audiotime_updated, NULL);
    396392
    397393    pthread_mutex_unlock(&avsync_lock);
     
    539535   
    540536    len = WaitForFreeSpace(samples);
    541537
     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
    542556    if (interleaved)
    543557    {
    544558        char *mybuf = (char*)buffer;
     
    621635    }
    622636
    623637    waud = org_waud;
    624     lastaudiolen = audiolen(false);
    625638
    626     if (timecode < 0)
    627         timecode = audbuf_timecode; // add to current timecode
    628    
    629     /* we want the time at the end -- but the file format stores
    630        time at the start of the chunk. */
    631     // even with timestretch, timecode is still calculated from original
    632     // sample count
    633     audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    634639    if (interleaved)
    635640        dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    636641
     
    817822
    818823        /* update raud */
    819824        raud = (raud + fragment_size) % AUDBUFSIZE;
     825        soundcard_position += fragment_size;
    820826        VERBOSE(VB_AUDIO, "Broadcasting free space avail");
    821827        pthread_cond_broadcast(&audio_bufsig);
    822828
  • audiooutput.h

     
    5151    // Wait for all data to finish playing
    5252    virtual void Drain(void) = 0;
    5353
    54     virtual int GetAudiotime(void) = 0;
     54    virtual long long GetAudiotime(void) = 0;
    5555
    5656    virtual void SetSourceBitrate(int ) { }
    5757