Index: libs/libmyth/audiooutputbase.h
===================================================================
--- libs/libmyth/audiooutputbase.h	(revision 8338)
+++ libs/libmyth/audiooutputbase.h	(working copy)
@@ -47,7 +47,7 @@
     // Wait for all data to finish playing
     virtual void Drain(void);
  
-    virtual int GetAudiotime(void);
+    virtual long long GetAudiotime(void);
 
     // Send output events showing current progress
     virtual void Status(void);
@@ -130,8 +130,6 @@
 
     bool blocking; // do AddSamples calls block?
 
-    int lastaudiolen;
-
     pthread_t output_audio;
     pthread_mutex_t audio_buflock; /* adjustments to audiotimecode, waud, and
                                       raud can only be made while holding this
@@ -142,16 +140,18 @@
 
     pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
                                     'audiotime' and 'audiotime_updated' */
-    int audiotime; // timecode of audio leaving the soundcard (same units as
-                   //                                          timecodes) ...
+    long long audiotime; // timecode of audio leaving the soundcard
+                         // (same units as timecodes) ...
     struct timeval audiotime_updated; // ... which was last updated at this time
 
     /* Audio circular buffer */
     unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
     int raud, waud;     /* read and write positions */
-    int audbuf_timecode;    /* timecode of audio most recently placed into
-                   buffer */
 
+    long long specified_timecode; // timecode specified
+    long long soundcard_position; // position of data sent to soundcard (bytes)
+                                  // (relative to specified_timecode)
+
     int numlowbuffer;
 
     QMutex killAudioLock;
Index: libs/libmyth/audiooutputbase.cpp
===================================================================
--- libs/libmyth/audiooutputbase.cpp	(revision 8338)
+++ libs/libmyth/audiooutputbase.cpp	(working copy)
@@ -113,7 +113,6 @@
     pthread_mutex_lock(&audio_buflock);
     pthread_mutex_lock(&avsync_lock);
 
-    lastaudiolen = 0;
     waud = raud = 0;
     audio_actually_paused = false;
     
@@ -157,7 +156,8 @@
     if (!gContext->GetNumSetting("AggressiveSoundcardBuffer", 0))
         audio_buffer_unused = 0;
 
-    audbuf_timecode = 0;
+    soundcard_position = 0;
+    specified_timecode = 0;
     audiotime = 0;
     effdsp = audio_samplerate * 100;
     gettimeofday(&audiotime_updated, NULL);
@@ -260,7 +260,8 @@
     pthread_mutex_lock(&avsync_lock);
 
     raud = waud = 0;
-    audbuf_timecode = 0;
+    soundcard_position = 0;
+    specified_timecode = 0;
     audiotime = 0;
     current_seconds = -1;
     was_paused = !pauseaudio;
@@ -277,7 +278,15 @@
 void AudioOutputBase::SetTimecode(long long timecode)
 {
     pthread_mutex_lock(&audio_buflock);
-    audbuf_timecode = timecode;
+    specified_timecode = timecode;
+    soundcard_position = -audiolen(false);
+
+    if (pSoundStretch)
+    {
+        // add the effect of unprocessed samples in time stretch algo
+        soundcard_position += (long long)((pSoundStretch->numUnprocessedSamples() *
+                                           audio_bytes_per_sample) / audio_stretchfactor);
+    }
     pthread_mutex_unlock(&audio_buflock);
 }
 
@@ -320,7 +329,7 @@
        be is AUDBUFSIZE - 1. */
 }
 
-int AudioOutputBase::GetAudiotime(void)
+long long AudioOutputBase::GetAudiotime(void)
 {
     /* Returns the current timecode of audio leaving the soundcard, based
        on the 'audiotime' computed earlier, and the delay since it was computed.
@@ -330,7 +339,7 @@
        The reason is that computing 'audiotime' requires acquiring the audio 
        lock, which the video thread should not do. So, we call 'SetAudioTime()'
        from the audio thread, and then call this from the video thread. */
-    int ret;
+    long long ret;
     struct timeval now;
 
     if (audiotime == 0)
@@ -342,7 +351,7 @@
 
     ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
     ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
-    ret = (int)(ret * audio_stretchfactor);
+    ret = (long long)(ret * audio_stretchfactor);
 
     ret += audiotime;
 
@@ -352,12 +361,8 @@
 
 void AudioOutputBase::SetAudiotime(void)
 {
-    if (audbuf_timecode == 0)
-        return;
+    int soundcard_buffer;
 
-    int soundcard_buffer = 0;
-    int totalbuffer;
-
     /* We want to calculate 'audiotime', which is the timestamp of the audio
        which is leaving the sound card at this instant.
 
@@ -370,28 +375,19 @@
        written into the buffer.
 
        'totalbuffer' is the total # of bytes in our audio buffer, and the
-       sound card's buffer.
+       sound card's bulong longffer.
 
        'ms/byte' is given by '25000/effdsp'...
      */
 
     pthread_mutex_lock(&audio_buflock);
     pthread_mutex_lock(&avsync_lock);
- 
+
     soundcard_buffer = getBufferedOnSoundcard(); // bytes
-    totalbuffer = audiolen(false) + soundcard_buffer;
- 
-    // include algorithmic latencies
-    if (pSoundStretch)
-    {
-        // add the effect of unprocessed samples in time stretch algo
-        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
-                              audio_bytes_per_sample) / audio_stretchfactor);
-    }
-               
-    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
-                                   (audio_bytes_per_sample * effdspstretched));
- 
+
+    audiotime = specified_timecode + (100000 * (soundcard_position - soundcard_buffer)) /
+                                     (audio_bytes_per_sample * effdspstretched);
+
     gettimeofday(&audiotime_updated, NULL);
 
     pthread_mutex_unlock(&avsync_lock);
@@ -539,6 +535,24 @@
     
     len = WaitForFreeSpace(samples);
 
+    if (timecode >= 0)
+    {
+        specified_timecode = timecode;
+        soundcard_position = -audiolen(false);
+
+        if (pSoundStretch)
+        {
+            // add the effect of unprocessed samples in time stretch algo
+            soundcard_position -= (long long)((pSoundStretch->numUnprocessedSamples() *
+                                               audio_bytes_per_sample) / audio_stretchfactor);
+        }
+    }
+    else
+    {
+        timecode = specified_timecode + (100000 * (soundcard_position + audiolen(false))) /
+                                        (audio_bytes_per_sample * effdsp);
+    }
+
     if (interleaved) 
     {
         char *mybuf = (char*)buffer;
@@ -621,16 +635,7 @@
     }
 
     waud = org_waud;
-    lastaudiolen = audiolen(false);
 
-    if (timecode < 0) 
-        timecode = audbuf_timecode; // add to current timecode
-    
-    /* we want the time at the end -- but the file format stores
-       time at the start of the chunk. */
-    // even with timestretch, timecode is still calculated from original
-    // sample count
-    audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
     if (interleaved)
         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
 
@@ -817,6 +822,7 @@
 
         /* update raud */
         raud = (raud + fragment_size) % AUDBUFSIZE;
+        soundcard_position += fragment_size;
         VERBOSE(VB_AUDIO, "Broadcasting free space avail");
         pthread_cond_broadcast(&audio_bufsig);
 
Index: libs/libmyth/audiooutput.h
===================================================================
--- libs/libmyth/audiooutput.h	(revision 8338)
+++ libs/libmyth/audiooutput.h	(working copy)
@@ -51,7 +51,7 @@
     // Wait for all data to finish playing
     virtual void Drain(void) = 0;
 
-    virtual int GetAudiotime(void) = 0;
+    virtual long long GetAudiotime(void) = 0;
 
     virtual void SetSourceBitrate(int ) { }
 
Index: programs/mythtranscode/transcode.cpp
===================================================================
--- programs/mythtranscode/transcode.cpp	(revision 8338)
+++ programs/mythtranscode/transcode.cpp	(working copy)
@@ -137,7 +137,7 @@
         return;
     }
 
-    virtual int GetAudiotime(void)
+    virtual long long GetAudiotime(void)
     {
         return last_audiotime;
     }
