Ticket #1104: mythtv_ac3.15.patch

File mythtv_ac3.15.patch, 87.5 KB (added by Mark Spieth, 14 years ago)

6 ch mmx support

  • libs/libmyth/libmyth.pro

     
    3434SOURCES += virtualkeyboard.cpp mythobservable.cpp
    3535
    3636INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../..
     37INCLUDEPATH += ../libavutil ..
    3738DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch
     39DEPENDPATH += ../libavutil ../libavcodec
    3840
    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

     
    2727
    2828    // reconfigure sound out for new params
    2929    virtual void Reconfigure(int audio_bits,
    30                              int audio_channels, int audio_samplerate) = 0;
     30                             int audio_channels,
     31                             int audio_samplerate,
     32                             void* audio_codec = NULL
     33                             ) = 0;
    3134   
    3235    virtual void SetStretchFactor(float factor);
    3336
     
    6568 protected:
    6669    void Error(QString msg)
    6770     { lastError = msg; VERBOSE(VB_IMPORTANT, lastError); };
     71    void ClearError()
     72     { lastError = QString::null; };
    6873
    6974 private:
    7075    QString lastError;
  • libs/libmyth/audiooutputdx.h

     
    2121
    2222    virtual void Reset(void);
    2323    virtual void Reconfigure(int audio_bits,
    24                          int audio_channels, int audio_samplerate);
     24                         int audio_channels,
     25                         int audio_samplerate
     26                         AudioCodecMode aom = AUDIOCODECMODE_NORMAL);
    2527    virtual void SetBlocking(bool blocking);
    2628
    2729    virtual bool AddSamples(char *buffer, int samples, long long timecode);
  • libs/libmyth/audiooutputdx.cpp

     
    119119}
    120120
    121121void AudioOutputDX::Reconfigure(int audio_bits,
    122                                   int audio_channels, int audio_samplerate)
     122                                int audio_channels,
     123                                int audio_samplerate,
     124                                AudioCodecMode laom
     125                                )
    123126{
    124127    if (dsbuffer)
    125128        DestroyDSBuffer();
  • libs/libmyth/audiooutputbase.h

     
    1212#include "samplerate.h"
    1313#include "SoundTouch.h"
    1414
    15 #define AUDBUFSIZE 768000
     15struct AVCodecContext;
     16class DigitalEncoder;
    1617
     18//#define AUDBUFSIZE 768000
     19//divisible by 12,10,8,6,4,2 and around 1024000
     20//#define AUDBUFSIZE 1024080
     21#define AUDBUFSIZE 1536000
     22
    1723class AudioOutputBase : public AudioOutput
    1824{
    1925 public:
     
    2430
    2531    // reconfigure sound out for new params
    2632    virtual void Reconfigure(int audio_bits,
    27                              int audio_channels, int audio_samplerate);
     33                             int audio_channels,
     34                             int audio_samplerate,
     35                             void* audio_codec = NULL);
    2836   
    2937    // do AddSamples calls block?
    3038    virtual void SetBlocking(bool blocking);
     
    5260    // Send output events showing current progress
    5361    virtual void Status(void);
    5462
    55     QString GetError() { return lastError; };
     63    //QString GetError() { return lastError; };
    5664
    5765    virtual void SetSourceBitrate(int rate);
    5866
     
    108116
    109117    float audio_stretchfactor;
    110118    AudioOutputSource source;
     119    AVCodecContext *audio_codec;
    111120
    112121    bool killaudio;
    113122
     
    116125    bool buffer_output_data_for_use; //  used by AudioOutputNULL
    117126   
    118127 private:
    119     QString lastError;
     128    //QString lastError;
    120129
    121130    // resampler
    122131    bool need_resampler;
     
    127136
    128137    // timestretch
    129138    soundtouch::SoundTouch * pSoundStretch;
     139    DigitalEncoder * encoder;
    130140
    131141    bool blocking; // do AddSamples calls block?
    132142
     
    142152
    143153    pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write
    144154                                    'audiotime' and 'audiotime_updated' */
    145     int audiotime; // timecode of audio leaving the soundcard (same units as
     155    long long audiotime; // timecode of audio leaving the soundcard (same units as
    146156                   //                                          timecodes) ...
    147157    struct timeval audiotime_updated; // ... which was last updated at this time
    148158
    149159    /* Audio circular buffer */
    150160    unsigned char audiobuffer[AUDBUFSIZE];  /* buffer */
    151161    int raud, waud;     /* read and write positions */
    152     int audbuf_timecode;    /* timecode of audio most recently placed into
     162    long long audbuf_timecode;    /* timecode of audio most recently placed into
    153163                   buffer */
    154164
    155165    int numlowbuffer;
  • libs/libmyth/audiooutputbase.cpp

     
    1212#include <sys/time.h>
    1313#include <unistd.h>
    1414
     15extern "C" {
     16#include "libavcodec/avcodec.h"
     17#include "libavcodec/liba52/a52.h"
     18}
    1519
     20#if QT_VERSION < 0x030200
     21#define LONGLONGCONVERT (long)
     22#else
     23#define LONGLONGCONVERT
     24#endif
     25
     26#define LOC QString("DEnc: ");
     27#define MAX_AC3_FRAME_SIZE 6144
     28class DigitalEncoder
     29{
     30public:
     31    DigitalEncoder();
     32    ~DigitalEncoder();
     33    void Dispose();
     34    bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels);
     35    size_t Encode(short * buff);
     36
     37    // if needed
     38    char * GetFrameBuffer()
     39    {
     40        if (!frame_buffer && av_context)
     41        {
     42            frame_buffer = new char [one_frame_bytes];
     43        }
     44        return frame_buffer;
     45    }   
     46    size_t FrameSize() const { return one_frame_bytes; }
     47    char * GetOutBuff() const { return outbuf; }
     48
     49    size_t audio_bytes_per_sample;
     50private:
     51    AVCodecContext *av_context;
     52    char * outbuf;
     53    char * frame_buffer;
     54    int outbuf_size;
     55    size_t one_frame_bytes;
     56};
     57
     58DigitalEncoder::DigitalEncoder()
     59{
     60    av_context = NULL;
     61    outbuf = NULL;
     62    outbuf_size = 0;
     63    one_frame_bytes = 0;
     64    frame_buffer = NULL;
     65}
     66
     67DigitalEncoder::~DigitalEncoder()
     68{
     69    Dispose();
     70}
     71
     72void DigitalEncoder::Dispose()
     73{
     74    if (av_context)
     75    {
     76        avcodec_close(av_context);
     77        av_free(av_context);
     78        av_context = NULL;
     79    }
     80    if (outbuf)
     81    {
     82        delete [] outbuf;
     83        outbuf = NULL;
     84        outbuf_size = 0;
     85    }
     86    if (frame_buffer)
     87    {
     88        delete [] frame_buffer;
     89        frame_buffer = NULL;
     90        one_frame_bytes = 0;
     91    }
     92}
     93
     94//CODEC_ID_AC3
     95bool DigitalEncoder::Init(CodecID codec_id, int bitrate, int samplerate, int channels)
     96{
     97    AVCodec * codec;
     98    int ret;
     99
     100    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init codecid=%1, br=%2, sr=%3, ch=%4")
     101            .arg(codec_id_string(codec_id))
     102            .arg(bitrate)
     103            .arg(samplerate)
     104            .arg(channels));
     105    //codec = avcodec_find_encoder(codec_id);
     106    // always AC3 as there is no DTS encoder at the moment 2005/1/9
     107    codec = avcodec_find_encoder(CODEC_ID_AC3);
     108    if (!codec)
     109    {
     110        VERBOSE(VB_IMPORTANT,"Error: could not find codec");
     111        return false;
     112    }
     113    av_context = avcodec_alloc_context();
     114    av_context->bit_rate = bitrate;
     115    av_context->sample_rate = samplerate;
     116    av_context->channels = channels;
     117    // open it */
     118    if ((ret = avcodec_open(av_context, codec)) < 0)
     119    {
     120        VERBOSE(VB_IMPORTANT,"Error: could not open codec, invalid bitrate or samplerate");
     121        Dispose();
     122        return false;
     123    }
     124
     125    size_t bytes_per_frame = av_context->channels * sizeof(short);
     126    audio_bytes_per_sample = bytes_per_frame;
     127    one_frame_bytes = bytes_per_frame * av_context->frame_size;
     128
     129    outbuf_size = 16384;    // ok for AC3 but DTS?
     130    outbuf = new char [outbuf_size];
     131    VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3")
     132            .arg(av_context->frame_size)
     133            .arg(bytes_per_frame)
     134            .arg(one_frame_bytes)
     135           );
     136
     137    return true;
     138}
     139
     140static int DTS_SAMPLEFREQS[16] =
     141{
     142    0,      8000,   16000,  32000,  64000,  128000, 11025,  22050,
     143    44100,  88200,  176400, 12000,  24000,  48000,  96000,  192000
     144};
     145
     146static int DTS_BITRATES[30] =
     147{
     148    32000,    56000,    64000,    96000,    112000,   128000,
     149    192000,   224000,   256000,   320000,   384000,   448000,
     150    512000,   576000,   640000,   768000,   896000,   1024000,
     151    1152000,  1280000,  1344000,  1408000,  1411200,  1472000,
     152    1536000,  1920000,  2048000,  3072000,  3840000,  4096000
     153};
     154
     155static int dts_decode_header(uint8_t *indata_ptr, int *rate,
     156                             int *nblks, int *sfreq)
     157{
     158    uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
     159               (indata_ptr[2] << 8)  | (indata_ptr[3]));
     160
     161    if (id != 0x7ffe8001)
     162        return -1;
     163
     164    int ftype = indata_ptr[4] >> 7;
     165
     166    int surp = (indata_ptr[4] >> 2) & 0x1f;
     167    surp = (surp + 1) % 32;
     168
     169    *nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
     170    ++*nblks;
     171
     172    int fsize = (indata_ptr[5] & 0x03) << 12 |
     173                (indata_ptr[6]         << 4) | (indata_ptr[7] >> 4);
     174    ++fsize;
     175
     176    *sfreq = (indata_ptr[8] >> 2) & 0x0f;
     177    *rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
     178
     179    if (ftype != 1)
     180    {
     181        VERBOSE(VB_IMPORTANT, LOC +
     182                QString("DTS: Termination frames not handled (ftype %1)")
     183                .arg(ftype));
     184        return -1;
     185    }
     186
     187    if (*sfreq != 13)
     188    {
     189        VERBOSE(VB_IMPORTANT, LOC +
     190                QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
     191        return -1;
     192    }
     193
     194    if ((fsize > 8192) || (fsize < 96))
     195    {
     196        VERBOSE(VB_IMPORTANT, LOC +
     197                QString("DTS: fsize: %1 invalid").arg(fsize));
     198        return -1;
     199    }
     200
     201    if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
     202        *nblks != 64 && *nblks != 128 && ftype == 1)
     203    {
     204        VERBOSE(VB_IMPORTANT, LOC +
     205                QString("DTS: nblks %1 not valid for normal frame")
     206                .arg(*nblks));
     207        return -1;
     208    }
     209
     210    return fsize;
     211}
     212
     213static int dts_syncinfo(uint8_t *indata_ptr, int * /*flags*/,
     214                        int *sample_rate, int *bit_rate)
     215{
     216    int nblks;
     217    int rate;
     218    int sfreq;
     219
     220    int fsize = dts_decode_header(indata_ptr, &rate, &nblks, &sfreq);
     221    if (fsize >= 0)
     222    {
     223        if (rate >= 0 && rate <= 29)
     224            *bit_rate = DTS_BITRATES[rate];
     225        else
     226            *bit_rate = 0;
     227        if (sfreq >= 1 && sfreq <= 15)
     228            *sample_rate = DTS_SAMPLEFREQS[sfreq];
     229        else
     230            *sample_rate = 0;
     231    }
     232    return fsize;
     233}
     234
     235static int encode_frame(
     236        bool dts,
     237        unsigned char *data,
     238        size_t &len)
     239{
     240    size_t enc_len;
     241    int flags, sample_rate, bit_rate;
     242
     243    // we don't do any length/crc validation of the AC3 frame here; presumably
     244    // the receiver will have enough sense to do that.  if someone has a
     245    // receiver that doesn't, here would be a good place to put in a call
     246    // to a52_crc16_block(samples+2, data_size-2) - but what do we do if the
     247    // packet is bad?  we'd need to send something that the receiver would
     248    // ignore, and if so, may as well just assume that it will ignore
     249    // anything with a bad CRC...
     250
     251    uint nr_samples = 0, block_len;
     252    if (dts)
     253    {
     254        enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     255        int rate, sfreq, nblks;
     256        dts_decode_header(data+8, &rate, &nblks, &sfreq);
     257        nr_samples = nblks * 32;
     258        block_len = nr_samples * 2 * 2;
     259    }
     260    else
     261    {
     262        enc_len = a52_syncinfo(data+8, &flags, &sample_rate, &bit_rate);
     263        block_len = MAX_AC3_FRAME_SIZE;
     264    }
     265
     266    if (enc_len == 0 || enc_len > len)
     267    {
     268        int l = len;
     269        len = 0;
     270        return l;
     271    }
     272
     273    enc_len = min((uint)enc_len, block_len - 8);
     274
     275    //uint32_t x = *(uint32_t*)(data+8);
     276    // in place swab
     277    swab(data+8, data+8, enc_len);
     278    //VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     279    //        QString("DigitalEncoder::Encode swab test %1 %2")
     280    //        .arg(x,0,16).arg(*(uint32_t*)(data+8),0,16));
     281
     282    // the following values come from libmpcodecs/ad_hwac3.c in mplayer.
     283    // they form a valid IEC958 AC3 header.
     284    data[0] = 0x72;
     285    data[1] = 0xF8;
     286    data[2] = 0x1F;
     287    data[3] = 0x4E;
     288    data[4] = 0x01;
     289    if (dts)
     290    {
     291        switch(nr_samples)
     292        {
     293            case 512:
     294                data[4] = 0x0B;      /* DTS-1 (512-sample bursts) */
     295                break;
     296
     297            case 1024:
     298                data[4] = 0x0C;      /* DTS-2 (1024-sample bursts) */
     299                break;
     300
     301            case 2048:
     302                data[4] = 0x0D;      /* DTS-3 (2048-sample bursts) */
     303                break;
     304
     305            default:
     306                VERBOSE(VB_IMPORTANT, LOC +
     307                        QString("DTS: %1-sample bursts not supported")
     308                        .arg(nr_samples));
     309                data[4] = 0x00;
     310                break;
     311        }
     312    }
     313    data[5] = 0x00;
     314    data[6] = (enc_len << 3) & 0xFF;
     315    data[7] = (enc_len >> 5) & 0xFF;
     316    memset(data + 8 + enc_len, 0, block_len - 8 - enc_len);
     317    len = block_len;
     318
     319    return enc_len;
     320}
     321
     322// must have exactly 1 frames worth of data
     323size_t DigitalEncoder::Encode(short * buff)
     324{
     325    int encsize = 0;
     326    size_t outsize = 0;
     327 
     328    // put data in the correct spot for encode frame
     329    outsize = avcodec_encode_audio(
     330                av_context,
     331                ((uchar*)outbuf)+8,
     332                outbuf_size-8,
     333                buff);
     334    size_t tmpsize = outsize;
     335
     336    outsize = MAX_AC3_FRAME_SIZE;
     337    encsize = encode_frame(
     338            //av_context->codec_id==CODEC_ID_DTS,
     339            false,
     340            (unsigned char*)outbuf, outsize);
     341    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     342            QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3")
     343                .arg(tmpsize)
     344                .arg(encsize)
     345                .arg(outsize)
     346           );
     347
     348    return outsize;
     349}
     350#undef LOC
     351#define LOC QString("AO: ")
     352
    16353AudioOutputBase::AudioOutputBase(QString audiodevice, int,
    17354                                 int, int,
    18355                                 AudioOutputSource source, bool set_initial_vol)
     
    29366    current_seconds = -1;
    30367    source_bitrate = -1;
    31368    audio_stretchfactor = 1.0;
     369    audio_codec = NULL;
    32370    pSoundStretch = NULL;
     371    encoder = NULL;
    33372    blocking = false;
    34373    this->source = source;
    35374    this->set_initial_vol = set_initial_vol;
     
    78417            VERBOSE(VB_GENERAL, QString("Using time stretch %1")
    79418                                        .arg(audio_stretchfactor));
    80419            pSoundStretch = new soundtouch::SoundTouch();
    81             pSoundStretch->setSampleRate(audio_samplerate);
    82             pSoundStretch->setChannels(audio_channels);
     420            if (audio_codec)
     421            {
     422                if (!encoder)
     423                {
     424                    VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size));
     425                    encoder = new DigitalEncoder();
     426                    if (!encoder->Init(audio_codec->codec_id,
     427                                audio_codec->bit_rate,
     428                                audio_codec->sample_rate,
     429                                audio_codec->channels
     430                                ))
     431                    {
     432                        // eeks
     433                        delete encoder;
     434                        encoder = NULL;
     435                        VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     436                    }
     437                }
     438            }
     439            if (encoder)
     440            {
     441                pSoundStretch->setSampleRate(audio_codec->sample_rate);
     442                pSoundStretch->setChannels(audio_codec->channels);
     443            }
     444            else
     445            {
     446                pSoundStretch->setSampleRate(audio_samplerate);
     447                pSoundStretch->setChannels(audio_channels);
     448            }
    83449
    84450            pSoundStretch->setTempo(audio_stretchfactor);
    85451            pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
     
    102468}
    103469
    104470void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels,
    105                                  int laudio_samplerate)
     471                                 int laudio_samplerate, void* laudio_codec)
    106472{
     473    int codec_id = CODEC_ID_NONE;
     474    int lcodec_id = CODEC_ID_NONE;
     475    if (laudio_codec)
     476    {
     477        lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id;
     478        laudio_bits = 16;
     479        laudio_channels = 2;
     480        laudio_samplerate = 48000;
     481    }
     482    if (audio_codec)
     483        codec_id = audio_codec->codec_id;
     484    ClearError();
    107485    if (laudio_bits == audio_bits && laudio_channels == audio_channels &&
    108         laudio_samplerate == audio_samplerate && !need_resampler)
     486        laudio_samplerate == audio_samplerate && !need_resampler &&
     487        lcodec_id == codec_id)
    109488        return;
    110489
    111490    KillAudio();
     
    120499    audio_channels = laudio_channels;
    121500    audio_bits = laudio_bits;
    122501    audio_samplerate = laudio_samplerate;
     502    audio_codec = (AVCodecContext*)laudio_codec;
    123503    if (audio_bits != 8 && audio_bits != 16)
    124504    {
    125505        Error("AudioOutput only supports 8 or 16bit audio.");
     
    135515   
    136516    numlowbuffer = 0;
    137517
    138     VERBOSE(VB_GENERAL, QString("Opening audio device '%1'.")
    139             .arg(audiodevice));
     518    VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3")
     519            .arg(audiodevice).arg(audio_channels).arg(audio_samplerate));
    140520   
    141521    // Actually do the device specific open call
    142522    if (!OpenDevice()) {
    143523        pthread_mutex_unlock(&avsync_lock);
    144524        pthread_mutex_unlock(&audio_buflock);
     525        if (GetError().isEmpty())
     526            Error("Aborting reconfigure");
    145527        VERBOSE(VB_AUDIO, "Aborting reconfigure");
    146528        return;
    147529    }
     
    185567    }
    186568
    187569    VERBOSE(VB_AUDIO, QString("Audio Stretch Factor: %1").arg(audio_stretchfactor));
     570    VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")
     571            .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set"));
    188572
    189573    SetStretchFactorLocked(audio_stretchfactor);
    190574    if (pSoundStretch)
    191575    {
    192         pSoundStretch->setSampleRate(audio_samplerate);
    193         pSoundStretch->setChannels(audio_channels);
     576        // if its passthru then we need to reencode
     577        if (audio_codec)
     578        {
     579            if (!encoder)
     580            {
     581                VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id));
     582                encoder = new DigitalEncoder();
     583                if (!encoder->Init(audio_codec->codec_id,
     584                            audio_codec->bit_rate,
     585                            audio_codec->sample_rate,
     586                            audio_codec->channels
     587                            ))
     588                {
     589                    // eeks
     590                    delete encoder;
     591                    encoder = NULL;
     592                    VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder"));
     593                }
     594            }
     595        }
     596        if (encoder)
     597        {
     598            pSoundStretch->setSampleRate(audio_codec->sample_rate);
     599            pSoundStretch->setChannels(audio_codec->channels);
     600        }
     601        else
     602        {
     603            pSoundStretch->setSampleRate(audio_samplerate);
     604            pSoundStretch->setChannels(audio_channels);
     605        }
    194606    }
    195607
    196608    // Setup visualisations, zero the visualisations buffers
     
    237649        pSoundStretch = NULL;
    238650    }
    239651
     652    if (encoder)
     653    {
     654        delete encoder;
     655        encoder = NULL;
     656    }
     657
    240658    CloseDevice();
    241659
    242660    killAudioLock.unlock();
     
    330748       The reason is that computing 'audiotime' requires acquiring the audio
    331749       lock, which the video thread should not do. So, we call 'SetAudioTime()'
    332750       from the audio thread, and then call this from the video thread. */
    333     int ret;
     751    long long ret;
    334752    struct timeval now;
    335753
    336754    if (audiotime == 0)
     
    342760
    343761    ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000;
    344762    ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000;
    345     ret = (int)(ret * audio_stretchfactor);
     763    ret = (long long)(ret * audio_stretchfactor);
    346764
     765#if 1
     766    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     767            QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7")
     768            .arg(now.tv_sec).arg(now.tv_usec)
     769            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     770            .arg(ret)
     771            .arg(audiotime)
     772            .arg(audio_stretchfactor)
     773           );
     774#endif
     775
    347776    ret += audiotime;
    348777
    349778    pthread_mutex_unlock(&avsync_lock);
    350     return ret;
     779    return (int)ret;
    351780}
    352781
    353782void AudioOutputBase::SetAudiotime(void)
     
    384813    // include algorithmic latencies
    385814    if (pSoundStretch)
    386815    {
     816        // if encoder is active, then use its idea of audiobytes
     817        //size_t abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     818
     819        // add the effect of any unused but processed samples, AC3 reencode does this
     820        totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample);
    387821        // add the effect of unprocessed samples in time stretch algo
    388822        totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() *
    389823                              audio_bytes_per_sample) / audio_stretchfactor);
    390824    }
    391                
     825
    392826    audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 /
    393827                                   (audio_bytes_per_sample * effdspstretched));
    394828 
    395829    gettimeofday(&audiotime_updated, NULL);
     830#if 1
     831    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     832            QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9")
     833            .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec)
     834            .arg(audiotime)
     835            .arg(audbuf_timecode)
     836            .arg(totalbuffer)
     837            .arg(soundcard_buffer)
     838            .arg(effdspstretched)
     839            .arg(audio_bytes_per_sample)
     840            .arg(audio_stretchfactor)
     841           );
     842#endif
    396843
    397844    pthread_mutex_unlock(&avsync_lock);
    398845    pthread_mutex_unlock(&audio_buflock);
     
    452899    // NOTE: This function is not threadsafe
    453900
    454901    int afree = audiofree(true);
    455     int len = samples * audio_bytes_per_sample;
     902    int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample);
    456903
    457904    // Check we have enough space to write the data
    458905    if (need_resampler && src_ctx)
    459906        len = (int)ceilf(float(len) * src_data.src_ratio);
    460907    if ((len > afree) && !blocking)
     908    {
     909        VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4")
     910            .arg(len)
     911            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    461912        return false; // would overflow
     913    }
    462914
    463915    // resample input if necessary
    464916    if (need_resampler && src_ctx)
     
    492944
    493945int AudioOutputBase::WaitForFreeSpace(int samples)
    494946{
    495     int len = samples * audio_bytes_per_sample;
     947    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     948    int len = samples * abps;
    496949    int afree = audiofree(false);
    497950
    498951    while (len > afree)
    499952    {
    500953        if (blocking)
    501954        {
    502             VERBOSE(VB_AUDIO, "Waiting for free space");
     955            VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space");
    503956            // wait for more space
    504957            pthread_cond_wait(&audio_bufsig, &audio_buflock);
    505958            afree = audiofree(false);
    506959        }
    507960        else
    508961        {
    509             VERBOSE(VB_IMPORTANT, "Audio buffer overflow, audio data lost!");
    510             samples = afree / audio_bytes_per_sample;
    511             len = samples * audio_bytes_per_sample;
     962            VERBOSE(VB_IMPORTANT,
     963                    QString("Audio buffer overflow, %1 audio samples lost!")
     964                        .arg(samples-afree / abps));
     965            samples = afree / abps;
     966            len = samples * abps;
    512967            if (src_ctx)
    513968            {
    514969                int error = src_reset(src_ctx);
     
    533988   
    534989    int afree = audiofree(false);
    535990
    536     VERBOSE(VB_AUDIO, QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4")
    537             .arg(samples * audio_bytes_per_sample)
    538             .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode));
     991    int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample;
     992    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5")
     993            .arg(samples)
     994            .arg(samples * abps)
     995            .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode));
    539996   
    540997    len = WaitForFreeSpace(samples);
    541998
     
    5721029
    5731030    if (pSoundStretch)
    5741031    {
     1032
    5751033        // does not change the timecode, only the number of samples
    5761034        // back to orig pos
    5771035        org_waud = waud;
    5781036        int bdiff = AUDBUFSIZE - org_waud;
    579         int nSamplesToEnd = bdiff/audio_bytes_per_sample;
     1037        int nSamplesToEnd = bdiff/abps;
    5801038        if (bdiff < len)
    5811039        {
    5821040            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    5831041                                      org_waud), nSamplesToEnd);
    5841042            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,
    585                                       (len - bdiff) / audio_bytes_per_sample);
     1043                                      (len - bdiff) / abps);
    5861044        }
    5871045        else
    5881046        {
    5891047            pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +
    590                                       org_waud), len / audio_bytes_per_sample);
     1048                                      org_waud), len / abps);
    5911049        }
    5921050
    593         int newLen = 0;
    594         int nSamples;
    595         len = WaitForFreeSpace(pSoundStretch->numSamples() *
    596                                audio_bytes_per_sample);
    597         do
     1051        if (encoder)
    5981052        {
    599             int samplesToGet = len/audio_bytes_per_sample;
    600             if (samplesToGet > nSamplesToEnd)
     1053            // pull out a packet's worth and reencode it until we dont have enough
     1054            // for any more packets
     1055            soundtouch::SAMPLETYPE* temp_buff =
     1056                (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();
     1057            size_t frameSize = encoder->FrameSize()/abps;
     1058            VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1059                    QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3")
     1060                    .arg(frameSize)
     1061                    .arg(encoder->FrameSize())
     1062                    .arg(pSoundStretch->numSamples())
     1063                   );
     1064            // process the same number of samples as it creates a full encoded buffer
     1065            // just like before
     1066            while (pSoundStretch->numSamples() >= frameSize)
    6011067            {
    602                 samplesToGet = nSamplesToEnd;   
     1068                int got = pSoundStretch->receiveSamples(temp_buff, frameSize);
     1069                int amount = encoder->Encode(temp_buff);
     1070                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
     1071                        QString("_AddSamples Enc bytes=%1 got=%2 left=%3")
     1072                        .arg(amount)
     1073                        .arg(got)
     1074                        .arg(pSoundStretch->numSamples())
     1075                       );
     1076                if (amount == 0)
     1077                    continue;
     1078                //len = WaitForFreeSpace(amount);
     1079                char * ob = encoder->GetOutBuff();
     1080                if (amount >= bdiff)
     1081                {
     1082                    memcpy(audiobuffer + org_waud, ob, bdiff);
     1083                    ob += bdiff;
     1084                    amount -= bdiff;
     1085                    org_waud = 0;
     1086                }
     1087                if (amount > 0)
     1088                    memcpy(audiobuffer + org_waud, ob, amount);
     1089                bdiff = AUDBUFSIZE - amount;
     1090                org_waud += amount;
    6031091            }
    604 
    605             nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
    606                                       (audiobuffer + org_waud), samplesToGet);
    607             if (nSamples == nSamplesToEnd)
     1092        }
     1093        else
     1094        {
     1095            int newLen = 0;
     1096            int nSamples;
     1097            len = WaitForFreeSpace(pSoundStretch->numSamples() *
     1098                                   audio_bytes_per_sample);
     1099            do
    6081100            {
    609                 org_waud = 0;
    610                 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
    611             }
    612             else
    613             {
    614                 org_waud += nSamples * audio_bytes_per_sample;
    615                 nSamplesToEnd -= nSamples;
    616             }
     1101                int samplesToGet = len/audio_bytes_per_sample;
     1102                if (samplesToGet > nSamplesToEnd)
     1103                {
     1104                    samplesToGet = nSamplesToEnd;   
     1105                }
    6171106
    618             newLen += nSamples * audio_bytes_per_sample;
    619             len -= nSamples * audio_bytes_per_sample;
    620         } while (nSamples > 0);
     1107                nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*)
     1108                                          (audiobuffer + org_waud), samplesToGet);
     1109                if (nSamples == nSamplesToEnd)
     1110                {
     1111                    org_waud = 0;
     1112                    nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample;
     1113                }
     1114                else
     1115                {
     1116                    org_waud += nSamples * audio_bytes_per_sample;
     1117                    nSamplesToEnd -= nSamples;
     1118                }
     1119
     1120                newLen += nSamples * audio_bytes_per_sample;
     1121                len -= nSamples * audio_bytes_per_sample;
     1122            } while (nSamples > 0);
     1123        }
    6211124    }
    6221125
    6231126    waud = org_waud;
     
    6871190            space_on_soundcard = getSpaceOnSoundcard();
    6881191
    6891192            if (space_on_soundcard != last_space_on_soundcard) {
    690                 VERBOSE(VB_AUDIO, QString("%1 bytes free on soundcard")
     1193                VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("%1 bytes free on soundcard")
    6911194                        .arg(space_on_soundcard));
    6921195                last_space_on_soundcard = space_on_soundcard;
    6931196            }
     
    7001203                    WriteAudio(zeros, fragment_size);
    7011204                } else {
    7021205                    // this should never happen now -dag
    703                     VERBOSE(VB_AUDIO,
     1206                    VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7041207                            QString("waiting for space on soundcard "
    7051208                                    "to write zeros: have %1 need %2")
    7061209                            .arg(space_on_soundcard).arg(fragment_size));
     
    7361239        if (fragment_size > audiolen(true))
    7371240        {
    7381241            if (audiolen(true) > 0)  // only log if we're sending some audio
    739                 VERBOSE(VB_AUDIO,
     1242                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7401243                        QString("audio waiting for buffer to fill: "
    7411244                                "have %1 want %2")
    7421245                        .arg(audiolen(true)).arg(fragment_size));
    7431246
    744             VERBOSE(VB_AUDIO, "Broadcasting free space avail");
     1247            //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail");
    7451248            pthread_mutex_lock(&audio_buflock);
    7461249            pthread_cond_broadcast(&audio_bufsig);
    7471250            pthread_mutex_unlock(&audio_buflock);
     
    7551258        if (fragment_size > space_on_soundcard)
    7561259        {
    7571260            if (space_on_soundcard != last_space_on_soundcard) {
    758                 VERBOSE(VB_AUDIO,
     1261                VERBOSE(VB_AUDIO|VB_TIMESTAMP,
    7591262                        QString("audio waiting for space on soundcard: "
    7601263                                "have %1 need %2")
    7611264                        .arg(space_on_soundcard).arg(fragment_size));
     
    8171320
    8181321        /* update raud */
    8191322        raud = (raud + fragment_size) % AUDBUFSIZE;
    820         VERBOSE(VB_AUDIO, "Broadcasting free space avail");
     1323        //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail");
    8211324        pthread_cond_broadcast(&audio_bufsig);
    8221325
    8231326        written_size = fragment_size;
  • libs/libmyth/audiooutputalsa.cpp

     
    7575    }
    7676    else
    7777    {
    78         fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     78        //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits
     79        //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits
     80        fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30);
    7981        buffer_time = 500000;  // .5 seconds
    8082        period_time = buffer_time / 4;  // 4 interrupts per buffer
    8183    }
     
    148150   
    149151    tmpbuf = aubuf;
    150152
    151     VERBOSE(VB_AUDIO, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
     153    VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)")
    152154            .arg(size).arg(frames));
    153155   
    154156    while (frames > 0)
  • libs/libmythsoundtouch/TDStretch.cpp

     
    9696
    9797    pMidBuffer = NULL;
    9898    pRefMidBufferUnaligned = NULL;
     99    midBufferLength = 0;
    99100    overlapLength = 0;
    100101
    101102    setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
     
    108109
    109110TDStretch::~TDStretch()
    110111{
    111     delete[] pMidBuffer;
    112     delete[] pRefMidBufferUnaligned;
     112    if (midBufferLength)
     113    {
     114        delete[] pMidBuffer;
     115        delete[] pRefMidBufferUnaligned;
     116        midBufferLength = 0;
     117    }
    113118}
    114119
    115120
     
    196201
    197202void TDStretch::clearMidBuffer()
    198203{
    199     if (bMidBufferDirty)
     204    if (bMidBufferDirty && midBufferLength)
    200205    {
    201         memset(pMidBuffer, 0, 2 * sizeof(SAMPLETYPE) * overlapLength);
     206        memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
    202207        bMidBufferDirty = FALSE;
    203208    }
    204209}
     
    239244// Seeks for the optimal overlap-mixing position.
    240245uint TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
    241246{
     247#ifdef MULTICHANNEL
     248    if (channels > 2)
     249    {
     250        // stereo sound
     251        if (bQuickseek)
     252        {
     253            return seekBestOverlapPositionMultiQuick(refPos);
     254        }
     255        else
     256        {
     257            return seekBestOverlapPositionMulti(refPos);
     258        }
     259    }
     260    else
     261#endif
    242262    if (channels == 2)
    243263    {
    244264        // stereo sound
     
    272292// of 'ovlPos'.
    273293inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const
    274294{
     295#ifdef MULTICHANNEL
     296    if (channels > 2)
     297    {
     298        overlapMulti(output, input + channels * ovlPos);
     299    }
     300    else
     301#endif
    275302    if (channels == 2)
    276303    {
    277304        // stereo sound
     
    291318// The best position is determined as the position where the two overlapped
    292319// sample sequences are 'most alike', in terms of the highest cross-correlation
    293320// value over the overlapping period
     321uint TDStretch::seekBestOverlapPositionMulti(const SAMPLETYPE *refPos)
     322{
     323    uint bestOffs;
     324    LONG_SAMPLETYPE bestCorr, corr;
     325    uint i;
     326
     327    // Slopes the amplitudes of the 'midBuffer' samples
     328    precalcCorrReference();
     329
     330    bestCorr = INT_MIN;
     331    bestOffs = 0;
     332
     333    // Scans for the best correlation value by testing each possible position
     334    // over the permitted range.
     335    for (i = 0; i < seekLength; i ++)
     336    {
     337        // Calculates correlation value for the mixing position corresponding
     338        // to 'i'
     339        corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer);
     340
     341        // Checks for the highest correlation value
     342        if (corr > bestCorr)
     343        {
     344            bestCorr = corr;
     345            bestOffs = i;
     346        }
     347    }
     348    // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     349    clearCrossCorrState();
     350
     351    return bestOffs;
     352}
     353
     354
     355// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
     356// routine
     357//
     358// The best position is determined as the position where the two overlapped
     359// sample sequences are 'most alike', in terms of the highest cross-correlation
     360// value over the overlapping period
     361uint TDStretch::seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos)
     362{
     363    uint j;
     364    uint bestOffs;
     365    LONG_SAMPLETYPE bestCorr, corr;
     366    uint scanCount, corrOffset, tempOffset;
     367
     368    // Slopes the amplitude of the 'midBuffer' samples
     369    precalcCorrReference();
     370
     371    bestCorr = INT_MIN;
     372    bestOffs = 0;
     373    corrOffset = 0;
     374    tempOffset = 0;
     375
     376    // Scans for the best correlation value using four-pass hierarchical search.
     377    //
     378    // The look-up table 'scans' has hierarchical position adjusting steps.
     379    // In first pass the routine searhes for the highest correlation with
     380    // relatively coarse steps, then rescans the neighbourhood of the highest
     381    // correlation with better resolution and so on.
     382    for (scanCount = 0;scanCount < 4; scanCount ++)
     383    {
     384        j = 0;
     385        while (scanOffsets[scanCount][j])
     386        {
     387            tempOffset = corrOffset + scanOffsets[scanCount][j];
     388            if (tempOffset >= seekLength) break;
     389
     390            // Calculates correlation value for the mixing position corresponding
     391            // to 'tempOffset'
     392            corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer);
     393
     394            // Checks for the highest correlation value
     395            if (corr > bestCorr)
     396            {
     397                bestCorr = corr;
     398                bestOffs = tempOffset;
     399            }
     400            j ++;
     401        }
     402        corrOffset = bestOffs;
     403    }
     404    // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
     405    clearCrossCorrState();
     406
     407    return bestOffs;
     408}
     409
     410
     411// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
     412// routine
     413//
     414// The best position is determined as the position where the two overlapped
     415// sample sequences are 'most alike', in terms of the highest cross-correlation
     416// value over the overlapping period
    294417uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos)
    295418{
    296419    uint bestOffs;
     
    512635void TDStretch::setChannels(uint numChannels)
    513636{
    514637    if (channels == numChannels) return;
     638#ifdef MULTICHANNEL
     639    assert(numChannels >= 1 && numChannels <= MULTICHANNEL);
     640#else
    515641    assert(numChannels == 1 || numChannels == 2);
     642#endif
    516643
    517644    channels = numChannels;
    518645    inputBuffer.setChannels(channels);
     
    635762/// Set new overlap length parameter & reallocate RefMidBuffer if necessary.
    636763void TDStretch::acceptNewOverlapLength(uint newOverlapLength)
    637764{
    638     uint prevOvl;
     765    //uint prevOvl;
    639766
    640     prevOvl = overlapLength;
     767    //prevOvl = overlapLength;
    641768    overlapLength = newOverlapLength;
    642769
    643     if (overlapLength > prevOvl)
     770    //if (overlapLength > prevOvl)
     771    if (overlapLength*channels > midBufferLength)
    644772    {
    645         delete[] pMidBuffer;
    646         delete[] pRefMidBufferUnaligned;
     773        if (midBufferLength)
     774        {
     775            delete[] pMidBuffer;
     776            delete[] pRefMidBufferUnaligned;
     777            midBufferLength = 0;
     778        }
    647779
    648         pMidBuffer = new SAMPLETYPE[overlapLength * 2];
     780        pMidBuffer = new SAMPLETYPE[overlapLength * channels];
    649781        bMidBufferDirty = TRUE;
    650782        clearMidBuffer();
     783        midBufferLength = overlapLength * channels;
    651784
    652         pRefMidBufferUnaligned = new SAMPLETYPE[2 * overlapLength + 16 / sizeof(SAMPLETYPE)];
     785        pRefMidBufferUnaligned = new SAMPLETYPE[channels * overlapLength + 16 / sizeof(SAMPLETYPE)];
    653786        // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency
    654787        pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16);
    655788    }
     
    718851
    719852#ifdef INTEGER_SAMPLES
    720853
     854#ifdef MULTICHANNEL
    721855// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
    722856// is faster to calculate
     857void TDStretch::precalcCorrReference()
     858{
     859    int i,j;
     860    int temp, temp2;
     861    short *src = pMidBuffer;
     862    short *dest = pRefMidBuffer;
     863
     864    for (i=0 ; i < (int)overlapLength ;i ++)
     865    {
     866        temp = i * (overlapLength - i);
     867
     868        for(j=0;j<channels;j++)
     869        {
     870            temp2 = (*src++ * temp) / slopingDivider;
     871            *dest++ = (short)(temp2);
     872        }
     873    }
     874}
     875#endif
     876
     877// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
     878// is faster to calculate
    723879void TDStretch::precalcCorrReferenceStereo()
    724880{
    725881    int i, cnt2;
     
    772928    }
    773929}
    774930
     931#ifdef MULTICHANNEL
     932// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
     933// version of the routine.
     934void TDStretch::overlapMulti(short *output, const short *input) const
     935{
     936    int i,j;
     937    short temp;
     938    //uint cnt2;
     939    const short *ip = input;
     940    short *op = output;
     941    const short *md = pMidBuffer;
    775942
     943    for (i = 0; i < (int)overlapLength ; i ++)
     944    {
     945        temp = (short)(overlapLength - i);
     946        for(j=0;j<channels;j++)
     947            *op++ = (*ip++ * i + *md++ * temp )  / overlapLength;
     948    }
     949}
     950#endif
     951
     952
    776953/// Calculates overlap period length in samples.
    777954/// Integer version rounds overlap length to closest power of 2
    778955/// for a divide scaling operation.
     
    8241001    return corr;
    8251002}
    8261003
     1004#ifdef MULTICHANNEL
     1005long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const
     1006{
     1007    long corr;
     1008    uint i;
     1009
     1010    corr = 0;
     1011    for (i = channels; i < channels * overlapLength; i++)
     1012    {
     1013        corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
     1014    }
     1015
     1016    return corr;
     1017}
     1018#endif
     1019
    8271020#endif // INTEGER_SAMPLES
    8281021
    8291022//////////////////////////////////////////////////////////////////////////////
     
    9311124    return corr;
    9321125}
    9331126
    934 #endif // FLOAT_SAMPLES
    935  No newline at end of file
     1127#endif // FLOAT_SAMPLES
  • libs/libmythsoundtouch/TDStretch.h

     
    4848#include "RateTransposer.h"
    4949#include "FIFOSamplePipe.h"
    5050
     51#define USE_MULTI_MMX
     52
    5153namespace soundtouch
    5254{
    5355
     
    100102    SAMPLETYPE *pMidBuffer;
    101103    SAMPLETYPE *pRefMidBuffer;
    102104    SAMPLETYPE *pRefMidBufferUnaligned;
     105    uint midBufferLength;
    103106    uint overlapLength;
    104107    uint overlapDividerBits;
    105108    uint slopingDivider;
     
    123126    virtual void clearCrossCorrState();
    124127    void calculateOverlapLength(uint overlapMs);
    125128
     129#ifdef MULTICHANNEL
     130    virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
     131#endif
    126132    virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    127133    virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    128134
     135#ifdef MULTICHANNEL
     136    virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos);
     137    virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos);
     138#endif
    129139    virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
    130140    virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
    131141    virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
    132142    virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
    133143    uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
    134144
     145#ifdef MULTICHANNEL
     146    virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
     147#endif
    135148    virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    136149    virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    137150
    138151    void clearMidBuffer();
    139152    void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
    140153
     154#ifdef MULTICHANNEL
     155    void precalcCorrReference();
     156#endif
    141157    void precalcCorrReferenceMono();
    142158    void precalcCorrReferenceStereo();
    143159
     
    225241    class TDStretchMMX : public TDStretch
    226242    {
    227243    protected:
     244#ifdef USE_MULTI_MMX
     245#ifdef MULTICHANNEL
     246        long calcCrossCorrMulti(const short *mixingPos, const short *compare) const;
     247#endif
     248#endif
    228249        long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
    229250        virtual void overlapStereo(short *output, const short *input) const;
    230251        virtual void clearCrossCorrState();
     
    237258    class TDStretch3DNow : public TDStretch
    238259    {
    239260    protected:
     261#ifdef MULTICHANNEL
     262        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     263#endif
    240264        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    241265    };
    242266#endif /// ALLOW_3DNOW
     
    247271    class TDStretchSSE : public TDStretch
    248272    {
    249273    protected:
     274#ifdef MULTICHANNEL
     275        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     276#endif
    250277        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    251278    };
    252279
  • libs/libmythsoundtouch/RateTransposer.cpp

     
    330330{
    331331    if (uChannels == numchannels) return;
    332332
     333#ifdef MULTICHANNEL
     334    assert(numchannels >= 1 && numchannels <= MULTICHANNEL);
     335#else
    333336    assert(numchannels == 1 || numchannels == 2);
     337#endif
    334338    uChannels = numchannels;
    335339
    336340    storeBuffer.setChannels(uChannels);
  • libs/libmythsoundtouch/mmx_gcc.cpp

     
    141141    return tmp;
    142142}
    143143
     144#ifdef USE_MULTI_MMX
     145// Calculates cross correlation of two buffers
     146long TDStretchMMX::calcCrossCorrMulti(const short *pV1, const short *pV2) const
     147{
     148    //static const unsigned long long int mm_half __attribute__ ((aligned(8))) = 0xffffffffULL;
     149    static const __m64 mm_mask[4][8] __attribute__ ((aligned(8))) = {
     150        {
     151            // even bit
     152            0xffffffffffffffffULL,
     153            0xffffffffffffffffULL,
     154            0xffffffffffffffffULL,
     155            0xffffffffffffffffULL,
     156            0,
     157            0,
     158            0,
     159            0
     160        },
     161        {
     162            0xffffffffffffffffULL,
     163            0xffffffffffffffffULL,
     164            0xffffffffffffffffULL,
     165            0x0000ffffffffffffULL,
     166            0,
     167            0,
     168            0,
     169            0
     170        },
     171        {
     172            0xffffffffffffffffULL,
     173            0xffffffffffffffffULL,
     174            0xffffffffffffffffULL,
     175            0x00000000ffffffffULL,
     176            0,
     177            0,
     178            0,
     179            0
     180        },
     181        {
     182            0xffffffffffffffffULL,
     183            0xffffffffffffffffULL,
     184            0xffffffffffffffffULL,
     185            0x000000000000ffffULL,
     186            0,
     187            0,
     188            0,
     189            0
     190        }
     191    };
     192    uint tmp;
     193    uint adjustedOverlapLength = overlapLength*channels;
     194    uint counter = ((adjustedOverlapLength+15)>>4)-1;    // load counter to counter = overlapLength / 8 - 1
     195    uint remainder = (16-adjustedOverlapLength)&0xf;     // since there are 1/3 sample per 1/2 quadword
     196
     197    __m64 *ph = (__m64*)&mm_mask[remainder&3][remainder>>2];
     198    __m64 *pv1=(__m64*)pV1, *pv2=(__m64*)pV2;
     199    GI(__m64 m0, m1, m2, m3, m4, m5, m6); // temporaries
     200    uint shift = overlapDividerBits;
     201
     202    // prepare to the first round by loading
     203    SI(m1 = pv1[0],             movq_a2r(0, pv1, mm1)); // load m1 = pv1[0]
     204    SI(m2 = pv1[1],             movq_a2r(8, pv1, mm2)); // load m2 = pv1[1]
     205    SI(m0 = _mm_setzero_si64(), pxor_r2r(mm0, mm0));    // clear m0
     206    SI(m5 = _mm_cvtsi32_si64(shift),movd_v2r(shift, mm5));   // shift in 64bit reg
     207
     208    do {
     209        // Calculate cross-correlation between the tempOffset and tmpbid_buffer.
     210        // Process 4 parallel batches of 2 * stereo samples each during one
     211        // round to improve CPU-level parallellization.
     212        SI(m1 = _mm_madd_pi16(m1, pv2[0]),pmaddwd_a2r(0, pv2, mm1)); // multiply-add m1 = m1 * pv2[0]
     213        SI(m3 = pv1[2],                   movq_a2r(16, pv1, mm3));   // load mm3 = pv1[2]
     214        SI(m2 = _mm_madd_pi16(m2, pv2[1]),pmaddwd_a2r(8, pv2, mm2)); // multiply-add m2 = m2 * pv2[1]
     215        SI(m4 = pv1[3],                   movq_a2r(24, pv1, mm4));   // load mm4 = pv1[3]
     216        SI(m3 = _mm_madd_pi16(m3, pv2[2]),pmaddwd_a2r(16, pv2, mm3));// multiply-add m3 = m3 * pv2[2]
     217        SI(m2 = _mm_add_pi32(m2, m1),     paddd_r2r(mm1, mm2));      // add m2 += m1
     218        SI(m4 = _mm_madd_pi16(m4, pv2[3]),pmaddwd_a2r(24, pv2, mm4));// multiply-add m4 = m4 * pv2[3]
     219        SI(m1 = pv1[4],                   movq_a2r(32, pv1, mm1));   // mm1 = pv1[0] for next round
     220        SI(m2 = _mm_srai_pi32(m2, m5),    psrad_r2r(mm5, mm2));      // m2 >>= shift (mm5)
     221        pv1 += 4;                                                    // increment first pointer
     222        SI(m3 = _mm_add_pi32(m3, m4),     paddd_r2r(mm4, mm3));      // m3 += m4
     223        SI(m0 = _mm_add_pi32(m0, m2),     paddd_r2r(mm2, mm0));      // m0 += m2
     224        SI(m2 = pv1[1],                   movq_a2r(8, pv1, mm2));    // mm2 = pv1[1] for next round
     225        SI(m3 = _mm_srai_pi32(m3, m5),    psrad_r2r(mm5, mm3));    // m3 >>= shift (mm5)
     226        pv2 += 4;                                                    // increment second pointer
     227        SI(m0 = _mm_add_pi32(m0, m3),     paddd_r2r(mm3, mm0));      // add m0 += m3
     228    } while ((--counter)!=0);
     229
     230    SI(m6 = ph[0], movq_a2r(0, ph, mm6));
     231    // Finalize the last partial loop:
     232    SI(m1 = _mm_madd_pi16(m1, pv2[0]), pmaddwd_a2r(0, pv2, mm1));
     233    SI(m1 = _mm_and_si64(m1, m6),      pand_r2r(mm6, mm1));
     234    SI(m3 = pv1[2],                    movq_a2r(16, pv1, mm3));
     235    SI(m6 = ph[1], movq_a2r(8, ph, mm6));
     236    SI(m2 = _mm_madd_pi16(m2, pv2[1]), pmaddwd_a2r(8, pv2, mm2));
     237    SI(m2 = _mm_and_si64(m2, m6),      pand_r2r(mm6, mm2));
     238    SI(m4 = pv1[3],                    movq_a2r(24, pv1, mm4));
     239    SI(m6 = ph[2], movq_a2r(16, ph, mm6));
     240    SI(m3 = _mm_madd_pi16(m3, pv2[2]), pmaddwd_a2r(16, pv2, mm3));
     241    SI(m3 = _mm_and_si64(m3, m6),      pand_r2r(mm6, mm3));
     242    SI(m2 = _mm_add_pi32(m2, m1),      paddd_r2r(mm1, mm2));
     243    SI(m6 = ph[3], movq_a2r(24, ph, mm6));
     244    SI(m4 = _mm_madd_pi16(m4, pv2[3]), pmaddwd_a2r(24, pv2, mm4));
     245    SI(m4 = _mm_and_si64(m4, m6),      pand_r2r(mm6, mm4));
     246    SI(m2 = _mm_srai_pi32(m2, m5),     psrad_r2r(mm5, mm2));
     247    SI(m3 = _mm_add_pi32(m3, m4),      paddd_r2r(mm4, mm3));
     248    SI(m0 = _mm_add_pi32(m0, m2),      paddd_r2r(mm2, mm0));
     249    SI(m3 = _mm_srai_pi32(m3, m5),     psrad_r2r(mm5, mm3));
     250    SI(m0 = _mm_add_pi32(m0, m3),      paddd_r2r(mm3, mm0));
     251
     252    // copy hi-dword of mm0 to lo-dword of mm1, then sum mm0+mm1
     253    // and finally return the result
     254    SI(m1 = m0,                        movq_r2r(mm0, mm1));
     255    SI(m1 = _mm_srli_si64(m1, 32),     psrld_i2r(32, mm1));
     256    SI(m0 = _mm_add_pi32(m0, m1),      paddd_r2r(mm1, mm0));
     257    SI(tmp = _mm_cvtsi64_si32(m0),     movd_r2m(mm0, tmp));
     258    return tmp;
     259}
     260#endif
     261
    144262void TDStretchMMX::clearCrossCorrState()
    145263{
    146264    _mm_empty();
     
    224342    _mm_empty();
    225343}
    226344
     345#if 0
     346// MMX-optimized version of the function overlapMulti
     347void TDStretchMMX::overlapMulti(short *output, const short *input) const
     348{
     349    _mm_empty();
     350    uint shift = overlapDividerBits;
     351    uint counter = overlapLength>>2;                 // counter = overlapLength / 4
     352    __m64 *inPtr = (__m64*) input;                   // load address of inputBuffer
     353    __m64 *midPtr = (__m64*) pMidBuffer;             // load address of midBuffer
     354    __m64 *outPtr = ((__m64*) output)-2;             // load address of outputBuffer
     355    GI(__m64 m0, m1, m2, m3, m4, m5, m6, m7);        // temporaries
     356
     357    // load mixing value adder to mm5
     358    uint tmp0 = 0x0002fffe;                                      // tmp0 = 0x0002 fffe
     359    SI(m5 = _mm_cvtsi32_si64(tmp0),    movd_v2r(tmp0, mm5));     // mm5 = 0x0000 0000 0002 fffe
     360    SI(m5 = _mm_unpacklo_pi32(m5,m5),  punpckldq_r2r(mm5, mm5)); // mm5 = 0x0002 fffe 0002 fffe
     361    // load sliding mixing value counter to mm6
     362    SI(m6 = _mm_cvtsi32_si64(overlapLength), movd_v2r(overlapLength, mm6));
     363    SI(m6 = _mm_unpacklo_pi32(m6, m6), punpckldq_r2r(mm6, mm6)); // mm6 = 0x0000 OVL_ 0000 OVL_
     364    // load sliding mixing value counter to mm7
     365    uint tmp1 = (overlapLength-1)|0x00010000;                    // tmp1 = 0x0001 overlapLength-1
     366    SI(m7 = _mm_cvtsi32_si64(tmp1),    movd_v2r(tmp1, mm7));     // mm7 = 0x0000 0000 0001 01ff
     367    SI(m7 = _mm_unpacklo_pi32(m7, m7), punpckldq_r2r(mm7, mm7)); // mm7 = 0x0001 01ff 0001 01ff
     368
     369    do {
     370        // Process two parallel batches of 2+2 stereo samples during each round
     371        // to improve CPU-level parallellization.
     372        //
     373        // Load [midPtr] into m0 and m1
     374        // Load [inPtr] into m3
     375        // unpack words of m0, m1 and m3 into m0 and m1
     376        // multiply-add m0*m6 and m1*m7, store results into m0 and m1
     377        // divide m0 and m1 by 512 (=right-shift by overlapDividerBits)
     378        // pack the result into m0 and store into [edx]
     379        //
     380        // Load [midPtr+8] into m2 and m3
     381        // Load [inPtr+8] into m4
     382        // unpack words of m2, m3 and m4 into m2 and m3
     383        // multiply-add m2*m6 and m3*m7, store results into m2 and m3
     384        // divide m2 and m3 by 512 (=right-shift by overlapDividerBits)
     385        // pack the result into m2 and store into [edx+8]
     386        SI(m0 = midPtr[0],                movq_a2r(0, midPtr, mm0));// mm0 = m1l m1r m0l m0r
     387        outPtr += 2;
     388        SI(m3 = inPtr[0],                 movq_a2r(0, inPtr, mm3)); // mm3 = i1l i1r i0l i0r
     389        SI(m1 = m0,                       movq_r2r(mm0, mm1));      // mm1 = m1l m1r m0l m0r
     390        SI(m2 = midPtr[1],                movq_a2r(8, midPtr, mm2));// mm2 = m3l m3r m2l m2r
     391        SI(m0 = _mm_unpacklo_pi16(m0, m3),punpcklwd_r2r(mm3, mm0)); // mm0 = i0l m0l i0r m0r
     392        midPtr += 2;
     393        SI(m4 = inPtr[1],                 movq_a2r(8, inPtr, mm4)); // mm4 = i3l i3r i2l i2r
     394        SI(m1 = _mm_unpackhi_pi16(m1, m3),punpckhwd_r2r(mm3, mm1)); // mm1 = i1l m1l i1r m1r
     395        inPtr+=2;
     396        SI(m3 = m2,                       movq_r2r(mm2, mm3));      // mm3 = m3l m3r m2l m2r
     397        SI(m2 = _mm_unpacklo_pi16(m2, m4),punpcklwd_r2r(mm4, mm2)); // mm2 = i2l m2l i2r m2r
     398        // mm0 = i0l*m63+m0l*m62 i0r*m61+m0r*m60
     399        SI(m0 = _mm_madd_pi16(m0, m6),    pmaddwd_r2r(mm6, mm0));
     400        SI(m3 = _mm_unpackhi_pi16(m3, m4),punpckhwd_r2r(mm4, mm3)); // mm3 = i3l m3l i3r m3r
     401        SI(m4 = _mm_cvtsi32_si64(shift),  movd_v2r(shift, mm4));    // mm4 = shift
     402        // mm1 = i1l*m73+m1l*m72 i1r*m71+m1r*m70
     403        SI(m1 = _mm_madd_pi16(m1, m7),    pmaddwd_r2r(mm7, mm1));
     404        SI(m6 = _mm_add_pi16(m6, m5),     paddw_r2r(mm5, mm6));
     405        SI(m7 = _mm_add_pi16(m7, m5),     paddw_r2r(mm5, mm7));
     406        SI(m0 = _mm_srai_pi32(m0, m4),    psrad_r2r(mm4, mm0));    // mm0 >>= shift
     407        // mm2 = i2l*m63+m2l*m62 i2r*m61+m2r*m60
     408        SI(m2 = _mm_madd_pi16(m2, m6),    pmaddwd_r2r(mm6, mm2));
     409        SI(m1 = _mm_srai_pi32(m1, m4),    psrad_r2r(mm4, mm1));    // mm1 >>= shift
     410        // mm3 = i3l*m73+m3l*m72 i3r*m71+m3r*m70
     411        SI(m3 = _mm_madd_pi16(m3, m7),    pmaddwd_r2r(mm7, mm3));
     412        SI(m2 = _mm_srai_pi32(m2, m4),    psrad_r2r(mm4, mm2));    // mm2 >>= shift
     413        SI(m0 = _mm_packs_pi32(m0, m1),   packssdw_r2r(mm1, mm0)); // mm0 = mm1h mm1l mm0h mm0l
     414        SI(m3 = _mm_srai_pi32(m3, m4),    psrad_r2r(mm4, mm3));    // mm3 >>= shift
     415        SI(m6 = _mm_add_pi16(m6, m5),     paddw_r2r(mm5, mm6));
     416        SI(m2 = _mm_packs_pi32(m2, m3),   packssdw_r2r(mm3, mm2)); // mm2 = mm2h mm2l mm3h mm3l
     417        SI(m7 = _mm_add_pi16(m7, m5),     paddw_r2r(mm5, mm7));
     418        SI(outPtr[0] = m0,                movq_r2a(mm0, 0, outPtr));
     419        SI(outPtr[1] = m2,                movq_r2a(mm2, 8, outPtr));
     420    } while ((--counter)!=0);
     421    _mm_empty();
     422}
     423#endif
     424
    227425//////////////////////////////////////////////////////////////////////////////
    228426//
    229427// implementation of MMX optimized functions of class 'FIRFilter'
  • libs/libmythsoundtouch/STTypes.h

     
    6161    #define INTEGER_SAMPLES       //< 16bit integer samples
    6262    //#define FLOAT_SAMPLES       //< 32bit float samples
    6363
     64    #define MULTICHANNEL 6
    6465
    6566    /// Define this to allow CPU-specific assembler optimizations. Notice that
    6667    /// having this enabled on non-x86 platforms doesn't matter; the compiler can
  • libs/libmythsoundtouch/SoundTouch.cpp

     
    140140// Sets the number of channels, 1 = mono, 2 = stereo
    141141void SoundTouch::setChannels(uint numChannels)
    142142{
     143#ifdef MULTICHANNEL
     144    if (numChannels < 1 || numChannels > MULTICHANNEL)
     145#else
    143146    if (numChannels != 1 && numChannels != 2)
     147#endif
    144148    {
    145149        throw std::runtime_error("Illegal number of channels");
    146150    }
  • programs/mythfrontend/globalsettings.cpp

     
    3636        dev.setNameFilter("adsp*");
    3737        gc->fillSelectionsFromDir(dev);
    3838    }
     39#ifdef USE_ALSA
     40    gc->addSelection("ALSA:default", "ALSA:default");
     41    gc->addSelection("ALSA:analog", "ALSA:analog");
     42    gc->addSelection("ALSA:digital", "ALSA:digital");
     43    gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog");
     44    gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital");
     45#endif
     46#ifdef USE_ARTS
     47    gc->addSelection("ARTS:", "ARTS:");
     48#endif
     49#ifdef USE_JACK
     50    gc->addSelection("JACK:output", "JACK:output");
     51#endif
     52    gc->addSelection("NULL", "NULL");
    3953
    4054    return gc;
    4155}
    4256
     57static HostComboBox *MaxAudioChannels()
     58{
     59    HostComboBox *gc = new HostComboBox("MaxChannels",false);
     60    gc->setLabel(QObject::tr("Max Audio Channels"));
     61    //gc->addSelection(QObject::tr("Mono"), "1");
     62    //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default
     63    //gc->addSelection(QObject::tr("3 Channel: L C R"), "3");
     64    //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4");
     65    //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5");
     66    //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6");
     67    gc->addSelection(QObject::tr("Stereo"), "2", true); // default
     68    gc->addSelection(QObject::tr("6 Channel"), "6");
     69    gc->setHelpText(
     70            QObject::tr("Set the maximum number of audio channels to be decoded. "
     71                "This is for multi-channel/surround audio playback."));
     72    return gc;
     73}
     74
    4375static HostCheckBox *MythControlsVolume()
    4476{
    4577    HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
     
    20922124         setUseLabel(false);
    20932125
    20942126         addChild(AudioOutputDevice());
     2127#if 0
     2128         ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false);
     2129         ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false);
     2130         settingsLeft->addChild(AC3PassThrough());
     2131#ifdef CONFIG_DTS
     2132         settingsLeft->addChild(DTSPassThrough());
     2133#endif
     2134         settingsLeft->addChild(AggressiveBuffer());
     2135         hg->addChild(settingsLeft);
     2136
     2137         ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false);
     2138         settingsRight->addChild(MaxAudioChannels());
     2139         hg->addChild(settingsRight);
     2140
     2141         addChild(hg);
     2142#else
    20952143         addChild(AC3PassThrough());
    20962144#ifdef CONFIG_DTS
    20972145         addChild(DTSPassThrough());
    20982146#endif
    20992147         addChild(AggressiveBuffer());
     2148         addChild(MaxAudioChannels());
     2149#endif
    21002150
    21012151         Setting* volumeControl = MythControlsVolume();
    21022152         addChild(volumeControl);
  • programs/mythtranscode/transcode.cpp

     
    4646
    4747    // reconfigure sound out for new params
    4848    virtual void Reconfigure(int audio_bits,
    49                         int audio_channels, int audio_samplerate)
     49                        int audio_channels, int audio_samplerate,
     50                        void * = NULL)
    5051    {
     52        ClearError();
    5153        (void)audio_samplerate;
    5254        bits = audio_bits;
    5355        channels = audio_channels;
    5456        bytes_per_sample = bits * channels / 8;
     57        if (channels>2)
     58            Error("Invalid channel count");
    5559    }
    5660
    5761    // dsprate is in 100 * samples/second
  • libs/libmythtv/avformatdecoder.h

     
    238238    bool              allow_ac3_passthru;
    239239    bool              allow_dts_passthru;
    240240    bool              disable_passthru;
     241    int               max_channels;
    241242
    242243    AudioInfo         audioIn;
    243244    AudioInfo         audioOut;
  • libs/libmythtv/avformatdecoder.cpp

     
    3838#define MAX_AC3_FRAME_SIZE 6144
    3939
    4040/** Set to zero to allow any number of AC3 channels. */
     41#define MAXCHANNELSELECT 1
     42#if MAXCHANNELSELECT
     43#define MAX_OUTPUT_CHANNELS compiler error
     44#else
    4145#define MAX_OUTPUT_CHANNELS 2
     46#endif
    4247
    4348static int dts_syncinfo(uint8_t *indata_ptr, int *flags,
    4449                        int *sample_rate, int *bit_rate);
     
    286291#ifdef CONFIG_DTS
    287292    allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
    288293#endif
     294    max_channels = gContext->GetNumSetting("MaxChannels", 2);
    289295
    290296    audioIn.sample_size = -32; // force SetupAudioStream to run once
    291297}
     
    406412    framesPlayed = lastKey;
    407413    framesRead = lastKey;
    408414
     415    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")
     416        .arg(desiredFrame)
     417        .arg(fps)
     418        .arg(ts)
     419        .arg(discardFrames)
     420        .arg(framesPlayed)
     421        .arg(st->cur_dts)
     422        .arg(adj_cur_dts)
     423        .arg(newts)
     424        .arg(frameseekadjust)
     425        );
     426
    409427    int normalframes = desiredFrame - framesPlayed;
    410428
     429#if 0
     430    if (!exactseeks)
     431        normalframes = 0;
     432#endif
     433
    411434    SeekReset(lastKey, normalframes, discardFrames, discardFrames);
    412435
    413436    if (discardFrames)
     
    739762
    740763    fmt->flags &= ~AVFMT_NOFILE;
    741764
     765#if 1
     766    if ((m_playbackinfo) || livetv || watchingrecording)
     767    {
     768        const char *name = ic->av_class->item_name(ic);
     769        VERBOSE(VB_GENERAL, QString("libavformat type %1").arg(name));
     770    }
     771#endif
     772 
     773    //struct timeval one, two, res;
     774    //gettimeofday(&one, NULL);
     775
    742776    av_estimate_timings(ic);
    743777    av_read_frame_flush(ic);
    744778
     
    769803    // If we don't have a position map, set up ffmpeg for seeking
    770804    if (!recordingHasPositionMap)
    771805    {
     806        const char *name = ic->av_class->item_name(ic);
    772807        VERBOSE(VB_PLAYBACK, LOC +
    773                 "Recording has no position -- using libavformat seeking.");
     808                QString("Recording has no position -- using libavformat seeking. %1").arg(name));
    774809        int64_t dur = ic->duration / (int64_t)AV_TIME_BASE;
    775810
    776811        if (dur > 0)
     
    10481083                            <<") already open, leaving it alone.");
    10491084                }
    10501085                assert(enc->codec_id);
     1086                VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels));
     1087#if 0
     1088                if (enc->channels > 2)
     1089                    enc->channels = 2;
     1090#endif
    10511091
     1092#if 0
    10521093                // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU
    10531094                if (enc->codec_id == CODEC_ID_DTS)
    10541095                {
     
    10571098                    // enc->bit_rate = what??;
    10581099                }
    10591100                // HACK END REALLY UGLY HACK FOR DTS PASSTHRU
     1101#endif
    10601102
    10611103                bitrate += enc->bit_rate;
    10621104                break;
     
    15571599        {
    15581600            long long startpos = pkt->pos;
    15591601
    1560             VERBOSE(VB_PLAYBACK, LOC +
     1602            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
    15611603                    QString("positionMap[ %1 ] == %2.")
    15621604                    .arg(prevgoppos / keyframedist)
    15631605                    .arg((int)startpos));
     
    22682310
    22692311        AVStream *curstream = ic->streams[pkt->stream_index];
    22702312
     2313#if 0
     2314        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3")
     2315                .arg(pkt->pts)
     2316                .arg(pkt->dts)
     2317                .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1)
     2318               );
     2319#endif
     2320
    22712321        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    22722322            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    22732323
     
    23812431                    if (!curstream->codec->channels)
    23822432                    {
    23832433                        QMutexLocker locker(&avcodeclock);
     2434#if MAXCHANNELSELECT
     2435                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     2436                        curstream->codec->channels = audioOut.channels;
     2437#else
    23842438                        curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     2439#endif
    23852440                        ret = avcodec_decode_audio(
    23862441                            curstream->codec, audioSamples,
    23872442                            &data_size, ptr, len);
     
    24322487                    {
    24332488                        AVCodecContext *ctx = curstream->codec;
    24342489
     2490#if MAXCHANNELSELECT
    24352491                        if ((ctx->channels == 0) ||
     2492                            (ctx->channels > audioOut.channels))
     2493                            ctx->channels = audioOut.channels;
     2494#else
     2495                        if ((ctx->channels == 0) ||
    24362496                            (ctx->channels > MAX_OUTPUT_CHANNELS))
    24372497                            ctx->channels = MAX_OUTPUT_CHANNELS;
     2498#endif
    24382499
    24392500                        ret = avcodec_decode_audio(
    24402501                            ctx, audioSamples, &data_size, ptr, len);
     
    24702531                                (curstream->codec->channels * 2) /
    24712532                                curstream->codec->sample_rate);
    24722533
     2534                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4")
     2535                            .arg(pkt->pts)
     2536                            .arg(pkt->dts)
     2537                            .arg(temppts).arg(lastapts));
    24732538                    GetNVP()->AddAudioData((char *)audioSamples, data_size,
    24742539                                           temppts);
    24752540
     
    25612626                    else
    25622627                        temppts = lastvpts;
    25632628
     2629                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4")
     2630                            .arg(pkt->pts)
     2631                            .arg(pkt->dts)
     2632                            .arg(temppts).arg(lastvpts));
    25642633/* XXX: Broken.
    25652634                    if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 &&
    25662635                        context->height == picframe->height)
     
    26552724
    26562725void AvFormatDecoder::SetDisablePassThrough(bool disable)
    26572726{
     2727#if MAXCHANNELSELECT
     2728    // can only disable never reenable as once tiemstretch is on its on for the session
     2729    if (disable_passthru)
     2730        return;
     2731#endif
    26582732    if (selectedAudioStream.av_stream_index < 0)
    26592733    {
    26602734        disable_passthru = disable;
    26612735        return;
    26622736    }
    2663 
     2737 
    26642738    if (disable != disable_passthru)
    26652739    {
    26662740        disable_passthru = disable;
     
    26872761    AVCodecContext *codec_ctx = NULL;
    26882762    AudioInfo old_in  = audioIn;
    26892763    AudioInfo old_out = audioOut;
     2764    bool using_passthru = false;
    26902765
    26912766    if ((currentAudioTrack >= 0) &&
    26922767        (selectedAudioStream.av_stream_index <= ic->nb_streams) &&
     
    26962771        assert(curstream->codec);
    26972772        codec_ctx = curstream->codec;       
    26982773        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2699                                 !disable_passthru &&
    27002774                                (codec_ctx->codec_id == CODEC_ID_AC3));
    27012775        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2702                                 !disable_passthru &&
    27032776                                (codec_ctx->codec_id == CODEC_ID_DTS));
     2777        using_passthru = do_ac3_passthru || do_dts_passthru;
    27042778        info = AudioInfo(codec_ctx->codec_id,
    27052779                         codec_ctx->sample_rate, codec_ctx->channels,
    2706                          do_ac3_passthru || do_dts_passthru);
     2780                         using_passthru && !disable_passthru);
    27072781    }
    27082782
    27092783    if (info == audioIn)
    27102784        return false; // no change
    27112785
     2786    QString ptmsg = "";
     2787    if (using_passthru)
     2788    {
     2789        ptmsg = QString(" using passthru");
     2790    }
    27122791    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    2713             QString("audio track #%1").arg(currentAudioTrack+1));
     2792            QString("audio track #%1")
     2793                .arg(currentAudioTrack+1)
     2794            + ptmsg );
    27142795
    27152796    audioOut = audioIn = info;
     2797#if MAXCHANNELSELECT
     2798    if (using_passthru)
     2799#else
    27162800    if (audioIn.do_passthru)
     2801#endif
    27172802    {
    27182803        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    2719         audioOut.channels    = 2;
    2720         audioOut.sample_rate = 48000;
    2721         audioOut.sample_size = 4;
     2804        AudioInfo digInfo = audioOut;
     2805        if (!disable_passthru)
     2806        {
     2807            digInfo.channels    = 2;
     2808            digInfo.sample_rate = 48000;
     2809            digInfo.sample_size = 4;
     2810        }
     2811        if (audioOut.channels > max_channels)
     2812        {
     2813            audioOut.channels = max_channels;
     2814            audioOut.sample_size = audioOut.channels * 2;
     2815            codec_ctx->channels = audioOut.channels;
     2816        }
     2817#if MAXCHANNELSELECT
     2818        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     2819                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     2820                .arg(digInfo.toString())
     2821                .arg(old_in.toString()).arg(old_out.toString())
     2822                .arg(audioIn.toString()).arg(audioOut.toString()));
     2823
     2824        if (digInfo.sample_rate > 0)
     2825            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     2826
     2827        //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     2828        //                         audioOut.sample_rate);
     2829        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     2830                                 digInfo.sample_rate);
     2831        // allow the audio stuff to reencode
     2832        GetNVP()->SetAudioCodec(codec_ctx);
     2833        GetNVP()->ReinitAudio();
     2834        return true;
     2835#endif
    27222836    }
     2837#if MAXCHANNELSELECT
    27232838    else
    27242839    {
     2840        if (audioOut.channels > max_channels)
     2841        {
     2842            audioOut.channels = max_channels;
     2843            audioOut.sample_size = audioOut.channels * 2;
     2844            codec_ctx->channels = audioOut.channels;
     2845        }
     2846    }
     2847    bool audiook;
     2848    do
     2849    {
     2850#else
     2851    else
     2852    {
    27252853        if (audioOut.channels > MAX_OUTPUT_CHANNELS)
    27262854        {
    27272855            audioOut.channels = MAX_OUTPUT_CHANNELS;
     
    27292857            codec_ctx->channels = MAX_OUTPUT_CHANNELS;
    27302858        }
    27312859    }
     2860#endif
    27322861
    27332862    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    27342863            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    27402869
    27412870    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    27422871                             audioOut.sample_rate);
    2743     GetNVP()->ReinitAudio();
     2872    // allow the audio stuff to reencode
     2873    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     2874    QString errMsg = GetNVP()->ReinitAudio();
     2875#if MAXCHANNELSELECT
     2876        audiook = errMsg.isEmpty();
     2877        if (!audiook)
     2878        {
     2879            switch (audioOut.channels)
     2880            {
     2881#if 0
     2882                case 8:
     2883                    audioOut.channels = 6;
     2884                    break;
     2885#endif
     2886                case 6:
     2887                    audioOut.channels = 5;
     2888                    break;
     2889                case 5:
     2890                    audioOut.channels = 4;
     2891                    break;
     2892                case 4:
     2893                    audioOut.channels = 3;
     2894                    break;
     2895                case 3:
     2896                    audioOut.channels = 2;
     2897                    break;
     2898                case 2:
     2899                    audioOut.channels = 1;
     2900                    break;
     2901                default:
     2902                    // failed to reconfigure under any circumstances
     2903                    audiook = true;
     2904                    audioOut.channels = 0;
     2905                    break;
     2906            }
     2907            audioOut.sample_size = audioOut.channels * 2;
     2908            codec_ctx->channels = audioOut.channels;
     2909        }
     2910    } while (!audiook);
     2911#endif
    27442912
    27452913    return true;
    27462914}
  • libs/libmythtv/NuppelVideoPlayer.h

     
    107107    void SetVideoParams(int w, int h, double fps, int keydist,
    108108                        float a = 1.33333, FrameScanType scan = kScan_Ignore);
    109109    void SetAudioParams(int bits, int channels, int samplerate);
     110    void SetAudioCodec(void *ac);
    110111    void SetEffDsp(int dsprate);
    111112    void SetFileLength(int total, int frames);
    112113    void Zoom(int direction);
     
    142143    bool    AtNormalSpeed(void) const         { return next_normal_speed; }
    143144    bool    IsDecoderThreadAlive(void) const  { return decoder_thread_alive; }
    144145    bool    IsNearEnd(long long framesRemaining = -1) const;
     146    float   GetAudioStretchFactor() { return audio_stretchfactor; }
    145147    bool    PlayingSlowForPrebuffer(void) const { return m_playing_slower; }
    146148    bool    HasAudioIn(void) const            { return !no_audio_in; }
    147149    bool    HasAudioOut(void) const           { return !no_audio_out; }
     
    170172    bool Play(float speed = 1.0, bool normal = true,
    171173              bool unpauseaudio = true);
    172174    bool GetPause(void) const;
     175    float GetNextPlaySpeed() { return next_play_speed; }
    173176
    174177    // Seek stuff
    175178    bool FastForward(float seconds);
     
    492495    int      audio_bits;
    493496    int      audio_samplerate;
    494497    float    audio_stretchfactor;
     498    void     *audio_codec;
    495499
    496500    // Picture-in-Picture
    497501    NuppelVideoPlayer *pipplayer;
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    124124      audioOutput(NULL),            audiodevice("/dev/dsp"),
    125125      audio_channels(2),            audio_bits(-1),
    126126      audio_samplerate(44100),      audio_stretchfactor(1.0f),
     127      audio_codec(NULL),
    127128      // Picture-in-Picture
    128129      pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false),
    129130      // Preview window support
     
    528529
    529530    if (audioOutput)
    530531    {
    531         audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate);
     532        audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_codec);
    532533        errMsg = audioOutput->GetError();
    533534        if (!errMsg.isEmpty())
    534535            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    661662        {
    662663            VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    663664                    "framerate (refresh rate too low for bob deint)");
     665            //m_scan = kScan_Ignore;
     666            //m_can_double = false;
    664667            FallbackDeint();
    665668        }
    666669    }
     
    15131516    warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) /
    15141517                      WARPAVLEN;
    15151518
    1516     //cerr << "Divergence: " << divergence << "  Rate: " << rate
    1517     //<< "  Warpfactor: " << warpfactor << "  warpfactor_avg: "
    1518     //<< warpfactor_avg << endl;
     1519#if 1
     1520    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1521        "Divergence: %1 "
     1522        "  Rate: %2"
     1523        "  Warpfactor: %3"
     1524        "  warpfactor_avg: %4")
     1525        .arg(divergence)
     1526        .arg(rate)
     1527        .arg(warpfactor)
     1528        .arg(warpfactor_avg)
     1529        );
     1530#endif
    15191531    return divergence;
    15201532}
    15211533
     
    15961608    if (diverge < -MAXDIVERGE)
    15971609    {
    15981610        // If video is way ahead of audio, adjust for it...
    1599         QString dbg = QString("Video is %1 frames ahead of audio, ")
     1611        QString dbg = QString("Audio is %1 frames ahead of video, ")
    16001612            .arg(-diverge);
    16011613
    16021614        // Reset A/V Sync
     
    16111623            // decoding; display the frame, but don't wait for A/V Sync.
    16121624            videoOutput->PrepareFrame(buffer, ps);
    16131625            videoOutput->Show(m_scan);
    1614             VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
     1626            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait.");
    16151627        }
    16161628        else
    16171629        {
    16181630            // If we are using software decoding, skip this frame altogether.
    1619             VERBOSE(VB_PLAYBACK, LOC + dbg + "dropping frame.");
     1631            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame.");
    16201632        }
    16211633    }
    16221634    else if (!using_null_videoout)
     
    16251637        if (buffer)
    16261638            videoOutput->PrepareFrame(buffer, ps);
    16271639
     1640        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate));
    16281641        videosync->WaitForFrame(avsync_adjustment);
     1642        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
    16291643        if (!resetvideo)
    16301644            videoOutput->Show(m_scan);
    16311645
     
    16451659
    16461660            // Display the second field
    16471661            videosync->AdvanceTrigger();
    1648             videosync->WaitForFrame(0);
     1662            videosync->WaitForFrame(avsync_adjustment);
    16491663            if (!resetvideo)
    16501664                videoOutput->Show(kScan_Intr2ndField);
    16511665        }
     
    16571671
    16581672    if (output_jmeter && output_jmeter->RecordCycleTime())
    16591673    {
    1660         //cerr << "avsync_delay: " << avsync_delay / 1000
    1661         //     << ", avsync_avg: " << avsync_avg / 1000
    1662         //     << ", warpfactor: " << warpfactor
    1663         //     << ", warpfactor_avg: " << warpfactor_avg << endl;
     1674#if 1
     1675        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1676            "avsync_delay: %1"
     1677            ", avsync_avg: %2"
     1678            ", warpfactor: %3"
     1679            ", warpfactor_avg: %4")
     1680                .arg(avsync_delay / 1000)
     1681                .arg(avsync_avg / 1000)
     1682                .arg(warpfactor)
     1683                .arg(warpfactor_avg));
     1684#endif
    16641685    }
    16651686
    16661687    videosync->AdvanceTrigger();
     
    16711692        // If audio is way ahead of video, adjust for it...
    16721693        // by cutting the frame rate in half for the length of this frame
    16731694
    1674         avsync_adjustment = frame_interval;
     1695        //avsync_adjustment = frame_interval;
     1696        avsync_adjustment = refreshrate;
    16751697        lastsync = true;
    1676         VERBOSE(VB_PLAYBACK, LOC +
    1677                 QString("Audio is %1 frames ahead of video,\n"
     1698        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
     1699                QString("Video is %1 frames ahead of audio,\n"
    16781700                        "\t\t\tdoubling video frame interval.").arg(diverge));
    16791701    }
    16801702
    16811703    if (audioOutput && normal_speed)
    16821704    {
    16831705        long long currentaudiotime = audioOutput->GetAudiotime();
    1684 #if 0
    1685         VERBOSE(VB_PLAYBACK, QString(
     1706#if 1
     1707        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString(
    16861708                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    16871709                    "avdel %4 avg %5 tcoffset %6")
    16881710                .arg(currentaudiotime)
     
    19681990            {
    19691991                VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    19701992                        "framerate (refresh rate too low for bob deint)");
     1993                //m_scan = kScan_Ignore;
     1994                //m_can_double = false;
    19711995                FallbackDeint();
    19721996            }
    19731997        }
     
    26722696    audio_samplerate = samplerate;
    26732697}
    26742698
     2699void NuppelVideoPlayer::SetAudioCodec(void* ac)
     2700{
     2701    audio_codec = ac;
     2702}
     2703
    26752704void NuppelVideoPlayer::SetEffDsp(int dsprate)
    26762705{
    26772706    if (audioOutput)
     
    27162745        tc_avcheck_framecounter++;
    27172746        if (tc_avcheck_framecounter == 30)
    27182747        {
    2719 #define AUTO_RESYNC 1
     2748#define AUTO_RESYNC 0
    27202749#if AUTO_RESYNC
    27212750            // something's terribly, terribly wrong.
    27222751            if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 ||
  • libs/libavcodec/a52dec.c

     
    149149    }
    150150}
    151151
     152static inline int16_t convert (int32_t i)
     153{
     154    if (i > 0x43c07fff)
     155        return 32767;
     156    else if (i < 0x43bf8000)
     157        return -32768;
     158    else
     159        return i - 0x43c00000;
     160}
     161
     162void float2s16_2 (float * _f, int16_t * s16)
     163{
     164    int i;
     165    int32_t * f = (int32_t *) _f;
     166
     167    for (i = 0; i < 256; i++) {
     168        s16[2*i] = convert (f[i]);
     169        s16[2*i+1] = convert (f[i+256]);
     170    }
     171}
     172
     173void float2s16_4 (float * _f, int16_t * s16)
     174{
     175    int i;
     176    int32_t * f = (int32_t *) _f;
     177
     178    for (i = 0; i < 256; i++) {
     179        s16[4*i] = convert (f[i]);
     180        s16[4*i+1] = convert (f[i+256]);
     181        s16[4*i+2] = convert (f[i+512]);
     182        s16[4*i+3] = convert (f[i+768]);
     183    }
     184}
     185
     186void float2s16_5 (float * _f, int16_t * s16)
     187{
     188    int i;
     189    int32_t * f = (int32_t *) _f;
     190
     191    for (i = 0; i < 256; i++) {
     192        s16[5*i] = convert (f[i]);
     193        s16[5*i+1] = convert (f[i+256]);
     194        s16[5*i+2] = convert (f[i+512]);
     195        s16[5*i+3] = convert (f[i+768]);
     196        s16[5*i+4] = convert (f[i+1024]);
     197    }
     198}
     199
     200int channels_multi (int flags)
     201{
     202    if (flags & A52_LFE)
     203        return 6;
     204    else if (flags & 1) /* center channel */
     205        return 5;
     206    else if ((flags & A52_CHANNEL_MASK) == A52_2F2R)
     207        return 4;
     208    else
     209        return 2;
     210}
     211
     212void float2s16_multi (float * _f, int16_t * s16, int flags)
     213{
     214    int i;
     215    int32_t * f = (int32_t *) _f;
     216
     217    switch (flags) {
     218    case A52_MONO:
     219        for (i = 0; i < 256; i++) {
     220            s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0;
     221            s16[5*i+4] = convert (f[i]);
     222        }
     223        break;
     224    case A52_CHANNEL:
     225    case A52_STEREO:
     226    case A52_DOLBY:
     227        float2s16_2 (_f, s16);
     228        break;
     229    case A52_3F:
     230        for (i = 0; i < 256; i++) {
     231            s16[5*i] = convert (f[i]);
     232            s16[5*i+1] = convert (f[i+512]);
     233            s16[5*i+2] = s16[5*i+3] = 0;
     234            s16[5*i+4] = convert (f[i+256]);
     235        }
     236        break;
     237    case A52_2F2R:
     238        float2s16_4 (_f, s16);
     239        break;
     240    case A52_3F2R:
     241        float2s16_5 (_f, s16);
     242        break;
     243    case A52_MONO | A52_LFE:
     244        for (i = 0; i < 256; i++) {
     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        }
     249        break;
     250    case A52_CHANNEL | A52_LFE:
     251    case A52_STEREO | A52_LFE:
     252    case A52_DOLBY | A52_LFE:
     253        for (i = 0; i < 256; i++) {
     254            s16[6*i] = convert (f[i+256]);
     255            s16[6*i+1] = convert (f[i+512]);
     256            s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0;
     257            s16[6*i+5] = convert (f[i]);
     258        }
     259        break;
     260    case A52_3F | A52_LFE:
     261        for (i = 0; i < 256; i++) {
     262            s16[6*i] = convert (f[i+256]);
     263            s16[6*i+1] = convert (f[i+768]);
     264            s16[6*i+2] = s16[6*i+3] = 0;
     265            s16[6*i+4] = convert (f[i+512]);
     266            s16[6*i+5] = convert (f[i]);
     267        }
     268        break;
     269    case A52_2F2R | A52_LFE:
     270        for (i = 0; i < 256; i++) {
     271            s16[6*i] = convert (f[i+256]);
     272            s16[6*i+1] = convert (f[i+512]);
     273            s16[6*i+2] = convert (f[i+768]);
     274            s16[6*i+3] = convert (f[i+1024]);
     275            s16[6*i+4] = 0;
     276            s16[6*i+5] = convert (f[i]);
     277        }
     278        break;
     279    case A52_3F2R | A52_LFE:
     280        for (i = 0; i < 256; i++) {
     281            s16[6*i] = convert (f[i+256]);
     282            s16[6*i+1] = convert (f[i+768]);
     283            s16[6*i+2] = convert (f[i+1024]);
     284            s16[6*i+3] = convert (f[i+1280]);
     285            s16[6*i+4] = convert (f[i+512]);
     286            s16[6*i+5] = convert (f[i]);
     287        }
     288        break;
     289    }
     290}
     291
     292
    152293/**** end */
    153294
    154295#define HEADER_SIZE 7
     
    212353            s->inbuf_ptr += len;
    213354            buf_size -= len;
    214355        } else {
     356            int chans;
    215357            flags = s->flags;
    216358            if (avctx->channels == 1)
    217359                flags = A52_MONO;
    218             else if (avctx->channels == 2)
    219                 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            }
    220366            else
    221367                flags |= A52_ADJUST_LEVEL;
    222368            level = 1;
     369            chans = channels_multi(flags);
    223370            if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) {
    224371            fail:
    225372                s->inbuf_ptr = s->inbuf;
     
    229376            for (i = 0; i < 6; i++) {
    230377                if (s->a52_block(s->state))
    231378                    goto fail;
    232                 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     379                //float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);
     380                float2s16_multi(s->samples, out_samples + i * 256 * chans, flags);
    233381            }
    234382            s->inbuf_ptr = s->inbuf;
    235383            s->frame_size = 0;
    236             *data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
     384            //*data_size = 6 * avctx->channels * 256 * sizeof(int16_t);
     385            *data_size = 6 * channels_multi(flags) * 256 * sizeof(int16_t);
    237386            break;
    238387        }
    239388    }
  • libs/libavcodec/ac3enc.c

     
    13621362{
    13631363    AC3EncodeContext *s = avctx->priv_data;
    13641364    int16_t *samples = data;
     1365    // expects L C R LS RS LFE
     1366    // audio format is L R LS RS C LFE
     1367    static int channel_index[6] = { 0, 4, 1, 2, 3, 5 };
     1368    /*
     1369     * A52->Analog->AC3Enc
     1370     * 1->0->0
     1371     * 3->1->2
     1372     * 4->2->3
     1373     * 5->3->4
     1374     * 2->4->1
     1375     * 0->5->5
     1376     */
    13651377    int i, j, k, v, ch;
    13661378    int16_t input_samples[N];
    13671379    int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2];
     
    13821394            /* compute input samples */
    13831395            memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t));
    13841396            sinc = s->nb_all_channels;
    1385             sptr = samples + (sinc * (N/2) * i) + ch;
     1397            sptr = samples + (sinc * (N/2) * i) + channel_index[ch];
    13861398            for(j=0;j<N/2;j++) {
    13871399                v = *sptr;
    13881400                input_samples[j + N/2] = v;
     
    14031415            v = 14 - log2_tab(input_samples, N);
    14041416            if (v < 0)
    14051417                v = 0;
    1406             exp_samples[i][ch] = v - 8;
     1418            exp_samples[i][ch] = v - 9;
    14071419            lshift_tab(input_samples, N, v);
    14081420
    14091421            /* do the MDCT */