Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 23717)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -7202,14 +7202,11 @@
     }
     else
     {
-        // BEGIN HACK
-        // Like frame based subtitles this can get out of sync after
-        // transcoding, using the raw timecode doesn't work either
-        // with DTV broadcasts where the timecode isn't zero on the
-        // first frame, and may roll over during the broadcast.
-        playPos = (uint64_t)
-            ((currentFrame->frameNumber / video_frame_rate) * 1000);
-        // END HACK
+        // Use timecodes for time based SRT subtitles. Feeding this into
+        // NormalizeVideoTimecode should adjust for non-zero start times
+        // and wraps. For MPEG wraps will occur just once every 26.5 hours
+        // so this should be sufficient.
+        playPos = GetDecoder()->NormalizeVideoTimecode(currentFrame->timecode);
     }
 
     if (!textSubtitles.HasSubtitleChanged(playPos))
Index: libs/libmythtv/decoderbase.h
===================================================================
--- libs/libmythtv/decoderbase.h	(revision 23717)
+++ libs/libmythtv/decoderbase.h	(working copy)
@@ -113,6 +113,8 @@
     virtual bool DoRewind(long long desiredFrame, bool doflush = true);
     virtual bool DoFastForward(long long desiredFrame, bool doflush = true);
 
+    virtual int64_t NormalizeVideoTimecode(int64_t timecode) { return timecode; }
+
     virtual bool isLastFrameKey() = 0;
     virtual void WriteStoredData(RingBuffer *rb, bool storevid,
                                  long timecodeOffset) = 0;
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 23717)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -616,6 +616,36 @@
     return  ((lsb - base_ts)&mask);
 }
 
+int64_t AvFormatDecoder::NormalizeVideoTimecode(int64_t timecode)
+{
+    AVStream *st = NULL;
+    for (uint i = 0; i < ic->nb_streams; i++)
+    {
+        AVStream *st1 = ic->streams[i];
+        if (st1 && st1->codec->codec_type == CODEC_TYPE_VIDEO)
+        {
+            st = st1;
+            break;
+        }
+    }
+    if (!st)
+        return false;
+
+   // convert timecode and start_time to AV_TIME_BASE units
+   int64_t start_ts = av_rescale(ic->start_time,
+                                 st->time_base.den,
+                                 AV_TIME_BASE * (int64_t)st->time_base.num);
+
+   int64_t ts = av_rescale(timecode / 1000.0 * AV_TIME_BASE,
+                           st->time_base.den,
+                           AV_TIME_BASE * (int64_t)st->time_base.num);
+
+   // adjust for start time and wrap
+   ts = lsb3full(ts, start_ts, st->pts_wrap_bits);
+
+   return (int64_t)(av_q2d(st->time_base) * ts * 1000);
+}
+
 int AvFormatDecoder::GetNumChapters()
 {
     return ic->nb_chapters;
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 23717)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -141,6 +141,8 @@
     virtual bool DoRewind(long long desiredFrame, bool doflush = true);
     virtual bool DoFastForward(long long desiredFrame, bool doflush = true);
 
+    virtual int64_t NormalizeVideoTimecode(int64_t timecode);
+
     virtual int  GetTeletextDecoderType(void) const;
     virtual void SetTeletextDecoderViewer(TeletextViewer*);
 
