Ticket #730: mythtv-dtspassthru.patch

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

DTS patch against r8079

  • libs/libmythtv/avformatdecoder.cpp

     
    2929
    3030#define MAX_AC3_FRAME_SIZE 6144
    3131
     32static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *bit_rate);
     33static int dts_decode_header(uint8_t *indata_ptr, int *rate, int *nblks, int *sfreq);
     34
    3235extern pthread_mutex_t avcodeclock;
    3336
    3437int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic);
     
    919922                            <<") already open, leaving it alone.");
    920923                }
    921924                assert(enc->codec_id);
     925                if (enc->codec_id == CODEC_ID_DTS)
     926                {
     927                    enc->sample_rate = 48000;
     928                    enc->channels = 2;
     929                    // enc->bit_rate = what??;
     930                }
    922931                if (enc->channels > 2)
    923932                    enc->channels = 2;
    924933                bitrate += enc->bit_rate;
     
    17601769
    17611770//
    17621771// This function will select the best audio track
    1763 // available usgin the following rules:
     1772// available using the following rules:
    17641773//
    1765 // 1. The fist AC3 track found will be select,
    1766 // 2. If no AC3 is found then the audio track with
    1767 // the most number of channels is selected.
     1774// 1. The first DTS track found will be selected,
     1775// 2. If no DTS is found then the fist AC3 track will be selected,
     1776// 3. If no AC3 is found then the audio track with the most number
     1777//    of channels is selected.
    17681778//
    17691779// This code has no awareness to language preferences
    17701780// although I don't think it would be too hard to
     
    17781788        return false;
    17791789    }
    17801790
    1781     int minChannels = 1;
    17821791    int maxTracks = (audioStreams.size() - 1);
    17831792    int track;
    1784     if (do_ac3_passthru)
    1785         minChannels = 2;
     1793    int firstAC3Track = -1;
     1794    int firstDtsTrack = -1;
    17861795
    17871796    int selectedTrack = -1;
    1788     int selectedChannels = -1;
    1789    
    1790     while ((selectedTrack == -1) && (minChannels >= 0))
     1797    int selectedChannels = 0;
     1798
     1799    for (track = 0; track <= maxTracks; track++)
    17911800    {
    1792         for (track = 0; track <= maxTracks; track++)
     1801        int tempStream = audioStreams[track];
     1802        AVCodecContext *e = ic->streams[tempStream]->codec;
     1803
     1804        switch (e->codec_id)
    17931805        {
    1794             int tempStream = audioStreams[track];
    1795             AVCodecContext *e = ic->streams[tempStream]->codec;
     1806            case CODEC_ID_AC3:
     1807                if(firstAC3Track == -1)
     1808                {
     1809                    firstAC3Track = track;
     1810                }
     1811                break;
    17961812
    1797             if (e->channels > minChannels)
    1798             {
    1799                 //if we find an AC3 codec then we select it
    1800                 //as the preferred codec.
    1801                 if (e->codec_id == CODEC_ID_AC3)
     1813            case CODEC_ID_DTS:
     1814                if(firstDtsTrack == -1)
    18021815                {
    1803                     selectedTrack = track;
    1804                     break;
     1816                    firstDtsTrack = track;
    18051817                }
     1818                break;
    18061819
     1820            default:
     1821
    18071822                if (e->channels > selectedChannels)
    18081823                {
    18091824                    // this is a candidate with more channels
     
    18121827                    selectedChannels = e->channels;
    18131828                    selectedTrack = track;
    18141829                }
    1815             }
    18161830        }
    1817         if (selectedTrack == -1)
     1831    }
     1832
     1833    if (!transcoding)
     1834    {
     1835        if (firstDtsTrack >= 0 && gContext->GetNumSetting("DTSPassThru", false))
    18181836        {
    1819             minChannels--;
     1837            selectedTrack = firstDtsTrack;
    18201838        }
     1839        else if(firstAC3Track >= 0 && gContext->GetNumSetting("AC3PassThru", false))
     1840        {
     1841            selectedTrack = firstAC3Track;
     1842        }
    18211843    }
    18221844
    18231845    if (selectedTrack == -1)
     
    18301852    wantedAudioStream = audioStreams[currentAudioTrack];
    18311853     
    18321854    AVCodecContext *e = ic->streams[wantedAudioStream]->codec;
    1833     if (e->codec_id == CODEC_ID_AC3)
     1855    switch (e->codec_id)
    18341856    {
    1835         VERBOSE(VB_AUDIO, LOC +
    1836                 QString("Auto-selecting AC3 audio track (stream #%2).")
    1837                 .arg(wantedAudioStream));
     1857        case CODEC_ID_AC3:
     1858            VERBOSE(VB_AUDIO, LOC +
     1859                    QString("Auto-selecting AC3 audio track (stream #%2).")
     1860                    .arg(wantedAudioStream));
     1861            break;
     1862
     1863        case CODEC_ID_DTS:
     1864            VERBOSE(VB_AUDIO, LOC +
     1865                    QString("Auto-selecting DTS audio track (stream #%2).")
     1866                    .arg(wantedAudioStream));
     1867            break;
     1868
     1869        default:
     1870            VERBOSE(VB_AUDIO, LOC +
     1871                    QString("Auto-selecting audio track #%1 (stream #%2).")
     1872                    .arg(selectedTrack + 1).arg(wantedAudioStream) + "\n\t\t\t" +
     1873                    QString("It has %1 channels and we needed at least 1")
     1874                    .arg(selectedChannels));
    18381875    }
    1839     else
    1840     {
    1841         VERBOSE(VB_AUDIO, LOC +
    1842                 QString("Auto-selecting audio track #%1 (stream #%2).")
    1843                 .arg(selectedTrack + 1).arg(wantedAudioStream) + "\n\t\t\t" +
    1844                 QString("It has %1 channels and we needed at least %2")
    1845                 .arg(selectedChannels).arg(do_ac3_passthru ? 2 : 1));
    1846     }
    18471876    SetupAudioStream();
    18481877    CheckAudioParams(e->sample_rate, e->channels, true);
    18491878    return true;
     
    18631892
    18641893    GetNVP()->SetEffDsp(curstream->codec->sample_rate * 100);
    18651894
    1866     do_ac3_passthru = curstream->codec->codec_id == CODEC_ID_AC3 &&
    1867                       !transcoding &&
    1868                       gContext->GetNumSetting("AC3PassThru", false);
     1895    do_ac3_passthru = !transcoding &&
     1896                      (curstream->codec->codec_id == CODEC_ID_AC3 &&
     1897                       gContext->GetNumSetting("AC3PassThru", false) ||
     1898                       curstream->codec->codec_id == CODEC_ID_DTS &&
     1899                       gContext->GetNumSetting("DTSPassThru", false));
    18691900}
    18701901
    18711902
     
    21982229                    }
    21992230                    pthread_mutex_unlock(&avcodeclock);
    22002231
    2201                     ptr += ret;
    2202                     len -= ret;
    22032232
    22042233                    if (data_size <= 0)
     2234                    {
     2235                        ptr += ret;
     2236                        len -= ret;
    22052237                        continue;
     2238                    }
    22062239
    22072240                    if (!do_ac3_passthru)
    22082241                        CheckAudioParams(curstream->codec->sample_rate,
     
    23852418{
    23862419    int enc_len;
    23872420    int flags, sample_rate, bit_rate;
     2421    int nr_samples = 0, block_len;
     2422    bool dts = false;
    23882423    unsigned char* ucsamples = (unsigned char*) samples;
    23892424
    23902425    // we don't do any length/crc validation of the AC3 frame here; presumably
     
    23952430    // ignore, and if so, may as well just assume that it will ignore
    23962431    // anything with a bad CRC...
    23972432
    2398     enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2433    enc_len = dts_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2434    if(enc_len >= 10)
     2435    {
     2436        dts = true;
     2437        int rate, sfreq, nblks;
     2438        dts_decode_header(data, &rate, &nblks, &sfreq);
     2439        nr_samples = nblks * 32;
     2440        block_len = nr_samples * 2 * 2;
     2441    }
     2442    else
     2443    {
     2444        enc_len = a52_syncinfo(data, &flags, &sample_rate, &bit_rate);
     2445        block_len = MAX_AC3_FRAME_SIZE;
     2446    }
    23992447
    24002448    if (enc_len == 0 || enc_len > len)
    24012449    {
     
    24032451        return len;
    24042452    }
    24052453
    2406     if (enc_len > MAX_AC3_FRAME_SIZE - 8)
    2407         enc_len = MAX_AC3_FRAME_SIZE - 8;
     2454    if (enc_len > block_len - 8)
     2455    {
     2456        enc_len = block_len - 8;
     2457    }
    24082458
    24092459    swab(data, ucsamples + 8, enc_len);
    24102460
    2411     // the following values come from ao_hwac3.c in mplayer.
     2461    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
    24122462    // they form a valid IEC958 AC3 header.
    24132463    ucsamples[0] = 0x72;
    24142464    ucsamples[1] = 0xF8;
    24152465    ucsamples[2] = 0x1F;
    24162466    ucsamples[3] = 0x4E;
    2417     ucsamples[4] = 0x01;
     2467    if(dts)
     2468    {
     2469        switch(nr_samples)
     2470        {
     2471            case 512:
     2472                ucsamples[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     2473                break;
     2474
     2475            case 1024:
     2476                ucsamples[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     2477                break;
     2478
     2479            case 2048:
     2480                ucsamples[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     2481                break;
     2482
     2483            default:
     2484                VERBOSE(VB_IMPORTANT, LOC +
     2485                        QString("DTS: %1-sample bursts not supported")
     2486                        .arg(nr_samples));
     2487                ucsamples[4] = 0x00;
     2488                break;
     2489        }
     2490    }
     2491    else
     2492    {
     2493        ucsamples[4] = 0x01;
     2494    }
    24182495    ucsamples[5] = 0x00;
    24192496    ucsamples[6] = (enc_len << 3) & 0xFF;
    24202497    ucsamples[7] = (enc_len >> 5) & 0xFF;
    2421     memset(ucsamples + 8 + enc_len, 0, MAX_AC3_FRAME_SIZE - 8 - enc_len);
    2422     samples_size = MAX_AC3_FRAME_SIZE;
     2498    memset(ucsamples + 8 + enc_len, 0, block_len - 8 - enc_len);
     2499    samples_size = block_len;
    24232500
    2424     return len;  // consume whole frame even if len > enc_len ?
     2501    return enc_len;
    24252502}
    24262503
    24272504void AvFormatDecoder::AddTextData(unsigned char *buf, int len,
     
    24292506{
    24302507    m_parent->AddTextData((char*)buf, len, timecode, type);
    24312508}
     2509 
     2510static int DTS_SAMPLEFREQS[16] =
     2511{
     2512    0,
     2513    8000,
     2514    16000,
     2515    32000,
     2516    64000,
     2517    128000,
     2518    11025,
     2519    22050,
     2520    44100,
     2521    88200,
     2522    176400,
     2523    12000,
     2524    24000,
     2525    48000,
     2526    96000,
     2527    192000
     2528};
     2529
     2530static int DTS_BITRATES[30] =
     2531{
     2532    32000,
     2533    56000,
     2534    64000,
     2535    96000,
     2536    112000,
     2537    128000,
     2538    192000,
     2539    224000,
     2540    256000,
     2541    320000,
     2542    384000,
     2543    448000,
     2544    512000,
     2545    576000,
     2546    640000,
     2547    768000,
     2548    896000,
     2549    1024000,
     2550    1152000,
     2551    1280000,
     2552    1344000,
     2553    1408000,
     2554    1411200,
     2555    1472000,
     2556    1536000,
     2557    1920000,
     2558    2048000,
     2559    3072000,
     2560    3840000,
     2561    4096000
     2562};
     2563
     2564static int dts_syncinfo(uint8_t *indata_ptr, int */*flags*/, int *sample_rate, int *bit_rate)
     2565{
     2566    int nblks;
     2567    int rate;
     2568    int sfreq;
     2569
     2570    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     2571    if(fsize >= 0)
     2572    {
     2573        if(rate >= 0 && rate <= 29)
     2574            *bit_rate = DTS_BITRATES[rate];
     2575        else
     2576            *bit_rate = 0;
     2577        if(sfreq >= 1 && sfreq <= 15)
     2578            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     2579        else
     2580            *sample_rate = 0;
     2581    }
     2582    return fsize;
     2583}
     2584
     2585static int dts_decode_header(uint8_t *indata_ptr, int *rate, int *nblks, int *sfreq)
     2586{
     2587    if(((indata_ptr[0] << 24) | (indata_ptr[1] << 16) | (indata_ptr[2] << 8)
     2588        | (indata_ptr[3])) != 0x7ffe8001)
     2589        return -1;
     2590
     2591    int ftype = indata_ptr[4] >> 7;
     2592
     2593    int surp = (indata_ptr[4] >> 2) & 0x1f;
     2594    surp = (surp + 1) % 32;
     2595
     2596    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     2597    *nblks = *nblks + 1;
     2598
     2599    int fsize = (indata_ptr[5] & 0x03) << 12 | (indata_ptr[6] << 4) | (indata_ptr[7] >> 4);
     2600    fsize = fsize + 1;
     2601
     2602    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     2603    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     2604
     2605    if(ftype != 1)
     2606    {
     2607        VERBOSE(VB_IMPORTANT, LOC +
     2608                QString("DTS: Termination frames not handled (ftype %1)").arg(ftype));
     2609        return -1;
     2610    }
     2611
     2612    if(*sfreq != 13)
     2613    {
     2614        VERBOSE(VB_IMPORTANT, LOC +
     2615                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     2616        return -1;
     2617    }
     2618
     2619    if((fsize > 8192) || (fsize < 96))
     2620    {
     2621        VERBOSE(VB_IMPORTANT, LOC +
     2622                QString("DTS: fsize: %1 invalid").arg(fsize));
     2623        return -1;
     2624    }
     2625
     2626    if(*nblks != 8 &&
     2627       *nblks != 16 &&
     2628       *nblks != 32 &&
     2629       *nblks != 64 &&
     2630       *nblks != 128 &&
     2631       ftype == 1)
     2632    {
     2633        VERBOSE(VB_IMPORTANT, LOC +
     2634                QString("DTS: nblks %1 not valid for normal frame").arg(*nblks));
     2635        return -1;
     2636    }
     2637
     2638    return fsize;
     2639}
  • 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");
     
    20432057
    20442058         addChild(AudioOutputDevice());
    20452059         addChild(AC3PassThrough());
     2060#ifdef CONFIG_DTS
     2061         addChild(DTSPassThrough());
     2062#endif
    20462063         addChild(AggressiveBuffer());
    20472064
    20482065         Setting* volumeControl = MythControlsVolume();