Ticket #1104: mythtv_ac3.46.patch
File mythtv_ac3.46.patch, 60.0 KB (added by , 16 years ago) |
---|
-
libs/libs.pro
6 6 # Directories 7 7 SUBDIRS += libavutil libavcodec libavformat libmythsamplerate 8 8 SUBDIRS += libmythsoundtouch libmythmpeg2 libmythdvdnav 9 SUBDIRS += libmythfreesurround 9 10 10 11 mingw : SUBDIRS += libmyth libmythupnp libmythui 11 12 !mingw: SUBDIRS += libmythupnp libmythui libmyth -
libs/libmyth/libmyth.pro
25 25 HEADERS += volumebase.h volumecontrol.h virtualkeyboard.h visual.h xmlparse.h 26 26 HEADERS += mythhdd.h mythcdrom.h 27 27 HEADERS += compat.h 28 HEADERS += audiooutputdigitalencoder.h 28 29 29 30 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 30 31 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp … … 40 41 SOURCES += uilistbtntype.cpp uitypes.cpp util.cpp util-x11.cpp 41 42 SOURCES += volumebase.cpp volumecontrol.cpp virtualkeyboard.cpp xmlparse.cpp 42 43 SOURCES += mythhdd.cpp mythcdrom.cpp 44 SOURCES += audiooutputdigitalencoder.cpp 43 45 44 46 INCLUDEPATH += ../libmythsamplerate ../libmythsoundtouch ../.. ../ ./ 47 INCLUDEPATH += ../libavutil 48 INCLUDEPATH += ../libmythfreesurround 45 49 DEPENDPATH += ../libmythsamplerate ../libmythsoundtouch ../ ../libmythui 46 50 DEPENDPATH += ../libmythupnp 51 DEPENDPATH += ../libavutil ../libavcodec 52 DEPENDPATH += ../libmythfreesurround 47 53 48 54 LIBS += -L../libmythsamplerate -lmythsamplerate-$${LIBVERSION} 49 55 LIBS += -L../libmythsoundtouch -lmythsoundtouch-$${LIBVERSION} 56 LIBS += -L../libmythfreesurround -lmythfreesurround-$${LIBVERSION} 57 LIBS += -L../libavcodec -lmythavcodec-$${LIBVERSION} 58 LIBS += -lfftw3f 50 59 LIBS += -L../libmythui -lmythui-$${LIBVERSION} 51 60 LIBS += -L../libmythupnp -lmythupnp-$${LIBVERSION} 52 61 53 62 TARGETDEPS += ../libmythsamplerate/libmythsamplerate-$${MYTH_LIB_EXT} 54 63 TARGETDEPS += ../libmythsoundtouch/libmythsoundtouch-$${MYTH_LIB_EXT} 64 TARGETDEPS += ../libmythfreesurround/libmythfreesurround-$${MYTH_LIB_EXT} 55 65 56 66 # Install headers so that plugins can compile independently 57 67 inc.path = $${PREFIX}/include/mythtv/ -
libs/libmyth/audiooutput.h
31 31 virtual ~AudioOutput() { }; 32 32 33 33 // reconfigure sound out for new params 34 virtual void Reconfigure(int audio_bits, int audio_channels, 35 int audio_samplerate, bool audio_passthru) = 0; 34 virtual void Reconfigure(int audio_bits, 35 int audio_channels, 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL 39 ) = 0; 36 40 37 41 virtual void SetStretchFactor(float factor); 42 virtual float GetStretchFactor(); 38 43 39 44 // do AddSamples calls block? 40 45 virtual void SetBlocking(bool blocking) = 0; … … 76 81 lastError = msg; 77 82 VERBOSE(VB_IMPORTANT, "AudioOutput Error: " + lastError); 78 83 } 84 void ClearError() 85 { lastError = QString::null; }; 79 86 80 87 void Warn(QString msg) 81 88 { -
libs/libmyth/audiooutput.cpp
133 133 { 134 134 } 135 135 136 float AudioOutput::GetStretchFactor() 137 { 138 return 1.0; 139 } 136 140 141 142 -
libs/libmyth/audiooutputdx.h
35 35 /// END HACK HACK HACK HACK 36 36 37 37 virtual void Reset(void); 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, int audio_passthru); 38 virtual void Reconfigure(int audio_bits, 39 int audio_channels, 40 int audio_samplerate, 41 bool audio_passthru, 42 AudioCodecMode aom = AUDIOCODECMODE_NORMAL); 40 43 virtual void SetBlocking(bool blocking); 41 44 42 45 virtual bool AddSamples(char *buffer, int samples, long long timecode); -
libs/libmyth/audiooutputdx.cpp
130 130 // FIXME: kedl: not sure what else could be required here? 131 131 } 132 132 133 void AudioOutputDX::Reconfigure(int audio_bits, int audio_channels, 134 int audio_samplerate, int audio_passthru) 133 void AudioOutputDX::Reconfigure(int audio_bits, 134 int audio_channels, 135 int audio_samplerate, 136 int audio_passthru, 137 AudioCodecMode laom 138 ) 135 139 { 136 140 if (dsbuffer) 137 141 DestroyDSBuffer(); -
libs/libmyth/audiooutputbase.h
16 16 // MythTV headers 17 17 #include "audiooutput.h" 18 18 #include "samplerate.h" 19 #include "SoundTouch.h"20 19 21 #define AUDBUFSIZE 768000 20 namespace soundtouch { 21 class SoundTouch; 22 }; 23 class FreeSurround; 24 class AudioOutputDigitalEncoder; 25 struct AVCodecContext; 26 22 27 #define AUDIO_SRC_IN_SIZE 16384 23 28 #define AUDIO_SRC_OUT_SIZE (16384*6) 24 29 #define AUDIO_TMP_BUF_SIZE (16384*6) 25 30 31 //#define AUDBUFSIZE 768000 32 //divisible by 12,10,8,6,4,2 and around 1024000 33 //#define AUDBUFSIZE 1024080 34 #define AUDBUFSIZE 1536000 35 26 36 class AudioOutputBase : public AudioOutput 27 37 { 28 38 public: … … 35 45 virtual ~AudioOutputBase(); 36 46 37 47 // reconfigure sound out for new params 38 virtual void Reconfigure(int audio_bits, int audio_channels, 39 int audio_samplerate, bool audio_passthru); 48 virtual void Reconfigure(int audio_bits, 49 int audio_channels, 50 int audio_samplerate, 51 bool audio_passthru, 52 void* audio_codec = NULL); 40 53 41 54 // do AddSamples calls block? 42 55 virtual void SetBlocking(bool blocking); … … 45 58 virtual void SetEffDsp(int dsprate); 46 59 47 60 virtual void SetStretchFactor(float factor); 61 virtual float GetStretchFactor(); 48 62 49 63 virtual void Reset(void); 50 64 … … 127 141 bool audio_passthru; 128 142 129 143 float audio_stretchfactor; 144 AVCodecContext *audio_codec; 130 145 AudioOutputSource source; 131 146 132 147 bool killaudio; … … 135 150 bool set_initial_vol; 136 151 bool buffer_output_data_for_use; // used by AudioOutputNULL 137 152 153 int configured_audio_channels; 154 138 155 private: 139 156 // resampler 140 157 bool need_resampler; … … 146 163 147 164 // timestretch 148 165 soundtouch::SoundTouch * pSoundStretch; 166 AudioOutputDigitalEncoder * encoder; 167 FreeSurround * upmixer; 149 168 169 int source_audio_channels; 170 int source_audio_bytes_per_sample; 171 bool needs_upmix; 172 int surround_mode; 173 150 174 bool blocking; // do AddSamples calls block? 151 175 152 176 int lastaudiolen; … … 164 188 165 189 pthread_mutex_t avsync_lock; /* must hold avsync_lock to read or write 166 190 'audiotime' and 'audiotime_updated' */ 167 intaudiotime; // timecode of audio leaving the soundcard (same units as191 long long audiotime; // timecode of audio leaving the soundcard (same units as 168 192 // timecodes) ... 169 193 struct timeval audiotime_updated; // ... which was last updated at this time 170 194 171 195 /* Audio circular buffer */ 172 196 unsigned char audiobuffer[AUDBUFSIZE]; /* buffer */ 173 197 int raud, waud; /* read and write positions */ 174 intaudbuf_timecode; /* timecode of audio most recently placed into198 long long audbuf_timecode; /* timecode of audio most recently placed into 175 199 buffer */ 176 200 177 201 int numlowbuffer; -
libs/libmyth/audiooutputbase.cpp
15 15 16 16 // MythTV headers 17 17 #include "audiooutputbase.h" 18 #include "audiooutputdigitalencoder.h" 19 #include "SoundTouch.h" 20 #include "freesurround.h" 18 21 #include "compat.h" 19 22 20 23 #define LOC QString("AO: ") … … 36 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 37 40 audio_passthru(false), audio_stretchfactor(1.0f), 38 41 42 audio_codec(NULL), 39 43 source(lsource), killaudio(false), 40 44 41 45 pauseaudio(false), audio_actually_paused(false), … … 47 51 48 52 src_ctx(NULL), 49 53 50 pSoundStretch(NULL), blocking(false), 54 pSoundStretch(NULL), 55 encoder(NULL), 56 upmixer(NULL), 57 source_audio_channels(-1), 58 source_audio_bytes_per_sample(0), 59 needs_upmix(false), 60 surround_mode(FreeSurround::SurroundModePassive), 51 61 62 blocking(false), 63 52 64 lastaudiolen(0), samples_buffered(0), 53 65 54 66 audio_thread_exists(false), … … 71 83 memset(tmp_buff, 0, sizeof(short) * AUDIO_TMP_BUF_SIZE); 72 84 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 73 85 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 74 87 75 88 // You need to call Reconfigure from your concrete class. 76 89 // Reconfigure(laudio_bits, laudio_channels, … … 111 124 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 112 125 .arg(audio_stretchfactor)); 113 126 pSoundStretch = new soundtouch::SoundTouch(); 114 pSoundStretch->setSampleRate(audio_samplerate); 115 pSoundStretch->setChannels(audio_channels); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1 origfs %2").arg(audio_codec->codec_id).arg(audio_codec->frame_size)); 132 encoder = new AudioOutputDigitalEncoder(); 133 if (!encoder->Init(audio_codec->codec_id, 134 audio_codec->bit_rate, 135 audio_codec->sample_rate, 136 audio_codec->channels 137 )) 138 { 139 // eeks 140 delete encoder; 141 encoder = NULL; 142 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 143 } 144 } 145 } 146 if (encoder) 147 { 148 pSoundStretch->setSampleRate(audio_codec->sample_rate); 149 pSoundStretch->setChannels(audio_codec->channels); 150 } 151 else 152 { 153 pSoundStretch->setSampleRate(audio_samplerate); 154 pSoundStretch->setChannels(audio_channels); 155 } 116 156 117 157 pSoundStretch->setTempo(audio_stretchfactor); 118 158 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … 134 174 pthread_mutex_unlock(&audio_buflock); 135 175 } 136 176 177 float AudioOutputBase::GetStretchFactor() 178 { 179 return audio_stretchfactor; 180 } 181 137 182 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 138 int laudio_samplerate, bool laudio_passthru) 183 int laudio_samplerate, bool laudio_passthru, 184 void* laudio_codec) 139 185 { 140 if (laudio_bits == audio_bits && laudio_channels == audio_channels && 141 laudio_samplerate == audio_samplerate && 142 laudio_passthru == audio_passthru && !need_resampler) 186 int codec_id = CODEC_ID_NONE; 187 int lcodec_id = CODEC_ID_NONE; 188 int lcchannels = 0; 189 int cchannels = 0; 190 int lsource_audio_channels = laudio_channels; 191 bool lneeds_upmix = false; 192 193 if (laudio_codec) 194 { 195 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 196 laudio_bits = 16; 197 laudio_channels = 2; 198 lsource_audio_channels = laudio_channels; 199 laudio_samplerate = 48000; 200 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 201 } 202 if (audio_codec) 203 { 204 codec_id = audio_codec->codec_id; 205 cchannels = ((AVCodecContext*)audio_codec)->channels; 206 } 207 if ((configured_audio_channels == 6) && 208 !(laudio_codec || audio_codec)) 209 { 210 laudio_channels = configured_audio_channels; 211 lneeds_upmix = true; 212 VERBOSE(VB_AUDIO,LOC + "Needs upmix"); 213 } 214 ClearError(); 215 if (laudio_bits == audio_bits && 216 lsource_audio_channels == source_audio_channels && 217 laudio_channels == audio_channels && 218 laudio_samplerate == audio_samplerate && !need_resampler && 219 laudio_passthru == audio_passthru && 220 lneeds_upmix == needs_upmix && 221 lcodec_id == codec_id && lcchannels == cchannels) 222 { 223 VERBOSE(VB_AUDIO,LOC + "no change exiting"); 143 224 return; 144 225 } 145 226 KillAudio(); 146 227 147 228 pthread_mutex_lock(&audio_buflock); … … 151 232 waud = raud = 0; 152 233 audio_actually_paused = false; 153 234 235 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels); 154 236 audio_channels = laudio_channels; 237 source_audio_channels = lsource_audio_channels; 155 238 audio_bits = laudio_bits; 156 239 audio_samplerate = laudio_samplerate; 240 audio_codec = (AVCodecContext*)laudio_codec; 157 241 audio_passthru = laudio_passthru; 242 needs_upmix = lneeds_upmix; 158 243 if (audio_bits != 8 && audio_bits != 16) 159 244 { 160 245 pthread_mutex_unlock(&avsync_lock); … … 163 248 return; 164 249 } 165 250 audio_bytes_per_sample = audio_channels * audio_bits / 8; 251 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 166 252 167 253 need_resampler = false; 168 254 killaudio = false; … … 172 258 173 259 numlowbuffer = 0; 174 260 261 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 262 .arg(audio_main_device).arg(audio_channels) 263 .arg(source_audio_channels).arg(audio_samplerate)); 264 175 265 // Actually do the device specific open call 176 266 if (!OpenDevice()) 177 267 { 178 268 VERBOSE(VB_AUDIO, LOC_ERR + "Aborting reconfigure"); 179 269 pthread_mutex_unlock(&avsync_lock); 180 270 pthread_mutex_unlock(&audio_buflock); 271 if (GetError().isEmpty()) 272 Error("Aborting reconfigure"); 273 VERBOSE(VB_AUDIO, "Aborting reconfigure"); 181 274 return; 182 275 } 183 276 … … 200 293 current_seconds = -1; 201 294 source_bitrate = -1; 202 295 296 // NOTE: this wont do anything as above samplerate vars are set equal 203 297 // Check if we need the resampler 204 298 if (audio_samplerate != laudio_samplerate) 205 299 { … … 222 316 need_resampler = true; 223 317 } 224 318 319 if (needs_upmix) 320 { 321 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); 322 if (configured_audio_channels == 6) 323 { 324 surround_mode = gContext->GetNumSetting("AudioUpmixType", 2); 325 } 326 upmixer = new FreeSurround(audio_samplerate, 327 source == AUDIOOUTPUT_VIDEO, 328 (FreeSurround::SurroundMode)surround_mode); 329 VERBOSE(VB_AUDIO, LOC + QString("create upmixer done with surround mode %1").arg(surround_mode)); 330 } 331 225 332 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 226 333 .arg(audio_stretchfactor)); 334 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1") 335 .arg(audio_codec?codec_id_string(audio_codec->codec_id):"not set")); 227 336 228 SetStretchFactorLocked(audio_stretchfactor); 229 if (pSoundStretch) 337 if (redo_stretch) 230 338 { 231 pSoundStretch->setSampleRate(audio_samplerate); 232 pSoundStretch->setChannels(audio_channels); 339 float laudio_stretchfactor = audio_stretchfactor; 340 delete pSoundStretch; 341 pSoundStretch = NULL; 342 audio_stretchfactor = 0.0; 343 SetStretchFactorLocked(laudio_stretchfactor); 233 344 } 345 else 346 { 347 SetStretchFactorLocked(audio_stretchfactor); 348 if (pSoundStretch) 349 { 350 // if its passthru then we need to reencode 351 if (audio_codec) 352 { 353 if (!encoder) 354 { 355 VERBOSE(VB_AUDIO, LOC + QString("Creating Encoder for codec %1").arg(audio_codec->codec_id)); 356 encoder = new AudioOutputDigitalEncoder(); 357 if (!encoder->Init(audio_codec->codec_id, 358 audio_codec->bit_rate, 359 audio_codec->sample_rate, 360 audio_codec->channels 361 )) 362 { 363 // eeks 364 delete encoder; 365 encoder = NULL; 366 VERBOSE(VB_AUDIO, LOC + QString("Failed to Create Encoder")); 367 } 368 } 369 } 370 if (encoder) 371 { 372 pSoundStretch->setSampleRate(audio_codec->sample_rate); 373 pSoundStretch->setChannels(audio_codec->channels); 374 } 375 else 376 { 377 pSoundStretch->setSampleRate(audio_samplerate); 378 pSoundStretch->setChannels(audio_channels); 379 } 380 } 381 } 234 382 235 383 // Setup visualisations, zero the visualisations buffers 236 384 prepareVisuals(); … … 290 438 pSoundStretch = NULL; 291 439 } 292 440 441 if (encoder) 442 { 443 delete encoder; 444 encoder = NULL; 445 } 446 447 if (upmixer) 448 { 449 delete upmixer; 450 upmixer = NULL; 451 } 452 needs_upmix = false; 453 293 454 CloseDevice(); 294 455 295 456 killAudioLock.unlock(); … … 303 464 304 465 void AudioOutputBase::Pause(bool paused) 305 466 { 467 VERBOSE(VB_AUDIO, LOC+ QString("Pause %0").arg(paused)); 306 468 pauseaudio = paused; 307 469 audio_actually_paused = false; 308 470 } … … 385 547 The reason is that computing 'audiotime' requires acquiring the audio 386 548 lock, which the video thread should not do. So, we call 'SetAudioTime()' 387 549 from the audio thread, and then call this from the video thread. */ 388 intret;550 long long ret; 389 551 struct timeval now; 390 552 391 553 if (audiotime == 0) … … 397 559 398 560 ret = (now.tv_sec - audiotime_updated.tv_sec) * 1000; 399 561 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 400 ret = ( int)(ret * audio_stretchfactor);562 ret = (long long)(ret * audio_stretchfactor); 401 563 564 #if 1 565 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 566 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 567 .arg(now.tv_sec).arg(now.tv_usec) 568 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 569 .arg(ret) 570 .arg(audiotime) 571 .arg(audio_stretchfactor) 572 ); 573 #endif 574 402 575 ret += audiotime; 403 576 404 577 pthread_mutex_unlock(&avsync_lock); 405 return ret;578 return (int)ret; 406 579 } 407 580 408 581 void AudioOutputBase::SetAudiotime(void) … … 439 612 // include algorithmic latencies 440 613 if (pSoundStretch) 441 614 { 615 // add the effect of any unused but processed samples, AC3 reencode does this 616 totalbuffer += (int)(pSoundStretch->numSamples() * audio_bytes_per_sample); 442 617 // add the effect of unprocessed samples in time stretch algo 443 618 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 444 619 audio_bytes_per_sample) / audio_stretchfactor); 445 620 } 446 621 622 if (upmixer && needs_upmix) 623 { 624 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 625 } 626 447 627 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 448 628 (audio_bytes_per_sample * effdspstretched)); 449 629 450 630 gettimeofday(&audiotime_updated, NULL); 631 #if 1 632 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 633 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") 634 .arg(audiotime_updated.tv_sec).arg(audiotime_updated.tv_usec) 635 .arg(audiotime) 636 .arg(audbuf_timecode) 637 .arg(totalbuffer) 638 .arg(soundcard_buffer) 639 .arg(effdspstretched) 640 .arg(audio_bytes_per_sample) 641 .arg(audio_stretchfactor) 642 ); 643 #endif 451 644 452 645 pthread_mutex_unlock(&avsync_lock); 453 646 pthread_mutex_unlock(&audio_buflock); … … 458 651 { 459 652 // NOTE: This function is not threadsafe 460 653 int afree = audiofree(true); 461 int abps = audio_bytes_per_sample;654 int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 462 655 int len = samples * abps; 463 656 464 657 // Check we have enough space to write the data 465 658 if (need_resampler && src_ctx) 466 659 len = (int)ceilf(float(len) * src_data.src_ratio); 467 660 661 // include samples in upmix buffer that may be flushed 662 if (needs_upmix && upmixer) 663 len += upmixer->numUnprocessedSamples()*abps; 664 468 665 if (pSoundStretch) 469 666 len += (pSoundStretch->numUnprocessedSamples() + 470 667 (int)(pSoundStretch->numSamples()/audio_stretchfactor))*abps; … … 520 717 // NOTE: This function is not threadsafe 521 718 522 719 int afree = audiofree(true); 523 int abps = audio_bytes_per_sample;720 int abps = (encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample); 524 721 int len = samples * abps; 525 722 526 723 // Check we have enough space to write the data 527 724 if (need_resampler && src_ctx) 528 725 len = (int)ceilf(float(len) * src_data.src_ratio); 529 726 727 // include samples in upmix buffer that may be flushed 728 if (needs_upmix && upmixer) 729 len += upmixer->numUnprocessedSamples()*abps; 730 530 731 if (pSoundStretch) 531 732 { 532 733 len += (pSoundStretch->numUnprocessedSamples() + … … 575 776 576 777 int AudioOutputBase::WaitForFreeSpace(int samples) 577 778 { 578 int len = samples * audio_bytes_per_sample; 779 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 780 int len = samples * abps; 579 781 int afree = audiofree(false); 580 782 581 783 while (len > afree) 582 784 { 583 785 if (blocking) 584 786 { 585 VERBOSE(VB_AUDIO , LOC + "Waiting for free space " +787 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Waiting for free space " + 586 788 QString("(need %1, available %2)").arg(len).arg(afree)); 587 789 588 790 // wait for more space … … 591 793 } 592 794 else 593 795 { 594 VERBOSE(VB_IMPORTANT, LOC_ERR + 595 "Audio buffer overflow, audio data lost!"); 596 samples = afree / audio_bytes_per_sample; 597 len = samples * audio_bytes_per_sample; 796 VERBOSE(VB_IMPORTANT, LOC_ERR + 797 QString("Audio buffer overflow, %1 audio samples lost!") 798 .arg(samples - (afree / abps))); 799 samples = afree / abps; 800 len = samples * abps; 598 801 if (src_ctx) 599 802 { 600 803 int error = src_reset(src_ctx); … … 619 822 620 823 int afree = audiofree(false); 621 824 622 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 623 LOC + QString("_AddSamples bytes=%1, used=%2, free=%3, timecode=%4") 624 .arg(samples * audio_bytes_per_sample) 625 .arg(AUDBUFSIZE-afree).arg(afree).arg((long)timecode)); 825 int abps = encoder?encoder->audio_bytes_per_sample:audio_bytes_per_sample; 826 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 827 LOC + QString("_AddSamples samples=%1 bytes=%2, used=%3, free=%4, timecode=%5 needsupmix %6") 828 .arg(samples) 829 .arg(samples * abps) 830 .arg(AUDBUFSIZE-afree).arg(afree).arg(timecode) 831 .arg(needs_upmix) 832 ); 626 833 627 len = WaitForFreeSpace(samples); 628 629 if (interleaved) 834 if (upmixer && needs_upmix) 630 835 { 631 char *mybuf = (char*)buffer; 632 int bdiff = AUDBUFSIZE - org_waud; 633 if (bdiff < len) 836 int out_samples = 0; 837 int step = (interleaved)?source_audio_channels:1; 838 len = WaitForFreeSpace(samples); // test 839 for(int itemp=0; itemp<samples; ) 634 840 { 635 memcpy(audiobuffer + org_waud, mybuf, bdiff); 636 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 841 // just in case it does a processing cycle, release the lock 842 // to allow the output loop to do output 843 pthread_mutex_unlock(&audio_buflock); 844 if (audio_bytes == 2) 845 itemp += upmixer->putSamples((short*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 846 else 847 itemp += upmixer->putSamples((char*)buffer+itemp*step,samples-itemp,source_audio_channels,interleaved?0:samples); 848 pthread_mutex_lock(&audio_buflock); 849 850 int copy_samples = upmixer->numSamples(); 851 if (copy_samples) 852 { 853 int copy_len = copy_samples * abps; 854 out_samples += copy_samples; 855 if (out_samples > samples) 856 len = WaitForFreeSpace(out_samples); 857 int bdiff = AUDBUFSIZE - org_waud; 858 if (bdiff < copy_len) 859 { 860 int bdiff_samples = bdiff/abps; 861 upmixer->receiveSamples((short*)(audiobuffer + org_waud), bdiff_samples); 862 upmixer->receiveSamples((short*)(audiobuffer), (copy_samples - bdiff_samples)); 863 } 864 else 865 { 866 upmixer->receiveSamples((short*)(audiobuffer + org_waud), copy_samples); 867 } 868 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 869 } 637 870 } 638 else 639 memcpy(audiobuffer + org_waud, mybuf, len); 640 641 org_waud = (org_waud + len) % AUDBUFSIZE; 642 } 643 else 871 if (samples > 0) 872 { 873 len = WaitForFreeSpace(out_samples); 874 } 875 samples = out_samples; 876 } 877 else 644 878 { 645 char **mybuf = (char**)buffer; 646 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 879 len = WaitForFreeSpace(samples); 880 881 if (interleaved) 647 882 { 648 for (int chan = 0; chan < audio_channels; chan++) 883 char *mybuf = (char*)buffer; 884 int bdiff = AUDBUFSIZE - org_waud; 885 if (bdiff < len) 649 886 { 650 audiobuffer[org_waud++] = mybuf[chan][itemp]; 651 if (audio_bits == 16) 652 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 887 memcpy(audiobuffer + org_waud, mybuf, bdiff); 888 memcpy(audiobuffer, mybuf + bdiff, len - bdiff); 889 } 890 else 891 memcpy(audiobuffer + org_waud, mybuf, len); 892 893 org_waud = (org_waud + len) % AUDBUFSIZE; 894 } 895 else 896 { 897 char **mybuf = (char**)buffer; 898 for (int itemp = 0; itemp < samples * audio_bytes; itemp += audio_bytes) 899 { 900 for (int chan = 0; chan < audio_channels; chan++) 901 { 902 audiobuffer[org_waud++] = mybuf[chan][itemp]; 903 if (audio_bits == 16) 904 audiobuffer[org_waud++] = mybuf[chan][itemp+1]; 653 905 654 if (org_waud >= AUDBUFSIZE) 655 org_waud -= AUDBUFSIZE; 906 if (org_waud >= AUDBUFSIZE) 907 org_waud -= AUDBUFSIZE; 908 } 656 909 } 657 910 } 658 911 } 659 912 660 if ( pSoundStretch)913 if (samples > 0) 661 914 { 662 // does not change the timecode, only the number of samples 663 // back to orig pos 664 org_waud = waud; 665 int bdiff = AUDBUFSIZE - org_waud; 666 int nSamplesToEnd = bdiff/audio_bytes_per_sample; 667 if (bdiff < len) 915 if (pSoundStretch) 668 916 { 669 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +670 org_waud), nSamplesToEnd);671 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer,672 (len - bdiff) / audio_bytes_per_sample);673 }674 else675 {676 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer +677 org_waud), len / audio_bytes_per_sample);678 }679 917 680 int newLen = 0; 681 int nSamples; 682 len = WaitForFreeSpace(pSoundStretch->numSamples() * 683 audio_bytes_per_sample); 684 do 685 { 686 int samplesToGet = len/audio_bytes_per_sample; 687 if (samplesToGet > nSamplesToEnd) 918 // does not change the timecode, only the number of samples 919 // back to orig pos 920 org_waud = waud; 921 int bdiff = AUDBUFSIZE - org_waud; 922 int nSamplesToEnd = bdiff/abps; 923 if (bdiff < len) 688 924 { 689 samplesToGet = nSamplesToEnd; 925 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 926 org_waud), nSamplesToEnd); 927 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 928 (len - bdiff) / abps); 690 929 } 930 else 931 { 932 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)(audiobuffer + 933 org_waud), len / abps); 934 } 691 935 692 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 693 (audiobuffer + org_waud), samplesToGet); 694 if (nSamples == nSamplesToEnd) 936 if (encoder) 695 937 { 696 org_waud = 0; 697 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 938 // pull out a packet's worth and reencode it until we dont have enough 939 // for any more packets 940 soundtouch::SAMPLETYPE* temp_buff = 941 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 942 size_t frameSize = encoder->FrameSize()/abps; 943 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 944 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 945 .arg(frameSize) 946 .arg(encoder->FrameSize()) 947 .arg(pSoundStretch->numSamples()) 948 ); 949 // process the same number of samples as it creates a full encoded buffer 950 // just like before 951 while (pSoundStretch->numSamples() >= frameSize) 952 { 953 int got = pSoundStretch->receiveSamples(temp_buff, frameSize); 954 int amount = encoder->Encode(temp_buff); 955 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 956 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 957 .arg(amount) 958 .arg(got) 959 .arg(pSoundStretch->numSamples()) 960 ); 961 if (amount == 0) 962 continue; 963 //len = WaitForFreeSpace(amount); 964 char * ob = encoder->GetOutBuff(); 965 if (amount >= bdiff) 966 { 967 memcpy(audiobuffer + org_waud, ob, bdiff); 968 ob += bdiff; 969 amount -= bdiff; 970 org_waud = 0; 971 } 972 if (amount > 0) 973 memcpy(audiobuffer + org_waud, ob, amount); 974 bdiff = AUDBUFSIZE - amount; 975 org_waud += amount; 976 } 698 977 } 699 978 else 700 979 { 701 org_waud += nSamples * audio_bytes_per_sample; 702 nSamplesToEnd -= nSamples; 980 int newLen = 0; 981 int nSamples; 982 len = WaitForFreeSpace(pSoundStretch->numSamples() * 983 audio_bytes_per_sample); 984 do 985 { 986 int samplesToGet = len/audio_bytes_per_sample; 987 if (samplesToGet > nSamplesToEnd) 988 { 989 samplesToGet = nSamplesToEnd; 990 } 991 992 nSamples = pSoundStretch->receiveSamples((soundtouch::SAMPLETYPE*) 993 (audiobuffer + org_waud), samplesToGet); 994 if (nSamples == nSamplesToEnd) 995 { 996 org_waud = 0; 997 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 998 } 999 else 1000 { 1001 org_waud += nSamples * audio_bytes_per_sample; 1002 nSamplesToEnd -= nSamples; 1003 } 1004 1005 newLen += nSamples * audio_bytes_per_sample; 1006 len -= nSamples * audio_bytes_per_sample; 1007 } while (nSamples > 0); 703 1008 } 1009 } 704 1010 705 newLen += nSamples * audio_bytes_per_sample; 706 len -= nSamples * audio_bytes_per_sample; 707 } while (nSamples > 0); 708 } 1011 waud = org_waud; 1012 lastaudiolen = audiolen(false); 709 1013 710 waud = org_waud; 711 lastaudiolen = audiolen(false); 1014 if (timecode < 0) 1015 { 1016 // mythmusic doesn't give timestamps.. 1017 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1018 } 1019 1020 samples_buffered += samples; 1021 1022 /* we want the time at the end -- but the file format stores 1023 time at the start of the chunk. */ 1024 // even with timestretch, timecode is still calculated from original 1025 // sample count 1026 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 712 1027 713 samples_buffered += samples; 714 715 if (timecode < 0) 716 { 717 // mythmusic doesn't give timestamps.. 718 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1028 if (interleaved) 1029 dispatchVisual((unsigned char *)buffer, len, timecode, source_audio_channels, audio_bits); 719 1030 } 720 721 /* we want the time at the end -- but the file format stores722 time at the start of the chunk. */723 // even with timestretch, timecode is still calculated from original724 // sample count725 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);726 1031 727 if (interleaved)728 dispatchVisual((unsigned char *)buffer, len, timecode, audio_channels, audio_bits);729 730 1032 pthread_mutex_unlock(&audio_buflock); 731 1033 } 732 1034 … … 739 1041 740 1042 if (source_bitrate == -1) 741 1043 { 742 source_bitrate = audio_samplerate * audio_channels * audio_bits;1044 source_bitrate = audio_samplerate * source_audio_channels * audio_bits; 743 1045 } 744 1046 745 1047 if (ct / 1000 != current_seconds) … … 747 1049 current_seconds = ct / 1000; 748 1050 OutputEvent e(current_seconds, ct, 749 1051 source_bitrate, audio_samplerate, audio_bits, 750 audio_channels);1052 source_audio_channels); 751 1053 dispatch(e); 752 1054 } 753 1055 } … … 786 1088 space_on_soundcard = getSpaceOnSoundcard(); 787 1089 788 1090 if (space_on_soundcard != last_space_on_soundcard) { 789 VERBOSE(VB_AUDIO , LOC + QString("%1 bytes free on soundcard")1091 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + QString("%1 bytes free on soundcard") 790 1092 .arg(space_on_soundcard)); 791 1093 last_space_on_soundcard = space_on_soundcard; 792 1094 } … … 799 1101 WriteAudio(zeros, fragment_size); 800 1102 } else { 801 1103 // this should never happen now -dag 802 VERBOSE(VB_AUDIO , LOC +1104 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 803 1105 QString("waiting for space on soundcard " 804 1106 "to write zeros: have %1 need %2") 805 1107 .arg(space_on_soundcard).arg(fragment_size)); … … 835 1137 if (fragment_size > audiolen(true)) 836 1138 { 837 1139 if (audiolen(true) > 0) // only log if we're sending some audio 838 VERBOSE(VB_AUDIO , LOC +1140 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 839 1141 QString("audio waiting for buffer to fill: " 840 1142 "have %1 want %2") 841 1143 .arg(audiolen(true)).arg(fragment_size)); 842 1144 843 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1145 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 844 1146 pthread_mutex_lock(&audio_buflock); 845 1147 pthread_cond_broadcast(&audio_bufsig); 846 1148 pthread_mutex_unlock(&audio_buflock); … … 854 1156 if (fragment_size > space_on_soundcard) 855 1157 { 856 1158 if (space_on_soundcard != last_space_on_soundcard) { 857 VERBOSE(VB_AUDIO , LOC +1159 VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + 858 1160 QString("audio waiting for space on soundcard: " 859 1161 "have %1 need %2") 860 1162 .arg(space_on_soundcard).arg(fragment_size)); … … 916 1218 917 1219 /* update raud */ 918 1220 raud = (raud + fragment_size) % AUDBUFSIZE; 919 VERBOSE(VB_AUDIO, LOC + "Broadcasting free space avail");1221 //VERBOSE(VB_AUDIO|VB_TIMESTAMP, LOC + "Broadcasting free space avail"); 920 1222 pthread_cond_broadcast(&audio_bufsig); 921 1223 922 1224 written_size = fragment_size; -
libs/libmyth/audiooutputalsa.cpp
52 52 QString real_device = (audio_passthru) ? 53 53 audio_passthru_device : audio_main_device; 54 54 55 int index; 56 if ((index=real_device.find('|'))>=0) 57 { 58 if (audio_channels >= 2) 59 real_device = real_device.mid(index+1); 60 else 61 real_device = real_device.left(index); 62 } 63 55 64 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 65 .arg(real_device)); 57 66 … … 89 98 } 90 99 else 91 100 { 92 fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 93 buffer_time = 500000; // .5 seconds 101 //fragment_size = 6144; // nicely divisible by 2,4,6,8 channels @ 16-bits 102 //fragment_size = 3072*audio_channels; // nicely divisible by 2,4,6,8 channels @ 16-bits 103 fragment_size = (audio_bits * audio_channels * audio_samplerate) / (8*30); 104 buffer_time = 100000; // .5 seconds 94 105 period_time = buffer_time / 4; // 4 interrupts per buffer 95 106 } 96 107 … … 162 173 163 174 tmpbuf = aubuf; 164 175 165 VERBOSE(VB_AUDIO , QString("WriteAudio: Preparing %1 bytes (%2 frames)")176 VERBOSE(VB_AUDIO|VB_TIMESTAMP, QString("WriteAudio: Preparing %1 bytes (%2 frames)") 166 177 .arg(size).arg(frames)); 167 178 168 179 while (frames > 0) -
programs/mythfrontend/globalsettings.cpp
57 57 #endif 58 58 #ifdef USING_ALSA 59 59 gc->addSelection("ALSA:default", "ALSA:default"); 60 gc->addSelection("ALSA:surround51", "ALSA:surround51"); 61 gc->addSelection("ALSA:analog", "ALSA:analog"); 62 gc->addSelection("ALSA:digital", "ALSA:digital"); 63 gc->addSelection("ALSA:mixed-analog", "ALSA:mixed-analog"); 64 gc->addSelection("ALSA:mixed-digital", "ALSA:mixed-digital"); 60 65 #endif 61 66 #ifdef USING_ARTS 62 67 gc->addSelection("ARTS:", "ARTS:"); … … 78 83 return gc; 79 84 } 80 85 86 static HostComboBox *MaxAudioChannels() 87 { 88 HostComboBox *gc = new HostComboBox("MaxChannels",false); 89 gc->setLabel(QObject::tr("Max Audio Channels")); 90 gc->addSelection(QObject::tr("Stereo"), "2", true); // default 91 gc->addSelection(QObject::tr("5.1"), "6"); 92 gc->setHelpText( 93 QObject::tr("Set the maximum number of audio channels to be decoded. " 94 "This is for multi-channel/surround audio playback.")); 95 return gc; 96 } 97 98 static HostComboBox *AudioUpmixType() 99 { 100 HostComboBox *gc = new HostComboBox("AudioUpmixType",false); 101 gc->setLabel(QObject::tr("Upmix")); 102 gc->addSelection(QObject::tr("Passive"), "0"); 103 gc->addSelection(QObject::tr("Active Simple"), "1"); 104 gc->addSelection(QObject::tr("Active Linear"), "2", true); // default 105 gc->setHelpText( 106 QObject::tr("Set the audio upmix type for 2ch to 6ch conversion. " 107 "This is for multi-channel/surround audio playback.")); 108 return gc; 109 } 110 81 111 static HostComboBox *PassThroughOutputDevice() 82 112 { 83 113 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … 3156 3186 vgrp0->addChild(AC3PassThrough()); 3157 3187 vgrp0->addChild(DTSPassThrough()); 3158 3188 3189 HorizontalConfigurationGroup *agrp = 3190 new HorizontalConfigurationGroup(false, false, true, true); 3191 agrp->addChild(MaxAudioChannels()); 3192 agrp->addChild(AudioUpmixType()); 3193 addChild(agrp); 3194 3159 3195 VerticalConfigurationGroup *vgrp1 = 3160 3196 new VerticalConfigurationGroup(false, false, true, true); 3161 3197 vgrp1->addChild(AggressiveBuffer()); -
programs/mythtranscode/transcode.cpp
55 55 56 56 // reconfigure sound out for new params 57 57 virtual void Reconfigure(int audio_bits, int audio_channels, 58 int audio_samplerate, bool audio_passthru) 58 int audio_samplerate, bool audio_passthru, 59 void * = NULL) 59 60 { 61 ClearError(); 60 62 (void)audio_samplerate; 61 63 (void)audio_passthru; 62 64 bits = audio_bits; 63 65 channels = audio_channels; 64 66 bytes_per_sample = bits * channels / 8; 67 if (channels>2) 68 Error("Invalid channel count"); 65 69 } 66 70 67 71 // dsprate is in 100 * samples/second -
libs/libmythtv/avformatdecoder.h
261 261 bool allow_ac3_passthru; 262 262 bool allow_dts_passthru; 263 263 bool disable_passthru; 264 int max_channels; 264 265 VideoFrame *dummy_frame; 265 266 266 267 AudioInfo audioIn; -
libs/libmythtv/avformatdecoder.cpp
51 51 52 52 #define MAX_AC3_FRAME_SIZE 6144 53 53 54 /** Set to zero to allow any number of AC3 channels. */55 #define MAX_OUTPUT_CHANNELS 256 57 54 static int cc608_parity(uint8_t byte); 58 55 static int cc608_good_parity(const int *parity_table, uint16_t data); 59 56 static void cc608_build_parity_table(int *parity_table); … … 417 414 418 415 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 419 416 allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false); 417 max_channels = gContext->GetNumSetting("MaxChannels", 2); 420 418 421 419 audioIn.sample_size = -32; // force SetupAudioStream to run once 422 420 itv = GetNVP()->GetInteractiveTV(); … … 1587 1585 <<") already open, leaving it alone."); 1588 1586 } 1589 1587 //assert(enc->codec_id); 1588 VERBOSE(VB_GENERAL, QString("AVFD: codec %1 has %2 channels").arg(codec_id_string(enc->codec_id)).arg(enc->channels)); 1590 1589 1590 #if 0 1591 // HACK MULTICHANNEL DTS passthru disabled for multichannel, dont know how to handle this 1591 1592 // HACK BEGIN REALLY UGLY HACK FOR DTS PASSTHRU 1592 1593 if (enc->codec_id == CODEC_ID_DTS) 1593 1594 { … … 1596 1597 // enc->bit_rate = what??; 1597 1598 } 1598 1599 // HACK END REALLY UGLY HACK FOR DTS PASSTHRU 1600 #endif 1599 1601 1600 1602 bitrate += enc->bit_rate; 1601 1603 break; … … 3285 3287 3286 3288 // detect channels on streams that need 3287 3289 // to be decoded before we can know this 3290 int prev_channels = curstream->codec->channels; 3291 bool already_decoded = false; 3288 3292 if (!curstream->codec->channels) 3289 3293 { 3290 3294 QMutexLocker locker(&avcodeclock); 3291 curstream->codec->channels = MAX_OUTPUT_CHANNELS; 3295 VERBOSE(VB_IMPORTANT, LOC + QString("Setting channels to %1").arg(audioOut.channels)); 3296 curstream->codec->channels = audioOut.channels; 3297 curstream->codec->request_channels = audioOut.channels; 3292 3298 ret = avcodec_decode_audio( 3293 3299 curstream->codec, audioSamples, 3294 3300 &data_size, ptr, len); 3301 already_decoded = true; 3295 3302 3296 3303 reselectAudioTrack |= curstream->codec->channels; 3297 3304 } … … 3349 3356 AVCodecContext *ctx = curstream->codec; 3350 3357 3351 3358 if ((ctx->channels == 0) || 3352 (ctx->channels > MAX_OUTPUT_CHANNELS))3353 ctx->channels = MAX_OUTPUT_CHANNELS;3359 (ctx->channels > audioOut.channels)) 3360 ctx->channels = audioOut.channels; 3354 3361 3355 ret = avcodec_decode_audio( 3356 ctx, audioSamples, &data_size, ptr, len); 3362 if (!already_decoded) 3363 { 3364 curstream->codec->request_channels = audioOut.channels; 3365 ret = avcodec_decode_audio( 3366 ctx, audioSamples, &data_size, ptr, len); 3367 } 3357 3368 3358 3369 // When decoding some audio streams the number of 3359 3370 // channels, etc isn't known until we try decoding it. … … 3783 3794 3784 3795 void AvFormatDecoder::SetDisablePassThrough(bool disable) 3785 3796 { 3797 // can only disable never reenable as once timestretch is on its on for the session 3798 if (disable_passthru) 3799 return; 3786 3800 if (selectedTrack[kTrackTypeAudio].av_stream_index < 0) 3787 3801 { 3788 3802 disable_passthru = disable; … … 3815 3829 AVCodecContext *codec_ctx = NULL; 3816 3830 AudioInfo old_in = audioIn; 3817 3831 AudioInfo old_out = audioOut; 3832 bool using_passthru = false; 3818 3833 3819 3834 if ((currentTrack[kTrackTypeAudio] >= 0) && 3820 3835 (selectedTrack[kTrackTypeAudio].av_stream_index <= … … 3826 3841 assert(curstream->codec); 3827 3842 codec_ctx = curstream->codec; 3828 3843 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3829 !disable_passthru &&3830 3844 (codec_ctx->codec_id == CODEC_ID_AC3)); 3831 3845 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3832 !disable_passthru &&3833 3846 (codec_ctx->codec_id == CODEC_ID_DTS)); 3847 using_passthru = do_ac3_passthru || do_dts_passthru; 3834 3848 info = AudioInfo(codec_ctx->codec_id, 3835 3849 codec_ctx->sample_rate, codec_ctx->channels, 3836 do_ac3_passthru || do_dts_passthru);3850 using_passthru && !disable_passthru); 3837 3851 } 3838 3852 3839 3853 if (info == audioIn) 3840 3854 return false; // no change 3841 3855 3856 QString ptmsg = ""; 3857 if (using_passthru) 3858 { 3859 ptmsg = QString(" using passthru"); 3860 } 3842 3861 VERBOSE(VB_AUDIO, LOC + "Initializing audio parms from " + 3843 3862 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 3844 3863 3845 3864 audioOut = audioIn = info; 3846 if ( audioIn.do_passthru)3865 if (using_passthru) 3847 3866 { 3848 3867 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 3849 audioOut.channels = 2; 3850 audioOut.sample_rate = 48000; 3851 audioOut.sample_size = 4; 3868 AudioInfo digInfo = audioOut; 3869 if (!disable_passthru) 3870 { 3871 digInfo.channels = 2; 3872 digInfo.sample_rate = 48000; 3873 digInfo.sample_size = 4; 3874 } 3875 if (audioOut.channels > max_channels) 3876 { 3877 audioOut.channels = max_channels; 3878 audioOut.sample_size = audioOut.channels * 2; 3879 codec_ctx->channels = audioOut.channels; 3880 } 3881 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 3882 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 3883 .arg(digInfo.toString()) 3884 .arg(old_in.toString()).arg(old_out.toString()) 3885 .arg(audioIn.toString()).arg(audioOut.toString())); 3886 3887 if (digInfo.sample_rate > 0) 3888 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 3889 3890 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 3891 digInfo.sample_rate, audioIn.do_passthru); 3892 // allow the audio stuff to reencode 3893 GetNVP()->SetAudioCodec(codec_ctx); 3894 GetNVP()->ReinitAudio(); 3895 return true; 3852 3896 } 3853 3897 else 3854 3898 { 3855 if (audioOut.channels > MAX_OUTPUT_CHANNELS)3899 if (audioOut.channels > max_channels) 3856 3900 { 3857 audioOut.channels = MAX_OUTPUT_CHANNELS;3901 audioOut.channels = max_channels; 3858 3902 audioOut.sample_size = audioOut.channels * 2; 3859 codec_ctx->channels = MAX_OUTPUT_CHANNELS;3903 codec_ctx->channels = audioOut.channels; 3860 3904 } 3861 3905 } 3906 bool audiook; 3862 3907 3863 3908 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 3864 3909 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") … … 3871 3916 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 3872 3917 audioOut.sample_rate, 3873 3918 audioIn.do_passthru); 3874 GetNVP()->ReinitAudio(); 3919 // allow the audio stuff to reencode 3920 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL); 3921 QString errMsg = GetNVP()->ReinitAudio(); 3922 audiook = errMsg.isEmpty(); 3875 3923 3876 3924 return true; 3877 3925 } -
libs/libmythtv/NuppelVideoPlayer.h
127 127 void SetAudioInfo(const QString &main, const QString &passthru, uint rate); 128 128 void SetAudioParams(int bits, int channels, int samplerate, bool passthru); 129 129 void SetEffDsp(int dsprate); 130 void SetAudioCodec(void *ac); 130 131 131 132 // Sets 132 133 void SetParentWidget(QWidget *widget) { parentWidget = widget; } … … 683 684 int audio_bits; 684 685 int audio_samplerate; 685 686 float audio_stretchfactor; 687 void *audio_codec; 686 688 bool audio_passthru; 687 689 688 690 // Picture-in-Picture -
libs/libmythtv/NuppelVideoPlayer.cpp
206 206 audio_passthru_device(QString::null), 207 207 audio_channels(2), audio_bits(-1), 208 208 audio_samplerate(44100), audio_stretchfactor(1.0f), 209 audio_codec(NULL), 209 210 // Picture-in-Picture 210 211 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 211 212 // Preview window support … … 767 768 if (audioOutput) 768 769 { 769 770 audioOutput->Reconfigure(audio_bits, audio_channels, 770 audio_samplerate, audio_passthru); 771 audio_samplerate, audio_passthru, 772 audio_codec); 771 773 errMsg = audioOutput->GetError(); 772 774 if (!errMsg.isEmpty()) 773 775 audioOutput->SetStretchFactor(audio_stretchfactor); … … 3650 3657 audio_passthru = passthru; 3651 3658 } 3652 3659 3660 void NuppelVideoPlayer::SetAudioCodec(void* ac) 3661 { 3662 audio_codec = ac; 3663 } 3664 3653 3665 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3654 3666 { 3655 3667 if (audioOutput) -
libs/libavcodec/liba52.c
134 134 } 135 135 } 136 136 137 static inline int16_t convert(int32_t i) 138 { 139 return av_clip_int16(i - 0x43c00000); 140 } 141 142 void float2s16_2 (float * _f, int16_t * s16) 143 { 144 int i; 145 int32_t * f = (int32_t *) _f; 146 147 for (i = 0; i < 256; i++) { 148 s16[2*i] = convert (f[i]); 149 s16[2*i+1] = convert (f[i+256]); 150 } 151 } 152 153 void float2s16_4 (float * _f, int16_t * s16) 154 { 155 int i; 156 int32_t * f = (int32_t *) _f; 157 158 for (i = 0; i < 256; i++) { 159 s16[4*i] = convert (f[i]); 160 s16[4*i+1] = convert (f[i+256]); 161 s16[4*i+2] = convert (f[i+512]); 162 s16[4*i+3] = convert (f[i+768]); 163 } 164 } 165 166 void float2s16_5 (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[5*i] = convert (f[i]); 173 s16[5*i+1] = convert (f[i+256]); 174 s16[5*i+2] = convert (f[i+512]); 175 s16[5*i+3] = convert (f[i+768]); 176 s16[5*i+4] = convert (f[i+1024]); 177 } 178 } 179 180 #define LIKEAC3DEC 1 181 int channels_multi (int flags) 182 { 183 if (flags & A52_LFE) 184 return 6; 185 else if (flags & 1) /* center channel */ 186 return 5; 187 else if ((flags & A52_CHANNEL_MASK) == A52_2F2R) 188 return 4; 189 else 190 return 2; 191 } 192 193 void float2s16_multi (float * _f, int16_t * s16, int flags) 194 { 195 int i; 196 int32_t * f = (int32_t *) _f; 197 198 switch (flags) { 199 case A52_MONO: 200 for (i = 0; i < 256; i++) { 201 s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; 202 s16[5*i+4] = convert (f[i]); 203 } 204 break; 205 case A52_CHANNEL: 206 case A52_STEREO: 207 case A52_DOLBY: 208 float2s16_2 (_f, s16); 209 break; 210 case A52_3F: 211 for (i = 0; i < 256; i++) { 212 s16[5*i] = convert (f[i]); 213 s16[5*i+1] = convert (f[i+512]); 214 s16[5*i+2] = s16[5*i+3] = 0; 215 s16[5*i+4] = convert (f[i+256]); 216 } 217 break; 218 case A52_2F2R: 219 float2s16_4 (_f, s16); 220 break; 221 case A52_3F2R: 222 float2s16_5 (_f, s16); 223 break; 224 case A52_MONO | A52_LFE: 225 for (i = 0; i < 256; i++) { 226 #if LIKEAC3DEC 227 s16[6*i] = s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; 228 s16[6*i+1] = convert (f[i+256]); 229 s16[6*i+5] = convert (f[i]); 230 #else 231 s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; 232 s16[6*i+4] = convert (f[i+256]); 233 s16[6*i+5] = convert (f[i]); 234 #endif 235 } 236 break; 237 case A52_CHANNEL | A52_LFE: 238 case A52_STEREO | A52_LFE: 239 case A52_DOLBY | A52_LFE: 240 for (i = 0; i < 256; i++) { 241 #if LIKEAC3DEC 242 s16[6*i] = convert (f[i+256]); 243 s16[6*i+2] = convert (f[i+512]); 244 s16[6*i+1] = s16[6*i+3] = s16[6*i+4] = 0; 245 s16[6*i+5] = convert (f[i]); 246 #else 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 #endif 252 } 253 break; 254 case A52_3F | A52_LFE: 255 for (i = 0; i < 256; i++) { 256 #if LIKEAC3DEC 257 s16[6*i] = convert (f[i+256]); 258 s16[6*i+2] = convert (f[i+768]); 259 s16[6*i+3] = s16[6*i+4] = 0; 260 s16[6*i+1] = convert (f[i+512]); 261 s16[6*i+5] = convert (f[i]); 262 #else 263 s16[6*i] = convert (f[i+256]); 264 s16[6*i+1] = convert (f[i+768]); 265 s16[6*i+2] = s16[6*i+3] = 0; 266 s16[6*i+4] = convert (f[i+512]); 267 s16[6*i+5] = convert (f[i]); 268 #endif 269 } 270 break; 271 case A52_2F2R | A52_LFE: 272 for (i = 0; i < 256; i++) { 273 #if LIKEAC3DEC 274 s16[6*i] = convert (f[i+256]); 275 s16[6*i+1] = 0; 276 s16[6*i+2] = convert (f[i+512]); 277 s16[6*i+3] = convert (f[i+768]); 278 s16[6*i+4] = convert (f[i+1024]); 279 s16[6*i+5] = convert (f[i]); 280 #else 281 s16[6*i] = convert (f[i+256]); 282 s16[6*i+1] = convert (f[i+512]); 283 s16[6*i+2] = convert (f[i+768]); 284 s16[6*i+3] = convert (f[i+1024]); 285 s16[6*i+4] = 0; 286 s16[6*i+5] = convert (f[i]); 287 #endif 288 } 289 break; 290 case A52_3F2R | A52_LFE: 291 for (i = 0; i < 256; i++) { 292 #if LIKEAC3DEC 293 s16[6*i] = convert (f[i+256]); 294 s16[6*i+1] = convert (f[i+512]); 295 s16[6*i+2] = convert (f[i+768]); 296 s16[6*i+3] = convert (f[i+1024]); 297 s16[6*i+4] = convert (f[i+1280]); 298 s16[6*i+5] = convert (f[i]); 299 #else 300 s16[6*i] = convert (f[i+256]); 301 s16[6*i+1] = convert (f[i+768]); 302 s16[6*i+2] = convert (f[i+1024]); 303 s16[6*i+3] = convert (f[i+1280]); 304 s16[6*i+4] = convert (f[i+512]); 305 s16[6*i+5] = convert (f[i]); 306 #endif 307 } 308 break; 309 } 310 } 311 137 312 /**** end */ 138 313 139 314 #define HEADER_SIZE 7 … … 179 354 s->channels = ac3_channels[s->flags & 7]; 180 355 if (s->flags & A52_LFE) 181 356 s->channels++; 357 if (avctx->request_channels > 0) 358 { 359 avctx->channels = s->channels; 360 if (s->channels > avctx->channels) 361 avctx->channels = avctx->request_channels; 362 } 182 363 if (avctx->channels == 0) 183 364 /* No specific number of channel requested */ 184 365 avctx->channels = s->channels; … … 199 380 s->inbuf_ptr += len; 200 381 buf_size -= len; 201 382 } else { 383 int chans; 202 384 flags = s->flags; 203 385 if (avctx->channels == 1) 204 386 flags = A52_MONO; 205 else if (avctx->channels == 2) 206 flags = A52_STEREO; 387 else if (avctx->channels == 2) { 388 if (s->channels>2) 389 flags = A52_DOLBY; 390 else 391 flags = A52_STEREO; 392 } 207 393 else 208 394 flags |= A52_ADJUST_LEVEL; 209 395 level = 1; 396 chans = channels_multi(flags); 210 397 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { 211 398 fail: 212 399 av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); … … 217 404 for (i = 0; i < 6; i++) { 218 405 if (s->a52_block(s->state)) 219 406 goto fail; 220 float _to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels);407 float2s16_multi(s->samples, out_samples + i * 256 * chans, flags); 221 408 } 222 409 s->inbuf_ptr = s->inbuf; 223 410 s->frame_size = 0; -
libs/libavcodec/ac3dec.c
1132 1132 1133 1133 /* channel config */ 1134 1134 ctx->out_channels = ctx->nchans; 1135 if (avctx->request_channels > 0) 1136 { 1137 avctx->channels = ctx->out_channels; 1138 if (avctx->channels > avctx->request_channels) 1139 avctx->channels = avctx->request_channels; 1140 } 1135 1141 if (avctx->channels == 0) { 1136 1142 avctx->channels = ctx->out_channels; 1137 1143 } else if(ctx->out_channels < avctx->channels) { -
libs/libavcodec/dca.c
1159 1159 avctx->bit_rate = s->bit_rate; 1160 1160 1161 1161 channels = s->prim_channels + !!s->lfe; 1162 avctx->channels = avctx->request_channels; 1162 //avctx->channels = avctx->request_channels; 1163 if (avctx->request_channels > 0) 1164 { 1165 avctx->channels = channels; 1166 if (avctx->channels > avctx->request_channels) 1167 avctx->channels = avctx->request_channels; 1168 } 1163 1169 if(avctx->channels == 0) { 1164 1170 avctx->channels = channels; 1165 1171 } else if(channels < avctx->channels) {