Ticket #1104: mythtv_ac3.15.patch
File mythtv_ac3.15.patch, 87.5 KB (added by , 18 years ago) |
---|
-
libs/libmyth/libmyth.pro
34 34 SOURCES += virtualkeyboard.cpp mythobservable.cpp 35 35 36 36 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. 37 INCLUDEPATH += ../libavutil .. 37 38 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch 39 DEPENDPATH += ../libavutil ../libavcodec 38 40 39 41 40 42 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 41 43 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 44 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 42 45 43 46 isEmpty(QMAKE_EXTENSION_SHLIB) { 44 47 QMAKE_EXTENSION_SHLIB=so -
libs/libmyth/audiooutput.h
27 27 28 28 // reconfigure sound out for new params 29 29 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; 31 34 32 35 virtual void SetStretchFactor(float factor); 33 36 … … 65 68 protected: 66 69 void Error(QString msg) 67 70 { lastError = msg; VERBOSE(VB_IMPORTANT, lastError); }; 71 void ClearError() 72 { lastError = QString::null; }; 68 73 69 74 private: 70 75 QString lastError; -
libs/libmyth/audiooutputdx.h
21 21 22 22 virtual void Reset(void); 23 23 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); 25 27 virtual void SetBlocking(bool blocking); 26 28 27 29 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
119 119 } 120 120 121 121 void AudioOutputDX::Reconfigure(int audio_bits, 122 int audio_channels, int audio_samplerate) 122 int audio_channels, 123 int audio_samplerate, 124 AudioCodecMode laom 125 ) 123 126 { 124 127 if (dsbuffer) 125 128 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
12 12 #include "samplerate.h" 13 13 #include "SoundTouch.h" 14 14 15 #define AUDBUFSIZE 768000 15 struct AVCodecContext; 16 class DigitalEncoder; 16 17 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 17 23 class AudioOutputBase : public AudioOutput 18 24 { 19 25 public: … … 24 30 25 31 // reconfigure sound out for new params 26 32 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); 28 36 29 37 // do AddSamples calls block? 30 38 virtual void SetBlocking(bool blocking); … … 52 60 // Send output events showing current progress 53 61 virtual void Status(void); 54 62 55 QString GetError() { return lastError; };63 //QString GetError() { return lastError; }; 56 64 57 65 virtual void SetSourceBitrate(int rate); 58 66 … … 108 116 109 117 float audio_stretchfactor; 110 118 AudioOutputSource source; 119 AVCodecContext *audio_codec; 111 120 112 121 bool killaudio; 113 122 … … 116 125 bool buffer_output_data_for_use; // used by AudioOutputNULL 117 126 118 127 private: 119 QString lastError;128 //QString lastError; 120 129 121 130 // resampler 122 131 bool need_resampler; … … 127 136 128 137 // timestretch 129 138 soundtouch::SoundTouch * pSoundStretch; 139 DigitalEncoder * encoder; 130 140 131 141 bool blocking; // do AddSamples calls block? 132 142 … … 142 152 143 153 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 144 154 'audiotime' and 'audiotime_updated' */ 145 intaudiotime; // timecode of audio leaving the soundcard (same units as155 long long audiotime; // timecode of audio leaving the soundcard (same units as 146 156 // timecodes) ... 147 157 struct timeval audiotime_updated; // ... which was last updated at this time 148 158 149 159 /* Audio circular buffer */ 150 160 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 151 161 int raud, waud; /* read and write positions */ 152 intaudbuf_timecode; /* timecode of audio most recently placed into162 long long audbuf_timecode; /* timecode of audio most recently placed into 153 163 buffer */ 154 164 155 165 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
12 12 #include <sys/time.h> 13 13 #include <unistd.h> 14 14 15 extern "C" { 16 #include "libavcodec/avcodec.h" 17 #include "libavcodec/liba52/a52.h" 18 } 15 19 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 28 class DigitalEncoder 29 { 30 public: 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; 50 private: 51 AVCodecContext *av_context; 52 char * outbuf; 53 char * frame_buffer; 54 int outbuf_size; 55 size_t one_frame_bytes; 56 }; 57 58 DigitalEncoder::DigitalEncoder() 59 { 60 av_context = NULL; 61 outbuf = NULL; 62 outbuf_size = 0; 63 one_frame_bytes = 0; 64 frame_buffer = NULL; 65 } 66 67 DigitalEncoder::~DigitalEncoder() 68 { 69 Dispose(); 70 } 71 72 void 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 95 bool 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 140 static 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 146 static 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 155 static 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 213 static 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 235 static 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 323 size_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 16 353 AudioOutputBase::AudioOutputBase(QString audiodevice, int, 17 354 int, int, 18 355 AudioOutputSource source, bool set_initial_vol) … … 29 366 current_seconds = -1; 30 367 source_bitrate = -1; 31 368 audio_stretchfactor = 1.0; 369 audio_codec = NULL; 32 370 pSoundStretch = NULL; 371 encoder = NULL; 33 372 blocking = false; 34 373 this->source = source; 35 374 this->set_initial_vol = set_initial_vol; … … 78 417 VERBOSE(VB_GENERAL, QString("Using time stretch %1") 79 418 .arg(audio_stretchfactor)); 80 419 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 } 83 449 84 450 pSoundStretch->setTempo(audio_stretchfactor); 85 451 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 102 468 } 103 469 104 470 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 105 int laudio_samplerate )471 int laudio_samplerate, void* laudio_codec) 106 472 { 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(); 107 485 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) 109 488 return; 110 489 111 490 KillAudio(); … … 120 499 audio_channels = laudio_channels; 121 500 audio_bits = laudio_bits; 122 501 audio_samplerate = laudio_samplerate; 502 audio_codec = (AVCodecContext*)laudio_codec; 123 503 if (audio_bits != 8 && audio_bits != 16) 124 504 { 125 505 Error("AudioOutput only supports 8 or 16bit audio."); … … 135 515 136 516 numlowbuffer = 0; 137 517 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)); 140 520 141 521 // Actually do the device specific open call 142 522 if (!OpenDevice()) { 143 523 pthread_mutex_unlock(&avsync_lock); 144 524 pthread_mutex_unlock(&audio_buflock); 525 if (GetError().isEmpty()) 526 Error("Aborting reconfigure"); 145 527 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 146 528 return; 147 529 } … … 185 567 } 186 568 187 569 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")); 188 572 189 573 SetStretchFactorLocked(audio_stretchfactor); 190 574 if (pSoundStretch) 191 575 { 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 } 194 606 } 195 607 196 608 // Setup visualisations, zero the visualisations buffers … … 237 649 pSoundStretch = NULL; 238 650 } 239 651 652 if (encoder) 653 { 654 delete encoder; 655 encoder = NULL; 656 } 657 240 658 CloseDevice(); 241 659 242 660 killAudioLock.unlock(); … … 330 748 The reason is that computing 'audiotime' requires acquiring the audio 331 749 lock, which the video thread should not do. So, we call 'SetAudioTime()' 332 750 from the audio thread, and then call this from the video thread. */ 333 intret;751 long long ret; 334 752 struct timeval now; 335 753 336 754 if (audiotime == 0) … … 342 760 343 761 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 344 762 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 345 ret = ( int)(ret * audio_stretchfactor);763 ret = (long long)(ret * audio_stretchfactor); 346 764 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 347 776 ret += audiotime; 348 777 349 778 pthread_mutex_unlock(&avsync_lock); 350 return ret;779 return (int)ret; 351 780 } 352 781 353 782 void AudioOutputBase::SetAudiotime(void) … … 384 813 // include algorithmic latencies 385 814 if (pSoundStretch) 386 815 { 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); 387 821 // add the effect of unprocessed samples in time stretch algo 388 822 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 389 823 audio_bytes_per_sample) / audio_stretchfactor); 390 824 } 391 825 392 826 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 393 827 (audio_bytes_per_sample * effdspstretched)); 394 828 395 829 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 396 843 397 844 pthread_mutex_unlock(&avsync_lock); 398 845 pthread_mutex_unlock(&audio_buflock); … … 452 899 // NOTE: This function is not threadsafe 453 900 454 901 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); 456 903 457 904 // Check we have enough space to write the data 458 905 if (need_resampler && src_ctx) 459 906 len = (int)ceilf(float(len) * src_data.src_ratio); 460 907 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)); 461 912 return false; // would overflow 913 } 462 914 463 915 // resample input if necessary 464 916 if (need_resampler && src_ctx) … … 492 944 493 945 int AudioOutputBase::WaitForFreeSpace(int samples) 494 946 { 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; 496 949 int afree = audiofree(false); 497 950 498 951 while (len > afree) 499 952 { 500 953 if (blocking) 501 954 { 502 VERBOSE(VB_AUDIO , "Waiting for free space");955 VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space"); 503 956 // wait for more space 504 957 pthread_cond_wait(&audio_bufsig, &audio_buflock); 505 958 afree = audiofree(false); 506 959 } 507 960 else 508 961 { 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; 512 967 if (src_ctx) 513 968 { 514 969 int error = src_reset(src_ctx); … … 533 988 534 989 int afree = audiofree(false); 535 990 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)); 539 996 540 997 len = WaitForFreeSpace(samples); 541 998 … … 572 1029 573 1030 if (pSoundStretch) 574 1031 { 1032 575 1033 // does not change the timecode, only the number of samples 576 1034 // back to orig pos 577 1035 org_waud = waud; 578 1036 int bdiff = AUDBUFSIZE - org_waud; 579 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1037 int nSamplesToEnd = bdiff/abps; 580 1038 if (bdiff < len) 581 1039 { 582 1040 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 583 1041 org_waud), nSamplesToEnd); 584 1042 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 585 (len - bdiff) / a udio_bytes_per_sample);1043 (len - bdiff) / abps); 586 1044 } 587 1045 else 588 1046 { 589 1047 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 590 org_waud), len / a udio_bytes_per_sample);1048 org_waud), len / abps); 591 1049 } 592 1050 593 int newLen = 0; 594 int nSamples; 595 len = WaitForFreeSpace(pSoundStretch->numSamples() * 596 audio_bytes_per_sample); 597 do 1051 if (encoder) 598 1052 { 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) 601 1067 { 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; 603 1091 } 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 608 1100 { 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 } 617 1106 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 } 621 1124 } 622 1125 623 1126 waud = org_waud; … … 687 1190 space_on_soundcard = getSpaceOnSoundcard(); 688 1191 689 1192 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") 691 1194 .arg(space_on_soundcard)); 692 1195 last_space_on_soundcard = space_on_soundcard; 693 1196 } … … 700 1203 WriteAudio(zeros, fragment_size); 701 1204 } else { 702 1205 // this should never happen now -dag 703 VERBOSE(VB_AUDIO ,1206 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 704 1207 QString("waiting for space on soundcard " 705 1208 "to write zeros: have %1 need %2") 706 1209 .arg(space_on_soundcard).arg(fragment_size)); … … 736 1239 if (fragment_size > audiolen(true)) 737 1240 { 738 1241 if (audiolen(true) > 0) // only log if we're sending some audio 739 VERBOSE(VB_AUDIO ,1242 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 740 1243 QString("audio waiting for buffer to fill: " 741 1244 "have %1 want %2") 742 1245 .arg(audiolen(true)).arg(fragment_size)); 743 1246 744 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1247 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 745 1248 pthread_mutex_lock(&audio_buflock); 746 1249 pthread_cond_broadcast(&audio_bufsig); 747 1250 pthread_mutex_unlock(&audio_buflock); … … 755 1258 if (fragment_size > space_on_soundcard) 756 1259 { 757 1260 if (space_on_soundcard != last_space_on_soundcard) { 758 VERBOSE(VB_AUDIO ,1261 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 759 1262 QString("audio waiting for space on soundcard: " 760 1263 "have %1 need %2") 761 1264 .arg(space_on_soundcard).arg(fragment_size)); … … 817 1320 818 1321 /* update raud */ 819 1322 raud = (raud + fragment_size) % AUDBUFSIZE; 820 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1323 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 821 1324 pthread_cond_broadcast(&audio_bufsig); 822 1325 823 1326 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
75 75 } 76 76 else 77 77 { 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); 79 81 buffer_time = 500000; // .5 seconds 80 82 period_time = buffer_time / 4; // 4 interrupts per buffer 81 83 } … … 148 150 149 151 tmpbuf = aubuf; 150 152 151 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")153 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 152 154 .arg(size).arg(frames)); 153 155 154 156 while (frames > 0) -
libs/libmythsoundtouch/TDStretch.cpp
96 96 97 97 pMidBuffer = NULL; 98 98 pRefMidBufferUnaligned = NULL; 99 midBufferLength = 0; 99 100 overlapLength = 0; 100 101 101 102 setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS); … … 108 109 109 110 TDStretch::~TDStretch() 110 111 { 111 delete[] pMidBuffer; 112 delete[] pRefMidBufferUnaligned; 112 if (midBufferLength) 113 { 114 delete[] pMidBuffer; 115 delete[] pRefMidBufferUnaligned; 116 midBufferLength = 0; 117 } 113 118 } 114 119 115 120 … … 196 201 197 202 void TDStretch::clearMidBuffer() 198 203 { 199 if (bMidBufferDirty )204 if (bMidBufferDirty && midBufferLength) 200 205 { 201 memset(pMidBuffer, 0, 2* sizeof(SAMPLETYPE) * overlapLength);206 memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength); 202 207 bMidBufferDirty = FALSE; 203 208 } 204 209 } … … 239 244 // Seeks for the optimal overlap-mixing position. 240 245 uint TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos) 241 246 { 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 242 262 if (channels == 2) 243 263 { 244 264 // stereo sound … … 272 292 // of 'ovlPos'. 273 293 inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const 274 294 { 295 #ifdef MULTICHANNEL 296 if (channels > 2) 297 { 298 overlapMulti(output, input + channels * ovlPos); 299 } 300 else 301 #endif 275 302 if (channels == 2) 276 303 { 277 304 // stereo sound … … 291 318 // The best position is determined as the position where the two overlapped 292 319 // sample sequences are 'most alike', in terms of the highest cross-correlation 293 320 // value over the overlapping period 321 uint 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 361 uint 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 294 417 uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) 295 418 { 296 419 uint bestOffs; … … 512 635 void TDStretch::setChannels(uint numChannels) 513 636 { 514 637 if (channels == numChannels) return; 638 #ifdef MULTICHANNEL 639 assert(numChannels >= 1 && numChannels <= MULTICHANNEL); 640 #else 515 641 assert(numChannels == 1 || numChannels == 2); 642 #endif 516 643 517 644 channels = numChannels; 518 645 inputBuffer.setChannels(channels); … … 635 762 /// Set new overlap length parameter & reallocate RefMidBuffer if necessary. 636 763 void TDStretch::acceptNewOverlapLength(uint newOverlapLength) 637 764 { 638 uint prevOvl;765 //uint prevOvl; 639 766 640 prevOvl = overlapLength;767 //prevOvl = overlapLength; 641 768 overlapLength = newOverlapLength; 642 769 643 if (overlapLength > prevOvl) 770 //if (overlapLength > prevOvl) 771 if (overlapLength*channels > midBufferLength) 644 772 { 645 delete[] pMidBuffer; 646 delete[] pRefMidBufferUnaligned; 773 if (midBufferLength) 774 { 775 delete[] pMidBuffer; 776 delete[] pRefMidBufferUnaligned; 777 midBufferLength = 0; 778 } 647 779 648 pMidBuffer = new SAMPLETYPE[overlapLength * 2];780 pMidBuffer = new SAMPLETYPE[overlapLength * channels]; 649 781 bMidBufferDirty = TRUE; 650 782 clearMidBuffer(); 783 midBufferLength = overlapLength * channels; 651 784 652 pRefMidBufferUnaligned = new SAMPLETYPE[ 2* overlapLength + 16 / sizeof(SAMPLETYPE)];785 pRefMidBufferUnaligned = new SAMPLETYPE[channels * overlapLength + 16 / sizeof(SAMPLETYPE)]; 653 786 // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency 654 787 pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16); 655 788 } … … 718 851 719 852 #ifdef INTEGER_SAMPLES 720 853 854 #ifdef MULTICHANNEL 721 855 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 722 856 // is faster to calculate 857 void 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 723 879 void TDStretch::precalcCorrReferenceStereo() 724 880 { 725 881 int i, cnt2; … … 772 928 } 773 929 } 774 930 931 #ifdef MULTICHANNEL 932 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' 933 // version of the routine. 934 void 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; 775 942 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 776 953 /// Calculates overlap period length in samples. 777 954 /// Integer version rounds overlap length to closest power of 2 778 955 /// for a divide scaling operation. … … 824 1001 return corr; 825 1002 } 826 1003 1004 #ifdef MULTICHANNEL 1005 long 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 827 1020 #endif // INTEGER_SAMPLES 828 1021 829 1022 ////////////////////////////////////////////////////////////////////////////// … … 931 1124 return corr; 932 1125 } 933 1126 934 #endif // FLOAT_SAMPLES 935 No newline at end of file 1127 #endif // FLOAT_SAMPLES -
libs/libmythsoundtouch/TDStretch.h
48 48 #include "RateTransposer.h" 49 49 #include "FIFOSamplePipe.h" 50 50 51 #define USE_MULTI_MMX 52 51 53 namespace soundtouch 52 54 { 53 55 … … 100 102 SAMPLETYPE *pMidBuffer; 101 103 SAMPLETYPE *pRefMidBuffer; 102 104 SAMPLETYPE *pRefMidBufferUnaligned; 105 uint midBufferLength; 103 106 uint overlapLength; 104 107 uint overlapDividerBits; 105 108 uint slopingDivider; … … 123 126 virtual void clearCrossCorrState(); 124 127 void calculateOverlapLength(uint overlapMs); 125 128 129 #ifdef MULTICHANNEL 130 virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 131 #endif 126 132 virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 127 133 virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 128 134 135 #ifdef MULTICHANNEL 136 virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos); 137 virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos); 138 #endif 129 139 virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos); 130 140 virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos); 131 141 virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos); 132 142 virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos); 133 143 uint seekBestOverlapPosition(const SAMPLETYPE *refPos); 134 144 145 #ifdef MULTICHANNEL 146 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 147 #endif 135 148 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 136 149 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 137 150 138 151 void clearMidBuffer(); 139 152 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 140 153 154 #ifdef MULTICHANNEL 155 void precalcCorrReference(); 156 #endif 141 157 void precalcCorrReferenceMono(); 142 158 void precalcCorrReferenceStereo(); 143 159 … … 225 241 class TDStretchMMX : public TDStretch 226 242 { 227 243 protected: 244 #ifdef USE_MULTI_MMX 245 #ifdef MULTICHANNEL 246 long calcCrossCorrMulti(const short *mixingPos, const short *compare) const; 247 #endif 248 #endif 228 249 long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; 229 250 virtual void overlapStereo(short *output, const short *input) const; 230 251 virtual void clearCrossCorrState(); … … 237 258 class TDStretch3DNow : public TDStretch 238 259 { 239 260 protected: 261 #ifdef MULTICHANNEL 262 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 263 #endif 240 264 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 241 265 }; 242 266 #endif /// ALLOW_3DNOW … … 247 271 class TDStretchSSE : public TDStretch 248 272 { 249 273 protected: 274 #ifdef MULTICHANNEL 275 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 276 #endif 250 277 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 251 278 }; 252 279 -
libs/libmythsoundtouch/RateTransposer.cpp
330 330 { 331 331 if (uChannels == numchannels) return; 332 332 333 #ifdef MULTICHANNEL 334 assert(numchannels >= 1 && numchannels <= MULTICHANNEL); 335 #else 333 336 assert(numchannels == 1 || numchannels == 2); 337 #endif 334 338 uChannels = numchannels; 335 339 336 340 storeBuffer.setChannels(uChannels); -
libs/libmythsoundtouch/mmx_gcc.cpp
141 141 return tmp; 142 142 } 143 143 144 #ifdef USE_MULTI_MMX 145 // Calculates cross correlation of two buffers 146 long TDStretchMMX::calcCrossCorrMulti(const short *pV1, const short *pV2) const 147 { 148 //static const unsigned long long int mm_half __attribute__ ((aligned(8))) = 0xffffffffULL; 149 static const __m64 mm_mask[4][8] __attribute__ ((aligned(8))) = { 150 { 151 // even bit 152 0xffffffffffffffffULL, 153 0xffffffffffffffffULL, 154 0xffffffffffffffffULL, 155 0xffffffffffffffffULL, 156 0, 157 0, 158 0, 159 0 160 }, 161 { 162 0xffffffffffffffffULL, 163 0xffffffffffffffffULL, 164 0xffffffffffffffffULL, 165 0x0000ffffffffffffULL, 166 0, 167 0, 168 0, 169 0 170 }, 171 { 172 0xffffffffffffffffULL, 173 0xffffffffffffffffULL, 174 0xffffffffffffffffULL, 175 0x00000000ffffffffULL, 176 0, 177 0, 178 0, 179 0 180 }, 181 { 182 0xffffffffffffffffULL, 183 0xffffffffffffffffULL, 184 0xffffffffffffffffULL, 185 0x000000000000ffffULL, 186 0, 187 0, 188 0, 189 0 190 } 191 }; 192 uint tmp; 193 uint adjustedOverlapLength = overlapLength*channels; 194 uint counter = ((adjustedOverlapLength+15)>>4)-1; // load counter to counter = overlapLength / 8 - 1 195 uint remainder = (16-adjustedOverlapLength)&0xf; // since there are 1/3 sample per 1/2 quadword 196 197 __m64 *ph = (__m64*)&mm_mask[remainder&3][remainder>>2]; 198 __m64 *pv1=(__m64*)pV1, *pv2=(__m64*)pV2; 199 GI(__m64 m0, m1, m2, m3, m4, m5, m6); // temporaries 200 uint shift = overlapDividerBits; 201 202 // prepare to the first round by loading 203 SI(m1 = pv1[0], movq_a2r(0, pv1, mm1)); // load m1 = pv1[0] 204 SI(m2 = pv1[1], movq_a2r(8, pv1, mm2)); // load m2 = pv1[1] 205 SI(m0 = _mm_setzero_si64(), pxor_r2r(mm0, mm0)); // clear m0 206 SI(m5 = _mm_cvtsi32_si64(shift),movd_v2r(shift, mm5)); // shift in 64bit reg 207 208 do { 209 // Calculate cross-correlation between the tempOffset and tmpbid_buffer. 210 // Process 4 parallel batches of 2 * stereo samples each during one 211 // round to improve CPU-level parallellization. 212 SI(m1 = _mm_madd_pi16(m1, pv2[0]),pmaddwd_a2r(0, pv2, mm1)); // multiply-add m1 = m1 * pv2[0] 213 SI(m3 = pv1[2], movq_a2r(16, pv1, mm3)); // load mm3 = pv1[2] 214 SI(m2 = _mm_madd_pi16(m2, pv2[1]),pmaddwd_a2r(8, pv2, mm2)); // multiply-add m2 = m2 * pv2[1] 215 SI(m4 = pv1[3], movq_a2r(24, pv1, mm4)); // load mm4 = pv1[3] 216 SI(m3 = _mm_madd_pi16(m3, pv2[2]),pmaddwd_a2r(16, pv2, mm3));// multiply-add m3 = m3 * pv2[2] 217 SI(m2 = _mm_add_pi32(m2, m1), paddd_r2r(mm1, mm2)); // add m2 += m1 218 SI(m4 = _mm_madd_pi16(m4, pv2[3]),pmaddwd_a2r(24, pv2, mm4));// multiply-add m4 = m4 * pv2[3] 219 SI(m1 = pv1[4], movq_a2r(32, pv1, mm1)); // mm1 = pv1[0] for next round 220 SI(m2 = _mm_srai_pi32(m2, m5), psrad_r2r(mm5, mm2)); // m2 >>= shift (mm5) 221 pv1 += 4; // increment first pointer 222 SI(m3 = _mm_add_pi32(m3, m4), paddd_r2r(mm4, mm3)); // m3 += m4 223 SI(m0 = _mm_add_pi32(m0, m2), paddd_r2r(mm2, mm0)); // m0 += m2 224 SI(m2 = pv1[1], movq_a2r(8, pv1, mm2)); // mm2 = pv1[1] for next round 225 SI(m3 = _mm_srai_pi32(m3, m5), psrad_r2r(mm5, mm3)); // m3 >>= shift (mm5) 226 pv2 += 4; // increment second pointer 227 SI(m0 = _mm_add_pi32(m0, m3), paddd_r2r(mm3, mm0)); // add m0 += m3 228 } while ((--counter)!=0); 229 230 SI(m6 = ph[0], movq_a2r(0, ph, mm6)); 231 // Finalize the last partial loop: 232 SI(m1 = _mm_madd_pi16(m1, pv2[0]), pmaddwd_a2r(0, pv2, mm1)); 233 SI(m1 = _mm_and_si64(m1, m6), pand_r2r(mm6, mm1)); 234 SI(m3 = pv1[2], movq_a2r(16, pv1, mm3)); 235 SI(m6 = ph[1], movq_a2r(8, ph, mm6)); 236 SI(m2 = _mm_madd_pi16(m2, pv2[1]), pmaddwd_a2r(8, pv2, mm2)); 237 SI(m2 = _mm_and_si64(m2, m6), pand_r2r(mm6, mm2)); 238 SI(m4 = pv1[3], movq_a2r(24, pv1, mm4)); 239 SI(m6 = ph[2], movq_a2r(16, ph, mm6)); 240 SI(m3 = _mm_madd_pi16(m3, pv2[2]), pmaddwd_a2r(16, pv2, mm3)); 241 SI(m3 = _mm_and_si64(m3, m6), pand_r2r(mm6, mm3)); 242 SI(m2 = _mm_add_pi32(m2, m1), paddd_r2r(mm1, mm2)); 243 SI(m6 = ph[3], movq_a2r(24, ph, mm6)); 244 SI(m4 = _mm_madd_pi16(m4, pv2[3]), pmaddwd_a2r(24, pv2, mm4)); 245 SI(m4 = _mm_and_si64(m4, m6), pand_r2r(mm6, mm4)); 246 SI(m2 = _mm_srai_pi32(m2, m5), psrad_r2r(mm5, mm2)); 247 SI(m3 = _mm_add_pi32(m3, m4), paddd_r2r(mm4, mm3)); 248 SI(m0 = _mm_add_pi32(m0, m2), paddd_r2r(mm2, mm0)); 249 SI(m3 = _mm_srai_pi32(m3, m5), psrad_r2r(mm5, mm3)); 250 SI(m0 = _mm_add_pi32(m0, m3), paddd_r2r(mm3, mm0)); 251 252 // copy hi-dword of mm0 to lo-dword of mm1, then sum mm0+mm1 253 // and finally return the result 254 SI(m1 = m0, movq_r2r(mm0, mm1)); 255 SI(m1 = _mm_srli_si64(m1, 32), psrld_i2r(32, mm1)); 256 SI(m0 = _mm_add_pi32(m0, m1), paddd_r2r(mm1, mm0)); 257 SI(tmp = _mm_cvtsi64_si32(m0), movd_r2m(mm0, tmp)); 258 return tmp; 259 } 260 #endif 261 144 262 void TDStretchMMX::clearCrossCorrState() 145 263 { 146 264 _mm_empty(); … … 224 342 _mm_empty(); 225 343 } 226 344 345 #if 0 346 // MMX-optimized version of the function overlapMulti 347 void TDStretchMMX::overlapMulti(short *output, const short *input) const 348 { 349 _mm_empty(); 350 uint shift = overlapDividerBits; 351 uint counter = overlapLength>>2; // counter = overlapLength / 4 352 __m64 *inPtr = (__m64*) input; // load address of inputBuffer 353 __m64 *midPtr = (__m64*) pMidBuffer; // load address of midBuffer 354 __m64 *outPtr = ((__m64*) output)-2; // load address of outputBuffer 355 GI(__m64 m0, m1, m2, m3, m4, m5, m6, m7); // temporaries 356 357 // load mixing value adder to mm5 358 uint tmp0 = 0x0002fffe; // tmp0 = 0x0002 fffe 359 SI(m5 = _mm_cvtsi32_si64(tmp0), movd_v2r(tmp0, mm5)); // mm5 = 0x0000 0000 0002 fffe 360 SI(m5 = _mm_unpacklo_pi32(m5,m5), punpckldq_r2r(mm5, mm5)); // mm5 = 0x0002 fffe 0002 fffe 361 // load sliding mixing value counter to mm6 362 SI(m6 = _mm_cvtsi32_si64(overlapLength), movd_v2r(overlapLength, mm6)); 363 SI(m6 = _mm_unpacklo_pi32(m6, m6), punpckldq_r2r(mm6, mm6)); // mm6 = 0x0000 OVL_ 0000 OVL_ 364 // load sliding mixing value counter to mm7 365 uint tmp1 = (overlapLength-1)|0x00010000; // tmp1 = 0x0001 overlapLength-1 366 SI(m7 = _mm_cvtsi32_si64(tmp1), movd_v2r(tmp1, mm7)); // mm7 = 0x0000 0000 0001 01ff 367 SI(m7 = _mm_unpacklo_pi32(m7, m7), punpckldq_r2r(mm7, mm7)); // mm7 = 0x0001 01ff 0001 01ff 368 369 do { 370 // Process two parallel batches of 2+2 stereo samples during each round 371 // to improve CPU-level parallellization. 372 // 373 // Load [midPtr] into m0 and m1 374 // Load [inPtr] into m3 375 // unpack words of m0, m1 and m3 into m0 and m1 376 // multiply-add m0*m6 and m1*m7, store results into m0 and m1 377 // divide m0 and m1 by 512 (=right-shift by overlapDividerBits) 378 // pack the result into m0 and store into [edx] 379 // 380 // Load [midPtr+8] into m2 and m3 381 // Load [inPtr+8] into m4 382 // unpack words of m2, m3 and m4 into m2 and m3 383 // multiply-add m2*m6 and m3*m7, store results into m2 and m3 384 // divide m2 and m3 by 512 (=right-shift by overlapDividerBits) 385 // pack the result into m2 and store into [edx+8] 386 SI(m0 = midPtr[0], movq_a2r(0, midPtr, mm0));// mm0 = m1l m1r m0l m0r 387 outPtr += 2; 388 SI(m3 = inPtr[0], movq_a2r(0, inPtr, mm3)); // mm3 = i1l i1r i0l i0r 389 SI(m1 = m0, movq_r2r(mm0, mm1)); // mm1 = m1l m1r m0l m0r 390 SI(m2 = midPtr[1], movq_a2r(8, midPtr, mm2));// mm2 = m3l m3r m2l m2r 391 SI(m0 = _mm_unpacklo_pi16(m0, m3),punpcklwd_r2r(mm3, mm0)); // mm0 = i0l m0l i0r m0r 392 midPtr += 2; 393 SI(m4 = inPtr[1], movq_a2r(8, inPtr, mm4)); // mm4 = i3l i3r i2l i2r 394 SI(m1 = _mm_unpackhi_pi16(m1, m3),punpckhwd_r2r(mm3, mm1)); // mm1 = i1l m1l i1r m1r 395 inPtr+=2; 396 SI(m3 = m2, movq_r2r(mm2, mm3)); // mm3 = m3l m3r m2l m2r 397 SI(m2 = _mm_unpacklo_pi16(m2, m4),punpcklwd_r2r(mm4, mm2)); // mm2 = i2l m2l i2r m2r 398 // mm0 = i0l*m63+m0l*m62 i0r*m61+m0r*m60 399 SI(m0 = _mm_madd_pi16(m0, m6), pmaddwd_r2r(mm6, mm0)); 400 SI(m3 = _mm_unpackhi_pi16(m3, m4),punpckhwd_r2r(mm4, mm3)); // mm3 = i3l m3l i3r m3r 401 SI(m4 = _mm_cvtsi32_si64(shift), movd_v2r(shift, mm4)); // mm4 = shift 402 // mm1 = i1l*m73+m1l*m72 i1r*m71+m1r*m70 403 SI(m1 = _mm_madd_pi16(m1, m7), pmaddwd_r2r(mm7, mm1)); 404 SI(m6 = _mm_add_pi16(m6, m5), paddw_r2r(mm5, mm6)); 405 SI(m7 = _mm_add_pi16(m7, m5), paddw_r2r(mm5, mm7)); 406 SI(m0 = _mm_srai_pi32(m0, m4), psrad_r2r(mm4, mm0)); // mm0 >>= shift 407 // mm2 = i2l*m63+m2l*m62 i2r*m61+m2r*m60 408 SI(m2 = _mm_madd_pi16(m2, m6), pmaddwd_r2r(mm6, mm2)); 409 SI(m1 = _mm_srai_pi32(m1, m4), psrad_r2r(mm4, mm1)); // mm1 >>= shift 410 // mm3 = i3l*m73+m3l*m72 i3r*m71+m3r*m70 411 SI(m3 = _mm_madd_pi16(m3, m7), pmaddwd_r2r(mm7, mm3)); 412 SI(m2 = _mm_srai_pi32(m2, m4), psrad_r2r(mm4, mm2)); // mm2 >>= shift 413 SI(m0 = _mm_packs_pi32(m0, m1), packssdw_r2r(mm1, mm0)); // mm0 = mm1h mm1l mm0h mm0l 414 SI(m3 = _mm_srai_pi32(m3, m4), psrad_r2r(mm4, mm3)); // mm3 >>= shift 415 SI(m6 = _mm_add_pi16(m6, m5), paddw_r2r(mm5, mm6)); 416 SI(m2 = _mm_packs_pi32(m2, m3), packssdw_r2r(mm3, mm2)); // mm2 = mm2h mm2l mm3h mm3l 417 SI(m7 = _mm_add_pi16(m7, m5), paddw_r2r(mm5, mm7)); 418 SI(outPtr[0] = m0, movq_r2a(mm0, 0, outPtr)); 419 SI(outPtr[1] = m2, movq_r2a(mm2, 8, outPtr)); 420 } while ((--counter)!=0); 421 _mm_empty(); 422 } 423 #endif 424 227 425 ////////////////////////////////////////////////////////////////////////////// 228 426 // 229 427 // implementation of MMX optimized functions of class 'FIRFilter' -
libs/libmythsoundtouch/STTypes.h
61 61 #define INTEGER_SAMPLES //< 16bit integer samples 62 62 //#define FLOAT_SAMPLES //< 32bit float samples 63 63 64 #define MULTICHANNEL 6 64 65 65 66 /// Define this to allow CPU-specific assembler optimizations. Notice that 66 67 /// having this enabled on non-x86 platforms doesn't matter; the compiler can -
libs/libmythsoundtouch/SoundTouch.cpp
140 140 // Sets the number of channels, 1 = mono, 2 = stereo 141 141 void SoundTouch::setChannels(uint numChannels) 142 142 { 143 #ifdef MULTICHANNEL 144 if (numChannels < 1 || numChannels > MULTICHANNEL) 145 #else 143 146 if (numChannels != 1 && numChannels != 2) 147 #endif 144 148 { 145 149 throw std::runtime_error("Illegal number of channels"); 146 150 } -
programs/mythfrontend/globalsettings.cpp
36 36 dev.setNameFilter("adsp*"); 37 37 gc->fillSelectionsFromDir(dev); 38 38 } 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"); 39 53 40 54 return gc; 41 55 } 42 56 57 static HostComboBox *MaxAudioChannels() 58 { 59 HostComboBox *gc = new HostComboBox("MaxChannels",false); 60 gc->setLabel(QObject::tr("Max Audio Channels")); 61 //gc->addSelection(QObject::tr("Mono"), "1"); 62 //gc->addSelection(QObject::tr("Stereo L+R"), "2", true); // default 63 //gc->addSelection(QObject::tr("3 Channel: L C R"), "3"); 64 //gc->addSelection(QObject::tr("4 Channel: L R LS RS"), "4"); 65 //gc->addSelection(QObject::tr("5 Channel: L C R LS RS"), "5"); 66 //gc->addSelection(QObject::tr("6 Channel: L C R LS RS LFE"), "6"); 67 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 68 gc->addSelection(QObject::tr("6 Channel"), "6"); 69 gc->setHelpText( 70 QObject::tr("Set the maximum number of audio channels to be decoded. " 71 "This is for multi-channel/surround audio playback.")); 72 return gc; 73 } 74 43 75 static HostCheckBox *MythControlsVolume() 44 76 { 45 77 HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); … … 2092 2124 setUseLabel(false); 2093 2125 2094 2126 addChild(AudioOutputDevice()); 2127 #if 0 2128 ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false); 2129 ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false); 2130 settingsLeft->addChild(AC3PassThrough()); 2131 #ifdef CONFIG_DTS 2132 settingsLeft->addChild(DTSPassThrough()); 2133 #endif 2134 settingsLeft->addChild(AggressiveBuffer()); 2135 hg->addChild(settingsLeft); 2136 2137 ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false); 2138 settingsRight->addChild(MaxAudioChannels()); 2139 hg->addChild(settingsRight); 2140 2141 addChild(hg); 2142 #else 2095 2143 addChild(AC3PassThrough()); 2096 2144 #ifdef CONFIG_DTS 2097 2145 addChild(DTSPassThrough()); 2098 2146 #endif 2099 2147 addChild(AggressiveBuffer()); 2148 addChild(MaxAudioChannels()); 2149 #endif 2100 2150 2101 2151 Setting* volumeControl = MythControlsVolume(); 2102 2152 addChild(volumeControl); -
programs/mythtranscode/transcode.cpp
46 46 47 47 // reconfigure sound out for new params 48 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, int audio_samplerate) 49 int audio_channels, int audio_samplerate, 50 void * = NULL) 50 51 { 52 ClearError(); 51 53 (void)audio_samplerate; 52 54 bits = audio_bits; 53 55 channels = audio_channels; 54 56 bytes_per_sample = bits * channels / 8; 57 if (channels>2) 58 Error("Invalid channel count"); 55 59 } 56 60 57 61 // dsprate is in 100 * samples/second -
libs/libmythtv/avformatdecoder.h
238 238 bool allow_ac3_passthru; 239 239 bool allow_dts_passthru; 240 240 bool disable_passthru; 241 int max_channels; 241 242 242 243 AudioInfo audioIn; 243 244 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
38 38 #define MAX_AC3_FRAME_SIZE 6144 39 39 40 40 /** 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 41 45 #define MAX_OUTPUT_CHANNELS 2 46 #endif 42 47 43 48 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, 44 49 int *sample_rate, int *bit_rate); … … 286 291 #ifdef CONFIG_DTS 287 292 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 288 293 #endif 294 max_channels = gContext->GetNumSetting("MaxChannels", 2); 289 295 290 296 audioIn.sample_size = -32; // force SetupAudioStream to run once 291 297 } … … 406 412 framesPlayed = lastKey; 407 413 framesRead = lastKey; 408 414 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 409 427 int normalframes = desiredFrame - framesPlayed; 410 428 429 #if 0 430 if (!exactseeks) 431 normalframes = 0; 432 #endif 433 411 434 SeekReset(lastKey, normalframes, discardFrames, discardFrames); 412 435 413 436 if (discardFrames) … … 739 762 740 763 fmt->flags &= ~AVFMT_NOFILE; 741 764 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 742 776 av_estimate_timings(ic); 743 777 av_read_frame_flush(ic); 744 778 … … 769 803 // If we don't have a position map, set up ffmpeg for seeking 770 804 if (!recordingHasPositionMap) 771 805 { 806 const char *name = ic->av_class->item_name(ic); 772 807 VERBOSE(VB_PLAYBACK, LOC + 773 "Recording has no position -- using libavformat seeking.");808 QString("Recording has no position -- using libavformat seeking. %1").arg(name)); 774 809 int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; 775 810 776 811 if (dur > 0) … … 1048 1083 <<") already open, leaving it alone."); 1049 1084 } 1050 1085 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 1051 1091 1092 #if 0 1052 1093 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1053 1094 if (enc->codec_id == CODEC_ID_DTS) 1054 1095 { … … 1057 1098 // enc->bit_rate = what??; 1058 1099 } 1059 1100 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1101 #endif 1060 1102 1061 1103 bitrate += enc->bit_rate; 1062 1104 break; … … 1557 1599 { 1558 1600 long long startpos = pkt->pos; 1559 1601 1560 VERBOSE(VB_PLAYBACK , LOC +1602 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1561 1603 QString("positionMap[ %1 ] == %2.") 1562 1604 .arg(prevgoppos / keyframedist) 1563 1605 .arg((int)startpos)); … … 2268 2310 2269 2311 AVStream *curstream = ic->streams[pkt->stream_index]; 2270 2312 2313 #if 0 2314 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3") 2315 .arg(pkt->pts) 2316 .arg(pkt->dts) 2317 .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1) 2318 ); 2319 #endif 2320 2271 2321 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 2272 2322 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 2273 2323 … … 2381 2431 if (!curstream->codec->channels) 2382 2432 { 2383 2433 QMutexLocker locker(&avcodeclock); 2434 #if MAXCHANNELSELECT 2435 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 2436 curstream->codec->channels = audioOut.channels; 2437 #else 2384 2438 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 2439 #endif 2385 2440 ret = avcodec_decode_audio( 2386 2441 curstream->codec, audioSamples, 2387 2442 &data_size, ptr, len); … … 2432 2487 { 2433 2488 AVCodecContext *ctx = curstream->codec; 2434 2489 2490 #if MAXCHANNELSELECT 2435 2491 if ((ctx->channels == 0) || 2492 (ctx->channels > audioOut.channels)) 2493 ctx->channels = audioOut.channels; 2494 #else 2495 if ((ctx->channels == 0) || 2436 2496 (ctx->channels > MAX_OUTPUT_CHANNELS)) 2437 2497 ctx->channels = MAX_OUTPUT_CHANNELS; 2498 #endif 2438 2499 2439 2500 ret = avcodec_decode_audio( 2440 2501 ctx, audioSamples, &data_size, ptr, len); … … 2470 2531 (curstream->codec->channels * 2) / 2471 2532 curstream->codec->sample_rate); 2472 2533 2534 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4") 2535 .arg(pkt->pts) 2536 .arg(pkt->dts) 2537 .arg(temppts).arg(lastapts)); 2473 2538 GetNVP()->AddAudioData((char *)audioSamples, data_size, 2474 2539 temppts); 2475 2540 … … 2561 2626 else 2562 2627 temppts = lastvpts; 2563 2628 2629 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4") 2630 .arg(pkt->pts) 2631 .arg(pkt->dts) 2632 .arg(temppts).arg(lastvpts)); 2564 2633 /* XXX: Broken. 2565 2634 if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && 2566 2635 context->height == picframe->height) … … 2655 2724 2656 2725 void AvFormatDecoder::SetDisablePassThrough(bool disable) 2657 2726 { 2727 #if MAXCHANNELSELECT 2728 // can only disable never reenable as once tiemstretch is on its on for the session 2729 if (disable_passthru) 2730 return; 2731 #endif 2658 2732 if (selectedAudioStream.av_stream_index < 0) 2659 2733 { 2660 2734 disable_passthru = disable; 2661 2735 return; 2662 2736 } 2663 2737 2664 2738 if (disable != disable_passthru) 2665 2739 { 2666 2740 disable_passthru = disable; … … 2687 2761 AVCodecContext *codec_ctx = NULL; 2688 2762 AudioInfo old_in = audioIn; 2689 2763 AudioInfo old_out = audioOut; 2764 bool using_passthru = false; 2690 2765 2691 2766 if ((currentAudioTrack >= 0) && 2692 2767 (selectedAudioStream.av_stream_index <= ic->nb_streams) && … … 2696 2771 assert(curstream->codec); 2697 2772 codec_ctx = curstream->codec; 2698 2773 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 2699 !disable_passthru &&2700 2774 (codec_ctx->codec_id == CODEC_ID_AC3)); 2701 2775 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 2702 !disable_passthru &&2703 2776 (codec_ctx->codec_id == CODEC_ID_DTS)); 2777 using_passthru = do_ac3_passthru || do_dts_passthru; 2704 2778 info = AudioInfo(codec_ctx->codec_id, 2705 2779 codec_ctx->sample_rate, codec_ctx->channels, 2706 do_ac3_passthru || do_dts_passthru);2780 using_passthru && !disable_passthru); 2707 2781 } 2708 2782 2709 2783 if (info == audioIn) 2710 2784 return false; // no change 2711 2785 2786 QString ptmsg = ""; 2787 if (using_passthru) 2788 { 2789 ptmsg = QString(" using passthru"); 2790 } 2712 2791 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 2713 QString("audio track #%1").arg(currentAudioTrack+1)); 2792 QString("audio track #%1") 2793 .arg(currentAudioTrack+1) 2794 + ptmsg ); 2714 2795 2715 2796 audioOut = audioIn = info; 2797 #if MAXCHANNELSELECT 2798 if (using_passthru) 2799 #else 2716 2800 if (audioIn.do_passthru) 2801 #endif 2717 2802 { 2718 2803 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 2719 audioOut.channels = 2; 2720 audioOut.sample_rate = 48000; 2721 audioOut.sample_size = 4; 2804 AudioInfo digInfo = audioOut; 2805 if (!disable_passthru) 2806 { 2807 digInfo.channels = 2; 2808 digInfo.sample_rate = 48000; 2809 digInfo.sample_size = 4; 2810 } 2811 if (audioOut.channels > max_channels) 2812 { 2813 audioOut.channels = max_channels; 2814 audioOut.sample_size = audioOut.channels * 2; 2815 codec_ctx->channels = audioOut.channels; 2816 } 2817 #if MAXCHANNELSELECT 2818 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 2819 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 2820 .arg(digInfo.toString()) 2821 .arg(old_in.toString()).arg(old_out.toString()) 2822 .arg(audioIn.toString()).arg(audioOut.toString())); 2823 2824 if (digInfo.sample_rate > 0) 2825 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 2826 2827 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2828 // audioOut.sample_rate); 2829 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 2830 digInfo.sample_rate); 2831 // allow the audio stuff to reencode 2832 GetNVP()->SetAudioCodec(codec_ctx); 2833 GetNVP()->ReinitAudio(); 2834 return true; 2835 #endif 2722 2836 } 2837 #if MAXCHANNELSELECT 2723 2838 else 2724 2839 { 2840 if (audioOut.channels > max_channels) 2841 { 2842 audioOut.channels = max_channels; 2843 audioOut.sample_size = audioOut.channels * 2; 2844 codec_ctx->channels = audioOut.channels; 2845 } 2846 } 2847 bool audiook; 2848 do 2849 { 2850 #else 2851 else 2852 { 2725 2853 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 2726 2854 { 2727 2855 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 2729 2857 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 2730 2858 } 2731 2859 } 2860 #endif 2732 2861 2733 2862 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 2734 2863 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 2740 2869 2741 2870 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2742 2871 audioOut.sample_rate); 2743 GetNVP()->ReinitAudio(); 2872 // allow the audio stuff to reencode 2873 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 2874 QString errMsg = GetNVP()->ReinitAudio(); 2875 #if MAXCHANNELSELECT 2876 audiook = errMsg.isEmpty(); 2877 if (!audiook) 2878 { 2879 switch (audioOut.channels) 2880 { 2881 #if 0 2882 case 8: 2883 audioOut.channels = 6; 2884 break; 2885 #endif 2886 case 6: 2887 audioOut.channels = 5; 2888 break; 2889 case 5: 2890 audioOut.channels = 4; 2891 break; 2892 case 4: 2893 audioOut.channels = 3; 2894 break; 2895 case 3: 2896 audioOut.channels = 2; 2897 break; 2898 case 2: 2899 audioOut.channels = 1; 2900 break; 2901 default: 2902 // failed to reconfigure under any circumstances 2903 audiook = true; 2904 audioOut.channels = 0; 2905 break; 2906 } 2907 audioOut.sample_size = audioOut.channels * 2; 2908 codec_ctx->channels = audioOut.channels; 2909 } 2910 } while (!audiook); 2911 #endif 2744 2912 2745 2913 return true; 2746 2914 } -
libs/libmythtv/NuppelVideoPlayer.h
107 107 void SetVideoParams(int w, int h, double fps, int keydist, 108 108 float a = 1.33333, FrameScanType scan = kScan_Ignore); 109 109 void SetAudioParams(int bits, int channels, int samplerate); 110 void SetAudioCodec(void *ac); 110 111 void SetEffDsp(int dsprate); 111 112 void SetFileLength(int total, int frames); 112 113 void Zoom(int direction); … … 142 143 bool AtNormalSpeed(void) const { return next_normal_speed; } 143 144 bool IsDecoderThreadAlive(void) const { return decoder_thread_alive; } 144 145 bool IsNearEnd(long long framesRemaining = -1) const; 146 float GetAudioStretchFactor() { return audio_stretchfactor; } 145 147 bool PlayingSlowForPrebuffer(void) const { return m_playing_slower; } 146 148 bool HasAudioIn(void) const { return !no_audio_in; } 147 149 bool HasAudioOut(void) const { return !no_audio_out; } … … 170 172 bool Play(float speed = 1.0, bool normal = true, 171 173 bool unpauseaudio = true); 172 174 bool GetPause(void) const; 175 float GetNextPlaySpeed() { return next_play_speed; } 173 176 174 177 // Seek stuff 175 178 bool FastForward(float seconds); … … 492 495 int audio_bits; 493 496 int audio_samplerate; 494 497 float audio_stretchfactor; 498 void *audio_codec; 495 499 496 500 // Picture-in-Picture 497 501 NuppelVideoPlayer *pipplayer; -
libs/libmythtv/NuppelVideoPlayer.cpp
124 124 audioOutput(NULL), audiodevice("/dev/dsp"), 125 125 audio_channels(2), audio_bits(-1), 126 126 audio_samplerate(44100), audio_stretchfactor(1.0f), 127 audio_codec(NULL), 127 128 // Picture-in-Picture 128 129 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 129 130 // Preview window support … … 528 529 529 530 if (audioOutput) 530 531 { 531 audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate );532 audioOutput->Reconfigure(audio_bits, audio_channels, audio_samplerate, audio_codec); 532 533 errMsg = audioOutput->GetError(); 533 534 if (!errMsg.isEmpty()) 534 535 audioOutput->SetStretchFactor(audio_stretchfactor); … … 661 662 { 662 663 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 663 664 "framerate (refresh rate too low for bob deint)"); 665 //m_scan = kScan_Ignore; 666 //m_can_double = false; 664 667 FallbackDeint(); 665 668 } 666 669 } … … 1513 1516 warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) / 1514 1517 WARPAVLEN; 1515 1518 1516 //cerr << "Divergence: " << divergence << " Rate: " << rate 1517 //<< " Warpfactor: " << warpfactor << " warpfactor_avg: " 1518 //<< warpfactor_avg << endl; 1519 #if 1 1520 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1521 "Divergence: %1 " 1522 " Rate: %2" 1523 " Warpfactor: %3" 1524 " warpfactor_avg: %4") 1525 .arg(divergence) 1526 .arg(rate) 1527 .arg(warpfactor) 1528 .arg(warpfactor_avg) 1529 ); 1530 #endif 1519 1531 return divergence; 1520 1532 } 1521 1533 … … 1596 1608 if (diverge < -MAXDIVERGE) 1597 1609 { 1598 1610 // If video is way ahead of audio, adjust for it... 1599 QString dbg = QString(" Video is %1 frames ahead of audio, ")1611 QString dbg = QString("Audio is %1 frames ahead of video, ") 1600 1612 .arg(-diverge); 1601 1613 1602 1614 // Reset A/V Sync … … 1611 1623 // decoding; display the frame, but don't wait for A/V Sync. 1612 1624 videoOutput->PrepareFrame(buffer, ps); 1613 1625 videoOutput->Show(m_scan); 1614 VERBOSE(VB_PLAYBACK , LOC + dbg + "skipping A/V wait.");1626 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait."); 1615 1627 } 1616 1628 else 1617 1629 { 1618 1630 // If we are using software decoding, skip this frame altogether. 1619 VERBOSE(VB_PLAYBACK , LOC + dbg + "dropping frame.");1631 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame."); 1620 1632 } 1621 1633 } 1622 1634 else if (!using_null_videoout) … … 1625 1637 if (buffer) 1626 1638 videoOutput->PrepareFrame(buffer, ps); 1627 1639 1640 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate)); 1628 1641 videosync->WaitForFrame(avsync_adjustment); 1642 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 1629 1643 if (!resetvideo) 1630 1644 videoOutput->Show(m_scan); 1631 1645 … … 1645 1659 1646 1660 // Display the second field 1647 1661 videosync->AdvanceTrigger(); 1648 videosync->WaitForFrame( 0);1662 videosync->WaitForFrame(avsync_adjustment); 1649 1663 if (!resetvideo) 1650 1664 videoOutput->Show(kScan_Intr2ndField); 1651 1665 } … … 1657 1671 1658 1672 if (output_jmeter && output_jmeter->RecordCycleTime()) 1659 1673 { 1660 //cerr << "avsync_delay: " << avsync_delay / 1000 1661 // << ", avsync_avg: " << avsync_avg / 1000 1662 // << ", warpfactor: " << warpfactor 1663 // << ", warpfactor_avg: " << warpfactor_avg << endl; 1674 #if 1 1675 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1676 "avsync_delay: %1" 1677 ", avsync_avg: %2" 1678 ", warpfactor: %3" 1679 ", warpfactor_avg: %4") 1680 .arg(avsync_delay / 1000) 1681 .arg(avsync_avg / 1000) 1682 .arg(warpfactor) 1683 .arg(warpfactor_avg)); 1684 #endif 1664 1685 } 1665 1686 1666 1687 videosync->AdvanceTrigger(); … … 1671 1692 // If audio is way ahead of video, adjust for it... 1672 1693 // by cutting the frame rate in half for the length of this frame 1673 1694 1674 avsync_adjustment = frame_interval; 1695 //avsync_adjustment = frame_interval; 1696 avsync_adjustment = refreshrate; 1675 1697 lastsync = true; 1676 VERBOSE(VB_PLAYBACK , LOC +1677 QString(" Audio is %1 frames ahead of video,\n"1698 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1699 QString("Video is %1 frames ahead of audio,\n" 1678 1700 "\t\t\tdoubling video frame interval.").arg(diverge)); 1679 1701 } 1680 1702 1681 1703 if (audioOutput && normal_speed) 1682 1704 { 1683 1705 long long currentaudiotime = audioOutput->GetAudiotime(); 1684 #if 01685 VERBOSE(VB_PLAYBACK , QString(1706 #if 1 1707 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString( 1686 1708 "A/V timecodes audio %1 video %2 frameinterval %3 " 1687 1709 "avdel %4 avg %5 tcoffset %6") 1688 1710 .arg(currentaudiotime) … … 1968 1990 { 1969 1991 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 1970 1992 "framerate (refresh rate too low for bob deint)"); 1993 //m_scan = kScan_Ignore; 1994 //m_can_double = false; 1971 1995 FallbackDeint(); 1972 1996 } 1973 1997 } … … 2672 2696 audio_samplerate = samplerate; 2673 2697 } 2674 2698 2699 void NuppelVideoPlayer::SetAudioCodec(void* ac) 2700 { 2701 audio_codec = ac; 2702 } 2703 2675 2704 void NuppelVideoPlayer::SetEffDsp(int dsprate) 2676 2705 { 2677 2706 if (audioOutput) … … 2716 2745 tc_avcheck_framecounter++; 2717 2746 if (tc_avcheck_framecounter == 30) 2718 2747 { 2719 #define AUTO_RESYNC 12748 #define AUTO_RESYNC 0 2720 2749 #if AUTO_RESYNC 2721 2750 // something's terribly, terribly wrong. 2722 2751 if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 || -
libs/libavcodec/a52dec.c
149 149 } 150 150 } 151 151 152 static 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 162 void 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 173 void 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 186 void 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 200 int 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 212 void 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 152 293 /**** end */ 153 294 154 295 #define HEADER_SIZE 7 … … 212 353 s->inbuf_ptr += len; 213 354 buf_size -= len; 214 355 } else { 356 int chans; 215 357 flags = s->flags; 216 358 if (avctx->channels == 1) 217 359 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 } 220 366 else 221 367 flags |= A52_ADJUST_LEVEL; 222 368 level = 1; 369 chans = channels_multi(flags); 223 370 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 224 371 fail: 225 372 s->inbuf_ptr = s->inbuf; … … 229 376 for (i = 0; i < 6; i++) { 230 377 if (s->a52_block(s->state)) 231 378 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); 233 381 } 234 382 s->inbuf_ptr = s->inbuf; 235 383 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); 237 386 break; 238 387 } 239 388 } -
libs/libavcodec/ac3enc.c
1362 1362 { 1363 1363 AC3EncodeContext *s = avctx->priv_data; 1364 1364 int16_t *samples = data; 1365 // expects L C R LS RS LFE 1366 // audio format is L R LS RS C LFE 1367 static int channel_index[6] = { 0, 4, 1, 2, 3, 5 }; 1368 /* 1369 * A52->Analog->AC3Enc 1370 * 1->0->0 1371 * 3->1->2 1372 * 4->2->3 1373 * 5->3->4 1374 * 2->4->1 1375 * 0->5->5 1376 */ 1365 1377 int i, j, k, v, ch; 1366 1378 int16_t input_samples[N]; 1367 1379 int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; … … 1382 1394 /* compute input samples */ 1383 1395 memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(int16_t)); 1384 1396 sinc = s->nb_all_channels; 1385 sptr = samples + (sinc * (N/2) * i) + ch ;1397 sptr = samples + (sinc * (N/2) * i) + channel_index[ch]; 1386 1398 for(j=0;j<N/2;j++) { 1387 1399 v = *sptr; 1388 1400 input_samples[j + N/2] = v; … … 1403 1415 v = 14 - log2_tab(input_samples, N); 1404 1416 if (v < 0) 1405 1417 v = 0; 1406 exp_samples[i][ch] = v - 8;1418 exp_samples[i][ch] = v - 9; 1407 1419 lshift_tab(input_samples, N, v); 1408 1420 1409 1421 /* do the MDCT */