Ticket #9282: 9282.diff

File 9282.diff, 18.9 KB (added by JYA, 10 years ago)

Patches for 0.24-fixes

  • mythtv/libs/libmyth/audiooutputbase.h

    Property changes on: .
    ___________________________________________________________________
    Modified: svn:mergeinfo
       Merged /trunk:r27358,27368-27369
    
     
    9595    virtual void bufferOutputData(bool y){ buffer_output_data_for_use = y; }
    9696    virtual int readOutputData(unsigned char *read_buffer, int max_length);
    9797
    98     static const uint kAudioSRCInputSize  = 16384<<1;
    99     static const uint kAudioSRCOutputSize = 16384<<3;
     98    static const uint kAudioSRCInputSize = 32768;
     99
    100100    /// Audio Buffer Size -- should be divisible by 32,24,16,12,10,8,6,4,2..
    101101    static const uint kAudioRingBufferSize   = 3072000;
    102102
     
    224224    uint memory_corruption_test0;
    225225    float src_in_buf[kAudioSRCInputSize + 16];
    226226    uint memory_corruption_test1;
    227     float src_out[kAudioSRCOutputSize];
     227    float *src_out;
     228    int kAudioSRCOutputSize;
    228229    uint memory_corruption_test2;
    229230    /** main audio buffer */
    230231    uchar audiobuffer[kAudioRingBufferSize];
  • mythtv/libs/libmyth/audiooutputbase.cpp

     
    9393
    9494    memory_corruption_test0(0xdeadbeef),
    9595    memory_corruption_test1(0xdeadbeef),
     96    src_out(NULL),              kAudioSRCOutputSize(0),
    9697    memory_corruption_test2(0xdeadbeef),
    9798    memory_corruption_test3(0xdeadbeef)
    9899{
     
    100101    // The following are not bzero() because MS Windows doesn't like it.
    101102    memset(&src_data,          0, sizeof(SRC_DATA));
    102103    memset(src_in,             0, sizeof(float) * kAudioSRCInputSize);
    103     memset(src_out,            0, sizeof(float) * kAudioSRCOutputSize);
    104104    memset(audiobuffer,        0, sizeof(char)  * kAudioRingBufferSize);
    105105
    106106    // Default SRC quality - QUALITY_HIGH is quite expensive
     
    134134    delete output_settings;
    135135    delete output_settingsraw;
    136136
     137    if (kAudioSRCOutputSize > 0)
     138        delete[] src_out;
     139
    137140    assert(memory_corruption_test0 == 0xdeadbeef);
    138141    assert(memory_corruption_test1 == 0xdeadbeef);
    139142    assert(memory_corruption_test2 == 0xdeadbeef);
     
    474477
    475478        src_data.src_ratio      = (double)samplerate / settings.samplerate;
    476479        src_data.data_in        = src_in;
     480        int newsize             = ((long)((float)kAudioSRCInputSize *
     481                                          samplerate / settings.samplerate) +
     482                                   15) & ~0xf;
     483        if (kAudioSRCOutputSize < newsize)
     484        {
     485            kAudioSRCOutputSize = newsize;
     486            VBAUDIO(QString("Resampler allocating %1").arg(newsize));
     487            if (src_out)
     488                delete[] src_out;
     489            src_out = new float[kAudioSRCOutputSize];
     490        }
    477491        src_data.data_out       = src_out;
    478492        src_data.output_frames  = kAudioSRCOutputSize;
    479493        src_data.end_of_input = 0;
     
    789803
    790804    /* timecode is the stretch adjusted version
    791805       of major post-stretched buffer contents
    792        processing latencies are catered for in AddSamples/SetAudiotime
     806       processing latencies are catered for in AddFrames/SetAudiotime
    793807       to eliminate race */
    794808    audiotime = audbuf_timecode - (
    795809        ((main_buffer + soundcard_buffer) * eff_stretchfactor ) /
     
    819833/**
    820834 * Set the timecode of the top of the ringbuffer
    821835 * Exclude all other processing elements as they dont vary
    822  * between AddSamples calls
     836 * between AddFrames calls
    823837 */
    824838void AudioOutputBase::SetAudiotime(int frames, int64_t timecode)
    825839{
     
    841855
    842856    int64_t old_audbuf_timecode = audbuf_timecode;
    843857
    844     audbuf_timecode = timecode + 
     858    audbuf_timecode = timecode +
    845859                (((frames + processframes_unstretched) * 100000) +
    846860                  (processframes_stretched * eff_stretchfactor )) / effdsp;
    847861
    848862    // check for timecode wrap and reset audiotime if detected
    849     // timecode will always be monotonic asc if not seeked and reset 
     863    // timecode will always be monotonic asc if not seeked and reset
    850864    // happens if seek or pause happens
    851865    if (audbuf_timecode < old_audbuf_timecode)
    852866        audiotime = 0;
     
    979993    }
    980994
    981995    // Upmix to 6ch via FreeSurround
    982 
    983996    // Calculate frame size of input
    984997    off =  processing ? 4 : output_settings->SampleSize(format);
    985998    off *= source_channels;
    986999
    987     int i = 0;
    988     while (i < frames)
    989         i += upmixer->putFrames(buffer + i * off, frames - i, source_channels);
     1000    int remaining_frames = frames;
     1001    len = 0;
     1002    do
     1003    {
     1004        int i;
     1005        frames = remaining_frames;
     1006        if (frames * source_channels > SURROUND_BUFSIZE)
     1007        {
     1008            frames = SURROUND_BUFSIZE / source_channels;
     1009        }
    9901010
    991     int nFrames = upmixer->numFrames();
    992     if (!nFrames)
    993         return 0;
     1011        i = 0;
     1012        while (i < frames)
     1013            i += upmixer->putFrames(buffer + i * off,
     1014                                    frames - i, source_channels);
    9941015
    995     len = CheckFreeSpace(nFrames);
     1016        remaining_frames -= i;
     1017        buffer += i * off;
    9961018
    997     int bdFrames = bdiff / bpf;
    998     if (bdFrames < nFrames)
    999     {
    1000         upmixer->receiveFrames((float *)(WPOS), bdFrames);
    1001         nFrames -= bdFrames;
    1002         org_waud = 0;
     1019        int nFrames = upmixer->numFrames();
     1020        if (!nFrames)
     1021            continue;
     1022
     1023        len += CheckFreeSpace(nFrames);
     1024
     1025        int bdFrames = (kAudioRingBufferSize - org_waud) / bpf;
     1026        if (bdFrames < nFrames)
     1027        {
     1028            upmixer->receiveFrames((float *)(WPOS), bdFrames);
     1029            nFrames -= bdFrames;
     1030            org_waud = 0;
     1031        }
     1032        if (nFrames > 0)
     1033            upmixer->receiveFrames((float *)(WPOS), nFrames);
     1034
     1035        org_waud += nFrames * bpf;
    10031036    }
    1004     if (nFrames > 0)
    1005         upmixer->receiveFrames((float *)(WPOS), nFrames);
    1006 
    1007     org_waud += nFrames * bpf;
     1037    while (remaining_frames > 0);
    10081038    return len;
    10091039}
    10101040
     
    10131043 *
    10141044 * Returns false if there's not enough space right now
    10151045 */
    1016 bool AudioOutputBase::AddFrames(void *buffer, int in_frames, int64_t timecode)
     1046bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames,
     1047                                int64_t timecode)
    10171048{
    10181049    int org_waud = waud,               afree = audiofree();
    10191050    int frames   = in_frames;
    1020     int bpf      = bytes_per_frame,    len   = frames * source_bytes_per_frame;
     1051    void *buffer = in_buffer;
     1052    int bpf      = bytes_per_frame,    len = frames * source_bytes_per_frame;
    10211053    int used     = kAudioRingBufferSize - afree;
    10221054    bool music   = false;
    10231055    int bdiff;
     
    10441076        // Send original samples to mythmusic visualisation
    10451077        timecode = (int64_t)(frames_buffered) * 1000 / source_samplerate;
    10461078        frames_buffered += frames;
    1047         dispatchVisual((uchar *)buffer, len, timecode, source_channels,
     1079        dispatchVisual((uchar *)in_buffer, len, timecode, source_channels,
    10481080                       output_settings->FormatToBits(format));
    10491081        music = true;
    10501082    }
    10511083
     1084    // Calculate amount of free space required in ringbuffer
    10521085    if (processing)
    10531086    {
    1054         // Convert to floats
    1055         len = AudioOutputUtil::toFloat(format, src_in, buffer, len);
     1087        // Final float conversion space requirement
     1088        len = sizeof(*src_in_buf) /
     1089            AudioOutputSettings::SampleSize(format) * len;
    10561090
    10571091        // Account for changes in number of channels
    10581092        if (needs_upmix || needs_downmix)
     
    10741108
    10751109    if (len > afree)
    10761110    {
    1077             VBAUDIOTS("Buffer is full, AddFrames returning false");
    1078             return false; // would overflow
     1111        VBAUDIOTS("Buffer is full, AddFrames returning false");
     1112        return false; // would overflow
    10791113    }
    10801114
    1081     // Perform downmix if necessary
    1082     if (needs_downmix)
    1083         if(AudioOutputDownmix::DownmixFrames(source_channels, channels,
    1084                                              src_in, src_in, frames) < 0)
    1085             VBERROR("Error occurred while downmixing");
     1115    int frames_remaining = in_frames;
     1116    int frames_offset = 0;
     1117    int frames_final = 0;
    10861118
    1087     // Resample if necessary
    1088     if (need_resampler && src_ctx)
     1119    while(frames_remaining > 0)
    10891120    {
    1090         src_data.input_frames = frames;
    1091         int error = src_process(src_ctx, &src_data);
     1121        buffer = (char *)in_buffer + frames_offset;
     1122        frames = frames_remaining;
    10921123
    1093         if (error)
    1094             VBERROR(QString("Error occurred while resampling audio: %1")
    1095                     .arg(src_strerror(error)));
     1124        len = frames * source_bytes_per_frame;
    10961125
    1097         buffer = src_out;
    1098         in_frames = frames = src_data.output_frames_gen;
    1099     }
    1100     else if (processing)
    1101         buffer = src_in;
     1126        if (processing)
     1127        {
     1128            if (frames * source_channels > (int)kAudioSRCInputSize)
     1129            {
     1130                frames = kAudioSRCInputSize / source_channels;
     1131                len = frames * source_bytes_per_frame;
     1132                frames_offset += len;
     1133            }
     1134            // Convert to floats
     1135            len = AudioOutputUtil::toFloat(format, src_in, buffer, len);
     1136        }
     1137        frames_remaining -= frames;
    11021138
    1103     /* we want the timecode of the last sample added but we are given the
    1104        timecode of the first - add the time in ms that the frames added
    1105        represent */
     1139        // Perform downmix if necessary
     1140        if (needs_downmix)
     1141            if(AudioOutputDownmix::DownmixFrames(source_channels, channels,
     1142                                                 src_in, src_in, frames) < 0)
     1143                VBERROR("Error occurred while downmixing");
    11061144
    1107     // Copy samples into audiobuffer, with upmix if necessary
    1108     if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
    1109     {
    1110         SetAudiotime(in_frames, timecode);
    1111         return true;
    1112     }
     1145        // Resample if necessary
     1146        if (need_resampler && src_ctx)
     1147        {
     1148            src_data.input_frames = frames;
     1149            int error = src_process(src_ctx, &src_data);
    11131150
    1114     frames = len / bpf;
     1151            if (error)
     1152                VBERROR(QString("Error occurred while resampling audio: %1")
     1153                        .arg(src_strerror(error)));
    11151154
    1116     bdiff = kAudioRingBufferSize - waud;
     1155            buffer = src_out;
     1156            frames = src_data.output_frames_gen;
     1157            frames_final += frames;
     1158        }
     1159        else
     1160        {
     1161            frames_final += frames;
     1162            if (processing)
     1163                buffer = src_in;
     1164        }
    11171165
    1118     if (pSoundStretch)
    1119     {
    1120         // does not change the timecode, only the number of samples
    1121         org_waud     = waud;
    1122         int bdFrames = bdiff / bpf;
     1166        /* we want the timecode of the last sample added but we are given the
     1167           timecode of the first - add the time in ms that the frames added
     1168           represent */
    11231169
    1124         if (bdiff < len)
     1170        // Copy samples into audiobuffer, with upmix if necessary
     1171        if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
    11251172        {
    1126             pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
    1127             pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
     1173            continue;
    11281174        }
    1129         else
    1130             pSoundStretch->putSamples((STST *)(WPOS), frames);
    11311175
    1132         int nFrames = pSoundStretch->numSamples();
    1133         if (nFrames > frames)
    1134             CheckFreeSpace(nFrames);
     1176        frames = len / bpf;
    11351177
    1136         len = nFrames * bpf;
     1178        bdiff = kAudioRingBufferSize - waud;
    11371179
    1138         if (nFrames > bdFrames)
     1180        if (pSoundStretch)
    11391181        {
    1140             nFrames -= pSoundStretch->receiveSamples((STST *)(WPOS), bdFrames);
    1141             org_waud = 0;
    1142         }
    1143         if (nFrames > 0)
    1144             nFrames = pSoundStretch->receiveSamples((STST *)(WPOS), nFrames);
     1182            // does not change the timecode, only the number of samples
     1183            org_waud     = waud;
     1184            int bdFrames = bdiff / bpf;
    11451185
    1146         org_waud += nFrames * bpf;
    1147     }
     1186            if (bdiff < len)
     1187            {
     1188                pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
     1189                pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
     1190            }
     1191            else
     1192                pSoundStretch->putSamples((STST *)(WPOS), frames);
    11481193
    1149     if (internal_vol && SWVolume())
    1150     {
    1151         org_waud    = waud;
    1152         int num     = len;
     1194            int nFrames = pSoundStretch->numSamples();
     1195            if (nFrames > frames)
     1196                CheckFreeSpace(nFrames);
    11531197
    1154         if (bdiff <= num)
    1155         {
    1156             AudioOutputUtil::AdjustVolume(WPOS, bdiff, volume,
    1157                                           music, needs_upmix && upmixer);
    1158             num -= bdiff;
    1159             org_waud = 0;
     1198            len = nFrames * bpf;
     1199
     1200            if (nFrames > bdFrames)
     1201            {
     1202                nFrames -= pSoundStretch->receiveSamples((STST *)(WPOS),
     1203                                                         bdFrames);
     1204                org_waud = 0;
     1205            }
     1206            if (nFrames > 0)
     1207                nFrames = pSoundStretch->receiveSamples((STST *)(WPOS),
     1208                                                        nFrames);
     1209
     1210            org_waud += nFrames * bpf;
    11601211        }
    1161         if (num > 0)
    1162             AudioOutputUtil::AdjustVolume(WPOS, num, volume,
    1163                                           music, needs_upmix && upmixer);
    1164         org_waud += num;
    1165     }
    11661212
    1167     if (encoder)
    1168     {
    1169         org_waud   = waud;
    1170         int to_get = 0;
     1213        if (internal_vol && SWVolume())
     1214        {
     1215            org_waud    = waud;
     1216            int num     = len;
    11711217
    1172         if (bdiff < len)
    1173         {
    1174             encoder->Encode(WPOS, bdiff, processing);
    1175             to_get = encoder->Encode(ABUF, len - bdiff, processing);
     1218            if (bdiff <= num)
     1219            {
     1220                AudioOutputUtil::AdjustVolume(WPOS, bdiff, volume,
     1221                                              music, needs_upmix && upmixer);
     1222                num -= bdiff;
     1223                org_waud = 0;
     1224            }
     1225            if (num > 0)
     1226                AudioOutputUtil::AdjustVolume(WPOS, num, volume,
     1227                                              music, needs_upmix && upmixer);
     1228            org_waud += num;
    11761229        }
    1177         else
    1178             to_get = encoder->Encode(WPOS, len, processing);
    11791230
    1180         if (bdiff <= to_get)
     1231        if (encoder)
    11811232        {
    1182             encoder->GetFrames(WPOS, bdiff);
    1183             to_get -= bdiff;
    1184             org_waud = 0;
     1233            org_waud            = waud;
     1234            int org_waud2       = waud;
     1235            int remaining       = len;
     1236            int to_get          = 0;
     1237            // The AC3 encoder can only work on 128kB of data at a time
     1238            int maxframes       = (INBUFSIZE / encoder->FrameSize()) *
     1239                encoder->FrameSize();
     1240
     1241            do
     1242            {
     1243                len = remaining;
     1244                if (len > maxframes)
     1245                {
     1246                    len = maxframes;
     1247                }
     1248                remaining -= len;
     1249
     1250                bdiff = kAudioRingBufferSize - org_waud;
     1251                if (bdiff < len)
     1252                {
     1253                    encoder->Encode(WPOS, bdiff, processing);
     1254                    to_get = encoder->Encode(ABUF, len - bdiff, processing);
     1255                    org_waud = len - bdiff;
     1256                }
     1257                else
     1258                {
     1259                    to_get = encoder->Encode(WPOS, len, processing);
     1260                    org_waud += len;
     1261                }
     1262
     1263                bdiff = kAudioRingBufferSize - org_waud2;
     1264                if (bdiff <= to_get)
     1265                {
     1266                    encoder->GetFrames(audiobuffer + org_waud2, bdiff);
     1267                    to_get -= bdiff ;
     1268                    org_waud2 = 0;
     1269                }
     1270                if (to_get > 0)
     1271                    encoder->GetFrames(audiobuffer + org_waud2, to_get);
     1272
     1273                org_waud2 += to_get;
     1274            }
     1275            while (remaining > 0);
     1276            org_waud = org_waud2;
    11851277        }
    1186         if (to_get > 0)
    1187             encoder->GetFrames(WPOS, to_get);
    11881278
    1189         org_waud += to_get;
     1279        waud = org_waud;
    11901280    }
    11911281
    1192     waud = org_waud;
     1282    SetAudiotime(frames_final, timecode);
    11931283
    1194     SetAudiotime(in_frames, timecode);
    1195 
    11961284    return true;
    11971285}
    11981286
  • mythtv/libs/libmyth/audiooutpututil.cpp

     
    120120}
    121121
    122122/*
    123  All fromFloat variants require 16 byte aligned output buffers on x86
    124  The SSE code processes 16 bytes at a time and leaves any remainder for the C
    125  - there is no remainder in practice */
     123  The SSE code processes 16 bytes at a time and leaves any remainder for the C
     124  - there is no remainder in practice */
    126125
    127126static int fromFloat8(uchar *out, float *in, int len)
    128127{
     
    130129    float f = (1<<7) - 1;
    131130
    132131#if ARCH_X86
    133     if (sse_check() && len >= 16)
     132    if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
    134133    {
    135134        int loops = len >> 4;
    136135        i = loops << 4;
     
    235234    float f = (1<<15) - 1;
    236235
    237236#if ARCH_X86
    238     if (sse_check() && len >= 16)
     237    if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
    239238    {
    240239        int loops = len >> 4;
    241240        i = loops << 4;
     
    342341        shift = 0;
    343342
    344343#if ARCH_X86
    345     if (sse_check() && len >= 16)
     344    if (sse_check() && len >= 16 && ((unsigned long)out & 0xf) == 0)
    346345    {
    347346        float o = 1, mo = -1;
    348347        int loops = len >> 4;
     
    407406    int i = 0;
    408407
    409408#if ARCH_X86
    410     if (sse_check() && len >= 16)
     409    if (sse_check() && len >= 16 && ((unsigned long)in & 0xf) == 0)
    411410    {
    412411        int loops = len >> 4;
    413412        float o = 1, mo = -1;
  • mythtv/libs/libmythfreesurround/freesurround.cpp

     
    3737#include <QDateTime>
    3838
    3939// our default internal block size, in floats
    40 static const unsigned default_block_size = 8192;
     40static const unsigned default_block_size = SURROUND_BUFSIZE;
    4141// Gain of center and lfe channels in passive mode (sqrt 0.5)
    4242static const float center_level = 0.707107;
    4343
  • mythtv/libs/libmythfreesurround/freesurround.h

     
    2121
    2222#include "compat.h"  // instead of sys/types.h, for MinGW compatibility
    2323
     24#define SURROUND_BUFSIZE 8192
     25
    2426class FreeSurround
    2527{
    2628public: