Ticket #1104: mythtv_ac3.22.patch

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

     
    3535SOURCES += virtualkeyboard.cpp mythobservable.cpp mythsocket.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
  • 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

     
    1616// MythTV headers
    1717#include "audiooutputbase.h"
    1818
     19extern "C" {
     20#include "libavcodec/avcodec.h"
     21#include "libavcodec/liba52/a52.h"
     22}
     23
     24#if QT_VERSION < 0x030200
     25#define LONGLONGCONVERT (long)
     26#else
     27#define LONGLONGCONVERT
     28#endif
     29
     30#define LOC QString("DEnc: ");
     31#define MAX_AC3_FRAME_SIZE 6144
     32class DigitalEncoder
     33{
     34public:
     35    DigitalEncoder();
     36    ~DigitalEncoder();
     37    void Dispose();
     38    bool Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     39    size_t Encode(short * buff);
     40
     41    // if needed
     42    char * GetFrameBuffer()
     43    {
     44        if (!frame_buffer && av_context)
     45        {
     46            frame_buffer = new char [one_frame_bytes];
     47        }
     48        return frame_buffer;
     49    }   
     50    size_t FrameSize() const { return one_frame_bytes; }
     51    char * GetOutBuff() const { return outbuf; }
     52
     53    size_t audio_bytes_per_sample;
     54private:
     55    AVCodecContext *av_context;
     56    char * outbuf;
     57    char * frame_buffer;
     58    int outbuf_size;
     59    size_t one_frame_bytes;
     60};
     61
     62DigitalEncoder::DigitalEncoder()
     63{
     64    av_context = NULL;
     65    outbuf = NULL;
     66    outbuf_size = 0;
     67    one_frame_bytes = 0;
     68    frame_buffer = NULL;
     69}
     70
     71DigitalEncoder::~DigitalEncoder()
     72{
     73    Dispose();
     74}
     75
     76void DigitalEncoder::Dispose()
     77{
     78    if (av_context)
     79    {
     80        avcodec_close(av_context);
     81        av_free(av_context);
     82        av_context = NULL;
     83    }
     84    if (outbuf)
     85    {
     86        delete [] outbuf;
     87        outbuf = NULL;
     88        outbuf_size = 0;
     89    }
     90    if (frame_buffer)
     91    {
     92        delete [] frame_buffer;
     93        frame_buffer = NULL;
     94        one_frame_bytes = 0;
     95    }
     96}
     97
     98//CODEC_ID_AC3
     99bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     100{
     101    AVCodec * codec;
     102    int ret;
     103
     104    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     105            .arg(codec_id_string(codec_id))
     106            .arg(bitrate)
     107            .arg(samplerate)
     108            .arg(channels));
     109    //codec = avcodec_find_encoder(codec_id);
     110    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     111    codec = avcodec_find_encoder(CODEC_ID_AC3);
     112    if (!codec)
     113    {
     114        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     115        return false;
     116    }
     117    av_context = avcodec_alloc_context();
     118    av_context->bit_rate = bitrate;
     119    av_context->sample_rate = samplerate;
     120    av_context->channels = channels;
     121    // open it */
     122    if ((ret = avcodec_open(av_context, codec)) < 0)
     123    {
     124        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     125        Dispose();
     126        return false;
     127    }
     128
     129    size_t bytes_per_frame = av_context->channels * sizeof(short);
     130    audio_bytes_per_sample = bytes_per_frame;
     131    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     132
     133    outbuf_size = 16384;    // ok for AC3 but DTS?
     134    outbuf = new char [outbuf_size];
     135    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     136            .arg(av_context->frame_size)
     137            .arg(bytes_per_frame)
     138            .arg(one_frame_bytes)
     139           );
     140
     141    return true;
     142}
     143
     144static int DTS_SAMPLEFREQS[16] =
     145{
     146    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     147    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     148};
     149
     150static int DTS_BITRATES[30] =
     151{
     152    32000,    56000,    64000,    96000,    112000,   128000,
     153    192000,   224000,   256000,   320000,   384000,   448000,
     154    512000,   576000,   640000,   768000,   896000,   1024000,
     155    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     156    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     157};
     158
     159static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     160                             int *nblks, int *sfreq)
     161{
     162    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     163               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     164
     165    if (id != 0x7ffe8001)
     166        return -1;
     167
     168    int ftype = indata_ptr[4] >> 7;
     169
     170    int surp = (indata_ptr[4] >> 2) & 0x1f;
     171    surp = (surp + 1) % 32;
     172
     173    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     174    ++*nblks;
     175
     176    int fsize = (indata_ptr[5] & 0x03) << 12 |
     177                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     178    ++fsize;
     179
     180    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     181    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     182
     183    if (ftype != 1)
     184    {
     185        VERBOSE(VB_IMPORTANT, LOC +
     186                QString("DTS: Termination frames not handled (ftype %1)")
     187                .arg(ftype));
     188        return -1;
     189    }
     190
     191    if (*sfreq != 13)
     192    {
     193        VERBOSE(VB_IMPORTANT, LOC +
     194                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     195        return -1;
     196    }
     197
     198    if ((fsize > 8192) || (fsize < 96))
     199    {
     200        VERBOSE(VB_IMPORTANT, LOC +
     201                QString("DTS: fsize: %1 invalid").arg(fsize));
     202        return -1;
     203    }
     204
     205    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     206        *nblks != 64 && *nblks != 128 && ftype == 1)
     207    {
     208        VERBOSE(VB_IMPORTANT, LOC +
     209                QString("DTS: nblks %1 not valid for normal frame")
     210                .arg(*nblks));
     211        return -1;
     212    }
     213
     214    return fsize;
     215}
     216
     217static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     218                        int *sample_rate, int *bit_rate)
     219{
     220    int nblks;
     221    int rate;
     222    int sfreq;
     223
     224    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     225    if (fsize >= 0)
     226    {
     227        if (rate >= 0 && rate <= 29)
     228            *bit_rate = DTS_BITRATES[rate];
     229        else
     230            *bit_rate = 0;
     231        if (sfreq >= 1 && sfreq <= 15)
     232            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     233        else
     234            *sample_rate = 0;
     235    }
     236    return fsize;
     237}
     238
     239static int encode_frame(
     240        bool dts,
     241        unsigned char *data,
     242        size_t &len)
     243{
     244    size_t enc_len;
     245    int flags, sample_rate, bit_rate;
     246
     247    // we don't do any length/crc validation of the AC3 frame here; presumably
     248    // the receiver will have enough sense to do that.  if someone has a
     249    // receiver that doesn't, here would be a good place to put in a call
     250    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     251    // packet is bad?  we'd need to send something that the receiver would
     252    // ignore, and if so, may as well just assume that it will ignore
     253    // anything with a bad CRC...
     254
     255    uint nr_samples = 0, block_len;
     256    if (dts)
     257    {
     258        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     259        int rate, sfreq, nblks;
     260        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     261        nr_samples = nblks * 32;
     262        block_len = nr_samples * 2 * 2;
     263    }
     264    else
     265    {
     266        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     267        block_len = MAX_AC3_FRAME_SIZE;
     268    }
     269
     270    if (enc_len == 0 || enc_len > len)
     271    {
     272        int l = len;
     273        len = 0;
     274        return l;
     275    }
     276
     277    enc_len = min((uint)enc_len, block_len - 8);
     278
     279    //uint32_t x = *(uint32_t*)(data+8);
     280    // in place swab
     281    swab(data+8, data+8, enc_len);
     282    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     283    //        QString("DigitalEncoder::Encode swab test %1 %2")
     284    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     285
     286    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     287    // they form a valid IEC958 AC3 header.
     288    data[0] = 0x72;
     289    data[1] = 0xF8;
     290    data[2] = 0x1F;
     291    data[3] = 0x4E;
     292    data[4] = 0x01;
     293    if (dts)
     294    {
     295        switch(nr_samples)
     296        {
     297            case 512:
     298                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     299                break;
     300
     301            case 1024:
     302                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     303                break;
     304
     305            case 2048:
     306                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     307                break;
     308
     309            default:
     310                VERBOSE(VB_IMPORTANT, LOC +
     311                        QString("DTS: %1-sample bursts not supported")
     312                        .arg(nr_samples));
     313                data[4] = 0x00;
     314                break;
     315        }
     316    }
     317    data[5] = 0x00;
     318    data[6] = (enc_len << 3) & 0xFF;
     319    data[7] = (enc_len >> 5) & 0xFF;
     320    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     321    len = block_len;
     322
     323    return enc_len;
     324}
     325
     326// must have exactly 1 frames worth of data
     327size_t DigitalEncoder::Encode(short * buff)
     328{
     329    int encsize = 0;
     330    size_t outsize = 0;
     331 
     332    // put data in the correct spot for encode frame
     333    outsize = avcodec_encode_audio(
     334                av_context,
     335                ((uchar*)outbuf)+8,
     336                outbuf_size-8,
     337                buff);
     338    size_t tmpsize = outsize;
     339
     340    outsize = MAX_AC3_FRAME_SIZE;
     341    encsize = encode_frame(
     342            //av_context->codec_id==CODEC_ID_DTS,
     343            false,
     344            (unsigned char*)outbuf, outsize);
     345    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     346            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     347                .arg(tmpsize)
     348                .arg(encsize)
     349                .arg(outsize)
     350           );
     351
     352    return outsize;
     353}
     354#undef LOC
    19355#define LOC QString("AO: ")
    20356#define LOC_ERR QString("AO, ERROR: ")
    21357
     
    24360    int     /*laudio_bits*/,       int               /*laudio_channels*/,
    25361    int     /*laudio_samplerate*/, AudioOutputSource lsource,
    26362    bool    lset_initial_vol,      bool              /*laudio_passthru*/) :
    27 
    28363    effdsp(0),                  effdspstretched(0),
    29364    audio_channels(-1),         audio_bytes_per_sample(0),
    30365    audio_bits(-1),             audio_samplerate(-1),
     
    35370    audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)),
    36371    audio_passthru(false),      audio_stretchfactor(1.0f),
    37372
     373    audio_codec(NULL),
    38374    source(lsource),            killaudio(false),
    39375
    40376    pauseaudio(false),          audio_actually_paused(false),
     
    46382
    47383    src_ctx(NULL),
    48384
    49     pSoundStretch(NULL),        blocking(false),
     385    pSoundStretch(NULL),       
     386    encoder(NULL),
     387    blocking(false),
    50388
    51389    lastaudiolen(0),            samples_buffered(0),
    52390    audiotime(0),
     
    61399    pthread_cond_init(&audio_bufsig, NULL);
    62400
    63401    output_audio = 0; // TODO FIXME Not POSIX compatible!
     402    configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2);
    64403
    65404    bzero(&src_data,          sizeof(SRC_DATA));
    66405    bzero(src_in,             sizeof(float) * AUDIO_SRC_IN_SIZE);
     
    108447            VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1")
    109448                                        .arg(audio_stretchfactor));
    110449            pSoundStretch = new soundtouch::SoundTouch();
    111             pSoundStretch->setSampleRate(audio_samplerate);
    112             pSoundStretch->setChannels(audio_channels);
     450            if (audio_codec)
     451            {
     452                if (!encoder)
     453                {
     454                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     455                    encoder = new DigitalEncoder();
     456                    if (!encoder->Init(audio_codec->codec_id,
     457                                audio_codec->bit_rate,
     458                                audio_codec->sample_rate,
     459                                audio_codec->channels
     460                                ))
     461                    {
     462                        // eeks
     463                        delete encoder;
     464                        encoder = NULL;
     465                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     466                    }
     467                }
     468            }
     469            if (encoder)
     470            {
     471                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     472                pSoundStretch->setChannels(audio_codec->channels);
     473            }
     474            else
     475            {
     476                pSoundStretch->setSampleRate(audio_samplerate);
     477                pSoundStretch->setChannels(audio_channels);
     478            }
    113479
    114480            pSoundStretch->setTempo(audio_stretchfactor);
    115481            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    132498}
    133499
    134500void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    135                                  int laudio_samplerate, bool laudio_passthru)
     501                                 int laudio_samplerate, bool laudio_passthru,
     502                                 void* laudio_codec)
    136503{
     504    int codec_id = CODEC_ID_NONE;
     505    int lcodec_id = CODEC_ID_NONE;
     506    int lcchannels = 0;
     507    int cchannels = 0;
     508    if (laudio_codec)
     509    {
     510        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     511        laudio_bits = 16;
     512        laudio_channels = 2;
     513        laudio_samplerate = 48000;
     514        lcchannels = ((AVCodecContext*)laudio_codec)->channels;
     515    }
     516    if (audio_codec)
     517    {
     518        codec_id = audio_codec->codec_id;
     519        cchannels = ((AVCodecContext*)audio_codec)->channels;
     520    }
     521    ClearError();
    137522    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    138         laudio_samplerate == audio_samplerate &&
    139         laudio_passthru == audio_passthru && !need_resampler)
     523        laudio_samplerate == audio_samplerate && !need_resampler &&
     524        laudio_passthru == audio_passthru &&
     525        lcodec_id == codec_id && lcchannels == cchannels)
    140526        return;
    141527
    142528    KillAudio();
     
    148534    waud = raud = 0;
    149535    audio_actually_paused = false;
    150536   
     537    bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);
    151538    audio_channels = laudio_channels;
    152539    audio_bits = laudio_bits;
    153540    audio_samplerate = laudio_samplerate;
     541    audio_codec = (AVCodecContext*)laudio_codec;
    154542    audio_passthru = laudio_passthru;
    155543    if (audio_bits != 8 && audio_bits != 16)
    156544    {
     
    169557   
    170558    numlowbuffer = 0;
    171559
     560    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3")
     561            .arg(audio_main_device).arg(audio_channels).arg(audio_samplerate));
     562   
    172563    // Actually do the device specific open call
    173564    if (!OpenDevice())
    174565    {
    175566        VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure");
    176567        pthread_mutex_unlock(&avsync_lock);
    177568        pthread_mutex_unlock(&audio_buflock);
     569        if (GetError().isEmpty())
     570            Error("Aborting reconfigure");
     571        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    178572        return;
    179573    }
    180574
     
    197591    current_seconds = -1;
    198592    source_bitrate = -1;
    199593
     594    // NOTE: this wont do anything as above samplerate vars are set equal
    200595    // Check if we need the resampler
    201596    if (audio_samplerate != laudio_samplerate)
    202597    {
     
    221616
    222617    VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1")
    223618            .arg(audio_stretchfactor));
     619    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     620            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    224621
    225     SetStretchFactorLocked(audio_stretchfactor);
    226     if (pSoundStretch)
     622    if (redo_stretch)
    227623    {
    228         pSoundStretch->setSampleRate(audio_samplerate);
    229         pSoundStretch->setChannels(audio_channels);
     624        float laudio_stretchfactor = audio_stretchfactor;
     625        delete pSoundStretch;
     626        pSoundStretch = NULL;
     627        audio_stretchfactor = 0.0;
     628        SetStretchFactorLocked(laudio_stretchfactor);
    230629    }
     630    else
     631    {
     632        SetStretchFactorLocked(audio_stretchfactor);
     633        if (pSoundStretch)
     634        {
     635            // if its passthru then we need to reencode
     636            if (audio_codec)
     637            {
     638                if (!encoder)
     639                {
     640                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     641                    encoder = new DigitalEncoder();
     642                    if (!encoder->Init(audio_codec->codec_id,
     643                                audio_codec->bit_rate,
     644                                audio_codec->sample_rate,
     645                                audio_codec->channels
     646                                ))
     647                    {
     648                        // eeks
     649                        delete encoder;
     650                        encoder = NULL;
     651                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     652                    }
     653                }
     654            }
     655            if (encoder)
     656            {
     657                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     658                pSoundStretch->setChannels(audio_codec->channels);
     659            }
     660            else
     661            {
     662                pSoundStretch->setSampleRate(audio_samplerate);
     663                pSoundStretch->setChannels(audio_channels);
     664            }
     665        }
     666    }
    231667
    232668    // Setup visualisations, zero the visualisations buffers
    233669    prepareVisuals();
     
    273709        pSoundStretch = NULL;
    274710    }
    275711
     712    if (encoder)
     713    {
     714        delete encoder;
     715        encoder = NULL;
     716    }
     717
    276718    CloseDevice();
    277719
    278720    killAudioLock.unlock();
     
    286728
    287729void AudioOutputBase::Pause(bool paused)
    288730{
     731    VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused));
    289732    pauseaudio = paused;
    290733    audio_actually_paused = false;
    291734}
     
    368811       The reason is that computing 'audiotime' requires acquiring the audio
    369812       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    370813       from the audio thread, and then call this from the video thread. */
    371     int ret;
     814    long long ret;
    372815    struct timeval now;
    373816
    374817    if (audiotime == 0)
     
    380823
    381824    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    382825    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    383     ret = (int)(ret * audio_stretchfactor);
     826    ret = (long long)(ret * audio_stretchfactor);
    384827
     828#if 1
     829    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     830            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     831            .arg(now.tv_sec).arg(now.tv_usec)
     832            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     833            .arg(ret)
     834            .arg(audiotime)
     835            .arg(audio_stretchfactor)
     836           );
     837#endif
     838
    385839    ret += audiotime;
    386840
    387841    pthread_mutex_unlock(&avsync_lock);
    388     return ret;
     842    return (int)ret;
    389843}
    390844
    391845void AudioOutputBase::SetAudiotime(void)
     
    422876    // include algorithmic latencies
    423877    if (pSoundStretch)
    424878    {
     879        // add the effect of any unused but processed samples, AC3 reencode does this
     880        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    425881        // add the effect of unprocessed samples in time stretch algo
    426882        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    427883                              audio_bytes_per_sample) / audio_stretchfactor);
    428884    }
    429                
     885
    430886    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    431887                                   (audio_bytes_per_sample * effdspstretched));
    432888 
    433889    gettimeofday(&audiotime_updated, NULL);
     890#if 1
     891    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     892            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     893            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     894            .arg(audiotime)
     895            .arg(audbuf_timecode)
     896            .arg(totalbuffer)
     897            .arg(soundcard_buffer)
     898            .arg(effdspstretched)
     899            .arg(audio_bytes_per_sample)
     900            .arg(audio_stretchfactor)
     901           );
     902#endif
    434903
    435904    pthread_mutex_unlock(&avsync_lock);
    436905    pthread_mutex_unlock(&audio_buflock);
     
    498970    // NOTE: This function is not threadsafe
    499971
    500972    int afree = audiofree(true);
    501     int len = samples * audio_bytes_per_sample;
     973    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    502974
    503975    // Check we have enough space to write the data
    504976    if (need_resampler && src_ctx)
     
    509981        VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString(
    510982                "AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
    511983                .arg(len).arg(AUDBUFSIZE-afree).arg(afree)
    512                 .arg(timecode));
    513 
     984                .arg(LONGLONGCONVERT timecode));
    514985        return false; // would overflow
    515986    }
    516987
     
    5471018
    5481019int AudioOutputBase::WaitForFreeSpace(int samples)
    5491020{
    550     int len = samples * audio_bytes_per_sample;
     1021    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     1022    int len = samples * abps;
    5511023    int afree = audiofree(false);
    5521024
    5531025    while (len > afree)
    5541026    {
    5551027        if (blocking)
    5561028        {
    557             VERBOSE(VB_AUDIO, LOC + "Waiting for free space");
     1029            VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space");
    5581030            // wait for more space
    5591031            pthread_cond_wait(&audio_bufsig, &audio_buflock);
    5601032            afree = audiofree(false);
    5611033        }
    5621034        else
    5631035        {
    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;
     1036            VERBOSE(VB_IMPORTANT, LOC_ERR +
     1037                    QString("Audio buffer overflow, %1 audio samples lost!")
     1038                        .arg(samples-afree / abps));
     1039            samples = afree / abps;
     1040            len = samples * abps;
    5681041            if (src_ctx)
    5691042            {
    5701043                int error = src_reset(src_ctx);
     
    5891062   
    5901063    int afree = audiofree(false);
    5911064
    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));
     1065    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     1066    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1067            LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5")
     1068            .arg(samples)
     1069            .arg(samples * abps)
     1070            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    5961071   
    5971072    len = WaitForFreeSpace(samples);
    5981073
     
    6291104
    6301105    if (pSoundStretch)
    6311106    {
     1107
    6321108        // does not change the timecode, only the number of samples
    6331109        // back to orig pos
    6341110        org_waud = waud;
    6351111        int bdiff = AUDBUFSIZE - org_waud;
    636         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     1112        int nSamplesToEnd = bdiff/abps;
    6371113        if (bdiff < len)
    6381114        {
    6391115            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    6401116                                      org_waud), nSamplesToEnd);
    6411117            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    642                                       (len - bdiff) / audio_bytes_per_sample);
     1118                                      (len - bdiff) / abps);
    6431119        }
    6441120        else
    6451121        {
    6461122            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    647                                       org_waud), len / audio_bytes_per_sample);
     1123                                      org_waud), len / abps);
    6481124        }
    6491125
    650         int newLen = 0;
    651         int nSamples;
    652         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    653                                audio_bytes_per_sample);
    654         do
     1126        if (encoder)
    6551127        {
    656             int samplesToGet = len/audio_bytes_per_sample;
    657             if (samplesToGet > nSamplesToEnd)
     1128            // pull out a packet's worth and reencode it until we dont have enough
     1129            // for any more packets
     1130            soundtouch::SAMPLETYPE* temp_buff =
     1131                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     1132            size_t frameSize = encoder->FrameSize()/abps;
     1133            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1134                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     1135                    .arg(frameSize)
     1136                    .arg(encoder->FrameSize())
     1137                    .arg(pSoundStretch->numSamples())
     1138                   );
     1139            // process the same number of samples as it creates a full encoded buffer
     1140            // just like before
     1141            while (pSoundStretch->numSamples() >= frameSize)
    6581142            {
    659                 samplesToGet = nSamplesToEnd;   
     1143                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     1144                int amount = encoder->Encode(temp_buff);
     1145                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1146                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1147                        .arg(amount)
     1148                        .arg(got)
     1149                        .arg(pSoundStretch->numSamples())
     1150                       );
     1151                if (amount == 0)
     1152                    continue;
     1153                //len = WaitForFreeSpace(amount);
     1154                char * ob = encoder->GetOutBuff();
     1155                if (amount >= bdiff)
     1156                {
     1157                    memcpy(audiobuffer + org_waud, ob, bdiff);
     1158                    ob += bdiff;
     1159                    amount -= bdiff;
     1160                    org_waud = 0;
     1161                }
     1162                if (amount > 0)
     1163                    memcpy(audiobuffer + org_waud, ob, amount);
     1164                bdiff = AUDBUFSIZE - amount;
     1165                org_waud += amount;
    6601166            }
    661 
    662             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    663                                       (audiobuffer + org_waud), samplesToGet);
    664             if (nSamples == nSamplesToEnd)
     1167        }
     1168        else
     1169        {
     1170            int newLen = 0;
     1171            int nSamples;
     1172            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1173                                   audio_bytes_per_sample);
     1174            do
    6651175            {
    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             }
     1176                int samplesToGet = len/audio_bytes_per_sample;
     1177                if (samplesToGet > nSamplesToEnd)
     1178                {
     1179                    samplesToGet = nSamplesToEnd;   
     1180                }
    6741181
    675             newLen += nSamples * audio_bytes_per_sample;
    676             len -= nSamples * audio_bytes_per_sample;
    677         } while (nSamples > 0);
     1182                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1183                                          (audiobuffer + org_waud), samplesToGet);
     1184                if (nSamples == nSamplesToEnd)
     1185                {
     1186                    org_waud = 0;
     1187                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1188                }
     1189                else
     1190                {
     1191                    org_waud += nSamples * audio_bytes_per_sample;
     1192                    nSamplesToEnd -= nSamples;
     1193                }
     1194
     1195                newLen += nSamples * audio_bytes_per_sample;
     1196                len -= nSamples * audio_bytes_per_sample;
     1197            } while (nSamples > 0);
     1198        }
    6781199    }
    6791200
    6801201    waud = org_waud;
     
    7501271            space_on_soundcard = getSpaceOnSoundcard();
    7511272
    7521273            if (space_on_soundcard != last_space_on_soundcard) {
    753                 VERBOSE(VB_AUDIO, LOC + QString("%1 bytes free on soundcard")
     1274                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard")
    7541275                        .arg(space_on_soundcard));
    7551276                last_space_on_soundcard = space_on_soundcard;
    7561277            }
     
    7631284                    WriteAudio(zeros, fragment_size);
    7641285                } else {
    7651286                    // this should never happen now -dag
    766                     VERBOSE(VB_AUDIO, LOC +
     1287                    VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    7671288                            QString("waiting for space on soundcard "
    7681289                                    "to write zeros: have %1 need %2")
    7691290                            .arg(space_on_soundcard).arg(fragment_size));
     
    7991320        if (fragment_size > audiolen(true))
    8001321        {
    8011322            if (audiolen(true) > 0)  // only log if we're sending some audio
    802                 VERBOSE(VB_AUDIO, LOC +
     1323                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8031324                        QString("audio waiting for buffer to fill: "
    8041325                                "have %1 want %2")
    8051326                        .arg(audiolen(true)).arg(fragment_size));
    8061327
    807             VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1328            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8081329            pthread_mutex_lock(&audio_buflock);
    8091330            pthread_cond_broadcast(&audio_bufsig);
    8101331            pthread_mutex_unlock(&audio_buflock);
     
    8181339        if (fragment_size > space_on_soundcard)
    8191340        {
    8201341            if (space_on_soundcard != last_space_on_soundcard) {
    821                 VERBOSE(VB_AUDIO, LOC +
     1342                VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC +
    8221343                        QString("audio waiting for space on soundcard: "
    8231344                                "have %1 need %2")
    8241345                        .arg(space_on_soundcard).arg(fragment_size));
     
    8801401
    8811402        /* update raud */
    8821403        raud = (raud + fragment_size) % AUDBUFSIZE;
    883         VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");
     1404        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail");
    8841405        pthread_cond_broadcast(&audio_bufsig);
    8851406
    8861407        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

     
    3939        dev.setNameFilter("adsp*");
    4040        gc->fillSelectionsFromDir(dev);
    4141    }
     42#ifdef USE_ALSA
     43    gc->addSelection("ALSA:default", "ALSA:default");
     44    gc->addSelection("ALSA:analog", "ALSA:analog");
     45    gc->addSelection("ALSA:digital", "ALSA:digital");
     46    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     47    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
     48#endif
     49#ifdef USE_ARTS
     50    gc->addSelection("ARTS:", "ARTS:");
     51#endif
     52#ifdef USE_JACK
     53    gc->addSelection("JACK:output", "JACK:output");
     54#endif
     55    gc->addSelection("NULL", "NULL");
    4256
    4357    return gc;
    4458}
    4559
     60static HostComboBox *MaxAudioChannels()
     61{
     62    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     63    gc->setLabel(QObject::tr("Max Audio Channels"));
     64    //gc->addSelection(QObject::tr("Mono"), "1");
     65    //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default
     66    //gc->addSelection(QObject::tr("3 Channel: L C R"), "3");
     67    //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4");
     68    //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5");
     69    //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6");
     70    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     71    gc->addSelection(QObject::tr("6 Channel"), "6");
     72    gc->setHelpText(
     73            QObject::tr("Set the maximum number of audio channels to be decoded. "
     74                "This is for multi-channel/surround audio playback."));
     75    return gc;
     76}
     77
    4678static HostComboBox *PassThroughOutputDevice()
    4779{
    4880    HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true);
     
    24442476#ifdef CONFIG_DTS
    24452477         vgrp0->addChild(DTSPassThrough());
    24462478#endif
     2479         addChild(MaxAudioChannels());
    24472480
    24482481         VerticalConfigurationGroup *vgrp1 =
    24492482             new VerticalConfigurationGroup(false, false, true, true);
  • programs/mythtranscode/transcode.cpp

     
    4949
    5050    // reconfigure sound out for new params
    5151    virtual void Reconfigure(int audio_bits, int audio_channels,
    52                              int audio_samplerate, bool audio_passthru)
     52                             int audio_samplerate, bool audio_passthru,
     53                             void * = NULL)
    5354    {
     55        ClearError();
    5456        (void)audio_samplerate;
    5557        (void)audio_passthru;
    5658        bits = audio_bits;
    5759        channels = audio_channels;
    5860        bytes_per_sample = bits * channels / 8;
     61        if (channels>2)
     62            Error("Invalid channel count");
    5963    }
    6064
    6165    // 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

     
    247247    bool              allow_ac3_passthru;
    248248    bool              allow_dts_passthru;
    249249    bool              disable_passthru;
     250    int               max_channels;
    250251
    251252    AudioInfo         audioIn;
    252253    AudioInfo         audioOut;
  • libs/libmythtv/avformatdecoder.cpp

     
    4747#define MAX_AC3_FRAME_SIZE 6144
    4848
    4949/** Set to zero to allow any number of AC3 channels. */
     50#define MAXCHANNELSELECT 1
     51#if MAXCHANNELSELECT
     52#define MAX_OUTPUT_CHANNELS compiler error
     53#else
    5054#define MAX_OUTPUT_CHANNELS 2
     55#endif
    5156
    5257static int cc608_parity(uint8_t byte);
    5358static int cc608_good_parity(const int *parity_table, uint16_t data);
     
    309314#ifdef CONFIG_DTS
    310315    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    311316#endif
     317    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    312318
    313319    audioIn.sample_size = -32; // force SetupAudioStream to run once
    314320    itv = GetNVP()->GetInteractiveTV();
     
    457463    framesPlayed = lastKey;
    458464    framesRead = lastKey;
    459465
     466    VERBOSE(VB_PLAYBACK, QString("AvFormatDecoder::DoFastForward newframe %5 frame %1 fps %2 ts %3 disc %4 cur_dts %6 adj %7 newts %8 fsa %9")
     467        .arg(desiredFrame)
     468        .arg(fps)
     469        .arg(ts)
     470        .arg(discardFrames)
     471        .arg(framesPlayed)
     472        .arg(st->cur_dts)
     473        .arg(adj_cur_dts)
     474        .arg(newts)
     475        .arg(frameseekadjust)
     476        );
     477
    460478    int normalframes = desiredFrame - framesPlayed;
    461479    normalframes = max(normalframes, 0);
     480#if 0
     481    if (!exactseeks)
     482        normalframes = 0;
     483#endif
     484
    462485    SeekReset(lastKey, normalframes, discardFrames, discardFrames);
    463486
    464487    if (discardFrames)
     
    545568    // Skip all the desired number of skipFrames
    546569    for (;skipFrames > 0 && !ateof; skipFrames--)
    547570    {
    548         GetFrame(0);
     571            GetFrame(0);
    549572        if (decoded_video_frame)
    550573            GetNVP()->DiscardVideoFrame(decoded_video_frame);
    551574    }
     
    812854    // If we don't have a position map, set up ffmpeg for seeking
    813855    if (!recordingHasPositionMap)
    814856    {
     857        const char *name = ic->av_class->item_name(ic);
    815858        VERBOSE(VB_PLAYBACK, LOC +
    816                 "Recording has no position -- using libavformat seeking.");
     859                QString("Recording has no position -- using libavformat seeking. %1").arg(name));
    817860        int64_t dur = ic->duration / (int64_t)AV_TIME_BASE;
    818861
    819862        if (dur > 0)
     
    14021448                            <<") type ("<<codec_type_string(enc->codec_type)
    14031449                            <<") already open, leaving it alone.");
    14041450                }
     1451#if MAXCHANNELSELECT
     1452                if (enc->cqp != max_channels)
     1453                {
     1454                    VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(enc->cqp));
     1455                    enc->cqp = max_channels;
     1456                }
     1457#endif
    14051458                //assert(enc->codec_id);
     1459                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
    14061460
     1461#if 0
    14071462                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    14081463                if (enc->codec_id == CODEC_ID_DTS)
    14091464                {
     
    14121478                    // enc->bit_rate = what??;
    14131479                }
    14141480                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1481#endif
    14151482
    14161483                bitrate += enc->bit_rate;
    14171484                break;
     
    29753050                    if (!curstream->codec->channels)
    29763051                    {
    29773052                        QMutexLocker locker(&avcodeclock);
     3053#if MAXCHANNELSELECT
     3054                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     3055                        curstream->codec->cqp = max_channels;
     3056                        curstream->codec->channels = audioOut.channels;
     3057#else
    29783058                        curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     3059#endif
    29793060                        ret = avcodec_decode_audio(
    29803061                            curstream->codec, audioSamples,
    29813062                            &data_size, ptr, len);
    29823063
    29833064                        reselectAudioTrack |= curstream->codec->channels;
    29843065                    }
     3066#if MAXCHANNELSELECT
     3067                    if (curstream->codec->cqp != max_channels)
     3068                    {
     3069                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting maxchannels to %1, %2").arg(max_channels).arg(curstream->codec->cqp));
     3070                        curstream->codec->cqp = max_channels;
     3071                    }
     3072#endif
    29853073
    29863074                    if (reselectAudioTrack)
    29873075                    {
     
    30353123                    {
    30363124                        AVCodecContext *ctx = curstream->codec;
    30373125
     3126#if MAXCHANNELSELECT
    30383127                        if ((ctx->channels == 0) ||
     3128                            (ctx->channels > audioOut.channels))
     3129                            ctx->channels = audioOut.channels;
     3130#else
     3131                        if ((ctx->channels == 0) ||
    30393132                            (ctx->channels > MAX_OUTPUT_CHANNELS))
    30403133                            ctx->channels = MAX_OUTPUT_CHANNELS;
     3134#endif
    30413135
    30423136                        ret = avcodec_decode_audio(
    30433137                            ctx, audioSamples, &data_size, ptr, len);
     
    33733467
    33743468void AvFormatDecoder::SetDisablePassThrough(bool disable)
    33753469{
     3470#if MAXCHANNELSELECT
     3471    // can only disable never reenable as once tiemstretch is on its on for the session
     3472    if (disable_passthru)
     3473        return;
     3474#endif
    33763475    if (selectedTrack[kTrackTypeAudio].av_stream_index < 0)
    33773476    {
    33783477        disable_passthru = disable;
     
    34053504    AVCodecContext *codec_ctx = NULL;
    34063505    AudioInfo old_in  = audioIn;
    34073506    AudioInfo old_out = audioOut;
     3507    bool using_passthru = false;
    34083508
    34093509    if ((currentTrack[kTrackTypeAudio] >= 0) &&
    34103510        (selectedTrack[kTrackTypeAudio].av_stream_index <=
     
    34143514    {
    34153515        assert(curstream);
    34163516        assert(curstream->codec);
    3417         codec_ctx = curstream->codec;       
     3517        codec_ctx = curstream->codec;
    34183518        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    3419                                 !disable_passthru &&
    34203519                                (codec_ctx->codec_id == CODEC_ID_AC3));
    34213520        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    3422                                 !disable_passthru &&
    34233521                                (codec_ctx->codec_id == CODEC_ID_DTS));
     3522        using_passthru = do_ac3_passthru || do_dts_passthru;
    34243523        info = AudioInfo(codec_ctx->codec_id,
    34253524                         codec_ctx->sample_rate, codec_ctx->channels,
    3426                          do_ac3_passthru || do_dts_passthru);
     3525                         using_passthru && !disable_passthru);
    34273526    }
    34283527
    34293528    if (info == audioIn)
    34303529        return false; // no change
    34313530
     3531    QString ptmsg = "";
     3532    if (using_passthru)
     3533    {
     3534        ptmsg = QString(" using passthru");
     3535    }
    34323536    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    34333537            QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1));
    34343538
    34353539    audioOut = audioIn = info;
     3540#if MAXCHANNELSELECT
     3541    if (using_passthru)
     3542#else
    34363543    if (audioIn.do_passthru)
     3544#endif
    34373545    {
    34383546        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    3439         audioOut.channels    = 2;
    3440         audioOut.sample_rate = 48000;
    3441         audioOut.sample_size = 4;
     3547        AudioInfo digInfo = audioOut;
     3548        if (!disable_passthru)
     3549        {
     3550            digInfo.channels    = 2;
     3551            digInfo.sample_rate = 48000;
     3552            digInfo.sample_size = 4;
     3553        }
     3554        if (audioOut.channels > max_channels)
     3555        {
     3556            audioOut.channels = max_channels;
     3557            audioOut.sample_size = audioOut.channels * 2;
     3558            codec_ctx->channels = audioOut.channels;
     3559        }
     3560#if MAXCHANNELSELECT
     3561        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     3562                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     3563                .arg(digInfo.toString())
     3564                .arg(old_in.toString()).arg(old_out.toString())
     3565                .arg(audioIn.toString()).arg(audioOut.toString()));
     3566
     3567        if (digInfo.sample_rate > 0)
     3568            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     3569
     3570        //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     3571        //                         audioOut.sample_rate);
     3572        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     3573                                 digInfo.sample_rate, audioIn.do_passthru);
     3574        // allow the audio stuff to reencode
     3575        GetNVP()->SetAudioCodec(codec_ctx);
     3576        GetNVP()->ReinitAudio();
     3577        return true;
     3578#endif
    34423579    }
     3580#if MAXCHANNELSELECT
    34433581    else
    34443582    {
     3583        if (audioOut.channels > max_channels)
     3584        {
     3585            audioOut.channels = max_channels;
     3586            audioOut.sample_size = audioOut.channels * 2;
     3587            codec_ctx->channels = audioOut.channels;
     3588        }
     3589    }
     3590    bool audiook;
     3591#else
     3592    else
     3593    {
    34453594        if (audioOut.channels > MAX_OUTPUT_CHANNELS)
    34463595        {
    34473596            audioOut.channels = MAX_OUTPUT_CHANNELS;
     
    34493602            codec_ctx->channels = MAX_OUTPUT_CHANNELS;
    34503603        }
    34513604    }
     3605#endif
    34523606
    34533607    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    34543608            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    34613615    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    34623616                             audioOut.sample_rate,
    34633617                             audioIn.do_passthru);
    3464     GetNVP()->ReinitAudio();
     3618    // allow the audio stuff to reencode
     3619    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     3620    QString errMsg = GetNVP()->ReinitAudio();
     3621#if MAXCHANNELSELECT
     3622        audiook = errMsg.isEmpty();
     3623#if 0
     3624        if (!audiook)
     3625        {
     3626            switch (audioOut.channels)
     3627            {
     3628#if 0
     3629                case 8:
     3630                    audioOut.channels = 6;
     3631                    break;
     3632#endif
     3633                case 6:
     3634#if 0
     3635                    audioOut.channels = 5;
     3636                    break;
     3637                case 5:
     3638                    audioOut.channels = 4;
     3639                    break;
     3640                case 4:
     3641                    audioOut.channels = 3;
     3642                    break;
     3643                case 3:
     3644#endif
     3645                    audioOut.channels = 2;
     3646                    break;
     3647#if 0
     3648                case 2:
     3649                    audioOut.channels = 1;
     3650                    break;
     3651#endif
     3652                default:
     3653                    // failed to reconfigure under any circumstances
     3654                    audiook = true;
     3655                    audioOut.channels = 0;
     3656                    break;
     3657            }
     3658            audioOut.sample_size = audioOut.channels * 2;
     3659            codec_ctx->channels = audioOut.channels;
     3660        }
     3661    } while (!audiook);
     3662#endif
     3663#endif
    34653664
    34663665    return true;
    34673666}
  • libs/libmythtv/NuppelVideoPlayer.h

     
    126126    void SetAudioInfo(const QString &main, const QString &passthru, uint rate);
    127127    void SetAudioParams(int bits, int channels, int samplerate, bool passthru);
    128128    void SetEffDsp(int dsprate);
     129    void SetAudioCodec(void *ac);
    129130
    130131    // Sets
    131132    void SetParentWidget(QWidget *widget)     { parentWidget = widget; }
     
    668671    int      audio_bits;
    669672    int      audio_samplerate;
    670673    float    audio_stretchfactor;
     674    void     *audio_codec;
    671675    bool     audio_passthru;
    672676
    673677    // 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
     
    686687    if (audioOutput)
    687688    {
    688689        audioOutput->Reconfigure(audio_bits, audio_channels,
    689                                  audio_samplerate, audio_passthru);
     690                                 audio_samplerate, audio_passthru,
     691                                 audio_codec);
    690692        errMsg = audioOutput->GetError();
    691693        if (!errMsg.isEmpty())
    692694            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    34743485    audio_passthru = passthru;
    34753486}
    34763487
     3488void NuppelVideoPlayer::SetAudioCodec(void* ac)
     3489{
     3490    audio_codec = ac;
     3491}
     3492
    34773493void NuppelVideoPlayer::SetEffDsp(int dsprate)
    34783494{
    34793495    if (audioOutput)
  • libs/libavcodec/a52dec.c

     
    144144    }
    145145}
    146146
     147static inline int16_t convert (int32_t i)
     148{
     149    if (i > 0x43c07fff)
     150        return 32767;
     151    else if (i < 0x43bf8000)
     152        return -32768;
     153    else
     154        return i - 0x43c00000;
     155}
     156
     157void float2s16_2 (float * _f, int16_t * s16)
     158{
     159    int i;
     160    int32_t * f = (int32_t *) _f;
     161
     162    for (i = 0; i < 256; i++) {
     163        s16[2*i] = convert (f[i]);
     164        s16[2*i+1] = convert (f[i+256]);
     165    }
     166}
     167
     168void float2s16_4 (float * _f, int16_t * s16)
     169{
     170    int i;
     171    int32_t * f = (int32_t *) _f;
     172
     173    for (i = 0; i < 256; i++) {
     174        s16[4*i] = convert (f[i]);
     175        s16[4*i+1] = convert (f[i+256]);
     176        s16[4*i+2] = convert (f[i+512]);
     177        s16[4*i+3] = convert (f[i+768]);
     178    }
     179}
     180
     181void float2s16_5 (float * _f, int16_t * s16)
     182{
     183    int i;
     184    int32_t * f = (int32_t *) _f;
     185
     186    for (i = 0; i < 256; i++) {
     187        s16[5*i] = convert (f[i]);
     188        s16[5*i+1] = convert (f[i+256]);
     189        s16[5*i+2] = convert (f[i+512]);
     190        s16[5*i+3] = convert (f[i+768]);
     191        s16[5*i+4] = convert (f[i+1024]);
     192    }
     193}
     194
     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            s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0;
     241            s16[6*i+4] = convert (f[i+256]);
     242            s16[6*i+5] = convert (f[i]);
     243        }
     244        break;
     245    case A52_CHANNEL | A52_LFE:
     246    case A52_STEREO | A52_LFE:
     247    case A52_DOLBY | A52_LFE:
     248        for (i = 0; i < 256; i++) {
     249            s16[6*i] = convert (f[i+256]);
     250            s16[6*i+1] = convert (f[i+512]);
     251            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     252            s16[6*i+5] = convert (f[i]);
     253        }
     254        break;
     255    case A52_3F | A52_LFE:
     256        for (i = 0; i < 256; i++) {
     257            s16[6*i] = convert (f[i+256]);
     258            s16[6*i+1] = convert (f[i+768]);
     259            s16[6*i+2] = s16[6*i+3] = 0;
     260            s16[6*i+4] = convert (f[i+512]);
     261            s16[6*i+5] = convert (f[i]);
     262        }
     263        break;
     264    case A52_2F2R | A52_LFE:
     265        for (i = 0; i < 256; i++) {
     266            s16[6*i] = convert (f[i+256]);
     267            s16[6*i+1] = convert (f[i+512]);
     268            s16[6*i+2] = convert (f[i+768]);
     269            s16[6*i+3] = convert (f[i+1024]);
     270            s16[6*i+4] = 0;
     271            s16[6*i+5] = convert (f[i]);
     272        }
     273        break;
     274    case A52_3F2R | A52_LFE:
     275        for (i = 0; i < 256; i++) {
     276            s16[6*i] = convert (f[i+256]);
     277            s16[6*i+1] = convert (f[i+768]);
     278            s16[6*i+2] = convert (f[i+1024]);
     279            s16[6*i+3] = convert (f[i+1280]);
     280            s16[6*i+4] = convert (f[i+512]);
     281            s16[6*i+5] = convert (f[i]);
     282        }
     283        break;
     284    }
     285}
     286
     287
    147288/**** end */
    148289
    149290#define HEADER_SIZE 7
     
    187329                    /* update codec info */
    188330                    avctx->sample_rate = sample_rate;
    189331                    s->channels = ac3_channels[s->flags & 7];
     332                    if (avctx->cqp >= 0)
     333                        avctx->channels = avctx->cqp;
    190334                    if (s->flags & A52_LFE)
    191335                        s->channels++;
    192336                    if (avctx->channels == 0)
     
    209353            s->inbuf_ptr += len;
    210354            buf_size -= len;
    211355        } else {
     356            int chans;
    212357            flags = s->flags;
    213358            if (avctx->channels == 1)
    214359                flags = A52_MONO;
    215             else if (avctx->channels == 2)
    216                 flags = A52_STEREO;
     360            else if (avctx->channels == 2) {
     361                if (s->channels>2)
     362                    flags = A52_DOLBY;
     363                else
     364                    flags = A52_STEREO;
     365            }
    217366            else
    218367                flags |= A52_ADJUST_LEVEL;
    219368            level = 1;
     369            chans = channels_multi(flags);
    220370            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    221371            fail:
    222372                av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
     
    227377            for (i = 0; i < 6; i++) {
    228378                if (s->a52_block(s->state))
    229379                    goto fail;
     380                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    230381            }
    231382            s->inbuf_ptr = s->inbuf;
    232383            s->frame_size = 0;
     384            *data_size = 6 * chans * 256 * sizeof(int16_t);
    233385            break;
    234386        }
    235387    }
  • libs/libavcodec/ac3enc.c

     
    13381338{
    13391339    AC3EncodeContext *s = avctx->priv_data;
    13401340    int16_t *samples = data;
     1341    // expects L C R LS RS LFE
     1342    // audio format is L R LS RS C LFE
     1343    static int channel_index[6] = { 0, 4, 1, 2, 3, 5 };
     1344    /*
     1345     * A52->Analog->AC3Enc
     1346     * 1->0->0
     1347     * 3->1->2
     1348     * 4->2->3
     1349     * 5->3->4
     1350     * 2->4->1
     1351     * 0->5->5
     1352     */
    13411353    int i, j, k, v, ch;
    13421354    int16_t input_samples[N];
    13431355    int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2];
     
    13581370            /* compute input samples */
    13591371            memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t));
    13601372            sinc = s->nb_all_channels;
    1361             sptr = samples + (sinc * (N/2) * i) + ch;
     1373            sptr = samples + (sinc * (N/2) * i) + channel_index[ch];
    13621374            for(j=0;j<N/2;j++) {
    13631375                v = *sptr;
    13641376                input_samples[j + N/2] = v;