Ticket #5900: audioencoding-fixes-vdpau-jya10.patch

File audioencoding-fixes-vdpau-jya10.patch, 92.3 KB (added by jyavenard@…, 11 years ago)

Patch for 0.21-fixes after VDPAU patches have been applied

  • mythplugins/mythmusic/mythmusic/main.cpp

    diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/main.cpp c/mythplugins/mythmusic/mythmusic/main.cpp
    a c  
    378378    REG_KEY("Music", "VOLUMEDOWN", "Volume down",       "[,{,F10,Volume Down");
    379379    REG_KEY("Music", "VOLUMEUP",   "Volume up",         "],},F11,Volume Up");
    380380    REG_KEY("Music", "MUTE",       "Mute",              "|,\\,F9,Volume Mute");
     381    REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer",             "Ctrl+U");
    381382    REG_KEY("Music", "CYCLEVIS",   "Cycle visualizer mode",      "6");
    382383    REG_KEY("Music", "BLANKSCR",   "Blank screen",               "5");
    383384    REG_KEY("Music", "THMBUP",     "Increase rating",            "9");
  • mythplugins/mythmusic/mythmusic/musicplayer.cpp

    diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/musicplayer.cpp c/mythplugins/mythmusic/mythmusic/musicplayer.cpp
    a c  
    347347
    348348void MusicPlayer::openOutputDevice(void)
    349349{
    350     QString adevice;
     350    QString adevice, pdevice;
    351351
    352352    if (gContext->GetSetting("MusicAudioDevice") == "default")
    353353        adevice = gContext->GetSetting("AudioOutputDevice");
    354354    else
    355355        adevice = gContext->GetSetting("MusicAudioDevice");
    356356
     357    if (!gContext->GetNumSetting("MythAC3Upmix", 0))
     358        pdevice = "default";
     359    else
     360        pdevice = gContext->GetSetting("PassThruOutputDevice");
     361
    357362    // TODO: Error checking that device is opened correctly!
    358     m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
     363    m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100,
    359364                                    AUDIOOUTPUT_MUSIC, true, false);
    360365    m_output->setBufferSize(256 * 1024);
    361366    m_output->SetBlocking(false);
  • mythplugins/mythmusic/mythmusic/playbackbox.cpp

    diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/playbackbox.cpp c/mythplugins/mythmusic/mythmusic/playbackbox.cpp
    a c  
    358358            changeSpeed(true);
    359359        else if (action == "MUTE")
    360360            toggleMute();
     361        else if (action == "TOGGLEUPMIX")
     362            toggleUpmix();
    361363        else if (action == "MENU" && visualizer_status != 2)
    362364        {
    363365            menufilters = false;
     
    11781180    }
    11791181}
    11801182
     1183void PlaybackBoxMusic::toggleUpmix()
     1184{
     1185    if (gPlayer->getOutput())
     1186        gPlayer->getOutput()->ToggleUpmix();
     1187}
     1188   
     1189
    11811190void PlaybackBoxMusic::showProgressBar()
    11821191{
    11831192    if (progress_bar)
  • mythplugins/mythmusic/mythmusic/playbackbox.h

    diff -Naur --exclude=.svn a/mythplugins/mythmusic/mythmusic/playbackbox.h c/mythplugins/mythmusic/mythmusic/playbackbox.h
    a c  
    6969    void changeVolume(bool up_or_down);
    7070    void changeSpeed(bool up_or_down);
    7171    void toggleMute();
     72    void toggleUpmix();
    7273    void resetTimer();
    7374    void hideVolume(){showVolume(false);}
    7475    void showVolume(bool on_or_off);
  • mythtv/libs/libmyth/audiooutput.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutput.cpp c/mythtv/libs/libmyth/audiooutput.cpp
    a c  
    3636                                    int audio_bits,
    3737                                    int audio_channels, int audio_samplerate,
    3838                                    AudioOutputSource source,
    39                                     bool set_initial_vol, bool audio_passthru)
     39                                    bool set_initial_vol, bool audio_passthru, bool AC3upmix)
    4040{
    4141    if (passthru_device.isEmpty() || passthru_device.lower() == "default")
    4242        passthru_device = main_device;
     
    4747        return new AudioOutputALSA(main_device.remove(0, 5),
    4848                                   passthru_device.remove(0, 5), audio_bits,
    4949                                   audio_channels, audio_samplerate, source,
    50                                    set_initial_vol, audio_passthru);
     50                                   set_initial_vol, audio_passthru, AC3upmix);
    5151#else
    5252        VERBOSE(VB_IMPORTANT, "Audio output device is set to an ALSA device "
    5353                              "but ALSA support is not compiled in!");
  • mythtv/libs/libmyth/audiooutput.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutput.h c/mythtv/libs/libmyth/audiooutput.h
    a c  
    2222                                  int audio_bits,
    2323                                  int audio_channels, int audio_samplerate,
    2424                                  AudioOutputSource source,
    25                                   bool set_initial_vol, bool audio_passthru);
     25                                  bool set_initial_vol, bool audio_passthru, bool AC3upmix=false);
    2626
    2727    AudioOutput() :
    2828        VolumeBase(),             OutputListeners(),
    29         lastError(QString::null), lastWarn(QString::null) {}
     29        isAC3upmix(false),
     30        lastError(QString::null), lastWarn(QString::null) { };
    3031
    3132    virtual ~AudioOutput() { };
    3233
     
    3940   
    4041    virtual void SetStretchFactor(float factor);
    4142    virtual float GetStretchFactor(void) { return 1.0f; }
     43    virtual bool ToggleUpmix(void) = 0;
     44    bool isAC3upmix;
    4245
    4346    // do AddSamples calls block?
    4447    virtual void SetBlocking(bool blocking) = 0;
  • mythtv/libs/libmyth/audiooutputalsa.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputalsa.cpp c/mythtv/libs/libmyth/audiooutputalsa.cpp
    a c  
    1717    QString laudio_main_device, QString           laudio_passthru_device,
    1818    int     laudio_bits,        int               laudio_channels,
    1919    int     laudio_samplerate,  AudioOutputSource lsource,
    20     bool    lset_initial_vol,   bool              laudio_passthru) :
     20    bool    lset_initial_vol,   bool              laudio_passthru,
     21    bool    AC3upmix) :
    2122    AudioOutputBase(laudio_main_device, laudio_passthru_device,
    2223                    laudio_bits,        laudio_channels,
    2324                    laudio_samplerate,  lsource,
    24                     lset_initial_vol,   laudio_passthru),
     25                    lset_initial_vol,   laudio_passthru,
     26                    AC3upmix),
    2527    pcm_handle(NULL),             numbadioctls(0),
    2628    killAudioLock(false),         mixer_handle(NULL),
    2729    mixer_control(QString::null), volume_range_multiplier(1.0f),
     
    3537AudioOutputALSA::~AudioOutputALSA()
    3638{
    3739    KillAudio();
     40    if (isAC3upmix)
     41        SetIECStatus(true);
     42}
     43
     44void AudioOutputALSA::SetIECStatus(bool audio) {
     45   
     46    snd_ctl_t *ctl;
     47    const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT);
     48    int spdif_index = -1;
     49    snd_ctl_elem_list_t *clist;
     50    snd_ctl_elem_id_t *cid;
     51    snd_ctl_elem_value_t *cval;
     52    snd_aes_iec958_t iec958;
     53    int cidx, controls;
     54
     55    VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1")
     56                      .arg(audio ? "audio" : "non-audio"));
     57   
     58    int err;
     59    if ((err = snd_ctl_open(&ctl, "default", 0)) < 0)
     60    {
     61        Error(QString("AudioOutputALSA::SetIECStatus: snd_ctl_open(default): %1")
     62              .arg(snd_strerror(err)));
     63        return;
     64    }
     65    snd_ctl_elem_list_alloca(&clist);
     66    snd_ctl_elem_list(ctl, clist);
     67    snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist));
     68    snd_ctl_elem_list(ctl, clist);
     69    controls = snd_ctl_elem_list_get_used(clist);
     70    for (cidx = 0; cidx < controls; cidx++)
     71    {
     72        if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str))
     73            if (spdif_index < 0 ||
     74                snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index)
     75                    break;
     76    }
     77
     78    if (cidx >= controls)
     79        return;
     80
     81    snd_ctl_elem_id_alloca(&cid);
     82    snd_ctl_elem_list_get_id(clist, cidx, cid);
     83    snd_ctl_elem_value_alloca(&cval);
     84    snd_ctl_elem_value_set_id(cval, cid);
     85    snd_ctl_elem_read(ctl,cval);
     86    snd_ctl_elem_value_get_iec958(cval, &iec958);
     87   
     88    if (!audio)
     89        iec958.status[0] |= IEC958_AES0_NONAUDIO;
     90    else
     91        iec958.status[0] &= ~IEC958_AES0_NONAUDIO;
     92
     93    snd_ctl_elem_value_set_iec958(cval, &iec958);
     94    snd_ctl_elem_write(ctl, cval);
     95
    3896}
    3997
    4098bool AudioOutputALSA::OpenDevice()
     
    42100    snd_pcm_format_t format;
    43101    unsigned int buffer_time, period_time;
    44102    int err;
     103    QString real_device;
    45104
    46105    if (pcm_handle != NULL)
    47106        CloseDevice();
     
    49108    pcm_handle = NULL;
    50109    numbadioctls = 0;
    51110
    52     QString real_device = (audio_passthru) ?
    53         audio_passthru_device : audio_main_device;
     111    if (!isAC3upmix) {
     112        real_device = (audio_passthru) ?
     113            audio_passthru_device : audio_main_device;
     114    }
     115    else
     116        if (audio_passthru || audio_enc)
     117        {
     118            real_device = audio_passthru_device;
     119            SetIECStatus(false);
     120        }
     121        else
     122        {
     123            real_device = audio_main_device;
     124            SetIECStatus(true);
     125        }
    54126
    55127    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    56128            .arg(real_device));
     
    148220}
    149221
    150222
     223void AudioOutputALSA::reorder_6ch_ac3(void *buf, unsigned int len) {
     224    unsigned short *src = (unsigned short *)buf;
     225    unsigned short tmp;
     226    unsigned int samples = len >> 1;
     227
     228    for (uint i = 0; i < samples; i += 6) {
     229        tmp = src[i+1];
     230        src[i+1] = src[i+2];
     231        src[i+2] = src[i+3];
     232        src[i+3] = src[i+4];
     233        src[i+4] = tmp;
     234    }
     235}
     236
    151237void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size)
    152238{
    153239    unsigned char *tmpbuf;
     
    159245        VERBOSE(VB_IMPORTANT, QString("WriteAudio() called with pcm_handle == NULL!"));
    160246        return;
    161247    }
    162    
     248
     249    // Re-Order channels mapping if analog output is used and source is stereo
     250    if (isAC3upmix && !audio_passthru && (source_audio_channels > 2)) {
     251        reorder_6ch_ac3(aubuf, size);
     252    }
    163253    tmpbuf = aubuf;
    164254
    165255    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
  • mythtv/libs/libmyth/audiooutputalsa.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputalsa.h c/mythtv/libs/libmyth/audiooutputalsa.h
    a c  
    2020                    int laudio_bits,
    2121                    int laudio_channels, int laudio_samplerate,
    2222                    AudioOutputSource source,
    23                     bool set_initial_vol, bool laudio_passthru);
     23                    bool set_initial_vol, bool laudio_passthru,
     24                    bool AC3upmix = false);
    2425    virtual ~AudioOutputALSA();
    2526
    2627    // Volume control
     
    3738    virtual inline int getBufferedOnSoundcard(void);
    3839
    3940  private:
     41    void SetIECStatus(bool audio);
    4042    inline int SetParameters(snd_pcm_t *handle,
    4143                             snd_pcm_format_t format, unsigned int channels,
    4244                             unsigned int rate, unsigned int buffer_time,
     
    4951    void CloseMixer(void);
    5052    void SetupMixer(void);
    5153    void GetVolumeRange(snd_mixer_elem_t *elem);
     54    void reorder_6ch_ac3(void *buf, unsigned int len);
    5255
    5356  private:
    5457    snd_pcm_t   *pcm_handle;
  • mythtv/libs/libmyth/audiooutputbase.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputbase.cpp c/mythtv/libs/libmyth/audiooutputbase.cpp
    a c  
    2727    QString laudio_main_device,    QString           laudio_passthru_device,
    2828    int     /*laudio_bits*/,       int               /*laudio_channels*/,
    2929    int     /*laudio_samplerate*/, AudioOutputSource lsource,
    30     bool    lset_initial_vol,      bool              /*laudio_passthru*/) :
     30    bool    lset_initial_vol,      bool              /*laudio_passthru*/,
     31    bool    AC3upmix) :
    3132
    3233    effdsp(0),                  effdspstretched(0),
    3334    audio_channels(-1),         audio_bytes_per_sample(0),
     
    3738
    3839    audio_main_device(QDeepCopy<QString>(laudio_main_device)),
    3940    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    40     audio_passthru(false),      audio_stretchfactor(1.0f),
     41    audio_passthru(false),      audio_enc(false),
     42    audio_reenc(false),         audio_stretchfactor(1.0f),
    4143
    4244    audio_codec(NULL),
    4345    source(lsource),            killaudio(false),
     
    5456    pSoundStretch(NULL),       
    5557    encoder(NULL),
    5658    upmixer(NULL),
     59
    5760    source_audio_channels(-1),
     61    source_audio_samplerate(0),
    5862    source_audio_bytes_per_sample(0),
    5963    needs_upmix(false),
    6064    surround_mode(FreeSurround::SurroundModePassive),
     65    old_audio_stretchfactor(1.0),
    6166
    6267    blocking(false),
    6368
     
    8489    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    8590    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
    8691    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
     92    orig_config_channels = configured_audio_channels;
     93    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
     94    src_quality = gContext->GetNumSetting("SRCQuality", 3);
     95    isAC3upmix = AC3upmix;
    8796
    8897    // You need to call Reconfigure from your concrete class.
    8998    // Reconfigure(laudio_bits,       laudio_channels,
     
    110119void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor)
    111120{
    112121    effdspstretched = (int)((float)effdsp / laudio_stretchfactor);
    113     if (audio_stretchfactor != laudio_stretchfactor)
     122    if ((audio_stretchfactor != laudio_stretchfactor) || !pSoundStretch)
    114123    {
    115124        audio_stretchfactor = laudio_stretchfactor;
    116125        if (pSoundStretch)
     
    124133            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    125134                                        .arg(audio_stretchfactor));
    126135            pSoundStretch = new soundtouch::SoundTouch();
    127             if (audio_codec)
    128             {
    129                 if (!encoder)
     136            if (!isAC3upmix) {
     137                if (audio_codec)
    130138                {
    131                     VERBOSE(VB_AUDIO, LOC +
    132                             QString("Creating Encoder for codec %1 origfs %2")
    133                             .arg(audio_codec->codec_id)
    134                             .arg(audio_codec->frame_size));
    135 
    136                     encoder = new AudioOutputDigitalEncoder();
    137                     if (!encoder->Init(audio_codec->codec_id,
    138                                 audio_codec->bit_rate,
    139                                 audio_codec->sample_rate,
    140                                 audio_codec->channels
    141                                 ))
     139                    if (!encoder)
    142140                    {
    143                         // eeks
    144                         delete encoder;
    145                         encoder = NULL;
    146141                        VERBOSE(VB_AUDIO, LOC +
    147                                 QString("Failed to Create Encoder"));
     142                                QString("Creating Encoder for codec %1 origfs %2")
     143                                .arg(audio_codec->codec_id)
     144                                .arg(audio_codec->frame_size));
     145
     146                        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     147                        if (!encoder->Init(audio_codec->codec_id,
     148                                    audio_codec->bit_rate,
     149                                    audio_codec->sample_rate,
     150                                    audio_codec->channels
     151                                    ))
     152                        {
     153                            // eeks
     154                            delete encoder;
     155                            encoder = NULL;
     156                            VERBOSE(VB_AUDIO, LOC +
     157                                    QString("Failed to Create Encoder"));
     158                        }
    148159                    }
    149160                }
    150             }
    151             if (audio_codec && encoder)
    152             {
    153                 pSoundStretch->setSampleRate(audio_codec->sample_rate);
    154                 pSoundStretch->setChannels(audio_codec->channels);
    155             }
    156             else
    157             {
     161                if (audio_codec && encoder)
     162                {
     163                    pSoundStretch->setSampleRate(audio_codec->sample_rate);
     164                    pSoundStretch->setChannels(audio_codec->channels);
     165                }
     166                else
     167                {
     168                    pSoundStretch->setSampleRate(audio_samplerate);
     169                    pSoundStretch->setChannels(audio_channels);
     170                }
     171            } else {
    158172                pSoundStretch->setSampleRate(audio_samplerate);
    159                 pSoundStretch->setChannels(audio_channels);
     173                pSoundStretch->setChannels(upmixer ?
     174                    configured_audio_channels : source_audio_channels);
    160175            }
    161 
    162176            pSoundStretch->setTempo(audio_stretchfactor);
    163177            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
    164178
    165179            // dont need these with only tempo change
    166180            //pSoundStretch->setPitch(1.0);
    167181            //pSoundStretch->setRate(1.0);
    168 
    169182            //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true);
    170183            //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false);
    171184        }
     
    184197    return audio_stretchfactor;
    185198}
    186199
     200bool AudioOutputBase::ToggleUpmix(void)
     201{
     202    if (orig_config_channels == 2 || audio_passthru)
     203        return false;
     204    if (configured_audio_channels == 6)
     205        configured_audio_channels = 2;
     206    else
     207        configured_audio_channels = 6;
     208   
     209    Reconfigure(audio_bits, source_audio_channels,
     210        source_audio_samplerate, audio_passthru);
     211    return (configured_audio_channels == 6);
     212}
     213
    187214void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    188215                                  int laudio_samplerate, bool laudio_passthru,
    189216                                  void *laudio_codec)
     
    194221    int cchannels = 0;
    195222    int lsource_audio_channels = laudio_channels;
    196223    bool lneeds_upmix = false;
     224    bool laudio_reenc = false;
    197225
    198     if (laudio_codec)
    199     {
    200         lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
    201         laudio_bits = 16;
    202         laudio_channels = 2;
    203         lsource_audio_channels = laudio_channels;
    204         laudio_samplerate = 48000;
    205         lcchannels = ((AVCodecContext*)laudio_codec)->channels;
    206     }
     226    if (!isAC3upmix) {
     227        if (laudio_codec)
     228        {
     229            lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     230            laudio_bits = 16;
     231            laudio_channels = 2;
     232            lsource_audio_channels = laudio_channels;
     233            laudio_samplerate = 48000;
     234            lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     235        }
    207236
    208     if (audio_codec)
    209     {
    210         codec_id = audio_codec->codec_id;
    211         cchannels = ((AVCodecContext*)audio_codec)->channels;
    212     }
     237        if (audio_codec)
     238        {
     239            codec_id = audio_codec->codec_id;
     240            cchannels = ((AVCodecContext*)audio_codec)->channels;
     241        }
    213242
    214     if ((configured_audio_channels == 6) &&
    215         !(laudio_codec || audio_codec))
    216     {
    217         laudio_channels = configured_audio_channels;
    218         lneeds_upmix = true;
    219         VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     243        if ((configured_audio_channels == 6) &&
     244            !(laudio_codec || audio_codec))
     245        {
     246            laudio_channels = configured_audio_channels;
     247            lneeds_upmix = true;
     248            VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     249        }
     250    } else { //AC3 Upmix
     251        // Are we perhaps reencoding a (previously) timestretched bitstream?
     252        if (laudio_channels > 2 && !laudio_passthru)
     253            laudio_reenc = true;
     254 
     255        // Enough channels? Upmix if not
     256        if (laudio_channels < configured_audio_channels && !laudio_passthru)
     257        {
     258            laudio_channels = configured_audio_channels;
     259            lneeds_upmix = true;
     260            VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     261        }
    220262    }
    221 
     263   
    222264    ClearError();
    223265    bool general_deps = (laudio_bits == audio_bits &&
    224266        laudio_channels == audio_channels &&
    225267        laudio_samplerate == audio_samplerate && !need_resampler &&
    226268        laudio_passthru == audio_passthru &&
    227269        lneeds_upmix == needs_upmix &&
    228         lcodec_id == codec_id && lcchannels == cchannels);
     270        (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels))
     271        );
    229272    bool upmix_deps =
    230273        (lsource_audio_channels == source_audio_channels);
    231274    if (general_deps && upmix_deps)
     
    256299    audio_channels = laudio_channels;
    257300    source_audio_channels = lsource_audio_channels;
    258301    audio_bits = laudio_bits;
    259     audio_samplerate = laudio_samplerate;
    260     audio_codec = (AVCodecContext*)laudio_codec;
     302    if (!isAC3upmix) {
     303        audio_samplerate = laudio_samplerate;
     304        audio_codec = (AVCodecContext*)laudio_codec;
     305    } else {
     306        source_audio_samplerate = audio_samplerate = laudio_samplerate;
     307        audio_reenc = laudio_reenc;
     308    }
    261309    audio_passthru = laudio_passthru;
    262310    needs_upmix = lneeds_upmix;
    263311
     
    268316        Error("AudioOutput only supports 8 or 16bit audio.");
    269317        return;
    270318    }
    271     audio_bytes_per_sample = audio_channels * audio_bits / 8;
    272     source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    273319   
    274320    need_resampler = false;
    275321    killaudio = false;
     
    279325   
    280326    numlowbuffer = 0;
    281327
     328    if (!isAC3upmix) {
     329    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     330    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     331    } else {
     332    // Encode to AC-3 if not passing thru, there's more than 2 channels
     333    // and we're allowed to passthru AC-3
     334    // This won't reencode timestretched 2ch AC-3 but there's no point doing so
     335    if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru)
     336    {
     337        VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder");
     338        int srate = src_quality == 0 ? audio_samplerate : 48000;
     339        encoder = new AudioOutputDigitalEncoder();
     340        if (!encoder->Init(CODEC_ID_AC3, 448000, srate,
     341                           audio_channels, audio_reenc))
     342        {
     343            VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder");
     344            delete encoder;
     345            encoder = NULL;
     346        }
     347       
     348        audio_enc = true;
     349    }       
     350   
     351    if(audio_passthru || audio_enc)
     352        // AC-3 output - soundcard expects a 2ch 48k stream
     353        audio_channels = 2;
     354   
     355    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     356    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     357
     358    // Always resample to 48k - many cards can't do anything else
     359    // and ALSA will do it with linear interpolation (yuk) if we don't anyway
     360    if (src_quality != 0 && audio_samplerate != 48000)
     361    {
     362        int error;
     363        audio_samplerate = 48000;
     364        VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")
     365            .arg(laudio_samplerate).arg(audio_samplerate));
     366        src_ctx = src_new(3-src_quality, audio_channels, &error);
     367        if (error)
     368        {
     369            Error(QString("Error creating resampler, the error was: %1")
     370                  .arg(src_strerror(error)) );
     371            pthread_mutex_unlock(&avsync_lock);
     372            pthread_mutex_unlock(&audio_buflock);
     373            src_ctx = NULL;
     374            return;
     375        }
     376        src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;
     377        src_data.data_in = src_in;
     378        src_data.data_out = src_out;
     379        src_data.output_frames = 16384*6;
     380        need_resampler = true;
     381    }
     382    }
    282383    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
    283384            .arg(audio_main_device).arg(audio_channels)
    284385            .arg(source_audio_channels).arg(audio_samplerate));
     
    314415    current_seconds = -1;
    315416    source_bitrate = -1;
    316417
     418    if (!isAC3upmix) {
    317419    // NOTE: this won't do anything as above samplerate vars are set equal
    318420    // Check if we need the resampler
    319421    if (audio_samplerate != laudio_samplerate)
     
    336438        src_data.output_frames = 16384*6;
    337439        need_resampler = true;
    338440    }
    339 
     441    }
    340442    if (needs_upmix)
    341443    {
    342444        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     
    348450        upmixer = new FreeSurround(
    349451            audio_samplerate,
    350452            source == AUDIOOUTPUT_VIDEO,
    351             (FreeSurround::SurroundMode)surround_mode);
     453            (FreeSurround::SurroundMode)surround_mode,isAC3upmix);
    352454
    353455        VERBOSE(VB_AUDIO, LOC +
    354456                QString("create upmixer done with surround mode %1")
     
    357459
    358460    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    359461            .arg(audio_stretchfactor));
    360     VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
    361             .arg((audio_codec) ?
    362                  codec_id_string(audio_codec->codec_id) : "not set"));
    363 
    364     if (redo_stretch)
    365     {
    366         float laudio_stretchfactor = audio_stretchfactor;
    367         delete pSoundStretch;
    368         pSoundStretch = NULL;
    369         audio_stretchfactor = 0.0f;
    370         SetStretchFactorLocked(laudio_stretchfactor);
    371     }
    372     else
    373     {
    374         SetStretchFactorLocked(audio_stretchfactor);
    375         if (pSoundStretch)
     462    if (!isAC3upmix) {
     463        VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     464                .arg((audio_codec) ?
     465                  codec_id_string(audio_codec->codec_id) : "not set"));
     466
     467        if (redo_stretch)
     468        {
     469            delete pSoundStretch;
     470            pSoundStretch = NULL;
     471            SetStretchFactorLocked(audio_stretchfactor);
     472        }
     473        else
    376474        {
    377             // if its passthru then we need to reencode
    378             if (audio_codec)
     475            SetStretchFactorLocked(audio_stretchfactor);
     476            if (pSoundStretch)
    379477            {
    380                 if (!encoder)
     478                // if its passthru then we need to reencode
     479                if (audio_codec)
    381480                {
    382                     VERBOSE(VB_AUDIO, LOC +
    383                             QString("Creating Encoder for codec %1")
    384                             .arg(audio_codec->codec_id));
    385 
    386                     encoder = new AudioOutputDigitalEncoder();
    387                     if (!encoder->Init(audio_codec->codec_id,
    388                                 audio_codec->bit_rate,
    389                                 audio_codec->sample_rate,
    390                                 audio_codec->channels
    391                                 ))
     481                    if (!encoder)
    392482                    {
    393                         // eeks
    394                         delete encoder;
    395                         encoder = NULL;
    396                         VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     483                        VERBOSE(VB_AUDIO, LOC +
     484                                QString("Creating Encoder for codec %1")
     485                                .arg(audio_codec->codec_id));
     486
     487                        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     488                        if (!encoder->Init(audio_codec->codec_id,
     489                                    audio_codec->bit_rate,
     490                                    audio_codec->sample_rate,
     491                                    audio_codec->channels
     492                                    ))
     493                        {
     494                            // eeks
     495                            delete encoder;
     496                            encoder = NULL;
     497                            VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     498                        }
    397499                    }
    398500                }
    399             }
    400             if (audio_codec && encoder)
    401             {
    402                 pSoundStretch->setSampleRate(audio_codec->sample_rate);
    403                 pSoundStretch->setChannels(audio_codec->channels);
    404             }
    405             else
    406             {
    407                 pSoundStretch->setSampleRate(audio_samplerate);
    408                 pSoundStretch->setChannels(audio_channels);
     501                if (audio_codec && encoder)
     502                {
     503                    pSoundStretch->setSampleRate(audio_codec->sample_rate);
     504                    pSoundStretch->setChannels(audio_codec->channels);
     505                }
     506                else
     507                {
     508                    pSoundStretch->setSampleRate(audio_samplerate);
     509                    pSoundStretch->setChannels(audio_channels);
     510                }
    409511            }
    410512        }
     513    } else {
     514        SetStretchFactorLocked(old_audio_stretchfactor);
    411515    }
    412 
    413516    // Setup visualisations, zero the visualisations buffers
    414517    prepareVisuals();
    415518
     
    456559    killaudio = true;
    457560    StopOutputThread();
    458561
     562    if (isAC3upmix)
     563        pthread_mutex_lock(&audio_buflock);
     564
    459565    // Close resampler?
    460     if (src_ctx)
     566    if (src_ctx) {
    461567        src_delete(src_ctx);
     568        if (isAC3upmix)
     569            src_ctx = NULL;
     570    }
    462571    need_resampler = false;
    463572
    464573    // close sound stretcher
     
    466575    {
    467576        delete pSoundStretch;
    468577        pSoundStretch = NULL;
     578        if (isAC3upmix) {
     579            old_audio_stretchfactor = audio_stretchfactor;
     580            audio_stretchfactor = 1.0;
     581        }
    469582    }
    470583
    471584    if (encoder)
     
    480593        upmixer = NULL;
    481594    }
    482595    needs_upmix = false;
     596    if (isAC3upmix)
     597        audio_enc = false;
    483598
    484599    CloseDevice();
    485600
     601    if (isAC3upmix)
     602        pthread_mutex_unlock(&audio_buflock);
    486603    killAudioLock.unlock();
    487604}
    488605
     
    642759    // include algorithmic latencies
    643760    if (pSoundStretch)
    644761    {
    645         // add the effect of any unused but processed samples,
    646         // AC3 reencode does this
    647         totalbuffer += (int)(pSoundStretch->numSamples() *
    648                              audio_bytes_per_sample);
     762        if (!isAC3upmix) {
     763            // add the effect of any unused but processed samples,
     764            // AC3 reencode does this
     765            totalbuffer += (int)(pSoundStretch->numSamples() *
     766                                 audio_bytes_per_sample);
     767        }
    649768        // add the effect of unprocessed samples in time stretch algo
    650769        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    651770                              audio_bytes_per_sample) / audio_stretchfactor);
     
    656775        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
    657776    }
    658777
     778    if (isAC3upmix && encoder)
     779        totalbuffer += encoder->Buffered();
     780
    659781    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    660782                                   (audio_bytes_per_sample * effdspstretched));
    661783 
     
    709831        return false; // would overflow
    710832    }
    711833
     834    if (isAC3upmix)
     835        pthread_mutex_lock(&audio_buflock);
     836
    712837    // resample input if necessary
    713838    if (need_resampler && src_ctx)
    714839    {
     
    742867        _AddSamples(buffers, false, samples, timecode);
    743868    }
    744869
     870    if (isAC3upmix)
     871        pthread_mutex_unlock(&audio_buflock);
     872
    745873    return true;
    746874}
    747875
     
    753881    int abps = (encoder) ?
    754882        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    755883    int len = samples * abps;
     884 
     885    if (isAC3upmix) {
     886        // Give original samples to mythmusic visualisation
     887        dispatchVisual((unsigned char *)buffer, len, timecode,
     888                       source_audio_channels, audio_bits);
     889    }
    756890
    757891    // Check we have enough space to write the data
    758892    if (need_resampler && src_ctx)
     
    777911        return false; // would overflow
    778912    }
    779913
     914    if (isAC3upmix)
     915        pthread_mutex_lock(&audio_buflock);
     916
    780917    // resample input if necessary
    781918    if (need_resampler && src_ctx)
    782919    {
     
    805942        _AddSamples(buffer, true, samples, timecode);
    806943    }
    807944
     945    if (isAC3upmix)
     946        pthread_mutex_unlock(&audio_buflock);
     947
    808948    return true;
    809949}
    810950
     
    837977            {
    838978                int error = src_reset(src_ctx);
    839979                if (error)
     980                {
    840981                    VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
    841982                            "Error occured while resetting resampler: %1")
    842983                            .arg(src_strerror(error)));
     984                    if (isAC3upmix)
     985                        src_ctx = NULL;
     986                }
    843987            }
    844988        }
    845989    }
     
    849993void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples,
    850994                                  long long timecode)
    851995{
    852     pthread_mutex_lock(&audio_buflock);
     996    if (!isAC3upmix)
     997        pthread_mutex_lock(&audio_buflock);
    853998
    854999    int len; // = samples * audio_bytes_per_sample;
    8551000    int audio_bytes = audio_bits / 8;
     
    8681013            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
    8691014            .arg(needs_upmix));
    8701015   
     1016    if (isAC3upmix)
     1017        len = WaitForFreeSpace(samples);
     1018   
    8711019    if (upmixer && needs_upmix)
    8721020    {
    8731021        int out_samples = 0;
    8741022        int step = (interleaved)?source_audio_channels:1;
    875         len = WaitForFreeSpace(samples);    // test
     1023       
     1024        if (!isAC3upmix) {
     1025            org_waud = waud;
     1026            len = WaitForFreeSpace(samples);
     1027        }
    8761028        for (int itemp = 0; itemp < samples; )
    8771029        {
    8781030            // just in case it does a processing cycle, release the lock
    8791031            // to allow the output loop to do output
    880             pthread_mutex_unlock(&audio_buflock);
     1032            if (!isAC3upmix)
     1033                pthread_mutex_unlock(&audio_buflock);
    8811034            if (audio_bytes == 2)
    8821035            {
    8831036                itemp += upmixer->putSamples(
     
    8941047                    source_audio_channels,
    8951048                    (interleaved) ? 0 : samples);
    8961049            }
    897             pthread_mutex_lock(&audio_buflock);
     1050            if (!isAC3upmix)
     1051                pthread_mutex_lock(&audio_buflock);
    8981052
    8991053            int copy_samples = upmixer->numSamples();
    9001054            if (copy_samples)
     
    9281082    }
    9291083    else
    9301084    {
    931         len = WaitForFreeSpace(samples);
    932 
     1085        if (!isAC3upmix)
     1086            len = WaitForFreeSpace(samples);
    9331087        if (interleaved)
    9341088        {
    9351089            char *mybuf = (char*)buffer;
     
    9651119        }
    9661120    }
    9671121
     1122    if (!isAC3upmix) {
    9681123    if (samples > 0)
    9691124    {
    9701125        if (pSoundStretch)
     
    10221177                        continue;
    10231178
    10241179                    //len = WaitForFreeSpace(amount);
    1025                     char *ob = encoder->GetOutBuff();
     1180                    const char *ob = encoder->GetOutBuff();
    10261181                    if (amount >= bdiff)
    10271182                    {
    10281183                        memcpy(audiobuffer + org_waud, ob, bdiff);
     
    10351190
    10361191                    bdiff = AUDBUFSIZE - amount;
    10371192                    org_waud += amount;
     1193                    if (org_waud >= AUDBUFSIZE)
     1194                    {
     1195                        VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2").arg(org_waud).arg(amount));
     1196                        org_waud -= AUDBUFSIZE;
     1197                    }
    10381198                }
    10391199            }
    10401200            else
     
    10641224                        org_waud += nSamples * audio_bytes_per_sample;
    10651225                        nSamplesToEnd -= nSamples;
    10661226                    }
     1227                    if (org_waud >= AUDBUFSIZE)
     1228                    {
     1229                        VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2 %3").arg(org_waud).arg(nSamples).arg(audio_bytes_per_sample));
     1230                        org_waud -= AUDBUFSIZE;
     1231                    }
    10671232
    10681233                    newLen += nSamples * audio_bytes_per_sample;
    10691234                    len -= nSamples * audio_bytes_per_sample;
     
    10961261    }
    10971262
    10981263    pthread_mutex_unlock(&audio_buflock);
     1264    } else {
     1265    if (samples <= 0)
     1266        return;
     1267   
     1268    if (pSoundStretch)
     1269    {
     1270        // does not change the timecode, only the number of samples
     1271        // back to orig pos
     1272        org_waud = waud;
     1273        int bdiff = AUDBUFSIZE - org_waud;
     1274        int nSamplesToEnd = bdiff/abps;
     1275        if (bdiff < len)
     1276        {
     1277            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1278                                      (audiobuffer +
     1279                                       org_waud), nSamplesToEnd);
     1280            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     1281                                      (len - bdiff) / abps);
     1282        }
     1283        else
     1284            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1285                                      (audiobuffer + org_waud),
     1286                                      len / abps);
     1287
     1288        int nSamples = pSoundStretch->numSamples();
     1289        len = WaitForFreeSpace(nSamples);
     1290       
     1291        while ((nSamples = pSoundStretch->numSamples()))
     1292        {
     1293            if (nSamples > nSamplesToEnd)
     1294                nSamples = nSamplesToEnd;
     1295           
     1296            nSamples = pSoundStretch->receiveSamples(
     1297                (soundtouch::SAMPLETYPE*)
     1298                (audiobuffer + org_waud), nSamples
     1299            );
     1300           
     1301            if (nSamples == nSamplesToEnd) {
     1302                org_waud = 0;
     1303                nSamplesToEnd = AUDBUFSIZE/abps;
     1304            }
     1305            else {
     1306                org_waud += nSamples * abps;
     1307                nSamplesToEnd -= nSamples;
     1308            }
     1309           
     1310        }
     1311       
     1312    }
     1313
     1314    // Encode to AC-3?
     1315    if (encoder)
     1316    {
     1317       
     1318        org_waud = waud;
     1319        int bdiff = AUDBUFSIZE - org_waud;
     1320        int to_get = 0;
     1321
     1322        if (bdiff < len)
     1323        {
     1324            encoder->EncodeUpmix(audiobuffer + org_waud, bdiff);
     1325            to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff);
     1326        }
     1327        else
     1328            to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len);
     1329       
     1330        if (to_get > 0)
     1331        {
     1332           
     1333            if (to_get >= bdiff)
     1334            {
     1335                encoder->GetFrames(audiobuffer + org_waud, bdiff);
     1336                to_get -= bdiff;
     1337                org_waud = 0;
     1338            }
     1339            if (to_get > 0)
     1340                encoder->GetFrames(audiobuffer + org_waud, to_get);
     1341
     1342            org_waud += to_get;
     1343
     1344        }
     1345
     1346    }
     1347
     1348    waud = org_waud;
     1349    lastaudiolen = audiolen(false);
     1350
     1351    if (timecode < 0)
     1352        // mythmusic doesn't give timestamps..
     1353        timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1354   
     1355    samples_buffered += samples;
     1356   
     1357    /* we want the time at the end -- but the file format stores
     1358       time at the start of the chunk. */
     1359    // even with timestretch, timecode is still calculated from original
     1360    // sample count
     1361    audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
     1362    } // End AC3 upmiz
    10991363}
    11001364
    11011365void AudioOutputBase::Status()
  • mythtv/libs/libmyth/audiooutputbase.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputbase.h c/mythtv/libs/libmyth/audiooutputbase.h
    a c  
    4141                    int laudio_bits,
    4242                    int laudio_channels, int laudio_samplerate,
    4343                    AudioOutputSource lsource,
    44                     bool lset_initial_vol, bool laudio_passthru);
     44                    bool lset_initial_vol, bool laudio_passthru,
     45                    bool AC3upmix = false);
    4546    virtual ~AudioOutputBase();
    4647
    4748    // reconfigure sound out for new params
     
    5960
    6061    virtual void SetStretchFactor(float factor);
    6162    virtual float GetStretchFactor(void);
     63    virtual bool ToggleUpmix(void);
    6264
    6365    virtual void Reset(void);
    6466
     
    139141    QString audio_passthru_device;
    140142
    141143    bool audio_passthru;
     144    bool audio_enc;
     145    bool audio_reenc;
    142146
    143147    float audio_stretchfactor;
    144148    AVCodecContext *audio_codec;
     
    151155    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    152156   
    153157    int configured_audio_channels;
     158    int orig_config_channels;
     159    int src_quality;
     160    int source_audio_channels;
    154161
    155162 private:
    156163    // resampler
     
    166173    AudioOutputDigitalEncoder *encoder;
    167174    FreeSurround              *upmixer;
    168175
    169     int source_audio_channels;
     176    int source_audio_samplerate;
    170177    int source_audio_bytes_per_sample;
    171178    bool needs_upmix;
    172179    int surround_mode;
     180    bool allow_ac3_passthru;
     181    float old_audio_stretchfactor;
    173182
    174183    bool blocking; // do AddSamples calls block?
    175184
  • mythtv/libs/libmyth/audiooutputdigitalencoder.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp c/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
    a c  
    2727
    2828AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) :
    2929    av_context(NULL),
    30     outbuf(NULL),
    31     outbuf_size(0),
    3230    frame_buffer(NULL),
    33     one_frame_bytes(0)
     31    one_frame_bytes(0),
     32    outbuflen(0),
     33    inbuflen(0),
     34    reorder(true),
     35    isAC3upmix(false)
     36{
     37}
     38
     39AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(bool AC3upmix) :
     40    av_context(NULL),
     41    frame_buffer(NULL),
     42    one_frame_bytes(0),
     43    outbuflen(0),
     44    inbuflen(0),
     45    reorder(true),
     46    isAC3upmix(AC3upmix)
    3447{
    3548}
    3649
     
    4861        av_context = NULL;
    4962    }
    5063
    51     if (outbuf)
    52     {
    53         delete [] outbuf;
    54         outbuf = NULL;
    55         outbuf_size = 0;
    56     }
    57 
    58     if (frame_buffer)
     64    if (!isAC3upmix && frame_buffer)
    5965    {
    6066        delete [] frame_buffer;
    6167        frame_buffer = NULL;
     
    6571
    6672//CODEC_ID_AC3
    6773bool AudioOutputDigitalEncoder::Init(
    68     CodecID codec_id, int bitrate, int samplerate, int channels)
     74    CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding)
    6975{
    7076    AVCodec *codec;
    7177    int ret;
    7278
    73     VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4")
     79    VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5")
    7480            .arg(codec_id_string(codec_id))
    7581            .arg(bitrate)
    7682            .arg(samplerate)
    77             .arg(channels));
    78 
     83            .arg(channels)
     84            .arg(reencoding));
     85   
     86    reorder = !reencoding;
     87
     88    // We need to do this when called from mythmusic
     89    if (isAC3upmix) {
     90        avcodec_init();
     91        avcodec_register_all();
     92    }
    7993    //codec = avcodec_find_encoder(codec_id);
    8094    // always AC3 as there is no DTS encoder at the moment 2005/1/9
    8195    codec = avcodec_find_encoder(CODEC_ID_AC3);
     
    105119    audio_bytes_per_sample = bytes_per_frame;
    106120    one_frame_bytes = bytes_per_frame * av_context->frame_size;
    107121
    108     outbuf_size = 16384;    // ok for AC3 but DTS?
    109     outbuf = new char [outbuf_size];
    110122    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
    111123            .arg(av_context->frame_size)
    112124            .arg(bytes_per_frame)
     
    256268
    257269} AESHeader;
    258270
     271void reorder_6ch_ac3(void *buf, unsigned int len) {
     272    unsigned short *src = (unsigned short *)buf;
     273    unsigned short tmp;
     274    unsigned int samples = len >> 1;
     275
     276    for (uint i = 0; i < samples; i += 6) {
     277        tmp = src[i+4];
     278        src[i+4] = src[i+3];
     279        src[i+3] = src[i+2];
     280        src[i+2] = src[i+1];
     281        src[i+1] = tmp;
     282    }
     283}
     284
    259285static int encode_frame(
    260286        bool dts,
    261287        unsigned char *data,
    262         size_t &len)
     288        size_t &len, bool AC3upmix)
    263289{
    264     size_t enc_len;
     290    size_t enc_len = len;
    265291    int flags, sample_rate, bit_rate;
    266292
    267293    // we don't do any length/crc validation of the AC3 frame here; presumably
     
    272298    // ignore, and if so, may as well just assume that it will ignore
    273299    // anything with a bad CRC...
    274300
    275     uint nr_samples = 0, block_len;
     301    uint nr_samples = 0, block_len = 0;
     302   
    276303    if (dts)
    277304    {
    278305        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     
    293320#endif
    294321    }
    295322
    296     if (enc_len == 0 || enc_len > len)
     323    if (!AC3upmix && (enc_len == 0 || enc_len > len))
    297324    {
    298325        int l = len;
    299326        len = 0;
     
    352379    data[6] = (enc_len << 3) & 0xFF;
    353380    data[7] = (enc_len >> 5) & 0xFF;
    354381    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
    355     len = block_len;
     382    if (!AC3upmix)
     383        len = block_len;
    356384
    357385    return enc_len;
    358386}
     
    365393 
    366394    // put data in the correct spot for encode frame
    367395    outsize = avcodec_encode_audio(
    368         av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff);
     396        av_context, ((uchar*)outbuf) + 8, OUTBUFSIZE - 8, buff);
    369397
    370398    size_t tmpsize = outsize;
    371399
    372400    outsize = MAX_AC3_FRAME_SIZE;
    373401    encsize = encode_frame(
    374402        /*av_context->codec_id==CODEC_ID_DTS*/ false,
    375         (unsigned char*)outbuf, outsize);
     403        (unsigned char*)outbuf, outsize, false);
    376404
    377405    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    378406            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     
    380408
    381409    return outsize;
    382410}
     411
     412size_t AudioOutputDigitalEncoder::EncodeUpmix(void *buf, int len)
     413{
     414    size_t outsize = 0;
     415 
     416    int fs = FrameSize();
     417    memcpy(inbuf+inbuflen, buf, len);
     418    inbuflen += len;
     419    int frames = inbuflen / fs;
     420
     421    while (frames--)
     422    {
     423        if (reorder)
     424            reorder_6ch_ac3(inbuf, fs);
     425       
     426        // put data in the correct spot for encode frame
     427        outsize = avcodec_encode_audio(
     428            av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf);
     429
     430        encode_frame(
     431            /*av_context->codec_id==CODEC_ID_DTS*/ false,
     432            (unsigned char*)outbuf + outbuflen, outsize, true
     433        );
     434
     435        outbuflen += MAX_AC3_FRAME_SIZE;
     436        inbuflen -= fs;
     437        memmove(inbuf, inbuf+fs, inbuflen);
     438    }
     439
     440    return outbuflen;
     441}
     442
     443void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen)
     444{
     445    int len = (maxlen < outbuflen ? maxlen : outbuflen);
     446    memcpy(ptr, outbuf, len);
     447    outbuflen -= len;
     448    memmove(outbuf, outbuf+len, outbuflen);
     449}
  • mythtv/libs/libmyth/audiooutputdigitalencoder.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmyth/audiooutputdigitalencoder.h c/mythtv/libs/libmyth/audiooutputdigitalencoder.h
    a c  
    55#include "libavcodec/avcodec.h"
    66};
    77
     8#define INBUFSIZE 131072
     9#define OUTBUFSIZE 98304
     10
    811class AudioOutputDigitalEncoder
    912{
    1013  public:
    1114    AudioOutputDigitalEncoder(void);
     15    AudioOutputDigitalEncoder(bool AC3upmix);
    1216    ~AudioOutputDigitalEncoder();
    1317
    14     bool   Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     18    bool   Init(CodecID codec_id, int bitrate, int samplerate,
     19                int channels, bool reencoding = false);
    1520    void   Dispose(void);
    1621    size_t Encode(short * buff);
    1722
    1823    inline char *GetFrameBuffer(void);
    1924    size_t FrameSize(void)  const { return one_frame_bytes; }
    20     char  *GetOutBuff(void) const { return outbuf;          }
     25    const char  *GetOutBuff(void) const { return outbuf; }
     26    //AC3 upmix
     27    size_t EncodeUpmix(void *buf, int len);
     28    void   GetFrames(void *ptr, int maxlen);
     29    int    Buffered(void) const { return inbuflen; }
    2130
    2231  public:
    2332    size_t audio_bytes_per_sample;
    2433
    2534  private:
    2635    AVCodecContext *av_context;
    27     char           *outbuf;
    28     int             outbuf_size;
     36    char            outbuf[OUTBUFSIZE];
    2937    char           *frame_buffer;
    3038    size_t          one_frame_bytes;
     39    // AC3 upmix
     40    char            inbuf[INBUFSIZE];
     41    int             outbuflen;
     42    int             inbuflen;
     43    bool            reorder;
     44    bool            isAC3upmix;
    3145};
    3246
    3347inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)
  • mythtv/libs/libmythfreesurround/el_processor.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/el_processor.cpp c/mythtv/libs/libmythfreesurround/el_processor.cpp
    a c  
    4040
    4141const float PI = 3.141592654;
    4242const float epsilon = 0.000001;
     43const float center_level_upmix = 0.5*sqrt(0.5);
    4344//const float center_level = 0.5*sqrt(0.5);   // gain of the center channel
    4445//const float center_level = sqrt(0.5);   // gain of the center channel
    4546const float center_level = 1.0;   // gain of the center channel
     
    5758public:
    5859    // create an instance of the decoder
    5960    //  blocksize is fixed over the lifetime of this object for performance reasons
    60     decoder_impl(unsigned blocksize=8192): N(blocksize), halfN(blocksize/2) {
     61  decoder_impl(unsigned blocksize=8192, bool AC3upmix=false): N(blocksize), halfN(blocksize/2), isAC3upmix(AC3upmix) {
    6162#ifdef USE_FFTW3
    6263        // create FFTW buffers
    6364        lt = (float*)fftwf_malloc(sizeof(float)*N);
     
    99100            filter[c].resize(N);
    100101        }
    101102        // DC component of filters is always 0
    102         for (unsigned c=0;c<5;c++)
    103         {
    104             filter[c][0] = 0.0;
    105             filter[c][1] = 0.0;
    106             filter[c][halfN] = 0.0;
    107         }
    108         sample_rate(48000);
    109         // generate the window function (square root of hann, b/c it is applied before and after the transform)
    110         wnd.resize(N);
    111         // dft normalization included in the window for zero cost scaling
    112         // also add a gain factor of *2 due to processing gain in algo (see center_level)
    113         surround_gain(1.0);
     103        if (!isAC3upmix) {
     104            for (unsigned c=0;c<5;c++)
     105            {
     106                filter[c][0] = 0.0;
     107                filter[c][1] = 0.0;
     108                filter[c][halfN] = 0.0;
     109            }
     110            sample_rate(48000);
     111            // generate the window function (square root of hann, b/c it is applied before and after the transform)
     112            wnd.resize(N);
     113            // dft normalization included in the window for zero cost scaling
     114            // also add a gain factor of *2 due to processing gain in algo (see center_level)
     115            surround_gain(1.0);
     116        } else {
     117            sample_rate(48000);
     118            // generate the window function (square root of hann, b/c it is applied before and after the transform)
     119            wnd.resize(N);
     120            for (unsigned k=0;k<N;k++)
     121                wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N);
     122        }
    114123        current_buf = 0;
    115124        // set the default coefficients
    116125        surround_coefficients(0.8165,0.5774);
     
    192201    // set lfe filter params
    193202    void sample_rate(unsigned int srate) {
    194203        // lfe filter is just straight through band limited
    195         unsigned int cutoff = (250*N)/srate;
    196         for (unsigned f=0;f<=halfN;f++) {           
    197             if ((f>=2) && (f<cutoff))
    198                 filter[5][f] = 1.0;
    199             else
    200                 filter[5][f] = 0.0;
     204        unsigned int cutoff;
     205        if (!isAC3upmix) {
     206             cutoff = (250*N)/srate;
     207            for (unsigned f=0;f<=halfN;f++) {           
     208                if ((f>=2) && (f<cutoff))
     209                    filter[5][f] = 1.0;
     210                else
     211                    filter[5][f] = 0.0;
     212            }
     213        } else {
     214            cutoff = (30*N)/srate;
     215            for (unsigned f=0;f<=halfN;f++) {           
     216                if (f<cutoff)
     217                    filter[5][f] = 0.5*sqrt(0.5);
     218                else
     219                    filter[5][f] = 0.0;
     220            }
    201221        }
    202222    }
    203223
     
    237257    }
    238258
    239259private:
     260    bool isAC3upmix;
    240261    // polar <-> cartesian coodinates conversion
    241262    static inline float amplitude(const float cf[2]) { return sqrt(cf[0]*cf[0] + cf[1]*cf[1]); }
    242263    static inline float phase(const float cf[2]) { return atan2(cf[1],cf[0]); }
     
    290311
    291312        // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field
    292313        //    but dont do DC or N/2 component
    293         for (unsigned f=2;f<halfN;f++) {           
     314        unsigned start_f = isAC3upmix ? 0:2;
     315        for (unsigned f=start_f;f<halfN;f++) {           
    294316            // get left/right amplitudes/phases
    295317            float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]);
    296318            float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]);
     
    357379                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
    358380                float volume[5] = {
    359381                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),  // left
    360                     front * center_level*((1-abs(xfs[f])) * (1-center_width)),          // center
     382                    front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)),          // center
    361383                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)), // right
    362384                    back * surround_level * left,                                       // left surround
    363385                    back * surround_level * right                                       // right surround
     
    402424                float front = (1+yfs[f])/2, back = (1-yfs[f])/2;
    403425                float volume[5] = {
    404426                    front * (left * center_width + max(0,-xfs[f]) * (1-center_width)),      // left
    405                     front * center_level*((1-abs(xfs[f])) * (1-center_width)),              // center
     427                    front * (isAC3upmix ? center_level_upmix : center_level) *((1-abs(xfs[f])) * (1-center_width)),          // center
    406428                    front * (right * center_width + max(0, xfs[f]) * (1-center_width)),     // right
    407429                    back * surround_level*max(0,min(1,((1-(xfs[f]/surround_balance))/2))),  // left surround
    408430                    back * surround_level*max(0,min(1,((1+(xfs[f]/surround_balance))/2)))   // right surround
     
    613635
    614636// implementation of the shell class
    615637
    616 fsurround_decoder::fsurround_decoder(unsigned blocksize): impl(new decoder_impl(blocksize)) { }
     638fsurround_decoder::fsurround_decoder(unsigned blocksize, bool AC3upmix): impl(new decoder_impl(blocksize,AC3upmix)) { }
    617639
    618640fsurround_decoder::~fsurround_decoder() { delete impl; }
    619641
  • mythtv/libs/libmythfreesurround/el_processor.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/el_processor.h c/mythtv/libs/libmythfreesurround/el_processor.h
    a c  
    2424public:
    2525        // create an instance of the decoder
    2626        //  blocksize is fixed over the lifetime of this object for performance reasons
    27         fsurround_decoder(unsigned blocksize=8192);
     27        fsurround_decoder(unsigned blocksize=8192, bool AC3upmix=false);
    2828        // destructor
    2929        ~fsurround_decoder();
    3030       
     
    5151        void gain(float gain);
    5252
    5353        // set the phase shifting mode for decoding
    54         // 0 = (+0°,+0°)   - music mode
    55         // 1 = (+0°,+180°) - PowerDVD compatibility
    56         // 2 = (+180°,+0°) - BeSweet compatibility
    57         // 3 = (-90°,+90°) - This seems to work. I just don't know why.
     54        // 0 = (+0,+0)   - music mode
     55        // 1 = (+0,+180) - PowerDVD compatibility
     56        // 2 = (+180,+0) - BeSweet compatibility
     57        // 3 = (-90,+90) - This seems to work. I just don't know why.
    5858        void phase_mode(unsigned mode);
    5959
    6060        // override the steering mode
     
    7171
    7272private:
    7373        class decoder_impl *impl; // private implementation (details hidden)
     74        bool isAC3upmix;
    7475};
    7576
    7677
  • mythtv/libs/libmythfreesurround/freesurround.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/freesurround.cpp c/mythtv/libs/libmythfreesurround/freesurround.cpp
    a c  
    163163
    164164// construction methods
    165165void *new_decoder() { return new fsurround_decoder(block_size); }
     166void *new_decoder_upmix() { return new fsurround_decoder(block_size,true); }
    166167void *new_buffers() { return new buffers(block_size/2); }
    167168void *new_int16buffers() { return new int16buffers(block_size/2); }
    168169
    169170object_pool dp(&new_decoder);
     171object_pool dp_upmix(&new_decoder_upmix);
    170172//object_pool bp(&new_buffers);
    171173object_pool bp16(&new_int16buffers);
    172174
     
    175177int channel_select = -1;
    176178#endif
    177179
    178 FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) :
     180FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode, bool AC3upmix) :
    179181        srate(srate),
    180182        open_(false),
    181183        initialized_(false),
     
    185187        in_count(0),
    186188        out_count(0),
    187189        processed(true),
    188         surround_mode(smode)
     190        surround_mode(smode),
     191        isAC3upmix(AC3upmix)
    189192{
    190193    VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2").arg(srate).arg(moviemode));
    191194    if (moviemode)
    192195    {
    193196        params.phasemode = 1;
    194         params.center_width = 0;
    195         params.gain = 1.0;
     197        if (!isAC3upmix) {
     198            params.center_width = 0;
     199            params.gain = 1.0;
     200        } else {
     201            params.center_width = 25;
     202            params.dimension = 0.5;
     203        }
    196204    }
    197205    else
    198206    {
    199         params.center_width = 70;
    200         // for 50, gain should be about 1.9, c/lr about 2.7
    201         // for 70, gain should be about 3.1, c/lr about 1.5
    202         params.gain = 3.1;
     207        if (!isAC3upmix) {
     208            params.center_width = 70;
     209            // for 50, gain should be about 1.9, c/lr about 2.7
     210            // for 70, gain should be about 3.1, c/lr about 1.5
     211            params.gain = 3.1;
     212        } else {
     213            params.center_width = 65;
     214            params.dimension = 0.3;
     215        }
    203216    }
    204217    switch (surround_mode)
    205218    {
     
    235248        decoder->phase_mode(params.phasemode);
    236249        decoder->surround_coefficients(params.coeff_a, params.coeff_b);                         
    237250        decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
    238         decoder->gain(params.gain);
     251        if (!isAC3upmix)
     252            decoder->gain(params.gain);
    239253    }
    240254}
    241255
     
    654668    {
    655669        if (decoder)
    656670        {
    657             // actually these params need only be set when they change... but it doesn't hurt
    658 #if 0
    659             decoder->steering_mode(params.steering);
    660             decoder->phase_mode(params.phasemode);
    661             decoder->surround_coefficients(params.coeff_a, params.coeff_b);                             
    662             decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);
    663 #endif
    664             // decode the bufs->block
    665             //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);
    666             //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);
    667671            decoder->decode(params.center_width/100.0,params.dimension/100.0);
    668672        }
    669673    }
     
    693697{               
    694698    if (!decoder)
    695699    {
    696         decoder = (fsurround_decoder*)dp.acquire((void*)1);
     700        if (!isAC3upmix)
     701            decoder = (fsurround_decoder*)dp.acquire((void*)1);
     702        else
     703            decoder = (fsurround_decoder*)dp_upmix.acquire((void*)1);
    697704        decoder->flush();
    698705        //if (bufs)
    699706        //    bufs->clear();
     
    708715{
    709716    if (decoder)
    710717    {
    711         dp.release(this);
     718        if (!isAC3upmix)
     719            dp.release(this);
     720        else
     721            dp_upmix.release(this);
    712722        decoder = 0;
    713723    }
    714724}
  • mythtv/libs/libmythfreesurround/freesurround.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythfreesurround/freesurround.h c/mythtv/libs/libmythfreesurround/freesurround.h
    a c  
    3131        SurroundModeActiveLinear
    3232    } SurroundMode;
    3333public:
    34     FreeSurround(uint srate, bool moviemode, SurroundMode mode);
     34    FreeSurround(uint srate, bool moviemode, SurroundMode mode, bool AC3upmix=false);
    3535    ~FreeSurround();
    3636
    3737    // put samples in buffer, returns number of samples used
     
    8888    bool processed;             // whether processing is enabled or not for latency calc
    8989    int processed_size;         // amount processed
    9090    SurroundMode surround_mode; // 1 of 3 surround modes supported
     91    bool isAC3upmix;
    9192
    9293};
    9394
  • mythtv/libs/libmythsamplerate/samplerate.c

    diff -Naur --exclude=.svn a/mythtv/libs/libmythsamplerate/samplerate.c c/mythtv/libs/libmythsamplerate/samplerate.c
    a c  
    428428
    429429        error = src_process (src_state, src_data) ;
    430430
    431         src_state = src_delete (src_state) ;
     431        src_delete (src_state) ;
    432432
    433433        return error ;
    434434} /* src_simple */
     
    452452        {       len -- ;
    453453
    454454                scaled_value = in [len] * (8.0 * 0x10000000) ;
    455                 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
     455                if (scaled_value >= (1.0 * 0x7FFFFFFF))
    456456                {       out [len] = 32767 ;
    457457                        continue ;
    458458                        } ;
    459                 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
     459                if (scaled_value <= (-8.0 * 0x10000000))
    460460                {       out [len] = -32768 ;
    461461                        continue ;
    462462                        } ;
  • mythtv/libs/libmythtv/NuppelVideoPlayer.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp c/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
    a c  
    769769
    770770    no_audio_in = false;
    771771
     772    bool isAC3upmix = gContext->GetNumSetting("MythAC3Upmix",0);
     773    // If previously AC3 upmixer was different than current state, delete AudioOutput
     774    if (audioOutput && (audioOutput->isAC3upmix != isAC3upmix))
     775    {
     776        delete audioOutput;
     777        audioOutput = NULL;
     778    }
     779
    772780    if (!audioOutput && !using_null_videoout)
    773781    {
    774782        bool setVolume = gContext->GetNumSetting("MythControlsVolume", 1);
     
    777785                                             audio_bits, audio_channels,
    778786                                             audio_samplerate,
    779787                                             AUDIOOUTPUT_VIDEO,
    780                                              setVolume, audio_passthru);
     788                                             setVolume, audio_passthru, isAC3upmix);
    781789        if (!audioOutput)
    782790            errMsg = QObject::tr("Unable to create AudioOutput.");
    783791        else
     
    806814        audioOutput->Reconfigure(audio_bits, audio_channels,
    807815                                 audio_samplerate, audio_passthru,
    808816                                 audio_codec);
     817        if (audioOutput->isAC3upmix && audio_passthru)
     818            audio_channels = 2;
    809819        errMsg = audioOutput->GetError();
    810820        if (!errMsg.isEmpty())
    811821            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    49434953    }
    49444954}
    49454955
     4956bool NuppelVideoPlayer::ToggleUpmix()
     4957{
     4958    if (audioOutput)
     4959        return audioOutput->ToggleUpmix();
     4960    return false;
     4961}
     4962
    49464963void NuppelVideoPlayer::Zoom(ZoomDirection direction)
    49474964{
    49484965    if (videoOutput)
  • mythtv/libs/libmythtv/NuppelVideoPlayer.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/NuppelVideoPlayer.h c/mythtv/libs/libmythtv/NuppelVideoPlayer.h
    a c  
    175175    // Toggle Sets
    176176    void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle);
    177177    void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle);
     178    bool ToggleUpmix(void);
    178179
    179180    // Gets
    180181    QSize   GetVideoBufferSize(void) const    { return video_dim; }
  • mythtv/libs/libmythtv/avformatdecoder.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.cpp c/mythtv/libs/libmythtv/avformatdecoder.cpp
    a c  
    427427      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    428428      allow_ac3_passthru(false),    allow_dts_passthru(false),
    429429      disable_passthru(false),      max_channels(2),
    430       dummy_frame(NULL),
     430      last_ac3_channels(0),         dummy_frame(NULL),
    431431      // DVD
    432432      lastdvdtitle(-1),
    433433      decodeStillFrame(false),
     
    445445    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    446446    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    447447    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
     448    isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0);
    448449
    449450    audioIn.sample_size = -32; // force SetupAudioStream to run once
    450451    itv = GetNVP()->GetInteractiveTV();
     
    29462947    {
    29472948        int idx = atracks[i].av_stream_index;
    29482949        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
    2949         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2950                                 !disable_passthru &&
    2951                                 (codec_ctx->codec_id == CODEC_ID_AC3));
    2952         bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2953                                 !disable_passthru &&
    2954                                 (codec_ctx->codec_id == CODEC_ID_DTS));
    29552950        AudioInfo item(codec_ctx->codec_id,
    29562951                       codec_ctx->sample_rate, codec_ctx->channels,
    2957                        do_ac3_passthru || do_dts_passthru);
     2952                       DoPassThrough(codec_ctx));
    29582953        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
    29592954    }
    29602955#endif
     
    30883083bool AvFormatDecoder::GetFrame(int onlyvideo)
    30893084{
    30903085    AVPacket *pkt = NULL;
     3086    AC3HeaderInfo hdr;
    30913087    int len;
    30923088    unsigned char *ptr;
    30933089    int data_size = 0;
     
    32743270        pts = 0;
    32753271
    32763272        AVStream *curstream = ic->streams[pkt->stream_index];
     3273        AVCodecContext *ctx = curstream->codec;
    32773274
    32783275        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    32793276            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    32803277
    32813278        if (ringBuffer->isDVD() &&
    3282             curstream->codec->codec_type == CODEC_TYPE_VIDEO)
     3279            ctx->codec_type == CODEC_TYPE_VIDEO)
    32833280        {
    32843281            MpegPreProcessPkt(curstream, pkt);
    32853282
     
    33073304
    33083305            if (!d->HasMPEG2Dec())
    33093306            {
    3310                 int current_width = curstream->codec->width;
     3307                int current_width = ctx->width;
    33113308                int video_width = GetNVP()->GetVideoSize().width();
    33123309                if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput())
    33133310                {
     
    33483345        }
    33493346
    33503347        if (storevideoframes &&
    3351             curstream->codec->codec_type == CODEC_TYPE_VIDEO)
     3348            ctx->codec_type == CODEC_TYPE_VIDEO)
    33523349        {
    33533350            av_dup_packet(pkt);
    33543351            storedPackets.append(pkt);
     
    33563353            continue;
    33573354        }
    33583355
    3359         if (len > 0 && curstream->codec->codec_type == CODEC_TYPE_VIDEO &&
     3356        if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO &&
    33603357            pkt->stream_index == selectedVideoIndex)
    33613358        {
    3362             AVCodecContext *context = curstream->codec;
    33633359
    3364             if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
    3365                 context->codec_id == CODEC_ID_MPEG2VIDEO ||
    3366                 context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
    3367                 context->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
    3368                 context->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
     3360            if (ctx->codec_id == CODEC_ID_MPEG1VIDEO ||
     3361                ctx->codec_id == CODEC_ID_MPEG2VIDEO ||
     3362                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||
     3363                ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||
     3364                ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)
    33693365            {
    33703366                if (!ringBuffer->isDVD())
    33713367                    MpegPreProcessPkt(curstream, pkt);
    33723368            }
    3373             else if (context->codec_id == CODEC_ID_H264 ||
    3374                      context->codec_id == CODEC_ID_H264_VDPAU)
     3369            else if (ctx->codec_id == CODEC_ID_H264 ||
     3370                     ctx->codec_id == CODEC_ID_H264_VDPAU)
    33753371            {
    33763372                H264PreProcessPkt(curstream, pkt);
    33773373            }
     
    34173413        }
    34183414
    34193415        if (len > 0 &&
    3420             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3421             curstream->codec->codec_id   == CODEC_ID_MPEG2VBI)
     3416            ctx->codec_type == CODEC_TYPE_DATA &&
     3417            ctx->codec_id   == CODEC_ID_MPEG2VBI)
    34223418        {
    34233419            ProcessVBIDataPacket(curstream, pkt);
    34243420
     
    34273423        }
    34283424
    34293425        if (len > 0 &&
    3430             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3431             curstream->codec->codec_id   == CODEC_ID_DVB_VBI)
     3426            ctx->codec_type == CODEC_TYPE_DATA &&
     3427            ctx->codec_id   == CODEC_ID_DVB_VBI)
    34323428        {
    34333429            ProcessDVBDataPacket(curstream, pkt);
    34343430
     
    34373433        }
    34383434
    34393435        if (len > 0 &&
    3440             curstream->codec->codec_type == CODEC_TYPE_DATA &&
    3441             curstream->codec->codec_id   == CODEC_ID_DSMCC_B)
     3436            ctx->codec_type == CODEC_TYPE_DATA &&
     3437            ctx->codec_id   == CODEC_ID_DSMCC_B)
    34423438        {
    34433439            ProcessDSMCCPacket(curstream, pkt);
    34443440
     
    34583454        }
    34593455
    34603456        // we don't care about other data streams
    3461         if (curstream->codec->codec_type == CODEC_TYPE_DATA)
     3457        if (ctx->codec_type == CODEC_TYPE_DATA)
    34623458        {
    34633459            av_free_packet(pkt);
    34643460            continue;
    34653461        }
    34663462
    3467         if (!curstream->codec->codec)
     3463        if (!ctx->codec)
    34683464        {
    34693465            VERBOSE(VB_PLAYBACK, LOC +
    34703466                    QString("No codec for stream index %1, type(%2) id(%3:%4)")
    34713467                    .arg(pkt->stream_index)
    3472                     .arg(codec_type_string(curstream->codec->codec_type))
    3473                     .arg(codec_id_string(curstream->codec->codec_id))
    3474                     .arg(curstream->codec->codec_id));
     3468                    .arg(codec_type_string(ctx->codec_type))
     3469                    .arg(codec_id_string(ctx->codec_id))
     3470                    .arg(ctx->codec_id));
    34753471            av_free_packet(pkt);
    34763472            continue;
    34773473        }
     
    34803476        have_err = false;
    34813477
    34823478        avcodeclock.lock();
    3483         int ctype  = curstream->codec->codec_type;
     3479        int ctype  = ctx->codec_type;
    34843480        int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index;
    34853481        int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index;
    34863482        int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index;
     
    35053501
    35063502                    // detect switches between stereo and dual languages
    35073503                    bool wasDual = audSubIdx != -1;
    3508                     bool isDual = curstream->codec->avcodec_dual_language;
     3504                    bool isDual = ctx->avcodec_dual_language;
    35093505                    if ((wasDual && !isDual) || (!wasDual &&  isDual))
    35103506                    {
    35113507                        SetupAudioStreamSubIndexes(audIdx);
    35123508                        reselectAudioTrack = true;
    35133509                    }                           
    35143510
    3515                     bool do_ac3_passthru =
    3516                         (allow_ac3_passthru && !transcoding &&
    3517                          (curstream->codec->codec_id == CODEC_ID_AC3));
    3518                     bool do_dts_passthru =
    3519                         (allow_dts_passthru && !transcoding &&
    3520                          (curstream->codec->codec_id == CODEC_ID_DTS));
    3521                     bool using_passthru = do_ac3_passthru || do_dts_passthru;
    3522 
    35233511                    // detect channels on streams that need
    35243512                    // to be decoded before we can know this
    35253513                    bool already_decoded = false;
    3526                     if (!curstream->codec->channels)
     3514                    if (!ctx->channels)
    35273515                    {
    35283516                        QMutexLocker locker(&avcodeclock);
    35293517                        VERBOSE(VB_IMPORTANT, LOC +
    35303518                                QString("Setting channels to %1")
    35313519                                .arg(audioOut.channels));
    35323520
    3533                         if (using_passthru)
     3521                        if (DoPassThrough(ctx))
    35343522                        {
    35353523                            // for passthru let it select the max number
    35363524                            // of channels
    3537                             curstream->codec->channels = 0;
    3538                             curstream->codec->request_channels = 0;
     3525                            ctx->channels = 0;
     3526                            ctx->request_channels = 0;
    35393527                        }
    35403528                        else
    35413529                        {
    3542                             curstream->codec->channels = audioOut.channels;
    3543                             curstream->codec->request_channels =
     3530                            ctx->channels = audioOut.channels;
     3531                            ctx->request_channels =
    35443532                                audioOut.channels;
    35453533                        }
    35463534                        ret = avcodec_decode_audio(
    3547                             curstream->codec, audioSamples,
     3535                            ctx, audioSamples,
    35483536                            &data_size, ptr, len);
    35493537                        already_decoded = true;
    35503538
    3551                         reselectAudioTrack |= curstream->codec->channels;
     3539                        reselectAudioTrack |= ctx->channels;
     3540                    }
     3541
     3542                    if (isAC3upmix && ctx->codec_id == CODEC_ID_AC3 &&
     3543                        !ff_ac3_parse_header(ptr, &hdr))
     3544                    {
     3545                        if (hdr.channels != last_ac3_channels)
     3546                        {
     3547                            last_ac3_channels = ctx->channels = hdr.channels;
     3548                            SetupAudioStream();
     3549                        }
    35523550                    }
    35533551
    35543552                    if (reselectAudioTrack)
     
    35643562                            .av_stream_index;
    35653563                        audSubIdx = selectedTrack[kTrackTypeAudio]
    35663564                            .av_substream_index;
     3565                        ctx = curstream->codec;
    35673566                    }
    35683567
    35693568                    if ((onlyvideo > 0) || (pkt->stream_index != audIdx))
     
    35953594                    if (audioOut.do_passthru)
    35963595                    {
    35973596                        data_size = pkt->size;
    3598                         bool dts = CODEC_ID_DTS == curstream->codec->codec_id;
     3597                        bool dts = CODEC_ID_DTS == ctx->codec_id;
    35993598                        ret = encode_frame(dts, ptr, len,
    36003599                                           audioSamples, data_size);
    36013600                    }
    36023601                    else
    36033602                    {
    3604                         AVCodecContext *ctx = curstream->codec;
    3605 
    36063603                        if ((ctx->channels == 0) ||
    36073604                            (ctx->channels > audioOut.channels))
    36083605                        {
     
    36113608
    36123609                        if (!already_decoded)
    36133610                        {
    3614                             curstream->codec->request_channels =
    3615                                 audioOut.channels;
     3611                            ctx->request_channels = audioOut.channels;
    36163612                            ret = avcodec_decode_audio(
    36173613                                ctx, audioSamples, &data_size, ptr, len);
    36183614                        }
     
    36293625                            audIdx = -1;
    36303626                            AutoSelectAudioTrack();
    36313627                            data_size = 0;
     3628                            ctx = curstream->codec;
    36323629                        }
    36333630                    }
    36343631                    avcodeclock.unlock();
     
    36463643
    36473644                    // calc for next frame
    36483645                    lastapts += (long long)((double)(data_size * 1000) /
    3649                                 (curstream->codec->channels * 2) /
    3650                                 curstream->codec->sample_rate);
     3646                                (ctx->channels * 2) / ctx->sample_rate);
    36513647
    36523648                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP,
    36533649                            LOC + QString("audio timecode %1 %2 %3 %4")
     
    37073703                        continue;
    37083704                    }
    37093705
    3710                     AVCodecContext *context = curstream->codec;
    37113706                    AVFrame mpa_pic;
    37123707                    bzero(&mpa_pic, sizeof(AVFrame));
    37133708
     
    37223717                            // HACK
    37233718                            while (!gotpicture && count < 5)
    37243719                            {
    3725                                 ret = d->DecodeMPEG2Video(context, &mpa_pic,
     3720                                ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
    37263721                                                  &gotpicture, ptr, len);
    37273722                                count++;
    37283723                            }
    37293724                        }
    37303725                        else
    37313726                        {
    3732                             ret = d->DecodeMPEG2Video(context, &mpa_pic,
     3727                            ret = d->DecodeMPEG2Video(ctx, &mpa_pic,
    37333728                                                &gotpicture, ptr, len);
    37343729                        }
    37353730                    }
    37363731                    else
    37373732                    {
    3738                         ret = avcodec_decode_video(context, &mpa_pic,
     3733                        ret = avcodec_decode_video(ctx, &mpa_pic,
    37393734                                                   &gotpicture, ptr, len);
    37403735                        // Reparse it to not drop the DVD still frame
    37413736                        if (decodeStillFrame)
    3742                             ret = avcodec_decode_video(context, &mpa_pic,
     3737                            ret = avcodec_decode_video(ctx, &mpa_pic,
    37433738                                                        &gotpicture, ptr, len);
    37443739                    }
    37453740                    avcodeclock.unlock();
     
    38063801
    38073802                        img_convert(&tmppicture, PIX_FMT_YUV420P,
    38083803                                    (AVPicture *)&mpa_pic,
    3809                                     context->pix_fmt,
    3810                                     context->width,
    3811                                     context->height);
     3804                                    ctx->pix_fmt,
     3805                                    ctx->width,
     3806                                    ctx->height);
    38123807
    38133808                        if (xf)
    38143809                        {
     
    38313826                        (temppts + 10000 > lastvpts || temppts < 0))
    38323827                    {
    38333828                        temppts = lastvpts;
    3834                         temppts += (long long)(1000 * av_q2d(context->time_base));
     3829                        temppts += (long long)(1000 * av_q2d(ctx->time_base));
    38353830                        // MPEG2 frames can be repeated, update pts accordingly
    38363831                        temppts += (long long)(mpa_pic.repeat_pict * 500
    3837                                       * av_q2d(curstream->codec->time_base));
     3832                                      * av_q2d(ctx->time_base));
    38383833                    }
    38393834
    38403835                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
     
    38703865                    picframe->frameNumber = framesPlayed;
    38713866                    GetNVP()->ReleaseNextVideoFrame(picframe, temppts);
    38723867                    if (d->HasMPEG2Dec() && mpa_pic.data[3])
    3873                         context->release_buffer(context, &mpa_pic);
     3868                        ctx->release_buffer(ctx, &mpa_pic);
    38743869
    38753870                    decoded_video_frame = picframe;
    38763871                    gotvideo = 1;
     
    39293924                }
    39303925                default:
    39313926                {
    3932                     AVCodecContext *enc = curstream->codec;
    39333927                    VERBOSE(VB_IMPORTANT, LOC_ERR +
    39343928                            QString("Decoding - id(%1) type(%2)")
    3935                             .arg(codec_id_string(enc->codec_id))
    3936                             .arg(codec_type_string(enc->codec_type)));
     3929                            .arg(codec_id_string(ctx->codec_id))
     3930                            .arg(codec_type_string(ctx->codec_type)));
    39373931                    have_err = true;
    39383932                    break;
    39393933                }
     
    40824076    }
    40834077}
    40844078
     4079bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx)
     4080{
     4081    bool do_ac3_passthru =
     4082        (allow_ac3_passthru && !transcoding &&
     4083        (ctx->codec_id == CODEC_ID_AC3));
     4084    bool do_dts_passthru =
     4085        (allow_dts_passthru && !transcoding &&
     4086        (ctx->codec_id == CODEC_ID_DTS));
     4087    bool using_passthru = do_ac3_passthru || do_dts_passthru;
     4088
     4089    if (!isAC3upmix)
     4090        return using_passthru;
     4091
     4092    bool passthru = false;
     4093
     4094    if (ctx->codec_id == CODEC_ID_AC3)
     4095        passthru = allow_ac3_passthru &&
     4096                   ctx->channels >= (int)max_channels;
     4097    else if (ctx->codec_id == CODEC_ID_DTS)
     4098        passthru = allow_dts_passthru;
     4099   
     4100    passthru &= !transcoding && !disable_passthru;
     4101    // Don't know any cards that support spdif clocked at < 44100
     4102    // Some US cable transmissions have 2ch 32k AC-3 streams
     4103    passthru &= ctx->sample_rate >= 44100;
     4104
     4105    return passthru;
     4106}
     4107
    40854108/** \fn AvFormatDecoder::SetupAudioStream(void)
    40864109 *  \brief Reinitializes audio if it needs to be reinitialized.
    40874110 *
     
    41074130        assert(curstream);
    41084131        assert(curstream->codec);
    41094132        codec_ctx = curstream->codec;       
    4110         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    4111                                 (codec_ctx->codec_id == CODEC_ID_AC3));
    4112         bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    4113                                 (codec_ctx->codec_id == CODEC_ID_DTS));
    4114         using_passthru = do_ac3_passthru || do_dts_passthru;
    4115         info = AudioInfo(codec_ctx->codec_id,
    4116                          codec_ctx->sample_rate, codec_ctx->channels,
    4117                          using_passthru && !disable_passthru);
     4133        using_passthru = DoPassThrough(codec_ctx);
     4134        if (!isAC3upmix)
     4135            info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, codec_ctx->channels, using_passthru && !disable_passthru);
     4136        else
     4137            info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate,
     4138                             codec_ctx->channels, using_passthru);
    41184139    }
    41194140
    41204141    if (info == audioIn)
     
    41254146            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    41264147
    41274148    audioOut = audioIn = info;
     4149    if (!isAC3upmix) {
    41284150    if (using_passthru)
    41294151    {
    41304152        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
     
    41814203
    41824204    // allow the audio stuff to reencode
    41834205    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     4206    } else {
     4207
     4208    if (!using_passthru && audioOut.channels > (int)max_channels)
     4209    {
     4210        audioOut.channels = (int)max_channels;
     4211        audioOut.sample_size = audioOut.channels * 2;
     4212        codec_ctx->channels = audioOut.channels;
     4213    }
     4214   
     4215    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
     4216            QString("\n\t\t\tfrom %1 to %2")
     4217            .arg(old_in.toString()).arg(audioOut.toString()));
     4218
     4219    if (audioOut.sample_rate > 0)
     4220        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
     4221
     4222    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     4223                             audioOut.sample_rate,
     4224                             audioOut.do_passthru);
     4225   
     4226    }
    41844227    QString errMsg = GetNVP()->ReinitAudio();
    41854228    bool audiook = errMsg.isEmpty();
    41864229
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.h c/mythtv/libs/libmythtv/avformatdecoder.h
    a c  
    185185    void InitVideoCodec(AVStream *stream, AVCodecContext *enc,
    186186                        bool selectedStream = false);
    187187
    188     /// Preprocess a packet, setting the video parms if nessesary.
     188    /// Preprocess a packet, setting the video parms if necessary.
    189189    void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt);
    190190    void H264PreProcessPkt(AVStream *stream, AVPacket *pkt);
    191191
     
    198198
    199199    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
    200200
     201    bool DoPassThrough(const AVCodecContext *ctx);
    201202    bool SetupAudioStream(void);
    202203    void SetupAudioStreamSubIndexes(int streamIndex);
    203204    void RemoveAudioStreams();
     
    266267    bool              allow_dts_passthru;
    267268    bool              disable_passthru;
    268269    uint              max_channels;
     270    uint              last_ac3_channels;
     271    bool              isAC3upmix;
    269272
    270273    VideoFrame       *dummy_frame;
    271274
  • mythtv/libs/libmythtv/tv_play.cpp

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/tv_play.cpp c/mythtv/libs/libmythtv/tv_play.cpp
    a c  
    348348    REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down");
    349349    REG_KEY("TV Playback", "VOLUMEUP",   "Volume up",   "],},F11,Volume Up");
    350350    REG_KEY("TV Playback", "MUTE",       "Mute",        "|,\\,F9,Volume Mute");
     351    REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U");
    351352    REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode",
    352353            "V");
    353354    REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B");
     
    480481  Teletext     F2,F3,F4,F5,F6,F7,F8
    481482  ITV          F2,F3,F4,F5,F6,F7,F12
    482483
    483   Playback: Ctrl-B,Ctrl-G,Ctrl-Y
     484  Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U
    484485*/
    485486}
    486487
     
    27122713            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
    27132714                     action == "STRETCHINC" || action == "STRETCHDEC" ||
    27142715                     action == "MUTE"       || action == "TOGGLEASPECT" ||
    2715                      action == "TOGGLEFILL" )
     2716                     action == "TOGGLEFILL" || action == "TOGGLEUPMIX")
    27162717            {
    27172718                passThru = 1;
    27182719                handled = false;
     
    27672768            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
    27682769                     action == "STRETCHINC" || action == "STRETCHDEC" ||
    27692770                     action == "MUTE" || action == "PAUSE" ||
    2770                      action == "CLEAROSD")
     2771                     action == "CLEAROSD" || action == "TOGGLEUPMIX")
    27712772            {
    27722773                passThru = 1;
    27732774                handled = false;
     
    30723073            ChangeTimeStretch(0);   // just display
    30733074        else if (action == "TOGGLESTRETCH")
    30743075            ToggleTimeStretch();
     3076        else if (action == "TOGGLEUPMIX")
     3077            ToggleUpmix();
    30753078        else if (action == "CYCLECOMMSKIPMODE") {
    30763079            SetAutoCommercialSkip((enum commSkipMode)
    30773080                                  ((autoCommercialSkip + 1) % CommSkipModes));
     
    60566059    }
    60576060}
    60586061
     6062void TV::ToggleUpmix()
     6063{
     6064    AudioOutput *aud = nvp->getAudioOutput();
     6065    if (!aud)
     6066        return;
     6067    QString text;
     6068    if(!aud->isAC3upmix) {
     6069        text = tr("Upmixer disabled !");
     6070    } else {
     6071        if (aud->ToggleUpmix())
     6072            text = tr("Upmixer On");
     6073        else
     6074            text = tr("Upmixer Off");
     6075    }
     6076   
     6077    if (GetOSD() && !browsemode)
     6078        GetOSD()->SetSettingsText(text, 5);
     6079}
     6080   
     6081
    60596082// dir in 10ms jumps
    60606083void TV::ChangeAudioSync(int dir, bool allowEdit)
    60616084{
     
    73047327
    73057328        ChangeTimeStretch(0, !floatRead);   // just display
    73067329    }
     7330    else if (action == "TOGGLEUPMIX")
     7331        ToggleUpmix();
    73077332    else if (action.left(11) == "SELECTSCAN_")
    73087333        activenvp->SetScanType((FrameScanType) action.right(1).toInt());
    73097334    else if (action.left(15) == "TOGGLEAUDIOSYNC")
     
    75527577                                 (speedX100 == 150) ? 1 : 0, NULL,
    75537578                                 "STRETCHGROUP");
    75547579
     7580    if(nvp && nvp->getAudioOutput()->isAC3upmix)
     7581        item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX");
     7582
    75557583    // add scan mode override settings to menu
    75567584    FrameScanType scan_type = kScan_Ignore;
    75577585    bool scan_type_locked = false;
  • mythtv/libs/libmythtv/tv_play.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/tv_play.h c/mythtv/libs/libmythtv/tv_play.h
    a c  
    314314    void ChangeSpeed(int direction);
    315315    void ToggleTimeStretch(void);
    316316    void ChangeTimeStretch(int dir, bool allowEdit = true);
     317    void ToggleUpmix(void);
    317318    void ChangeAudioSync(int dir, bool allowEdit = true);
    318319    float StopFFRew(void);
    319320    void ChangeFFRew(int direction);
  • mythtv/programs/mythfrontend/globalsettings.cpp

    diff -Naur --exclude=.svn a/mythtv/programs/mythfrontend/globalsettings.cpp c/mythtv/programs/mythfrontend/globalsettings.cpp
    a c  
    116116    return gc;
    117117}
    118118
     119static HostCheckBox *AC3Upmix()
     120{
     121    HostCheckBox *gc = new HostCheckBox("MythAC3Upmix");
     122    gc->setLabel(QObject::tr("AC3 audio upmixer"));
     123    gc->setValue(false);
     124    gc->setHelpText(QObject::tr("Enable AC3 upmixer and digital software volume control."));
     125    return gc;
     126}
     127
     128static HostComboBox *SRCQuality()
     129{
     130    HostComboBox *gc = new HostComboBox("SRCQuality", false);
     131    gc->setLabel(QObject::tr("Sample Rate Conversion"));
     132    gc->addSelection(QObject::tr("Best"), "3", true); // default
     133    gc->addSelection(QObject::tr("Medium"), "2");
     134    gc->addSelection(QObject::tr("Fastest"), "1");
     135    gc->addSelection(QObject::tr("Disabled"), "0");
     136    gc->setHelpText(
     137            QObject::tr(
     138                "Set the quality of audio sample rate conversion. "
     139                "This only affects non 48000Hz PCM audio. "
     140                "All three options offer a worst-case SNR of 97dB. "
     141                "'Best' at a bandwidth of 97%. "
     142                "'Medium' at a bandwidth of 90%. "
     143                "'Fastest' at a bandwidth of 80%. "
     144                "Set 'Disabled' only if you know what you are doing."));
     145    return gc;
     146}
     147
    119148static HostComboBox *PassThroughOutputDevice()
    120149{
    121150    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    32843313    return gs;
    32853314}
    32863315
     3316class AC3UpmixSettings : public TriggeredConfigurationGroup
     3317{
     3318  public:
     3319     AC3UpmixSettings(Setting *checkbox, ConfigurationGroup *group) :
     3320         TriggeredConfigurationGroup(false, false, false, false)
     3321     {
     3322        setTrigger(checkbox);
     3323
     3324        addTarget("1", group);
     3325        addTarget("0", new VerticalConfigurationGroup(false,false));
     3326     }
     3327};
     3328
    32873329class AudioSettings : public TriggeredConfigurationGroup
    32883330{
    32893331  public:
     
    32963338         addChild(AudioOutputDevice());
    32973339         addChild(PassThroughOutputDevice());
    32983340
    3299          // General boolean settings
    3300          VerticalConfigurationGroup *vgrp0 =
     3341        // General boolean settings
     3342        VerticalConfigurationGroup *vgrp0 =
    33013343             new VerticalConfigurationGroup(false, false, true, true);
    3302          vgrp0->addChild(AC3PassThrough());
    3303          vgrp0->addChild(DTSPassThrough());
     3344        vgrp0->addChild(AC3PassThrough());
     3345        vgrp0->addChild(DTSPassThrough());
    33043346
    3305          HorizontalConfigurationGroup *agrp =
     3347        HorizontalConfigurationGroup *agrp =
    33063348             new HorizontalConfigurationGroup(false, false, true, true);
    3307          agrp->addChild(MaxAudioChannels());
    3308          agrp->addChild(AudioUpmixType());
    3309          addChild(agrp);
     3349        agrp->addChild(MaxAudioChannels());
     3350        agrp->addChild(AudioUpmixType());
     3351        addChild(agrp);
     3352
     3353        HorizontalConfigurationGroup *agrp1 =
     3354             new HorizontalConfigurationGroup(false, false, true, true);
     3355
     3356        VerticalConfigurationGroup *agrp1v1 =
     3357             new VerticalConfigurationGroup(false, false, true, true);
     3358
     3359        Setting* ac3upmix = AC3Upmix();
     3360            agrp1v1->addChild(ac3upmix);
     3361        agrp1->addChild(agrp1v1);
     3362
     3363        VerticalConfigurationGroup *agrp1v2 =
     3364            new VerticalConfigurationGroup(false, false, true, true);
     3365
     3366        agrp1v2->addChild(SRCQuality());
     3367
     3368        AC3UpmixSettings *sub1 =
     3369            new AC3UpmixSettings(ac3upmix, agrp1v2);
     3370        agrp1->addChild(sub1);
     3371        addChild(agrp1);
    33103372
    33113373         VerticalConfigurationGroup *vgrp1 =
    33123374             new VerticalConfigurationGroup(false, false, true, true);
  • mythtv/programs/mythtranscode/transcode.cpp

    diff -Naur --exclude=.svn a/mythtv/programs/mythtranscode/transcode.cpp c/mythtv/programs/mythtranscode/transcode.cpp
    a c  
    218218        // Do nothing
    219219        return MUTE_OFF;
    220220    }
     221    virtual bool ToggleUpmix(void)
     222    {
     223        // Do nothing
     224        return false;
     225    }
    221226
    222227    //  These are pure virtual in AudioOutput, but we don't need them here
    223228    virtual void bufferOutputData(bool){ return; }