Ticket #1104: mythtv_ac3.28.patch

File mythtv_ac3.28.patch, 61.4 KB (added by Mark Spieth, 17 years ago)
  • libs/libmyth/libmyth.pro

     
    3535SOURCES += virtualkeyboard.cpp mythobservable.cpp mythsocket.cpp themeinfo.cpp
    3636
    3737INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../
     38INCLUDEPATH += ../libavutil
    3839DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui
     40DEPENDPATH += ../libavutil ../libavcodec
    3941
    4042LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION}
    4143LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION}
     44LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION}
    4245
    4346isEmpty(QMAKE_EXTENSION_SHLIB) {
    4447  QMAKE_EXTENSION_SHLIB=so
     
    186189use_hidesyms {
    187190    QMAKE_CXXFLAGS += -fvisibility=hidden
    188191}
     192
     193contains( CONFIG_LIBA52, yes ) {
     194    LIBS += -la52
     195}
  • 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
     21struct AVCodecContext;
     22class DigitalEncoder;
    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    DigitalEncoder * encoder;
    147160
    148161    bool blocking; // do AddSamples calls block?
    149162
     
    160173
    161174    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    162175                                    'audiotime' and 'audiotime_updated' */
    163     int audiotime; // timecode of audio leaving the soundcard (same units as
     176    long long audiotime; // timecode of audio leaving the soundcard (same units as
    164177                   //                                          timecodes) ...
    165178    struct timeval audiotime_updated; // ... which was last updated at this time
    166179
    167180    /* Audio circular buffer */
    168181    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    169182    int raud, waud;     /* read and write positions */
    170     int audbuf_timecode;    /* timecode of audio most recently placed into
     183    long long audbuf_timecode;    /* timecode of audio most recently placed into
    171184                   buffer */
    172185
    173186    int numlowbuffer;
  • libs/libmyth/audiooutputbase.cpp

     
    1414#include <qdeepcopy.h>
    1515
    1616// MythTV headers
     17#include "config.h"
    1718#include "audiooutputbase.h"
    1819
     20extern "C" {
     21#include "libavcodec/avcodec.h"
     22#ifdef ENABLE_AC3_DECODER
     23#include "libavcodec/parser.h"
     24#else
     25//#include "libavcodec/liba52/a52.h"
     26#include <a52dec/a52.h>
     27#endif
     28}
     29
     30#if QT_VERSION < 0x030200
     31#define LONGLONGCONVERT (long)
     32#else
     33#define LONGLONGCONVERT
     34#endif
     35
     36#define LOC QString("DEnc: ");
     37#define MAX_AC3_FRAME_SIZE 6144
     38class DigitalEncoder
     39{
     40public:
     41    DigitalEncoder();
     42    ~DigitalEncoder();
     43    void Dispose();
     44    bool Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     45    size_t Encode(short * buff);
     46
     47    // if needed
     48    char * GetFrameBuffer()
     49    {
     50        if (!frame_buffer && av_context)
     51        {
     52            frame_buffer = new char [one_frame_bytes];
     53        }
     54        return frame_buffer;
     55    }   
     56    size_t FrameSize() const { return one_frame_bytes; }
     57    char * GetOutBuff() const { return outbuf; }
     58
     59    size_t audio_bytes_per_sample;
     60private:
     61    AVCodecContext *av_context;
     62    char * outbuf;
     63    char * frame_buffer;
     64    int outbuf_size;
     65    size_t one_frame_bytes;
     66};
     67
     68DigitalEncoder::DigitalEncoder()
     69{
     70    av_context = NULL;
     71    outbuf = NULL;
     72    outbuf_size = 0;
     73    one_frame_bytes = 0;
     74    frame_buffer = NULL;
     75}
     76
     77DigitalEncoder::~DigitalEncoder()
     78{
     79    Dispose();
     80}
     81
     82void DigitalEncoder::Dispose()
     83{
     84    if (av_context)
     85    {
     86        avcodec_close(av_context);
     87        av_free(av_context);
     88        av_context = NULL;
     89    }
     90    if (outbuf)
     91    {
     92        delete [] outbuf;
     93        outbuf = NULL;
     94        outbuf_size = 0;
     95    }
     96    if (frame_buffer)
     97    {
     98        delete [] frame_buffer;
     99        frame_buffer = NULL;
     100        one_frame_bytes = 0;
     101    }
     102}
     103
     104//CODEC_ID_AC3
     105bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     106{
     107    AVCodec * codec;
     108    int ret;
     109
     110    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     111            .arg(codec_id_string(codec_id))
     112            .arg(bitrate)
     113            .arg(samplerate)
     114            .arg(channels));
     115    //codec = avcodec_find_encoder(codec_id);
     116    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     117    codec = avcodec_find_encoder(CODEC_ID_AC3);
     118    if (!codec)
     119    {
     120        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     121        return false;
     122    }
     123    av_context = avcodec_alloc_context();
     124    av_context->bit_rate = bitrate;
     125    av_context->sample_rate = samplerate;
     126    av_context->channels = channels;
     127    // open it */
     128    if ((ret = avcodec_open(av_context, codec)) < 0)
     129    {
     130        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     131        Dispose();
     132        return false;
     133    }
     134
     135    size_t bytes_per_frame = av_context->channels * sizeof(short);
     136    audio_bytes_per_sample = bytes_per_frame;
     137    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     138
     139    outbuf_size = 16384;    // ok for AC3 but DTS?
     140    outbuf = new char [outbuf_size];
     141    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     142            .arg(av_context->frame_size)
     143            .arg(bytes_per_frame)
     144            .arg(one_frame_bytes)
     145           );
     146
     147    return true;
     148}
     149
     150static int DTS_SAMPLEFREQS[16] =
     151{
     152    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     153    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     154};
     155
     156static int DTS_BITRATES[30] =
     157{
     158    32000,    56000,    64000,    96000,    112000,   128000,
     159    192000,   224000,   256000,   320000,   384000,   448000,
     160    512000,   576000,   640000,   768000,   896000,   1024000,
     161    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     162    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     163};
     164
     165static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     166                             int *nblks, int *sfreq)
     167{
     168    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     169               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     170
     171    if (id != 0x7ffe8001)
     172        return -1;
     173
     174    int ftype = indata_ptr[4] >> 7;
     175
     176    int surp = (indata_ptr[4] >> 2) & 0x1f;
     177    surp = (surp + 1) % 32;
     178
     179    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     180    ++*nblks;
     181
     182    int fsize = (indata_ptr[5] & 0x03) << 12 |
     183                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     184    ++fsize;
     185
     186    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     187    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     188
     189    if (ftype != 1)
     190    {
     191        VERBOSE(VB_IMPORTANT, LOC +
     192                QString("DTS: Termination frames not handled (ftype %1)")
     193                .arg(ftype));
     194        return -1;
     195    }
     196
     197    if (*sfreq != 13)
     198    {
     199        VERBOSE(VB_IMPORTANT, LOC +
     200                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     201        return -1;
     202    }
     203
     204    if ((fsize > 8192) || (fsize < 96))
     205    {
     206        VERBOSE(VB_IMPORTANT, LOC +
     207                QString("DTS: fsize: %1 invalid").arg(fsize));
     208        return -1;
     209    }
     210
     211    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     212        *nblks != 64 && *nblks != 128 && ftype == 1)
     213    {
     214        VERBOSE(VB_IMPORTANT, LOC +
     215                QString("DTS: nblks %1 not valid for normal frame")
     216                .arg(*nblks));
     217        return -1;
     218    }
     219
     220    return fsize;
     221}
     222
     223static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     224                        int *sample_rate, int *bit_rate)
     225{
     226    int nblks;
     227    int rate;
     228    int sfreq;
     229
     230    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     231    if (fsize >= 0)
     232    {
     233        if (rate >= 0 && rate <= 29)
     234            *bit_rate = DTS_BITRATES[rate];
     235        else
     236            *bit_rate = 0;
     237        if (sfreq >= 1 && sfreq <= 15)
     238            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     239        else
     240            *sample_rate = 0;
     241    }
     242    return fsize;
     243}
     244
     245// until there is an easy way to do this with ffmpeg
     246// get the code from libavcodec/parser.c made non static
     247extern "C" int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
     248                            int *bit_rate, int *samples);
     249
     250static int encode_frame(
     251        bool dts,
     252        unsigned char *data,
     253        size_t &len)
     254{
     255    size_t enc_len;
     256    int flags, sample_rate, bit_rate;
     257
     258    // we don't do any length/crc validation of the AC3 frame here; presumably
     259    // the receiver will have enough sense to do that.  if someone has a
     260    // receiver that doesn't, here would be a good place to put in a call
     261    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     262    // packet is bad?  we'd need to send something that the receiver would
     263    // ignore, and if so, may as well just assume that it will ignore
     264    // anything with a bad CRC...
     265
     266    uint nr_samples = 0, block_len;
     267    if (dts)
     268    {
     269        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     270        int rate, sfreq, nblks;
     271        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     272        nr_samples = nblks * 32;
     273        block_len = nr_samples * 2 * 2;
     274    }
     275    else
     276    {
     277#ifdef ENABLE_AC3_DECODER
     278        enc_len = ac3_sync(data+8, &flags, &sample_rate, &bit_rate, (int*)&block_len);
     279#else
     280        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     281        block_len = MAX_AC3_FRAME_SIZE;
     282#endif
     283    }
     284
     285    if (enc_len == 0 || enc_len > len)
     286    {
     287        int l = len;
     288        len = 0;
     289        return l;
     290    }
     291
     292    enc_len = min((uint)enc_len, block_len - 8);
     293
     294    //uint32_t x = *(uint32_t*)(data+8);
     295    // in place swab
     296    swab(data+8, data+8, enc_len);
     297    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     298    //        QString("DigitalEncoder::Encode swab test %1 %2")
     299    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     300
     301    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     302    // they form a valid IEC958 AC3 header.
     303    data[0] = 0x72;
     304    data[1] = 0xF8;
     305    data[2] = 0x1F;
     306    data[3] = 0x4E;
     307    data[4] = 0x01;
     308    if (dts)
     309    {
     310        switch(nr_samples)
     311        {
     312            case 512:
     313                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     314                break;
     315
     316            case 1024:
     317                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     318                break;
     319
     320            case 2048:
     321                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     322                break;
     323
     324            default:
     325                VERBOSE(VB_IMPORTANT, LOC +
     326                        QString("DTS: %1-sample bursts not supported")
     327                        .arg(nr_samples));
     328                data[4] = 0x00;
     329                break;
     330        }
     331    }
     332    data[5] = 0x00;
     333    data[6] = (enc_len << 3) & 0xFF;
     334    data[7] = (enc_len >> 5) & 0xFF;
     335    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     336    len = block_len;
     337
     338    return enc_len;
     339}
     340
     341// must have exactly 1 frames worth of data
     342size_t DigitalEncoder::Encode(short * buff)
     343{
     344    int encsize = 0;
     345    size_t outsize = 0;
     346 
     347    // put data in the correct spot for encode frame
     348    outsize = avcodec_encode_audio(
     349                av_context,
     350                ((uchar*)outbuf)+8,
     351                outbuf_size-8,
     352                buff);
     353    size_t tmpsize = outsize;
     354
     355    outsize = MAX_AC3_FRAME_SIZE;
     356    encsize = encode_frame(
     357            //av_context->codec_id==CODEC_ID_DTS,
     358            false,
     359            (unsigned char*)outbuf, outsize);
     360    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     361            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     362                .arg(tmpsize)
     363                .arg(encsize)
     364                .arg(outsize)
     365           );
     366
     367    return outsize;
     368}
     369#undef LOC
    19370#define LOC QString("AO: ")
    20371#define LOC_ERR QString("AO, ERROR: ")
    21372
     
    24375    int     /*laudio_bits*/,       int               /*laudio_channels*/,
    25376    int     /*laudio_samplerate*/, AudioOutputSource lsource,
    26377    bool    lset_initial_vol,      bool              /*laudio_passthru*/) :
    27 
    28378    effdsp(0),                  effdspstretched(0),
    29379    audio_channels(-1),         audio_bytes_per_sample(0),
    30380    audio_bits(-1),             audio_samplerate(-1),
     
    35385    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    36386    audio_passthru(false),      audio_stretchfactor(1.0f),
    37387
     388    audio_codec(NULL),
    38389    source(lsource),            killaudio(false),
    39390
    40391    pauseaudio(false),          audio_actually_paused(false),
     
    46397
    47398    src_ctx(NULL),
    48399
    49     pSoundStretch(NULL),        blocking(false),
     400    pSoundStretch(NULL),       
     401    encoder(NULL),
     402    blocking(false),
    50403
    51404    lastaudiolen(0),            samples_buffered(0),
    52405    audiotime(0),
     
    61414    pthread_cond_init(&audio_bufsig, NULL);
    62415
    63416    output_audio = 0; // TODO FIXME Not POSIX compatible!
     417    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    64418
    65419    bzero(&src_data,          sizeof(SRC_DATA));
    66420    bzero(src_in,             sizeof(float) * AUDIO_SRC_IN_SIZE);
     
    108462            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    109463                                        .arg(audio_stretchfactor));
    110464            pSoundStretch = new soundtouch::SoundTouch();
    111             pSoundStretch->setSampleRate(audio_samplerate);
    112             pSoundStretch->setChannels(audio_channels);
     465            if (audio_codec)
     466            {
     467                if (!encoder)
     468                {
     469                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     470                    encoder = new DigitalEncoder();
     471                    if (!encoder->Init(audio_codec->codec_id,
     472                                audio_codec->bit_rate,
     473                                audio_codec->sample_rate,
     474                                audio_codec->channels
     475                                ))
     476                    {
     477                        // eeks
     478                        delete encoder;
     479                        encoder = NULL;
     480                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     481                    }
     482                }
     483            }
     484            if (encoder)
     485            {
     486                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     487                pSoundStretch->setChannels(audio_codec->channels);
     488            }
     489            else
     490            {
     491                pSoundStretch->setSampleRate(audio_samplerate);
     492                pSoundStretch->setChannels(audio_channels);
     493            }
    113494
    114495            pSoundStretch->setTempo(audio_stretchfactor);
    115496            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    132513}
    133514
    134515void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    135                                  int laudio_samplerate, bool laudio_passthru)
     516                                 int laudio_samplerate, bool laudio_passthru,
     517                                 void* laudio_codec)
    136518{
     519    int codec_id = CODEC_ID_NONE;
     520    int lcodec_id = CODEC_ID_NONE;
     521    int lcchannels = 0;
     522    int cchannels = 0;
     523    if (laudio_codec)
     524    {
     525        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     526        laudio_bits = 16;
     527        laudio_channels = 2;
     528        laudio_samplerate = 48000;
     529        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     530    }
     531    if (audio_codec)
     532    {
     533        codec_id = audio_codec->codec_id;
     534        cchannels = ((AVCodecContext*)audio_codec)->channels;
     535    }
     536    ClearError();
    137537    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    138         laudio_samplerate == audio_samplerate &&
    139         laudio_passthru == audio_passthru && !need_resampler)
     538        laudio_samplerate == audio_samplerate && !need_resampler &&
     539        laudio_passthru == audio_passthru &&
     540        lcodec_id == codec_id && lcchannels == cchannels)
    140541        return;
    141542
    142543    KillAudio();
     
    148549    waud = raud = 0;
    149550    audio_actually_paused = false;
    150551   
     552    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    151553    audio_channels = laudio_channels;
    152554    audio_bits = laudio_bits;
    153555    audio_samplerate = laudio_samplerate;
     556    audio_codec = (AVCodecContext*)laudio_codec;
    154557    audio_passthru = laudio_passthru;
    155558    if (audio_bits != 8 && audio_bits != 16)
    156559    {
     
    169572   
    170573    numlowbuffer = 0;
    171574
     575    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3")
     576            .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate));
     577   
    172578    // Actually do the device specific open call
    173579    if (!OpenDevice())
    174580    {
    175581        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    176582        pthread_mutex_unlock(&avsync_lock);
    177583        pthread_mutex_unlock(&audio_buflock);
     584        if (GetError().isEmpty())
     585            Error("Aborting reconfigure");
     586        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    178587        return;
    179588    }
    180589
     
    197606    current_seconds = -1;
    198607    source_bitrate = -1;
    199608
     609    // NOTE: this wont do anything as above samplerate vars are set equal
    200610    // Check if we need the resampler
    201611    if (audio_samplerate != laudio_samplerate)
    202612    {
     
    221631
    222632    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    223633            .arg(audio_stretchfactor));
     634    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     635            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    224636
    225     SetStretchFactorLocked(audio_stretchfactor);
    226     if (pSoundStretch)
     637    if (redo_stretch)
    227638    {
    228         pSoundStretch->setSampleRate(audio_samplerate);
    229         pSoundStretch->setChannels(audio_channels);
     639        float laudio_stretchfactor = audio_stretchfactor;
     640        delete pSoundStretch;
     641        pSoundStretch = NULL;
     642        audio_stretchfactor = 0.0;
     643        SetStretchFactorLocked(laudio_stretchfactor);
    230644    }
     645    else
     646    {
     647        SetStretchFactorLocked(audio_stretchfactor);
     648        if (pSoundStretch)
     649        {
     650            // if its passthru then we need to reencode
     651            if (audio_codec)
     652            {
     653                if (!encoder)
     654                {
     655                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     656                    encoder = new DigitalEncoder();
     657                    if (!encoder->Init(audio_codec->codec_id,
     658                                audio_codec->bit_rate,
     659                                audio_codec->sample_rate,
     660                                audio_codec->channels
     661                                ))
     662                    {
     663                        // eeks
     664                        delete encoder;
     665                        encoder = NULL;
     666                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     667                    }
     668                }
     669            }
     670            if (encoder)
     671            {
     672                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     673                pSoundStretch->setChannels(audio_codec->channels);
     674            }
     675            else
     676            {
     677                pSoundStretch->setSampleRate(audio_samplerate);
     678                pSoundStretch->setChannels(audio_channels);
     679            }
     680        }
     681    }
    231682
    232683    // Setup visualisations, zero the visualisations buffers
    233684    prepareVisuals();
     
    273724        pSoundStretch = NULL;
    274725    }
    275726
     727    if (encoder)
     728    {
     729        delete encoder;
     730        encoder = NULL;
     731    }
     732
    276733    CloseDevice();
    277734
    278735    killAudioLock.unlock();
     
    286743
    287744void AudioOutputBase::Pause(bool paused)
    288745{
     746    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    289747    pauseaudio = paused;
    290748    audio_actually_paused = false;
    291749}
     
    368826       The reason is that computing 'audiotime' requires acquiring the audio
    369827       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    370828       from the audio thread, and then call this from the video thread. */
    371     int ret;
     829    long long ret;
    372830    struct timeval now;
    373831
    374832    if (audiotime == 0)
     
    380838
    381839    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    382840    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    383     ret = (int)(ret * audio_stretchfactor);
     841    ret = (long long)(ret * audio_stretchfactor);
    384842
     843#if 1
     844    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     845            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     846            .arg(now.tv_sec).arg(now.tv_usec)
     847            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     848            .arg(ret)
     849            .arg(audiotime)
     850            .arg(audio_stretchfactor)
     851           );
     852#endif
     853
    385854    ret += audiotime;
    386855
    387856    pthread_mutex_unlock(&avsync_lock);
    388     return ret;
     857    return (int)ret;
    389858}
    390859
    391860void AudioOutputBase::SetAudiotime(void)
     
    422891    // include algorithmic latencies
    423892    if (pSoundStretch)
    424893    {
     894        // add the effect of any unused but processed samples, AC3 reencode does this
     895        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    425896        // add the effect of unprocessed samples in time stretch algo
    426897        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    427898                              audio_bytes_per_sample) / audio_stretchfactor);
    428899    }
    429                
     900
    430901    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    431902                                   (audio_bytes_per_sample * effdspstretched));
    432903 
    433904    gettimeofday(&audiotime_updated, NULL);
     905#if 1
     906    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     907            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     908            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     909            .arg(audiotime)
     910            .arg(audbuf_timecode)
     911            .arg(totalbuffer)
     912            .arg(soundcard_buffer)
     913            .arg(effdspstretched)
     914            .arg(audio_bytes_per_sample)
     915            .arg(audio_stretchfactor)
     916           );
     917#endif
    434918
    435919    pthread_mutex_unlock(&avsync_lock);
    436920    pthread_mutex_unlock(&audio_buflock);
     
    498982    // NOTE: This function is not threadsafe
    499983
    500984    int afree = audiofree(true);
    501     int len = samples * audio_bytes_per_sample;
     985    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    502986
    503987    // Check we have enough space to write the data
    504988    if (need_resampler && src_ctx)
     
    509993        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
    510994                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    511995                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    512                 .arg(timecode));
    513 
     996                .arg(LONGLONGCONVERT timecode));
    514997        return false; // would overflow
    515998    }
    516999
     
    5471030
    5481031int AudioOutputBase::WaitForFreeSpace(int samples)
    5491032{
    550     int len = samples * audio_bytes_per_sample;
     1033    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     1034    int len = samples * abps;
    5511035    int afree = audiofree(false);
    5521036
    5531037    while (len > afree)
    5541038    {
    5551039        if (blocking)
    5561040        {
    557             VERBOSE(VB_AUDIO, LOC + "Waiting for free space");
     1041            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space");
    5581042            // wait for more space
    5591043            pthread_cond_wait(&audio_bufsig, &audio_buflock);
    5601044            afree = audiofree(false);
    5611045        }
    5621046        else
    5631047        {
    564             VERBOSE(VB_IMPORTANT, LOC_ERR +
    565                     "Audio buffer overflow, audio data lost!");
    566             samples = afree / audio_bytes_per_sample;
    567             len = samples * audio_bytes_per_sample;
     1048            VERBOSE(VB_IMPORTANT, LOC_ERR +
     1049                    QString("Audio buffer overflow, %1 audio samples lost!")
     1050                        .arg(samples-afree / abps));
     1051            samples = afree / abps;
     1052            len = samples * abps;
    5681053            if (src_ctx)
    5691054            {
    5701055                int error = src_reset(src_ctx);
     
    5891074   
    5901075    int afree = audiofree(false);
    5911076
    592     VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    593             LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    594             .arg(samples * audio_bytes_per_sample)
    595             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     1077    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     1078    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1079            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5")
     1080            .arg(samples)
     1081            .arg(samples * abps)
     1082            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    5961083   
    5971084    len = WaitForFreeSpace(samples);
    5981085
    5991086    if (interleaved)
    6001087    {
    6011088        char *mybuf = (char*)buffer;
     1089#if 0
     1090#ifdef ENABLE_AC3_DECODER
     1091        if (audio_channels == 6)
     1092        {
     1093            // reorder samples from L:C:R:LL:LR:LFE to L:R:LL:LR:C:LFE
     1094            int i;
     1095            short * p = (short*)buffer;
     1096            for(i=0;i<samples;i++,p+=6)
     1097            {
     1098                short x = p[1];
     1099                p[1] = p[2];
     1100                p[2] = p[3];
     1101                p[3] = p[4];
     1102                p[4] = x;
     1103            }
     1104        }
     1105#endif
     1106#endif
    6021107        int bdiff = AUDBUFSIZE - org_waud;
    6031108        if (bdiff < len)
    6041109        {
     
    6291134
    6301135    if (pSoundStretch)
    6311136    {
     1137
    6321138        // does not change the timecode, only the number of samples
    6331139        // back to orig pos
    6341140        org_waud = waud;
    6351141        int bdiff = AUDBUFSIZE - org_waud;
    636         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     1142        int nSamplesToEnd = bdiff/abps;
    6371143        if (bdiff < len)
    6381144        {
    6391145            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    6401146                                      org_waud), nSamplesToEnd);
    6411147            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    642                                       (len - bdiff) / audio_bytes_per_sample);
     1148                                      (len - bdiff) / abps);
    6431149        }
    6441150        else
    6451151        {
    6461152            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    647                                       org_waud), len / audio_bytes_per_sample);
     1153                                      org_waud), len / abps);
    6481154        }
    6491155
    650         int newLen = 0;
    651         int nSamples;
    652         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    653                                audio_bytes_per_sample);
    654         do
     1156        if (encoder)
    6551157        {
    656             int samplesToGet = len/audio_bytes_per_sample;
    657             if (samplesToGet > nSamplesToEnd)
     1158            // pull out a packet's worth and reencode it until we dont have enough
     1159            // for any more packets
     1160            soundtouch::SAMPLETYPE* temp_buff =
     1161                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     1162            size_t frameSize = encoder->FrameSize()/abps;
     1163            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1164                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     1165                    .arg(frameSize)
     1166                    .arg(encoder->FrameSize())
     1167                    .arg(pSoundStretch->numSamples())
     1168                   );
     1169            // process the same number of samples as it creates a full encoded buffer
     1170            // just like before
     1171            while (pSoundStretch->numSamples() >= frameSize)
    6581172            {
    659                 samplesToGet = nSamplesToEnd;   
     1173                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     1174                int amount = encoder->Encode(temp_buff);
     1175                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1176                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1177                        .arg(amount)
     1178                        .arg(got)
     1179                        .arg(pSoundStretch->numSamples())
     1180                       );
     1181                if (amount == 0)
     1182                    continue;
     1183                //len = WaitForFreeSpace(amount);
     1184                char * ob = encoder->GetOutBuff();
     1185                if (amount >= bdiff)
     1186                {
     1187                    memcpy(audiobuffer + org_waud, ob, bdiff);
     1188                    ob += bdiff;
     1189                    amount -= bdiff;
     1190                    org_waud = 0;
     1191                }
     1192                if (amount > 0)
     1193                    memcpy(audiobuffer + org_waud, ob, amount);
     1194                bdiff = AUDBUFSIZE - amount;
     1195                org_waud += amount;
    6601196            }
    661 
    662             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    663                                       (audiobuffer + org_waud), samplesToGet);
    664             if (nSamples == nSamplesToEnd)
     1197        }
     1198        else
     1199        {
     1200            int newLen = 0;
     1201            int nSamples;
     1202            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1203                                   audio_bytes_per_sample);
     1204            do
    6651205            {
    666                 org_waud = 0;
    667                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
    668             }
    669             else
    670             {
    671                 org_waud += nSamples * audio_bytes_per_sample;
    672                 nSamplesToEnd -= nSamples;
    673             }
     1206                int samplesToGet = len/audio_bytes_per_sample;
     1207                if (samplesToGet > nSamplesToEnd)
     1208                {
     1209                    samplesToGet = nSamplesToEnd;   
     1210                }
    6741211
    675             newLen += nSamples * audio_bytes_per_sample;
    676             len -= nSamples * audio_bytes_per_sample;
    677         } while (nSamples > 0);
     1212                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1213                                          (audiobuffer + org_waud), samplesToGet);
     1214                if (nSamples == nSamplesToEnd)
     1215                {
     1216                    org_waud = 0;
     1217                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1218                }
     1219                else
     1220                {
     1221                    org_waud += nSamples * audio_bytes_per_sample;
     1222                    nSamplesToEnd -= nSamples;
     1223                }
     1224
     1225                newLen += nSamples * audio_bytes_per_sample;
     1226                len -= nSamples * audio_bytes_per_sample;
     1227            } while (nSamples > 0);
     1228        }
    6781229    }
    6791230
    6801231    waud = org_waud;
     
    7501301            space_on_soundcard = getSpaceOnSoundcard();
    7511302
    7521303            if (space_on_soundcard != last_space_on_soundcard) {
    753                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1304                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7541305                        .arg(space_on_soundcard));
    7551306                last_space_on_soundcard = space_on_soundcard;
    7561307            }
     
    7631314                    WriteAudio(zeros, fragment_size);
    7641315                } else {
    7651316                    // this should never happen now -dag
    766                     VERBOSE(VB_AUDIO, LOC +
     1317                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7671318                            QString("waiting for space on soundcard "
    7681319                                    "to write zeros: have %1 need %2")
    7691320                            .arg(space_on_soundcard).arg(fragment_size));
     
    7991350        if (fragment_size > audiolen(true))
    8001351        {
    8011352            if (audiolen(true) > 0)  // only log if we're sending some audio
    802                 VERBOSE(VB_AUDIO, LOC +
     1353                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031354                        QString("audio waiting for buffer to fill: "
    8041355                                "have %1 want %2")
    8051356                        .arg(audiolen(true)).arg(fragment_size));
    8061357
    807             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1358            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8081359            pthread_mutex_lock(&audio_buflock);
    8091360            pthread_cond_broadcast(&audio_bufsig);
    8101361            pthread_mutex_unlock(&audio_buflock);
     
    8181369        if (fragment_size > space_on_soundcard)
    8191370        {
    8201371            if (space_on_soundcard != last_space_on_soundcard) {
    821                 VERBOSE(VB_AUDIO, LOC +
     1372                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221373                        QString("audio waiting for space on soundcard: "
    8231374                                "have %1 need %2")
    8241375                        .arg(space_on_soundcard).arg(fragment_size));
     
    8801431
    8811432        /* update raud */
    8821433        raud = (raud + fragment_size) % AUDBUFSIZE;
    883         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1434        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8841435        pthread_cond_broadcast(&audio_bufsig);
    8851436
    8861437        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

     
    4949    QString real_device = (audio_passthru) ?
    5050        audio_passthru_device : audio_main_device;
    5151
     52    int index;
     53    if ((index=real_device.find('|'))>=0)
     54    {
     55        if (audio_channels != 2)
     56            real_device = real_device.mid(index+1);
     57        else
     58            real_device = real_device.left(index);
     59    }
     60
    5261    VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.")
    5362            .arg(real_device));
    5463
     
    8695    }
    8796    else
    8897    {
    89         fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
    90         buffer_time = 500000;  // .5 seconds
     98        //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     99        //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits
     100        fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30);
     101        buffer_time = 100000;  // .5 seconds
    91102        period_time = buffer_time / 4;  // 4 interrupts per buffer
    92103    }
    93104
     
    159170   
    160171    tmpbuf = aubuf;
    161172
    162     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     173    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    163174            .arg(size).arg(frames));
    164175   
    165176    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#ifdef CONFIG_LIBDTS
    31313153         vgrp0->addChild(DTSPassThrough());
    31323154#endif
     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

     
    11INCLUDEPATH += ../../libs/libmythui ../../libs/libmyth
    22
    3 LIBS += -L../../libs/libmyth -L../../libs/libmythui
     3LIBS += -L../../libs/libmyth -L../../libs/libmythui -L../../libs/libavcodec -L../../libs/libavutil
    44
    55include ( ../../config.mak )
    66include ( ../../settings.pro )
     
    99TARGET = mythuitest
    1010CONFIG += thread opengl
    1111
    12 LIBS += -lmythui-$$LIBVERSION -lmyth-$$LIBVERSION $$EXTRA_LIBS
     12LIBS += -lmythui-$$LIBVERSION -lmyth-$$LIBVERSION -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION $$EXTRA_LIBS
    1313
    1414isEmpty(QMAKE_EXTENSION_SHLIB) {
    1515  QMAKE_EXTENSION_SHLIB=so
     
    1919}
    2020TARGETDEPS += ../../libs/libmythui/libmythui-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
    2121TARGETDEPS += ../../libs/libmyth/libmyth-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     22TARGETDEPS += ../../libs/libavcodec/libmythavcodec-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
     23TARGETDEPS += ../../libs/libavutil/libmythavutil-$${LIBVERSION}.$${QMAKE_EXTENSION_SHLIB}
    2224
    2325macx {
    2426    # Duplication of source with libmyth (e.g. oldsettings.cpp)
  • 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

     
    5252#define MAX_AC3_FRAME_SIZE 6144
    5353
    5454/** Set to zero to allow any number of AC3 channels. */
     55#define MAXCHANNELSELECT 1
     56#if MAXCHANNELSELECT
     57#define MAX_OUTPUT_CHANNELS compiler error
     58#else
    5559#define MAX_OUTPUT_CHANNELS 2
     60#endif
    5661
    5762static int cc608_parity(uint8_t byte);
    5863static int cc608_good_parity(const int *parity_table, uint16_t data);
     
    419424#ifdef CONFIG_LIBDTS
    420425    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    421426#endif
     427    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    422428
    423429    audioIn.sample_size = -32; // force SetupAudioStream to run once
    424430    itv = GetNVP()->GetInteractiveTV();
     
    15891640                            <<") type ("<<codec_type_string(enc->codec_type)
    15901641                            <<") already open, leaving it alone.");
    15911642                }
     1643#if MAXCHANNELSELECT
     1644                if (enc->cqp != max_channels)
     1645                {
     1646                    VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(enc->cqp));
     1647                    enc->cqp = max_channels;
     1648                }
     1649#endif
    15921650                //assert(enc->codec_id);
     1651                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
     1652#if 0
     1653                if (enc->channels > 2)
     1654                    enc->channels = 2;
     1655#endif
     1656#if MAXCHANNELSELECT && 0
     1657                if (enc->channels == 0)
     1658                {
     1659                    //we have had a problem in parsing the codec params in this stream
     1660                    //enc->channels = max_channels;
     1661                }
     1662#endif
    15931663
     1664#if 0
    15941665                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    15951666                if (enc->codec_id == CODEC_ID_DTS)
    15961667                {
     
    15991670                    // enc->bit_rate = what??;
    16001671                }
    16011672                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1673#endif
    16021674
    16031675                bitrate += enc->bit_rate;
    16041676                break;
     
    32703358                    if (!curstream->codec->channels)
    32713359                    {
    32723360                        QMutexLocker locker(&avcodeclock);
     3361#if MAXCHANNELSELECT
     3362                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3363                        curstream->codec->cqp = max_channels;
     3364                        curstream->codec->channels = audioOut.channels;
     3365#else
    32733366                        curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3367#endif
    32743368                        ret = avcodec_decode_audio(
    32753369                            curstream->codec, audioSamples,
    32763370                            &data_size, ptr, len);
    32773371
    32783372                        reselectAudioTrack |= curstream->codec->channels;
    32793373                    }
     3374#if MAXCHANNELSELECT
     3375                    if (curstream->codec->cqp != max_channels)
     3376                    {
     3377                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(curstream->codec->cqp));
     3378                        curstream->codec->cqp = max_channels;
     3379                    }
     3380#endif
    32803381
    32813382                    if (reselectAudioTrack)
    32823383                    {
     
    33303431                    {
    33313432                        AVCodecContext *ctx = curstream->codec;
    33323433
     3434#if MAXCHANNELSELECT
    33333435                        if ((ctx->channels == 0) ||
     3436                            (ctx->channels > audioOut.channels))
     3437                            ctx->channels = audioOut.channels;
     3438#else
     3439                        if ((ctx->channels == 0) ||
    33343440                            (ctx->channels > MAX_OUTPUT_CHANNELS))
    33353441                            ctx->channels = MAX_OUTPUT_CHANNELS;
     3442#endif
    33363443
    33373444                        ret = avcodec_decode_audio(
    33383445                            ctx, audioSamples, &data_size, ptr, len);
     
    36853792
    36863793void AvFormatDecoder::SetDisablePassThrough(bool disable)
    36873794{
     3795#if MAXCHANNELSELECT
     3796    // can only disable never reenable as once tiemstretch is on its on for the session
     3797    if (disable_passthru)
     3798        return;
     3799#endif
    36883800    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    36893801    {
    36903802        disable_passthru = disable;
    36913803        return;
    36923804    }
    3693 
     3805 
    36943806    if (disable != disable_passthru)
    36953807    {
    36963808        disable_passthru = disable;
     
    37173829    AVCodecContext *codec_ctx = NULL;
    37183830    AudioInfo old_in  = audioIn;
    37193831    AudioInfo old_out = audioOut;
     3832    bool using_passthru = false;
    37203833
    37213834    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    37223835        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    37263839    {
    37273840        assert(curstream);
    37283841        assert(curstream->codec);
    3729         codec_ctx = curstream->codec;       
     3842        codec_ctx = curstream->codec;
    37303843        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3731                                 !disable_passthru &&
    37323844                                (codec_ctx->codec_id == CODEC_ID_AC3));
    37333845        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3734                                 !disable_passthru &&
    37353846                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3847        using_passthru = do_ac3_passthru || do_dts_passthru;
    37363848        info = AudioInfo(codec_ctx->codec_id,
    37373849                         codec_ctx->sample_rate, codec_ctx->channels,
    3738                          do_ac3_passthru || do_dts_passthru);
     3850                         using_passthru && !disable_passthru);
    37393851    }
    37403852
    37413853    if (info == audioIn)
    37423854        return false; // no change
    37433855
     3856    QString ptmsg = "";
     3857    if (using_passthru)
     3858    {
     3859        ptmsg = QString(" using passthru");
     3860    }
    37443861    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    37453862            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    37463863
    37473864    audioOut = audioIn = info;
     3865#if MAXCHANNELSELECT
     3866    if (using_passthru)
     3867#else
    37483868    if (audioIn.do_passthru)
     3869#endif
    37493870    {
    37503871        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3751         audioOut.channels    = 2;
    3752         audioOut.sample_rate = 48000;
    3753         audioOut.sample_size = 4;
     3872        AudioInfo digInfo = audioOut;
     3873        if (!disable_passthru)
     3874        {
     3875            digInfo.channels    = 2;
     3876            digInfo.sample_rate = 48000;
     3877            digInfo.sample_size = 4;
     3878        }
     3879        if (audioOut.channels > max_channels)
     3880        {
     3881            audioOut.channels = max_channels;
     3882            audioOut.sample_size = audioOut.channels * 2;
     3883            codec_ctx->channels = audioOut.channels;
     3884        }
     3885#if MAXCHANNELSELECT
     3886        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3887                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3888                .arg(digInfo.toString())
     3889                .arg(old_in.toString()).arg(old_out.toString())
     3890                .arg(audioIn.toString()).arg(audioOut.toString()));
     3891
     3892        if (digInfo.sample_rate > 0)
     3893            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3894
     3895        //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     3896        //                         audioOut.sample_rate);
     3897        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3898                                 digInfo.sample_rate, audioIn.do_passthru);
     3899        // allow the audio stuff to reencode
     3900        GetNVP()->SetAudioCodec(codec_ctx);
     3901        GetNVP()->ReinitAudio();
     3902        return true;
     3903#endif
    37543904    }
     3905#if MAXCHANNELSELECT
    37553906    else
    37563907    {
     3908        if (audioOut.channels > max_channels)
     3909        {
     3910            audioOut.channels = max_channels;
     3911            audioOut.sample_size = audioOut.channels * 2;
     3912            codec_ctx->channels = audioOut.channels;
     3913        }
     3914    }
     3915    bool audiook;
     3916#if 0
     3917    do
     3918    {
     3919#endif
     3920#else
     3921    else
     3922    {
    37573923        if (audioOut.channels > MAX_OUTPUT_CHANNELS)
    37583924        {
    37593925            audioOut.channels = MAX_OUTPUT_CHANNELS;
     
    37613927            codec_ctx->channels = MAX_OUTPUT_CHANNELS;
    37623928        }
    37633929    }
     3930#endif
    37643931
    37653932    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    37663933            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    37733940    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    37743941                             audioOut.sample_rate,
    37753942                             audioIn.do_passthru);
    3776     GetNVP()->ReinitAudio();
     3943    // allow the audio stuff to reencode
     3944    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3945    QString errMsg = GetNVP()->ReinitAudio();
     3946#if MAXCHANNELSELECT
     3947        audiook = errMsg.isEmpty();
     3948#if 0
     3949        if (!audiook)
     3950        {
     3951            switch (audioOut.channels)
     3952            {
     3953#if 0
     3954                case 8:
     3955                    audioOut.channels = 6;
     3956                    break;
     3957#endif
     3958                case 6:
     3959#if 0
     3960                    audioOut.channels = 5;
     3961                    break;
     3962                case 5:
     3963                    audioOut.channels = 4;
     3964                    break;
     3965                case 4:
     3966                    audioOut.channels = 3;
     3967                    break;
     3968                case 3:
     3969#endif
     3970                    audioOut.channels = 2;
     3971                    break;
     3972#if 0
     3973                case 2:
     3974                    audioOut.channels = 1;
     3975                    break;
     3976#endif
     3977                default:
     3978                    // failed to reconfigure under any circumstances
     3979                    audiook = true;
     3980                    audioOut.channels = 0;
     3981                    break;
     3982            }
     3983            audioOut.sample_size = audioOut.channels * 2;
     3984            codec_ctx->channels = audioOut.channels;
     3985        }
     3986    } while (!audiook);
     3987#endif
     3988#endif
    37773989
    37783990    return true;
    37793991}
  • 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; }
     
    679680    int      audio_bits;
    680681    int      audio_samplerate;
    681682    float    audio_stretchfactor;
     683    void     *audio_codec;
    682684    bool     audio_passthru;
    683685
    684686    // Picture-in-Picture
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    206206      audio_passthru_device(QString::null),
    207207      audio_channels(2),            audio_bits(-1),
    208208      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     209      audio_codec(NULL),
    209210      // Picture-in-Picture
    210211      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    211212      // Preview window support
     
    734735    if (audioOutput)
    735736    {
    736737        audioOutput->Reconfigure(audio_bits, audio_channels,
    737                                  audio_samplerate, audio_passthru);
     738                                 audio_samplerate, audio_passthru,
     739                                 audio_codec);
    738740        errMsg = audioOutput->GetError();
    739741        if (!errMsg.isEmpty())
    740742            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    35443556    audio_passthru = passthru;
    35453557}
    35463558
     3559void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3560{
     3561    audio_codec = ac;
     3562}
     3563
    35473564void NuppelVideoPlayer::SetEffDsp(int dsprate)
    35483565{
    35493566    if (audioOutput)
  • libs/libavcodec/a52dec.c

     
    143143    }
    144144}
    145145
     146static inline int16_t convert (int32_t i)
     147{
     148    if (i > 0x43c07fff)
     149        return 32767;
     150    else if (i < 0x43bf8000)
     151        return -32768;
     152    else
     153        return i - 0x43c00000;
     154}
     155
     156void float2s16_2 (float * _f, int16_t * s16)
     157{
     158    int i;
     159    int32_t * f = (int32_t *) _f;
     160
     161    for (i = 0; i < 256; i++) {
     162        s16[2*i] = convert (f[i]);
     163        s16[2*i+1] = convert (f[i+256]);
     164    }
     165}
     166
     167void float2s16_4 (float * _f, int16_t * s16)
     168{
     169    int i;
     170    int32_t * f = (int32_t *) _f;
     171
     172    for (i = 0; i < 256; i++) {
     173        s16[4*i] = convert (f[i]);
     174        s16[4*i+1] = convert (f[i+256]);
     175        s16[4*i+2] = convert (f[i+512]);
     176        s16[4*i+3] = convert (f[i+768]);
     177    }
     178}
     179
     180void float2s16_5 (float * _f, int16_t * s16)
     181{
     182    int i;
     183    int32_t * f = (int32_t *) _f;
     184
     185    for (i = 0; i < 256; i++) {
     186        s16[5*i] = convert (f[i]);
     187        s16[5*i+1] = convert (f[i+256]);
     188        s16[5*i+2] = convert (f[i+512]);
     189        s16[5*i+3] = convert (f[i+768]);
     190        s16[5*i+4] = convert (f[i+1024]);
     191    }
     192}
     193
     194#define LIKEAC3DEC 1
     195int channels_multi (int flags)
     196{
     197    if (flags & A52_LFE)
     198        return 6;
     199    else if (flags & 1) /* center channel */
     200        return 5;
     201    else if ((flags & A52_CHANNEL_MASK) == A52_2F2R)
     202        return 4;
     203    else
     204        return 2;
     205}
     206
     207void float2s16_multi (float * _f, int16_t * s16, int flags)
     208{
     209    int i;
     210    int32_t * f = (int32_t *) _f;
     211
     212    switch (flags) {
     213    case A52_MONO:
     214        for (i = 0; i < 256; i++) {
     215            s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
     216            s16[5*i+4] = convert (f[i]);
     217        }
     218        break;
     219    case A52_CHANNEL:
     220    case A52_STEREO:
     221    case A52_DOLBY:
     222        float2s16_2 (_f, s16);
     223        break;
     224    case A52_3F:
     225        for (i = 0; i < 256; i++) {
     226            s16[5*i] = convert (f[i]);
     227            s16[5*i+1] = convert (f[i+512]);
     228            s16[5*i+2] = s16[5*i+3] = 0;
     229            s16[5*i+4] = convert (f[i+256]);
     230        }
     231        break;
     232    case A52_2F2R:
     233        float2s16_4 (_f, s16);
     234        break;
     235    case A52_3F2R:
     236        float2s16_5 (_f, s16);
     237        break;
     238    case A52_MONO | A52_LFE:
     239        for (i = 0; i < 256; i++) {
     240#if LIKEAC3DEC
     241            s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     242            s16[6*i+1] = convert (f[i+256]);
     243            s16[6*i+5] = convert (f[i]);
     244#else
     245            s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
     246            s16[6*i+4] = convert (f[i+256]);
     247            s16[6*i+5] = convert (f[i]);
     248#endif
     249        }
     250        break;
     251    case A52_CHANNEL | A52_LFE:
     252    case A52_STEREO | A52_LFE:
     253    case A52_DOLBY | A52_LFE:
     254        for (i = 0; i < 256; i++) {
     255#if LIKEAC3DEC
     256            s16[6*i] = convert (f[i+256]);
     257            s16[6*i+2] = convert (f[i+512]);
     258            s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0;
     259            s16[6*i+5] = convert (f[i]);
     260#else
     261            s16[6*i] = convert (f[i+256]);
     262            s16[6*i+1] = convert (f[i+512]);
     263            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     264            s16[6*i+5] = convert (f[i]);
     265#endif
     266        }
     267        break;
     268    case A52_3F | A52_LFE:
     269        for (i = 0; i < 256; i++) {
     270#if LIKEAC3DEC
     271            s16[6*i] = convert (f[i+256]);
     272            s16[6*i+2] = convert (f[i+768]);
     273            s16[6*i+3] = s16[6*i+4] = 0;
     274            s16[6*i+1] = convert (f[i+512]);
     275            s16[6*i+5] = convert (f[i]);
     276#else
     277            s16[6*i] = convert (f[i+256]);
     278            s16[6*i+1] = convert (f[i+768]);
     279            s16[6*i+2] = s16[6*i+3] = 0;
     280            s16[6*i+4] = convert (f[i+512]);
     281            s16[6*i+5] = convert (f[i]);
     282#endif
     283        }
     284        break;
     285    case A52_2F2R | A52_LFE:
     286        for (i = 0; i < 256; i++) {
     287#if LIKEAC3DEC
     288            s16[6*i] = convert (f[i+256]);
     289            s16[6*i+1] = 0;
     290            s16[6*i+2] = convert (f[i+512]);
     291            s16[6*i+3] = convert (f[i+768]);
     292            s16[6*i+4] = convert (f[i+1024]);
     293            s16[6*i+5] = convert (f[i]);
     294#else
     295            s16[6*i] = convert (f[i+256]);
     296            s16[6*i+1] = convert (f[i+512]);
     297            s16[6*i+2] = convert (f[i+768]);
     298            s16[6*i+3] = convert (f[i+1024]);
     299            s16[6*i+4] = 0;
     300            s16[6*i+5] = convert (f[i]);
     301#endif
     302        }
     303        break;
     304    case A52_3F2R | A52_LFE:
     305        for (i = 0; i < 256; i++) {
     306#if LIKEAC3DEC
     307            s16[6*i] = convert (f[i+256]);
     308            s16[6*i+1] = convert (f[i+512]);
     309            s16[6*i+2] = convert (f[i+768]);
     310            s16[6*i+3] = convert (f[i+1024]);
     311            s16[6*i+4] = convert (f[i+1280]);
     312            s16[6*i+5] = convert (f[i]);
     313#else
     314            s16[6*i] = convert (f[i+256]);
     315            s16[6*i+1] = convert (f[i+768]);
     316            s16[6*i+2] = convert (f[i+1024]);
     317            s16[6*i+3] = convert (f[i+1280]);
     318            s16[6*i+4] = convert (f[i+512]);
     319            s16[6*i+5] = convert (f[i]);
     320#endif
     321        }
     322        break;
     323    }
     324}
     325
     326
    146327/**** end */
    147328
    148329#define HEADER_SIZE 7
     
    168349        len = s->inbuf_ptr - s->inbuf;
    169350        if (s->frame_size == 0) {
    170351            /* no header seen : find one. We need at least 7 bytes to parse it */
     352            //av_log(avctx, AV_LOG_DEBUG, "ac3dec: no frame processing, len %d buf_size %d\n",len,buf_size);
    171353            len = HEADER_SIZE - len;
    172354            if (len > buf_size)
    173355                len = buf_size;
     
    186368                    /* update codec info */
    187369                    avctx->sample_rate = sample_rate;
    188370                    s->channels = ac3_channels[s->flags & 7];
     371                    if (avctx->cqp >= 0)
     372                        avctx->channels = avctx->cqp;
    189373                    if (s->flags & A52_LFE)
    190374                        s->channels++;
    191375                    if (avctx->channels == 0)
    192376                        /* No specific number of channel requested */
    193377                        avctx->channels = s->channels;
    194378                    else if (s->channels < avctx->channels) {
    195                         av_log(avctx, AV_LOG_ERROR, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len);
     379                        //av_log(avctx, AV_LOG_ERROR, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len);
    196380                        avctx->channels = s->channels;
    197381                    }
    198382                    avctx->bit_rate = bit_rate;
     
    208392            s->inbuf_ptr += len;
    209393            buf_size -= len;
    210394        } else {
     395            int chans;
    211396            flags = s->flags;
    212397            if (avctx->channels == 1)
    213398                flags = A52_MONO;
    214             else if (avctx->channels == 2)
    215                 flags = A52_STEREO;
     399            else if (avctx->channels == 2) {
     400                if (s->channels>2)
     401                    flags = A52_DOLBY;
     402                else
     403                    flags = A52_STEREO;
     404            }
    216405            else
    217406                flags |= A52_ADJUST_LEVEL;
    218407            level = 1;
     408            chans = channels_multi(flags);
    219409            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    220410            fail:
    221411                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    226416            for (i = 0; i < 6; i++) {
    227417                if (s->a52_block(s->state))
    228418                    goto fail;
    229                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     419                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    230420            }
    231421            s->inbuf_ptr = s->inbuf;
    232422            s->frame_size = 0;
    233             *data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
     423            *data_size = 6 * chans * 256 * sizeof(int16_t);
    234424            break;
    235425        }
    236426    }