Ticket #1104: mythtv_ac3.12.patch

File mythtv_ac3.12.patch, 75.2 KB (added by Mark Spieth, 20 years ago)
  • 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

     
    100100    SAMPLETYPE *pMidBuffer;
    101101    SAMPLETYPE *pRefMidBuffer;
    102102    SAMPLETYPE *pRefMidBufferUnaligned;
     103    uint midBufferLength;
    103104    uint overlapLength;
    104105    uint overlapDividerBits;
    105106    uint slopingDivider;
     
    123124    virtual void clearCrossCorrState();
    124125    void calculateOverlapLength(uint overlapMs);
    125126
     127#ifdef MULTICHANNEL
     128    virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
     129#endif
    126130    virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    127131    virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
    128132
     133#ifdef MULTICHANNEL
     134    virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos);
     135    virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos);
     136#endif
    129137    virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
    130138    virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
    131139    virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
    132140    virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
    133141    uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
    134142
     143#ifdef MULTICHANNEL
     144    virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const;
     145#endif
    135146    virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    136147    virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
    137148
    138149    void clearMidBuffer();
    139150    void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
    140151
     152#ifdef MULTICHANNEL
     153    void precalcCorrReference();
     154#endif
    141155    void precalcCorrReferenceMono();
    142156    void precalcCorrReferenceStereo();
    143157
     
    225239    class TDStretchMMX : public TDStretch
    226240    {
    227241    protected:
     242#ifdef MULTICHANNEL
     243        //long calcCrossCorrMulti(const short *mixingPos, const short *compare) const;
     244#endif
    228245        long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
    229246        virtual void overlapStereo(short *output, const short *input) const;
    230247        virtual void clearCrossCorrState();
     
    237254    class TDStretch3DNow : public TDStretch
    238255    {
    239256    protected:
     257#ifdef MULTICHANNEL
     258        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     259#endif
    240260        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    241261    };
    242262#endif /// ALLOW_3DNOW
     
    247267    class TDStretchSSE : public TDStretch
    248268    {
    249269    protected:
     270#ifdef MULTICHANNEL
     271        //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const;
     272#endif
    250273        double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
    251274    };
    252275
  • 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/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->setHelpText(
     68            QObject::tr("Set the maximum number of audio channels to be decoded. "
     69                "This is for multi-channel/surround audio playback."));
     70    return gc;
     71}
     72
    4373static HostCheckBox *MythControlsVolume()
    4474{
    4575    HostCheckBox *gc = new HostCheckBox("MythControlsVolume");
     
    20922122         setUseLabel(false);
    20932123
    20942124         addChild(AudioOutputDevice());
     2125#if 0
     2126         ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false);
     2127         ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false);
     2128         settingsLeft->addChild(AC3PassThrough());
     2129#ifdef CONFIG_DTS
     2130         settingsLeft->addChild(DTSPassThrough());
     2131#endif
     2132         settingsLeft->addChild(AggressiveBuffer());
     2133         hg->addChild(settingsLeft);
     2134
     2135         ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false);
     2136         settingsRight->addChild(MaxAudioChannels());
     2137         hg->addChild(settingsRight);
     2138
     2139         addChild(hg);
     2140#else
    20952141         addChild(AC3PassThrough());
    20962142#ifdef CONFIG_DTS
    20972143         addChild(DTSPassThrough());
    20982144#endif
    20992145         addChild(AggressiveBuffer());
     2146         addChild(MaxAudioChannels());
     2147#endif
    21002148
    21012149         Setting* volumeControl = MythControlsVolume();
    21022150         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#define VB_AUDIO VB_IMPORTANT
    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));
     
    22622304
    22632305        AVStream *curstream = ic->streams[pkt->stream_index];
    22642306
     2307#if 0
     2308        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3")
     2309                .arg(pkt->pts)
     2310                .arg(pkt->dts)
     2311                .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1)
     2312               );
     2313#endif
     2314
    22652315        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    22662316            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    22672317
     
    23752425                    if (!curstream->codec->channels)
    23762426                    {
    23772427                        QMutexLocker locker(&avcodeclock);
     2428#if MAXCHANNELSELECT
     2429                        VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels));
     2430                        curstream->codec->channels = audioOut.channels;
     2431#else
    23782432                        curstream->codec->channels = MAX_OUTPUT_CHANNELS;
     2433#endif
    23792434                        ret = avcodec_decode_audio(
    23802435                            curstream->codec, audioSamples,
    23812436                            &data_size, ptr, len);
     
    24262481                    {
    24272482                        AVCodecContext *ctx = curstream->codec;
    24282483
     2484#if MAXCHANNELSELECT
    24292485                        if ((ctx->channels == 0) ||
     2486                            (ctx->channels > audioOut.channels))
     2487                            ctx->channels = audioOut.channels;
     2488#else
     2489                        if ((ctx->channels == 0) ||
    24302490                            (ctx->channels > MAX_OUTPUT_CHANNELS))
    24312491                            ctx->channels = MAX_OUTPUT_CHANNELS;
     2492#endif
    24322493
    24332494                        ret = avcodec_decode_audio(
    24342495                            ctx, audioSamples, &data_size, ptr, len);
     
    24642525                                (curstream->codec->channels * 2) /
    24652526                                curstream->codec->sample_rate);
    24662527
     2528                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4")
     2529                            .arg(pkt->pts)
     2530                            .arg(pkt->dts)
     2531                            .arg(temppts).arg(lastapts));
    24672532                    GetNVP()->AddAudioData((char *)audioSamples, data_size,
    24682533                                           temppts);
    24692534
     
    25552620                    else
    25562621                        temppts = lastvpts;
    25572622
     2623                    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4")
     2624                            .arg(pkt->pts)
     2625                            .arg(pkt->dts)
     2626                            .arg(temppts).arg(lastvpts));
    25582627/* XXX: Broken.
    25592628                    if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 &&
    25602629                        context->height == picframe->height)
     
    26492718
    26502719void AvFormatDecoder::SetDisablePassThrough(bool disable)
    26512720{
     2721#if MAXCHANNELSELECT
     2722    // can only disable never reenable as once tiemstretch is on its on for the session
     2723    if (disable_passthru)
     2724        return;
     2725#endif
    26522726    if (selectedAudioStream.av_stream_index < 0)
    26532727    {
    26542728        disable_passthru = disable;
    26552729        return;
    26562730    }
    2657 
     2731 
    26582732    if (disable != disable_passthru)
    26592733    {
    26602734        disable_passthru = disable;
     
    26812755    AVCodecContext *codec_ctx = NULL;
    26822756    AudioInfo old_in  = audioIn;
    26832757    AudioInfo old_out = audioOut;
     2758    bool using_passthru = false;
    26842759
    26852760    if ((currentAudioTrack >= 0) &&
    26862761        (selectedAudioStream.av_stream_index <= ic->nb_streams) &&
     
    26902765        assert(curstream->codec);
    26912766        codec_ctx = curstream->codec;       
    26922767        bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&
    2693                                 !disable_passthru &&
    26942768                                (codec_ctx->codec_id == CODEC_ID_AC3));
    26952769        bool do_dts_passthru = (allow_dts_passthru && !transcoding &&
    2696                                 !disable_passthru &&
    26972770                                (codec_ctx->codec_id == CODEC_ID_DTS));
     2771        using_passthru = do_ac3_passthru || do_dts_passthru;
    26982772        info = AudioInfo(codec_ctx->codec_id,
    26992773                         codec_ctx->sample_rate, codec_ctx->channels,
    2700                          do_ac3_passthru || do_dts_passthru);
     2774                         using_passthru && !disable_passthru);
    27012775    }
    27022776
    27032777    if (info == audioIn)
    27042778        return false; // no change
    27052779
     2780    QString ptmsg = "";
     2781    if (using_passthru)
     2782    {
     2783        ptmsg = QString(" using passthru");
     2784    }
    27062785    VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " +
    2707             QString("audio track #%1").arg(currentAudioTrack+1));
     2786            QString("audio track #%1")
     2787                .arg(currentAudioTrack+1)
     2788            + ptmsg );
    27082789
    27092790    audioOut = audioIn = info;
     2791#if MAXCHANNELSELECT
     2792    if (using_passthru)
     2793#else
    27102794    if (audioIn.do_passthru)
     2795#endif
    27112796    {
    27122797        // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card
    2713         audioOut.channels    = 2;
    2714         audioOut.sample_rate = 48000;
    2715         audioOut.sample_size = 4;
     2798        AudioInfo digInfo = audioOut;
     2799        if (!disable_passthru)
     2800        {
     2801            digInfo.channels    = 2;
     2802            digInfo.sample_rate = 48000;
     2803            digInfo.sample_size = 4;
     2804        }
     2805        if (audioOut.channels > max_channels)
     2806        {
     2807            audioOut.channels = max_channels;
     2808            audioOut.sample_size = audioOut.channels * 2;
     2809            codec_ctx->channels = audioOut.channels;
     2810        }
     2811#if MAXCHANNELSELECT
     2812        VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " +
     2813                QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto   %4 ; %5")
     2814                .arg(digInfo.toString())
     2815                .arg(old_in.toString()).arg(old_out.toString())
     2816                .arg(audioIn.toString()).arg(audioOut.toString()));
     2817
     2818        if (digInfo.sample_rate > 0)
     2819            GetNVP()->SetEffDsp(digInfo.sample_rate * 100);
     2820
     2821        //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
     2822        //                         audioOut.sample_rate);
     2823        GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels,
     2824                                 digInfo.sample_rate);
     2825        // allow the audio stuff to reencode
     2826        GetNVP()->SetAudioCodec(codec_ctx);
     2827        GetNVP()->ReinitAudio();
     2828        return true;
     2829#endif
    27162830    }
     2831#if MAXCHANNELSELECT
    27172832    else
    27182833    {
     2834        if (audioOut.channels > max_channels)
     2835        {
     2836            audioOut.channels = max_channels;
     2837            audioOut.sample_size = audioOut.channels * 2;
     2838            codec_ctx->channels = audioOut.channels;
     2839        }
     2840    }
     2841    bool audiook;
     2842    do
     2843    {
     2844#else
     2845    else
     2846    {
    27192847        if (audioOut.channels > MAX_OUTPUT_CHANNELS)
    27202848        {
    27212849            audioOut.channels = MAX_OUTPUT_CHANNELS;
     
    27232851            codec_ctx->channels = MAX_OUTPUT_CHANNELS;
    27242852        }
    27252853    }
     2854#endif
    27262855
    27272856    VERBOSE(VB_AUDIO, LOC + "Audio format changed " +
    27282857            QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto   %3 ; %4")
     
    27342863
    27352864    GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels,
    27362865                             audioOut.sample_rate);
    2737     GetNVP()->ReinitAudio();
     2866    // allow the audio stuff to reencode
     2867    GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);
     2868    QString errMsg = GetNVP()->ReinitAudio();
     2869#if MAXCHANNELSELECT
     2870        audiook = errMsg.isEmpty();
     2871        if (!audiook)
     2872        {
     2873            switch (audioOut.channels)
     2874            {
     2875#if 0
     2876                case 8:
     2877                    audioOut.channels = 6;
     2878                    break;
     2879#endif
     2880                case 6:
     2881                    audioOut.channels = 5;
     2882                    break;
     2883                case 5:
     2884                    audioOut.channels = 4;
     2885                    break;
     2886                case 4:
     2887                    audioOut.channels = 3;
     2888                    break;
     2889                case 3:
     2890                    audioOut.channels = 2;
     2891                    break;
     2892                case 2:
     2893                    audioOut.channels = 1;
     2894                    break;
     2895                default:
     2896                    // failed to reconfigure under any circumstances
     2897                    audiook = true;
     2898                    audioOut.channels = 0;
     2899                    break;
     2900            }
     2901            audioOut.sample_size = audioOut.channels * 2;
     2902            codec_ctx->channels = audioOut.channels;
     2903        }
     2904    } while (!audiook);
     2905#endif
    27382906
    27392907    return true;
    27402908}
  • libs/libmythtv/NuppelVideoPlayer.h

     
    107107                        float a = 1.33333, FrameScanType scan = kScan_Ignore,
    108108                        bool reinit = false);
    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);
     
    487490    int      audio_bits;
    488491    int      audio_samplerate;
    489492    float    audio_stretchfactor;
     493    void     *audio_codec;
    490494
    491495    // Picture-in-Picture
    492496    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      // Filters
     
    514515
    515516    if (audioOutput)
    516517    {
    517         audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate);
     518        audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_codec);
    518519        errMsg = audioOutput->GetError();
    519520        if (!errMsg.isEmpty())
    520521            audioOutput->SetStretchFactor(audio_stretchfactor);
     
    647648        {
    648649            VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    649650                    "framerate (refresh rate too low for bob deint)");
     651            //m_scan = kScan_Ignore;
     652            //m_can_double = false;
    650653            FallbackDeint();
    651654        }
    652655    }
     
    14231426    warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) /
    14241427                      WARPAVLEN;
    14251428
    1426     //cerr << "Divergence: " << divergence << "  Rate: " << rate
    1427     //<< "  Warpfactor: " << warpfactor << "  warpfactor_avg: "
    1428     //<< warpfactor_avg << endl;
     1429#if 1
     1430    VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1431        "Divergence: %1 "
     1432        "  Rate: %2"
     1433        "  Warpfactor: %3"
     1434        "  warpfactor_avg: %4")
     1435        .arg(divergence)
     1436        .arg(rate)
     1437        .arg(warpfactor)
     1438        .arg(warpfactor_avg)
     1439        );
     1440#endif
    14291441    return divergence;
    14301442}
    14311443
     
    15061518    if (diverge < -MAXDIVERGE)
    15071519    {
    15081520        // If video is way ahead of audio, adjust for it...
    1509         QString dbg = QString("Video is %1 frames ahead of audio, ")
     1521        QString dbg = QString("Audio is %1 frames ahead of video, ")
    15101522            .arg(-diverge);
    15111523
    15121524        // Reset A/V Sync
     
    15211533            // decoding; display the frame, but don't wait for A/V Sync.
    15221534            videoOutput->PrepareFrame(buffer, ps);
    15231535            videoOutput->Show(m_scan);
    1524             VERBOSE(VB_PLAYBACK, LOC + dbg + "skipping A/V wait.");
     1536            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait.");
    15251537        }
    15261538        else
    15271539        {
    15281540            // If we are using software decoding, skip this frame altogether.
    1529             VERBOSE(VB_PLAYBACK, LOC + dbg + "dropping frame.");
     1541            VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame.");
    15301542        }
    15311543    }
    15321544    else if (!using_null_videoout)
     
    15351547        if (buffer)
    15361548            videoOutput->PrepareFrame(buffer, ps);
    15371549
     1550        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate));
    15381551        videosync->WaitForFrame(avsync_adjustment);
     1552        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show");
    15391553        if (!resetvideo)
    15401554            videoOutput->Show(m_scan);
    15411555
     
    15551569
    15561570            // Display the second field
    15571571            videosync->AdvanceTrigger();
    1558             videosync->WaitForFrame(0);
     1572            videosync->WaitForFrame(avsync_adjustment);
    15591573            if (!resetvideo)
    15601574                videoOutput->Show(kScan_Intr2ndField);
    15611575        }
     
    15671581
    15681582    if (output_jmeter && output_jmeter->RecordCycleTime())
    15691583    {
    1570         //cerr << "avsync_delay: " << avsync_delay / 1000
    1571         //     << ", avsync_avg: " << avsync_avg / 1000
    1572         //     << ", warpfactor: " << warpfactor
    1573         //     << ", warpfactor_avg: " << warpfactor_avg << endl;
     1584#if 1
     1585        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V "
     1586            "avsync_delay: %1"
     1587            ", avsync_avg: %2"
     1588            ", warpfactor: %3"
     1589            ", warpfactor_avg: %4")
     1590                .arg(avsync_delay / 1000)
     1591                .arg(avsync_avg / 1000)
     1592                .arg(warpfactor)
     1593                .arg(warpfactor_avg));
     1594#endif
    15741595    }
    15751596
    15761597    videosync->AdvanceTrigger();
     
    15811602        // If audio is way ahead of video, adjust for it...
    15821603        // by cutting the frame rate in half for the length of this frame
    15831604
    1584         avsync_adjustment = frame_interval;
     1605        //avsync_adjustment = frame_interval;
     1606        avsync_adjustment = refreshrate;
    15851607        lastsync = true;
    1586         VERBOSE(VB_PLAYBACK, LOC +
    1587                 QString("Audio is %1 frames ahead of video,\n"
     1608        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC +
     1609                QString("Video is %1 frames ahead of audio,\n"
    15881610                        "\t\t\tdoubling video frame interval.").arg(diverge));
    15891611    }
    15901612
    15911613    if (audioOutput && normal_speed)
    15921614    {
    15931615        long long currentaudiotime = audioOutput->GetAudiotime();
    1594 #if 0
    1595         VERBOSE(VB_PLAYBACK, QString(
     1616#if 1
     1617        VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString(
    15961618                    "A/V timecodes audio %1 video %2 frameinterval %3 "
    15971619                    "avdel %4 avg %5 tcoffset %6")
    15981620                .arg(currentaudiotime)
     
    18441866            {
    18451867                VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
    18461868                        "framerate (refresh rate too low for bob deint)");
     1869                //m_scan = kScan_Ignore;
     1870                //m_can_double = false;
    18471871                FallbackDeint();
    18481872            }
    18491873        }
     
    25342558    audio_samplerate = samplerate;
    25352559}
    25362560
     2561void NuppelVideoPlayer::SetAudioCodec(void* ac)
     2562{
     2563    audio_codec = ac;
     2564}
     2565
    25372566void NuppelVideoPlayer::SetEffDsp(int dsprate)
    25382567{
    25392568    if (audioOutput)
     
    25782607        tc_avcheck_framecounter++;
    25792608        if (tc_avcheck_framecounter == 30)
    25802609        {
    2581 #define AUTO_RESYNC 1
     2610#define AUTO_RESYNC 0
    25822611#if AUTO_RESYNC
    25832612            // something's terribly, terribly wrong.
    25842613            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    }