Ticket #1104: mythtv_ac3.46.patch

File mythtv_ac3.46.patch, 60.0 KB (added by Mark Spieth, 16 years ago)
  • libs/libs.pro

     
    66# Directories
    77SUBDIRS += libavutil libavcodec libavformat libmythsamplerate
    88SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav
     9SUBDIRS += libmythfreesurround
    910
    1011mingw : SUBDIRS += libmyth libmythupnp libmythui
    1112!mingw: SUBDIRS += libmythupnp libmythui libmyth
  • libs/libmyth/libmyth.pro

     
    2525HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2626HEADERS += mythhdd.h mythcdrom.h
    2727HEADERS += compat.h
     28HEADERS += audiooutputdigitalencoder.h
    2829
    2930SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
    3031SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
     
    4041SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp
    4142SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4243SOURCES += mythhdd.cpp mythcdrom.cpp
     44SOURCES += audiooutputdigitalencoder.cpp
    4345
    4446INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libavutil
     48INCLUDEPATH += ../libmythfreesurround
    4549DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    4650DEPENDPATH += ../libmythupnp
     51DEPENDPATH += ../libavutil ../libavcodec
     52DEPENDPATH += ../libmythfreesurround
    4753
    4854LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4955LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     56LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
     57LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
     58LIBS += -lfftw3f
    5059LIBS += -L../libmythui         -lmythui-$${LIBVERSION}
    5160LIBS += -L../libmythupnp       -lmythupnp-$${LIBVERSION}
    5261
    5362TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5463TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     64TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT}
    5565
    5666# Install headers so that plugins can compile independently
    5767inc.path = $${PREFIX}/include/mythtv/
  • libs/libmyth/audiooutput.h

     
    3131    virtual ~AudioOutput() { };
    3232
    3333    // reconfigure sound out for new params
    34     virtual void Reconfigure(int audio_bits, int audio_channels,
    35                              int audio_samplerate, bool audio_passthru) = 0;
     34    virtual void Reconfigure(int audio_bits,
     35                             int audio_channels,
     36                             int audio_samplerate,
     37                             bool audio_passthru,
     38                             void* audio_codec = NULL
     39                             ) = 0;
    3640   
    3741    virtual void SetStretchFactor(float factor);
     42    virtual float GetStretchFactor();
    3843
    3944    // do AddSamples calls block?
    4045    virtual void SetBlocking(bool blocking) = 0;
     
    7681        lastError = msg;
    7782        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7883    }
     84    void ClearError()
     85     { lastError = QString::null; };
    7986
    8087    void Warn(QString msg)
    8188    {
  • libs/libmyth/audiooutput.cpp

     
    133133{
    134134}
    135135
     136float AudioOutput::GetStretchFactor()
     137{
     138    return 1.0;
     139}
    136140
     141
     142
  • libs/libmyth/audiooutputdx.h

     
    3535    /// END HACK HACK HACK HACK
    3636       
    3737    virtual void Reset(void);
    38     virtual void Reconfigure(int audio_bits,       int audio_channels,
    39                              int audio_samplerate, int audio_passthru);
     38    virtual void Reconfigure(int audio_bits,
     39                         int audio_channels,
     40                         int audio_samplerate,
     41                         bool audio_passthru,
     42                         AudioCodecMode aom = AUDIOCODECMODE_NORMAL);
    4043    virtual void SetBlocking(bool blocking);
    4144
    4245    virtual bool AddSamples(char *buffer, int samples, long long timecode);
  • libs/libmyth/audiooutputdx.cpp

     
    130130    // FIXME: kedl: not sure what else could be required here?
    131131}
    132132
    133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels,
    134                                 int audio_samplerate, int audio_passthru)
     133void AudioOutputDX::Reconfigure(int audio_bits,
     134                                int audio_channels,
     135                                int audio_samplerate,
     136                                int audio_passthru,
     137                                AudioCodecMode laom
     138                                )
    135139{
    136140    if (dsbuffer)
    137141        DestroyDSBuffer();
  • libs/libmyth/audiooutputbase.h

     
    1616// MythTV headers
    1717#include "audiooutput.h"
    1818#include "samplerate.h"
    19 #include "SoundTouch.h"
    2019
    21 #define AUDBUFSIZE 768000
     20namespace soundtouch {
     21class SoundTouch;
     22};
     23class FreeSurround;
     24class AudioOutputDigitalEncoder;
     25struct AVCodecContext;
     26
    2227#define AUDIO_SRC_IN_SIZE   16384
    2328#define AUDIO_SRC_OUT_SIZE (16384*6)
    2429#define AUDIO_TMP_BUF_SIZE (16384*6)
    2530
     31//#define AUDBUFSIZE 768000
     32//divisible by 12,10,8,6,4,2 and around 1024000
     33//#define AUDBUFSIZE 1024080
     34#define AUDBUFSIZE 1536000
     35
    2636class AudioOutputBase : public AudioOutput
    2737{
    2838 public:
     
    3545    virtual ~AudioOutputBase();
    3646
    3747    // reconfigure sound out for new params
    38     virtual void Reconfigure(int audio_bits, int audio_channels,
    39                              int audio_samplerate, bool audio_passthru);
     48    virtual void Reconfigure(int audio_bits,
     49                             int audio_channels,
     50                             int audio_samplerate,
     51                             bool audio_passthru,
     52                             void* audio_codec = NULL);
    4053   
    4154    // do AddSamples calls block?
    4255    virtual void SetBlocking(bool blocking);
     
    4558    virtual void SetEffDsp(int dsprate);
    4659
    4760    virtual void SetStretchFactor(float factor);
     61    virtual float GetStretchFactor();
    4862
    4963    virtual void Reset(void);
    5064
     
    127141    bool audio_passthru;
    128142
    129143    float audio_stretchfactor;
     144    AVCodecContext *audio_codec;
    130145    AudioOutputSource source;
    131146
    132147    bool killaudio;
     
    135150    bool set_initial_vol;
    136151    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    137152   
     153    int configured_audio_channels;
     154
    138155 private:
    139156    // resampler
    140157    bool need_resampler;
     
    146163
    147164    // timestretch
    148165    soundtouch::SoundTouch * pSoundStretch;
     166    AudioOutputDigitalEncoder * encoder;
     167    FreeSurround * upmixer;
    149168
     169    int source_audio_channels;
     170    int source_audio_bytes_per_sample;
     171    bool needs_upmix;
     172    int surround_mode;
     173
    150174    bool blocking; // do AddSamples calls block?
    151175
    152176    int lastaudiolen;
     
    164188
    165189    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    166190                                    'audiotime' and 'audiotime_updated' */
    167     int audiotime; // timecode of audio leaving the soundcard (same units as
     191    long long audiotime; // timecode of audio leaving the soundcard (same units as
    168192                   //                                          timecodes) ...
    169193    struct timeval audiotime_updated; // ... which was last updated at this time
    170194
    171195    /* Audio circular buffer */
    172196    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    173197    int raud, waud;     /* read and write positions */
    174     int audbuf_timecode;    /* timecode of audio most recently placed into
     198    long long audbuf_timecode;    /* timecode of audio most recently placed into
    175199                   buffer */
    176200
    177201    int numlowbuffer;
  • libs/libmyth/audiooutputbase.cpp

     
    1515
    1616// MythTV headers
    1717#include "audiooutputbase.h"
     18#include "audiooutputdigitalencoder.h"
     19#include "SoundTouch.h"
     20#include "freesurround.h"
    1821#include "compat.h"
    1922
    2023#define LOC QString("AO: ")
     
    3639    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    3740    audio_passthru(false),      audio_stretchfactor(1.0f),
    3841
     42    audio_codec(NULL),
    3943    source(lsource),            killaudio(false),
    4044
    4145    pauseaudio(false),          audio_actually_paused(false),
     
    4751
    4852    src_ctx(NULL),
    4953
    50     pSoundStretch(NULL),        blocking(false),
     54    pSoundStretch(NULL),       
     55    encoder(NULL),
     56    upmixer(NULL),
     57    source_audio_channels(-1),
     58    source_audio_bytes_per_sample(0),
     59    needs_upmix(false),
     60    surround_mode(FreeSurround::SurroundModePassive),
    5161
     62    blocking(false),
     63
    5264    lastaudiolen(0),            samples_buffered(0),
    5365
    5466    audio_thread_exists(false),
     
    7183    memset(tmp_buff,           0, sizeof(short) * AUDIO_TMP_BUF_SIZE);
    7284    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    7385    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
     86    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    7487
    7588    // You need to call Reconfigure from your concrete class.
    7689    // Reconfigure(laudio_bits,       laudio_channels,
     
    111124            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    112125                                        .arg(audio_stretchfactor));
    113126            pSoundStretch = new soundtouch::SoundTouch();
    114             pSoundStretch->setSampleRate(audio_samplerate);
    115             pSoundStretch->setChannels(audio_channels);
     127            if (audio_codec)
     128            {
     129                if (!encoder)
     130                {
     131                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     132                    encoder = new AudioOutputDigitalEncoder();
     133                    if (!encoder->Init(audio_codec->codec_id,
     134                                audio_codec->bit_rate,
     135                                audio_codec->sample_rate,
     136                                audio_codec->channels
     137                                ))
     138                    {
     139                        // eeks
     140                        delete encoder;
     141                        encoder = NULL;
     142                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     143                    }
     144                }
     145            }
     146            if (encoder)
     147            {
     148                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     149                pSoundStretch->setChannels(audio_codec->channels);
     150            }
     151            else
     152            {
     153                pSoundStretch->setSampleRate(audio_samplerate);
     154                pSoundStretch->setChannels(audio_channels);
     155            }
    116156
    117157            pSoundStretch->setTempo(audio_stretchfactor);
    118158            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    134174    pthread_mutex_unlock(&audio_buflock);
    135175}
    136176
     177float AudioOutputBase::GetStretchFactor()
     178{
     179    return audio_stretchfactor;
     180}
     181
    137182void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     183                                 int laudio_samplerate, bool laudio_passthru,
     184                                 void* laudio_codec)
    139185{
    140     if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     186    int codec_id = CODEC_ID_NONE;
     187    int lcodec_id = CODEC_ID_NONE;
     188    int lcchannels = 0;
     189    int cchannels = 0;
     190    int lsource_audio_channels = laudio_channels;
     191    bool lneeds_upmix = false;
     192
     193    if (laudio_codec)
     194    {
     195        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     196        laudio_bits = 16;
     197        laudio_channels = 2;
     198        lsource_audio_channels = laudio_channels;
     199        laudio_samplerate = 48000;
     200        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     201    }
     202    if (audio_codec)
     203    {
     204        codec_id = audio_codec->codec_id;
     205        cchannels = ((AVCodecContext*)audio_codec)->channels;
     206    }
     207    if ((configured_audio_channels == 6) &&
     208        !(laudio_codec || audio_codec))
     209    {
     210        laudio_channels = configured_audio_channels;
     211        lneeds_upmix = true;
     212        VERBOSE(VB_AUDIO,LOC + "Needs upmix");
     213    }
     214    ClearError();
     215    if (laudio_bits == audio_bits &&
     216        lsource_audio_channels == source_audio_channels &&
     217        laudio_channels == audio_channels &&
     218        laudio_samplerate == audio_samplerate && !need_resampler &&
     219        laudio_passthru == audio_passthru &&
     220        lneeds_upmix == needs_upmix &&
     221        lcodec_id == codec_id && lcchannels == cchannels)
     222    {
     223        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143224        return;
    144 
     225    }
    145226    KillAudio();
    146227   
    147228    pthread_mutex_lock(&audio_buflock);
     
    151232    waud = raud = 0;
    152233    audio_actually_paused = false;
    153234   
     235    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154236    audio_channels = laudio_channels;
     237    source_audio_channels = lsource_audio_channels;
    155238    audio_bits = laudio_bits;
    156239    audio_samplerate = laudio_samplerate;
     240    audio_codec = (AVCodecContext*)laudio_codec;
    157241    audio_passthru = laudio_passthru;
     242    needs_upmix = lneeds_upmix;
    158243    if (audio_bits != 8 && audio_bits != 16)
    159244    {
    160245        pthread_mutex_unlock(&avsync_lock);
     
    163248        return;
    164249    }
    165250    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     251    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166252   
    167253    need_resampler = false;
    168254    killaudio = false;
     
    172258   
    173259    numlowbuffer = 0;
    174260
     261    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     262            .arg(audio_main_device).arg(audio_channels)
     263            .arg(source_audio_channels).arg(audio_samplerate));
     264 
    175265    // Actually do the device specific open call
    176266    if (!OpenDevice())
    177267    {
    178268        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179269        pthread_mutex_unlock(&avsync_lock);
    180270        pthread_mutex_unlock(&audio_buflock);
     271        if (GetError().isEmpty())
     272            Error("Aborting reconfigure");
     273        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181274        return;
    182275    }
    183276
     
    200293    current_seconds = -1;
    201294    source_bitrate = -1;
    202295
     296    // NOTE: this wont do anything as above samplerate vars are set equal
    203297    // Check if we need the resampler
    204298    if (audio_samplerate != laudio_samplerate)
    205299    {
     
    222316        need_resampler = true;
    223317    }
    224318
     319    if (needs_upmix)
     320    {
     321        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     322        if (configured_audio_channels == 6)
     323        {
     324            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
     325        }
     326        upmixer = new FreeSurround(audio_samplerate,
     327                                    source == AUDIOOUTPUT_VIDEO,
     328                                    (FreeSurround::SurroundMode)surround_mode);
     329        VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode));
     330    }
     331
    225332    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226333            .arg(audio_stretchfactor));
     334    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     335            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    227336
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     337    if (redo_stretch)
    230338    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     339        float laudio_stretchfactor = audio_stretchfactor;
     340        delete pSoundStretch;
     341        pSoundStretch = NULL;
     342        audio_stretchfactor = 0.0;
     343        SetStretchFactorLocked(laudio_stretchfactor);
    233344    }
     345    else
     346    {
     347        SetStretchFactorLocked(audio_stretchfactor);
     348        if (pSoundStretch)
     349        {
     350            // if its passthru then we need to reencode
     351            if (audio_codec)
     352            {
     353                if (!encoder)
     354                {
     355                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     356                    encoder = new AudioOutputDigitalEncoder();
     357                    if (!encoder->Init(audio_codec->codec_id,
     358                                audio_codec->bit_rate,
     359                                audio_codec->sample_rate,
     360                                audio_codec->channels
     361                                ))
     362                    {
     363                        // eeks
     364                        delete encoder;
     365                        encoder = NULL;
     366                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     367                    }
     368                }
     369            }
     370            if (encoder)
     371            {
     372                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     373                pSoundStretch->setChannels(audio_codec->channels);
     374            }
     375            else
     376            {
     377                pSoundStretch->setSampleRate(audio_samplerate);
     378                pSoundStretch->setChannels(audio_channels);
     379            }
     380        }
     381    }
    234382
    235383    // Setup visualisations, zero the visualisations buffers
    236384    prepareVisuals();
     
    290438        pSoundStretch = NULL;
    291439    }
    292440
     441    if (encoder)
     442    {
     443        delete encoder;
     444        encoder = NULL;
     445    }
     446
     447    if (upmixer)
     448    {
     449        delete upmixer;
     450        upmixer = NULL;
     451    }
     452    needs_upmix = false;
     453
    293454    CloseDevice();
    294455
    295456    killAudioLock.unlock();
     
    303464
    304465void AudioOutputBase::Pause(bool paused)
    305466{
     467    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    306468    pauseaudio = paused;
    307469    audio_actually_paused = false;
    308470}
     
    385547       The reason is that computing 'audiotime' requires acquiring the audio
    386548       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387549       from the audio thread, and then call this from the video thread. */
    388     int ret;
     550    long long ret;
    389551    struct timeval now;
    390552
    391553    if (audiotime == 0)
     
    397559
    398560    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399561    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     562    ret = (long long)(ret * audio_stretchfactor);
    401563
     564#if 1
     565    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     566            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     567            .arg(now.tv_sec).arg(now.tv_usec)
     568            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     569            .arg(ret)
     570            .arg(audiotime)
     571            .arg(audio_stretchfactor)
     572           );
     573#endif
     574
    402575    ret += audiotime;
    403576
    404577    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     578    return (int)ret;
    406579}
    407580
    408581void AudioOutputBase::SetAudiotime(void)
     
    439612    // include algorithmic latencies
    440613    if (pSoundStretch)
    441614    {
     615        // add the effect of any unused but processed samples, AC3 reencode does this
     616        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    442617        // add the effect of unprocessed samples in time stretch algo
    443618        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444619                              audio_bytes_per_sample) / audio_stretchfactor);
    445620    }
    446                
     621
     622    if (upmixer && needs_upmix)
     623    {
     624        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     625    }
     626
    447627    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448628                                   (audio_bytes_per_sample * effdspstretched));
    449629 
    450630    gettimeofday(&audiotime_updated, NULL);
     631#if 1
     632    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     633            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     634            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     635            .arg(audiotime)
     636            .arg(audbuf_timecode)
     637            .arg(totalbuffer)
     638            .arg(soundcard_buffer)
     639            .arg(effdspstretched)
     640            .arg(audio_bytes_per_sample)
     641            .arg(audio_stretchfactor)
     642           );
     643#endif
    451644
    452645    pthread_mutex_unlock(&avsync_lock);
    453646    pthread_mutex_unlock(&audio_buflock);
     
    458651{
    459652    // NOTE: This function is not threadsafe
    460653    int afree = audiofree(true);
    461     int abps = audio_bytes_per_sample;
     654    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    462655    int len = samples * abps;
    463656
    464657    // Check we have enough space to write the data
    465658    if (need_resampler && src_ctx)
    466659        len = (int)ceilf(float(len) * src_data.src_ratio);
    467660
     661    // include samples in upmix buffer that may be flushed
     662    if (needs_upmix && upmixer)
     663        len += upmixer->numUnprocessedSamples()*abps;
     664
    468665    if (pSoundStretch)
    469666        len += (pSoundStretch->numUnprocessedSamples() +
    470667                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     
    520717    // NOTE: This function is not threadsafe
    521718
    522719    int afree = audiofree(true);
    523     int abps = audio_bytes_per_sample;
     720    int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    524721    int len = samples * abps;
    525722
    526723    // Check we have enough space to write the data
    527724    if (need_resampler && src_ctx)
    528725        len = (int)ceilf(float(len) * src_data.src_ratio);
    529726
     727    // include samples in upmix buffer that may be flushed
     728    if (needs_upmix && upmixer)
     729        len += upmixer->numUnprocessedSamples()*abps;
     730 
    530731    if (pSoundStretch)
    531732    {
    532733        len += (pSoundStretch->numUnprocessedSamples() +
     
    575776
    576777int AudioOutputBase::WaitForFreeSpace(int samples)
    577778{
    578     int len = samples * audio_bytes_per_sample;
     779    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     780    int len = samples * abps;
    579781    int afree = audiofree(false);
    580782
    581783    while (len > afree)
    582784    {
    583785        if (blocking)
    584786        {
    585             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     787            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    586788                    QString("(need %1, available %2)").arg(len).arg(afree));
    587789
    588790            // wait for more space
     
    591793        }
    592794        else
    593795        {
    594             VERBOSE(VB_IMPORTANT, LOC_ERR +
    595                     "Audio buffer overflow, audio data lost!");
    596             samples = afree / audio_bytes_per_sample;
    597             len = samples * audio_bytes_per_sample;
     796            VERBOSE(VB_IMPORTANT, LOC_ERR +
     797                    QString("Audio buffer overflow, %1 audio samples lost!")
     798                        .arg(samples - (afree / abps)));
     799            samples = afree / abps;
     800            len = samples * abps;
    598801            if (src_ctx)
    599802            {
    600803                int error = src_reset(src_ctx);
     
    619822   
    620823    int afree = audiofree(false);
    621824
    622     VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    623             LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    624             .arg(samples * audio_bytes_per_sample)
    625             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     825    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     826    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     827            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6")
     828            .arg(samples)
     829            .arg(samples * abps)
     830            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     831            .arg(needs_upmix)
     832            );
    626833   
    627     len = WaitForFreeSpace(samples);
    628 
    629     if (interleaved)
     834    if (upmixer && needs_upmix)
    630835    {
    631         char *mybuf = (char*)buffer;
    632         int bdiff = AUDBUFSIZE - org_waud;
    633         if (bdiff < len)
     836        int out_samples = 0;
     837        int step = (interleaved)?source_audio_channels:1;
     838        len = WaitForFreeSpace(samples);    // test
     839        for(int itemp=0; itemp<samples; )
    634840        {
    635             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    636             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     841            // just in case it does a processing cycle, release the lock
     842            // to allow the output loop to do output
     843            pthread_mutex_unlock(&audio_buflock);
     844            if (audio_bytes == 2)
     845                itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     846            else
     847                itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples);
     848            pthread_mutex_lock(&audio_buflock);
     849
     850            int copy_samples = upmixer->numSamples();
     851            if (copy_samples)
     852            {
     853                int copy_len = copy_samples * abps;
     854                out_samples += copy_samples;
     855                if (out_samples > samples)
     856                    len = WaitForFreeSpace(out_samples);
     857                int bdiff = AUDBUFSIZE - org_waud;
     858                if (bdiff < copy_len)
     859                {
     860                    int bdiff_samples = bdiff/abps;
     861                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples);
     862                    upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples));
     863                }
     864                else
     865                {
     866                    upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples);
     867                }
     868                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     869            }
    637870        }
    638         else
    639             memcpy(audiobuffer + org_waud, mybuf, len);
    640  
    641         org_waud = (org_waud + len) % AUDBUFSIZE;
    642     }
    643     else
     871        if (samples > 0)
     872        {
     873            len = WaitForFreeSpace(out_samples);
     874        }
     875        samples = out_samples;
     876    }
     877    else
    644878    {
    645         char **mybuf = (char**)buffer;
    646         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     879        len = WaitForFreeSpace(samples);
     880
     881        if (interleaved)
    647882        {
    648             for (int chan = 0; chan < audio_channels; chan++)
     883            char *mybuf = (char*)buffer;
     884            int bdiff = AUDBUFSIZE - org_waud;
     885            if (bdiff < len)
    649886            {
    650                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    651                 if (audio_bits == 16)
    652                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     887                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     888                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     889            }
     890            else
     891                memcpy(audiobuffer + org_waud, mybuf, len);
     892     
     893            org_waud = (org_waud + len) % AUDBUFSIZE;
     894        }
     895        else
     896        {
     897            char **mybuf = (char**)buffer;
     898            for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     899            {
     900                for (int chan = 0; chan < audio_channels; chan++)
     901                {
     902                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     903                    if (audio_bits == 16)
     904                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    653905
    654                 if (org_waud >= AUDBUFSIZE)
    655                     org_waud -= AUDBUFSIZE;
     906                    if (org_waud >= AUDBUFSIZE)
     907                        org_waud -= AUDBUFSIZE;
     908                }
    656909            }
    657910        }
    658911    }
    659912
    660     if (pSoundStretch)
     913    if (samples > 0)
    661914    {
    662         // does not change the timecode, only the number of samples
    663         // back to orig pos
    664         org_waud = waud;
    665         int bdiff = AUDBUFSIZE - org_waud;
    666         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
    667         if (bdiff < len)
     915        if (pSoundStretch)
    668916        {
    669             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    670                                       org_waud), nSamplesToEnd);
    671             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    672                                       (len - bdiff) / audio_bytes_per_sample);
    673         }
    674         else
    675         {
    676             pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    677                                       org_waud), len / audio_bytes_per_sample);
    678         }
    679917
    680         int newLen = 0;
    681         int nSamples;
    682         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    683                                audio_bytes_per_sample);
    684         do
    685         {
    686             int samplesToGet = len/audio_bytes_per_sample;
    687             if (samplesToGet > nSamplesToEnd)
     918            // does not change the timecode, only the number of samples
     919            // back to orig pos
     920            org_waud = waud;
     921            int bdiff = AUDBUFSIZE - org_waud;
     922            int nSamplesToEnd = bdiff/abps;
     923            if (bdiff < len)
    688924            {
    689                 samplesToGet = nSamplesToEnd;   
     925                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     926                                          org_waud), nSamplesToEnd);
     927                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     928                                          (len - bdiff) / abps);
    690929            }
     930            else
     931            {
     932                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
     933                                          org_waud), len / abps);
     934            }
    691935
    692             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    693                                       (audiobuffer + org_waud), samplesToGet);
    694             if (nSamples == nSamplesToEnd)
     936            if (encoder)
    695937            {
    696                 org_waud = 0;
    697                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     938                // pull out a packet's worth and reencode it until we dont have enough
     939                // for any more packets
     940                soundtouch::SAMPLETYPE* temp_buff =
     941                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     942                size_t frameSize = encoder->FrameSize()/abps;
     943                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     944                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     945                        .arg(frameSize)
     946                        .arg(encoder->FrameSize())
     947                        .arg(pSoundStretch->numSamples())
     948                       );
     949                // process the same number of samples as it creates a full encoded buffer
     950                // just like before
     951                while (pSoundStretch->numSamples() >= frameSize)
     952                {
     953                    int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     954                    int amount = encoder->Encode(temp_buff);
     955                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     956                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     957                            .arg(amount)
     958                            .arg(got)
     959                            .arg(pSoundStretch->numSamples())
     960                           );
     961                    if (amount == 0)
     962                        continue;
     963                    //len = WaitForFreeSpace(amount);
     964                    char * ob = encoder->GetOutBuff();
     965                    if (amount >= bdiff)
     966                    {
     967                        memcpy(audiobuffer + org_waud, ob, bdiff);
     968                        ob += bdiff;
     969                        amount -= bdiff;
     970                        org_waud = 0;
     971                    }
     972                    if (amount > 0)
     973                        memcpy(audiobuffer + org_waud, ob, amount);
     974                    bdiff = AUDBUFSIZE - amount;
     975                    org_waud += amount;
     976                }
    698977            }
    699978            else
    700979            {
    701                 org_waud += nSamples * audio_bytes_per_sample;
    702                 nSamplesToEnd -= nSamples;
     980                int newLen = 0;
     981                int nSamples;
     982                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     983                                       audio_bytes_per_sample);
     984                do
     985                {
     986                    int samplesToGet = len/audio_bytes_per_sample;
     987                    if (samplesToGet > nSamplesToEnd)
     988                    {
     989                        samplesToGet = nSamplesToEnd;   
     990                    }
     991
     992                    nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     993                                              (audiobuffer + org_waud), samplesToGet);
     994                    if (nSamples == nSamplesToEnd)
     995                    {
     996                        org_waud = 0;
     997                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     998                    }
     999                    else
     1000                    {
     1001                        org_waud += nSamples * audio_bytes_per_sample;
     1002                        nSamplesToEnd -= nSamples;
     1003                    }
     1004
     1005                    newLen += nSamples * audio_bytes_per_sample;
     1006                    len -= nSamples * audio_bytes_per_sample;
     1007                } while (nSamples > 0);
    7031008            }
     1009        }
    7041010
    705             newLen += nSamples * audio_bytes_per_sample;
    706             len -= nSamples * audio_bytes_per_sample;
    707         } while (nSamples > 0);
    708     }
     1011        waud = org_waud;
     1012        lastaudiolen = audiolen(false);
    7091013
    710     waud = org_waud;
    711     lastaudiolen = audiolen(false);
     1014        if (timecode < 0)
     1015        {
     1016            // mythmusic doesn't give timestamps..
     1017            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1018        }
     1019       
     1020        samples_buffered += samples;
     1021       
     1022        /* we want the time at the end -- but the file format stores
     1023           time at the start of the chunk. */
     1024        // even with timestretch, timecode is still calculated from original
     1025        // sample count
     1026        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7121027
    713     samples_buffered += samples;
    714    
    715     if (timecode < 0)
    716     {
    717         // mythmusic doesn't give timestamps..
    718         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1028        if (interleaved)
     1029            dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits);
    7191030    }
    720    
    721     /* we want the time at the end -- but the file format stores
    722        time at the start of the chunk. */
    723     // even with timestretch, timecode is still calculated from original
    724     // sample count
    725     audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7261031
    727     if (interleaved)
    728         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    729 
    7301032    pthread_mutex_unlock(&audio_buflock);
    7311033}
    7321034
     
    7391041
    7401042    if (source_bitrate == -1)
    7411043    {
    742         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1044        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7431045    }
    7441046
    7451047    if (ct / 1000 != current_seconds)
     
    7471049        current_seconds = ct / 1000;
    7481050        OutputEvent e(current_seconds, ct,
    7491051                      source_bitrate, audio_samplerate, audio_bits,
    750                       audio_channels);
     1052                      source_audio_channels);
    7511053        dispatch(e);
    7521054    }
    7531055}
     
    7861088            space_on_soundcard = getSpaceOnSoundcard();
    7871089
    7881090            if (space_on_soundcard != last_space_on_soundcard) {
    789                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1091                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7901092                        .arg(space_on_soundcard));
    7911093                last_space_on_soundcard = space_on_soundcard;
    7921094            }
     
    7991101                    WriteAudio(zeros, fragment_size);
    8001102                } else {
    8011103                    // this should never happen now -dag
    802                     VERBOSE(VB_AUDIO, LOC +
     1104                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031105                            QString("waiting for space on soundcard "
    8041106                                    "to write zeros: have %1 need %2")
    8051107                            .arg(space_on_soundcard).arg(fragment_size));
     
    8351137        if (fragment_size > audiolen(true))
    8361138        {
    8371139            if (audiolen(true) > 0)  // only log if we're sending some audio
    838                 VERBOSE(VB_AUDIO, LOC +
     1140                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8391141                        QString("audio waiting for buffer to fill: "
    8401142                                "have %1 want %2")
    8411143                        .arg(audiolen(true)).arg(fragment_size));
    8421144
    843             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1145            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8441146            pthread_mutex_lock(&audio_buflock);
    8451147            pthread_cond_broadcast(&audio_bufsig);
    8461148            pthread_mutex_unlock(&audio_buflock);
     
    8541156        if (fragment_size > space_on_soundcard)
    8551157        {
    8561158            if (space_on_soundcard != last_space_on_soundcard) {
    857                 VERBOSE(VB_AUDIO, LOC +
     1159                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8581160                        QString("audio waiting for space on soundcard: "
    8591161                                "have %1 need %2")
    8601162                        .arg(space_on_soundcard).arg(fragment_size));
     
    9161218
    9171219        /* update raud */
    9181220        raud = (raud + fragment_size) % AUDBUFSIZE;
    919         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1221        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9201222        pthread_cond_broadcast(&audio_bufsig);
    9211223
    9221224        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

     
    5252    QString real_device = (audio_passthru) ?
    5353        audio_passthru_device : audio_main_device;
    5454
     55    int index;
     56    if ((index=real_device.find('|'))>=0)
     57    {
     58        if (audio_channels >= 2)
     59            real_device = real_device.mid(index+1);
     60        else
     61            real_device = real_device.left(index);
     62    }
     63
    5564    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    5665            .arg(real_device));
    5766
     
    8998    }
    9099    else
    91100    {
    92         fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
    93         buffer_time = 500000;  // .5 seconds
     101        //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     102        //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits
     103        fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30);
     104        buffer_time = 100000;  // .5 seconds
    94105        period_time = buffer_time / 4;  // 4 interrupts per buffer
    95106    }
    96107
     
    162173   
    163174    tmpbuf = aubuf;
    164175
    165     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     176    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    166177            .arg(size).arg(frames));
    167178   
    168179    while (frames > 0)
  • programs/mythfrontend/globalsettings.cpp

     
    5757#endif
    5858#ifdef USING_ALSA
    5959    gc->addSelection("ALSA:default", "ALSA:default");
     60    gc->addSelection("ALSA:surround51", "ALSA:surround51");
     61    gc->addSelection("ALSA:analog", "ALSA:analog");
     62    gc->addSelection("ALSA:digital", "ALSA:digital");
     63    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     64    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
    6065#endif
    6166#ifdef USING_ARTS
    6267    gc->addSelection("ARTS:", "ARTS:");
     
    7883    return gc;
    7984}
    8085
     86static HostComboBox *MaxAudioChannels()
     87{
     88    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     89    gc->setLabel(QObject::tr("Max Audio Channels"));
     90    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     91    gc->addSelection(QObject::tr("5.1"), "6");
     92    gc->setHelpText(
     93            QObject::tr("Set the maximum number of audio channels to be decoded. "
     94                "This is for multi-channel/surround audio playback."));
     95    return gc;
     96}
     97
     98static HostComboBox *AudioUpmixType()
     99{
     100    HostComboBox *gc = new HostComboBox("AudioUpmixType",false);
     101    gc->setLabel(QObject::tr("Upmix"));
     102    gc->addSelection(QObject::tr("Passive"), "0");
     103    gc->addSelection(QObject::tr("Active Simple"), "1");
     104    gc->addSelection(QObject::tr("Active Linear"), "2", true); // default
     105    gc->setHelpText(
     106            QObject::tr("Set the audio upmix type for 2ch to 6ch conversion. "
     107                "This is for multi-channel/surround audio playback."));
     108    return gc;
     109}
     110
    81111static HostComboBox *PassThroughOutputDevice()
    82112{
    83113    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31563186         vgrp0->addChild(AC3PassThrough());
    31573187         vgrp0->addChild(DTSPassThrough());
    31583188
     3189         HorizontalConfigurationGroup *agrp =
     3190             new HorizontalConfigurationGroup(false, false, true, true);
     3191         agrp->addChild(MaxAudioChannels());
     3192         agrp->addChild(AudioUpmixType());
     3193         addChild(agrp);
     3194
    31593195         VerticalConfigurationGroup *vgrp1 =
    31603196             new VerticalConfigurationGroup(false, false, true, true);
    31613197         vgrp1->addChild(AggressiveBuffer());
  • programs/mythtranscode/transcode.cpp

     
    5555
    5656    // reconfigure sound out for new params
    5757    virtual void Reconfigure(int audio_bits, int audio_channels,
    58                              int audio_samplerate, bool audio_passthru)
     58                             int audio_samplerate, bool audio_passthru,
     59                             void * = NULL)
    5960    {
     61        ClearError();
    6062        (void)audio_samplerate;
    6163        (void)audio_passthru;
    6264        bits = audio_bits;
    6365        channels = audio_channels;
    6466        bytes_per_sample = bits * channels / 8;
     67        if (channels>2)
     68            Error("Invalid channel count");
    6569    }
    6670
    6771    // dsprate is in 100 * samples/second
  • libs/libmythtv/avformatdecoder.h

     
    261261    bool              allow_ac3_passthru;
    262262    bool              allow_dts_passthru;
    263263    bool              disable_passthru;
     264    int               max_channels;
    264265    VideoFrame       *dummy_frame;
    265266
    266267    AudioInfo         audioIn;
  • libs/libmythtv/avformatdecoder.cpp

     
    5151
    5252#define MAX_AC3_FRAME_SIZE 6144
    5353
    54 /** Set to zero to allow any number of AC3 channels. */
    55 #define MAX_OUTPUT_CHANNELS 2
    56 
    5754static int cc608_parity(uint8_t byte);
    5855static int cc608_good_parity(const int *parity_table, uint16_t data);
    5956static void cc608_build_parity_table(int *parity_table);
     
    417414
    418415    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419416    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     417    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    420418
    421419    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422420    itv = GetNVP()->GetInteractiveTV();
     
    15871585                            <<") already open, leaving it alone.");
    15881586                }
    15891587                //assert(enc->codec_id);
     1588                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
    15901589
     1590#if 0
     1591                // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this
    15911592                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15921593                if (enc->codec_id == CODEC_ID_DTS)
    15931594                {
     
    15961597                    // enc->bit_rate = what??;
    15971598                }
    15981599                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1600#endif
    15991601
    16001602                bitrate += enc->bit_rate;
    16011603                break;
     
    32853287
    32863288                    // detect channels on streams that need
    32873289                    // to be decoded before we can know this
     3290                    int prev_channels = curstream->codec->channels;
     3291                    bool already_decoded = false;
    32883292                    if (!curstream->codec->channels)
    32893293                    {
    32903294                        QMutexLocker locker(&avcodeclock);
    3291                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3295                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3296                        curstream->codec->channels = audioOut.channels;
     3297                        curstream->codec->request_channels = audioOut.channels;
    32923298                        ret = avcodec_decode_audio(
    32933299                            curstream->codec, audioSamples,
    32943300                            &data_size, ptr, len);
     3301                        already_decoded = true;
    32953302
    32963303                        reselectAudioTrack |= curstream->codec->channels;
    32973304                    }
     
    33493356                        AVCodecContext *ctx = curstream->codec;
    33503357
    33513358                        if ((ctx->channels == 0) ||
    3352                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3353                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3359                            (ctx->channels > audioOut.channels))
     3360                            ctx->channels = audioOut.channels;
    33543361
    3355                         ret = avcodec_decode_audio(
    3356                             ctx, audioSamples, &data_size, ptr, len);
     3362                        if (!already_decoded)
     3363                        {
     3364                            curstream->codec->request_channels = audioOut.channels;
     3365                            ret = avcodec_decode_audio(
     3366                                ctx, audioSamples, &data_size, ptr, len);
     3367                        }
    33573368
    33583369                        // When decoding some audio streams the number of
    33593370                        // channels, etc isn't known until we try decoding it.
     
    37833794
    37843795void AvFormatDecoder::SetDisablePassThrough(bool disable)
    37853796{
     3797    // can only disable never reenable as once timestretch is on its on for the session
     3798    if (disable_passthru)
     3799        return;
    37863800    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    37873801    {
    37883802        disable_passthru = disable;
     
    38153829    AVCodecContext *codec_ctx = NULL;
    38163830    AudioInfo old_in  = audioIn;
    38173831    AudioInfo old_out = audioOut;
     3832    bool using_passthru = false;
    38183833
    38193834    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    38203835        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    38263841        assert(curstream->codec);
    38273842        codec_ctx = curstream->codec;       
    38283843        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3829                                 !disable_passthru &&
    38303844                                (codec_ctx->codec_id == CODEC_ID_AC3));
    38313845        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3832                                 !disable_passthru &&
    38333846                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3847        using_passthru = do_ac3_passthru || do_dts_passthru;
    38343848        info = AudioInfo(codec_ctx->codec_id,
    38353849                         codec_ctx->sample_rate, codec_ctx->channels,
    3836                          do_ac3_passthru || do_dts_passthru);
     3850                         using_passthru && !disable_passthru);
    38373851    }
    38383852
    38393853    if (info == audioIn)
    38403854        return false; // no change
    38413855
     3856    QString ptmsg = "";
     3857    if (using_passthru)
     3858    {
     3859        ptmsg = QString(" using passthru");
     3860    }
    38423861    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    38433862            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    38443863
    38453864    audioOut = audioIn = info;
    3846     if (audioIn.do_passthru)
     3865    if (using_passthru)
    38473866    {
    38483867        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3849         audioOut.channels    = 2;
    3850         audioOut.sample_rate = 48000;
    3851         audioOut.sample_size = 4;
     3868        AudioInfo digInfo = audioOut;
     3869        if (!disable_passthru)
     3870        {
     3871            digInfo.channels    = 2;
     3872            digInfo.sample_rate = 48000;
     3873            digInfo.sample_size = 4;
     3874        }
     3875        if (audioOut.channels > max_channels)
     3876        {
     3877            audioOut.channels = max_channels;
     3878            audioOut.sample_size = audioOut.channels * 2;
     3879            codec_ctx->channels = audioOut.channels;
     3880        }
     3881        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3882                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3883                .arg(digInfo.toString())
     3884                .arg(old_in.toString()).arg(old_out.toString())
     3885                .arg(audioIn.toString()).arg(audioOut.toString()));
     3886
     3887        if (digInfo.sample_rate > 0)
     3888            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3889
     3890        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3891                                 digInfo.sample_rate, audioIn.do_passthru);
     3892        // allow the audio stuff to reencode
     3893        GetNVP()->SetAudioCodec(codec_ctx);
     3894        GetNVP()->ReinitAudio();
     3895        return true;
    38523896    }
    38533897    else
    38543898    {
    3855         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3899        if (audioOut.channels > max_channels)
    38563900        {
    3857             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3901            audioOut.channels = max_channels;
    38583902            audioOut.sample_size = audioOut.channels * 2;
    3859             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3903            codec_ctx->channels = audioOut.channels;
    38603904        }
    38613905    }
     3906    bool audiook;
    38623907
    38633908    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    38643909            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    38713916    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    38723917                             audioOut.sample_rate,
    38733918                             audioIn.do_passthru);
    3874     GetNVP()->ReinitAudio();
     3919    // allow the audio stuff to reencode
     3920    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3921    QString errMsg = GetNVP()->ReinitAudio();
     3922    audiook = errMsg.isEmpty();
    38753923
    38763924    return true;
    38773925}
  • libs/libmythtv/NuppelVideoPlayer.h

     
    127127    void SetAudioInfo(const QString &main, const QString &passthru, uint rate);
    128128    void SetAudioParams(int bits, int channels, int samplerate, bool passthru);
    129129    void SetEffDsp(int dsprate);
     130    void SetAudioCodec(void *ac);
    130131
    131132    // Sets
    132133    void SetParentWidget(QWidget *widget)     { parentWidget = widget; }
     
    683684    int      audio_bits;
    684685    int      audio_samplerate;
    685686    float    audio_stretchfactor;
     687    void     *audio_codec;
    686688    bool     audio_passthru;
    687689
    688690    // Picture-in-Picture
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    206206      audio_passthru_device(QString::null),
    207207      audio_channels(2),            audio_bits(-1),
    208208      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     209      audio_codec(NULL),
    209210      // Picture-in-Picture
    210211      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    211212      // Preview window support
     
    767768    if (audioOutput)
    768769    {
    769770        audioOutput->Reconfigure(audio_bits, audio_channels,
    770                                  audio_samplerate, audio_passthru);
     771                                 audio_samplerate, audio_passthru,
     772                                 audio_codec);
    771773        errMsg = audioOutput->GetError();
    772774        if (!errMsg.isEmpty())
    773775            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    36503657    audio_passthru = passthru;
    36513658}
    36523659
     3660void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3661{
     3662    audio_codec = ac;
     3663}
     3664
    36533665void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36543666{
    36553667    if (audioOutput)
  • libs/libavcodec/liba52.c

     
    134134    }
    135135}
    136136
     137static inline int16_t convert(int32_t i)
     138{
     139    return av_clip_int16(i - 0x43c00000);
     140}
     141
     142void float2s16_2 (float * _f, int16_t * s16)
     143{
     144    int i;
     145    int32_t * f = (int32_t *) _f;
     146
     147    for (i = 0; i < 256; i++) {
     148        s16[2*i] = convert (f[i]);
     149        s16[2*i+1] = convert (f[i+256]);
     150    }
     151}
     152
     153void float2s16_4 (float * _f, int16_t * s16)
     154{
     155    int i;
     156    int32_t * f = (int32_t *) _f;
     157
     158    for (i = 0; i < 256; i++) {
     159        s16[4*i] = convert (f[i]);
     160        s16[4*i+1] = convert (f[i+256]);
     161        s16[4*i+2] = convert (f[i+512]);
     162        s16[4*i+3] = convert (f[i+768]);
     163    }
     164}
     165
     166void float2s16_5 (float * _f, int16_t * s16)
     167{
     168    int i;
     169    int32_t * f = (int32_t *) _f;
     170
     171    for (i = 0; i < 256; i++) {
     172        s16[5*i] = convert (f[i]);
     173        s16[5*i+1] = convert (f[i+256]);
     174        s16[5*i+2] = convert (f[i+512]);
     175        s16[5*i+3] = convert (f[i+768]);
     176        s16[5*i+4] = convert (f[i+1024]);
     177    }
     178}
     179
     180#define LIKEAC3DEC 1
     181int channels_multi (int flags)
     182{
     183    if (flags & A52_LFE)
     184        return 6;
     185    else if (flags & 1) /* center channel */
     186        return 5;
     187    else if ((flags & A52_CHANNEL_MASK) == A52_2F2R)
     188        return 4;
     189    else
     190        return 2;
     191}
     192
     193void float2s16_multi (float * _f, int16_t * s16, int flags)
     194{
     195    int i;
     196    int32_t * f = (int32_t *) _f;
     197
     198    switch (flags) {
     199    case A52_MONO:
     200        for (i = 0; i < 256; i++) {
     201            s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
     202            s16[5*i+4] = convert (f[i]);
     203        }
     204        break;
     205    case A52_CHANNEL:
     206    case A52_STEREO:
     207    case A52_DOLBY:
     208        float2s16_2 (_f, s16);
     209        break;
     210    case A52_3F:
     211        for (i = 0; i < 256; i++) {
     212            s16[5*i] = convert (f[i]);
     213            s16[5*i+1] = convert (f[i+512]);
     214            s16[5*i+2] = s16[5*i+3] = 0;
     215            s16[5*i+4] = convert (f[i+256]);
     216        }
     217        break;
     218    case A52_2F2R:
     219        float2s16_4 (_f, s16);
     220        break;
     221    case A52_3F2R:
     222        float2s16_5 (_f, s16);
     223        break;
     224    case A52_MONO | A52_LFE:
     225        for (i = 0; i < 256; i++) {
     226#if LIKEAC3DEC
     227            s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     228            s16[6*i+1] = convert (f[i+256]);
     229            s16[6*i+5] = convert (f[i]);
     230#else
     231            s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
     232            s16[6*i+4] = convert (f[i+256]);
     233            s16[6*i+5] = convert (f[i]);
     234#endif
     235        }
     236        break;
     237    case A52_CHANNEL | A52_LFE:
     238    case A52_STEREO | A52_LFE:
     239    case A52_DOLBY | A52_LFE:
     240        for (i = 0; i < 256; i++) {
     241#if LIKEAC3DEC
     242            s16[6*i] = convert (f[i+256]);
     243            s16[6*i+2] = convert (f[i+512]);
     244            s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0;
     245            s16[6*i+5] = convert (f[i]);
     246#else
     247            s16[6*i] = convert (f[i+256]);
     248            s16[6*i+1] = convert (f[i+512]);
     249            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     250            s16[6*i+5] = convert (f[i]);
     251#endif
     252        }
     253        break;
     254    case A52_3F | A52_LFE:
     255        for (i = 0; i < 256; i++) {
     256#if LIKEAC3DEC
     257            s16[6*i] = convert (f[i+256]);
     258            s16[6*i+2] = convert (f[i+768]);
     259            s16[6*i+3] = s16[6*i+4] = 0;
     260            s16[6*i+1] = convert (f[i+512]);
     261            s16[6*i+5] = convert (f[i]);
     262#else
     263            s16[6*i] = convert (f[i+256]);
     264            s16[6*i+1] = convert (f[i+768]);
     265            s16[6*i+2] = s16[6*i+3] = 0;
     266            s16[6*i+4] = convert (f[i+512]);
     267            s16[6*i+5] = convert (f[i]);
     268#endif
     269        }
     270        break;
     271    case A52_2F2R | A52_LFE:
     272        for (i = 0; i < 256; i++) {
     273#if LIKEAC3DEC
     274            s16[6*i] = convert (f[i+256]);
     275            s16[6*i+1] = 0;
     276            s16[6*i+2] = convert (f[i+512]);
     277            s16[6*i+3] = convert (f[i+768]);
     278            s16[6*i+4] = convert (f[i+1024]);
     279            s16[6*i+5] = convert (f[i]);
     280#else
     281            s16[6*i] = convert (f[i+256]);
     282            s16[6*i+1] = convert (f[i+512]);
     283            s16[6*i+2] = convert (f[i+768]);
     284            s16[6*i+3] = convert (f[i+1024]);
     285            s16[6*i+4] = 0;
     286            s16[6*i+5] = convert (f[i]);
     287#endif
     288        }
     289        break;
     290    case A52_3F2R | A52_LFE:
     291        for (i = 0; i < 256; i++) {
     292#if LIKEAC3DEC
     293            s16[6*i] = convert (f[i+256]);
     294            s16[6*i+1] = convert (f[i+512]);
     295            s16[6*i+2] = convert (f[i+768]);
     296            s16[6*i+3] = convert (f[i+1024]);
     297            s16[6*i+4] = convert (f[i+1280]);
     298            s16[6*i+5] = convert (f[i]);
     299#else
     300            s16[6*i] = convert (f[i+256]);
     301            s16[6*i+1] = convert (f[i+768]);
     302            s16[6*i+2] = convert (f[i+1024]);
     303            s16[6*i+3] = convert (f[i+1280]);
     304            s16[6*i+4] = convert (f[i+512]);
     305            s16[6*i+5] = convert (f[i]);
     306#endif
     307        }
     308        break;
     309    }
     310}
     311
    137312/**** end */
    138313
    139314#define HEADER_SIZE 7
     
    179354                    s->channels = ac3_channels[s->flags & 7];
    180355                    if (s->flags & A52_LFE)
    181356                        s->channels++;
     357                    if (avctx->request_channels > 0)
     358                    {
     359                        avctx->channels = s->channels;
     360                        if (s->channels > avctx->channels)
     361                            avctx->channels = avctx->request_channels;
     362                    }
    182363                    if (avctx->channels == 0)
    183364                        /* No specific number of channel requested */
    184365                        avctx->channels = s->channels;
     
    199380            s->inbuf_ptr += len;
    200381            buf_size -= len;
    201382        } else {
     383            int chans;
    202384            flags = s->flags;
    203385            if (avctx->channels == 1)
    204386                flags = A52_MONO;
    205             else if (avctx->channels == 2)
    206                 flags = A52_STEREO;
     387            else if (avctx->channels == 2) {
     388                if (s->channels>2)
     389                    flags = A52_DOLBY;
     390                else
     391                    flags = A52_STEREO;
     392            }
    207393            else
    208394                flags |= A52_ADJUST_LEVEL;
    209395            level = 1;
     396            chans = channels_multi(flags);
    210397            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    211398            fail:
    212399                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    217404            for (i = 0; i < 6; i++) {
    218405                if (s->a52_block(s->state))
    219406                    goto fail;
    220                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     407                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    221408            }
    222409            s->inbuf_ptr = s->inbuf;
    223410            s->frame_size = 0;
  • libs/libavcodec/ac3dec.c

     
    11321132
    11331133    /* channel config */
    11341134    ctx->out_channels = ctx->nchans;
     1135    if (avctx->request_channels > 0)
     1136    {
     1137        avctx->channels = ctx->out_channels;
     1138        if (avctx->channels > avctx->request_channels)
     1139            avctx->channels = avctx->request_channels;
     1140    }
    11351141    if (avctx->channels == 0) {
    11361142        avctx->channels = ctx->out_channels;
    11371143    } else if(ctx->out_channels < avctx->channels) {
  • libs/libavcodec/dca.c

     
    11591159    avctx->bit_rate = s->bit_rate;
    11601160
    11611161    channels = s->prim_channels + !!s->lfe;
    1162     avctx->channels = avctx->request_channels;
     1162    //avctx->channels = avctx->request_channels;
     1163    if (avctx->request_channels > 0)
     1164    {
     1165        avctx->channels = channels;
     1166        if (avctx->channels > avctx->request_channels)
     1167            avctx->channels = avctx->request_channels;
     1168    }
    11631169    if(avctx->channels == 0) {
    11641170        avctx->channels = channels;
    11651171    } else if(channels < avctx->channels) {