Ticket #730: dts.patch
| File dts.patch, 16.7 KB (added by , 20 years ago) |
|---|
-
libs/libmythtv/avformatdecoder.cpp
8 8 using namespace std; 9 9 10 10 // MythTV headers 11 #include "mythconfig.h" // for CONFIG_DTS 11 12 #include "avformatdecoder.h" 12 13 #include "RingBuffer.h" 13 14 #include "NuppelVideoPlayer.h" … … 36 37 /** Set to zero to allow any number of AC3 channels. */ 37 38 #define MAX_OUTPUT_CHANNELS 2 38 39 40 #define VB_AUDIO VB_IMPORTANT 41 42 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, 43 int *sample_rate, int *bit_rate); 44 static int dts_decode_header(uint8_t *indata_ptr, int *rate, 45 int *nblks, int *sfreq); 46 static int encode_frame(bool dts, unsigned char* data, int len, 47 short *samples, int &samples_size); 48 39 49 extern pthread_mutex_t avcodeclock; 40 50 41 51 int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic); … … 172 182 // Audio 173 183 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 174 184 allow_ac3_passthru(false), 185 allow_dts_passthru(false), 175 186 // Audio selection 176 187 wantedAudioStream(), selectedAudioStream(), 177 188 // Subtitle selection … … 188 199 189 200 save_cctc[0] = save_cctc[1] = 0; 190 201 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 202 #ifdef CONFIG_DTS 203 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 204 #endif // CONFIG_DTS 191 205 192 206 audioIn.sample_size = -32; // force SetupAudioStream to run once 193 207 } … … 1707 1721 return list; 1708 1722 } 1709 1723 1710 vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key)1724 static vector<int> filter_lang(const sinfo_vec_t &audioStreams, int lang_key) 1711 1725 { 1712 1726 vector<int> ret; 1713 1727 … … 1718 1732 return ret; 1719 1733 } 1720 1734 1721 int filter_ac3(const AVFormatContext *ic, 1722 const sinfo_vec_t &audioStreams, 1723 const vector<int> &fs) 1735 static int filter_codec(const AVFormatContext *ic, 1736 const CodecID codec, 1737 const sinfo_vec_t &audioStreams, 1738 const vector<int> &fs) 1724 1739 { 1725 1740 int selectedTrack = -1; 1726 1741 … … 1729 1744 { 1730 1745 const int stream_index = audioStreams[*it].av_stream_index; 1731 1746 const AVCodecContext *ctx = ic->streams[stream_index]->codec; 1732 if ( CODEC_ID_AC3== ctx->codec_id)1747 if (codec == ctx->codec_id) 1733 1748 { 1734 1749 selectedTrack = *it; 1735 1750 break; … … 1739 1754 return selectedTrack; 1740 1755 } 1741 1756 1742 int filter_max_ch(const AVFormatContext *ic,1743 const sinfo_vec_t &audioStreams,1744 const vector<int> &fs)1757 static int filter_max_ch(const AVFormatContext *ic, 1758 const sinfo_vec_t &audioStreams, 1759 const vector<int> &fs) 1745 1760 { 1746 1761 int selectedTrack = -1, max_seen = -1; 1747 1762 … … 1796 1811 { 1797 1812 int idx = audioStreams[i].av_stream_index; 1798 1813 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)); 1799 1818 AudioInfo item(codec_ctx->codec_id, 1800 1819 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); 1803 1821 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 1804 1822 } 1805 1823 #endif … … 1829 1847 // try to get best track for most preferred language 1830 1848 selectedTrack = -1; 1831 1849 vector<int>::const_iterator it = languagePreference.begin(); 1832 for (; it != languagePreference.end() ; ++it)1850 for (; it != languagePreference.end() && selectedTrack<0; ++it) 1833 1851 { 1834 1852 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); 1839 1861 } 1840 1862 // try to get best track for any language 1841 1863 if (selectedTrack < 0) 1842 1864 { 1843 1865 VERBOSE(VB_AUDIO, LOC + "Trying to select audio track (wo/lang)"); 1844 1866 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); 1847 1875 } 1848 1876 } 1849 1877 … … 2225 2253 pthread_mutex_lock(&avcodeclock); 2226 2254 ret = len; 2227 2255 data_size = 0; 2228 if (audioOut.do_ ac3_passthru)2256 if (audioOut.do_passthru) 2229 2257 { 2230 2258 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); 2233 2262 } 2234 2263 else 2235 2264 { … … 2459 2488 { 2460 2489 assert(curstream); 2461 2490 assert(curstream->codec); 2462 codec_ctx = curstream->codec; 2491 codec_ctx = curstream->codec; 2463 2492 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 2464 2493 (codec_ctx->codec_id == CODEC_ID_AC3)); 2494 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 2495 (codec_ctx->codec_id == CODEC_ID_DTS)); 2465 2496 info = AudioInfo(codec_ctx->codec_id, 2466 2497 codec_ctx->sample_rate, codec_ctx->channels, 2467 do_ac3_passthru );2498 do_ac3_passthru || do_dts_passthru); 2468 2499 } 2469 2500 2470 2501 if (info == audioIn) … … 2474 2505 QString("audio track #%1").arg(currentAudioTrack+1)); 2475 2506 2476 2507 audioOut = audioIn = info; 2477 if (audioIn.do_ ac3_passthru)2508 if (audioIn.do_passthru) 2478 2509 { 2479 2510 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 2480 2511 audioOut.channels = 2; … … 2506 2537 return true; 2507 2538 } 2508 2539 2509 int AvFormatDecoder::EncodeAC3Frame(unsigned char *data, int len,2510 short *samples, int &samples_size)2540 static int encode_frame(bool dts, unsigned char *data, int len, 2541 short *samples, int &samples_size) 2511 2542 { 2512 2543 int enc_len; 2513 2544 int flags, sample_rate, bit_rate; … … 2521 2552 // ignore, and if so, may as well just assume that it will ignore 2522 2553 // anything with a bad CRC... 2523 2554 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 } 2525 2569 2526 2570 if (enc_len == 0 || enc_len > len) 2527 2571 { … … 2529 2573 return len; 2530 2574 } 2531 2575 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); 2534 2577 2535 2578 swab(data, ucsamples + 8, enc_len); 2536 2579 … … 2544 2587 ucsamples[5] = 0x00; 2545 2588 ucsamples[6] = (enc_len << 3) & 0xFF; 2546 2589 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; 2549 2592 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; 2551 2612 } 2552 2613 2553 2614 void AvFormatDecoder::AddTextData(unsigned char *buf, int len, … … 2555 2616 { 2556 2617 m_parent->AddTextData((char*)buf, len, timecode, type); 2557 2618 } 2619 2620 /// DTS passthru info 2621 static 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 2628 static 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 2638 static 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 2661 static 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
38 38 public: 39 39 AudioInfo() : 40 40 codec_id(CODEC_ID_NONE), sample_size(-2), sample_rate(-1), 41 channels(-1), do_ ac3_passthru(false)41 channels(-1), do_passthru(false) 42 42 {;} 43 43 44 44 AudioInfo(CodecID id, int sr, int ch, bool ac3) : 45 45 codec_id(id), sample_size(ch*2), sample_rate(sr), 46 channels(ch), do_ ac3_passthru(ac3)46 channels(ch), do_passthru(ac3) 47 47 {;} 48 48 49 49 CodecID codec_id; 50 50 int sample_size, sample_rate, channels; 51 bool do_ ac3_passthru;51 bool do_passthru; 52 52 53 53 /// \brief Bits per sample. 54 54 int bps(void) const { return (8 * sample_size) / channels; } … … 56 56 { 57 57 return (codec_id==o.codec_id && channels==o.channels && 58 58 sample_size==o.sample_size && sample_rate==o.sample_rate && 59 do_ ac3_passthru==o.do_ac3_passthru);59 do_passthru==o.do_passthru); 60 60 } 61 61 QString toString() const 62 62 { 63 63 return QString("id(%1) %2Hz %3ch %4bps%5") 64 64 .arg(codec_id_string(codec_id),4).arg(sample_rate,5) 65 65 .arg(channels,2).arg(bps(),3) 66 .arg((do_ ac3_passthru) ? "pt":"",3);66 .arg((do_passthru) ? "pt":"",3); 67 67 } 68 68 }; 69 69 … … 183 183 184 184 bool SetupAudioStream(void); 185 185 186 int EncodeAC3Frame(unsigned char* data, int len, short *samples,187 int &samples_size);188 189 186 // Update our position map, keyframe distance, and the like. Called for key frame packets. 190 187 void HandleGopStart(AVPacket *pkt); 191 188 … … 233 230 // Audio 234 231 short int *audioSamples; 235 232 bool allow_ac3_passthru; 233 bool allow_dts_passthru; 236 234 237 235 AudioInfo audioIn; 238 236 AudioInfo audioOut; -
programs/mythfrontend/globalsettings.cpp
133 133 return gc; 134 134 } 135 135 136 #ifdef CONFIG_DTS 137 static 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 136 150 static HostCheckBox *Deinterlace() 137 151 { 138 152 HostCheckBox *gc = new HostCheckBox("Deinterlace"); … … 2069 2083 2070 2084 addChild(AudioOutputDevice()); 2071 2085 addChild(AC3PassThrough()); 2086 #ifdef CONFIG_DTS 2087 addChild(DTSPassThrough()); 2088 #endif 2072 2089 addChild(AggressiveBuffer()); 2073 2090 2074 2091 Setting* volumeControl = MythControlsVolume(); -
configure
334 334 x264="no" 335 335 a52="yes" 336 336 a52bin="no" 337 dts=" no"337 dts="yes" 338 338 pp="yes" 339 339 shared_pp="no" 340 340 mingw32="no" … … 682 682 ;; 683 683 --enable-a52bin) a52bin="yes" 684 684 ;; 685 --enable-dts) dts="yes" ; extralibs="$extralibs -ldts"685 --enable-dts) dts="yes" 686 686 ;; 687 --disable-dts) dts="no" 688 ;; 687 689 --disable-pp) pp="no" 688 690 ;; 689 691 --enable-shared-pp) shared_pp="yes" … … 1920 1922 mandir="${prefix}/man" 1921 1923 fi 1922 1924 1925 if test x"$dts" = x"yes"; then 1926 dts = "no" 1927 if has_library libdts ; then 1928 dts = "yes" 1929 extralibs="$extralibs -ldts" 1930 fi 1931 fi 1932 1923 1933 if test x"$dvb" = x"yes" ; then 1924 1934 dvb="no" 1925 1935 if test -f "$dvb_path"/linux/dvb/frontend.h ; then … … 2187 2197 echo "ALSA support $audio_alsa" 2188 2198 echo "aRts support $audio_arts" 2189 2199 echo "JACK support $audio_jack" 2200 echo "DTS passthrough $dts" 2190 2201 echo 2191 2202 echo "# Video Output Support" 2192 2203 echo "x11 support $x11"
