Ticket #1104: mythtv_ac3.17.patch
File mythtv_ac3.17.patch, 91.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
30 30 virtual ~AudioOutput() { }; 31 31 32 32 // reconfigure sound out for new params 33 virtual void Reconfigure(int audio_bits, int audio_channels, 34 int audio_samplerate, bool audio_passthru) = 0; 33 virtual void Reconfigure(int audio_bits, 34 int audio_channels, 35 int audio_samplerate, 36 bool audio_passthru, 37 void* audio_codec = NULL 38 ) = 0; 35 39 36 40 virtual void SetStretchFactor(float factor); 37 41 … … 73 77 lastError = msg; 74 78 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 75 79 } 80 void ClearError() 81 { lastError = QString::null; }; 76 82 77 83 void Warn(QString msg) 78 84 { -
libs/libmyth/audiooutputdx.h
22 22 23 23 virtual void Reset(void); 24 24 virtual void Reconfigure(int audio_bits, 25 int audio_channels, int audio_samplerate); 25 int audio_channels, 26 int audio_samplerate, 27 bool audio_passthru, 28 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 26 29 virtual void SetBlocking(bool blocking); 27 30 28 31 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
119 119 // FIXME: kedl: not sure what else could be required here? 120 120 } 121 121 122 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 123 int audio_samplerate, int audio_passthru) 122 void AudioOutputDX::Reconfigure(int audio_bits, 123 int audio_channels, 124 int audio_samplerate, 125 int audio_passthru, 126 AudioCodecMode laom 127 ) 124 128 { 125 129 if (dsbuffer) 126 130 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 virtual ~AudioOutputBase(); 25 31 26 32 // reconfigure sound out for new params 27 virtual void Reconfigure(int audio_bits, int audio_channels, 28 int audio_samplerate, bool audio_passthru); 33 virtual void Reconfigure(int audio_bits, 34 int audio_channels, 35 int audio_samplerate, 36 bool audio_passthru, 37 void* audio_codec = NULL); 29 38 30 39 // do AddSamples calls block? 31 40 virtual void SetBlocking(bool blocking); … … 109 118 110 119 float audio_stretchfactor; 111 120 AudioOutputSource source; 121 AVCodecContext *audio_codec; 112 122 113 123 bool killaudio; 114 124 … … 116 126 bool set_initial_vol; 117 127 bool buffer_output_data_for_use; // used by AudioOutputNULL 118 128 129 int configured_audio_channels; 130 119 131 private: 120 132 // resampler 121 133 bool need_resampler; … … 126 138 127 139 // timestretch 128 140 soundtouch::SoundTouch * pSoundStretch; 141 DigitalEncoder * encoder; 129 142 130 143 bool blocking; // do AddSamples calls block? 131 144 … … 141 154 142 155 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 143 156 'audiotime' and 'audiotime_updated' */ 144 intaudiotime; // timecode of audio leaving the soundcard (same units as157 long long audiotime; // timecode of audio leaving the soundcard (same units as 145 158 // timecodes) ... 146 159 struct timeval audiotime_updated; // ... which was last updated at this time 147 160 148 161 /* Audio circular buffer */ 149 162 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 150 163 int raud, waud; /* read and write positions */ 151 intaudbuf_timecode; /* timecode of audio most recently placed into164 long long audbuf_timecode; /* timecode of audio most recently placed into 152 165 buffer */ 153 166 154 167 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, … … 31 368 current_seconds = -1; 32 369 source_bitrate = -1; 33 370 audio_stretchfactor = 1.0; 371 audio_codec = NULL; 34 372 pSoundStretch = NULL; 373 encoder = NULL; 35 374 blocking = false; 36 375 this->source = source; 37 376 this->set_initial_vol = set_initial_vol; 38 377 soundcard_buffer_size = 0; 39 378 buffer_output_data_for_use = false; // used by AudioOutputNULL 379 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 40 380 41 42 381 src_ctx = NULL; 43 382 44 383 // You need to call the next line from your concrete class. … … 80 419 VERBOSE(VB_GENERAL, QString("Using time stretch %1") 81 420 .arg(audio_stretchfactor)); 82 421 pSoundStretch = new soundtouch::SoundTouch(); 83 pSoundStretch->setSampleRate(audio_samplerate); 84 pSoundStretch->setChannels(audio_channels); 422 if (audio_codec) 423 { 424 if (!encoder) 425 { 426 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 427 encoder = new DigitalEncoder(); 428 if (!encoder->Init(audio_codec->codec_id, 429 audio_codec->bit_rate, 430 audio_codec->sample_rate, 431 audio_codec->channels 432 )) 433 { 434 // eeks 435 delete encoder; 436 encoder = NULL; 437 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 438 } 439 } 440 } 441 if (encoder) 442 { 443 pSoundStretch->setSampleRate(audio_codec->sample_rate); 444 pSoundStretch->setChannels(audio_codec->channels); 445 } 446 else 447 { 448 pSoundStretch->setSampleRate(audio_samplerate); 449 pSoundStretch->setChannels(audio_channels); 450 } 85 451 86 452 pSoundStretch->setTempo(audio_stretchfactor); 87 453 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 104 470 } 105 471 106 472 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 107 int laudio_samplerate, bool laudio_passthru) 473 int laudio_samplerate, bool laudio_passthru, 474 void* laudio_codec) 108 475 { 476 int codec_id = CODEC_ID_NONE; 477 int lcodec_id = CODEC_ID_NONE; 478 int lcchannels = 0; 479 int cchannels = 0; 480 if (laudio_codec) 481 { 482 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 483 laudio_bits = 16; 484 laudio_channels = 2; 485 laudio_samplerate = 48000; 486 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 487 } 488 if (audio_codec) 489 { 490 codec_id = audio_codec->codec_id; 491 cchannels = ((AVCodecContext*)audio_codec)->channels; 492 } 493 ClearError(); 109 494 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 110 laudio_samplerate == audio_samplerate && 111 laudio_passthru == audio_passthru && !need_resampler) 495 laudio_samplerate == audio_samplerate && !need_resampler && 496 laudio_passthru == audio_passthru && 497 lcodec_id == codec_id && lcchannels == cchannels) 112 498 return; 113 499 114 500 KillAudio(); … … 120 506 waud = raud = 0; 121 507 audio_actually_paused = false; 122 508 509 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 123 510 audio_channels = laudio_channels; 124 511 audio_bits = laudio_bits; 125 512 audio_samplerate = laudio_samplerate; 513 audio_codec = (AVCodecContext*)laudio_codec; 126 514 audio_passthru = laudio_passthru; 127 515 if (audio_bits != 8 && audio_bits != 16) 128 516 { … … 141 529 142 530 numlowbuffer = 0; 143 531 144 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ")145 .arg(audiodevice) );532 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2 sr %3") 533 .arg(audiodevice).arg(audio_channels).arg(audio_samplerate)); 146 534 147 535 // Actually do the device specific open call 148 536 if (!OpenDevice()) 149 537 { 150 VERBOSE(VB_AUDIO, "Aborting reconfigure");151 538 pthread_mutex_unlock(&avsync_lock); 152 539 pthread_mutex_unlock(&audio_buflock); 540 if (GetError().isEmpty()) 541 Error("Aborting reconfigure"); 542 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 153 543 return; 154 544 } 155 545 … … 171 561 current_seconds = -1; 172 562 source_bitrate = -1; 173 563 564 // NOTE: this wont do anything as above samplerate vars are set equal 174 565 // Check if we need the resampler 175 566 if (audio_samplerate != laudio_samplerate) 176 567 { … … 194 585 } 195 586 196 587 VERBOSE(VB_AUDIO, QString("Audio Stretch Factor: %1").arg(audio_stretchfactor)); 588 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 589 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 197 590 198 SetStretchFactorLocked(audio_stretchfactor); 199 if (pSoundStretch) 591 if (redo_stretch) 200 592 { 201 pSoundStretch->setSampleRate(audio_samplerate); 202 pSoundStretch->setChannels(audio_channels); 593 float laudio_stretchfactor = audio_stretchfactor; 594 delete pSoundStretch; 595 pSoundStretch = NULL; 596 audio_stretchfactor = 0.0; 597 SetStretchFactorLocked(laudio_stretchfactor); 203 598 } 599 else 600 { 601 SetStretchFactorLocked(audio_stretchfactor); 602 if (pSoundStretch) 603 { 604 // if its passthru then we need to reencode 605 if (audio_codec) 606 { 607 if (!encoder) 608 { 609 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 610 encoder = new DigitalEncoder(); 611 if (!encoder->Init(audio_codec->codec_id, 612 audio_codec->bit_rate, 613 audio_codec->sample_rate, 614 audio_codec->channels 615 )) 616 { 617 // eeks 618 delete encoder; 619 encoder = NULL; 620 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 621 } 622 } 623 } 624 if (encoder) 625 { 626 pSoundStretch->setSampleRate(audio_codec->sample_rate); 627 pSoundStretch->setChannels(audio_codec->channels); 628 } 629 else 630 { 631 pSoundStretch->setSampleRate(audio_samplerate); 632 pSoundStretch->setChannels(audio_channels); 633 } 634 } 635 } 204 636 205 637 // Setup visualisations, zero the visualisations buffers 206 638 prepareVisuals(); … … 246 678 pSoundStretch = NULL; 247 679 } 248 680 681 if (encoder) 682 { 683 delete encoder; 684 encoder = NULL; 685 } 686 249 687 CloseDevice(); 250 688 251 689 killAudioLock.unlock(); … … 259 697 260 698 void AudioOutputBase::Pause(bool paused) 261 699 { 700 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 262 701 pauseaudio = paused; 263 702 audio_actually_paused = false; 264 703 } … … 339 778 The reason is that computing 'audiotime' requires acquiring the audio 340 779 lock, which the video thread should not do. So, we call 'SetAudioTime()' 341 780 from the audio thread, and then call this from the video thread. */ 342 intret;781 long long ret; 343 782 struct timeval now; 344 783 345 784 if (audiotime == 0) … … 351 790 352 791 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 353 792 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 354 ret = ( int)(ret * audio_stretchfactor);793 ret = (long long)(ret * audio_stretchfactor); 355 794 795 #if 1 796 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 797 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 798 .arg(now.tv_sec).arg(now.tv_usec) 799 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 800 .arg(ret) 801 .arg(audiotime) 802 .arg(audio_stretchfactor) 803 ); 804 #endif 805 356 806 ret += audiotime; 357 807 358 808 pthread_mutex_unlock(&avsync_lock); 359 return ret;809 return (int)ret; 360 810 } 361 811 362 812 void AudioOutputBase::SetAudiotime(void) … … 393 843 // include algorithmic latencies 394 844 if (pSoundStretch) 395 845 { 846 // if encoder is active, then use its idea of audiobytes 847 //size_t abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 848 849 // add the effect of any unused but processed samples, AC3 reencode does this 850 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 396 851 // add the effect of unprocessed samples in time stretch algo 397 852 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 398 853 audio_bytes_per_sample) / audio_stretchfactor); 399 854 } 400 855 401 856 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 402 857 (audio_bytes_per_sample * effdspstretched)); 403 858 404 859 gettimeofday(&audiotime_updated, NULL); 860 #if 1 861 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 862 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 863 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 864 .arg(audiotime) 865 .arg(audbuf_timecode) 866 .arg(totalbuffer) 867 .arg(soundcard_buffer) 868 .arg(effdspstretched) 869 .arg(audio_bytes_per_sample) 870 .arg(audio_stretchfactor) 871 ); 872 #endif 405 873 406 874 pthread_mutex_unlock(&avsync_lock); 407 875 pthread_mutex_unlock(&audio_buflock); … … 461 929 // NOTE: This function is not threadsafe 462 930 463 931 int afree = audiofree(true); 464 int len = samples * audio_bytes_per_sample;932 int len = samples * (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 465 933 466 934 // Check we have enough space to write the data 467 935 if (need_resampler && src_ctx) 468 936 len = (int)ceilf(float(len) * src_data.src_ratio); 469 937 if ((len > afree) && !blocking) 938 { 939 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("AddSamples FAILED bytes=%1, used=%2, free=%3, timecode=%4") 940 .arg(len) 941 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 470 942 return false; // would overflow 943 } 471 944 472 945 // resample input if necessary 473 946 if (need_resampler && src_ctx) … … 501 974 502 975 int AudioOutputBase::WaitForFreeSpace(int samples) 503 976 { 504 int len = samples * audio_bytes_per_sample; 977 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 978 int len = samples * abps; 505 979 int afree = audiofree(false); 506 980 507 981 while (len > afree) 508 982 { 509 983 if (blocking) 510 984 { 511 VERBOSE(VB_AUDIO , "Waiting for free space");985 VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Waiting for free space"); 512 986 // wait for more space 513 987 pthread_cond_wait(&audio_bufsig, &audio_buflock); 514 988 afree = audiofree(false); 515 989 } 516 990 else 517 991 { 518 VERBOSE(VB_IMPORTANT, "Audio buffer overflow, audio data lost!"); 519 samples = afree / audio_bytes_per_sample; 520 len = samples * audio_bytes_per_sample; 992 VERBOSE(VB_IMPORTANT, 993 QString("Audio buffer overflow, %1 audio samples lost!") 994 .arg(samples-afree / abps)); 995 samples = afree / abps; 996 len = samples * abps; 521 997 if (src_ctx) 522 998 { 523 999 int error = src_reset(src_ctx); … … 542 1018 543 1019 int afree = audiofree(false); 544 1020 545 VERBOSE(VB_AUDIO, QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 546 .arg(samples * audio_bytes_per_sample) 547 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 1021 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 1022 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5") 1023 .arg(samples) 1024 .arg(samples * abps) 1025 .arg(AUDBUFSIZE-afree).arg(afree).arg(LONGLONGCONVERT timecode)); 548 1026 549 1027 len = WaitForFreeSpace(samples); 550 1028 … … 581 1059 582 1060 if (pSoundStretch) 583 1061 { 1062 584 1063 // does not change the timecode, only the number of samples 585 1064 // back to orig pos 586 1065 org_waud = waud; 587 1066 int bdiff = AUDBUFSIZE - org_waud; 588 int nSamplesToEnd = bdiff/a udio_bytes_per_sample;1067 int nSamplesToEnd = bdiff/abps; 589 1068 if (bdiff < len) 590 1069 { 591 1070 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 592 1071 org_waud), nSamplesToEnd); 593 1072 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 594 (len - bdiff) / a udio_bytes_per_sample);1073 (len - bdiff) / abps); 595 1074 } 596 1075 else 597 1076 { 598 1077 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 599 org_waud), len / a udio_bytes_per_sample);1078 org_waud), len / abps); 600 1079 } 601 1080 602 int newLen = 0; 603 int nSamples; 604 len = WaitForFreeSpace(pSoundStretch->numSamples() * 605 audio_bytes_per_sample); 606 do 1081 if (encoder) 607 1082 { 608 int samplesToGet = len/audio_bytes_per_sample; 609 if (samplesToGet > nSamplesToEnd) 1083 // pull out a packet's worth and reencode it until we dont have enough 1084 // for any more packets 1085 soundtouch::SAMPLETYPE* temp_buff = 1086 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 1087 size_t frameSize = encoder->FrameSize()/abps; 1088 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1089 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1090 .arg(frameSize) 1091 .arg(encoder->FrameSize()) 1092 .arg(pSoundStretch->numSamples()) 1093 ); 1094 // process the same number of samples as it creates a full encoded buffer 1095 // just like before 1096 while (pSoundStretch->numSamples() >= frameSize) 610 1097 { 611 samplesToGet = nSamplesToEnd; 1098 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 1099 int amount = encoder->Encode(temp_buff); 1100 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1101 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1102 .arg(amount) 1103 .arg(got) 1104 .arg(pSoundStretch->numSamples()) 1105 ); 1106 if (amount == 0) 1107 continue; 1108 //len = WaitForFreeSpace(amount); 1109 char * ob = encoder->GetOutBuff(); 1110 if (amount >= bdiff) 1111 { 1112 memcpy(audiobuffer + org_waud, ob, bdiff); 1113 ob += bdiff; 1114 amount -= bdiff; 1115 org_waud = 0; 1116 } 1117 if (amount > 0) 1118 memcpy(audiobuffer + org_waud, ob, amount); 1119 bdiff = AUDBUFSIZE - amount; 1120 org_waud += amount; 612 1121 } 613 614 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 615 (audiobuffer + org_waud), samplesToGet); 616 if (nSamples == nSamplesToEnd) 1122 } 1123 else 1124 { 1125 int newLen = 0; 1126 int nSamples; 1127 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1128 audio_bytes_per_sample); 1129 do 617 1130 { 618 org_waud = 0; 619 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 620 } 621 else 622 { 623 org_waud += nSamples * audio_bytes_per_sample; 624 nSamplesToEnd -= nSamples; 625 } 1131 int samplesToGet = len/audio_bytes_per_sample; 1132 if (samplesToGet > nSamplesToEnd) 1133 { 1134 samplesToGet = nSamplesToEnd; 1135 } 626 1136 627 newLen += nSamples * audio_bytes_per_sample; 628 len -= nSamples * audio_bytes_per_sample; 629 } while (nSamples > 0); 1137 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 1138 (audiobuffer + org_waud), samplesToGet); 1139 if (nSamples == nSamplesToEnd) 1140 { 1141 org_waud = 0; 1142 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1143 } 1144 else 1145 { 1146 org_waud += nSamples * audio_bytes_per_sample; 1147 nSamplesToEnd -= nSamples; 1148 } 1149 1150 newLen += nSamples * audio_bytes_per_sample; 1151 len -= nSamples * audio_bytes_per_sample; 1152 } while (nSamples > 0); 1153 } 630 1154 } 631 1155 632 1156 waud = org_waud; … … 696 1220 space_on_soundcard = getSpaceOnSoundcard(); 697 1221 698 1222 if (space_on_soundcard != last_space_on_soundcard) { 699 VERBOSE(VB_AUDIO , QString("%1 bytes free on soundcard")1223 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("%1 bytes free on soundcard") 700 1224 .arg(space_on_soundcard)); 701 1225 last_space_on_soundcard = space_on_soundcard; 702 1226 } … … 709 1233 WriteAudio(zeros, fragment_size); 710 1234 } else { 711 1235 // this should never happen now -dag 712 VERBOSE(VB_AUDIO ,1236 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 713 1237 QString("waiting for space on soundcard " 714 1238 "to write zeros: have %1 need %2") 715 1239 .arg(space_on_soundcard).arg(fragment_size)); … … 745 1269 if (fragment_size > audiolen(true)) 746 1270 { 747 1271 if (audiolen(true) > 0) // only log if we're sending some audio 748 VERBOSE(VB_AUDIO ,1272 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 749 1273 QString("audio waiting for buffer to fill: " 750 1274 "have %1 want %2") 751 1275 .arg(audiolen(true)).arg(fragment_size)); 752 1276 753 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1277 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 754 1278 pthread_mutex_lock(&audio_buflock); 755 1279 pthread_cond_broadcast(&audio_bufsig); 756 1280 pthread_mutex_unlock(&audio_buflock); … … 764 1288 if (fragment_size > space_on_soundcard) 765 1289 { 766 1290 if (space_on_soundcard != last_space_on_soundcard) { 767 VERBOSE(VB_AUDIO ,1291 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 768 1292 QString("audio waiting for space on soundcard: " 769 1293 "have %1 need %2") 770 1294 .arg(space_on_soundcard).arg(fragment_size)); … … 826 1350 827 1351 /* update raud */ 828 1352 raud = (raud + fragment_size) % AUDBUFSIZE; 829 VERBOSE(VB_AUDIO, "Broadcasting free space avail");1353 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, "Broadcasting free space avail"); 830 1354 pthread_cond_broadcast(&audio_bufsig); 831 1355 832 1356 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
82 82 } 83 83 else 84 84 { 85 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 86 buffer_time = 500000; // .5 seconds 85 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 86 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 87 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 88 buffer_time = 100000; // .5 seconds 87 89 period_time = buffer_time / 4; // 4 interrupts per buffer 88 90 } 89 91 … … 155 157 156 158 tmpbuf = aubuf; 157 159 158 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")160 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 159 161 .arg(size).arg(frames)); 160 162 161 163 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 … … 285 312 286 313 287 314 315 #ifdef MULTICHANNEL 288 316 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 289 317 // routine 290 318 // 291 319 // The best position is determined as the position where the two overlapped 292 320 // sample sequences are 'most alike', in terms of the highest cross-correlation 293 321 // value over the overlapping period 322 uint TDStretch::seekBestOverlapPositionMulti(const SAMPLETYPE *refPos) 323 { 324 uint bestOffs; 325 LONG_SAMPLETYPE bestCorr, corr; 326 uint i; 327 328 // Slopes the amplitudes of the 'midBuffer' samples 329 precalcCorrReference(); 330 331 bestCorr = INT_MIN; 332 bestOffs = 0; 333 334 // Scans for the best correlation value by testing each possible position 335 // over the permitted range. 336 for (i = 0; i < seekLength; i ++) 337 { 338 // Calculates correlation value for the mixing position corresponding 339 // to 'i' 340 corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer); 341 342 // Checks for the highest correlation value 343 if (corr > bestCorr) 344 { 345 bestCorr = corr; 346 bestOffs = i; 347 } 348 } 349 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 350 clearCrossCorrState(); 351 352 return bestOffs; 353 } 354 355 356 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 357 // routine 358 // 359 // The best position is determined as the position where the two overlapped 360 // sample sequences are 'most alike', in terms of the highest cross-correlation 361 // value over the overlapping period 362 uint TDStretch::seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos) 363 { 364 uint j; 365 uint bestOffs; 366 LONG_SAMPLETYPE bestCorr, corr; 367 uint scanCount, corrOffset, tempOffset; 368 369 // Slopes the amplitude of the 'midBuffer' samples 370 precalcCorrReference(); 371 372 bestCorr = INT_MIN; 373 bestOffs = 0; 374 corrOffset = 0; 375 tempOffset = 0; 376 377 // Scans for the best correlation value using four-pass hierarchical search. 378 // 379 // The look-up table 'scans' has hierarchical position adjusting steps. 380 // In first pass the routine searhes for the highest correlation with 381 // relatively coarse steps, then rescans the neighbourhood of the highest 382 // correlation with better resolution and so on. 383 for (scanCount = 0;scanCount < 4; scanCount ++) 384 { 385 j = 0; 386 while (scanOffsets[scanCount][j]) 387 { 388 tempOffset = corrOffset + scanOffsets[scanCount][j]; 389 if (tempOffset >= seekLength) break; 390 391 // Calculates correlation value for the mixing position corresponding 392 // to 'tempOffset' 393 corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer); 394 395 // Checks for the highest correlation value 396 if (corr > bestCorr) 397 { 398 bestCorr = corr; 399 bestOffs = tempOffset; 400 } 401 j ++; 402 } 403 corrOffset = bestOffs; 404 } 405 // clear cross correlation routine state if necessary (is so e.g. in MMX routines). 406 clearCrossCorrState(); 407 408 return bestOffs; 409 } 410 #endif 411 412 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the 413 // routine 414 // 415 // The best position is determined as the position where the two overlapped 416 // sample sequences are 'most alike', in terms of the highest cross-correlation 417 // value over the overlapping period 294 418 uint TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos) 295 419 { 296 420 uint bestOffs; … … 512 636 void TDStretch::setChannels(uint numChannels) 513 637 { 514 638 if (channels == numChannels) return; 639 #ifdef MULTICHANNEL 640 assert(numChannels >= 1 && numChannels <= MULTICHANNEL); 641 #else 515 642 assert(numChannels == 1 || numChannels == 2); 643 #endif 516 644 517 645 channels = numChannels; 518 646 inputBuffer.setChannels(channels); … … 635 763 /// Set new overlap length parameter & reallocate RefMidBuffer if necessary. 636 764 void TDStretch::acceptNewOverlapLength(uint newOverlapLength) 637 765 { 638 uint prevOvl;639 640 prevOvl = overlapLength;641 766 overlapLength = newOverlapLength; 642 767 643 if (overlapLength > prevOvl)768 if (overlapLength*channels > midBufferLength) 644 769 { 645 delete[] pMidBuffer; 646 delete[] pRefMidBufferUnaligned; 770 if (midBufferLength) 771 { 772 delete[] pMidBuffer; 773 delete[] pRefMidBufferUnaligned; 774 midBufferLength = 0; 775 } 647 776 648 pMidBuffer = new SAMPLETYPE[overlapLength * 2]; 777 midBufferLength = overlapLength * channels; 778 pMidBuffer = new SAMPLETYPE[midBufferLength]; 649 779 bMidBufferDirty = TRUE; 650 780 clearMidBuffer(); 651 781 652 pRefMidBufferUnaligned = new SAMPLETYPE[ 2 * overlapLength + 16 / sizeof(SAMPLETYPE)];782 pRefMidBufferUnaligned = new SAMPLETYPE[midBufferLength + 16 / sizeof(SAMPLETYPE)]; 653 783 // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency 654 784 pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16); 655 785 } … … 718 848 719 849 #ifdef INTEGER_SAMPLES 720 850 851 #ifdef MULTICHANNEL 721 852 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 722 853 // is faster to calculate 854 void TDStretch::precalcCorrReference() 855 { 856 int i,j; 857 int temp, temp2; 858 short *src = pMidBuffer; 859 short *dest = pRefMidBuffer; 860 861 for (i=0 ; i < (int)overlapLength ;i ++) 862 { 863 temp = i * (overlapLength - i); 864 865 for(j=0;j<channels;j++) 866 { 867 temp2 = (*src++ * temp) / slopingDivider; 868 *dest++ = (short)(temp2); 869 } 870 } 871 } 872 #endif 873 874 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation 875 // is faster to calculate 723 876 void TDStretch::precalcCorrReferenceStereo() 724 877 { 725 878 int i, cnt2; … … 772 925 } 773 926 } 774 927 928 #ifdef MULTICHANNEL 929 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo' 930 // version of the routine. 931 void TDStretch::overlapMulti(short *output, const short *input) const 932 { 933 int i,j; 934 short temp; 935 //uint cnt2; 936 const short *ip = input; 937 short *op = output; 938 const short *md = pMidBuffer; 775 939 940 for (i = 0; i < (int)overlapLength ; i ++) 941 { 942 temp = (short)(overlapLength - i); 943 for(j=0;j<channels;j++) 944 *op++ = (*ip++ * i + *md++ * temp ) / overlapLength; 945 } 946 } 947 #endif 948 949 776 950 /// Calculates overlap period length in samples. 777 951 /// Integer version rounds overlap length to closest power of 2 778 952 /// for a divide scaling operation. … … 824 998 return corr; 825 999 } 826 1000 1001 #ifdef MULTICHANNEL 1002 long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const 1003 { 1004 long corr; 1005 uint i; 1006 1007 corr = 0; 1008 for (i = channels; i < channels * overlapLength; i++) 1009 { 1010 corr += (mixingPos[i] * compare[i]) >> overlapDividerBits; 1011 } 1012 1013 return corr; 1014 } 1015 #endif 1016 827 1017 #endif // INTEGER_SAMPLES 828 1018 829 1019 ////////////////////////////////////////////////////////////////////////////// … … 931 1121 return corr; 932 1122 } 933 1123 934 #endif // FLOAT_SAMPLES 935 No newline at end of file 1124 #endif // FLOAT_SAMPLES -
libs/libmythsoundtouch/TDStretch.h
48 48 #include "RateTransposer.h" 49 49 #include "FIFOSamplePipe.h" 50 50 51 #ifdef MULTICHANNEL 52 #define USE_MULTI_MMX 53 #endif 54 51 55 namespace soundtouch 52 56 { 53 57 … … 100 104 SAMPLETYPE *pMidBuffer; 101 105 SAMPLETYPE *pRefMidBuffer; 102 106 SAMPLETYPE *pRefMidBufferUnaligned; 107 uint midBufferLength; 103 108 uint overlapLength; 104 109 uint overlapDividerBits; 105 110 uint slopingDivider; … … 123 128 virtual void clearCrossCorrState(); 124 129 void calculateOverlapLength(uint overlapMs); 125 130 131 #ifdef MULTICHANNEL 132 virtual LONG_SAMPLETYPE calcCrossCorrMulti(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 133 #endif 126 134 virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 127 135 virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const; 128 136 137 #ifdef MULTICHANNEL 138 virtual uint seekBestOverlapPositionMulti(const SAMPLETYPE *refPos); 139 virtual uint seekBestOverlapPositionMultiQuick(const SAMPLETYPE *refPos); 140 #endif 129 141 virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos); 130 142 virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos); 131 143 virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos); 132 144 virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos); 133 145 uint seekBestOverlapPosition(const SAMPLETYPE *refPos); 134 146 147 #ifdef MULTICHANNEL 148 virtual void overlapMulti(SAMPLETYPE *output, const SAMPLETYPE *input) const; 149 #endif 135 150 virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const; 136 151 virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const; 137 152 138 153 void clearMidBuffer(); 139 154 void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const; 140 155 156 #ifdef MULTICHANNEL 157 void precalcCorrReference(); 158 #endif 141 159 void precalcCorrReferenceMono(); 142 160 void precalcCorrReferenceStereo(); 143 161 … … 225 243 class TDStretchMMX : public TDStretch 226 244 { 227 245 protected: 246 #ifdef USE_MULTI_MMX 247 #ifdef MULTICHANNEL 248 long calcCrossCorrMulti(const short *mixingPos, const short *compare) const; 249 #endif 250 #endif 228 251 long calcCrossCorrStereo(const short *mixingPos, const short *compare) const; 229 252 virtual void overlapStereo(short *output, const short *input) const; 230 253 virtual void clearCrossCorrState(); … … 237 260 class TDStretch3DNow : public TDStretch 238 261 { 239 262 protected: 263 #ifdef MULTICHANNEL 264 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 265 #endif 240 266 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 241 267 }; 242 268 #endif /// ALLOW_3DNOW … … 247 273 class TDStretchSSE : public TDStretch 248 274 { 249 275 protected: 276 #ifdef MULTICHANNEL 277 //double calcCrossCorrMulti(const float *mixingPos, const float *compare) const; 278 #endif 250 279 double calcCrossCorrStereo(const float *mixingPos, const float *compare) const; 251 280 }; 252 281 -
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"); … … 2125 2157 setUseLabel(false); 2126 2158 2127 2159 addChild(AudioOutputDevice()); 2160 #if 0 2161 ConfigurationGroup *hg = new HorizontalConfigurationGroup(false, false); 2162 ConfigurationGroup* settingsLeft = new VerticalConfigurationGroup(false,false); 2163 settingsLeft->addChild(AC3PassThrough()); 2164 #ifdef CONFIG_DTS 2165 settingsLeft->addChild(DTSPassThrough()); 2166 #endif 2167 settingsLeft->addChild(AggressiveBuffer()); 2168 hg->addChild(settingsLeft); 2169 2170 ConfigurationGroup* settingsRight = new VerticalConfigurationGroup(false,false); 2171 settingsRight->addChild(MaxAudioChannels()); 2172 hg->addChild(settingsRight); 2173 2174 addChild(hg); 2175 #else 2128 2176 addChild(AC3PassThrough()); 2129 2177 #ifdef CONFIG_DTS 2130 2178 addChild(DTSPassThrough()); 2131 2179 #endif 2132 2180 addChild(AggressiveBuffer()); 2181 addChild(MaxAudioChannels()); 2182 #endif 2133 2183 2134 2184 Setting* volumeControl = MythControlsVolume(); 2135 2185 addChild(volumeControl); -
programs/mythtranscode/transcode.cpp
46 46 47 47 // reconfigure sound out for new params 48 48 virtual void Reconfigure(int audio_bits, int audio_channels, 49 int audio_samplerate, bool audio_passthru) 49 int audio_samplerate, bool audio_passthru, 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
243 243 bool allow_ac3_passthru; 244 244 bool allow_dts_passthru; 245 245 bool disable_passthru; 246 int max_channels; 246 247 247 248 AudioInfo audioIn; 248 249 AudioInfo audioOut; -
libs/libmythtv/avformatdecoder.cpp
39 39 #define MAX_AC3_FRAME_SIZE 6144 40 40 41 41 /** Set to zero to allow any number of AC3 channels. */ 42 #define MAXCHANNELSELECT 1 43 #if MAXCHANNELSELECT 44 #define MAX_OUTPUT_CHANNELS compiler error 45 #else 42 46 #define MAX_OUTPUT_CHANNELS 2 47 #endif 43 48 44 49 static int dts_syncinfo(uint8_t *indata_ptr, int *flags, 45 50 int *sample_rate, int *bit_rate); … … 290 295 #ifdef CONFIG_DTS 291 296 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 292 297 #endif 298 max_channels = gContext->GetNumSetting("MaxChannels", 2); 293 299 294 300 audioIn.sample_size = -32; // force SetupAudioStream to run once 295 301 ttd = GetNVP()->GetTeletextDecoder(); … … 411 417 framesPlayed = lastKey; 412 418 framesRead = lastKey; 413 419 420 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") 421 .arg(desiredFrame) 422 .arg(fps) 423 .arg(ts) 424 .arg(discardFrames) 425 .arg(framesPlayed) 426 .arg(st->cur_dts) 427 .arg(adj_cur_dts) 428 .arg(newts) 429 .arg(frameseekadjust) 430 ); 431 414 432 int normalframes = desiredFrame - framesPlayed; 415 433 434 #if 0 435 if (!exactseeks) 436 normalframes = 0; 437 #endif 438 416 439 SeekReset(lastKey, normalframes, discardFrames, discardFrames); 417 440 418 441 if (discardFrames) … … 781 804 782 805 fmt->flags &= ~AVFMT_NOFILE; 783 806 807 #if 1 808 if ((m_playbackinfo) || livetv || watchingrecording) 809 { 810 const char *name = ic->av_class->item_name(ic); 811 VERBOSE(VB_GENERAL, QString("libavformat type %1").arg(name)); 812 } 813 #endif 814 815 //struct timeval one, two, res; 816 //gettimeofday(&one, NULL); 817 784 818 if (!ringBuffer->isDVD()) 785 819 av_estimate_timings(ic); 786 820 … … 791 825 if (-1 == ret) 792 826 return ret; 793 827 828 // make sure its at the real start due to av_find_stream_info reading 829 ret = av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BACKWARD); 830 if (ret < 0) 831 av_seek_frame(ic, -1, 0, AVSEEK_FLAG_BYTE); // reposition to start of stream 832 794 833 // Select some starting audio and subtitle tracks. 795 834 // TODO do we need this? They will be called by GetFrame() anyway... 796 835 autoSelectAudioTrack(); … … 813 852 // If we don't have a position map, set up ffmpeg for seeking 814 853 if (!recordingHasPositionMap) 815 854 { 855 const char *name = ic->av_class->item_name(ic); 816 856 VERBOSE(VB_PLAYBACK, LOC + 817 "Recording has no position -- using libavformat seeking.");857 QString("Recording has no position -- using libavformat seeking. %1").arg(name)); 818 858 int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; 819 859 820 860 if (dur > 0) … … 859 899 QString("Successfully opened decoder for file: " 860 900 "\"%1\". novideo(%2)").arg(filename).arg(novideo)); 861 901 902 // set initial position correctly 903 //DoFastForward(0, true); 904 862 905 // Return true if recording has position map 863 906 return recordingHasPositionMap; 864 907 } … … 1096 1139 <<") already open, leaving it alone."); 1097 1140 } 1098 1141 //assert(enc->codec_id); 1142 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1143 #if 0 1144 if (enc->channels > 2) 1145 enc->channels = 2; 1146 #endif 1099 1147 1148 #if 0 1100 1149 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1101 1150 if (enc->codec_id == CODEC_ID_DTS) 1102 1151 { … … 1105 1154 // enc->bit_rate = what??; 1106 1155 } 1107 1156 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1157 #endif 1108 1158 1109 1159 bitrate += enc->bit_rate; 1110 1160 break; … … 1605 1655 { 1606 1656 long long startpos = pkt->pos; 1607 1657 1608 VERBOSE(VB_PLAYBACK , LOC +1658 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1609 1659 QString("positionMap[ %1 ] == %2.") 1610 1660 .arg(prevgoppos / keyframedist) 1611 1661 .arg((int)startpos)); … … 2364 2414 2365 2415 AVStream *curstream = ic->streams[pkt->stream_index]; 2366 2416 2417 #if 0 2418 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("timecode pts:%1 dts:%2 codec:%3") 2419 .arg(pkt->pts) 2420 .arg(pkt->dts) 2421 .arg((curstream && curstream->codec)?curstream->codec->codec_type:-1) 2422 ); 2423 #endif 2424 2367 2425 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 2368 2426 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 2369 2427 … … 2484 2542 if (!curstream->codec->channels) 2485 2543 { 2486 2544 QMutexLocker locker(&avcodeclock); 2545 #if MAXCHANNELSELECT 2546 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 2547 curstream->codec->cqp = max_channels; 2548 curstream->codec->channels = audioOut.channels; 2549 #else 2487 2550 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 2551 #endif 2488 2552 ret = avcodec_decode_audio( 2489 2553 curstream->codec, audioSamples, 2490 2554 &data_size, ptr, len); … … 2535 2599 { 2536 2600 AVCodecContext *ctx = curstream->codec; 2537 2601 2602 #if MAXCHANNELSELECT 2538 2603 if ((ctx->channels == 0) || 2604 (ctx->channels > audioOut.channels)) 2605 ctx->channels = audioOut.channels; 2606 #else 2607 if ((ctx->channels == 0) || 2539 2608 (ctx->channels > MAX_OUTPUT_CHANNELS)) 2540 2609 ctx->channels = MAX_OUTPUT_CHANNELS; 2610 #endif 2541 2611 2542 2612 ret = avcodec_decode_audio( 2543 2613 ctx, audioSamples, &data_size, ptr, len); … … 2573 2643 (curstream->codec->channels * 2) / 2574 2644 curstream->codec->sample_rate); 2575 2645 2646 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("audio timecode %1 %2 %3 %4") 2647 .arg(pkt->pts) 2648 .arg(pkt->dts) 2649 .arg(temppts).arg(lastapts)); 2576 2650 GetNVP()->AddAudioData((char *)audioSamples, data_size, 2577 2651 temppts); 2578 2652 … … 2673 2747 else 2674 2748 temppts = lastvpts; 2675 2749 2750 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + QString("video timecode %1 %2 %3 %4") 2751 .arg(pkt->pts) 2752 .arg(pkt->dts) 2753 .arg(temppts).arg(lastvpts)); 2676 2754 /* XXX: Broken. 2677 2755 if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && 2678 2756 context->height == picframe->height) … … 2769 2847 2770 2848 void AvFormatDecoder::SetDisablePassThrough(bool disable) 2771 2849 { 2850 #if MAXCHANNELSELECT 2851 // can only disable never reenable as once tiemstretch is on its on for the session 2852 if (disable_passthru) 2853 return; 2854 #endif 2772 2855 if (selectedAudioStream.av_stream_index < 0) 2773 2856 { 2774 2857 disable_passthru = disable; 2775 2858 return; 2776 2859 } 2777 2860 2778 2861 if (disable != disable_passthru) 2779 2862 { 2780 2863 disable_passthru = disable; … … 2801 2884 AVCodecContext *codec_ctx = NULL; 2802 2885 AudioInfo old_in = audioIn; 2803 2886 AudioInfo old_out = audioOut; 2887 bool using_passthru = false; 2804 2888 2805 2889 if ((currentAudioTrack >= 0) && 2806 2890 (selectedAudioStream.av_stream_index <= ic->nb_streams) && … … 2808 2892 { 2809 2893 assert(curstream); 2810 2894 assert(curstream->codec); 2811 codec_ctx = curstream->codec; 2895 codec_ctx = curstream->codec; 2812 2896 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 2813 !disable_passthru &&2814 2897 (codec_ctx->codec_id == CODEC_ID_AC3)); 2815 2898 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 2816 !disable_passthru &&2817 2899 (codec_ctx->codec_id == CODEC_ID_DTS)); 2900 using_passthru = do_ac3_passthru || do_dts_passthru; 2818 2901 info = AudioInfo(codec_ctx->codec_id, 2819 2902 codec_ctx->sample_rate, codec_ctx->channels, 2820 do_ac3_passthru || do_dts_passthru);2903 using_passthru && !disable_passthru); 2821 2904 } 2822 2905 2823 2906 if (info == audioIn) 2824 2907 return false; // no change 2825 2908 2909 QString ptmsg = ""; 2910 if (using_passthru) 2911 { 2912 ptmsg = QString(" using passthru"); 2913 } 2826 2914 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 2827 QString("audio track #%1").arg(currentAudioTrack+1)); 2915 QString("audio track #%1") 2916 .arg(currentAudioTrack+1) 2917 + ptmsg ); 2828 2918 2829 2919 audioOut = audioIn = info; 2920 #if MAXCHANNELSELECT 2921 if (using_passthru) 2922 #else 2830 2923 if (audioIn.do_passthru) 2924 #endif 2831 2925 { 2832 2926 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 2833 audioOut.channels = 2; 2834 audioOut.sample_rate = 48000; 2835 audioOut.sample_size = 4; 2927 AudioInfo digInfo = audioOut; 2928 if (!disable_passthru) 2929 { 2930 digInfo.channels = 2; 2931 digInfo.sample_rate = 48000; 2932 digInfo.sample_size = 4; 2933 } 2934 if (audioOut.channels > max_channels) 2935 { 2936 audioOut.channels = max_channels; 2937 audioOut.sample_size = audioOut.channels * 2; 2938 codec_ctx->channels = audioOut.channels; 2939 } 2940 #if MAXCHANNELSELECT 2941 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 2942 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 2943 .arg(digInfo.toString()) 2944 .arg(old_in.toString()).arg(old_out.toString()) 2945 .arg(audioIn.toString()).arg(audioOut.toString())); 2946 2947 if (digInfo.sample_rate > 0) 2948 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 2949 2950 //GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2951 // audioOut.sample_rate); 2952 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 2953 digInfo.sample_rate, audioIn.do_passthru); 2954 // allow the audio stuff to reencode 2955 GetNVP()->SetAudioCodec(codec_ctx); 2956 GetNVP()->ReinitAudio(); 2957 return true; 2958 #endif 2836 2959 } 2960 #if MAXCHANNELSELECT 2837 2961 else 2838 2962 { 2963 if (audioOut.channels > max_channels) 2964 { 2965 audioOut.channels = max_channels; 2966 audioOut.sample_size = audioOut.channels * 2; 2967 codec_ctx->channels = audioOut.channels; 2968 } 2969 } 2970 bool audiook; 2971 #if 0 2972 do 2973 { 2974 #endif 2975 #else 2976 else 2977 { 2839 2978 if (audioOut.channels > MAX_OUTPUT_CHANNELS) 2840 2979 { 2841 2980 audioOut.channels = MAX_OUTPUT_CHANNELS; … … 2843 2982 codec_ctx->channels = MAX_OUTPUT_CHANNELS; 2844 2983 } 2845 2984 } 2985 #endif 2846 2986 2847 2987 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 2848 2988 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 2855 2995 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 2856 2996 audioOut.sample_rate, 2857 2997 audioIn.do_passthru); 2858 GetNVP()->ReinitAudio(); 2998 // allow the audio stuff to reencode 2999 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3000 QString errMsg = GetNVP()->ReinitAudio(); 3001 #if MAXCHANNELSELECT 3002 audiook = errMsg.isEmpty(); 3003 #if 0 3004 if (!audiook) 3005 { 3006 switch (audioOut.channels) 3007 { 3008 #if 0 3009 case 8: 3010 audioOut.channels = 6; 3011 break; 3012 #endif 3013 case 6: 3014 #if 0 3015 audioOut.channels = 5; 3016 break; 3017 case 5: 3018 audioOut.channels = 4; 3019 break; 3020 case 4: 3021 audioOut.channels = 3; 3022 break; 3023 case 3: 3024 #endif 3025 audioOut.channels = 2; 3026 break; 3027 #if 0 3028 case 2: 3029 audioOut.channels = 1; 3030 break; 3031 #endif 3032 default: 3033 // failed to reconfigure under any circumstances 3034 audiook = true; 3035 audioOut.channels = 0; 3036 break; 3037 } 3038 audioOut.sample_size = audioOut.channels * 2; 3039 codec_ctx->channels = audioOut.channels; 3040 } 3041 } while (!audiook); 3042 #endif 3043 #endif 2859 3044 2860 3045 return true; 2861 3046 } -
libs/libmythtv/NuppelVideoPlayer.h
112 112 void SetVideoParams(int w, int h, double fps, int keydist, 113 113 float a = 1.33333, FrameScanType scan = kScan_Ignore); 114 114 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 115 void SetAudioCodec(void *ac); 115 116 void SetEffDsp(int dsprate); 116 117 void SetFileLength(int total, int frames); 117 118 void Zoom(int direction); … … 149 150 bool IsDecoderThreadAlive(void) const { return decoder_thread_alive; } 150 151 bool IsReallyNearEnd(void) const; 151 152 bool IsNearEnd(long long framesRemaining = -1) const; 153 float GetAudioStretchFactor() { return audio_stretchfactor; } 152 154 bool PlayingSlowForPrebuffer(void) const { return m_playing_slower; } 153 155 bool HasAudioIn(void) const { return !no_audio_in; } 154 156 bool HasAudioOut(void) const { return !no_audio_out; } … … 178 180 bool Play(float speed = 1.0, bool normal = true, 179 181 bool unpauseaudio = true); 180 182 bool GetPause(void) const; 183 float GetNextPlaySpeed() { return next_play_speed; } 181 184 182 185 // Seek stuff 183 186 bool FastForward(float seconds); … … 509 512 int audio_bits; 510 513 int audio_samplerate; 511 514 float audio_stretchfactor; 515 void *audio_codec; 512 516 bool audio_passthru; 513 517 514 518 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
126 126 audioOutput(NULL), audiodevice("/dev/dsp"), 127 127 audio_channels(2), audio_bits(-1), 128 128 audio_samplerate(44100), audio_stretchfactor(1.0f), 129 audio_codec(NULL), 129 130 // Picture-in-Picture 130 131 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 131 132 // Preview window support … … 565 566 if (audioOutput) 566 567 { 567 568 audioOutput->Reconfigure(audio_bits, audio_channels, 568 audio_samplerate, audio_passthru); 569 audio_samplerate, audio_passthru, 570 audio_codec); 569 571 errMsg = audioOutput->GetError(); 570 572 if (!errMsg.isEmpty()) 571 573 audioOutput->SetStretchFactor(audio_stretchfactor); … … 698 700 { 699 701 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 700 702 "framerate (refresh rate too low for bob deint)"); 703 //m_scan = kScan_Ignore; 704 //m_can_double = false; 701 705 FallbackDeint(); 702 706 } 703 707 } … … 1567 1571 warpfactor_avg = (warpfactor + (warpfactor_avg * (WARPAVLEN - 1))) / 1568 1572 WARPAVLEN; 1569 1573 1570 //cerr << "Divergence: " << divergence << " Rate: " << rate 1571 //<< " Warpfactor: " << warpfactor << " warpfactor_avg: " 1572 //<< warpfactor_avg << endl; 1574 #if 1 1575 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1576 "Divergence: %1 " 1577 " Rate: %2" 1578 " Warpfactor: %3" 1579 " warpfactor_avg: %4") 1580 .arg(divergence) 1581 .arg(rate) 1582 .arg(warpfactor) 1583 .arg(warpfactor_avg) 1584 ); 1585 #endif 1573 1586 return divergence; 1574 1587 } 1575 1588 … … 1650 1663 if (diverge < -MAXDIVERGE) 1651 1664 { 1652 1665 // If video is way ahead of audio, adjust for it... 1653 QString dbg = QString(" Video is %1 frames ahead of audio, ")1666 QString dbg = QString("Audio is %1 frames ahead of video, ") 1654 1667 .arg(-diverge); 1655 1668 1656 1669 // Reset A/V Sync … … 1665 1678 // decoding; display the frame, but don't wait for A/V Sync. 1666 1679 videoOutput->PrepareFrame(buffer, ps); 1667 1680 videoOutput->Show(m_scan); 1668 VERBOSE(VB_PLAYBACK , LOC + dbg + "skipping A/V wait.");1681 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "skipping A/V wait."); 1669 1682 } 1670 1683 else 1671 1684 { 1672 1685 // If we are using software decoding, skip this frame altogether. 1673 VERBOSE(VB_PLAYBACK , LOC + dbg + "dropping frame.");1686 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + dbg + "dropping frame."); 1674 1687 } 1675 1688 } 1676 1689 else if (!using_null_videoout) … … 1679 1692 if (buffer) 1680 1693 videoOutput->PrepareFrame(buffer, ps); 1681 1694 1695 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("AVSync waitforframe %1 %2").arg(avsync_adjustment).arg(m_double_framerate)); 1682 1696 videosync->WaitForFrame(avsync_adjustment); 1697 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, "AVSync show"); 1683 1698 if (!resetvideo) 1684 1699 videoOutput->Show(m_scan); 1685 1700 … … 1699 1714 1700 1715 // Display the second field 1701 1716 videosync->AdvanceTrigger(); 1702 videosync->WaitForFrame( 0);1717 videosync->WaitForFrame(avsync_adjustment); 1703 1718 if (!resetvideo) 1704 1719 videoOutput->Show(kScan_Intr2ndField); 1705 1720 } … … 1711 1726 1712 1727 if (output_jmeter && output_jmeter->RecordCycleTime()) 1713 1728 { 1714 //cerr << "avsync_delay: " << avsync_delay / 1000 1715 // << ", avsync_avg: " << avsync_avg / 1000 1716 // << ", warpfactor: " << warpfactor 1717 // << ", warpfactor_avg: " << warpfactor_avg << endl; 1729 #if 1 1730 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString("A/V " 1731 "avsync_delay: %1" 1732 ", avsync_avg: %2" 1733 ", warpfactor: %3" 1734 ", warpfactor_avg: %4") 1735 .arg(avsync_delay / 1000) 1736 .arg(avsync_avg / 1000) 1737 .arg(warpfactor) 1738 .arg(warpfactor_avg)); 1739 #endif 1718 1740 } 1719 1741 1720 1742 videosync->AdvanceTrigger(); … … 1725 1747 // If audio is way ahead of video, adjust for it... 1726 1748 // by cutting the frame rate in half for the length of this frame 1727 1749 1728 avsync_adjustment = frame_interval; 1750 //avsync_adjustment = frame_interval; 1751 avsync_adjustment = refreshrate; 1729 1752 lastsync = true; 1730 VERBOSE(VB_PLAYBACK , LOC +1731 QString(" Audio is %1 frames ahead of video,\n"1753 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + 1754 QString("Video is %1 frames ahead of audio,\n" 1732 1755 "\t\t\tdoubling video frame interval.").arg(diverge)); 1733 1756 } 1734 1757 1735 1758 if (audioOutput && normal_speed) 1736 1759 { 1737 1760 long long currentaudiotime = audioOutput->GetAudiotime(); 1738 #if 01739 VERBOSE(VB_PLAYBACK , QString(1761 #if 1 1762 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, QString( 1740 1763 "A/V timecodes audio %1 video %2 frameinterval %3 " 1741 1764 "avdel %4 avg %5 tcoffset %6") 1742 1765 .arg(currentaudiotime) … … 2002 2025 2003 2026 usevideotimebase = gContext->GetNumSetting("UseVideoTimebase", 0); 2004 2027 2005 if ((print_verbose_messages & VB_PLAYBACK ) != 0)2028 if ((print_verbose_messages & VB_PLAYBACK|VB_TIMESTAMP) == (VB_PLAYBACK|VB_TIMESTAMP)) 2006 2029 output_jmeter = new Jitterometer("video_output", 100); 2007 2030 else 2008 2031 output_jmeter = NULL; … … 2042 2065 { 2043 2066 VERBOSE(VB_IMPORTANT, "Video sync method can't support double " 2044 2067 "framerate (refresh rate too low for bob deint)"); 2068 //m_scan = kScan_Ignore; 2069 //m_can_double = false; 2045 2070 FallbackDeint(); 2046 2071 } 2047 2072 } … … 2806 2831 audio_passthru = passthru; 2807 2832 } 2808 2833 2834 void NuppelVideoPlayer::SetAudioCodec(void* ac) 2835 { 2836 audio_codec = ac; 2837 } 2838 2809 2839 void NuppelVideoPlayer::SetEffDsp(int dsprate) 2810 2840 { 2811 2841 if (audioOutput) … … 2850 2880 tc_avcheck_framecounter++; 2851 2881 if (tc_avcheck_framecounter == 30) 2852 2882 { 2853 #define AUTO_RESYNC 12883 #define AUTO_RESYNC 0 2854 2884 #if AUTO_RESYNC 2855 2885 // something's terribly, terribly wrong. 2856 2886 if (tc_lastval[TC_AUDIO] < tc_lastval[TC_VIDEO] - 10000000 || -
libs/libavcodec/a52dec.c
142 142 } 143 143 } 144 144 145 static inline int16_t convert (int32_t i) 146 { 147 if (i > 0x43c07fff) 148 return 32767; 149 else if (i < 0x43bf8000) 150 return -32768; 151 else 152 return i - 0x43c00000; 153 } 154 155 void float2s16_2 (float * _f, int16_t * s16) 156 { 157 int i; 158 int32_t * f = (int32_t *) _f; 159 160 for (i = 0; i < 256; i++) { 161 s16[2*i] = convert (f[i]); 162 s16[2*i+1] = convert (f[i+256]); 163 } 164 } 165 166 void float2s16_4 (float * _f, int16_t * s16) 167 { 168 int i; 169 int32_t * f = (int32_t *) _f; 170 171 for (i = 0; i < 256; i++) { 172 s16[4*i] = convert (f[i]); 173 s16[4*i+1] = convert (f[i+256]); 174 s16[4*i+2] = convert (f[i+512]); 175 s16[4*i+3] = convert (f[i+768]); 176 } 177 } 178 179 void float2s16_5 (float * _f, int16_t * s16) 180 { 181 int i; 182 int32_t * f = (int32_t *) _f; 183 184 for (i = 0; i < 256; i++) { 185 s16[5*i] = convert (f[i]); 186 s16[5*i+1] = convert (f[i+256]); 187 s16[5*i+2] = convert (f[i+512]); 188 s16[5*i+3] = convert (f[i+768]); 189 s16[5*i+4] = convert (f[i+1024]); 190 } 191 } 192 193 int channels_multi (int flags) 194 { 195 if (flags & A52_LFE) 196 return 6; 197 else if (flags & 1) /* center channel */ 198 return 5; 199 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 200 return 4; 201 else 202 return 2; 203 } 204 205 void float2s16_multi (float * _f, int16_t * s16, int flags) 206 { 207 int i; 208 int32_t * f = (int32_t *) _f; 209 210 switch (flags) { 211 case A52_MONO: 212 for (i = 0; i < 256; i++) { 213 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 214 s16[5*i+4] = convert (f[i]); 215 } 216 break; 217 case A52_CHANNEL: 218 case A52_STEREO: 219 case A52_DOLBY: 220 float2s16_2 (_f, s16); 221 break; 222 case A52_3F: 223 for (i = 0; i < 256; i++) { 224 s16[5*i] = convert (f[i]); 225 s16[5*i+1] = convert (f[i+512]); 226 s16[5*i+2] = s16[5*i+3] = 0; 227 s16[5*i+4] = convert (f[i+256]); 228 } 229 break; 230 case A52_2F2R: 231 float2s16_4 (_f, s16); 232 break; 233 case A52_3F2R: 234 float2s16_5 (_f, s16); 235 break; 236 case A52_MONO | A52_LFE: 237 for (i = 0; i < 256; i++) { 238 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 239 s16[6*i+4] = convert (f[i+256]); 240 s16[6*i+5] = convert (f[i]); 241 } 242 break; 243 case A52_CHANNEL | A52_LFE: 244 case A52_STEREO | A52_LFE: 245 case A52_DOLBY | A52_LFE: 246 for (i = 0; i < 256; i++) { 247 s16[6*i] = convert (f[i+256]); 248 s16[6*i+1] = convert (f[i+512]); 249 s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 250 s16[6*i+5] = convert (f[i]); 251 } 252 break; 253 case A52_3F | A52_LFE: 254 for (i = 0; i < 256; i++) { 255 s16[6*i] = convert (f[i+256]); 256 s16[6*i+1] = convert (f[i+768]); 257 s16[6*i+2] = s16[6*i+3] = 0; 258 s16[6*i+4] = convert (f[i+512]); 259 s16[6*i+5] = convert (f[i]); 260 } 261 break; 262 case A52_2F2R | A52_LFE: 263 for (i = 0; i < 256; i++) { 264 s16[6*i] = convert (f[i+256]); 265 s16[6*i+1] = convert (f[i+512]); 266 s16[6*i+2] = convert (f[i+768]); 267 s16[6*i+3] = convert (f[i+1024]); 268 s16[6*i+4] = 0; 269 s16[6*i+5] = convert (f[i]); 270 } 271 break; 272 case A52_3F2R | A52_LFE: 273 for (i = 0; i < 256; i++) { 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = convert (f[i+768]); 276 s16[6*i+2] = convert (f[i+1024]); 277 s16[6*i+3] = convert (f[i+1280]); 278 s16[6*i+4] = convert (f[i+512]); 279 s16[6*i+5] = convert (f[i]); 280 } 281 break; 282 } 283 } 284 285 145 286 /**** end */ 146 287 147 288 #define HEADER_SIZE 7 … … 183 324 /* update codec info */ 184 325 avctx->sample_rate = sample_rate; 185 326 s->channels = ac3_channels[s->flags & 7]; 327 if (avctx->cqp >= 0) 328 avctx->channels = avctx->cqp; 186 329 if (s->flags & A52_LFE) 187 330 s->channels++; 188 331 if (avctx->channels == 0) … … 205 348 s->inbuf_ptr += len; 206 349 buf_size -= len; 207 350 } else { 351 int chans; 208 352 flags = s->flags; 209 353 if (avctx->channels == 1) 210 354 flags = A52_MONO; 211 else if (avctx->channels == 2) 212 flags = A52_STEREO; 355 else if (avctx->channels == 2) { 356 if (s->channels>2) 357 flags = A52_DOLBY; 358 else 359 flags = A52_STEREO; 360 } 213 361 else 214 362 flags |= A52_ADJUST_LEVEL; 215 363 level = 1; 364 chans = channels_multi(flags); 216 365 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 217 366 fail: 218 367 s->inbuf_ptr = s->inbuf; … … 222 371 for (i = 0; i < 6; i++) { 223 372 if (s->a52_block(s->state)) 224 373 goto fail; 225 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 374 //float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); 375 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 226 376 } 227 377 s->inbuf_ptr = s->inbuf; 228 378 s->frame_size = 0; 229 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 379 //*data_size = 6 * avctx->channels * 256 * sizeof(int16_t); 380 *data_size = 6 * chans * 256 * sizeof(int16_t); 230 381 break; 231 382 } 232 383 } -
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 */