Ticket #730: mythtv-dtspassthru.patch
| File mythtv-dtspassthru.patch, 13.4 KB (added by , 20 years ago) |
|---|
-
libs/libmythtv/avformatdecoder.cpp
29 29 30 30 #define MAX_AC3_FRAME_SIZE 6144 31 31 32 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, int *sample_rate, int *bit_rate); 33 static int dts_decode_header(uint8_t *indata_ptr, int *rate, int *nblks, int *sfreq); 34 32 35 extern pthread_mutex_t avcodeclock; 33 36 34 37 int get_avf_buffer_xvmc(struct AVCodecContext *c, AVFrame *pic); … … 919 922 <<") already open, leaving it alone."); 920 923 } 921 924 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 } 922 931 if (enc->channels > 2) 923 932 enc->channels = 2; 924 933 bitrate += enc->bit_rate; … … 1760 1769 1761 1770 // 1762 1771 // This function will select the best audio track 1763 // available us ginthe following rules:1772 // available using the following rules: 1764 1773 // 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. 1768 1778 // 1769 1779 // This code has no awareness to language preferences 1770 1780 // although I don't think it would be too hard to … … 1778 1788 return false; 1779 1789 } 1780 1790 1781 int minChannels = 1;1782 1791 int maxTracks = (audioStreams.size() - 1); 1783 1792 int track; 1784 i f (do_ac3_passthru)1785 minChannels = 2;1793 int firstAC3Track = -1; 1794 int firstDtsTrack = -1; 1786 1795 1787 1796 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++) 1791 1800 { 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) 1793 1805 { 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; 1796 1812 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) 1802 1815 { 1803 selectedTrack = track; 1804 break; 1816 firstDtsTrack = track; 1805 1817 } 1818 break; 1806 1819 1820 default: 1821 1807 1822 if (e->channels > selectedChannels) 1808 1823 { 1809 1824 // this is a candidate with more channels … … 1812 1827 selectedChannels = e->channels; 1813 1828 selectedTrack = track; 1814 1829 } 1815 }1816 1830 } 1817 if (selectedTrack == -1) 1831 } 1832 1833 if (!transcoding) 1834 { 1835 if (firstDtsTrack >= 0 && gContext->GetNumSetting("DTSPassThru", false)) 1818 1836 { 1819 minChannels--;1837 selectedTrack = firstDtsTrack; 1820 1838 } 1839 else if(firstAC3Track >= 0 && gContext->GetNumSetting("AC3PassThru", false)) 1840 { 1841 selectedTrack = firstAC3Track; 1842 } 1821 1843 } 1822 1844 1823 1845 if (selectedTrack == -1) … … 1830 1852 wantedAudioStream = audioStreams[currentAudioTrack]; 1831 1853 1832 1854 AVCodecContext *e = ic->streams[wantedAudioStream]->codec; 1833 if (e->codec_id == CODEC_ID_AC3)1855 switch (e->codec_id) 1834 1856 { 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)); 1838 1875 } 1839 else1840 {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 }1847 1876 SetupAudioStream(); 1848 1877 CheckAudioParams(e->sample_rate, e->channels, true); 1849 1878 return true; … … 1863 1892 1864 1893 GetNVP()->SetEffDsp(curstream->codec->sample_rate * 100); 1865 1894 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)); 1869 1900 } 1870 1901 1871 1902 … … 2198 2229 } 2199 2230 pthread_mutex_unlock(&avcodeclock); 2200 2231 2201 ptr += ret;2202 len -= ret;2203 2232 2204 2233 if (data_size <= 0) 2234 { 2235 ptr += ret; 2236 len -= ret; 2205 2237 continue; 2238 } 2206 2239 2207 2240 if (!do_ac3_passthru) 2208 2241 CheckAudioParams(curstream->codec->sample_rate, … … 2385 2418 { 2386 2419 int enc_len; 2387 2420 int flags, sample_rate, bit_rate; 2421 int nr_samples = 0, block_len; 2422 bool dts = false; 2388 2423 unsigned char* ucsamples = (unsigned char*) samples; 2389 2424 2390 2425 // we don't do any length/crc validation of the AC3 frame here; presumably … … 2395 2430 // ignore, and if so, may as well just assume that it will ignore 2396 2431 // anything with a bad CRC... 2397 2432 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 } 2399 2447 2400 2448 if (enc_len == 0 || enc_len > len) 2401 2449 { … … 2403 2451 return len; 2404 2452 } 2405 2453 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 } 2408 2458 2409 2459 swab(data, ucsamples + 8, enc_len); 2410 2460 2411 // the following values come from ao_hwac3.c in mplayer.2461 // the following values come from libmpcodecs/ad_hwac3.c in mplayer. 2412 2462 // they form a valid IEC958 AC3 header. 2413 2463 ucsamples[0] = 0x72; 2414 2464 ucsamples[1] = 0xF8; 2415 2465 ucsamples[2] = 0x1F; 2416 2466 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 } 2418 2495 ucsamples[5] = 0x00; 2419 2496 ucsamples[6] = (enc_len << 3) & 0xFF; 2420 2497 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; 2423 2500 2424 return len; // consume whole frame even if len > enc_len ?2501 return enc_len; 2425 2502 } 2426 2503 2427 2504 void AvFormatDecoder::AddTextData(unsigned char *buf, int len, … … 2429 2506 { 2430 2507 m_parent->AddTextData((char*)buf, len, timecode, type); 2431 2508 } 2509 2510 static 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 2530 static 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 2564 static 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 2585 static 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
88 88 #define AUDIO_ID 0xc0 89 89 #define VIDEO_ID 0xe0 90 90 #define AC3_ID 0x80 91 #define DTS_ID 0x8 a91 #define DTS_ID 0x88 92 92 #define LPCM_ID 0xa0 93 93 #define SUB_ID 0x20 94 94 -
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"); … … 2043 2057 2044 2058 addChild(AudioOutputDevice()); 2045 2059 addChild(AC3PassThrough()); 2060 #ifdef CONFIG_DTS 2061 addChild(DTSPassThrough()); 2062 #endif 2046 2063 addChild(AggressiveBuffer()); 2047 2064 2048 2065 Setting* volumeControl = MythControlsVolume();
