Ticket #1104: mythtv_ac3.32.patch

File mythtv_ac3.32.patch, 57.8 KB (added by Mark Spieth, 16 years ago)
  • (a) dummyemptyfile vs. (b) libs/libmyth/audiooutputdigitalencoder.cpp

    a b  
     1// Std C headers
     2#include <cstdio>
     3
     4// libav headers
     5extern "C" {
     6#include "libavcodec/avcodec.h"
     7#ifdef ENABLE_AC3_DECODER
     8#include "libavcodec/parser.h"
     9#else
     10#include <a52dec/a52.h>
     11#endif
     12}
     13
     14// MythTV headers
     15#include "config.h"
     16#include "mythcontext.h"
     17#include "audiooutputdigitalencoder.h"
     18#include "compat.h"
     19
     20#define LOC QString("DEnc: ");
     21
     22#define MAX_AC3_FRAME_SIZE 6144
     23
     24AudioOutputDigitalEncoder::AudioOutputDigitalEncoder()
     25{
     26    av_context = NULL;
     27    outbuf = NULL;
     28    outbuf_size = 0;
     29    one_frame_bytes = 0;
     30    frame_buffer = NULL;
     31}
     32
     33AudioOutputDigitalEncoder::~AudioOutputDigitalEncoder()
     34{
     35    Dispose();
     36}
     37
     38void AudioOutputDigitalEncoder::Dispose()
     39{
     40    if (av_context)
     41    {
     42        avcodec_close(av_context);
     43        av_free(av_context);
     44        av_context = NULL;
     45    }
     46    if (outbuf)
     47    {
     48        delete [] outbuf;
     49        outbuf = NULL;
     50        outbuf_size = 0;
     51    }
     52    if (frame_buffer)
     53    {
     54        delete [] frame_buffer;
     55        frame_buffer = NULL;
     56        one_frame_bytes = 0;
     57    }
     58}
     59
     60//CODEC_ID_AC3
     61bool AudioOutputDigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     62{
     63    AVCodec * codec;
     64    int ret;
     65
     66    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     67            .arg(codec_id_string(codec_id))
     68            .arg(bitrate)
     69            .arg(samplerate)
     70            .arg(channels));
     71    //codec = avcodec_find_encoder(codec_id);
     72    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     73    codec = avcodec_find_encoder(CODEC_ID_AC3);
     74    if (!codec)
     75    {
     76        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     77        return false;
     78    }
     79    av_context = avcodec_alloc_context();
     80    av_context->bit_rate = bitrate;
     81    av_context->sample_rate = samplerate;
     82    av_context->channels = channels;
     83    // open it */
     84    if ((ret = avcodec_open(av_context, codec)) < 0)
     85    {
     86        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     87        Dispose();
     88        return false;
     89    }
     90
     91    size_t bytes_per_frame = av_context->channels * sizeof(short);
     92    audio_bytes_per_sample = bytes_per_frame;
     93    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     94
     95    outbuf_size = 16384;    // ok for AC3 but DTS?
     96    outbuf = new char [outbuf_size];
     97    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     98            .arg(av_context->frame_size)
     99            .arg(bytes_per_frame)
     100            .arg(one_frame_bytes)
     101           );
     102
     103    return true;
     104}
     105
     106static int DTS_SAMPLEFREQS[16] =
     107{
     108    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     109    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     110};
     111
     112static int DTS_BITRATES[30] =
     113{
     114    32000,    56000,    64000,    96000,    112000,   128000,
     115    192000,   224000,   256000,   320000,   384000,   448000,
     116    512000,   576000,   640000,   768000,   896000,   1024000,
     117    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     118    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     119};
     120
     121static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     122                             int *nblks, int *sfreq)
     123{
     124    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     125               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     126
     127    if (id != 0x7ffe8001)
     128        return -1;
     129
     130    int ftype = indata_ptr[4] >> 7;
     131
     132    int surp = (indata_ptr[4] >> 2) & 0x1f;
     133    surp = (surp + 1) % 32;
     134
     135    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     136    ++*nblks;
     137
     138    int fsize = (indata_ptr[5] & 0x03) << 12 |
     139                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     140    ++fsize;
     141
     142    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     143    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     144
     145    if (ftype != 1)
     146    {
     147        VERBOSE(VB_IMPORTANT, LOC +
     148                QString("DTS: Termination frames not handled (ftype %1)")
     149                .arg(ftype));
     150        return -1;
     151    }
     152
     153    if (*sfreq != 13)
     154    {
     155        VERBOSE(VB_IMPORTANT, LOC +
     156                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     157        return -1;
     158    }
     159
     160    if ((fsize > 8192) || (fsize < 96))
     161    {
     162        VERBOSE(VB_IMPORTANT, LOC +
     163                QString("DTS: fsize: %1 invalid").arg(fsize));
     164        return -1;
     165    }
     166
     167    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     168        *nblks != 64 && *nblks != 128 && ftype == 1)
     169    {
     170        VERBOSE(VB_IMPORTANT, LOC +
     171                QString("DTS: nblks %1 not valid for normal frame")
     172                .arg(*nblks));
     173        return -1;
     174    }
     175
     176    return fsize;
     177}
     178
     179static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     180                        int *sample_rate, int *bit_rate)
     181{
     182    int nblks;
     183    int rate;
     184    int sfreq;
     185
     186    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     187    if (fsize >= 0)
     188    {
     189        if (rate >= 0 && rate <= 29)
     190            *bit_rate = DTS_BITRATES[rate];
     191        else
     192            *bit_rate = 0;
     193        if (sfreq >= 1 && sfreq <= 15)
     194            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     195        else
     196            *sample_rate = 0;
     197    }
     198    return fsize;
     199}
     200
     201// until there is an easy way to do this with ffmpeg
     202// get the code from libavcodec/parser.c made non static
     203extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
     204                            int *bit_rate, int *samples);
     205
     206static int encode_frame(
     207        bool dts,
     208        unsigned char *data,
     209        size_t &len)
     210{
     211    size_t enc_len;
     212    int flags, sample_rate, bit_rate;
     213
     214    // we don't do any length/crc validation of the AC3 frame here; presumably
     215    // the receiver will have enough sense to do that.  if someone has a
     216    // receiver that doesn't, here would be a good place to put in a call
     217    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     218    // packet is bad?  we'd need to send something that the receiver would
     219    // ignore, and if so, may as well just assume that it will ignore
     220    // anything with a bad CRC...
     221
     222    uint nr_samples = 0, block_len;
     223    if (dts)
     224    {
     225        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     226        int rate, sfreq, nblks;
     227        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     228        nr_samples = nblks * 32;
     229        block_len = nr_samples * 2 * 2;
     230    }
     231    else
     232    {
     233#ifdef ENABLE_AC3_DECODER
     234        enc_len = ac3_sync(data+8, &flags, &sample_rate, &bit_rate, (int*)&block_len);
     235#else
     236        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     237        block_len = MAX_AC3_FRAME_SIZE;
     238#endif
     239    }
     240
     241    if (enc_len == 0 || enc_len > len)
     242    {
     243        int l = len;
     244        len = 0;
     245        return l;
     246    }
     247
     248    enc_len = min((uint)enc_len, block_len - 8);
     249
     250    //uint32_t x = *(uint32_t*)(data+8);
     251    // in place swab
     252    swab(data+8, data+8, enc_len);
     253    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     254    //        QString("DigitalEncoder::Encode swab test %1 %2")
     255    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     256
     257    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     258    // they form a valid IEC958 AC3 header.
     259    data[0] = 0x72;
     260    data[1] = 0xF8;
     261    data[2] = 0x1F;
     262    data[3] = 0x4E;
     263    data[4] = 0x01;
     264    if (dts)
     265    {
     266        switch(nr_samples)
     267        {
     268            case 512:
     269                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     270                break;
     271
     272            case 1024:
     273                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     274                break;
     275
     276            case 2048:
     277                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     278                break;
     279
     280            default:
     281                VERBOSE(VB_IMPORTANT, LOC +
     282                        QString("DTS: %1-sample bursts not supported")
     283                        .arg(nr_samples));
     284                data[4] = 0x00;
     285                break;
     286        }
     287    }
     288    data[5] = 0x00;
     289    data[6] = (enc_len << 3) & 0xFF;
     290    data[7] = (enc_len >> 5) & 0xFF;
     291    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     292    len = block_len;
     293
     294    return enc_len;
     295}
     296
     297// must have exactly 1 frames worth of data
     298size_t AudioOutputDigitalEncoder::Encode(short * buff)
     299{
     300    int encsize = 0;
     301    size_t outsize = 0;
     302 
     303    // put data in the correct spot for encode frame
     304    outsize = avcodec_encode_audio(
     305                av_context,
     306                ((uchar*)outbuf)+8,
     307                outbuf_size-8,
     308                buff);
     309    size_t tmpsize = outsize;
     310
     311    outsize = MAX_AC3_FRAME_SIZE;
     312    encsize = encode_frame(
     313            //av_context->codec_id==CODEC_ID_DTS,
     314            false,
     315            (unsigned char*)outbuf, outsize);
     316    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     317            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     318                .arg(tmpsize)
     319                .arg(encsize)
     320                .arg(outsize)
     321           );
     322
     323    return outsize;
     324}
  • (a) dummyemptyfile vs. (b) libs/libmyth/audiooutputdigitalencoder.h

    a b  
     1#ifndef AUDIOOUTPUTREENCODER
     2#define AUDIOOUTPUTREENCODER
     3
     4extern "C" {
     5#include "libavcodec/avcodec.h"
     6};
     7
     8class AudioOutputDigitalEncoder
     9{
     10public:
     11    AudioOutputDigitalEncoder();
     12    ~AudioOutputDigitalEncoder();
     13    void Dispose();
     14    bool Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     15    size_t Encode(short * buff);
     16
     17    // if needed
     18    char * GetFrameBuffer()
     19    {
     20        if (!frame_buffer && av_context)
     21        {
     22            frame_buffer = new char [one_frame_bytes];
     23        }
     24        return frame_buffer;
     25    }   
     26    size_t FrameSize() const { return one_frame_bytes; }
     27    char * GetOutBuff() const { return outbuf; }
     28
     29    size_t audio_bytes_per_sample;
     30private:
     31    AVCodecContext *av_context;
     32    char * outbuf;
     33    char * frame_buffer;
     34    int outbuf_size;
     35    size_t one_frame_bytes;
     36};
     37
     38
     39#endif
  • libs/libmyth/libmyth.pro

     
    2525HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h
    2626HEADERS += mythhdd.h mythcdrom.h
    2727HEADERS += compat.h
     28HEADERS += audiooutputdigitalencoder.h
    2829
    2930SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
    3031SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
     
    4041SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp
    4142SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp
    4243SOURCES += mythhdd.cpp mythcdrom.cpp
     44SOURCES += audiooutputdigitalencoder.cpp
    4345
    4446INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./
     47INCLUDEPATH += ../libavutil
    4548DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
    4649DEPENDPATH += ../libmythupnp
     50DEPENDPATH += ../libavutil ../libavcodec
    4751
    4852LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4953LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     54LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
    5055
    5156TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT}
    5257TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT}
     
    208213use_hidesyms {
    209214    QMAKE_CXXFLAGS += -fvisibility=hidden
    210215}
     216
     217contains( CONFIG_LIBA52, yes ) {
     218    LIBS += -la52
     219}
  • libs/libmyth/audiooutput.h

     
    3131    virtual ~AudioOutput() { };
    3232
    3333    // reconfigure sound out for new params
    34     virtual void Reconfigure(int audio_bits, int audio_channels,
    35                              int audio_samplerate, bool audio_passthru) = 0;
     34    virtual void Reconfigure(int audio_bits,
     35                             int audio_channels,
     36                             int audio_samplerate,
     37                             bool audio_passthru,
     38                             void* audio_codec = NULL
     39                             ) = 0;
    3640   
    3741    virtual void SetStretchFactor(float factor);
    3842
     
    7478        lastError = msg;
    7579        VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError);
    7680    }
     81    void ClearError()
     82     { lastError = QString::null; };
    7783
    7884    void Warn(QString msg)
    7985    {
  • libs/libmyth/audiooutputdx.h

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

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

     
    1818#include "samplerate.h"
    1919#include "SoundTouch.h"
    2020
    21 #define AUDBUFSIZE 768000
     21class AudioOutputDigitalEncoder;
     22struct AVCodecContext;
    2223#define AUDIO_SRC_IN_SIZE   16384
    2324#define AUDIO_SRC_OUT_SIZE (16384*6)
    2425#define AUDIO_TMP_BUF_SIZE (16384*6)
    2526
     27//#define AUDBUFSIZE 768000
     28//divisible by 12,10,8,6,4,2 and around 1024000
     29//#define AUDBUFSIZE 1024080
     30#define AUDBUFSIZE 1536000
     31
    2632class AudioOutputBase : public AudioOutput
    2733{
    2834 public:
     
    3541    virtual ~AudioOutputBase();
    3642
    3743    // reconfigure sound out for new params
    38     virtual void Reconfigure(int audio_bits, int audio_channels,
    39                              int audio_samplerate, bool audio_passthru);
     44    virtual void Reconfigure(int audio_bits,
     45                             int audio_channels,
     46                             int audio_samplerate,
     47                             bool audio_passthru,
     48                             void* audio_codec = NULL);
    4049   
    4150    // do AddSamples calls block?
    4251    virtual void SetBlocking(bool blocking);
     
    125134    bool audio_passthru;
    126135
    127136    float audio_stretchfactor;
     137    AVCodecContext *audio_codec;
    128138    AudioOutputSource source;
    129139
    130140    bool killaudio;
     
    133143    bool set_initial_vol;
    134144    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    135145   
     146    int configured_audio_channels;
     147
    136148 private:
    137149    // resampler
    138150    bool need_resampler;
     
    144156
    145157    // timestretch
    146158    soundtouch::SoundTouch * pSoundStretch;
     159    AudioOutputDigitalEncoder * encoder;
    147160
    148161    bool blocking; // do AddSamples calls block?
    149162
     
    162175
    163176    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    164177                                    'audiotime' and 'audiotime_updated' */
    165     int audiotime; // timecode of audio leaving the soundcard (same units as
     178    long long audiotime; // timecode of audio leaving the soundcard (same units as
    166179                   //                                          timecodes) ...
    167180    struct timeval audiotime_updated; // ... which was last updated at this time
    168181
    169182    /* Audio circular buffer */
    170183    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    171184    int raud, waud;     /* read and write positions */
    172     int audbuf_timecode;    /* timecode of audio most recently placed into
     185    long long audbuf_timecode;    /* timecode of audio most recently placed into
    173186                   buffer */
    174187
    175188    int numlowbuffer;
  • libs/libmyth/audiooutputbase.cpp

     
    1515
    1616// MythTV headers
    1717#include "audiooutputbase.h"
     18#include "audiooutputdigitalencoder.h"
    1819#include "compat.h"
    1920
    2021#define LOC QString("AO: ")
     
    2526    int     /*laudio_bits*/,       int               /*laudio_channels*/,
    2627    int     /*laudio_samplerate*/, AudioOutputSource lsource,
    2728    bool    lset_initial_vol,      bool              /*laudio_passthru*/) :
    28 
    2929    effdsp(0),                  effdspstretched(0),
    3030    audio_channels(-1),         audio_bytes_per_sample(0),
    3131    audio_bits(-1),             audio_samplerate(-1),
     
    3636    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    3737    audio_passthru(false),      audio_stretchfactor(1.0f),
    3838
     39    audio_codec(NULL),
    3940    source(lsource),            killaudio(false),
    4041
    4142    pauseaudio(false),          audio_actually_paused(false),
     
    4748
    4849    src_ctx(NULL),
    4950
    50     pSoundStretch(NULL),        blocking(false),
     51    pSoundStretch(NULL),       
     52    encoder(NULL),
     53    blocking(false),
    5154
    5255    lastaudiolen(0),            samples_buffered(0),
    5356
     
    7174    memset(tmp_buff,           0, sizeof(short) * AUDIO_TMP_BUF_SIZE);
    7275    memset(&audiotime_updated, 0, sizeof(audiotime_updated));
    7376    memset(audiobuffer,        0, sizeof(char)  * AUDBUFSIZE);
     77    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    7478
    7579    // You need to call Reconfigure from your concrete class.
    7680    // Reconfigure(laudio_bits,       laudio_channels,
     
    111115            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    112116                                        .arg(audio_stretchfactor));
    113117            pSoundStretch = new soundtouch::SoundTouch();
    114             pSoundStretch->setSampleRate(audio_samplerate);
    115             pSoundStretch->setChannels(audio_channels);
     118            if (audio_codec)
     119            {
     120                if (!encoder)
     121                {
     122                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     123                    encoder = new AudioOutputDigitalEncoder();
     124                    if (!encoder->Init(audio_codec->codec_id,
     125                                audio_codec->bit_rate,
     126                                audio_codec->sample_rate,
     127                                audio_codec->channels
     128                                ))
     129                    {
     130                        // eeks
     131                        delete encoder;
     132                        encoder = NULL;
     133                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     134                    }
     135                }
     136            }
     137            if (encoder)
     138            {
     139                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     140                pSoundStretch->setChannels(audio_codec->channels);
     141            }
     142            else
     143            {
     144                pSoundStretch->setSampleRate(audio_samplerate);
     145                pSoundStretch->setChannels(audio_channels);
     146            }
    116147
    117148            pSoundStretch->setTempo(audio_stretchfactor);
    118149            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    135166}
    136167
    137168void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    138                                  int laudio_samplerate, bool laudio_passthru)
     169                                 int laudio_samplerate, bool laudio_passthru,
     170                                 void* laudio_codec)
    139171{
     172    int codec_id = CODEC_ID_NONE;
     173    int lcodec_id = CODEC_ID_NONE;
     174    int lcchannels = 0;
     175    int cchannels = 0;
     176    if (laudio_codec)
     177    {
     178        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     179        laudio_bits = 16;
     180        laudio_channels = 2;
     181        laudio_samplerate = 48000;
     182        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     183    }
     184    if (audio_codec)
     185    {
     186        codec_id = audio_codec->codec_id;
     187        cchannels = ((AVCodecContext*)audio_codec)->channels;
     188    }
     189    ClearError();
    140190    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    141         laudio_samplerate == audio_samplerate &&
    142         laudio_passthru == audio_passthru && !need_resampler)
     191        laudio_samplerate == audio_samplerate && !need_resampler &&
     192        laudio_passthru == audio_passthru &&
     193        lcodec_id == codec_id && lcchannels == cchannels)
    143194        return;
    144195
    145196    KillAudio();
     
    151202    waud = raud = 0;
    152203    audio_actually_paused = false;
    153204   
     205    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    154206    audio_channels = laudio_channels;
    155207    audio_bits = laudio_bits;
    156208    audio_samplerate = laudio_samplerate;
     209    audio_codec = (AVCodecContext*)laudio_codec;
    157210    audio_passthru = laudio_passthru;
    158211    if (audio_bits != 8 && audio_bits != 16)
    159212    {
     
    172225   
    173226    numlowbuffer = 0;
    174227
     228    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3")
     229            .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate));
     230   
    175231    // Actually do the device specific open call
    176232    if (!OpenDevice())
    177233    {
    178234        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    179235        pthread_mutex_unlock(&avsync_lock);
    180236        pthread_mutex_unlock(&audio_buflock);
     237        if (GetError().isEmpty())
     238            Error("Aborting reconfigure");
     239        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    181240        return;
    182241    }
    183242
     
    200259    current_seconds = -1;
    201260    source_bitrate = -1;
    202261
     262    // NOTE: this wont do anything as above samplerate vars are set equal
    203263    // Check if we need the resampler
    204264    if (audio_samplerate != laudio_samplerate)
    205265    {
     
    224284
    225285    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    226286            .arg(audio_stretchfactor));
     287    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     288            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    227289
    228     SetStretchFactorLocked(audio_stretchfactor);
    229     if (pSoundStretch)
     290    if (redo_stretch)
    230291    {
    231         pSoundStretch->setSampleRate(audio_samplerate);
    232         pSoundStretch->setChannels(audio_channels);
     292        float laudio_stretchfactor = audio_stretchfactor;
     293        delete pSoundStretch;
     294        pSoundStretch = NULL;
     295        audio_stretchfactor = 0.0;
     296        SetStretchFactorLocked(laudio_stretchfactor);
    233297    }
     298    else
     299    {
     300        SetStretchFactorLocked(audio_stretchfactor);
     301        if (pSoundStretch)
     302        {
     303            // if its passthru then we need to reencode
     304            if (audio_codec)
     305            {
     306                if (!encoder)
     307                {
     308                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     309                    encoder = new AudioOutputDigitalEncoder();
     310                    if (!encoder->Init(audio_codec->codec_id,
     311                                audio_codec->bit_rate,
     312                                audio_codec->sample_rate,
     313                                audio_codec->channels
     314                                ))
     315                    {
     316                        // eeks
     317                        delete encoder;
     318                        encoder = NULL;
     319                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     320                    }
     321                }
     322            }
     323            if (encoder)
     324            {
     325                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     326                pSoundStretch->setChannels(audio_codec->channels);
     327            }
     328            else
     329            {
     330                pSoundStretch->setSampleRate(audio_samplerate);
     331                pSoundStretch->setChannels(audio_channels);
     332            }
     333        }
     334    }
    234335
    235336    // Setup visualisations, zero the visualisations buffers
    236337    prepareVisuals();
     
    290391        pSoundStretch = NULL;
    291392    }
    292393
     394    if (encoder)
     395    {
     396        delete encoder;
     397        encoder = NULL;
     398    }
     399
    293400    CloseDevice();
    294401
    295402    killAudioLock.unlock();
     
    303410
    304411void AudioOutputBase::Pause(bool paused)
    305412{
     413    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    306414    pauseaudio = paused;
    307415    audio_actually_paused = false;
    308416}
     
    385493       The reason is that computing 'audiotime' requires acquiring the audio
    386494       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    387495       from the audio thread, and then call this from the video thread. */
    388     int ret;
     496    long long ret;
    389497    struct timeval now;
    390498
    391499    if (audiotime == 0)
     
    397505
    398506    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    399507    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    400     ret = (int)(ret * audio_stretchfactor);
     508    ret = (long long)(ret * audio_stretchfactor);
    401509
     510#if 1
     511    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     512            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     513            .arg(now.tv_sec).arg(now.tv_usec)
     514            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     515            .arg(ret)
     516            .arg(audiotime)
     517            .arg(audio_stretchfactor)
     518           );
     519#endif
     520
    402521    ret += audiotime;
    403522
    404523    pthread_mutex_unlock(&avsync_lock);
    405     return ret;
     524    return (int)ret;
    406525}
    407526
    408527void AudioOutputBase::SetAudiotime(void)
     
    439558    // include algorithmic latencies
    440559    if (pSoundStretch)
    441560    {
     561        // add the effect of any unused but processed samples, AC3 reencode does this
     562        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    442563        // add the effect of unprocessed samples in time stretch algo
    443564        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    444565                              audio_bytes_per_sample) / audio_stretchfactor);
    445566    }
    446                
     567
    447568    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    448569                                   (audio_bytes_per_sample * effdspstretched));
    449570 
    450571    gettimeofday(&audiotime_updated, NULL);
     572#if 1
     573    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     574            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     575            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     576            .arg(audiotime)
     577            .arg(audbuf_timecode)
     578            .arg(totalbuffer)
     579            .arg(soundcard_buffer)
     580            .arg(effdspstretched)
     581            .arg(audio_bytes_per_sample)
     582            .arg(audio_stretchfactor)
     583           );
     584#endif
    451585
    452586    pthread_mutex_unlock(&avsync_lock);
    453587    pthread_mutex_unlock(&audio_buflock);
     
    515649    // NOTE: This function is not threadsafe
    516650
    517651    int afree = audiofree(true);
    518     int len = samples * audio_bytes_per_sample;
     652    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    519653
    520654    // Check we have enough space to write the data
    521655    if (need_resampler && src_ctx)
     
    527661                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    528662                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    529663                .arg(timecode));
    530 
    531664        return false; // would overflow
    532665    }
    533666
     
    564697
    565698int AudioOutputBase::WaitForFreeSpace(int samples)
    566699{
    567     int len = samples * audio_bytes_per_sample;
     700    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     701    int len = samples * abps;
    568702    int afree = audiofree(false);
    569703
    570704    while (len > afree)
    571705    {
    572706        if (blocking)
    573707        {
    574             VERBOSE(VB_AUDIO, LOC + "Waiting for free space " +
     708            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " +
    575709                    QString("(need %1, available %2)").arg(len).arg(afree));
    576710
    577711            // wait for more space
     
    580714        }
    581715        else
    582716        {
    583             VERBOSE(VB_IMPORTANT, LOC_ERR +
    584                     "Audio buffer overflow, audio data lost!");
    585             samples = afree / audio_bytes_per_sample;
    586             len = samples * audio_bytes_per_sample;
     717            VERBOSE(VB_IMPORTANT, LOC_ERR +
     718                    QString("Audio buffer overflow, %1 audio samples lost!")
     719                        .arg(samples-afree / abps));
     720            samples = afree / abps;
     721            len = samples * abps;
    587722            if (src_ctx)
    588723            {
    589724                int error = src_reset(src_ctx);
     
    608743   
    609744    int afree = audiofree(false);
    610745
    611     VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    612             LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    613             .arg(samples * audio_bytes_per_sample)
    614             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     746    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     747    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     748            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5")
     749            .arg(samples)
     750            .arg(samples * abps)
     751            .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode));
    615752   
    616753    len = WaitForFreeSpace(samples);
    617754
     
    648785
    649786    if (pSoundStretch)
    650787    {
     788
    651789        // does not change the timecode, only the number of samples
    652790        // back to orig pos
    653791        org_waud = waud;
    654792        int bdiff = AUDBUFSIZE - org_waud;
    655         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     793        int nSamplesToEnd = bdiff/abps;
    656794        if (bdiff < len)
    657795        {
    658796            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    659797                                      org_waud), nSamplesToEnd);
    660798            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    661                                       (len - bdiff) / audio_bytes_per_sample);
     799                                      (len - bdiff) / abps);
    662800        }
    663801        else
    664802        {
    665803            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    666                                       org_waud), len / audio_bytes_per_sample);
     804                                      org_waud), len / abps);
    667805        }
    668806
    669         int newLen = 0;
    670         int nSamples;
    671         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    672                                audio_bytes_per_sample);
    673         do
     807        if (encoder)
    674808        {
    675             int samplesToGet = len/audio_bytes_per_sample;
    676             if (samplesToGet > nSamplesToEnd)
     809            // pull out a packet's worth and reencode it until we dont have enough
     810            // for any more packets
     811            soundtouch::SAMPLETYPE* temp_buff =
     812                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     813            size_t frameSize = encoder->FrameSize()/abps;
     814            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     815                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     816                    .arg(frameSize)
     817                    .arg(encoder->FrameSize())
     818                    .arg(pSoundStretch->numSamples())
     819                   );
     820            // process the same number of samples as it creates a full encoded buffer
     821            // just like before
     822            while (pSoundStretch->numSamples() >= frameSize)
    677823            {
    678                 samplesToGet = nSamplesToEnd;   
     824                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     825                int amount = encoder->Encode(temp_buff);
     826                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     827                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     828                        .arg(amount)
     829                        .arg(got)
     830                        .arg(pSoundStretch->numSamples())
     831                       );
     832                if (amount == 0)
     833                    continue;
     834                //len = WaitForFreeSpace(amount);
     835                char * ob = encoder->GetOutBuff();
     836                if (amount >= bdiff)
     837                {
     838                    memcpy(audiobuffer + org_waud, ob, bdiff);
     839                    ob += bdiff;
     840                    amount -= bdiff;
     841                    org_waud = 0;
     842                }
     843                if (amount > 0)
     844                    memcpy(audiobuffer + org_waud, ob, amount);
     845                bdiff = AUDBUFSIZE - amount;
     846                org_waud += amount;
    679847            }
    680 
    681             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    682                                       (audiobuffer + org_waud), samplesToGet);
    683             if (nSamples == nSamplesToEnd)
     848        }
     849        else
     850        {
     851            int newLen = 0;
     852            int nSamples;
     853            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     854                                   audio_bytes_per_sample);
     855            do
    684856            {
    685                 org_waud = 0;
    686                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
    687             }
    688             else
    689             {
    690                 org_waud += nSamples * audio_bytes_per_sample;
    691                 nSamplesToEnd -= nSamples;
    692             }
     857                int samplesToGet = len/audio_bytes_per_sample;
     858                if (samplesToGet > nSamplesToEnd)
     859                {
     860                    samplesToGet = nSamplesToEnd;   
     861                }
    693862
    694             newLen += nSamples * audio_bytes_per_sample;
    695             len -= nSamples * audio_bytes_per_sample;
    696         } while (nSamples > 0);
     863                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     864                                          (audiobuffer + org_waud), samplesToGet);
     865                if (nSamples == nSamplesToEnd)
     866                {
     867                    org_waud = 0;
     868                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     869                }
     870                else
     871                {
     872                    org_waud += nSamples * audio_bytes_per_sample;
     873                    nSamplesToEnd -= nSamples;
     874                }
     875
     876                newLen += nSamples * audio_bytes_per_sample;
     877                len -= nSamples * audio_bytes_per_sample;
     878            } while (nSamples > 0);
     879        }
    697880    }
    698881
    699882    waud = org_waud;
     
    769952            space_on_soundcard = getSpaceOnSoundcard();
    770953
    771954            if (space_on_soundcard != last_space_on_soundcard) {
    772                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     955                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    773956                        .arg(space_on_soundcard));
    774957                last_space_on_soundcard = space_on_soundcard;
    775958            }
     
    782965                    WriteAudio(zeros, fragment_size);
    783966                } else {
    784967                    // this should never happen now -dag
    785                     VERBOSE(VB_AUDIO, LOC +
     968                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    786969                            QString("waiting for space on soundcard "
    787970                                    "to write zeros: have %1 need %2")
    788971                            .arg(space_on_soundcard).arg(fragment_size));
     
    8181001        if (fragment_size > audiolen(true))
    8191002        {
    8201003            if (audiolen(true) > 0)  // only log if we're sending some audio
    821                 VERBOSE(VB_AUDIO, LOC +
     1004                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221005                        QString("audio waiting for buffer to fill: "
    8231006                                "have %1 want %2")
    8241007                        .arg(audiolen(true)).arg(fragment_size));
    8251008
    826             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1009            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8271010            pthread_mutex_lock(&audio_buflock);
    8281011            pthread_cond_broadcast(&audio_bufsig);
    8291012            pthread_mutex_unlock(&audio_buflock);
     
    8371020        if (fragment_size > space_on_soundcard)
    8381021        {
    8391022            if (space_on_soundcard != last_space_on_soundcard) {
    840                 VERBOSE(VB_AUDIO, LOC +
     1023                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8411024                        QString("audio waiting for space on soundcard: "
    8421025                                "have %1 need %2")
    8431026                        .arg(space_on_soundcard).arg(fragment_size));
     
    8991082
    9001083        /* update raud */
    9011084        raud = (raud + fragment_size) % AUDBUFSIZE;
    902         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1085        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    9031086        pthread_cond_broadcast(&audio_bufsig);
    9041087
    9051088        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

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

     
    5858#endif
    5959#ifdef USING_ALSA
    6060    gc->addSelection("ALSA:default", "ALSA:default");
     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");
    6165#endif
    6266#ifdef USING_ARTS
    6367    gc->addSelection("ARTS:", "ARTS:");
     
    7377    return gc;
    7478}
    7579
     80static HostComboBox *MaxAudioChannels()
     81{
     82    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     83    gc->setLabel(QObject::tr("Max Audio Channels"));
     84    //gc->addSelection(QObject::tr("Mono"), "1");
     85    //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default
     86    //gc->addSelection(QObject::tr("3 Channel: L C R"), "3");
     87    //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4");
     88    //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5");
     89    //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6");
     90    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     91    gc->addSelection(QObject::tr("6 Channel"), "6");
     92    gc->setHelpText(
     93            QObject::tr("Set the maximum number of audio channels to be decoded. "
     94                "This is for multi-channel/surround audio playback."));
     95    return gc;
     96}
     97
    7698static HostComboBox *PassThroughOutputDevice()
    7799{
    78100    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    31303152             new VerticalConfigurationGroup(false, false, true, true);
    31313153         vgrp0->addChild(AC3PassThrough());
    31323154         vgrp0->addChild(DTSPassThrough());
     3155         addChild(MaxAudioChannels());
    31333156
    31343157         VerticalConfigurationGroup *vgrp1 =
    31353158             new VerticalConfigurationGroup(false, false, true, true);
  • programs/mythtranscode/transcode.cpp

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

     
    66TARGET = mythuitest
    77CONFIG += thread opengl
    88
     9LIBS += -L../../libs/libavcodec -L../../libs/libavutil
     10LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION
    911LIBS += $$EXTRA_LIBS
    1012
     13TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     14TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     15
    1116macx {
    1217    # Duplication of source with libmyth (e.g. oldsettings.cpp)
    1318    # means that the linker complains, so we have to ignore duplicates
  • libs/libmythtv/avformatdecoder.h

     
    259259    bool              allow_ac3_passthru;
    260260    bool              allow_dts_passthru;
    261261    bool              disable_passthru;
     262    int               max_channels;
    262263
    263264    AudioInfo         audioIn;
    264265    AudioInfo         audioOut;
  • libs/libmythtv/avformatdecoder.cpp

     
    5151
    5252#define MAX_AC3_FRAME_SIZE 6144
    5353
    54 /** Set to zero to allow any number of AC3 channels. */
    55 #define MAX_OUTPUT_CHANNELS 2
    56 
    5754static int cc608_parity(uint8_t byte);
    5855static int cc608_good_parity(const int *parity_table, uint16_t data);
    5956static void cc608_build_parity_table(int *parity_table);
     
    417414
    418415    allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false);
    419416    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     417    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    420418
    421419    audioIn.sample_size = -32; // force SetupAudioStream to run once
    422420    itv = GetNVP()->GetInteractiveTV();
     
    15801578                            <<") already open, leaving it alone.");
    15811579                }
    15821580                //assert(enc->codec_id);
     1581                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
    15831582
     1583#if 0
     1584                // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this
    15841585                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15851586                if (enc->codec_id == CODEC_ID_DTS)
    15861587                {
     
    15891590                    // enc->bit_rate = what??;
    15901591                }
    15911592                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1593#endif
    15921594
    15931595                bitrate += enc->bit_rate;
    15941596                break;
     
    32603262                    if (!curstream->codec->channels)
    32613263                    {
    32623264                        QMutexLocker locker(&avcodeclock);
    3263                         curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3265                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3266                        curstream->codec->channels = audioOut.channels;
    32643267                        ret = avcodec_decode_audio(
    32653268                            curstream->codec, audioSamples,
    32663269                            &data_size, ptr, len);
     
    33213324                        AVCodecContext *ctx = curstream->codec;
    33223325
    33233326                        if ((ctx->channels == 0) ||
    3324                             (ctx->channels > MAX_OUTPUT_CHANNELS))
    3325                             ctx->channels = MAX_OUTPUT_CHANNELS;
     3327                            (ctx->channels > audioOut.channels))
     3328                            ctx->channels = audioOut.channels;
    33263329
    33273330                        ret = avcodec_decode_audio(
    33283331                            ctx, audioSamples, &data_size, ptr, len);
     
    36753678
    36763679void AvFormatDecoder::SetDisablePassThrough(bool disable)
    36773680{
     3681    // can only disable never reenable as once tiemstretch is on its on for the session
     3682    if (disable_passthru)
     3683        return;
    36783684    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    36793685    {
    36803686        disable_passthru = disable;
     
    37073713    AVCodecContext *codec_ctx = NULL;
    37083714    AudioInfo old_in  = audioIn;
    37093715    AudioInfo old_out = audioOut;
     3716    bool using_passthru = false;
    37103717
    37113718    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    37123719        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    37183725        assert(curstream->codec);
    37193726        codec_ctx = curstream->codec;       
    37203727        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3721                                 !disable_passthru &&
    37223728                                (codec_ctx->codec_id == CODEC_ID_AC3));
    37233729        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3724                                 !disable_passthru &&
    37253730                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3731        using_passthru = do_ac3_passthru || do_dts_passthru;
    37263732        info = AudioInfo(codec_ctx->codec_id,
    37273733                         codec_ctx->sample_rate, codec_ctx->channels,
    3728                          do_ac3_passthru || do_dts_passthru);
     3734                         using_passthru && !disable_passthru);
    37293735    }
    37303736
    37313737    if (info == audioIn)
    37323738        return false; // no change
    37333739
     3740    QString ptmsg = "";
     3741    if (using_passthru)
     3742    {
     3743        ptmsg = QString(" using passthru");
     3744    }
    37343745    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    37353746            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    37363747
    37373748    audioOut = audioIn = info;
    3738     if (audioIn.do_passthru)
     3749    if (using_passthru)
    37393750    {
    37403751        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3741         audioOut.channels    = 2;
    3742         audioOut.sample_rate = 48000;
    3743         audioOut.sample_size = 4;
     3752        AudioInfo digInfo = audioOut;
     3753        if (!disable_passthru)
     3754        {
     3755            digInfo.channels    = 2;
     3756            digInfo.sample_rate = 48000;
     3757            digInfo.sample_size = 4;
     3758        }
     3759        if (audioOut.channels > max_channels)
     3760        {
     3761            audioOut.channels = max_channels;
     3762            audioOut.sample_size = audioOut.channels * 2;
     3763            codec_ctx->channels = audioOut.channels;
     3764        }
     3765        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3766                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3767                .arg(digInfo.toString())
     3768                .arg(old_in.toString()).arg(old_out.toString())
     3769                .arg(audioIn.toString()).arg(audioOut.toString()));
     3770
     3771        if (digInfo.sample_rate > 0)
     3772            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3773
     3774        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3775                                 digInfo.sample_rate, audioIn.do_passthru);
     3776        // allow the audio stuff to reencode
     3777        GetNVP()->SetAudioCodec(codec_ctx);
     3778        GetNVP()->ReinitAudio();
     3779        return true;
    37443780    }
    37453781    else
    37463782    {
    3747         if (audioOut.channels > MAX_OUTPUT_CHANNELS)
     3783        if (audioOut.channels > max_channels)
    37483784        {
    3749             audioOut.channels = MAX_OUTPUT_CHANNELS;
     3785            audioOut.channels = max_channels;
    37503786            audioOut.sample_size = audioOut.channels * 2;
    3751             codec_ctx->channels = MAX_OUTPUT_CHANNELS;
     3787            codec_ctx->channels = audioOut.channels;
    37523788        }
    37533789    }
     3790    bool audiook;
    37543791
    37553792    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    37563793            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    37633800    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    37643801                             audioOut.sample_rate,
    37653802                             audioIn.do_passthru);
    3766     GetNVP()->ReinitAudio();
     3803    // allow the audio stuff to reencode
     3804    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3805    QString errMsg = GetNVP()->ReinitAudio();
     3806    audiook = errMsg.isEmpty();
    37673807
    37683808    return true;
    37693809}
  • 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; }
     
    682683    int      audio_bits;
    683684    int      audio_samplerate;
    684685    float    audio_stretchfactor;
     686    void     *audio_codec;
    685687    bool     audio_passthru;
    686688
    687689    // Picture-in-Picture
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    207207      audio_passthru_device(QString::null),
    208208      audio_channels(2),            audio_bits(-1),
    209209      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     210      audio_codec(NULL),
    210211      // Picture-in-Picture
    211212      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    212213      // Preview window support
     
    768769    if (audioOutput)
    769770    {
    770771        audioOutput->Reconfigure(audio_bits, audio_channels,
    771                                  audio_samplerate, audio_passthru);
     772                                 audio_samplerate, audio_passthru,
     773                                 audio_codec);
    772774        errMsg = audioOutput->GetError();
    773775        if (!errMsg.isEmpty())
    774776            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    36513658    audio_passthru = passthru;
    36523659}
    36533660
     3661void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3662{
     3663    audio_codec = ac;
     3664}
     3665
    36543666void NuppelVideoPlayer::SetEffDsp(int dsprate)
    36553667{
    36563668    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
     
    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/libavcodec/ac3_parser.c

     
    8484    return 0;
    8585}
    8686
    87 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
     87/*static*/ int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
    8888                    int *bit_rate, int *samples)
    8989{
    9090    int err;