Ticket #5900: audioencoding-fixes-jya15.patch

File audioencoding-fixes-jya15.patch, 80.7 KB (added by jyavenard@…, 15 years ago)

patch for 0.21-fixes (work with vdpau backport now)

  • 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;
     351    bool isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0);
    351352
    352353    if (gContext->GetSetting("MusicAudioDevice") == "default")
    353354        adevice = gContext->GetSetting("AudioOutputDevice");
    354355    else
    355356        adevice = gContext->GetSetting("MusicAudioDevice");
    356357
     358    if (!isAC3upmix)
     359        pdevice = "default";
     360    else
     361        pdevice = gContext->GetSetting("PassThruOutputDevice");
     362
    357363    // TODO: Error checking that device is opened correctly!
    358     m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,
    359                                     AUDIOOUTPUT_MUSIC, true, false);
     364    m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100,
     365                                    AUDIOOUTPUT_MUSIC, true, false, isAC3upmix);
    360366    m_output->setBufferSize(256 * 1024);
    361367    m_output->SetBlocking(false);
    362368
  • 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  
    88
    99#include "mythcontext.h"
    1010#include "audiooutputalsa.h"
     11#include "audiooutputdigitalencoder.h"
    1112   
    1213#define LOC QString("ALSA: ")
    1314#define LOC_WARN QString("ALSA, Warning: ")
     
    1718    QString laudio_main_device, QString           laudio_passthru_device,
    1819    int     laudio_bits,        int               laudio_channels,
    1920    int     laudio_samplerate,  AudioOutputSource lsource,
    20     bool    lset_initial_vol,   bool              laudio_passthru) :
     21    bool    lset_initial_vol,   bool              laudio_passthru,
     22    bool    AC3upmix) :
    2123    AudioOutputBase(laudio_main_device, laudio_passthru_device,
    2224                    laudio_bits,        laudio_channels,
    2325                    laudio_samplerate,  lsource,
    24                     lset_initial_vol,   laudio_passthru),
     26                    lset_initial_vol,   laudio_passthru,
     27                    AC3upmix),
    2528    pcm_handle(NULL),             numbadioctls(0),
    2629    killAudioLock(false),         mixer_handle(NULL),
    2730    mixer_control(QString::null), volume_range_multiplier(1.0f),
     
    3538AudioOutputALSA::~AudioOutputALSA()
    3639{
    3740    KillAudio();
     41    if (isAC3upmix)
     42        SetIECStatus(true);
     43}
     44
     45void AudioOutputALSA::SetIECStatus(bool audio) {
     46   
     47    snd_ctl_t *ctl;
     48    const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT);
     49    int spdif_index = -1;
     50    snd_ctl_elem_list_t *clist;
     51    snd_ctl_elem_id_t *cid;
     52    snd_ctl_elem_value_t *cval;
     53    snd_aes_iec958_t iec958;
     54    int cidx, controls;
     55
     56    VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1")
     57                      .arg(audio ? "audio" : "non-audio"));
     58   
     59    int err;
     60    if ((err = snd_ctl_open(&ctl, "default", 0)) < 0)
     61    {
     62        Error(QString("AudioOutputALSA::SetIECStatus: snd_ctl_open(default): %1")
     63              .arg(snd_strerror(err)));
     64        return;
     65    }
     66    snd_ctl_elem_list_alloca(&clist);
     67    snd_ctl_elem_list(ctl, clist);
     68    snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist));
     69    snd_ctl_elem_list(ctl, clist);
     70    controls = snd_ctl_elem_list_get_used(clist);
     71    for (cidx = 0; cidx < controls; cidx++)
     72    {
     73        if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str))
     74            if (spdif_index < 0 ||
     75                snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index)
     76                    break;
     77    }
     78
     79    if (cidx >= controls)
     80        return;
     81
     82    snd_ctl_elem_id_alloca(&cid);
     83    snd_ctl_elem_list_get_id(clist, cidx, cid);
     84    snd_ctl_elem_value_alloca(&cval);
     85    snd_ctl_elem_value_set_id(cval, cid);
     86    snd_ctl_elem_read(ctl,cval);
     87    snd_ctl_elem_value_get_iec958(cval, &iec958);
     88   
     89    if (!audio)
     90        iec958.status[0] |= IEC958_AES0_NONAUDIO;
     91    else
     92        iec958.status[0] &= ~IEC958_AES0_NONAUDIO;
     93
     94    snd_ctl_elem_value_set_iec958(cval, &iec958);
     95    snd_ctl_elem_write(ctl, cval);
     96
    3897}
    3998
    4099bool AudioOutputALSA::OpenDevice()
     
    42101    snd_pcm_format_t format;
    43102    unsigned int buffer_time, period_time;
    44103    int err;
     104    QString real_device;
    45105
    46106    if (pcm_handle != NULL)
    47107        CloseDevice();
     
    49109    pcm_handle = NULL;
    50110    numbadioctls = 0;
    51111
    52     QString real_device = (audio_passthru) ?
    53         audio_passthru_device : audio_main_device;
     112    if (!isAC3upmix) {
     113        real_device = (audio_passthru) ?
     114            audio_passthru_device : audio_main_device;
     115    }
     116    else
     117        if (audio_passthru || audio_enc)
     118        {
     119            real_device = audio_passthru_device;
     120            SetIECStatus(false);
     121        }
     122        else
     123        {
     124            real_device = audio_main_device;
     125            SetIECStatus(true);
     126        }
    54127
    55128    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    56129            .arg(real_device));
     
    148221}
    149222
    150223
     224void AudioOutputALSA::reorder_6ch_ac3(void *buf, unsigned int len) {
     225    unsigned short *src = (unsigned short *)buf;
     226    unsigned short tmp;
     227    unsigned int samples = len >> 1;
     228
     229    for (uint i = 0; i < samples; i += 6) {
     230        tmp = src[i+1];
     231        src[i+1] = src[i+2];
     232        src[i+2] = src[i+3];
     233        src[i+3] = src[i+4];
     234        src[i+4] = tmp;
     235    }
     236}
     237
    151238void AudioOutputALSA::WriteAudio(unsigned char *aubuf, int size)
    152239{
    153240    unsigned char *tmpbuf;
     
    159246        VERBOSE(VB_IMPORTANT, QString("WriteAudio() called with pcm_handle == NULL!"));
    160247        return;
    161248    }
    162    
     249
     250    // Re-Order channels mapping if analog output is used and source is AC3 multi-channels
     251    if (isAC3upmix && !(audio_passthru || audio_enc)
     252        && audio_codec && (audio_codec->codec_id == CODEC_ID_AC3)
     253        && (source_audio_channels > 2)) {
     254        VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     255                QString("WriteAudio: Re-ordering audio channels %1 bytes (%2 frames)")
     256                .arg(size).arg(frames));
     257        reorder_6ch_ac3(aubuf, size);
     258    }
    163259    tmpbuf = aubuf;
    164260
    165261    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        }
     262        if (laudio_codec)
     263            audio_codec = (AVCodecContext*)laudio_codec;
    220264    }
    221 
     265   
    222266    ClearError();
    223267    bool general_deps = (laudio_bits == audio_bits &&
    224268        laudio_channels == audio_channels &&
    225269        laudio_samplerate == audio_samplerate && !need_resampler &&
    226270        laudio_passthru == audio_passthru &&
    227271        lneeds_upmix == needs_upmix &&
    228         lcodec_id == codec_id && lcchannels == cchannels);
     272        (isAC3upmix ? (laudio_reenc == audio_reenc) : (lcodec_id == codec_id && lcchannels == cchannels))
     273        );
    229274    bool upmix_deps =
    230275        (lsource_audio_channels == source_audio_channels);
    231276    if (general_deps && upmix_deps)
     
    256301    audio_channels = laudio_channels;
    257302    source_audio_channels = lsource_audio_channels;
    258303    audio_bits = laudio_bits;
    259     audio_samplerate = laudio_samplerate;
    260     audio_codec = (AVCodecContext*)laudio_codec;
     304    if (!isAC3upmix) {
     305        audio_samplerate = laudio_samplerate;
     306        audio_codec = (AVCodecContext*)laudio_codec;
     307    } else {
     308        source_audio_samplerate = audio_samplerate = laudio_samplerate;
     309        audio_reenc = laudio_reenc;
     310    }
    261311    audio_passthru = laudio_passthru;
    262312    needs_upmix = lneeds_upmix;
    263313
     
    268318        Error("AudioOutput only supports 8 or 16bit audio.");
    269319        return;
    270320    }
    271     audio_bytes_per_sample = audio_channels * audio_bits / 8;
    272     source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    273321   
    274322    need_resampler = false;
    275323    killaudio = false;
     
    279327   
    280328    numlowbuffer = 0;
    281329
     330    if (!isAC3upmix) {
     331    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     332    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     333    } else {
     334    // Encode to AC-3 if not passing thru, there's more than 2 channels
     335    // and we're allowed to passthru AC-3
     336    // This won't reencode timestretched 2ch AC-3 but there's no point doing so
     337    if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru)
     338    {
     339        VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder");
     340        int srate = src_quality == 0 ? audio_samplerate : 48000;
     341        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     342        if (!encoder->Init(CODEC_ID_AC3, 448000, srate,
     343                           audio_channels, audio_reenc))
     344        {
     345            VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder");
     346            delete encoder;
     347            encoder = NULL;
     348        }
     349       
     350        audio_enc = true;
     351    }       
     352   
     353    if(audio_passthru || audio_enc)
     354        // AC-3 output - soundcard expects a 2ch 48k stream
     355        audio_channels = 2;
     356   
     357    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     358    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
     359
     360    // Always resample to 48k - many cards can't do anything else
     361    // and ALSA will do it with linear interpolation (yuk) if we don't anyway
     362    if (src_quality != 0 && audio_samplerate != 48000)
     363    {
     364        int error;
     365        audio_samplerate = 48000;
     366        VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")
     367            .arg(laudio_samplerate).arg(audio_samplerate));
     368        src_ctx = src_new(3-src_quality, audio_channels, &error);
     369        if (error)
     370        {
     371            Error(QString("Error creating resampler, the error was: %1")
     372                  .arg(src_strerror(error)) );
     373            pthread_mutex_unlock(&avsync_lock);
     374            pthread_mutex_unlock(&audio_buflock);
     375            src_ctx = NULL;
     376            return;
     377        }
     378        src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;
     379        src_data.data_in = src_in;
     380        src_data.data_out = src_out;
     381        src_data.output_frames = 16384*6;
     382        need_resampler = true;
     383    }
     384    }
    282385    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
    283386            .arg(audio_main_device).arg(audio_channels)
    284387            .arg(source_audio_channels).arg(audio_samplerate));
     
    314417    current_seconds = -1;
    315418    source_bitrate = -1;
    316419
     420    if (!isAC3upmix) {
    317421    // NOTE: this won't do anything as above samplerate vars are set equal
    318422    // Check if we need the resampler
    319423    if (audio_samplerate != laudio_samplerate)
     
    336440        src_data.output_frames = 16384*6;
    337441        need_resampler = true;
    338442    }
    339 
     443    }
    340444    if (needs_upmix)
    341445    {
    342446        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     
    348452        upmixer = new FreeSurround(
    349453            audio_samplerate,
    350454            source == AUDIOOUTPUT_VIDEO,
    351             (FreeSurround::SurroundMode)surround_mode);
     455            (FreeSurround::SurroundMode)surround_mode,isAC3upmix);
    352456
    353457        VERBOSE(VB_AUDIO, LOC +
    354458                QString("create upmixer done with surround mode %1")
     
    357461
    358462    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    359463            .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)
     464    if (!isAC3upmix) {
     465        VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     466                .arg((audio_codec) ?
     467                  codec_id_string(audio_codec->codec_id) : "not set"));
     468
     469        if (redo_stretch)
     470        {
     471            delete pSoundStretch;
     472            pSoundStretch = NULL;
     473            SetStretchFactorLocked(audio_stretchfactor);
     474        }
     475        else
    376476        {
    377             // if its passthru then we need to reencode
    378             if (audio_codec)
     477            SetStretchFactorLocked(audio_stretchfactor);
     478            if (pSoundStretch)
    379479            {
    380                 if (!encoder)
     480                // if its passthru then we need to reencode
     481                if (audio_codec)
    381482                {
    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                                 ))
     483                    if (!encoder)
    392484                    {
    393                         // eeks
    394                         delete encoder;
    395                         encoder = NULL;
    396                         VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     485                        VERBOSE(VB_AUDIO, LOC +
     486                                QString("Creating Encoder for codec %1")
     487                                .arg(audio_codec->codec_id));
     488
     489                        encoder = new AudioOutputDigitalEncoder(isAC3upmix);
     490                        if (!encoder->Init(audio_codec->codec_id,
     491                                    audio_codec->bit_rate,
     492                                    audio_codec->sample_rate,
     493                                    audio_codec->channels
     494                                    ))
     495                        {
     496                            // eeks
     497                            delete encoder;
     498                            encoder = NULL;
     499                            VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     500                        }
    397501                    }
    398502                }
    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);
     503                if (audio_codec && encoder)
     504                {
     505                    pSoundStretch->setSampleRate(audio_codec->sample_rate);
     506                    pSoundStretch->setChannels(audio_codec->channels);
     507                }
     508                else
     509                {
     510                    pSoundStretch->setSampleRate(audio_samplerate);
     511                    pSoundStretch->setChannels(audio_channels);
     512                }
    409513            }
    410514        }
     515    } else {
     516        SetStretchFactorLocked(old_audio_stretchfactor);
    411517    }
    412 
    413518    // Setup visualisations, zero the visualisations buffers
    414519    prepareVisuals();
    415520
     
    456561    killaudio = true;
    457562    StopOutputThread();
    458563
     564    if (isAC3upmix)
     565        pthread_mutex_lock(&audio_buflock);
     566
    459567    // Close resampler?
    460     if (src_ctx)
     568    if (src_ctx) {
    461569        src_delete(src_ctx);
     570        if (isAC3upmix)
     571            src_ctx = NULL;
     572    }
    462573    need_resampler = false;
    463574
    464575    // close sound stretcher
     
    466577    {
    467578        delete pSoundStretch;
    468579        pSoundStretch = NULL;
     580        if (isAC3upmix) {
     581            old_audio_stretchfactor = audio_stretchfactor;
     582            audio_stretchfactor = 1.0;
     583        }
    469584    }
    470585
    471586    if (encoder)
     
    480595        upmixer = NULL;
    481596    }
    482597    needs_upmix = false;
     598    if (isAC3upmix)
     599        audio_enc = false;
    483600
    484601    CloseDevice();
    485602
     603    if (isAC3upmix)
     604        pthread_mutex_unlock(&audio_buflock);
    486605    killAudioLock.unlock();
    487606}
    488607
     
    642761    // include algorithmic latencies
    643762    if (pSoundStretch)
    644763    {
    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);
     764        if (!isAC3upmix) {
     765            // add the effect of any unused but processed samples,
     766            // AC3 reencode does this
     767            totalbuffer += (int)(pSoundStretch->numSamples() *
     768                                 audio_bytes_per_sample);
     769        }
    649770        // add the effect of unprocessed samples in time stretch algo
    650771        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    651772                              audio_bytes_per_sample) / audio_stretchfactor);
     
    656777        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
    657778    }
    658779
     780    if (isAC3upmix && encoder)
     781        totalbuffer += encoder->Buffered();
     782
    659783    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    660784                                   (audio_bytes_per_sample * effdspstretched));
    661785 
     
    709833        return false; // would overflow
    710834    }
    711835
     836    if (isAC3upmix)
     837        pthread_mutex_lock(&audio_buflock);
     838
    712839    // resample input if necessary
    713840    if (need_resampler && src_ctx)
    714841    {
     
    742869        _AddSamples(buffers, false, samples, timecode);
    743870    }
    744871
     872    if (isAC3upmix)
     873        pthread_mutex_unlock(&audio_buflock);
     874
    745875    return true;
    746876}
    747877
     
    753883    int abps = (encoder) ?
    754884        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    755885    int len = samples * abps;
     886 
     887    if (isAC3upmix) {
     888        // Give original samples to mythmusic visualisation
     889        dispatchVisual((unsigned char *)buffer, len, timecode,
     890                       source_audio_channels, audio_bits);
     891    }
    756892
    757893    // Check we have enough space to write the data
    758894    if (need_resampler && src_ctx)
     
    777913        return false; // would overflow
    778914    }
    779915
     916    if (isAC3upmix)
     917        pthread_mutex_lock(&audio_buflock);
     918
    780919    // resample input if necessary
    781920    if (need_resampler && src_ctx)
    782921    {
     
    805944        _AddSamples(buffer, true, samples, timecode);
    806945    }
    807946
     947    if (isAC3upmix)
     948        pthread_mutex_unlock(&audio_buflock);
     949
    808950    return true;
    809951}
    810952
     
    837979            {
    838980                int error = src_reset(src_ctx);
    839981                if (error)
     982                {
    840983                    VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
    841984                            "Error occured while resetting resampler: %1")
    842985                            .arg(src_strerror(error)));
     986                    if (isAC3upmix)
     987                        src_ctx = NULL;
     988                }
    843989            }
    844990        }
    845991    }
     
    849995void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples,
    850996                                  long long timecode)
    851997{
    852     pthread_mutex_lock(&audio_buflock);
     998    if (!isAC3upmix)
     999        pthread_mutex_lock(&audio_buflock);
    8531000
    8541001    int len; // = samples * audio_bytes_per_sample;
    8551002    int audio_bytes = audio_bits / 8;
     
    8681015            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
    8691016            .arg(needs_upmix));
    8701017   
     1018    if (isAC3upmix)
     1019        len = WaitForFreeSpace(samples);
     1020   
    8711021    if (upmixer && needs_upmix)
    8721022    {
    8731023        int out_samples = 0;
    8741024        int step = (interleaved)?source_audio_channels:1;
    875         len = WaitForFreeSpace(samples);    // test
     1025       
     1026        if (!isAC3upmix) {
     1027            org_waud = waud;
     1028            len = WaitForFreeSpace(samples);
     1029        }
    8761030        for (int itemp = 0; itemp < samples; )
    8771031        {
    8781032            // just in case it does a processing cycle, release the lock
    8791033            // to allow the output loop to do output
    880             pthread_mutex_unlock(&audio_buflock);
     1034            if (!isAC3upmix)
     1035                pthread_mutex_unlock(&audio_buflock);
    8811036            if (audio_bytes == 2)
    8821037            {
    8831038                itemp += upmixer->putSamples(
     
    8941049                    source_audio_channels,
    8951050                    (interleaved) ? 0 : samples);
    8961051            }
    897             pthread_mutex_lock(&audio_buflock);
     1052            if (!isAC3upmix)
     1053                pthread_mutex_lock(&audio_buflock);
    8981054
    8991055            int copy_samples = upmixer->numSamples();
    9001056            if (copy_samples)
     
    9281084    }
    9291085    else
    9301086    {
    931         len = WaitForFreeSpace(samples);
    932 
     1087        if (!isAC3upmix)
     1088            len = WaitForFreeSpace(samples);
    9331089        if (interleaved)
    9341090        {
    9351091            char *mybuf = (char*)buffer;
     
    9651121        }
    9661122    }
    9671123
     1124    if (!isAC3upmix) {
    9681125    if (samples > 0)
    9691126    {
    9701127        if (pSoundStretch)
     
    10221179                        continue;
    10231180
    10241181                    //len = WaitForFreeSpace(amount);
    1025                     char *ob = encoder->GetOutBuff();
     1182                    const char *ob = encoder->GetOutBuff();
    10261183                    if (amount >= bdiff)
    10271184                    {
    10281185                        memcpy(audiobuffer + org_waud, ob, bdiff);
     
    10351192
    10361193                    bdiff = AUDBUFSIZE - amount;
    10371194                    org_waud += amount;
     1195                    if (org_waud >= AUDBUFSIZE)
     1196                    {
     1197                        VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2").arg(org_waud).arg(amount));
     1198                        org_waud -= AUDBUFSIZE;
     1199                    }
    10381200                }
    10391201            }
    10401202            else
     
    10641226                        org_waud += nSamples * audio_bytes_per_sample;
    10651227                        nSamplesToEnd -= nSamples;
    10661228                    }
     1229                    if (org_waud >= AUDBUFSIZE)
     1230                    {
     1231                        VERBOSE(VB_IMPORTANT, QString("org_waud >= kAudioRingBufferSize %1 %2 %3").arg(org_waud).arg(nSamples).arg(audio_bytes_per_sample));
     1232                        org_waud -= AUDBUFSIZE;
     1233                    }
    10671234
    10681235                    newLen += nSamples * audio_bytes_per_sample;
    10691236                    len -= nSamples * audio_bytes_per_sample;
     
    10961263    }
    10971264
    10981265    pthread_mutex_unlock(&audio_buflock);
     1266    } else {
     1267    if (samples <= 0)
     1268        return;
     1269   
     1270    if (pSoundStretch)
     1271    {
     1272        // does not change the timecode, only the number of samples
     1273        // back to orig pos
     1274        org_waud = waud;
     1275        int bdiff = AUDBUFSIZE - org_waud;
     1276        int nSamplesToEnd = bdiff/abps;
     1277        if (bdiff < len)
     1278        {
     1279            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1280                                      (audiobuffer +
     1281                                       org_waud), nSamplesToEnd);
     1282            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     1283                                      (len - bdiff) / abps);
     1284        }
     1285        else
     1286            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     1287                                      (audiobuffer + org_waud),
     1288                                      len / abps);
     1289
     1290        int nSamples = pSoundStretch->numSamples();
     1291        len = WaitForFreeSpace(nSamples);
     1292       
     1293        while ((nSamples = pSoundStretch->numSamples()))
     1294        {
     1295            if (nSamples > nSamplesToEnd)
     1296                nSamples = nSamplesToEnd;
     1297           
     1298            nSamples = pSoundStretch->receiveSamples(
     1299                (soundtouch::SAMPLETYPE*)
     1300                (audiobuffer + org_waud), nSamples
     1301            );
     1302           
     1303            if (nSamples == nSamplesToEnd) {
     1304                org_waud = 0;
     1305                nSamplesToEnd = AUDBUFSIZE/abps;
     1306            }
     1307            else {
     1308                org_waud += nSamples * abps;
     1309                nSamplesToEnd -= nSamples;
     1310            }
     1311           
     1312        }
     1313       
     1314    }
     1315
     1316    // Encode to AC-3?
     1317    if (encoder)
     1318    {
     1319       
     1320        org_waud = waud;
     1321        int bdiff = AUDBUFSIZE - org_waud;
     1322        int to_get = 0;
     1323
     1324        if (bdiff < len)
     1325        {
     1326            encoder->EncodeUpmix(audiobuffer + org_waud, bdiff);
     1327            to_get = encoder->EncodeUpmix(audiobuffer, len - bdiff);
     1328        }
     1329        else
     1330            to_get = encoder->EncodeUpmix(audiobuffer + org_waud, len);
     1331       
     1332        if (to_get > 0)
     1333        {
     1334           
     1335            if (to_get >= bdiff)
     1336            {
     1337                encoder->GetFrames(audiobuffer + org_waud, bdiff);
     1338                to_get -= bdiff;
     1339                org_waud = 0;
     1340            }
     1341            if (to_get > 0)
     1342                encoder->GetFrames(audiobuffer + org_waud, to_get);
     1343
     1344            org_waud += to_get;
     1345
     1346        }
     1347
     1348    }
     1349
     1350    waud = org_waud;
     1351    lastaudiolen = audiolen(false);
     1352
     1353    if (timecode < 0)
     1354        // mythmusic doesn't give timestamps..
     1355        timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1356   
     1357    samples_buffered += samples;
     1358   
     1359    /* we want the time at the end -- but the file format stores
     1360       time at the start of the chunk. */
     1361    // even with timestretch, timecode is still calculated from original
     1362    // sample count
     1363    audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
     1364    } // End AC3 upmiz
    10991365}
    11001366
    11011367void 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);
     
    49314941    }
    49324942}
    49334943
     4944bool NuppelVideoPlayer::ToggleUpmix()
     4945{
     4946    if (audioOutput)
     4947        return audioOutput->ToggleUpmix();
     4948    return false;
     4949}
     4950
    49344951void NuppelVideoPlayer::Zoom(ZoomDirection direction)
    49354952{
    49364953    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  
    411411      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    412412      allow_ac3_passthru(false),    allow_dts_passthru(false),
    413413      disable_passthru(false),      max_channels(2),
    414       dummy_frame(NULL),
     414      last_ac3_channels(0),         dummy_frame(NULL),
    415415      // DVD
    416416      lastdvdtitle(-1),
    417417      decodeStillFrame(false),
     
    429429    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    430430    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    431431    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
     432    isAC3upmix = gContext->GetNumSetting("MythAC3Upmix", 0);
    432433
    433434    audioIn.sample_size = -32; // force SetupAudioStream to run once
    434435    itv = GetNVP()->GetInteractiveTV();
     
    28292830    {
    28302831        int idx = atracks[i].av_stream_index;
    28312832        AVCodecContext *codec_ctx = ic->streams[idx]->codec;
    2832         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2833                                 !disable_passthru &&
    2834                                 (codec_ctx->codec_id == CODEC_ID_AC3));
    2835         bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2836                                 !disable_passthru &&
    2837                                 (codec_ctx->codec_id == CODEC_ID_DTS));
    28382833        AudioInfo item(codec_ctx->codec_id,
    28392834                       codec_ctx->sample_rate, codec_ctx->channels,
    2840                        do_ac3_passthru || do_dts_passthru);
     2835                       DoPassThrough(codec_ctx));
    28412836        VERBOSE(VB_AUDIO, LOC + " * " + item.toString());
    28422837    }
    28432838#endif
     
    29712966bool AvFormatDecoder::GetFrame(int onlyvideo)
    29722967{
    29732968    AVPacket *pkt = NULL;
     2969    AC3HeaderInfo hdr;
    29742970    int len;
    29752971    unsigned char *ptr;
    29762972    int data_size = 0;
     
    33933389                        reselectAudioTrack = true;
    33943390                    }                           
    33953391
    3396                     bool do_ac3_passthru =
    3397                         (allow_ac3_passthru && !transcoding &&
    3398                          (curstream->codec->codec_id == CODEC_ID_AC3));
    3399                     bool do_dts_passthru =
    3400                         (allow_dts_passthru && !transcoding &&
    3401                          (curstream->codec->codec_id == CODEC_ID_DTS));
    3402                     bool using_passthru = do_ac3_passthru || do_dts_passthru;
    3403 
    34043392                    // detect channels on streams that need
    34053393                    // to be decoded before we can know this
    34063394                    bool already_decoded = false;
     
    34113399                                QString("Setting channels to %1")
    34123400                                .arg(audioOut.channels));
    34133401
    3414                         if (using_passthru)
     3402                        if (DoPassThrough(curstream->codec))
    34153403                        {
    34163404                            // for passthru let it select the max number
    34173405                            // of channels
     
    34323420                        reselectAudioTrack |= curstream->codec->channels;
    34333421                    }
    34343422
     3423                    if (isAC3upmix && curstream->codec->codec_id == CODEC_ID_AC3 &&
     3424                        !ff_ac3_parse_header(ptr, &hdr))
     3425                    {
     3426                        if (hdr.channels != last_ac3_channels)
     3427                        {
     3428                            last_ac3_channels = curstream->codec->channels = hdr.channels;
     3429                            SetupAudioStream();
     3430                        }
     3431                    }
     3432
    34353433                    if (reselectAudioTrack)
    34363434                    {
    34373435                        QMutexLocker locker(&avcodeclock);
     
    39593957    }
    39603958}
    39613959
     3960bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx)
     3961{
     3962    bool do_ac3_passthru =
     3963        (allow_ac3_passthru && !transcoding &&
     3964        (ctx->codec_id == CODEC_ID_AC3));
     3965    bool do_dts_passthru =
     3966        (allow_dts_passthru && !transcoding &&
     3967        (ctx->codec_id == CODEC_ID_DTS));
     3968    bool using_passthru = do_ac3_passthru || do_dts_passthru;
     3969
     3970    if (!isAC3upmix)
     3971        return using_passthru;
     3972
     3973    bool passthru = false;
     3974
     3975    if (ctx->codec_id == CODEC_ID_AC3)
     3976        passthru = allow_ac3_passthru &&
     3977                   ctx->channels >= (int)max_channels;
     3978    else if (ctx->codec_id == CODEC_ID_DTS)
     3979        passthru = allow_dts_passthru;
     3980   
     3981    passthru &= !transcoding && !disable_passthru;
     3982    // Don't know any cards that support spdif clocked at < 44100
     3983    // Some US cable transmissions have 2ch 32k AC-3 streams
     3984    passthru &= ctx->sample_rate >= 44100;
     3985
     3986    return passthru;
     3987}
     3988
    39623989/** \fn AvFormatDecoder::SetupAudioStream(void)
    39633990 *  \brief Reinitializes audio if it needs to be reinitialized.
    39643991 *
     
    39844011        assert(curstream);
    39854012        assert(curstream->codec);
    39864013        codec_ctx = curstream->codec;       
    3987         bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3988                                 (codec_ctx->codec_id == CODEC_ID_AC3));
    3989         bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3990                                 (codec_ctx->codec_id == CODEC_ID_DTS));
    3991         using_passthru = do_ac3_passthru || do_dts_passthru;
    3992         info = AudioInfo(codec_ctx->codec_id,
    3993                          codec_ctx->sample_rate, codec_ctx->channels,
    3994                          using_passthru && !disable_passthru);
     4014        using_passthru = DoPassThrough(codec_ctx);
     4015        if (!isAC3upmix)
     4016            info = AudioInfo(codec_ctx->codec_id,
     4017                             codec_ctx->sample_rate, codec_ctx->channels,
     4018                             using_passthru && !disable_passthru);
     4019        else
     4020            info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate,
     4021                             codec_ctx->channels, using_passthru);
    39954022    }
    39964023
    39974024    if (info == audioIn)
     
    40024029            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    40034030
    40044031    audioOut = audioIn = info;
     4032    if (!isAC3upmix) {
    40054033    if (using_passthru)
    40064034    {
    40074035        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
     
    40584086
    40594087    // allow the audio stuff to reencode
    40604088    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     4089    } else {
     4090
     4091    if (!using_passthru && audioOut.channels > (int)max_channels)
     4092    {
     4093        audioOut.channels = (int)max_channels;
     4094        audioOut.sample_size = audioOut.channels * 2;
     4095        codec_ctx->channels = audioOut.channels;
     4096    }
     4097   
     4098    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
     4099            QString("\n\t\t\tfrom %1 to %2")
     4100            .arg(old_in.toString()).arg(audioOut.toString()));
     4101
     4102    if (audioOut.sample_rate > 0)
     4103        GetNVP()->SetEffDsp(audioOut.sample_rate * 100);
     4104
     4105    GetNVP()->SetAudioCodec(codec_ctx);
     4106    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     4107                             audioOut.sample_rate,
     4108                             audioOut.do_passthru);
     4109   
     4110    }
    40614111    QString errMsg = GetNVP()->ReinitAudio();
    40624112    bool audiook = errMsg.isEmpty();
    40634113
  • mythtv/libs/libmythtv/avformatdecoder.h

    diff -Naur --exclude=.svn a/mythtv/libs/libmythtv/avformatdecoder.h c/mythtv/libs/libmythtv/avformatdecoder.h
    a c  
    183183    void InitVideoCodec(AVStream *stream, AVCodecContext *enc,
    184184                        bool selectedStream = false);
    185185
    186     /// Preprocess a packet, setting the video parms if nessesary.
     186    /// Preprocess a packet, setting the video parms if necessary.
    187187    void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt);
    188188    void H264PreProcessPkt(AVStream *stream, AVPacket *pkt);
    189189
     
    196196
    197197    void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames);
    198198
     199    bool DoPassThrough(const AVCodecContext *ctx);
    199200    bool SetupAudioStream(void);
    200201    void SetupAudioStreamSubIndexes(int streamIndex);
    201202    void RemoveAudioStreams();
     
    264265    bool              allow_dts_passthru;
    265266    bool              disable_passthru;
    266267    uint              max_channels;
     268    uint              last_ac3_channels;
     269    bool              isAC3upmix;
    267270
    268271    VideoFrame       *dummy_frame;
    269272
  • 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
     
    27102711            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
    27112712                     action == "STRETCHINC" || action == "STRETCHDEC" ||
    27122713                     action == "MUTE"       || action == "TOGGLEASPECT" ||
    2713                      action == "TOGGLEFILL" )
     2714                     action == "TOGGLEFILL" || action == "TOGGLEUPMIX")
    27142715            {
    27152716                passThru = 1;
    27162717                handled = false;
     
    27652766            else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" ||
    27662767                     action == "STRETCHINC" || action == "STRETCHDEC" ||
    27672768                     action == "MUTE" || action == "PAUSE" ||
    2768                      action == "CLEAROSD")
     2769                     action == "CLEAROSD" || action == "TOGGLEUPMIX")
    27692770            {
    27702771                passThru = 1;
    27712772                handled = false;
     
    30703071            ChangeTimeStretch(0);   // just display
    30713072        else if (action == "TOGGLESTRETCH")
    30723073            ToggleTimeStretch();
     3074        else if (action == "TOGGLEUPMIX")
     3075            ToggleUpmix();
    30733076        else if (action == "CYCLECOMMSKIPMODE") {
    30743077            SetAutoCommercialSkip((enum commSkipMode)
    30753078                                  ((autoCommercialSkip + 1) % CommSkipModes));
     
    60546057    }
    60556058}
    60566059
     6060void TV::ToggleUpmix()
     6061{
     6062    AudioOutput *aud = nvp->getAudioOutput();
     6063    if (!aud)
     6064        return;
     6065    QString text;
     6066    if(!aud->isAC3upmix) {
     6067        text = tr("Upmixer disabled !");
     6068    } else {
     6069        if (aud->ToggleUpmix())
     6070            text = tr("Upmixer On");
     6071        else
     6072            text = tr("Upmixer Off");
     6073    }
     6074   
     6075    if (GetOSD() && !browsemode)
     6076        GetOSD()->SetSettingsText(text, 5);
     6077}
     6078   
     6079
    60576080// dir in 10ms jumps
    60586081void TV::ChangeAudioSync(int dir, bool allowEdit)
    60596082{
     
    73027325
    73037326        ChangeTimeStretch(0, !floatRead);   // just display
    73047327    }
     7328    else if (action == "TOGGLEUPMIX")
     7329        ToggleUpmix();
    73057330    else if (action.left(11) == "SELECTSCAN_")
    73067331        activenvp->SetScanType((FrameScanType) action.right(1).toInt());
    73077332    else if (action.left(15) == "TOGGLEAUDIOSYNC")
     
    75507575                                 (speedX100 == 150) ? 1 : 0, NULL,
    75517576                                 "STRETCHGROUP");
    75527577
     7578    if(nvp && nvp->getAudioOutput()->isAC3upmix)
     7579        item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX");
     7580
    75537581    // add scan mode override settings to menu
    75547582    FrameScanType scan_type = kScan_Ignore;
    75557583    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; }