Ticket #730: mythtv-dtspassthru.3.patch

File mythtv-dtspassthru.3.patch, 21.8 KB (added by martin@…, 20 years ago)

Updated DTS patch, merged with Daniel's changes. Against r8268

  • configure

     
    334334x264="no"
    335335a52="yes"
    336336a52bin="no"
    337 dts="no"
     337dts="yes"
    338338pp="yes"
    339339shared_pp="no"
    340340mingw32="no"
     
    682682  ;;
    683683  --enable-a52bin) a52bin="yes"
    684684  ;;
    685   --enable-dts) dts="yes" ; extralibs="$extralibs -ldts"
     685  --enable-dts) dts="yes"
    686686  ;;
     687  --disable-dts) dts="no"
     688  ;;
    687689  --disable-pp) pp="no"
    688690  ;;
    689691  --enable-shared-pp) shared_pp="yes"
     
    19201922mandir="${prefix}/man"
    19211923fi
    19221924
     1925if test x"$dts" = x"yes"; then
     1926    dts="no"
     1927    if has_library libdts ; then
     1928        dts="yes"
     1929        extralibs="$extralibs -ldts"
     1930    fi
     1931fi
     1932
    19231933if test x"$dvb" = x"yes" ; then
    19241934    dvb="no"
    19251935    if test -f "$dvb_path"/linux/dvb/frontend.h ; then
     
    21872197  echo "ALSA support     $audio_alsa"
    21882198  echo "aRts support     $audio_arts"
    21892199  echo "JACK support     $audio_jack"
     2200  echo "DTS passthrough  $dts"
    21902201  echo
    21912202  echo "# Video Output Support"
    21922203  echo "x11 support      $x11"
  • libs/libmythtv/avformatdecoder.cpp

     
    88using namespace std;
    99
    1010// MythTV headers
     11#include "mythconfig.h" // for CONFIG_DTS
    1112#include "avformatdecoder.h"
    1213#include "RingBuffer.h"
    1314#include "NuppelVideoPlayer.h"
     
    3940/** Set to zero to allow any number of AC3 channels. */
    4041#define MAX_OUTPUT_CHANNELS 2
    4142
     43static int dts_syncinfo(uint8_t *indata_ptr, int *flags,
     44                        int *sample_rate, int *bit_rate);
     45static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     46                             int *nblks, int *sfreq);
     47static int encode_frame(bool dts, unsigned char* data, int len,
     48                        short *samples, int &samples_size);
     49
    4250extern pthread_mutex_t avcodeclock;
    4351
    4452int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
     
    181189      // Audio
    182190      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    183191      allow_ac3_passthru(false),
     192      allow_dts_passthru(false),
    184193      // Audio selection
    185194      wantedAudioStream(),    selectedAudioStream(),
    186195      // Subtitle selection
     
    197206
    198207    save_cctc[0] = save_cctc[1] = 0;
    199208    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
     209#ifdef CONFIG_DTS
     210    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     211#endif
    200212
    201213    audioIn.sample_size = -32; // force SetupAudioStream to run once
    202214}
     
    948960                            <<") already open, leaving it alone.");
    949961                }
    950962                assert(enc->codec_id);
     963                if (enc->codec_id == CODEC_ID_DTS)
     964                {
     965                    enc->sample_rate = 48000;
     966                    enc->channels = 2;
     967                    // enc->bit_rate = what??;
     968                }
    951969                bitrate += enc->bit_rate;
    952970                break;
    953971            }
     
    17331751    return list;
    17341752}
    17351753
    1736 vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
     1754static vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
    17371755{
    17381756    vector<int> ret;
    17391757
     
    17441762    return ret;
    17451763}
    17461764
    1747 int filter_ac3(const AVFormatContext *ic,
    1748                const sinfo_vec_t     &audioStreams,
    1749                const vector<int>     &fs)
     1765static int filter_max_ch(const AVFormatContext *ic,
     1766                         const sinfo_vec_t     &audioStreams,
     1767                         const vector<int>     &fs,
     1768                         enum CodecID           codecId = CODEC_ID_NONE)
    17501769{
    1751     int selectedTrack = -1;
    1752 
    1753     vector<int>::const_iterator it = fs.begin();
    1754     for (; it != fs.end(); ++it)
    1755     {
    1756         const int stream_index    = audioStreams[*it].av_stream_index;
    1757         const AVCodecContext *ctx = ic->streams[stream_index]->codec;
    1758         if (CODEC_ID_AC3 == ctx->codec_id)
    1759         {
    1760             selectedTrack = *it;
    1761             break;
    1762         }
    1763     }
    1764 
    1765     return selectedTrack;
    1766 }
    1767 
    1768 int filter_max_ch(const AVFormatContext *ic,
    1769                   const sinfo_vec_t     &audioStreams,
    1770                   const vector<int>     &fs)
    1771 {
    17721770    int selectedTrack = -1, max_seen = -1;
    17731771
    17741772    vector<int>::const_iterator it = fs.begin();
     
    17761774    {
    17771775        const int stream_index    = audioStreams[*it].av_stream_index;
    17781776        const AVCodecContext *ctx = ic->streams[stream_index]->codec;
    1779         if (max_seen < ctx->channels)
     1777        if (codecId == CODEC_ID_NONE || codecId == ctx->codec_id)
    17801778        {
    1781             selectedTrack = *it;
    1782             max_seen = ctx->channels;
     1779            if (max_seen < ctx->channels)
     1780            {
     1781                selectedTrack = *it;
     1782                max_seen = ctx->channels;
     1783            }
    17831784        }
    17841785    }
    17851786
     
    17891790/** \fn AvFormatDecoder::autoSelectAudioTrack(void)
    17901791 *  \brief Selects the best audio track.
    17911792 *
    1792  *   This function will select the best audio track
    1793  *   available using the following rules:
     1793 *   This function will select the best audio track available
     1794 *   using the following criteria, in order of decreasing
     1795 *   preference:
    17941796 *
    1795  *   First we try to select the stream last selected by the
    1796  *   user, which is recalled as the Nth stream in the
    1797  *   preferred language. If it can not be located we attempt
    1798  *   to find a stream in the same language.
     1797 *   1) The stream last selected by the user, which is
     1798 *      recalled as the Nth stream in the preferred language.
     1799 *      If it can not be located we attempt to find a stream
     1800 *     in the same language.
    17991801 *
    1800  *   If we can not reselect the last user selected stream,
    1801  *   then for each preferred language from most preferred to
    1802  *   least preferred, we try to use the first AC3 track found,
    1803  *   or if no AC3 audio is found then we try to select the
    1804  *   audio track with the greatest number of audio channels.
     1802 *   2) If we can not reselect the last user selected stream,
     1803 *      then for each preferred language from most preferred
     1804 *      to least preferred, we try to find a new stream based
     1805 *      on the algorithm below.
    18051806 *
    1806  *   If we can not select a stream in a preferred language
    1807  *   we try to use the first AC3 track found irrespective
    1808  *   of language, and if no AC3 audio is found then we try
    1809  *   to select the audio track with the greatest number of
    1810  *   audio channels.
     1807 *   3) If we can not select a stream in a preferred language
     1808 *      we try to select a stream irrespective of language
     1809 *      based on the algorithm below.
     1810 *
     1811 *   When searching for a new stream (ie. options 2 and 3
     1812 *   above), the following search is carried out in order:
     1813 *
     1814 *   i)   If DTS passthrough is enabled then the DTS track with
     1815 *        the greatest number of audio channels is selected
     1816 *        (the first will be chosen if there are several the
     1817 *        same). If DTS passthrough is not enabled this step
     1818 *        will be skipped because internal DTS decoding is not
     1819 *        currently supported.
     1820 *
     1821 *   ii)  If no DTS track is chosen, the AC3 track with the
     1822 *        greatest number of audio channels is selected (the
     1823 *        first will be chosen if there are several the same).
     1824 *        Internal decoding of AC3 is supported, so this will
     1825 *        be used irrespective of whether AC3 passthrough is
     1826 *        enabled.
     1827 *
     1828 *   iii) Lastly the track with the greatest number of audio
     1829 *        channels irrespective of type will be selected.
    18111830 *  \return true if a track was selected, false otherwise
    18121831 */
    18131832bool AvFormatDecoder::autoSelectAudioTrack(void)
     
    18221841    {
    18231842        int idx = audioStreams[i].av_stream_index;
    18241843        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
     1844        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
     1845                                (codec_ctx->codec_id == CODEC_ID_AC3));
     1846        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
     1847                                (codec_ctx->codec_id == CODEC_ID_DTS));
    18251848        AudioInfo item(codec_ctx->codec_id,
    18261849                       codec_ctx->sample_rate, codec_ctx->channels,
    1827                        (allow_ac3_passthru && !transcoding &&
    1828                         (codec_ctx->codec_id == CODEC_ID_AC3)));
     1850                       do_ac3_passthru || do_dts_passthru);
    18291851        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
    18301852    }
    18311853#endif
     
    18551877        // try to get best track for most preferred language
    18561878        selectedTrack = -1;
    18571879        vector<int>::const_iterator it = languagePreference.begin();
    1858         for (; it !=  languagePreference.end(); ++it)
     1880        for (; it !=  languagePreference.end() && selectedTrack<0; ++it)
    18591881        {
    18601882            vector<int> flang = filter_lang(audioStreams, *it);
    1861             if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) >= 0)
    1862                 break;
    1863             if ((selectedTrack = filter_max_ch(ic, audioStreams, flang)) >= 0)
    1864                 break;
     1883            if (allow_dts_passthru && !transcoding)
     1884                selectedTrack = filter_max_ch(ic, audioStreams, flang,
     1885                                              CODEC_ID_DTS);
     1886            if (selectedTrack < 0)
     1887                selectedTrack = filter_max_ch(ic, audioStreams, flang,
     1888                                              CODEC_ID_AC3);
     1889            if (selectedTrack < 0)
     1890                selectedTrack = filter_max_ch(ic, audioStreams, flang);
    18651891        }
    18661892        // try to get best track for any language
    18671893        if (selectedTrack < 0)
    18681894        {
    18691895            VERBOSE(VB_AUDIO, LOC + "Trying to select audio track (wo/lang)");
    18701896            vector<int> flang = filter_lang(audioStreams, -1);
    1871             if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) < 0)
    1872                 selectedTrack  = filter_max_ch(ic, audioStreams, flang);
     1897            if (allow_dts_passthru && !transcoding)
     1898                selectedTrack = filter_max_ch(ic, audioStreams, flang,
     1899                                              CODEC_ID_DTS);
     1900            if (selectedTrack < 0)
     1901                selectedTrack = filter_max_ch(ic, audioStreams, flang,
     1902                                              CODEC_ID_AC3);
     1903            if (selectedTrack < 0)
     1904                selectedTrack = filter_max_ch(ic, audioStreams, flang);
    18731905        }
    18741906    }
    18751907
     
    22822314                    pthread_mutex_lock(&avcodeclock);
    22832315                    ret = len;
    22842316                    data_size = 0;
    2285                     if (audioOut.do_ac3_passthru)
     2317                    if (audioOut.do_passthru)
    22862318                    {
    22872319                        data_size = pkt->size;
    2288                         ret = EncodeAC3Frame(ptr, len, audioSamples,
    2289                                              data_size);
     2320                        bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
     2321                        ret = encode_frame(dts, ptr, len,
     2322                                           audioSamples, data_size);
    22902323                    }
    22912324                    else
    22922325                    {
     
    23142347                    }
    23152348                    pthread_mutex_unlock(&avcodeclock);
    23162349
    2317                     ptr += ret;
    2318                     len -= ret;
    23192350
    23202351                    if (data_size <= 0)
     2352                    {
     2353                        ptr += ret;
     2354                        len -= ret;
    23212355                        continue;
     2356                    }
    23222357
    23232358                    long long temppts = lastapts;
    23242359
     
    25162551    {
    25172552        assert(curstream);
    25182553        assert(curstream->codec);
    2519         codec_ctx = curstream->codec;       
     2554        codec_ctx = curstream->codec;
    25202555        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    25212556                                (codec_ctx->codec_id == CODEC_ID_AC3));
     2557        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
     2558                                (codec_ctx->codec_id == CODEC_ID_DTS));
    25222559        info = AudioInfo(codec_ctx->codec_id,
    25232560                         codec_ctx->sample_rate, codec_ctx->channels,
    2524                          do_ac3_passthru);
     2561                         do_ac3_passthru || do_dts_passthru);
    25252562    }
    25262563
    25272564    if (info == audioIn)
     
    25312568            QString("audio track #%1").arg(currentAudioTrack+1));
    25322569
    25332570    audioOut = audioIn = info;
    2534     if (audioIn.do_ac3_passthru)
     2571    if (audioIn.do_passthru)
    25352572    {
    25362573        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    25372574        audioOut.channels    = 2;
     
    25632600    return true;
    25642601}
    25652602
    2566 int AvFormatDecoder::EncodeAC3Frame(unsigned char *data, int len,
    2567                                     short *samples, int &samples_size)
     2603static int encode_frame(bool dts, unsigned char *data, int len,
     2604                        short *samples, int &samples_size)
    25682605{
    25692606    int enc_len;
    25702607    int flags, sample_rate, bit_rate;
     
    25782615    // ignore, and if so, may as well just assume that it will ignore
    25792616    // anything with a bad CRC...
    25802617
    2581     enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2618    uint nr_samples = 0, block_len;
     2619    if(dts)
     2620    {
     2621        enc_len = dts_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2622        int rate, sfreq, nblks;
     2623        dts_decode_header(data, &rate, &nblks, &sfreq);
     2624        nr_samples = nblks * 32;
     2625        block_len = nr_samples * 2 * 2;
     2626    }
     2627    else
     2628    {
     2629        enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2630        block_len = MAX_AC3_FRAME_SIZE;
     2631    }
    25822632
    25832633    if (enc_len == 0 || enc_len > len)
    25842634    {
     
    25862636        return len;
    25872637    }
    25882638
    2589     if (enc_len > MAX_AC3_FRAME_SIZE - 8)
    2590         enc_len = MAX_AC3_FRAME_SIZE - 8;
     2639    enc_len = min((uint)enc_len, block_len - 8);
    25912640
    25922641    swab(data, ucsamples + 8, enc_len);
    25932642
    2594     // the following values come from ao_hwac3.c in mplayer.
     2643    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
    25952644    // they form a valid IEC958 AC3 header.
    25962645    ucsamples[0] = 0x72;
    25972646    ucsamples[1] = 0xF8;
    25982647    ucsamples[2] = 0x1F;
    25992648    ucsamples[3] = 0x4E;
    2600     ucsamples[4] = 0x01;
     2649    if(dts)
     2650    {
     2651        switch(nr_samples)
     2652        {
     2653            case 512:
     2654                ucsamples[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     2655                break;
     2656
     2657            case 1024:
     2658                ucsamples[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     2659                break;
     2660
     2661            case 2048:
     2662                ucsamples[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     2663                break;
     2664
     2665            default:
     2666                VERBOSE(VB_IMPORTANT, LOC +
     2667                        QString("DTS: %1-sample bursts not supported")
     2668                        .arg(nr_samples));
     2669                ucsamples[4] = 0x00;
     2670                break;
     2671        }
     2672    }
     2673    else
     2674    {
     2675        ucsamples[4] = 0x01;
     2676    }
    26012677    ucsamples[5] = 0x00;
    26022678    ucsamples[6] = (enc_len << 3) & 0xFF;
    26032679    ucsamples[7] = (enc_len >> 5) & 0xFF;
    2604     memset(ucsamples + 8 + enc_len, 0, MAX_AC3_FRAME_SIZE - 8 - enc_len);
    2605     samples_size = MAX_AC3_FRAME_SIZE;
     2680    memset(ucsamples + 8 + enc_len, 0, block_len - 8 - enc_len);
     2681    samples_size = block_len;
    26062682
    2607     return len;  // consume whole frame even if len > enc_len ?
     2683    return enc_len;
    26082684}
    26092685
    26102686void AvFormatDecoder::AddTextData(unsigned char *buf, int len,
     
    26122688{
    26132689    m_parent->AddTextData((char*)buf, len, timecode, type);
    26142690}
     2691 
     2692static int DTS_SAMPLEFREQS[16] =
     2693{
     2694    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     2695    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     2696};
     2697
     2698static int DTS_BITRATES[30] =
     2699{
     2700    32000,    56000,    64000,    96000,    112000,   128000,
     2701    192000,   224000,   256000,   320000,   384000,   448000,
     2702    512000,   576000,   640000,   768000,   896000,   1024000,
     2703    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     2704    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     2705};
     2706
     2707static int dts_syncinfo(uint8_t *indata_ptr, int */*flags*/,
     2708                        int *sample_rate, int *bit_rate)
     2709{
     2710    int nblks;
     2711    int rate;
     2712    int sfreq;
     2713
     2714    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     2715    if(fsize >= 0)
     2716    {
     2717        if(rate >= 0 && rate <= 29)
     2718            *bit_rate = DTS_BITRATES[rate];
     2719        else
     2720            *bit_rate = 0;
     2721        if(sfreq >= 1 && sfreq <= 15)
     2722            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     2723        else
     2724            *sample_rate = 0;
     2725    }
     2726    return fsize;
     2727}
     2728
     2729static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     2730                             int *nblks, int *sfreq)
     2731{
     2732    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     2733               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     2734
     2735    if (id != 0x7ffe8001)
     2736        return -1;
     2737
     2738    int ftype = indata_ptr[4] >> 7;
     2739
     2740    int surp = (indata_ptr[4] >> 2) & 0x1f;
     2741    surp = (surp + 1) % 32;
     2742
     2743    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     2744    ++*nblks;
     2745
     2746    int fsize = (indata_ptr[5] & 0x03) << 12 |
     2747                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     2748    ++fsize;
     2749
     2750    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     2751    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     2752
     2753    if(ftype != 1)
     2754    {
     2755        VERBOSE(VB_IMPORTANT, LOC +
     2756                QString("DTS: Termination frames not handled (ftype %1)")
     2757                .arg(ftype));
     2758        return -1;
     2759    }
     2760
     2761    if(*sfreq != 13)
     2762    {
     2763        VERBOSE(VB_IMPORTANT, LOC +
     2764                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     2765        return -1;
     2766    }
     2767
     2768    if((fsize > 8192) || (fsize < 96))
     2769    {
     2770        VERBOSE(VB_IMPORTANT, LOC +
     2771                QString("DTS: fsize: %1 invalid").arg(fsize));
     2772        return -1;
     2773    }
     2774
     2775    if(*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     2776       *nblks != 64 && *nblks != 128 && ftype == 1)
     2777    {
     2778        VERBOSE(VB_IMPORTANT, LOC +
     2779                QString("DTS: nblks %1 not valid for normal frame")
     2780                .arg(*nblks));
     2781        return -1;
     2782    }
     2783
     2784    return fsize;
     2785}
  • libs/libmythtv/avformatdecoder.h

     
    3838  public:
    3939    AudioInfo() :
    4040        codec_id(CODEC_ID_NONE), sample_size(-2),   sample_rate(-1),
    41         channels(-1), do_ac3_passthru(false)
     41        channels(-1), do_passthru(false)
    4242    {;}
    4343
    44     AudioInfo(CodecID id, int sr, int ch, bool ac3) :
     44    AudioInfo(CodecID id, int sr, int ch, bool passthru) :
    4545        codec_id(id), sample_size(ch*2),   sample_rate(sr),
    46         channels(ch), do_ac3_passthru(ac3)
     46        channels(ch), do_passthru(passthru)
    4747    {;}
    4848
    4949    CodecID codec_id;
    5050    int sample_size, sample_rate, channels;
    51     bool do_ac3_passthru;
     51    bool do_passthru;
    5252
    5353    /// \brief Bits per sample.
    5454    int bps(void) const
     
    6060    {
    6161        return (codec_id==o.codec_id        && channels==o.channels       &&
    6262                sample_size==o.sample_size  && sample_rate==o.sample_rate &&
    63                 do_ac3_passthru==o.do_ac3_passthru);
     63                do_passthru==o.do_passthru);
    6464    }
    6565    QString toString() const
    6666    {
    6767        return QString("id(%1) %2Hz %3ch %4bps%5")
    6868            .arg(codec_id_string(codec_id),4).arg(sample_rate,5)
    6969            .arg(channels,2).arg(bps(),3)
    70             .arg((do_ac3_passthru) ? "pt":"",3);
     70            .arg((do_passthru) ? "pt":"",3);
    7171    }
    7272};
    7373
     
    143143
    144144  protected:
    145145    /// Attempt to find the optimal audio stream to use based on the number of channels,
    146     /// and if we're doing AC3 passthrough.  This will select the highest stream number
    147     /// that matches our criteria.
     146    /// and if we're doing AC3/DTS passthrough.  This will select the highest stream
     147    /// number that matches our criteria.
    148148    bool autoSelectAudioTrack();
    149149
    150150    bool autoSelectSubtitleTrack();
     
    187187
    188188    bool SetupAudioStream(void);
    189189
    190     int EncodeAC3Frame(unsigned char* data, int len, short *samples,
    191                        int &samples_size);
    192 
    193190    // Update our position map, keyframe distance, and the like.  Called for key frame packets.
    194191    void HandleGopStart(AVPacket *pkt);
    195192
     
    238235    // Audio
    239236    short int        *audioSamples;
    240237    bool              allow_ac3_passthru;
     238    bool              allow_dts_passthru;
    241239
    242240    AudioInfo         audioIn;
    243241    AudioInfo         audioOut;
  • libs/libavformat/mpeg.c

     
    8888#define AUDIO_ID 0xc0
    8989#define VIDEO_ID 0xe0
    9090#define AC3_ID   0x80
    91 #define DTS_ID   0x8a
     91#define DTS_ID   0x88
    9292#define LPCM_ID  0xa0
    9393#define SUB_ID   0x20
    9494
  • programs/mythfrontend/globalsettings.cpp

     
    133133    return gc;
    134134}
    135135
     136#ifdef CONFIG_DTS
     137static HostCheckBox *DTSPassThrough()
     138{
     139    HostCheckBox *gc = new HostCheckBox("DTSPassThru");
     140    gc->setLabel(QObject::tr("Enable DTS to SPDIF passthrough"));
     141    gc->setValue(false);
     142    gc->setHelpText(QObject::tr("Enable sending DTS audio directly to your "
     143                    "sound card's SPDIF output, on sources which contain "
     144                    "DTS soundtracks (usually DVDs).  Requires that the "
     145                    "audio output device be set to something suitable."));
     146    return gc;
     147}
     148#endif
     149
    136150static HostCheckBox *Deinterlace()
    137151{
    138152    HostCheckBox *gc = new HostCheckBox("Deinterlace");
     
    20592073
    20602074         addChild(AudioOutputDevice());
    20612075         addChild(AC3PassThrough());
     2076#ifdef CONFIG_DTS
     2077         addChild(DTSPassThrough());
     2078#endif
    20622079         addChild(AggressiveBuffer());
    20632080
    20642081         Setting* volumeControl = MythControlsVolume();