Ticket #730: dts.patch

File dts.patch, 16.7 KB (added by danielk, 20 years ago)

update

  • 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"
     
    3637/** Set to zero to allow any number of AC3 channels. */
    3738#define MAX_OUTPUT_CHANNELS 2
    3839
     40#define VB_AUDIO VB_IMPORTANT
     41
     42static int dts_syncinfo(uint8_t *indata_ptr, int *flags,
     43                        int *sample_rate, int *bit_rate);
     44static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     45                             int *nblks, int *sfreq);
     46static int encode_frame(bool dts, unsigned char* data, int len,
     47                        short *samples, int &samples_size);
     48
    3949extern pthread_mutex_t avcodeclock;
    4050
    4151int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
     
    172182      // Audio
    173183      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    174184      allow_ac3_passthru(false),
     185      allow_dts_passthru(false),
    175186      // Audio selection
    176187      wantedAudioStream(),    selectedAudioStream(),
    177188      // Subtitle selection
     
    188199
    189200    save_cctc[0] = save_cctc[1] = 0;
    190201    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
     202#ifdef CONFIG_DTS
     203    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     204#endif // CONFIG_DTS
    191205
    192206    audioIn.sample_size = -32; // force SetupAudioStream to run once
    193207}
     
    17071721    return list;
    17081722}
    17091723
    1710 vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
     1724static vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)
    17111725{
    17121726    vector<int> ret;
    17131727
     
    17181732    return ret;
    17191733}
    17201734
    1721 int filter_ac3(const AVFormatContext *ic,
    1722                const sinfo_vec_t     &audioStreams,
    1723                const vector<int>     &fs)
     1735static int filter_codec(const AVFormatContext *ic,
     1736                        const CodecID          codec,
     1737                        const sinfo_vec_t     &audioStreams,
     1738                        const vector<int>     &fs)
    17241739{
    17251740    int selectedTrack = -1;
    17261741
     
    17291744    {
    17301745        const int stream_index    = audioStreams[*it].av_stream_index;
    17311746        const AVCodecContext *ctx = ic->streams[stream_index]->codec;
    1732         if (CODEC_ID_AC3 == ctx->codec_id)
     1747        if (codec == ctx->codec_id)
    17331748        {
    17341749            selectedTrack = *it;
    17351750            break;
     
    17391754    return selectedTrack;
    17401755}
    17411756
    1742 int filter_max_ch(const AVFormatContext *ic,
    1743                   const sinfo_vec_t     &audioStreams,
    1744                   const vector<int>     &fs)
     1757static int filter_max_ch(const AVFormatContext *ic,
     1758                         const sinfo_vec_t     &audioStreams,
     1759                         const vector<int>     &fs)
    17451760{
    17461761    int selectedTrack = -1, max_seen = -1;
    17471762
     
    17961811    {
    17971812        int idx = audioStreams[i].av_stream_index;
    17981813        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
     1814        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
     1815                                (codec_ctx->codec_id == CODEC_ID_AC3));
     1816        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
     1817                                (codec_ctx->codec_id == CODEC_ID_DTS));
    17991818        AudioInfo item(codec_ctx->codec_id,
    18001819                       codec_ctx->sample_rate, codec_ctx->channels,
    1801                        (allow_ac3_passthru && !transcoding &&
    1802                         (codec_ctx->codec_id == CODEC_ID_AC3)));
     1820                       do_ac3_passthru || do_dts_passthru);
    18031821        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
    18041822    }
    18051823#endif
     
    18291847        // try to get best track for most preferred language
    18301848        selectedTrack = -1;
    18311849        vector<int>::const_iterator it = languagePreference.begin();
    1832         for (; it !=  languagePreference.end(); ++it)
     1850        for (; it !=  languagePreference.end() && selectedTrack<0; ++it)
    18331851        {
    18341852            vector<int> flang = filter_lang(audioStreams, *it);
    1835             if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) >= 0)
    1836                 break;
    1837             if ((selectedTrack = filter_max_ch(ic, audioStreams, flang)) >= 0)
    1838                 break;
     1853            if (allow_dts_passthru && !transcoding)
     1854                selectedTrack = filter_codec(ic, CODEC_ID_DTS,
     1855                                             audioStreams, flang);
     1856            if (selectedTrack < 0)
     1857                selectedTrack = filter_codec(ic, CODEC_ID_AC3,
     1858                                             audioStreams, flang);
     1859            if (selectedTrack < 0)
     1860                selectedTrack = filter_max_ch(ic, audioStreams, flang);
    18391861        }
    18401862        // try to get best track for any language
    18411863        if (selectedTrack < 0)
    18421864        {
    18431865            VERBOSE(VB_AUDIO, LOC + "Trying to select audio track (wo/lang)");
    18441866            vector<int> flang = filter_lang(audioStreams, -1);
    1845             if ((selectedTrack = filter_ac3(ic, audioStreams, flang)) < 0)
    1846                 selectedTrack  = filter_max_ch(ic, audioStreams, flang);
     1867            if (allow_dts_passthru && !transcoding)
     1868                selectedTrack = filter_codec(ic, CODEC_ID_DTS,
     1869                                             audioStreams, flang);
     1870            if (selectedTrack < 0)
     1871                selectedTrack = filter_codec(ic, CODEC_ID_AC3,
     1872                                             audioStreams, flang);
     1873            if (selectedTrack < 0)
     1874                selectedTrack = filter_max_ch(ic, audioStreams, flang);
    18471875        }
    18481876    }
    18491877
     
    22252253                    pthread_mutex_lock(&avcodeclock);
    22262254                    ret = len;
    22272255                    data_size = 0;
    2228                     if (audioOut.do_ac3_passthru)
     2256                    if (audioOut.do_passthru)
    22292257                    {
    22302258                        data_size = pkt->size;
    2231                         ret = EncodeAC3Frame(ptr, len, audioSamples,
    2232                                              data_size);
     2259                        bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
     2260                        ret = encode_frame(
     2261                            dts, ptr, len, audioSamples, data_size);
    22332262                    }
    22342263                    else
    22352264                    {
     
    24592488    {
    24602489        assert(curstream);
    24612490        assert(curstream->codec);
    2462         codec_ctx = curstream->codec;       
     2491        codec_ctx = curstream->codec;
    24632492        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    24642493                                (codec_ctx->codec_id == CODEC_ID_AC3));
     2494        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
     2495                                (codec_ctx->codec_id == CODEC_ID_DTS));
    24652496        info = AudioInfo(codec_ctx->codec_id,
    24662497                         codec_ctx->sample_rate, codec_ctx->channels,
    2467                          do_ac3_passthru);
     2498                         do_ac3_passthru || do_dts_passthru);
    24682499    }
    24692500
    24702501    if (info == audioIn)
     
    24742505            QString("audio track #%1").arg(currentAudioTrack+1));
    24752506
    24762507    audioOut = audioIn = info;
    2477     if (audioIn.do_ac3_passthru)
     2508    if (audioIn.do_passthru)
    24782509    {
    24792510        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    24802511        audioOut.channels    = 2;
     
    25062537    return true;
    25072538}
    25082539
    2509 int AvFormatDecoder::EncodeAC3Frame(unsigned char *data, int len,
    2510                                     short *samples, int &samples_size)
     2540static int encode_frame(bool dts, unsigned char *data, int len,
     2541                        short *samples, int &samples_size)
    25112542{
    25122543    int enc_len;
    25132544    int flags, sample_rate, bit_rate;
     
    25212552    // ignore, and if so, may as well just assume that it will ignore
    25222553    // anything with a bad CRC...
    25232554
    2524     enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2555    uint nr_samples = 0, block_len;
     2556    if (dts)
     2557    {
     2558        enc_len = dts_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2559        int rate, sfreq, nblks;
     2560        dts_decode_header(data, &rate, &nblks, &sfreq);
     2561        nr_samples = nblks * 32;
     2562        block_len = nr_samples * 2 * 2;
     2563    }
     2564    else
     2565    {
     2566        enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2567        block_len = MAX_AC3_FRAME_SIZE;
     2568    }
    25252569
    25262570    if (enc_len == 0 || enc_len > len)
    25272571    {
     
    25292573        return len;
    25302574    }
    25312575
    2532     if (enc_len > MAX_AC3_FRAME_SIZE - 8)
    2533         enc_len = MAX_AC3_FRAME_SIZE - 8;
     2576    enc_len = min((uint)enc_len, block_len - 8);
    25342577
    25352578    swab(data, ucsamples + 8, enc_len);
    25362579
     
    25442587    ucsamples[5] = 0x00;
    25452588    ucsamples[6] = (enc_len << 3) & 0xFF;
    25462589    ucsamples[7] = (enc_len >> 5) & 0xFF;
    2547     memset(ucsamples + 8 + enc_len, 0, MAX_AC3_FRAME_SIZE - 8 - enc_len);
    2548     samples_size = MAX_AC3_FRAME_SIZE;
     2590    memset(ucsamples + 8 + enc_len, 0, block_len - 8 - enc_len);
     2591    samples_size = block_len;
    25492592
    2550     return len;  // consume whole frame even if len > enc_len ?
     2593    if (dts)
     2594    {
     2595        // the following values come from libmpcodecs
     2596        static const unsigned char magic[8] =
     2597            { 0x0, 0xB, 0xC, 0x0, 0xD, 0x0, 0x0, 0x0 };
     2598        //         512  1024      2048
     2599        static const uint bad_bits = ~(111<<9);
     2600
     2601        ucsamples[4] = magic[(nr_samples>>9)&0x3];
     2602        if (nr_samples & bad_bits || ucsamples[4]==0)
     2603        {
     2604            VERBOSE(VB_IMPORTANT, LOC +
     2605                    QString("DTS: %1-sample bursts not supported")
     2606                    .arg(nr_samples));
     2607            ucsamples[4] = 0x00;
     2608        }
     2609    }
     2610
     2611    return enc_len;
    25512612}
    25522613
    25532614void AvFormatDecoder::AddTextData(unsigned char *buf, int len,
     
    25552616{
    25562617    m_parent->AddTextData((char*)buf, len, timecode, type);
    25572618}
     2619 
     2620/// DTS passthru info
     2621static const int DTS_SAMPLEFREQS[16] =
     2622{
     2623    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     2624    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000,
     2625};
     2626
     2627/// DTS passthru info
     2628static const int DTS_BITRATES[30] =
     2629{
     2630    32000,    56000,    64000,    96000,    112000,   128000,
     2631    192000,   224000,   256000,   320000,   384000,   448000,
     2632    512000,   576000,   640000,   768000,   896000,   1024000,
     2633    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     2634    1536000,  1920000,  2048000,  3072000,  3840000,  4096000,
     2635};
     2636
     2637/// DTS passthru func
     2638static int dts_syncinfo(uint8_t *indata_ptr, int */*flags*/,
     2639                        int *sample_rate, int *bit_rate)
     2640{
     2641    int nblks;
     2642    int rate;
     2643    int sfreq;
     2644
     2645    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     2646    if (fsize >= 0)
     2647    {
     2648        if (rate >= 0 && rate <= 29)
     2649            *bit_rate = DTS_BITRATES[rate];
     2650        else
     2651            *bit_rate = 0;
     2652        if (sfreq >= 1 && sfreq <= 15)
     2653            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     2654        else
     2655            *sample_rate = 0;
     2656    }
     2657    return fsize;
     2658}
     2659
     2660/// DTS passthru func
     2661static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     2662                             int *nblks, int *sfreq)
     2663{
     2664    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     2665               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     2666
     2667    if (id != 0x7ffe8001)
     2668        return -1;
     2669
     2670    int ftype, surp, fsize;
     2671
     2672    ftype  = (indata_ptr[4] >> 7);
     2673    surp   = (indata_ptr[4] >> 2) & 0x1f;
     2674    surp   = (surp + 1) % 32;
     2675
     2676    *nblks = ((indata_ptr[4] & 0x01) << 6) | (indata_ptr[5] >> 2);
     2677    *nblks = *nblks + 1;
     2678
     2679    fsize  = ((indata_ptr[5] & 0x03) << 12 |
     2680              (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4)) + 1;
     2681
     2682    *sfreq = ((indata_ptr[8] >> 2) & 0x0f);
     2683    *rate  = ((indata_ptr[8] & 0x03) << 3) | ((indata_ptr[9] >> 5) & 0x07);
     2684
     2685    if (ftype != 1)
     2686    {
     2687        VERBOSE(VB_IMPORTANT, LOC +
     2688                QString("DTS: Termination frames not handled (ftype %1)")
     2689                .arg(ftype));
     2690        return -1;
     2691    }
     2692
     2693    if (*sfreq != 13)
     2694    {
     2695        VERBOSE(VB_IMPORTANT, LOC +
     2696                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     2697        return -1;
     2698    }
     2699
     2700    if ((fsize > 8192) || (fsize < 96))
     2701    {
     2702        VERBOSE(VB_IMPORTANT, LOC +
     2703                QString("DTS: fsize: %1 invalid").arg(fsize));
     2704        return -1;
     2705    }
     2706
     2707    if ((*nblks != 8)  && (*nblks != 16)  && (*nblks != 32) &&
     2708        (*nblks != 64) && (*nblks != 128) && (ftype == 1))
     2709    {
     2710        VERBOSE(VB_IMPORTANT, LOC +
     2711                QString("DTS: nblks %1 not valid for normal frame")
     2712                .arg(*nblks));
     2713        return -1;
     2714    }
     2715
     2716    return fsize;
     2717}
  • 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
    4444    AudioInfo(CodecID id, int sr, int ch, bool ac3) :
    4545        codec_id(id), sample_size(ch*2),   sample_rate(sr),
    46         channels(ch), do_ac3_passthru(ac3)
     46        channels(ch), do_passthru(ac3)
    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 { return (8 * sample_size) / channels; }
     
    5656    {
    5757        return (codec_id==o.codec_id        && channels==o.channels       &&
    5858                sample_size==o.sample_size  && sample_rate==o.sample_rate &&
    59                 do_ac3_passthru==o.do_ac3_passthru);
     59                do_passthru==o.do_passthru);
    6060    }
    6161    QString toString() const
    6262    {
    6363        return QString("id(%1) %2Hz %3ch %4bps%5")
    6464            .arg(codec_id_string(codec_id),4).arg(sample_rate,5)
    6565            .arg(channels,2).arg(bps(),3)
    66             .arg((do_ac3_passthru) ? "pt":"",3);
     66            .arg((do_passthru) ? "pt":"",3);
    6767    }
    6868};
    6969
     
    183183
    184184    bool SetupAudioStream(void);
    185185
    186     int EncodeAC3Frame(unsigned char* data, int len, short *samples,
    187                        int &samples_size);
    188 
    189186    // Update our position map, keyframe distance, and the like.  Called for key frame packets.
    190187    void HandleGopStart(AVPacket *pkt);
    191188
     
    233230    // Audio
    234231    short int        *audioSamples;
    235232    bool              allow_ac3_passthru;
     233    bool              allow_dts_passthru;
    236234
    237235    AudioInfo         audioIn;
    238236    AudioInfo         audioOut;
  • 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");
     
    20692083
    20702084         addChild(AudioOutputDevice());
    20712085         addChild(AC3PassThrough());
     2086#ifdef CONFIG_DTS
     2087         addChild(DTSPassThrough());
     2088#endif
    20722089         addChild(AggressiveBuffer());
    20732090
    20742091         Setting* volumeControl = MythControlsVolume();
  • 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"