Ticket #730: dts.patch

File dts.patch, 16.7 KB (added by danielk, 6 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"