Ticket #1104: mythtv_ac3.44.patch

File mythtv_ac3.44.patch, 59.6 KB (added by danielk, 16 years ago)

Updatd patch

  • 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);
     
    36503652    audio_passthru = passthru;
    36513653}
    36523654
     3655void NuppelVideoPlayer::SetAudioCodec(void *ac)
     3656{
     3657    audio_codec = ac;
     3658}
     3659
    36533660void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36543661{
    36553662    if (audioOutput)
  • 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;
     
    32883294                    if (!curstream->codec->channels)
    32893295                    {
    32903296                        QMutexLocker locker(&avcodeclock);
    3291                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3297                        VERBOSE(VB_IMPORTANT, LOC +
     3298                                QString("Setting channels to %1")
     3299                                .arg(audioOut.channels));
     3300
     3301                        curstream->codec->channels = audioOut.channels;
    32923302                        ret = avcodec_decode_audio(
    32933303                            curstream->codec, audioSamples,
    32943304                            &data_size, ptr, len);
     
    33493359                        AVCodecContext *ctx = curstream->codec;
    33503360
    33513361                        if ((ctx->channels == 0) ||
    3352                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3353                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3362                            (ctx->channels > audioOut.channels))
     3363                            ctx->channels = audioOut.channels;
    33543364
    33553365                        ret = avcodec_decode_audio(
    33563366                            ctx, audioSamples, &data_size, ptr, len);
     
    37833793
    37843794void AvFormatDecoder::SetDisablePassThrough(bool disable)
    37853795{
     3796    // can only disable never reenable as once
     3797    // timestretch is on its on for the session
     3798    if (disable_passthru)
     3799        return;
     3800
    37863801    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    37873802    {
    37883803        disable_passthru = disable;
     
    38153830    AVCodecContext *codec_ctx = NULL;
    38163831    AudioInfo old_in  = audioIn;
    38173832    AudioInfo old_out = audioOut;
     3833    bool using_passthru = false;
    38183834
    38193835    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    38203836        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    38263842        assert(curstream->codec);
    38273843        codec_ctx = curstream->codec;       
    38283844        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3829                                 !disable_passthru &&
    38303845                                (codec_ctx->codec_id == CODEC_ID_AC3));
    38313846        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3832                                 !disable_passthru &&
    38333847                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3848        using_passthru = do_ac3_passthru || do_dts_passthru;
    38343849        info = AudioInfo(codec_ctx->codec_id,
    38353850                         codec_ctx->sample_rate, codec_ctx->channels,
    3836                          do_ac3_passthru || do_dts_passthru);
     3851                         using_passthru && !disable_passthru);
    38373852    }
    38383853
    38393854    if (info == audioIn)
    38403855        return false; // no change
    38413856
     3857    QString ptmsg = (using_passthru) ? " using passthru" : "";
    38423858    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    38433859            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    38443860
    38453861    audioOut = audioIn = info;
    3846     if (audioIn.do_passthru)
     3862    if (using_passthru)
    38473863    {
    38483864        // 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;
     3865        AudioInfo digInfo = audioOut;
     3866        if (!disable_passthru)
     3867        {
     3868            digInfo.channels    = 2;
     3869            digInfo.sample_rate = 48000;
     3870            digInfo.sample_size = 4;
     3871        }
     3872        if (audioOut.channels > (int) max_channels)
     3873        {
     3874            audioOut.channels = (int) max_channels;
     3875            audioOut.sample_size = audioOut.channels * 2;
     3876            codec_ctx->channels = audioOut.channels;
     3877        }
     3878        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3879                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3880                .arg(digInfo.toString())
     3881                .arg(old_in.toString()).arg(old_out.toString())
     3882                .arg(audioIn.toString()).arg(audioOut.toString()));
     3883
     3884        if (digInfo.sample_rate > 0)
     3885            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3886
     3887        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3888                                 digInfo.sample_rate, audioIn.do_passthru);
     3889        // allow the audio stuff to reencode
     3890        GetNVP()->SetAudioCodec(codec_ctx);
     3891        GetNVP()->ReinitAudio();
     3892        return true;
    38523893    }
    38533894    else
    38543895    {
    3855         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3896        if (audioOut.channels > (int) max_channels)
    38563897        {
    3857             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3898            audioOut.channels = (int) max_channels;
    38583899            audioOut.sample_size = audioOut.channels * 2;
    3859             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3900            codec_ctx->channels = audioOut.channels;
    38603901        }
    38613902    }
    38623903
     
    38713912    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    38723913                             audioOut.sample_rate,
    38733914                             audioIn.do_passthru);
    3874     GetNVP()->ReinitAudio();
    38753915
     3916    // allow the audio stuff to reencode
     3917    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3918    QString errMsg = GetNVP()->ReinitAudio();
     3919    bool audiook = errMsg.isEmpty();
     3920
    38763921    return true;
    38773922}
    38783923
  • 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/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/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/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
     
    177352                    /* update codec info */
    178353                    avctx->sample_rate = sample_rate;
    179354                    s->channels = ac3_channels[s->flags & 7];
     355                    if (avctx->cqp >= 0)
     356                        avctx->channels = avctx->cqp;
    180357                    if (s->flags & A52_LFE)
    181358                        s->channels++;
    182359                    if (avctx->channels == 0)
     
    199376            s->inbuf_ptr += len;
    200377            buf_size -= len;
    201378        } else {
     379            int chans;
    202380            flags = s->flags;
    203381            if (avctx->channels == 1)
    204382                flags = A52_MONO;
    205             else if (avctx->channels == 2)
    206                 flags = A52_STEREO;
     383            else if (avctx->channels == 2) {
     384                if (s->channels>2)
     385                    flags = A52_DOLBY;
     386                else
     387                    flags = A52_STEREO;
     388            }
    207389            else
    208390                flags |= A52_ADJUST_LEVEL;
    209391            level = 1;
     392            chans = channels_multi(flags);
    210393            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    211394            fail:
    212395                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    217400            for (i = 0; i < 6; i++) {
    218401                if (s->a52_block(s->state))
    219402                    goto fail;
    220                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     403                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    221404            }
    222405            s->inbuf_ptr = s->inbuf;
    223406            s->frame_size = 0;
  • 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/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)
  • 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{
     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
    140224    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     225        laudio_samplerate == audio_samplerate && !need_resampler &&
     226        laudio_passthru == audio_passthru &&
     227        lneeds_upmix == needs_upmix &&
     228        lcodec_id == codec_id && lcchannels == cchannels)
     229    {
     230        VERBOSE(VB_AUDIO,LOC + "no change exiting");
    143231        return;
     232    }
    144233
    145234    KillAudio();
    146235   
     
    151240    waud = raud = 0;
    152241    audio_actually_paused = false;
    153242   
     243    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154244    audio_channels = laudio_channels;
     245    source_audio_channels = lsource_audio_channels;
    155246    audio_bits = laudio_bits;
    156247    audio_samplerate = laudio_samplerate;
     248    audio_codec = (AVCodecContext*)laudio_codec;
    157249    audio_passthru = laudio_passthru;
     250    needs_upmix = lneeds_upmix;
     251
    158252    if (audio_bits != 8 && audio_bits != 16)
    159253    {
    160254        pthread_mutex_unlock(&avsync_lock);
     
    162256        Error("AudioOutput only supports 8 or 16bit audio.");
    163257        return;
    164258    }
     259
    165260    audio_bytes_per_sample = audio_channels * audio_bits / 8;
     261    source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;
    166262   
    167263    need_resampler = false;
    168264    killaudio = false;
     
    172268   
    173269    numlowbuffer = 0;
    174270
     271    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4")
     272            .arg(audio_main_device).arg(audio_channels)
     273            .arg(source_audio_channels).arg(audio_samplerate));
     274 
    175275    // Actually do the device specific open call
    176276    if (!OpenDevice())
    177277    {
    178278        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179279        pthread_mutex_unlock(&avsync_lock);
    180280        pthread_mutex_unlock(&audio_buflock);
     281        if (GetError().isEmpty())
     282            Error("Aborting reconfigure");
     283        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181284        return;
    182285    }
    183286
     
    200303    current_seconds = -1;
    201304    source_bitrate = -1;
    202305
     306    // NOTE: this won't do anything as above samplerate vars are set equal
    203307    // Check if we need the resampler
    204308    if (audio_samplerate != laudio_samplerate)
    205309    {
     
    222326        need_resampler = true;
    223327    }
    224328
     329    if (needs_upmix)
     330    {
     331        VERBOSE(VB_AUDIO, LOC + QString("create upmixer"));
     332        if (configured_audio_channels == 6)
     333        {
     334            surround_mode = gContext->GetNumSetting("AudioUpmixType", 2);
     335        }
     336
     337        upmixer = new FreeSurround(
     338            audio_samplerate,
     339            source == AUDIOOUTPUT_VIDEO,
     340            (FreeSurround::SurroundMode)surround_mode);
     341
     342        VERBOSE(VB_AUDIO, LOC +
     343                QString("create upmixer done with surround mode %1")
     344                .arg(surround_mode));
     345    }
     346
    225347    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226348            .arg(audio_stretchfactor));
     349    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     350            .arg((audio_codec) ?
     351                 codec_id_string(audio_codec->codec_id) : "not set"));
    227352
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     353    if (redo_stretch)
    230354    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     355        float laudio_stretchfactor = audio_stretchfactor;
     356        delete pSoundStretch;
     357        pSoundStretch = NULL;
     358        audio_stretchfactor = 0.0f;
     359        SetStretchFactorLocked(laudio_stretchfactor);
    233360    }
     361    else
     362    {
     363        SetStretchFactorLocked(audio_stretchfactor);
     364        if (pSoundStretch)
     365        {
     366            // if its passthru then we need to reencode
     367            if (audio_codec)
     368            {
     369                if (!encoder)
     370                {
     371                    VERBOSE(VB_AUDIO, LOC +
     372                            QString("Creating Encoder for codec %1")
     373                            .arg(audio_codec->codec_id));
    234374
     375                    encoder = new AudioOutputDigitalEncoder();
     376                    if (!encoder->Init(audio_codec->codec_id,
     377                                audio_codec->bit_rate,
     378                                audio_codec->sample_rate,
     379                                audio_codec->channels
     380                                ))
     381                    {
     382                        // eeks
     383                        delete encoder;
     384                        encoder = NULL;
     385                        VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");
     386                    }
     387                }
     388            }
     389            if (encoder)
     390            {
     391                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     392                pSoundStretch->setChannels(audio_codec->channels);
     393            }
     394            else
     395            {
     396                pSoundStretch->setSampleRate(audio_samplerate);
     397                pSoundStretch->setChannels(audio_channels);
     398            }
     399        }
     400    }
     401
    235402    // Setup visualisations, zero the visualisations buffers
    236403    prepareVisuals();
    237404
     
    290457        pSoundStretch = NULL;
    291458    }
    292459
     460    if (encoder)
     461    {
     462        delete encoder;
     463        encoder = NULL;
     464    }
     465
     466    if (upmixer)
     467    {
     468        delete upmixer;
     469        upmixer = NULL;
     470    }
     471    needs_upmix = false;
     472
    293473    CloseDevice();
    294474
    295475    killAudioLock.unlock();
     
    303483
    304484void AudioOutputBase::Pause(bool paused)
    305485{
     486    VERBOSE(VB_AUDIO, LOC + QString("Pause %0").arg(paused));
    306487    pauseaudio = paused;
    307488    audio_actually_paused = false;
    308489}
     
    385566       The reason is that computing 'audiotime' requires acquiring the audio
    386567       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387568       from the audio thread, and then call this from the video thread. */
    388     int ret;
     569    long long ret;
    389570    struct timeval now;
    390571
    391572    if (audiotime == 0)
     
    397578
    398579    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399580    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     581    ret = (long long)(ret * audio_stretchfactor);
    401582
     583#if 1
     584    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     585            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     586            .arg(now.tv_sec).arg(now.tv_usec)
     587            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     588            .arg(ret)
     589            .arg(audiotime)
     590            .arg(audio_stretchfactor)
     591           );
     592#endif
     593
    402594    ret += audiotime;
    403595
    404596    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     597    return (int)ret;
    406598}
    407599
    408600void AudioOutputBase::SetAudiotime(void)
     
    439631    // include algorithmic latencies
    440632    if (pSoundStretch)
    441633    {
     634        // add the effect of any unused but processed samples,
     635        // AC3 reencode does this
     636        totalbuffer += (int)(pSoundStretch->numSamples() *
     637                             audio_bytes_per_sample);
    442638        // add the effect of unprocessed samples in time stretch algo
    443639        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444640                              audio_bytes_per_sample) / audio_stretchfactor);
    445641    }
    446                
     642
     643    if (upmixer && needs_upmix)
     644    {
     645        totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample;
     646    }
     647
    447648    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448649                                   (audio_bytes_per_sample * effdspstretched));
    449650 
    450651    gettimeofday(&audiotime_updated, NULL);
     652#if 1
     653    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     654            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 "
     655                    "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     656            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     657            .arg(audiotime)
     658            .arg(audbuf_timecode)
     659            .arg(totalbuffer)
     660            .arg(soundcard_buffer)
     661            .arg(effdspstretched)
     662            .arg(audio_bytes_per_sample)
     663            .arg(audio_stretchfactor)
     664           );
     665#endif
    451666
    452667    pthread_mutex_unlock(&avsync_lock);
    453668    pthread_mutex_unlock(&audio_buflock);
     
    458673{
    459674    // NOTE: This function is not threadsafe
    460675    int afree = audiofree(true);
    461     int abps = audio_bytes_per_sample;
     676    int abps = (encoder) ?
     677        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    462678    int len = samples * abps;
    463679
    464680    // Check we have enough space to write the data
    465681    if (need_resampler && src_ctx)
    466682        len = (int)ceilf(float(len) * src_data.src_ratio);
    467683
     684    // include samples in upmix buffer that may be flushed
     685    if (needs_upmix && upmixer)
     686        len += upmixer->numUnprocessedSamples() * abps;
     687
    468688    if (pSoundStretch)
    469689        len += (pSoundStretch->numUnprocessedSamples() +
    470690                (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps;
     
    520740    // NOTE: This function is not threadsafe
    521741
    522742    int afree = audiofree(true);
    523     int abps = audio_bytes_per_sample;
     743    int abps = (encoder) ?
     744        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
    524745    int len = samples * abps;
    525746
    526747    // Check we have enough space to write the data
    527748    if (need_resampler && src_ctx)
    528749        len = (int)ceilf(float(len) * src_data.src_ratio);
    529750
     751    // include samples in upmix buffer that may be flushed
     752    if (needs_upmix && upmixer)
     753        len += upmixer->numUnprocessedSamples() * abps;
     754 
    530755    if (pSoundStretch)
    531756    {
    532757        len += (pSoundStretch->numUnprocessedSamples() +
     
    575800
    576801int AudioOutputBase::WaitForFreeSpace(int samples)
    577802{
    578     int len = samples * audio_bytes_per_sample;
     803    int abps = (encoder) ?
     804        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
     805    int len = samples * abps;
    579806    int afree = audiofree(false);
    580807
    581808    while (len > afree)
    582809    {
    583810        if (blocking)
    584811        {
    585             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     812            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    586813                    QString("(need %1, available %2)").arg(len).arg(afree));
    587814
    588815            // wait for more space
     
    591818        }
    592819        else
    593820        {
    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;
     821            VERBOSE(VB_IMPORTANT, LOC_ERR +
     822                    QString("Audio buffer overflow, %1 audio samples lost!")
     823                    .arg(samples - (afree / abps)));
     824            samples = afree / abps;
     825            len = samples * abps;
    598826            if (src_ctx)
    599827            {
    600828                int error = src_reset(src_ctx);
     
    619847   
    620848    int afree = audiofree(false);
    621849
    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));
     850    int abps = (encoder) ?
     851        encoder->audio_bytes_per_sample : audio_bytes_per_sample;
     852
     853    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     854            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, "
     855                          "free=%4, timecode=%5 needsupmix %6")
     856            .arg(samples)
     857            .arg(samples * abps)
     858            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode)
     859            .arg(needs_upmix));
    626860   
    627     len = WaitForFreeSpace(samples);
    628 
    629     if (interleaved)
     861    if (upmixer && needs_upmix)
    630862    {
    631         char *mybuf = (char*)buffer;
    632         int bdiff = AUDBUFSIZE - org_waud;
    633         if (bdiff < len)
     863        int out_samples = 0;
     864        int step = (interleaved)?source_audio_channels:1;
     865        len = WaitForFreeSpace(samples);    // test
     866        for (int itemp = 0; itemp < samples; )
    634867        {
    635             memcpy(audiobuffer + org_waud, mybuf, bdiff);
    636             memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     868            // just in case it does a processing cycle, release the lock
     869            // to allow the output loop to do output
     870            pthread_mutex_unlock(&audio_buflock);
     871            if (audio_bytes == 2)
     872            {
     873                itemp += upmixer->putSamples(
     874                    (short*)buffer + itemp * step,
     875                    samples - itemp,
     876                    source_audio_channels,
     877                    (interleaved) ? 0 : samples);
     878            }
     879            else
     880            {
     881                itemp += upmixer->putSamples(
     882                    (char*)buffer + itemp * step,
     883                    samples - itemp,
     884                    source_audio_channels,
     885                    (interleaved) ? 0 : samples);
     886            }
     887            pthread_mutex_lock(&audio_buflock);
     888
     889            int copy_samples = upmixer->numSamples();
     890            if (copy_samples)
     891            {
     892                int copy_len = copy_samples * abps;
     893                out_samples += copy_samples;
     894                if (out_samples > samples)
     895                    len = WaitForFreeSpace(out_samples);
     896                int bdiff = AUDBUFSIZE - org_waud;
     897                if (bdiff < copy_len)
     898                {
     899                    int bdiff_samples = bdiff/abps;
     900                    upmixer->receiveSamples(
     901                        (short*)(audiobuffer + org_waud), bdiff_samples);
     902                    upmixer->receiveSamples(
     903                        (short*)(audiobuffer), (copy_samples - bdiff_samples));
     904                }
     905                else
     906                {
     907                    upmixer->receiveSamples(
     908                        (short*)(audiobuffer + org_waud), copy_samples);
     909                }
     910                org_waud = (org_waud + copy_len) % AUDBUFSIZE;
     911            }
    637912        }
    638         else
    639             memcpy(audiobuffer + org_waud, mybuf, len);
    640  
    641         org_waud = (org_waud + len) % AUDBUFSIZE;
    642     }
    643     else
     913
     914        if (samples > 0)
     915            len = WaitForFreeSpace(out_samples);
     916
     917        samples = out_samples;
     918    }
     919    else
    644920    {
    645         char **mybuf = (char**)buffer;
    646         for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes)
     921        len = WaitForFreeSpace(samples);
     922
     923        if (interleaved)
    647924        {
    648             for (int chan = 0; chan < audio_channels; chan++)
     925            char *mybuf = (char*)buffer;
     926            int bdiff = AUDBUFSIZE - org_waud;
     927            if (bdiff < len)
    649928            {
    650                 audiobuffer[org_waud++] = mybuf[chan][itemp];
    651                 if (audio_bits == 16)
    652                     audiobuffer[org_waud++] = mybuf[chan][itemp+1];
     929                memcpy(audiobuffer + org_waud, mybuf, bdiff);
     930                memcpy(audiobuffer, mybuf + bdiff, len - bdiff);
     931            }
     932            else
     933            {
     934                memcpy(audiobuffer + org_waud, mybuf, len);
     935            }
     936     
     937            org_waud = (org_waud + len) % AUDBUFSIZE;
     938        }
     939        else
     940        {
     941            char **mybuf = (char**)buffer;
     942            for (int itemp = 0; itemp < samples * audio_bytes;
     943                 itemp += audio_bytes)
     944            {
     945                for (int chan = 0; chan < audio_channels; chan++)
     946                {
     947                    audiobuffer[org_waud++] = mybuf[chan][itemp];
     948                    if (audio_bits == 16)
     949                        audiobuffer[org_waud++] = mybuf[chan][itemp+1];
    653950
    654                 if (org_waud >= AUDBUFSIZE)
    655                     org_waud -= AUDBUFSIZE;
     951                    if (org_waud >= AUDBUFSIZE)
     952                        org_waud -= AUDBUFSIZE;
     953                }
    656954            }
    657955        }
    658956    }
    659957
    660     if (pSoundStretch)
     958    if (samples > 0)
    661959    {
    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)
     960        if (pSoundStretch)
    668961        {
    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         }
    679962
    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)
     963            // does not change the timecode, only the number of samples
     964            // back to orig pos
     965            org_waud = waud;
     966            int bdiff = AUDBUFSIZE - org_waud;
     967            int nSamplesToEnd = bdiff/abps;
     968            if (bdiff < len)
    688969            {
    689                 samplesToGet = nSamplesToEnd;   
     970                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     971                                          (audiobuffer +
     972                                           org_waud), nSamplesToEnd);
     973                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
     974                                          (len - bdiff) / abps);
    690975            }
     976            else
     977            {
     978                pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)
     979                                          (audiobuffer + org_waud),
     980                                          len / abps);
     981            }
    691982
    692             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    693                                       (audiobuffer + org_waud), samplesToGet);
    694             if (nSamples == nSamplesToEnd)
     983            if (encoder)
    695984            {
    696                 org_waud = 0;
    697                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     985                // pull out a packet's worth and reencode it until we
     986                // don't have enough for any more packets
     987                soundtouch::SAMPLETYPE *temp_buff =
     988                    (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     989                size_t frameSize = encoder->FrameSize()/abps;
     990
     991                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     992                        QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     993                        .arg(frameSize)
     994                        .arg(encoder->FrameSize())
     995                        .arg(pSoundStretch->numSamples()));
     996
     997                // process the same number of samples as it creates
     998                // a full encoded buffer just like before
     999                while (pSoundStretch->numSamples() >= frameSize)
     1000                {
     1001                    int got = pSoundStretch->receiveSamples(
     1002                        temp_buff, frameSize);
     1003                    int amount = encoder->Encode(temp_buff);
     1004
     1005                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1006                            QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1007                            .arg(amount)
     1008                            .arg(got)
     1009                            .arg(pSoundStretch->numSamples()));
     1010
     1011                    if (!amount)
     1012                        continue;
     1013
     1014                    //len = WaitForFreeSpace(amount);
     1015                    char *ob = encoder->GetOutBuff();
     1016                    if (amount >= bdiff)
     1017                    {
     1018                        memcpy(audiobuffer + org_waud, ob, bdiff);
     1019                        ob += bdiff;
     1020                        amount -= bdiff;
     1021                        org_waud = 0;
     1022                    }
     1023                    if (amount > 0)
     1024                        memcpy(audiobuffer + org_waud, ob, amount);
     1025
     1026                    bdiff = AUDBUFSIZE - amount;
     1027                    org_waud += amount;
     1028                }
    6981029            }
    6991030            else
    7001031            {
    701                 org_waud += nSamples * audio_bytes_per_sample;
    702                 nSamplesToEnd -= nSamples;
     1032                int newLen = 0;
     1033                int nSamples;
     1034                len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1035                                       audio_bytes_per_sample);
     1036                do
     1037                {
     1038                    int samplesToGet = len/audio_bytes_per_sample;
     1039                    if (samplesToGet > nSamplesToEnd)
     1040                    {
     1041                        samplesToGet = nSamplesToEnd;   
     1042                    }
     1043
     1044                    nSamples = pSoundStretch->receiveSamples(
     1045                        (soundtouch::SAMPLETYPE*)
     1046                        (audiobuffer + org_waud), samplesToGet);
     1047                    if (nSamples == nSamplesToEnd)
     1048                    {
     1049                        org_waud = 0;
     1050                        nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1051                    }
     1052                    else
     1053                    {
     1054                        org_waud += nSamples * audio_bytes_per_sample;
     1055                        nSamplesToEnd -= nSamples;
     1056                    }
     1057
     1058                    newLen += nSamples * audio_bytes_per_sample;
     1059                    len -= nSamples * audio_bytes_per_sample;
     1060                } while (nSamples > 0);
    7031061            }
     1062        }
    7041063
    705             newLen += nSamples * audio_bytes_per_sample;
    706             len -= nSamples * audio_bytes_per_sample;
    707         } while (nSamples > 0);
    708     }
     1064        waud = org_waud;
     1065        lastaudiolen = audiolen(false);
    7091066
    710     waud = org_waud;
    711     lastaudiolen = audiolen(false);
     1067        if (timecode < 0)
     1068        {
     1069            // mythmusic doesn't give timestamps..
     1070            timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1071        }
     1072       
     1073        samples_buffered += samples;
     1074       
     1075        /* we want the time at the end -- but the file format stores
     1076           time at the start of the chunk. */
     1077        // even with timestretch, timecode is still calculated from original
     1078        // sample count
     1079        audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);
    7121080
    713     samples_buffered += samples;
    714    
    715     if (timecode < 0)
    716     {
    717         // mythmusic doesn't give timestamps..
    718         timecode = (int)((samples_buffered * 100000.0) / effdsp);
     1081        if (interleaved)
     1082        {
     1083            dispatchVisual((unsigned char *)buffer, len, timecode,
     1084                           source_audio_channels, audio_bits);
     1085        }
    7191086    }
    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);
    7261087
    727     if (interleaved)
    728         dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);
    729 
    7301088    pthread_mutex_unlock(&audio_buflock);
    7311089}
    7321090
     
    7391097
    7401098    if (source_bitrate == -1)
    7411099    {
    742         source_bitrate = audio_samplerate * audio_channels * audio_bits;
     1100        source_bitrate = audio_samplerate * source_audio_channels * audio_bits;
    7431101    }
    7441102
    7451103    if (ct / 1000 != current_seconds)
     
    7471105        current_seconds = ct / 1000;
    7481106        OutputEvent e(current_seconds, ct,
    7491107                      source_bitrate, audio_samplerate, audio_bits,
    750                       audio_channels);
     1108                      source_audio_channels);
    7511109        dispatch(e);
    7521110    }
    7531111}
     
    7851143
    7861144            space_on_soundcard = getSpaceOnSoundcard();
    7871145
    788             if (space_on_soundcard != last_space_on_soundcard) {
    789                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1146            if (space_on_soundcard != last_space_on_soundcard)
     1147            {
     1148                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1149                        LOC + QString("%1 bytes free on soundcard")
    7901150                        .arg(space_on_soundcard));
     1151
    7911152                last_space_on_soundcard = space_on_soundcard;
    7921153            }
    7931154
     
    7991160                    WriteAudio(zeros, fragment_size);
    8001161                } else {
    8011162                    // this should never happen now -dag
    802                     VERBOSE(VB_AUDIO, LOC +
     1163                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031164                            QString("waiting for space on soundcard "
    8041165                                    "to write zeros: have %1 need %2")
    8051166                            .arg(space_on_soundcard).arg(fragment_size));
     
    8351196        if (fragment_size > audiolen(true))
    8361197        {
    8371198            if (audiolen(true) > 0)  // only log if we're sending some audio
    838                 VERBOSE(VB_AUDIO, LOC +
     1199                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8391200                        QString("audio waiting for buffer to fill: "
    8401201                                "have %1 want %2")
    8411202                        .arg(audiolen(true)).arg(fragment_size));
    8421203
    843             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1204            //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1205            //LOC + "Broadcasting free space avail");
    8441206            pthread_mutex_lock(&audio_buflock);
    8451207            pthread_cond_broadcast(&audio_bufsig);
    8461208            pthread_mutex_unlock(&audio_buflock);
     
    8541216        if (fragment_size > space_on_soundcard)
    8551217        {
    8561218            if (space_on_soundcard != last_space_on_soundcard) {
    857                 VERBOSE(VB_AUDIO, LOC +
     1219                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8581220                        QString("audio waiting for space on soundcard: "
    8591221                                "have %1 need %2")
    8601222                        .arg(space_on_soundcard).arg(fragment_size));
     
    9161278
    9171279        /* update raud */
    9181280        raud = (raud + fragment_size) % AUDBUFSIZE;
    919         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1281        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9201282        pthread_cond_broadcast(&audio_bufsig);
    9211283
    9221284        written_size = fragment_size;
  • 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/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/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);
  • 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