Ticket #1104: mythtv_ac3.47.patch

File mythtv_ac3.47.patch, 62.1 KB (added by Mark Spieth, 16 years ago)

same as 46 but formatted to daniels reviewed version

  • 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

     
    1111
    1212# Input
    1313HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h
     14HEADERS += audiooutputdigitalencoder.h
    1415HEADERS += backendselect.h dbsettings.h dialogbox.h
    1516HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h
    1617HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h
     
    2526HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2627HEADERS += mythhdd.h mythcdrom.h
    2728HEADERS += compat.h
     29HEADERS += audiooutputdigitalencoder.h
    2830
    2931SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
     32SOURCES += audiooutputdigitalencoder.cpp
    3033SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
    3134SOURCES += DisplayRes.cpp DisplayResScreen.cpp
    3235SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp
     
    4144SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4245SOURCES += mythhdd.cpp mythcdrom.cpp
    4346
    44 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../libmythfreesurround
     48INCLUDEPATH += ../libavcodec ../libavutil
     49INCLUDEPATH += ../.. ../ ./
    4550DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    46 DEPENDPATH += ../libmythupnp
     51DEPENDPATH += ../libmythupnp ../libmythfreesurround ../libavcodec ../libavutil
    4752
    48 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    49 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
    50 LIBS += -L../libmythui         -lmythui-$${LIBVERSION}
    51 LIBS += -L../libmythupnp       -lmythupnp-$${LIBVERSION}
    5253
     54LIBS += -L../libmythsamplerate   -lmythsamplerate-$${LIBVERSION}
     55LIBS += -L../libmythsoundtouch   -lmythsoundtouch-$${LIBVERSION}
     56LIBS += -L../libmythui           -lmythui-$${LIBVERSION}
     57LIBS += -L../libmythupnp         -lmythupnp-$${LIBVERSION}
     58LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION}
     59LIBS += -L../libavcodec          -lmythavcodec-$${LIBVERSION}
     60LIBS += -L../libavutil           -lmythavutil-$${LIBVERSION}
     61LIBS += -lfftw3f
     62
    5363TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5464TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     65TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT}
    5566
    5667# Install headers so that plugins can compile independently
    5768inc.path = $${PREFIX}/include/mythtv/
     
    221232use_hidesyms {
    222233    QMAKE_CXXFLAGS += -fvisibility=hidden
    223234}
     235
     236contains( CONFIG_LIBA52, yes ) {
     237    LIBS += -la52
     238}
  • 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) = 0;
    3639   
    3740    virtual void SetStretchFactor(float factor);
     41    virtual float GetStretchFactor(void) { return 1.0f; }
    3842
    3943    // do AddSamples calls block?
    4044    virtual void SetBlocking(bool blocking) = 0;
     
    7680        lastError = msg;
    7781        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7882    }
     83    void ClearError(void) { lastError = QString::null; }
    7984
    8085    void Warn(QString msg)
    8186    {
  • 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)
    135138{
    136139    if (dsbuffer)
    137140        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(void);
    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;
     
    145162    short tmp_buff[AUDIO_TMP_BUF_SIZE];
    146163
    147164    // timestretch
    148     soundtouch::SoundTouch * pSoundStretch;
     165    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
    168                    //                                          timecodes) ...
     191    /// timecode of audio leaving the soundcard (same units as timecodes)
     192    long long audiotime;
    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
    175                    buffer */
     198    /// timecode of audio most recently placed into buffer
     199    long long audbuf_timecode;
    176200
    177201    int numlowbuffer;
    178202
  • 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 +
     132                            QString("Creating Encoder for codec %1 origfs %2")
     133                            .arg(audio_codec->codec_id)
     134                            .arg(audio_codec->frame_size));
    116135
     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                                ))
     142                    {
     143                        // eeks
     144                        delete encoder;
     145                        encoder = NULL;
     146                        VERBOSE(VB_AUDIO, LOC +
     147                                QString("Failed to Create Encoder"));
     148                    }
     149                }
     150            }
     151            if (encoder)
     152            {
     153                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     154                pSoundStretch->setChannels(audio_codec->channels);
     155            }
     156            else
     157            {
     158                pSoundStretch->setSampleRate(audio_samplerate);
     159                pSoundStretch->setChannels(audio_channels);
     160            }
     161
    117162            pSoundStretch->setTempo(audio_stretchfactor);
    118163            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
    119164
     
    134179    pthread_mutex_unlock(&audio_buflock);
    135180}
    136181
     182float AudioOutputBase::GetStretchFactor()
     183{
     184    return audio_stretchfactor;
     185}
     186
    137187void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     188                                 int laudio_samplerate, bool laudio_passthru,
     189                                 void* laudio_codec)
    139190{
    140     if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     191    int codec_id = CODEC_ID_NONE;
     192    int lcodec_id = CODEC_ID_NONE;
     193    int lcchannels = 0;
     194    int cchannels = 0;
     195    int lsource_audio_channels = laudio_channels;
     196    bool lneeds_upmix = false;
     197
     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    }
     207
     208    if (audio_codec)
     209    {
     210        codec_id = audio_codec->codec_id;
     211        cchannels = ((AVCodecContext*)audio_codec)->channels;
     212    }
     213
     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");
     220    }
     221
     222    ClearError();
     223    if (laudio_bits == audio_bits &&
     224        lsource_audio_channels == source_audio_channels &&
     225        laudio_channels == audio_channels &&
     226        laudio_samplerate == audio_samplerate && !need_resampler &&
     227        laudio_passthru == audio_passthru &&
     228        lneeds_upmix == needs_upmix &&
     229        lcodec_id == codec_id && lcchannels == cchannels)
     230    {
     231        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143232        return;
     233    }
    144234
    145235    KillAudio();
    146236   
     
    151241    waud = raud = 0;
    152242    audio_actually_paused = false;
    153243   
     244    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154245    audio_channels = laudio_channels;
     246    source_audio_channels = lsource_audio_channels;
    155247    audio_bits = laudio_bits;
    156248    audio_samplerate = laudio_samplerate;
     249    audio_codec = (AVCodecContext*)laudio_codec;
    157250    audio_passthru = laudio_passthru;
     251    needs_upmix = lneeds_upmix;
     252
    158253    if (audio_bits != 8 && audio_bits != 16)
    159254    {
    160255        pthread_mutex_unlock(&avsync_lock);
     
    162257        Error("AudioOutput only supports 8 or 16bit audio.");
    163258        return;
    164259    }
     260
    165261    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     262    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166263   
    167264    need_resampler = false;
    168265    killaudio = false;
     
    172269   
    173270    numlowbuffer = 0;
    174271
     272    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     273            .arg(audio_main_device).arg(audio_channels)
     274            .arg(source_audio_channels).arg(audio_samplerate));
     275 
    175276    // Actually do the device specific open call
    176277    if (!OpenDevice())
    177278    {
    178279        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179280        pthread_mutex_unlock(&avsync_lock);
    180281        pthread_mutex_unlock(&audio_buflock);
     282        if (GetError().isEmpty())
     283            Error("Aborting reconfigure");
     284        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181285        return;
    182286    }
    183287
     
    200304    current_seconds = -1;
    201305    source_bitrate = -1;
    202306
     307    // NOTE: this won't do anything as above samplerate vars are set equal
    203308    // Check if we need the resampler
    204309    if (audio_samplerate != laudio_samplerate)
    205310    {
     
    222327        need_resampler = true;
    223328    }
    224329
     330    if (needs_upmix)
     331    {
     332        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     333        if (configured_audio_channels == 6)
     334        {
     335            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
     336        }
     337
     338        upmixer = new FreeSurround(
     339            audio_samplerate,
     340            source == AUDIOOUTPUT_VIDEO,
     341            (FreeSurround::SurroundMode)surround_mode);
     342
     343        VERBOSE(VB_AUDIO, LOC +
     344                QString("create upmixer done with surround mode %1")
     345                .arg(surround_mode));
     346    }
     347
    225348    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226349            .arg(audio_stretchfactor));
     350    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     351            .arg((audio_codec) ?
     352                 codec_id_string(audio_codec->codec_id) : "not set"));
    227353
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     354    if (redo_stretch)
    230355    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     356        float laudio_stretchfactor = audio_stretchfactor;
     357        delete pSoundStretch;
     358        pSoundStretch = NULL;
     359        audio_stretchfactor = 0.0f;
     360        SetStretchFactorLocked(laudio_stretchfactor);
    233361    }
     362    else
     363    {
     364        SetStretchFactorLocked(audio_stretchfactor);
     365        if (pSoundStretch)
     366        {
     367            // if its passthru then we need to reencode
     368            if (audio_codec)
     369            {
     370                if (!encoder)
     371                {
     372                    VERBOSE(VB_AUDIO, LOC +
     373                            QString("Creating Encoder for codec %1")
     374                            .arg(audio_codec->codec_id));
    234375
     376                    encoder = new AudioOutputDigitalEncoder();
     377                    if (!encoder->Init(audio_codec->codec_id,
     378                                audio_codec->bit_rate,
     379                                audio_codec->sample_rate,
     380                                audio_codec->channels
     381                                ))
     382                    {
     383                        // eeks
     384                        delete encoder;
     385                        encoder = NULL;
     386                        VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     387                    }
     388                }
     389            }
     390            if (encoder)
     391            {
     392                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     393                pSoundStretch->setChannels(audio_codec->channels);
     394            }
     395            else
     396            {
     397                pSoundStretch->setSampleRate(audio_samplerate);
     398                pSoundStretch->setChannels(audio_channels);
     399            }
     400        }
     401    }
     402
    235403    // Setup visualisations, zero the visualisations buffers
    236404    prepareVisuals();
    237405
     
    290458        pSoundStretch = NULL;
    291459    }
    292460
     461    if (encoder)
     462    {
     463        delete encoder;
     464        encoder = NULL;
     465    }
     466
     467    if (upmixer)
     468    {
     469        delete upmixer;
     470        upmixer = NULL;
     471    }
     472    needs_upmix = false;
     473
    293474    CloseDevice();
    294475
    295476    killAudioLock.unlock();
     
    303484
    304485void AudioOutputBase::Pause(bool paused)
    305486{
     487    VERBOSE(VB_AUDIO, LOC + QString("Pause %0").arg(paused));
    306488    pauseaudio = paused;
    307489    audio_actually_paused = false;
    308490}
     
    385567       The reason is that computing 'audiotime' requires acquiring the audio
    386568       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387569       from the audio thread, and then call this from the video thread. */
    388     int ret;
     570    long long ret;
    389571    struct timeval now;
    390572
    391573    if (audiotime == 0)
     
    397579
    398580    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399581    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     582    ret = (long long)(ret * audio_stretchfactor);
    401583
     584#if 1
     585    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     586            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     587            .arg(now.tv_sec).arg(now.tv_usec)
     588            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     589            .arg(ret)
     590            .arg(audiotime)
     591            .arg(audio_stretchfactor)
     592           );
     593#endif
     594
    402595    ret += audiotime;
    403596
    404597    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     598    return (int)ret;
    406599}
    407600
    408601void AudioOutputBase::SetAudiotime(void)
     
    439632    // include algorithmic latencies
    440633    if (pSoundStretch)
    441634    {
     635        // add the effect of any unused but processed samples,
     636        // AC3 reencode does this
     637        totalbuffer += (int)(pSoundStretch->numSamples() *
     638                             audio_bytes_per_sample);
    442639        // add the effect of unprocessed samples in time stretch algo
    443640        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444641                              audio_bytes_per_sample) / audio_stretchfactor);
    445642    }
    446                
     643
     644    if (upmixer && needs_upmix)
     645    {
     646        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     647    }
     648
    447649    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448650                                   (audio_bytes_per_sample * effdspstretched));
    449651 
    450652    gettimeofday(&audiotime_updated, NULL);
     653#if 1
     654    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     655            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 "
     656                    "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     657            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     658            .arg(audiotime)
     659            .arg(audbuf_timecode)
     660            .arg(totalbuffer)
     661            .arg(soundcard_buffer)
     662            .arg(effdspstretched)
     663            .arg(audio_bytes_per_sample)
     664            .arg(audio_stretchfactor)
     665           );
     666#endif
    451667
    452668    pthread_mutex_unlock(&avsync_lock);
    453669    pthread_mutex_unlock(&audio_buflock);
     
    458674{
    459675    // NOTE: This function is not threadsafe
    460676    int afree = audiofree(true);
    461     int abps = audio_bytes_per_sample;
     677    int abps = (encoder) ?
     678        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    462679    int len = samples * abps;
    463680
    464681    // Check we have enough space to write the data
    465682    if (need_resampler && src_ctx)
    466683        len = (int)ceilf(float(len) * src_data.src_ratio);
    467684
     685    // include samples in upmix buffer that may be flushed
     686    if (needs_upmix && upmixer)
     687        len += upmixer->numUnprocessedSamples() * abps;
     688
    468689    if (pSoundStretch)
    469690        len += (pSoundStretch->numUnprocessedSamples() +
    470691                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     
    520741    // NOTE: This function is not threadsafe
    521742
    522743    int afree = audiofree(true);
    523     int abps = audio_bytes_per_sample;
     744    int abps = (encoder) ?
     745        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    524746    int len = samples * abps;
    525747
    526748    // Check we have enough space to write the data
    527749    if (need_resampler && src_ctx)
    528750        len = (int)ceilf(float(len) * src_data.src_ratio);
    529751
     752    // include samples in upmix buffer that may be flushed
     753    if (needs_upmix && upmixer)
     754        len += upmixer->numUnprocessedSamples() * abps;
     755 
    530756    if (pSoundStretch)
    531757    {
    532758        len += (pSoundStretch->numUnprocessedSamples() +
     
    575801
    576802int AudioOutputBase::WaitForFreeSpace(int samples)
    577803{
    578     int len = samples * audio_bytes_per_sample;
     804    int abps = (encoder) ?
     805        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
     806    int len = samples * abps;
    579807    int afree = audiofree(false);
    580808
    581809    while (len > afree)
    582810    {
    583811        if (blocking)
    584812        {
    585             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     813            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    586814                    QString("(need %1, available %2)").arg(len).arg(afree));
    587815
    588816            // wait for more space
     
    591819        }
    592820        else
    593821        {
    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;
     822            VERBOSE(VB_IMPORTANT, LOC_ERR +
     823                    QString("Audio buffer overflow, %1 audio samples lost!")
     824                    .arg(samples - (afree / abps)));
     825            samples = afree / abps;
     826            len = samples * abps;
    598827            if (src_ctx)
    599828            {
    600829                int error = src_reset(src_ctx);
     
    619848   
    620849    int afree = audiofree(false);
    621850
    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));
     851    int abps = (encoder) ?
     852        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
     853
     854    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     855            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, "
     856                          "free=%4, timecode=%5 needsupmix %6")
     857            .arg(samples)
     858            .arg(samples * abps)
     859            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     860            .arg(needs_upmix));
    626861   
    627     len = WaitForFreeSpace(samples);
    628 
    629     if (interleaved)
     862    if (upmixer && needs_upmix)
    630863    {
    631         char *mybuf = (char*)buffer;
    632         int bdiff = AUDBUFSIZE - org_waud;
    633         if (bdiff < len)
     864        int out_samples = 0;
     865        int step = (interleaved)?source_audio_channels:1;
     866        len = WaitForFreeSpace(samples);    // test
     867        for (int itemp = 0; itemp < samples; )
    634868        {
    635             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    636             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     869            // just in case it does a processing cycle, release the lock
     870            // to allow the output loop to do output
     871            pthread_mutex_unlock(&audio_buflock);
     872            if (audio_bytes == 2)
     873            {
     874                itemp += upmixer->putSamples(
     875                    (short*)buffer + itemp * step,
     876                    samples - itemp,
     877                    source_audio_channels,
     878                    (interleaved) ? 0 : samples);
     879            }
     880            else
     881            {
     882                itemp += upmixer->putSamples(
     883                    (char*)buffer + itemp * step,
     884                    samples - itemp,
     885                    source_audio_channels,
     886                    (interleaved) ? 0 : samples);
     887            }
     888            pthread_mutex_lock(&audio_buflock);
     889
     890            int copy_samples = upmixer->numSamples();
     891            if (copy_samples)
     892            {
     893                int copy_len = copy_samples * abps;
     894                out_samples += copy_samples;
     895                if (out_samples > samples)
     896                    len = WaitForFreeSpace(out_samples);
     897                int bdiff = AUDBUFSIZE - org_waud;
     898                if (bdiff < copy_len)
     899                {
     900                    int bdiff_samples = bdiff/abps;
     901                    upmixer->receiveSamples(
     902                        (short*)(audiobuffer + org_waud), bdiff_samples);
     903                    upmixer->receiveSamples(
     904                        (short*)(audiobuffer), (copy_samples - bdiff_samples));
     905                }
     906                else
     907                {
     908                    upmixer->receiveSamples(
     909                        (short*)(audiobuffer + org_waud), copy_samples);
     910                }
     911                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     912            }
    637913        }
    638         else
    639             memcpy(audiobuffer + org_waud, mybuf, len);
    640  
    641         org_waud = (org_waud + len) % AUDBUFSIZE;
    642     }
    643     else
     914
     915        if (samples > 0)
     916            len = WaitForFreeSpace(out_samples);
     917
     918        samples = out_samples;
     919    }
     920    else
    644921    {
    645         char **mybuf = (char**)buffer;
    646         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     922        len = WaitForFreeSpace(samples);
     923
     924        if (interleaved)
    647925        {
    648             for (int chan = 0; chan < audio_channels; chan++)
     926            char *mybuf = (char*)buffer;
     927            int bdiff = AUDBUFSIZE - org_waud;
     928            if (bdiff < len)
    649929            {
    650                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    651                 if (audio_bits == 16)
    652                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     930                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     931                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     932            }
     933            else
     934            {
     935                memcpy(audiobuffer + org_waud, mybuf, len);
     936            }
     937     
     938            org_waud = (org_waud + len) % AUDBUFSIZE;
     939        }
     940        else
     941        {
     942            char **mybuf = (char**)buffer;
     943            for (int itemp = 0; itemp < samples * audio_bytes;
     944                 itemp += audio_bytes)
     945            {
     946                for (int chan = 0; chan < audio_channels; chan++)
     947                {
     948                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     949                    if (audio_bits == 16)
     950                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    653951
    654                 if (org_waud >= AUDBUFSIZE)
    655                     org_waud -= AUDBUFSIZE;
     952                    if (org_waud >= AUDBUFSIZE)
     953                        org_waud -= AUDBUFSIZE;
     954                }
    656955            }
    657956        }
    658957    }
    659958
    660     if (pSoundStretch)
     959    if (samples > 0)
    661960    {
    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)
     961        if (pSoundStretch)
    668962        {
    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         }
    679963
    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)
     964            // does not change the timecode, only the number of samples
     965            // back to orig pos
     966            org_waud = waud;
     967            int bdiff = AUDBUFSIZE - org_waud;
     968            int nSamplesToEnd = bdiff/abps;
     969            if (bdiff < len)
    688970            {
    689                 samplesToGet = nSamplesToEnd;   
     971                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     972                                          (audiobuffer +
     973                                           org_waud), nSamplesToEnd);
     974                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     975                                          (len - bdiff) / abps);
    690976            }
     977            else
     978            {
     979                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     980                                          (audiobuffer + org_waud),
     981                                          len / abps);
     982            }
    691983
    692             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    693                                       (audiobuffer + org_waud), samplesToGet);
    694             if (nSamples == nSamplesToEnd)
     984            if (encoder)
    695985            {
    696                 org_waud = 0;
    697                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     986                // pull out a packet's worth and reencode it until we
     987                // don't have enough for any more packets
     988                soundtouch::SAMPLETYPE *temp_buff =
     989                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     990                size_t frameSize = encoder->FrameSize()/abps;
     991
     992                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     993                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     994                        .arg(frameSize)
     995                        .arg(encoder->FrameSize())
     996                        .arg(pSoundStretch->numSamples()));
     997
     998                // process the same number of samples as it creates
     999                // a full encoded buffer just like before
     1000                while (pSoundStretch->numSamples() >= frameSize)
     1001                {
     1002                    int got = pSoundStretch->receiveSamples(
     1003                        temp_buff, frameSize);
     1004                    int amount = encoder->Encode(temp_buff);
     1005
     1006                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1007                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1008                            .arg(amount)
     1009                            .arg(got)
     1010                            .arg(pSoundStretch->numSamples()));
     1011
     1012                    if (!amount)
     1013                        continue;
     1014
     1015                    //len = WaitForFreeSpace(amount);
     1016                    char *ob = encoder->GetOutBuff();
     1017                    if (amount >= bdiff)
     1018                    {
     1019                        memcpy(audiobuffer + org_waud, ob, bdiff);
     1020                        ob += bdiff;
     1021                        amount -= bdiff;
     1022                        org_waud = 0;
     1023                    }
     1024                    if (amount > 0)
     1025                        memcpy(audiobuffer + org_waud, ob, amount);
     1026
     1027                    bdiff = AUDBUFSIZE - amount;
     1028                    org_waud += amount;
     1029                }
    6981030            }
    6991031            else
    7001032            {
    701                 org_waud += nSamples * audio_bytes_per_sample;
    702                 nSamplesToEnd -= nSamples;
     1033                int newLen = 0;
     1034                int nSamples;
     1035                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1036                                       audio_bytes_per_sample);
     1037                do
     1038                {
     1039                    int samplesToGet = len/audio_bytes_per_sample;
     1040                    if (samplesToGet > nSamplesToEnd)
     1041                    {
     1042                        samplesToGet = nSamplesToEnd;   
     1043                    }
     1044
     1045                    nSamples = pSoundStretch->receiveSamples(
     1046                        (soundtouch::SAMPLETYPE*)
     1047                        (audiobuffer + org_waud), samplesToGet);
     1048                    if (nSamples == nSamplesToEnd)
     1049                    {
     1050                        org_waud = 0;
     1051                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1052                    }
     1053                    else
     1054                    {
     1055                        org_waud += nSamples * audio_bytes_per_sample;
     1056                        nSamplesToEnd -= nSamples;
     1057                    }
     1058
     1059                    newLen += nSamples * audio_bytes_per_sample;
     1060                    len -= nSamples * audio_bytes_per_sample;
     1061                } while (nSamples > 0);
    7031062            }
     1063        }
    7041064
    705             newLen += nSamples * audio_bytes_per_sample;
    706             len -= nSamples * audio_bytes_per_sample;
    707         } while (nSamples > 0);
    708     }
     1065        waud = org_waud;
     1066        lastaudiolen = audiolen(false);
    7091067
    710     waud = org_waud;
    711     lastaudiolen = audiolen(false);
     1068        if (timecode < 0)
     1069        {
     1070            // mythmusic doesn't give timestamps..
     1071            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1072        }
     1073       
     1074        samples_buffered += samples;
     1075       
     1076        /* we want the time at the end -- but the file format stores
     1077           time at the start of the chunk. */
     1078        // even with timestretch, timecode is still calculated from original
     1079        // sample count
     1080        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7121081
    713     samples_buffered += samples;
    714    
    715     if (timecode < 0)
    716     {
    717         // mythmusic doesn't give timestamps..
    718         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1082        if (interleaved)
     1083        {
     1084            dispatchVisual((unsigned char *)buffer, len, timecode,
     1085                           source_audio_channels, audio_bits);
     1086        }
    7191087    }
    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);
    7261088
    727     if (interleaved)
    728         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    729 
    7301089    pthread_mutex_unlock(&audio_buflock);
    7311090}
    7321091
     
    7391098
    7401099    if (source_bitrate == -1)
    7411100    {
    742         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1101        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7431102    }
    7441103
    7451104    if (ct / 1000 != current_seconds)
     
    7471106        current_seconds = ct / 1000;
    7481107        OutputEvent e(current_seconds, ct,
    7491108                      source_bitrate, audio_samplerate, audio_bits,
    750                       audio_channels);
     1109                      source_audio_channels);
    7511110        dispatch(e);
    7521111    }
    7531112}
     
    7851144
    7861145            space_on_soundcard = getSpaceOnSoundcard();
    7871146
    788             if (space_on_soundcard != last_space_on_soundcard) {
    789                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1147            if (space_on_soundcard != last_space_on_soundcard)
     1148            {
     1149                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1150                        LOC + QString("%1 bytes free on soundcard")
    7901151                        .arg(space_on_soundcard));
     1152
    7911153                last_space_on_soundcard = space_on_soundcard;
    7921154            }
    7931155
     
    7991161                    WriteAudio(zeros, fragment_size);
    8001162                } else {
    8011163                    // this should never happen now -dag
    802                     VERBOSE(VB_AUDIO, LOC +
     1164                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031165                            QString("waiting for space on soundcard "
    8041166                                    "to write zeros: have %1 need %2")
    8051167                            .arg(space_on_soundcard).arg(fragment_size));
     
    8351197        if (fragment_size > audiolen(true))
    8361198        {
    8371199            if (audiolen(true) > 0)  // only log if we're sending some audio
    838                 VERBOSE(VB_AUDIO, LOC +
     1200                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8391201                        QString("audio waiting for buffer to fill: "
    8401202                                "have %1 want %2")
    8411203                        .arg(audiolen(true)).arg(fragment_size));
    8421204
    843             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1205            //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1206            //LOC + "Broadcasting free space avail");
    8441207            pthread_mutex_lock(&audio_buflock);
    8451208            pthread_cond_broadcast(&audio_bufsig);
    8461209            pthread_mutex_unlock(&audio_buflock);
     
    8541217        if (fragment_size > space_on_soundcard)
    8551218        {
    8561219            if (space_on_soundcard != last_space_on_soundcard) {
    857                 VERBOSE(VB_AUDIO, LOC +
     1220                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8581221                        QString("audio waiting for space on soundcard: "
    8591222                                "have %1 need %2")
    8601223                        .arg(space_on_soundcard).arg(fragment_size));
     
    9161279
    9171280        /* update raud */
    9181281        raud = (raud + fragment_size) % AUDBUFSIZE;
    919         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1282        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9201283        pthread_cond_broadcast(&audio_bufsig);
    9211284
    9221285        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 = real_device.find('|');
     56    if (index >= 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 =
     102            (audio_bits * audio_channels * audio_samplerate) / (8*30);
     103        buffer_time = 100000;
    94104        period_time = buffer_time / 4;  // 4 interrupts per buffer
    95105    }
    96106
     
    162172   
    163173    tmpbuf = aubuf;
    164174
    165     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     175    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     176            QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    166177            .arg(size).arg(frames));
    167178   
    168179    while (frames > 0)
  • programs/mythfrontend/globalsettings.cpp

     
    5656    }
    5757#endif
    5858#ifdef USING_ALSA
    59     gc->addSelection("ALSA:default", "ALSA:default");
     59    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(
     94                "Set the maximum number of audio channels to be decoded. "
     95                "This is for multi-channel/surround audio playback."));
     96    return gc;
     97}
     98
     99static HostComboBox *AudioUpmixType()
     100{
     101    HostComboBox *gc = new HostComboBox("AudioUpmixType",false);
     102    gc->setLabel(QObject::tr("Upmix"));
     103    gc->addSelection(QObject::tr("Passive"), "0");
     104    gc->addSelection(QObject::tr("Active Simple"), "1");
     105    gc->addSelection(QObject::tr("Active Linear"), "2", true); // default
     106    gc->setHelpText(
     107            QObject::tr(
     108                "Set the audio upmix type for 2ch to 6ch conversion. "
     109                "This is for multi-channel/surround audio playback."));
     110    return gc;
     111}
     112
    81113static HostComboBox *PassThroughOutputDevice()
    82114{
    83115    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31563188         vgrp0->addChild(AC3PassThrough());
    31573189         vgrp0->addChild(DTSPassThrough());
    31583190
     3191         HorizontalConfigurationGroup *agrp =
     3192             new HorizontalConfigurationGroup(false, false, true, true);
     3193         agrp->addChild(MaxAudioChannels());
     3194         agrp->addChild(AudioUpmixType());
     3195         addChild(agrp);
     3196
    31593197         VerticalConfigurationGroup *vgrp1 =
    31603198             new VerticalConfigurationGroup(false, false, true, true);
    31613199         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 *audio_codec = NULL)
    5960    {
     61        ClearError();
    6062        (void)audio_samplerate;
    6163        (void)audio_passthru;
     64        (void)audio_codec;
    6265        bits = audio_bits;
    6366        channels = audio_channels;
    6467        bytes_per_sample = bits * channels / 8;
     68        if ((uint)audio_channels > 2)
     69            Error(QString("Invalid channel count %1").arg(channels));
    6570    }
    6671
    6772    // 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    uint              max_channels;
     265
    264266    VideoFrame       *dummy_frame;
    265267
    266268    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);
     
    400397      // Audio
    401398      audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
    402399      allow_ac3_passthru(false),    allow_dts_passthru(false),
    403       disable_passthru(false),      dummy_frame(NULL),
     400      disable_passthru(false),      max_channels(2),
     401      dummy_frame(NULL),
    404402      // DVD
    405403      lastdvdtitle(-1), lastcellstart(0),
    406404      dvdmenupktseen(false), indvdstill(false),
     
    417415
    418416    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419417    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     418    max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
    420419
    421420    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422421    itv = GetNVP()->GetInteractiveTV();
     
    15871586                            <<") already open, leaving it alone.");
    15881587                }
    15891588                //assert(enc->codec_id);
     1589                VERBOSE(VB_GENERAL, LOC + QString("codec %1 has %2 channels")
     1590                        .arg(codec_id_string(enc->codec_id))
     1591                        .arg(enc->channels));
    15901592
     1593#if 0
     1594                // HACK MULTICHANNEL DTS passthru disabled for multichannel,
     1595                // dont know how to handle this
    15911596                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15921597                if (enc->codec_id == CODEC_ID_DTS)
    15931598                {
     
    15961601                    // enc->bit_rate = what??;
    15971602                }
    15981603                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1604#endif
    15991605
    16001606                bitrate += enc->bit_rate;
    16011607                break;
     
    32853291
    32863292                    // detect channels on streams that need
    32873293                    // to be decoded before we can know this
     3294                    int prev_channels = curstream->codec->channels;
     3295                    bool already_decoded = false;
    32883296                    if (!curstream->codec->channels)
    32893297                    {
    32903298                        QMutexLocker locker(&avcodeclock);
    3291                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3299                        VERBOSE(VB_IMPORTANT, LOC +
     3300                                QString("Setting channels to %1")
     3301                                .arg(audioOut.channels));
     3302
     3303                        curstream->codec->channels = audioOut.channels;
     3304                        curstream->codec->request_channels = audioOut.channels;
    32923305                        ret = avcodec_decode_audio(
    32933306                            curstream->codec, audioSamples,
    32943307                            &data_size, ptr, len);
     3308                        already_decoded = true;
    32953309
    32963310                        reselectAudioTrack |= curstream->codec->channels;
    32973311                    }
     
    33493363                        AVCodecContext *ctx = curstream->codec;
    33503364
    33513365                        if ((ctx->channels == 0) ||
    3352                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3353                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3366                            (ctx->channels > audioOut.channels))
     3367                            ctx->channels = audioOut.channels;
    33543368
    3355                         ret = avcodec_decode_audio(
    3356                             ctx, audioSamples, &data_size, ptr, len);
     3369                        if (!already_decoded)
     3370                        {
     3371                            curstream->codec->request_channels = audioOut.channels;
     3372                            ret = avcodec_decode_audio(
     3373                                ctx, audioSamples, &data_size, ptr, len);
     3374                        }
    33573375
    33583376                        // When decoding some audio streams the number of
    33593377                        // channels, etc isn't known until we try decoding it.
     
    37833801
    37843802void AvFormatDecoder::SetDisablePassThrough(bool disable)
    37853803{
     3804    // can only disable never reenable as once
     3805    // timestretch is on its on for the session
     3806    if (disable_passthru)
     3807        return;
     3808
    37863809    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    37873810    {
    37883811        disable_passthru = disable;
     
    38153838    AVCodecContext *codec_ctx = NULL;
    38163839    AudioInfo old_in  = audioIn;
    38173840    AudioInfo old_out = audioOut;
     3841    bool using_passthru = false;
    38183842
    38193843    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    38203844        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    38263850        assert(curstream->codec);
    38273851        codec_ctx = curstream->codec;       
    38283852        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3829                                 !disable_passthru &&
    38303853                                (codec_ctx->codec_id == CODEC_ID_AC3));
    38313854        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3832                                 !disable_passthru &&
    38333855                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3856        using_passthru = do_ac3_passthru || do_dts_passthru;
    38343857        info = AudioInfo(codec_ctx->codec_id,
    38353858                         codec_ctx->sample_rate, codec_ctx->channels,
    3836                          do_ac3_passthru || do_dts_passthru);
     3859                         using_passthru && !disable_passthru);
    38373860    }
    38383861
    38393862    if (info == audioIn)
    38403863        return false; // no change
    38413864
     3865    QString ptmsg = (using_passthru) ? " using passthru" : "";
    38423866    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    38433867            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    38443868
    38453869    audioOut = audioIn = info;
    3846     if (audioIn.do_passthru)
     3870    if (using_passthru)
    38473871    {
    38483872        // 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;
     3873        AudioInfo digInfo = audioOut;
     3874        if (!disable_passthru)
     3875        {
     3876            digInfo.channels    = 2;
     3877            digInfo.sample_rate = 48000;
     3878            digInfo.sample_size = 4;
     3879        }
     3880        if (audioOut.channels > (int) max_channels)
     3881        {
     3882            audioOut.channels = (int) max_channels;
     3883            audioOut.sample_size = audioOut.channels * 2;
     3884            codec_ctx->channels = audioOut.channels;
     3885        }
     3886        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3887                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3888                .arg(digInfo.toString())
     3889                .arg(old_in.toString()).arg(old_out.toString())
     3890                .arg(audioIn.toString()).arg(audioOut.toString()));
     3891
     3892        if (digInfo.sample_rate > 0)
     3893            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3894
     3895        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3896                                 digInfo.sample_rate, audioIn.do_passthru);
     3897        // allow the audio stuff to reencode
     3898        GetNVP()->SetAudioCodec(codec_ctx);
     3899        GetNVP()->ReinitAudio();
     3900        return true;
    38523901    }
    38533902    else
    38543903    {
    3855         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3904        if (audioOut.channels > (int) max_channels)
    38563905        {
    3857             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3906            audioOut.channels = (int) max_channels;
    38583907            audioOut.sample_size = audioOut.channels * 2;
    3859             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3908            codec_ctx->channels = audioOut.channels;
    38603909        }
    38613910    }
    38623911
     
    38713920    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    38723921                             audioOut.sample_rate,
    38733922                             audioIn.do_passthru);
    3874     GetNVP()->ReinitAudio();
    38753923
     3924    // allow the audio stuff to reencode
     3925    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3926    QString errMsg = GetNVP()->ReinitAudio();
     3927    bool audiook = errMsg.isEmpty();
     3928
    38763929    return true;
    38773930}
    38783931
  • 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) {