Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 8189)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -8,6 +8,7 @@
 using namespace std;
 
 // MythTV headers
+#include "mythconfig.h" // for CONFIG_DTS
 #include "avformatdecoder.h"
 #include "RingBuffer.h"
 #include "NuppelVideoPlayer.h"
@@ -36,6 +37,15 @@
 /** Set to zero to allow any number of AC3 channels. */
 #define MAX_OUTPUT_CHANNELS 2
 
+#define VB_AUDIO VB_IMPORTANT
+
+static int dts_syncinfo(uint8_t *indata_ptr, int *flags,
+                        int *sample_rate, int *bit_rate);
+static int dts_decode_header(uint8_t *indata_ptr, int *rate,
+                             int *nblks, int *sfreq);
+static int encode_frame(bool dts, unsigned char* data, int len,
+                        short *samples, int &samples_size);
+
 extern pthread_mutex_t avcodeclock;
 
 int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
@@ -172,6 +182,7 @@
       // Audio
       audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
       allow_ac3_passthru(false),
+      allow_dts_passthru(false),
       // Audio selection
       wantedAudioStream(),    selectedAudioStream(),
       // Subtitle selection
@@ -188,6 +199,9 @@
 
     save_cctc[0] = save_cctc[1] = 0;
     allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
+#ifdef CONFIG_DTS
+    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
+#endif // CONFIG_DTS
 
     audioIn.sample_size = -32; // force SetupAudioStream to run once
 }
@@ -1707,7 +1721,7 @@
     return list;
 }
 
-vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
+static vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
 {
     vector<int> ret;
 
@@ -1718,9 +1732,10 @@
     return ret;
 }
 
-int filter_ac3(const AVFormatContext *ic,
-               const sinfo_vec_t     &audioStreams,
-               const vector<int>     &fs)
+static int filter_codec(const AVFormatContext *ic,
+                        const CodecID          codec,
+                        const sinfo_vec_t     &audioStreams,
+                        const vector<int>     &fs)
 {
     int selectedTrack = -1;
 
@@ -1729,7 +1744,7 @@
     {
         const int stream_index    = audioStreams[*it].av_stream_index;
         const AVCodecContext *ctx = ic->streams[stream_index]->codec;
-        if (CODEC_ID_AC3 == ctx->codec_id)
+        if (codec == ctx->codec_id)
         {
             selectedTrack = *it;
             break;
@@ -1739,9 +1754,9 @@
     return selectedTrack;
 }
 
-int filter_max_ch(const AVFormatContext *ic,
-                  const sinfo_vec_t     &audioStreams,
-                  const vector<int>     &fs)
+static int filter_max_ch(const AVFormatContext *ic,
+                         const sinfo_vec_t     &audioStreams,
+                         const vector<int>     &fs)
 {
     int selectedTrack = -1, max_seen = -1;
 
@@ -1796,10 +1811,13 @@
     {
         int idx = audioStreams[i].av_stream_index;
         AVCodecContext *codec_ctx = ic->streams[idx]->codec;
+        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
+                                (codec_ctx->codec_id == CODEC_ID_AC3));
+        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
+                                (codec_ctx->codec_id == CODEC_ID_DTS));
         AudioInfo item(codec_ctx->codec_id,
                        codec_ctx->sample_rate, codec_ctx->channels,
-                       (allow_ac3_passthru && !transcoding &&
-                        (codec_ctx->codec_id == CODEC_ID_AC3)));
+                       do_ac3_passthru || do_dts_passthru);
         VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
     }
 #endif
@@ -1829,21 +1847,31 @@
         // try to get best track for most preferred language
         selectedTrack = -1;
         vector<int>::const_iterator it = languagePreference.begin();
-        for (; it !=  languagePreference.end(); ++it)
+        for (; it !=  languagePreference.end() && selectedTrack<0; ++it)
         {
             vector<int> flang = filter_lang(audioStreams, *it);
-            if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) >= 0)
-                break;
-            if ((selectedTrack = filter_max_ch(ic, audioStreams, flang)) >= 0)
-                break;
+            if (allow_dts_passthru && !transcoding)
+                selectedTrack = filter_codec(ic, CODEC_ID_DTS,
+                                             audioStreams, flang);
+            if (selectedTrack < 0)
+                selectedTrack = filter_codec(ic, CODEC_ID_AC3,
+                                             audioStreams, flang);
+            if (selectedTrack < 0)
+                selectedTrack = filter_max_ch(ic, audioStreams, flang);
         }
         // try to get best track for any language
         if (selectedTrack < 0)
         {
             VERBOSE(VB_AUDIO, LOC + "Trying to select audio track (wo/lang)");
             vector<int> flang = filter_lang(audioStreams, -1);
-            if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) < 0)
-                selectedTrack  = filter_max_ch(ic, audioStreams, flang);
+            if (allow_dts_passthru && !transcoding)
+                selectedTrack = filter_codec(ic, CODEC_ID_DTS,
+                                             audioStreams, flang);
+            if (selectedTrack < 0)
+                selectedTrack = filter_codec(ic, CODEC_ID_AC3,
+                                             audioStreams, flang);
+            if (selectedTrack < 0)
+                selectedTrack = filter_max_ch(ic, audioStreams, flang);
         }
     }
 
@@ -2225,11 +2253,12 @@
                     pthread_mutex_lock(&avcodeclock);
                     ret = len;
                     data_size = 0;
-                    if (audioOut.do_ac3_passthru)
+                    if (audioOut.do_passthru)
                     {
                         data_size = pkt->size;
-                        ret = EncodeAC3Frame(ptr, len, audioSamples,
-                                             data_size);
+                        bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
+                        ret = encode_frame(
+                            dts, ptr, len, audioSamples, data_size);
                     }
                     else
                     {
@@ -2459,12 +2488,14 @@
     {
         assert(curstream);
         assert(curstream->codec);
-        codec_ctx = curstream->codec;        
+        codec_ctx = curstream->codec;
         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
                                 (codec_ctx->codec_id == CODEC_ID_AC3));
+        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
+                                (codec_ctx->codec_id == CODEC_ID_DTS));
         info = AudioInfo(codec_ctx->codec_id,
                          codec_ctx->sample_rate, codec_ctx->channels,
-                         do_ac3_passthru);
+                         do_ac3_passthru || do_dts_passthru);
     }
 
     if (info == audioIn)
@@ -2474,7 +2505,7 @@
             QString("audio track #%1").arg(currentAudioTrack+1));
 
     audioOut = audioIn = info;
-    if (audioIn.do_ac3_passthru)
+    if (audioIn.do_passthru)
     {
         // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
         audioOut.channels    = 2;
@@ -2506,8 +2537,8 @@
     return true;
 }
 
-int AvFormatDecoder::EncodeAC3Frame(unsigned char *data, int len,
-                                    short *samples, int &samples_size)
+static int encode_frame(bool dts, unsigned char *data, int len,
+                        short *samples, int &samples_size)
 {
     int enc_len;
     int flags, sample_rate, bit_rate;
@@ -2521,7 +2552,20 @@
     // ignore, and if so, may as well just assume that it will ignore
     // anything with a bad CRC...
 
-    enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
+    uint nr_samples = 0, block_len;
+    if (dts)
+    {
+        enc_len = dts_syncinfo(data, &flags, &sample_rate, &bit_rate);
+        int rate, sfreq, nblks;
+        dts_decode_header(data, &rate, &nblks, &sfreq);
+        nr_samples = nblks * 32;
+        block_len = nr_samples * 2 * 2;
+    }
+    else
+    {
+        enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
+        block_len = MAX_AC3_FRAME_SIZE;
+    }
 
     if (enc_len == 0 || enc_len > len)
     {
@@ -2529,8 +2573,7 @@
         return len;
     }
 
-    if (enc_len > MAX_AC3_FRAME_SIZE - 8)
-        enc_len = MAX_AC3_FRAME_SIZE - 8;
+    enc_len = min((uint)enc_len, block_len - 8);
 
     swab(data, ucsamples + 8, enc_len);
 
@@ -2544,10 +2587,28 @@
     ucsamples[5] = 0x00;
     ucsamples[6] = (enc_len << 3) & 0xFF;
     ucsamples[7] = (enc_len >> 5) & 0xFF;
-    memset(ucsamples + 8 + enc_len, 0, MAX_AC3_FRAME_SIZE - 8 - enc_len);
-    samples_size = MAX_AC3_FRAME_SIZE;
+    memset(ucsamples + 8 + enc_len, 0, block_len - 8 - enc_len);
+    samples_size = block_len;
 
-    return len;  // consume whole frame even if len > enc_len ?
+    if (dts)
+    {
+        // the following values come from libmpcodecs
+        static const unsigned char magic[8] =
+            { 0x0, 0xB, 0xC, 0x0, 0xD, 0x0, 0x0, 0x0 };
+        //         512  1024      2048
+        static const uint bad_bits = ~(111<<9);
+
+        ucsamples[4] = magic[(nr_samples>>9)&0x3];
+        if (nr_samples & bad_bits || ucsamples[4]==0)
+        {
+            VERBOSE(VB_IMPORTANT, LOC +
+                    QString("DTS: %1-sample bursts not supported")
+                    .arg(nr_samples));
+            ucsamples[4] = 0x00;
+        }
+    }
+
+    return enc_len;
 }
 
 void AvFormatDecoder::AddTextData(unsigned char *buf, int len,
@@ -2555,3 +2616,102 @@
 {
     m_parent->AddTextData((char*)buf, len, timecode, type);
 }
+  
+/// DTS passthru info
+static const int DTS_SAMPLEFREQS[16] =
+{
+    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
+    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000,
+};
+
+/// DTS passthru info
+static const int DTS_BITRATES[30] =
+{
+    32000,    56000,    64000,    96000,    112000,   128000,
+    192000,   224000,   256000,   320000,   384000,   448000,
+    512000,   576000,   640000,   768000,   896000,   1024000,
+    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
+    1536000,  1920000,  2048000,  3072000,  3840000,  4096000,
+};
+
+/// DTS passthru func
+static int dts_syncinfo(uint8_t *indata_ptr, int */*flags*/,
+                        int *sample_rate, int *bit_rate)
+{
+    int nblks;
+    int rate;
+    int sfreq;
+
+    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
+    if (fsize >= 0)
+    {
+        if (rate >= 0 && rate <= 29)
+            *bit_rate = DTS_BITRATES[rate];
+        else
+            *bit_rate = 0;
+        if (sfreq >= 1 && sfreq <= 15)
+            *sample_rate = DTS_SAMPLEFREQS[sfreq];
+        else
+            *sample_rate = 0;
+    }
+    return fsize;
+}
+
+/// DTS passthru func
+static int dts_decode_header(uint8_t *indata_ptr, int *rate,
+                             int *nblks, int *sfreq)
+{
+    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
+               (indata_ptr[2] << 8)  | (indata_ptr[3]));
+
+    if (id != 0x7ffe8001)
+        return -1;
+
+    int ftype, surp, fsize;
+
+    ftype  = (indata_ptr[4] >> 7);
+    surp   = (indata_ptr[4] >> 2) & 0x1f;
+    surp   = (surp + 1) % 32;
+
+    *nblks = ((indata_ptr[4] & 0x01) << 6) | (indata_ptr[5] >> 2);
+    *nblks = *nblks + 1;
+
+    fsize  = ((indata_ptr[5] & 0x03) << 12 |
+              (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4)) + 1;
+
+    *sfreq = ((indata_ptr[8] >> 2) & 0x0f);
+    *rate  = ((indata_ptr[8] & 0x03) << 3) | ((indata_ptr[9] >> 5) & 0x07);
+
+    if (ftype != 1)
+    {
+        VERBOSE(VB_IMPORTANT, LOC +
+                QString("DTS: Termination frames not handled (ftype %1)")
+                .arg(ftype));
+        return -1;
+    }
+
+    if (*sfreq != 13)
+    {
+        VERBOSE(VB_IMPORTANT, LOC +
+                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
+        return -1;
+    }
+
+    if ((fsize > 8192) || (fsize < 96))
+    {
+        VERBOSE(VB_IMPORTANT, LOC +
+                QString("DTS: fsize: %1 invalid").arg(fsize));
+        return -1;
+    }
+
+    if ((*nblks != 8)  && (*nblks != 16)  && (*nblks != 32) &&
+        (*nblks != 64) && (*nblks != 128) && (ftype == 1))
+    {
+        VERBOSE(VB_IMPORTANT, LOC +
+                QString("DTS: nblks %1 not valid for normal frame")
+                .arg(*nblks));
+        return -1;
+    }
+
+    return fsize;
+}
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 8189)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -38,17 +38,17 @@
   public:
     AudioInfo() :
         codec_id(CODEC_ID_NONE), sample_size(-2),   sample_rate(-1),
-        channels(-1), do_ac3_passthru(false)
+        channels(-1), do_passthru(false)
     {;}
 
     AudioInfo(CodecID id, int sr, int ch, bool ac3) :
         codec_id(id), sample_size(ch*2),   sample_rate(sr),
-        channels(ch), do_ac3_passthru(ac3)
+        channels(ch), do_passthru(ac3)
     {;}
 
     CodecID codec_id;
     int sample_size, sample_rate, channels;
-    bool do_ac3_passthru;
+    bool do_passthru;
 
     /// \brief Bits per sample.
     int bps(void) const { return (8 * sample_size) / channels; }
@@ -56,14 +56,14 @@
     {
         return (codec_id==o.codec_id        && channels==o.channels       &&
                 sample_size==o.sample_size  && sample_rate==o.sample_rate &&
-                do_ac3_passthru==o.do_ac3_passthru);
+                do_passthru==o.do_passthru);
     }
     QString toString() const
     {
         return QString("id(%1) %2Hz %3ch %4bps%5")
             .arg(codec_id_string(codec_id),4).arg(sample_rate,5)
             .arg(channels,2).arg(bps(),3)
-            .arg((do_ac3_passthru) ? "pt":"",3);
+            .arg((do_passthru) ? "pt":"",3);
     }
 };
 
@@ -183,9 +183,6 @@
 
     bool SetupAudioStream(void);
 
-    int EncodeAC3Frame(unsigned char* data, int len, short *samples,
-                       int &samples_size);
-
     // Update our position map, keyframe distance, and the like.  Called for key frame packets.
     void HandleGopStart(AVPacket *pkt);
 
@@ -233,6 +230,7 @@
     // Audio
     short int        *audioSamples;
     bool              allow_ac3_passthru;
+    bool              allow_dts_passthru;
 
     AudioInfo         audioIn;
     AudioInfo         audioOut;
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 8189)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -133,6 +133,20 @@
     return gc;
 }
 
+#ifdef CONFIG_DTS
+static HostCheckBox *DTSPassThrough()
+{
+    HostCheckBox *gc = new HostCheckBox("DTSPassThru");
+    gc->setLabel(QObject::tr("Enable DTS to SPDIF passthrough"));
+    gc->setValue(false);
+    gc->setHelpText(QObject::tr("Enable sending DTS audio directly to your "
+                    "sound card's SPDIF output, on sources which contain "
+                    "DTS soundtracks (usually DVDs).  Requires that the "
+                    "audio output device be set to something suitable."));
+    return gc;
+}
+#endif
+
 static HostCheckBox *Deinterlace()
 {
     HostCheckBox *gc = new HostCheckBox("Deinterlace");
@@ -2069,6 +2083,9 @@
 
          addChild(AudioOutputDevice());
          addChild(AC3PassThrough());
+#ifdef CONFIG_DTS
+         addChild(DTSPassThrough());
+#endif
          addChild(AggressiveBuffer());
 
          Setting* volumeControl = MythControlsVolume();
Index: configure
===================================================================
--- configure	(revision 8189)
+++ configure	(working copy)
@@ -334,7 +334,7 @@
 x264="no"
 a52="yes"
 a52bin="no"
-dts="no"
+dts="yes"
 pp="yes"
 shared_pp="no"
 mingw32="no"
@@ -682,8 +682,10 @@
   ;;
   --enable-a52bin) a52bin="yes"
   ;;
-  --enable-dts) dts="yes" ; extralibs="$extralibs -ldts"
+  --enable-dts) dts="yes"
   ;;
+  --disable-dts) dts="no"
+  ;;
   --disable-pp) pp="no"
   ;;
   --enable-shared-pp) shared_pp="yes"
@@ -1920,6 +1922,14 @@
 mandir="${prefix}/man"
 fi
 
+if test x"$dts" = x"yes"; then
+    dts = "no"
+    if has_library libdts ; then
+        dts = "yes"
+        extralibs="$extralibs -ldts"
+    fi
+fi
+
 if test x"$dvb" = x"yes" ; then
     dvb="no"
     if test -f "$dvb_path"/linux/dvb/frontend.h ; then
@@ -2187,6 +2197,7 @@
   echo "ALSA support     $audio_alsa"
   echo "aRts support     $audio_arts"
   echo "JACK support     $audio_jack"
+  echo "DTS passthrough  $dts"
   echo
   echo "# Video Output Support"
   echo "x11 support      $x11"
