Ticket #5900: audioencoding-fixes-2.patch
File audioencoding-fixes-2.patch, 77.3 KB (added by , 15 years ago) |
---|
-
mythplugins/mythmusic/mythmusic/main.cpp
diff --git a/mythplugins/mythmusic/mythmusic/main.cpp b/mythplugins/mythmusic/mythmusic/main.cpp index 0ab4b45..490aab3 100644
a b void setupKeys(void) 378 378 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 379 379 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 380 380 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 381 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 381 382 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 382 383 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 383 384 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
mythplugins/mythmusic/mythmusic/playbackbox.cpp
diff --git a/mythplugins/mythmusic/mythmusic/playbackbox.cpp b/mythplugins/mythmusic/mythmusic/playbackbox.cpp index b3a8f61..b9885cb 100644
a b void PlaybackBoxMusic::keyPressEvent(QKeyEvent *e) 358 358 changeSpeed(true); 359 359 else if (action == "MUTE") 360 360 toggleMute(); 361 else if (action == "TOGGLEUPMIX") 362 toggleUpmix(); 361 363 else if (action == "MENU" && visualizer_status != 2) 362 364 { 363 365 menufilters = false; … … void PlaybackBoxMusic::toggleMute() 1175 1177 } 1176 1178 } 1177 1179 1180 void PlaybackBoxMusic::toggleUpmix() 1181 { 1182 if (gPlayer->getOutput()) 1183 gPlayer->getOutput()->ToggleUpmix(); 1184 } 1185 1186 1178 1187 void PlaybackBoxMusic::showProgressBar() 1179 1188 { 1180 1189 if (progress_bar) -
mythplugins/mythmusic/mythmusic/playbackbox.h
diff --git a/mythplugins/mythmusic/mythmusic/playbackbox.h b/mythplugins/mythmusic/mythmusic/playbackbox.h index 038ad97..2950d0b 100644
a b class PlaybackBoxMusic : public MythThemedDialog 69 69 void changeVolume(bool up_or_down); 70 70 void changeSpeed(bool up_or_down); 71 71 void toggleMute(); 72 void toggleUpmix(); 72 73 void resetTimer(); 73 74 void hideVolume(){showVolume(false);} 74 75 void showVolume(bool on_or_off); -
mythtv/libs/libmyth/audiooutput.h
diff --git a/mythtv/libs/libmyth/audiooutput.h b/mythtv/libs/libmyth/audiooutput.h index 7d65a51..b88c29f 100644
a b class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners 34 34 virtual void Reconfigure(int audio_bits, 35 35 int audio_channels, 36 36 int audio_samplerate, 37 bool audio_passthru, 38 void* audio_codec = NULL) = 0; 37 bool audio_passthru) = 0; 39 38 40 39 virtual void SetStretchFactor(float factor); 41 40 virtual float GetStretchFactor(void) { return 1.0f; } 41 virtual bool ToggleUpmix(void) = 0; 42 42 43 43 // do AddSamples calls block? 44 44 virtual void SetBlocking(bool blocking) = 0; -
mythtv/libs/libmyth/audiooutputalsa.cpp
diff --git a/mythtv/libs/libmyth/audiooutputalsa.cpp b/mythtv/libs/libmyth/audiooutputalsa.cpp index ba86f3b..0576276 100644
a b AudioOutputALSA::~AudioOutputALSA() 37 37 KillAudio(); 38 38 } 39 39 40 void SetIECBits(bool audio) { 41 42 snd_ctl_t *ctl; 43 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 44 int spdif_index = -1; 45 snd_ctl_elem_list_t *clist; 46 snd_ctl_elem_id_t *cid; 47 snd_ctl_elem_value_t *cval; 48 snd_aes_iec958_t iec958; 49 int cidx, controls; 50 51 VERBOSE(VB_GENERAL, QString("Setting IEC958 status bits")); 52 53 snd_ctl_open(&ctl, "default", 0); 54 snd_ctl_elem_list_alloca(&clist); 55 snd_ctl_elem_list(ctl, clist); 56 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 57 snd_ctl_elem_list(ctl, clist); 58 controls = snd_ctl_elem_list_get_used(clist); 59 for (cidx = 0; cidx < controls; cidx++) { 60 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 61 if (spdif_index < 0 || 62 snd_ctl_elem_list_get_index(clist, cidx) == spdif_index) 63 break; 64 } 65 snd_ctl_elem_id_alloca(&cid); 66 snd_ctl_elem_list_get_id(clist, cidx, cid); 67 snd_ctl_elem_value_alloca(&cval); 68 snd_ctl_elem_value_set_id(cval, cid); 69 snd_ctl_elem_read(ctl,cval); 70 snd_ctl_elem_value_get_iec958(cval, &iec958); 71 72 if (!audio) 73 iec958.status[0] |= IEC958_AES0_NONAUDIO; 74 else 75 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 76 77 snd_ctl_elem_value_set_iec958(cval, &iec958); 78 snd_ctl_elem_write(ctl, cval); 79 80 } 81 40 82 bool AudioOutputALSA::OpenDevice() 41 83 { 42 84 snd_pcm_format_t format; 43 85 unsigned int buffer_time, period_time; 44 86 int err; 87 QString real_device; 45 88 46 89 if (pcm_handle != NULL) 47 90 CloseDevice(); 48 91 49 92 pcm_handle = NULL; 50 93 numbadioctls = 0; 51 52 QString real_device = (audio_passthru) ? 53 audio_passthru_device : audio_main_device; 94 95 if (audio_passthru || audio_enc) 96 { 97 real_device = audio_passthru_device; 98 SetIECBits(false); 99 } 100 else 101 { 102 real_device = audio_main_device; 103 SetIECBits(true); 104 } 54 105 55 106 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 56 107 .arg(real_device)); -
mythtv/libs/libmyth/audiooutputbase.cpp
diff --git a/mythtv/libs/libmyth/audiooutputbase.cpp b/mythtv/libs/libmyth/audiooutputbase.cpp index 883136d..c211c10 100644
a b AudioOutputBase::AudioOutputBase( 37 37 38 38 audio_main_device(QDeepCopy<QString>(laudio_main_device)), 39 39 audio_passthru_device(QDeepCopy<QString>(laudio_passthru_device)), 40 audio_passthru(false), audio_stretchfactor(1.0f), 40 audio_passthru(false), audio_enc(false), 41 audio_reenc(false), audio_stretchfactor(1.0f), 41 42 42 audio_codec(NULL),43 43 source(lsource), killaudio(false), 44 44 45 45 pauseaudio(false), audio_actually_paused(false), … … AudioOutputBase::AudioOutputBase( 54 54 pSoundStretch(NULL), 55 55 encoder(NULL), 56 56 upmixer(NULL), 57 57 58 source_audio_channels(-1), 59 source_audio_samplerate(0), 58 60 source_audio_bytes_per_sample(0), 59 61 needs_upmix(false), 60 62 surround_mode(FreeSurround::SurroundModePassive), 63 old_audio_stretchfactor(1.0), 61 64 62 65 blocking(false), 63 66 … … AudioOutputBase::AudioOutputBase( 84 87 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 85 88 memset(audiobuffer, 0, sizeof(char) * AUDBUFSIZE); 86 89 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 90 disable_resampler = gContext->GetNumSetting("DisableResampler", 0); 87 91 88 92 // You need to call Reconfigure from your concrete class. 89 93 // Reconfigure(laudio_bits, laudio_channels, … … void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 124 128 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 129 .arg(audio_stretchfactor)); 126 130 pSoundStretch = new soundtouch::SoundTouch(); 127 if (audio_codec) 128 { 129 if (!encoder) 130 { 131 VERBOSE(VB_AUDIO, LOC + 132 QString("Creating Encoder for codec %1 origfs %2") 133 .arg(audio_codec->codec_id) 134 .arg(audio_codec->frame_size)); 135 136 encoder = new AudioOutputDigitalEncoder(); 137 if (!encoder->Init(audio_codec->codec_id, 138 audio_codec->bit_rate, 139 audio_codec->sample_rate, 140 audio_codec->channels 141 )) 142 { 143 // eeks 144 delete encoder; 145 encoder = NULL; 146 VERBOSE(VB_AUDIO, LOC + 147 QString("Failed to Create Encoder")); 148 } 149 } 150 } 151 if (audio_codec && encoder) 152 { 153 pSoundStretch->setSampleRate(audio_codec->sample_rate); 154 pSoundStretch->setChannels(audio_codec->channels); 155 } 156 else 157 { 158 pSoundStretch->setSampleRate(audio_samplerate); 159 pSoundStretch->setChannels(audio_channels); 160 } 131 pSoundStretch->setSampleRate(audio_samplerate); 132 pSoundStretch->setChannels(upmixer ? 133 configured_audio_channels : source_audio_channels); 161 134 162 135 pSoundStretch->setTempo(audio_stretchfactor); 163 136 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 165 138 // dont need these with only tempo change 166 139 //pSoundStretch->setPitch(1.0); 167 140 //pSoundStretch->setRate(1.0); 168 169 141 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 142 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 143 } … … float AudioOutputBase::GetStretchFactor(void) 184 156 return audio_stretchfactor; 185 157 } 186 158 159 bool AudioOutputBase::ToggleUpmix(void) 160 { 161 if (audio_passthru) 162 return false; 163 if (configured_audio_channels == 6) 164 configured_audio_channels = 2; 165 else 166 configured_audio_channels = 6; 167 168 Reconfigure(audio_bits, source_audio_channels, 169 source_audio_samplerate, audio_passthru); 170 return (configured_audio_channels == 6); 171 } 172 187 173 void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 188 int laudio_samplerate, bool laudio_passthru, 189 void *laudio_codec) 174 int laudio_samplerate, bool laudio_passthru) 190 175 { 191 int codec_id = CODEC_ID_NONE;192 int lcodec_id = CODEC_ID_NONE;193 int lcchannels = 0;194 int cchannels = 0;195 176 int lsource_audio_channels = laudio_channels; 196 177 bool lneeds_upmix = false; 197 198 if (laudio_codec) 199 { 200 lcodec_id = ((AVCodecContext*)laudio_codec)->codec_id; 201 laudio_bits = 16; 202 laudio_channels = 2; 203 lsource_audio_channels = laudio_channels; 204 laudio_samplerate = 48000; 205 lcchannels = ((AVCodecContext*)laudio_codec)->channels; 206 } 207 208 if (audio_codec) 209 { 210 codec_id = audio_codec->codec_id; 211 cchannels = ((AVCodecContext*)audio_codec)->channels; 212 } 213 214 if ((configured_audio_channels == 6) && 215 !(laudio_codec || audio_codec)) 178 bool laudio_reenc = false; 179 180 // Are we reencoding a (previously) timestretched bitstream? 181 if (laudio_channels > 2 && !laudio_passthru) 182 laudio_reenc = true; 183 184 // Enough channels? Upmix if not 185 if (laudio_channels < configured_audio_channels && !laudio_passthru) 216 186 { 217 187 laudio_channels = configured_audio_channels; 218 188 lneeds_upmix = true; … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 225 195 laudio_samplerate == audio_samplerate && !need_resampler && 226 196 laudio_passthru == audio_passthru && 227 197 lneeds_upmix == needs_upmix && 228 l codec_id == codec_id && lcchannels == cchannels);198 laudio_reenc == audio_reenc); 229 199 bool upmix_deps = 230 200 (lsource_audio_channels == source_audio_channels); 231 201 if (general_deps && upmix_deps) … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 252 222 waud = raud = 0; 253 223 audio_actually_paused = false; 254 224 255 bool redo_stretch = (pSoundStretch && audio_channels != laudio_channels);256 225 audio_channels = laudio_channels; 257 226 source_audio_channels = lsource_audio_channels; 258 227 audio_bits = laudio_bits; 259 audio_samplerate = laudio_samplerate;260 audio_ codec = (AVCodecContext*)laudio_codec;228 source_audio_samplerate = audio_samplerate = laudio_samplerate; 229 audio_reenc = laudio_reenc; 261 230 audio_passthru = laudio_passthru; 262 231 needs_upmix = lneeds_upmix; 263 232 … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 268 237 Error("AudioOutput only supports 8 or 16bit audio."); 269 238 return; 270 239 } 271 audio_bytes_per_sample = audio_channels * audio_bits / 8;272 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;273 240 274 241 need_resampler = false; 275 242 killaudio = false; … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 278 245 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 279 246 280 247 numlowbuffer = 0; 248 249 // Encode to AC-3 if not passing thru, there's more than 2 channels 250 // and a passhru device is defined 251 // This won't reencode timestretched 2ch AC-3 but there's no point doing so 252 if (!audio_passthru && audio_channels > 2 && 253 !audio_passthru_device.isEmpty()) 254 { 255 int srate = disable_resampler ? audio_samplerate : 48000; 256 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 257 encoder = new AudioOutputDigitalEncoder(); 258 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 259 audio_channels, audio_reenc)) 260 { 261 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 262 delete encoder; 263 encoder = NULL; 264 } 265 audio_channels = 2; 266 audio_enc = true; 267 } 268 269 if(audio_passthru) 270 // Soundcard expects a 2ch 48k stream 271 audio_channels = 2; 272 273 audio_bytes_per_sample = audio_channels * audio_bits / 8; 274 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 281 275 276 // Always resample to 48k - many cards can't do anything else 277 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 278 if (!disable_resampler && audio_samplerate != 48000) 279 { 280 int error; 281 audio_samplerate = 48000; 282 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 283 .arg(laudio_samplerate).arg(audio_samplerate)); 284 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error); 285 if (error) 286 { 287 Error(QString("Error creating resampler, the error was: %1") 288 .arg(src_strerror(error)) ); 289 pthread_mutex_unlock(&avsync_lock); 290 pthread_mutex_unlock(&audio_buflock); 291 src_ctx = NULL; 292 return; 293 } 294 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate; 295 src_data.data_in = src_in; 296 src_data.data_out = src_out; 297 src_data.output_frames = 16384*6; 298 need_resampler = true; 299 } 300 282 301 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 283 302 .arg(audio_main_device).arg(audio_channels) 284 303 .arg(source_audio_channels).arg(audio_samplerate)); … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 314 333 current_seconds = -1; 315 334 source_bitrate = -1; 316 335 317 // NOTE: this won't do anything as above samplerate vars are set equal318 // Check if we need the resampler319 if (audio_samplerate != laudio_samplerate)320 {321 int error;322 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")323 .arg(laudio_samplerate).arg(audio_samplerate));324 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);325 if (error)326 {327 Error(QString("Error creating resampler, the error was: %1")328 .arg(src_strerror(error)) );329 pthread_mutex_unlock(&avsync_lock);330 pthread_mutex_unlock(&audio_buflock);331 return;332 }333 src_data.src_ratio = (double) audio_samplerate / laudio_samplerate;334 src_data.data_in = src_in;335 src_data.data_out = src_out;336 src_data.output_frames = 16384*6;337 need_resampler = true;338 }339 340 336 if (needs_upmix) 341 337 { 342 338 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … void AudioOutputBase::Reconfigure(int laudio_bits, int laudio_channels, 351 347 (FreeSurround::SurroundMode)surround_mode); 352 348 353 349 VERBOSE(VB_AUDIO, LOC + 354 QString(" create upmixer done with surround mode %1")350 QString("Create upmixer done with surround mode %1") 355 351 .arg(surround_mode)); 356 352 } 357 353 358 354 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 359 355 .arg(audio_stretchfactor)); 360 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")361 .arg((audio_codec) ?362 codec_id_string(audio_codec->codec_id) : "not set"));363 356 364 if (redo_stretch) 365 { 366 float laudio_stretchfactor = audio_stretchfactor; 367 delete pSoundStretch; 368 pSoundStretch = NULL; 369 audio_stretchfactor = 0.0f; 370 SetStretchFactorLocked(laudio_stretchfactor); 371 } 372 else 373 { 374 SetStretchFactorLocked(audio_stretchfactor); 375 if (pSoundStretch) 376 { 377 // if its passthru then we need to reencode 378 if (audio_codec) 379 { 380 if (!encoder) 381 { 382 VERBOSE(VB_AUDIO, LOC + 383 QString("Creating Encoder for codec %1") 384 .arg(audio_codec->codec_id)); 385 386 encoder = new AudioOutputDigitalEncoder(); 387 if (!encoder->Init(audio_codec->codec_id, 388 audio_codec->bit_rate, 389 audio_codec->sample_rate, 390 audio_codec->channels 391 )) 392 { 393 // eeks 394 delete encoder; 395 encoder = NULL; 396 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder"); 397 } 398 } 399 } 400 if (audio_codec && encoder) 401 { 402 pSoundStretch->setSampleRate(audio_codec->sample_rate); 403 pSoundStretch->setChannels(audio_codec->channels); 404 } 405 else 406 { 407 pSoundStretch->setSampleRate(audio_samplerate); 408 pSoundStretch->setChannels(audio_channels); 409 } 410 } 411 } 357 SetStretchFactorLocked(old_audio_stretchfactor); 412 358 413 359 // Setup visualisations, zero the visualisations buffers 414 360 prepareVisuals(); … … void AudioOutputBase::KillAudio() 455 401 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 456 402 killaudio = true; 457 403 StopOutputThread(); 404 405 pthread_mutex_lock(&audio_buflock); 458 406 459 407 // Close resampler? 460 408 if (src_ctx) 409 { 461 410 src_delete(src_ctx); 411 src_ctx = NULL; 412 } 413 462 414 need_resampler = false; 463 415 464 416 // close sound stretcher … … void AudioOutputBase::KillAudio() 466 418 { 467 419 delete pSoundStretch; 468 420 pSoundStretch = NULL; 421 old_audio_stretchfactor = audio_stretchfactor; 422 audio_stretchfactor = 1.0; 469 423 } 470 424 471 425 if (encoder) … … void AudioOutputBase::KillAudio() 480 434 upmixer = NULL; 481 435 } 482 436 needs_upmix = false; 437 audio_enc = false; 483 438 484 439 CloseDevice(); 485 440 441 pthread_mutex_unlock(&audio_buflock); 486 442 killAudioLock.unlock(); 487 443 } 488 444 … … int AudioOutputBase::GetAudiotime(void) 591 547 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 592 548 ret = (long long)(ret * audio_stretchfactor); 593 549 594 #if 1595 550 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 596 551 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 597 552 .arg(now.tv_sec).arg(now.tv_usec) … … int AudioOutputBase::GetAudiotime(void) 600 555 .arg(audiotime) 601 556 .arg(audio_stretchfactor) 602 557 ); 603 #endif604 558 605 559 ret += audiotime; 606 560 … … void AudioOutputBase::SetAudiotime(void) 638 592 639 593 soundcard_buffer = getBufferedOnSoundcard(); // bytes 640 594 totalbuffer = audiolen(false) + soundcard_buffer; 641 595 642 596 // include algorithmic latencies 643 597 if (pSoundStretch) 644 {645 // add the effect of any unused but processed samples,646 // AC3 reencode does this647 totalbuffer += (int)(pSoundStretch->numSamples() *648 audio_bytes_per_sample);649 // add the effect of unprocessed samples in time stretch algo650 598 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 651 599 audio_bytes_per_sample) / audio_stretchfactor); 652 }653 600 654 601 if (upmixer && needs_upmix) 655 {656 602 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 657 } 603 604 if (encoder) 605 totalbuffer += encoder->Buffered(); 658 606 659 607 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 660 608 (audio_bytes_per_sample * effdspstretched)); 661 609 662 610 gettimeofday(&audiotime_updated, NULL); 663 #if 1 611 664 612 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 665 613 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 666 614 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … void AudioOutputBase::SetAudiotime(void) 672 620 .arg(effdspstretched) 673 621 .arg(audio_bytes_per_sample) 674 622 .arg(audio_stretchfactor)); 675 #endif676 623 677 624 pthread_mutex_unlock(&avsync_lock); 678 625 pthread_mutex_unlock(&audio_buflock); … … bool AudioOutputBase::AddSamples(char *buffers[], int samples, 708 655 709 656 return false; // would overflow 710 657 } 658 659 pthread_mutex_lock(&audio_buflock); 711 660 712 661 // resample input if necessary 713 662 if (need_resampler && src_ctx) … … bool AudioOutputBase::AddSamples(char *buffers[], int samples, 741 690 // Call our function to do the work 742 691 _AddSamples(buffers, false, samples, timecode); 743 692 } 693 694 pthread_mutex_unlock(&audio_buflock); 744 695 745 696 return true; 746 697 } … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 776 727 .arg(timecode)); 777 728 return false; // would overflow 778 729 } 730 731 pthread_mutex_lock(&audio_buflock); 779 732 780 733 // resample input if necessary 781 734 if (need_resampler && src_ctx) … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 804 757 // Call our function to do the work 805 758 _AddSamples(buffer, true, samples, timecode); 806 759 } 760 761 pthread_mutex_unlock(&audio_buflock); 807 762 808 763 return true; 809 764 } … … int AudioOutputBase::WaitForFreeSpace(int samples) 836 791 if (src_ctx) 837 792 { 838 793 int error = src_reset(src_ctx); 839 if (error) 794 if (error) 795 { 840 796 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 841 797 "Error occured while resetting resampler: %1") 842 798 .arg(src_strerror(error))); 799 src_ctx = NULL; 800 } 843 801 } 844 802 } 845 803 } … … int AudioOutputBase::WaitForFreeSpace(int samples) 849 807 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 850 808 long long timecode) 851 809 { 852 pthread_mutex_lock(&audio_buflock);853 854 810 int len; // = samples * audio_bytes_per_sample; 855 811 int audio_bytes = audio_bits / 8; 856 812 int org_waud = waud; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 871 827 if (upmixer && needs_upmix) 872 828 { 873 829 int out_samples = 0; 830 org_waud = waud; 874 831 int step = (interleaved)?source_audio_channels:1; 875 832 len = WaitForFreeSpace(samples); // test 833 876 834 for (int itemp = 0; itemp < samples; ) 877 835 { 878 // just in case it does a processing cycle, release the lock879 // to allow the output loop to do output880 pthread_mutex_unlock(&audio_buflock);881 836 if (audio_bytes == 2) 882 837 { 883 838 itemp += upmixer->putSamples( … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 894 849 source_audio_channels, 895 850 (interleaved) ? 0 : samples); 896 851 } 897 pthread_mutex_lock(&audio_buflock);898 852 899 853 int copy_samples = upmixer->numSamples(); 900 854 if (copy_samples) … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 913 867 (short*)(audiobuffer), (copy_samples - bdiff_samples)); 914 868 } 915 869 else 916 {917 870 upmixer->receiveSamples( 918 871 (short*)(audiobuffer + org_waud), copy_samples); 919 }872 920 873 org_waud = (org_waud + copy_len) % AUDBUFSIZE; 921 874 } 922 875 } … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 969 922 { 970 923 if (pSoundStretch) 971 924 { 972 973 925 // does not change the timecode, only the number of samples 974 926 // back to orig pos 975 927 org_waud = waud; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 984 936 (len - bdiff) / abps); 985 937 } 986 938 else 987 {988 939 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 989 940 (audiobuffer + org_waud), 990 941 len / abps); 991 }992 942 993 if (encoder) 943 int nSamples = pSoundStretch->numSamples(); 944 len = WaitForFreeSpace(nSamples); 945 946 while ((nSamples = pSoundStretch->numSamples())) 994 947 { 995 // pull out a packet's worth and reencode it until we 996 // don't have enough for any more packets 997 soundtouch::SAMPLETYPE *temp_buff = 998 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer(); 999 size_t frameSize = encoder->FrameSize()/abps; 1000 1001 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1002 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 1003 .arg(frameSize) 1004 .arg(encoder->FrameSize()) 1005 .arg(pSoundStretch->numSamples())); 1006 1007 // process the same number of samples as it creates 1008 // a full encoded buffer just like before 1009 while (pSoundStretch->numSamples() >= frameSize) 1010 { 1011 int got = pSoundStretch->receiveSamples( 1012 temp_buff, frameSize); 1013 int amount = encoder->Encode(temp_buff); 1014 1015 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 1016 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 1017 .arg(amount) 1018 .arg(got) 1019 .arg(pSoundStretch->numSamples())); 1020 1021 if (!amount) 1022 continue; 1023 1024 //len = WaitForFreeSpace(amount); 1025 char *ob = encoder->GetOutBuff(); 1026 if (amount >= bdiff) 1027 { 1028 memcpy(audiobuffer + org_waud, ob, bdiff); 1029 ob += bdiff; 1030 amount -= bdiff; 1031 org_waud = 0; 1032 } 1033 if (amount > 0) 1034 memcpy(audiobuffer + org_waud, ob, amount); 1035 1036 bdiff = AUDBUFSIZE - amount; 1037 org_waud += amount; 948 if (nSamples > nSamplesToEnd) 949 nSamples = nSamplesToEnd; 950 951 nSamples = pSoundStretch->receiveSamples( 952 (soundtouch::SAMPLETYPE*) 953 (audiobuffer + org_waud), nSamples 954 ); 955 956 if (nSamples == nSamplesToEnd) { 957 org_waud = 0; 958 nSamplesToEnd = AUDBUFSIZE/abps; 959 } 960 else { 961 org_waud += nSamples * abps; 962 nSamplesToEnd -= nSamples; 1038 963 } 964 1039 965 } 1040 else 966 967 } 968 969 // Encode to AC-3? 970 if (encoder) 971 { 972 973 org_waud = waud; 974 int bdiff = AUDBUFSIZE - org_waud; 975 int to_get = 0; 976 977 if (bdiff < len) 978 { 979 encoder->Encode(audiobuffer + org_waud, bdiff); 980 to_get = encoder->Encode(audiobuffer, len - bdiff); 981 } 982 else 983 to_get = encoder->Encode(audiobuffer + org_waud, len); 984 985 if (to_get > 0) 1041 986 { 1042 int newLen = 0; 1043 int nSamples; 1044 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1045 audio_bytes_per_sample); 1046 do 987 988 if (to_get >= bdiff) 1047 989 { 1048 int samplesToGet = len/audio_bytes_per_sample; 1049 if (samplesToGet > nSamplesToEnd) 1050 { 1051 samplesToGet = nSamplesToEnd; 1052 } 1053 1054 nSamples = pSoundStretch->receiveSamples( 1055 (soundtouch::SAMPLETYPE*) 1056 (audiobuffer + org_waud), samplesToGet); 1057 if (nSamples == nSamplesToEnd) 1058 { 1059 org_waud = 0; 1060 nSamplesToEnd = AUDBUFSIZE/audio_bytes_per_sample; 1061 } 1062 else 1063 { 1064 org_waud += nSamples * audio_bytes_per_sample; 1065 nSamplesToEnd -= nSamples; 1066 } 1067 1068 newLen += nSamples * audio_bytes_per_sample; 1069 len -= nSamples * audio_bytes_per_sample; 1070 } while (nSamples > 0); 990 encoder->GetFrames(audiobuffer + org_waud, bdiff); 991 to_get -= bdiff; 992 org_waud = 0; 993 } 994 if (to_get > 0) 995 encoder->GetFrames(audiobuffer + org_waud, to_get); 996 997 org_waud += to_get; 998 1071 999 } 1000 1072 1001 } 1073 1002 1074 1003 waud = org_waud; 1075 1004 lastaudiolen = audiolen(false); 1076 1005 1077 1006 if (timecode < 0) 1078 {1079 1007 // mythmusic doesn't give timestamps.. 1080 1008 timecode = (int)((samples_buffered * 100000.0) / effdsp); 1081 }1082 1009 1083 1010 samples_buffered += samples; 1084 1011 … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 1090 1017 1091 1018 if (interleaved) 1092 1019 { 1020 // Give original samples to mythmusic visualisation 1093 1021 dispatchVisual((unsigned char *)buffer, len, timecode, 1094 1022 source_audio_channels, audio_bits); 1095 1023 } 1096 1024 } 1097 1025 1098 pthread_mutex_unlock(&audio_buflock);1099 1026 } 1100 1027 1101 1028 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiooutputbase.h
diff --git a/mythtv/libs/libmyth/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h index d60c687..b46ed79 100644
a b class AudioOutputBase : public AudioOutput 48 48 virtual void Reconfigure(int audio_bits, 49 49 int audio_channels, 50 50 int audio_samplerate, 51 bool audio_passthru, 52 void *audio_codec = NULL); 51 bool audio_passthru); 53 52 54 53 // do AddSamples calls block? 55 54 virtual void SetBlocking(bool blocking); … … class AudioOutputBase : public AudioOutput 59 58 60 59 virtual void SetStretchFactor(float factor); 61 60 virtual float GetStretchFactor(void); 61 virtual bool ToggleUpmix(void); 62 62 63 63 virtual void Reset(void); 64 64 … … class AudioOutputBase : public AudioOutput 139 139 QString audio_passthru_device; 140 140 141 141 bool audio_passthru; 142 bool audio_enc; 143 bool audio_reenc; 142 144 143 145 float audio_stretchfactor; 144 AVCodecContext *audio_codec;145 146 AudioOutputSource source; 146 147 147 148 bool killaudio; … … class AudioOutputBase : public AudioOutput 151 152 bool buffer_output_data_for_use; // used by AudioOutputNULL 152 153 153 154 int configured_audio_channels; 155 bool disable_resampler; 154 156 155 157 private: 156 158 // resampler … … class AudioOutputBase : public AudioOutput 167 169 FreeSurround *upmixer; 168 170 169 171 int source_audio_channels; 172 int source_audio_samplerate; 170 173 int source_audio_bytes_per_sample; 171 174 bool needs_upmix; 172 175 int surround_mode; 176 float old_audio_stretchfactor; 173 177 174 178 bool blocking; // do AddSamples calls block? 175 179 -
mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
diff --git a/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp b/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp index 40c4acb..5bd2c01 100644
a b extern "C" { 27 27 28 28 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 29 29 av_context(NULL), 30 outbuf (NULL),31 outbuf_size(0),32 frame_buffer(NULL),33 one_frame_bytes(0)30 outbuflen(0), 31 inbuflen(0), 32 one_frame_bytes(0), 33 reorder(true) 34 34 { 35 35 } 36 36 … … void AudioOutputDigitalEncoder::Dispose() 47 47 av_free(av_context); 48 48 av_context = NULL; 49 49 } 50 51 if (outbuf)52 {53 delete [] outbuf;54 outbuf = NULL;55 outbuf_size = 0;56 }57 58 if (frame_buffer)59 {60 delete [] frame_buffer;61 frame_buffer = NULL;62 one_frame_bytes = 0;63 }64 50 } 65 51 66 52 //CODEC_ID_AC3 67 53 bool AudioOutputDigitalEncoder::Init( 68 CodecID codec_id, int bitrate, int samplerate, int channels )54 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 69 55 { 70 56 AVCodec *codec; 71 57 int ret; 72 58 73 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")59 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 74 60 .arg(codec_id_string(codec_id)) 75 61 .arg(bitrate) 76 62 .arg(samplerate) 77 .arg(channels)); 78 79 //codec = avcodec_find_encoder(codec_id); 63 .arg(channels) 64 .arg(reencoding)); 65 66 reorder = !reencoding; 67 68 // We need to do this when called from mythmusic 69 avcodec_init(); 70 avcodec_register_all(); 80 71 // always AC3 as there is no DTS encoder at the moment 2005/1/9 81 72 codec = avcodec_find_encoder(CODEC_ID_AC3); 82 73 if (!codec) … … bool AudioOutputDigitalEncoder::Init( 105 96 audio_bytes_per_sample = bytes_per_frame; 106 97 one_frame_bytes = bytes_per_frame * av_context->frame_size; 107 98 108 outbuf_size = 16384; // ok for AC3 but DTS?109 outbuf = new char [outbuf_size];110 99 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 111 100 .arg(av_context->frame_size) 112 101 .arg(bytes_per_frame) … … typedef struct { 256 245 257 246 } AESHeader; 258 247 248 249 void reorder_6ch_ac3(void *buf, unsigned int len) { 250 unsigned short *src = (unsigned short *)buf; 251 unsigned short tmp; 252 unsigned int samples = len >> 1; 253 254 for (uint i = 0; i < samples; i += 6) { 255 tmp = src[i+4]; 256 src[i+4] = src[i+3]; 257 src[i+3] = src[i+2]; 258 src[i+2] = src[i+1]; 259 src[i+1] = tmp; 260 } 261 } 262 259 263 static int encode_frame( 260 264 bool dts, 261 265 unsigned char *data, 262 size_t &len)266 size_t enc_len) 263 267 { 264 size_t enc_len;265 268 int flags, sample_rate, bit_rate; 266 269 267 270 // we don't do any length/crc validation of the AC3 frame here; presumably … … static int encode_frame( 273 276 // anything with a bad CRC... 274 277 275 278 uint nr_samples = 0, block_len; 279 276 280 if (dts) 277 281 { 278 282 enc_len = dts_syncinfo(data+8, &flags, &sample_rate, &bit_rate); … … static int encode_frame( 293 297 #endif 294 298 } 295 299 296 if (enc_len == 0 || enc_len > len)297 {298 int l = len;299 len = 0;300 return l;301 }302 303 300 enc_len = min((uint)enc_len, block_len - 8); 304 301 305 302 //uint32_t x = *(uint32_t*)(data+8); 306 303 // in place swab 307 304 swab((const char *)data + 8, (char *)data + 8, enc_len); … … static int encode_frame( 348 345 break; 349 346 } 350 347 } 351 data[5] = 0 x00;348 data[5] = 0; 352 349 data[6] = (enc_len << 3) & 0xFF; 353 350 data[7] = (enc_len >> 5) & 0xFF; 354 351 memset(data + 8 + enc_len, 0, block_len - 8 - enc_len); 355 len = block_len;356 352 357 353 return enc_len; 358 354 } 359 355 360 // must have exactly 1 frames worth of data 361 size_t AudioOutputDigitalEncoder::Encode(short *buff) 356 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 362 357 { 363 int encsize = 0;364 358 size_t outsize = 0; 365 359 366 // put data in the correct spot for encode frame 367 outsize = avcodec_encode_audio( 368 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff); 360 int fs = FrameSize(); 361 memcpy(inbuf+inbuflen, buf, len); 362 inbuflen += len; 363 int frames = inbuflen / fs; 369 364 370 size_t tmpsize = outsize; 371 372 outsize = MAX_AC3_FRAME_SIZE; 373 encsize = encode_frame( 374 /*av_context->codec_id==CODEC_ID_DTS*/ false, 375 (unsigned char*)outbuf, outsize); 365 while (frames--) 366 { 367 if (reorder) 368 reorder_6ch_ac3(inbuf, fs); 369 370 // put data in the correct spot for encode frame 371 outsize = avcodec_encode_audio( 372 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 373 374 encode_frame( 375 /*av_context->codec_id==CODEC_ID_DTS*/ false, 376 (unsigned char*)outbuf + outbuflen, outsize 377 ); 378 379 outbuflen += MAX_AC3_FRAME_SIZE; 380 inbuflen -= fs; 381 memmove(inbuf, inbuf+fs, inbuflen); 382 } 376 383 377 VERBOSE(VB_AUDIO|VB_TIMESTAMP, 378 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 379 .arg(tmpsize).arg(encsize).arg(outsize)); 384 return outbuflen; 385 } 380 386 381 return outsize; 387 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 388 { 389 int len = (maxlen < outbuflen ? maxlen : outbuflen); 390 memcpy(ptr, outbuf, len); 391 outbuflen -= len; 392 memmove(outbuf, outbuf+len, outbuflen); 382 393 } -
mythtv/libs/libmyth/audiooutputdigitalencoder.h
diff --git a/mythtv/libs/libmyth/audiooutputdigitalencoder.h b/mythtv/libs/libmyth/audiooutputdigitalencoder.h index 8a4689a..47e19af 100644
a b extern "C" { 5 5 #include "libavcodec/avcodec.h" 6 6 }; 7 7 8 #define INBUFSIZE 131072 9 #define OUTBUFSIZE 98304 10 8 11 class AudioOutputDigitalEncoder 9 12 { 10 13 public: 11 14 AudioOutputDigitalEncoder(void); 12 15 ~AudioOutputDigitalEncoder(); 13 16 14 bool Init(CodecID codec_id, int bitrate, int samplerate, int channels); 17 bool Init(CodecID codec_id, int bitrate, int samplerate, 18 int channels, bool reencoding); 15 19 void Dispose(void); 16 size_t Encode(short * buff); 17 18 inline char *GetFrameBuffer(void); 20 size_t Encode(void *buf, int len); 21 void GetFrames(void *ptr, int maxlen); 19 22 size_t FrameSize(void) const { return one_frame_bytes; } 20 char *GetOutBuff(void) const { return outbuf;}23 int Buffered(void) const { return inbuflen; } 21 24 22 25 public: 23 26 size_t audio_bytes_per_sample; 24 27 25 28 private: 26 29 AVCodecContext *av_context; 27 char *outbuf; 28 int outbuf_size; 29 char *frame_buffer; 30 char outbuf[OUTBUFSIZE]; 31 char inbuf[INBUFSIZE]; 32 int outbuflen; 33 int inbuflen; 30 34 size_t one_frame_bytes; 35 bool reorder; 31 36 }; 32 37 33 inline char *AudioOutputDigitalEncoder::GetFrameBuffer(void)34 {35 if (!frame_buffer && av_context)36 frame_buffer = new char [one_frame_bytes];37 38 return frame_buffer;39 }40 41 38 #endif -
mythtv/libs/libmythfreesurround/el_processor.cpp
diff --git a/mythtv/libs/libmythfreesurround/el_processor.cpp b/mythtv/libs/libmythfreesurround/el_processor.cpp index 8f24737..1cf0dc8 100644
a b typedef std::complex<float> cfloat; 40 40 41 41 const float PI = 3.141592654; 42 42 const float epsilon = 0.000001; 43 //const float center_level = 0.5*sqrt(0.5); // gain of the center channel 44 //const float center_level = sqrt(0.5); // gain of the center channel 45 const float center_level = 1.0; // gain of the center channel 46 //const float center_level = 0.5; // gain of the center channel 47 48 // should be .6-.7 49 // but with centerlevel 2x what its supposed to be, we halve 0.68 50 // to keep center from clipping 51 //const float window_gain = 0.34; 52 //const float window_gain = 0.68; 53 const float window_gain = 0.95; // to prive a bit of margin 43 const float center_level = 0.5*sqrt(0.5); 54 44 55 45 // private implementation of the surround decoder 56 46 class decoder_impl { … … public: 98 88 outbuf[c].resize(N); 99 89 filter[c].resize(N); 100 90 } 101 // DC component of filters is always 0102 for (unsigned c=0;c<5;c++)103 {104 filter[c][0] = 0.0;105 filter[c][1] = 0.0;106 filter[c][halfN] = 0.0;107 }108 91 sample_rate(48000); 109 92 // generate the window function (square root of hann, b/c it is applied before and after the transform) 110 93 wnd.resize(N); 111 // dft normalization included in the window for zero cost scaling 112 // also add a gain factor of *2 due to processing gain in algo (see center_level) 113 surround_gain(1.0); 94 for (unsigned k=0;k<N;k++) 95 wnd[k] = sqrt(0.5*(1-cos(2*PI*k/N))/N); 114 96 current_buf = 0; 115 97 // set the default coefficients 116 98 surround_coefficients(0.8165,0.5774); … … public: 192 174 // set lfe filter params 193 175 void sample_rate(unsigned int srate) { 194 176 // lfe filter is just straight through band limited 195 unsigned int cutoff = ( 250*N)/srate;177 unsigned int cutoff = (30*N)/srate; 196 178 for (unsigned f=0;f<=halfN;f++) { 197 if ( (f>=2) && (f<cutoff))198 filter[5][f] = 1.0;179 if (f<cutoff) 180 filter[5][f] = 0.5*sqrt(0.5); 199 181 else 200 182 filter[5][f] = 0.0; 201 183 } … … public: 214 196 E = (o+v)*n; F = (o+u)*n; G = (o-v)*n; H = (o-u)*n; 215 197 } 216 198 217 void surround_gain(float gain) {218 master_gain = gain * window_gain * 0.5 * 0.25;219 for (unsigned k=0;k<N;k++)220 wnd[k] = sqrt(master_gain*(1-cos(2*PI*k/N))/N);221 }222 223 199 // set the phase shifting mode 224 200 void phase_mode(unsigned mode) { 225 201 const float modes[4][2] = {{0,0},{0,PI},{PI,0},{-PI/2,PI/2}}; … … private: 290 266 291 267 // 2. compare amplitude and phase of each DFT bin and produce the X/Y coordinates in the sound field 292 268 // but dont do DC or N/2 component 293 for (unsigned f= 2;f<halfN;f++) {269 for (unsigned f=0;f<halfN;f++) { 294 270 // get left/right amplitudes/phases 295 271 float ampL = amplitude(dftL[f]), ampR = amplitude(dftR[f]); 296 272 float phaseL = phase(dftL[f]), phaseR = phase(dftR[f]); … … private: 305 281 phaseDiff = abs(phaseDiff); 306 282 307 283 if (linear_steering) { 308 /* cfloat w = polar(sqrt(ampL*ampL+ampR*ampR), (phaseL+phaseR)/2);309 cfloat lt = cfloat(dftL[f][0],dftL[f][1])/w, rt = cfloat(dftR[f][0],dftR[f][1])/w; */310 // xfs[f] = -(C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E).real();311 // yfs[f] = (rt - (xfs[f]*E+H))/(F+xfs[f]*G);312 313 /*314 Problem:315 This assumes that the values are interpolated linearly between the cardinal points.316 But this way we have no chance of knowing the average volume...317 - Can we solve that computing everything under the assumption of normalized volume?318 No. Seemingly not.319 - Maybe we should add w explitcitly into the equation and see if we can solve it...320 */321 322 323 //cfloat lt(0.5,0),rt(0.5,0);324 //cfloat x(0,0), y(1,0);325 /*cfloat p = (C*(rt-H) - B*E + F*A + G*(D-lt)) / (G*A - C*E);326 cfloat q = B*(rt+H) + F*(D-lt) / (G*A - C*E);327 cfloat s = sqrt(p*p/4.0f - q);328 cfloat x = -p;329 cfloat x1 = -p/2.0f + s;330 cfloat x2 = -p/2.0f - s;331 float x = 0;332 if (x1.real() >= -1 && x1.real() <= 1)333 x = x1.real();334 else if (x2.real() >= -1 && x2.real() <= 1)335 x = x2.real();*/336 337 //cfloat yp = (rt - (x*E+H))/(F+x*G);338 //cfloat xp = (lt - (y*B+D))/(A+y*C);339 340 /*xfs[f] = x;341 yfs[f] = y.real();*/342 343 284 // --- this is the fancy new linear mode --- 344 285 345 286 // get sound field x/y position … … private: 597 538 float surround_high,surround_low; // high and low surround mixing coefficient (e.g. 0.8165/0.5774) 598 539 float surround_balance; // the xfs balance that follows from the coeffs 599 540 float surround_level; // gain for the surround channels (follows from the coeffs 600 float master_gain; // gain for all channels601 541 float phase_offsetL, phase_offsetR;// phase shifts to be applied to the rear channels 602 542 float front_separation; // front stereo separation 603 543 float rear_separation; // rear stereo separation … … void fsurround_decoder::flush() { impl->flush(); } 625 565 626 566 void fsurround_decoder::surround_coefficients(float a, float b) { impl->surround_coefficients(a,b); } 627 567 628 void fsurround_decoder::gain(float gain) { impl->surround_gain(gain); }629 630 568 void fsurround_decoder::phase_mode(unsigned mode) { impl->phase_mode(mode); } 631 569 632 570 void fsurround_decoder::steering_mode(bool mode) { impl->steering_mode(mode); } -
mythtv/libs/libmythfreesurround/el_processor.h
diff --git a/mythtv/libs/libmythfreesurround/el_processor.h b/mythtv/libs/libmythfreesurround/el_processor.h index 021786a..26452f6 100644
a b public: 47 47 // a is the coefficient of left rear in left total, b is the coefficient of left rear in right total; the same is true for right. 48 48 void surround_coefficients(float a, float b); 49 49 50 // override for master surround gain51 void gain(float gain);52 53 50 // set the phase shifting mode for decoding 54 51 // 0 = (+0°,+0°) - music mode 55 52 // 1 = (+0°,+180°) - PowerDVD compatibility -
mythtv/libs/libmythfreesurround/freesurround.cpp
diff --git a/mythtv/libs/libmythfreesurround/freesurround.cpp b/mythtv/libs/libmythfreesurround/freesurround.cpp index 07fe0d8..85b4e59 100644
a b using namespace std; 63 63 const unsigned default_block_size = 8192; 64 64 // there will be a slider for this in the future 65 65 //const float master_gain = 1.0; 66 //#define MASTER_GAIN * master_gain 66 //#define MASTER_GAIN * master_gain 67 67 #define MASTER_GAIN 68 //const float master_gain = 1.0/(1<<15); 69 //const float inv_master_gain = (1<<15); 68 //const float inv_master_gain = 1.0; 70 69 //#define INV_MASTER_GAIN * inv_master_gain 71 70 #define INV_MASTER_GAIN 72 71 … … FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) : 191 190 if (moviemode) 192 191 { 193 192 params.phasemode = 1; 194 params.center_width = 0;195 params. gain = 1.0;193 params.center_width = 25; 194 params.dimension = 0.5; 196 195 } 197 196 else 198 197 { 199 params.center_width = 70; 200 // for 50, gain should be about 1.9, c/lr about 2.7 201 // for 70, gain should be about 3.1, c/lr about 1.5 202 params.gain = 3.1; 198 params.center_width = 65; 199 params.dimension = 0.3; 203 200 } 204 201 switch (surround_mode) 205 202 { … … void FreeSurround::SetParams() 235 232 decoder->phase_mode(params.phasemode); 236 233 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 237 234 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 238 decoder->gain(params.gain);239 235 } 240 236 } 241 237 … … FreeSurround::fsurround_params::fsurround_params( 249 245 phasemode(0), 250 246 steering(1), 251 247 front_sep(100), 252 rear_sep(100), 253 gain(1.0) 248 rear_sep(100) 254 249 { 255 250 } 256 251 … … void FreeSurround::process_block() 654 649 { 655 650 if (decoder) 656 651 { 657 // actually these params need only be set when they change... but it doesn't hurt658 #if 0659 decoder->steering_mode(params.steering);660 decoder->phase_mode(params.phasemode);661 decoder->surround_coefficients(params.coeff_a, params.coeff_b);662 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);663 #endif664 // decode the bufs->block665 //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);666 //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);667 652 decoder->decode(params.center_width/100.0,params.dimension/100.0); 668 653 } 669 654 } -
mythtv/libs/libmythsamplerate/samplerate.c
diff --git a/mythtv/libs/libmythsamplerate/samplerate.c b/mythtv/libs/libmythsamplerate/samplerate.c index d5a5abc..4d74640 100644
a b src_float_to_short_array (const float *in, short *out, int len) 452 452 { len -- ; 453 453 454 454 scaled_value = in [len] * (8.0 * 0x10000000) ; 455 if ( CPU_CLIPS_POSITIVE == 0 &&scaled_value >= (1.0 * 0x7FFFFFFF))455 if (scaled_value >= (1.0 * 0x7FFFFFFF)) 456 456 { out [len] = 32767 ; 457 457 continue ; 458 458 } ; 459 if ( CPU_CLIPS_NEGATIVE == 0 &&scaled_value <= (-8.0 * 0x10000000))459 if (scaled_value <= (-8.0 * 0x10000000)) 460 460 { out [len] = -32768 ; 461 461 continue ; 462 462 } ; -
mythtv/libs/libmythtv/NuppelVideoPlayer.cpp
diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp b/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp index d61ec62..d409409 100644
a b NuppelVideoPlayer::NuppelVideoPlayer(QString inUseID, const ProgramInfo *info) 209 209 audio_passthru_device(QString::null), 210 210 audio_channels(2), audio_bits(-1), 211 211 audio_samplerate(44100), audio_stretchfactor(1.0f), 212 audio_codec(NULL),213 212 // Picture-in-Picture 214 213 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 215 214 // Preview window support … … QString NuppelVideoPlayer::ReinitAudio(void) 804 803 if (audioOutput) 805 804 { 806 805 audioOutput->Reconfigure(audio_bits, audio_channels, 807 audio_samplerate, audio_passthru, 808 audio_codec); 806 audio_samplerate, audio_passthru); 807 if (audio_passthru) 808 audio_channels = 2; 809 809 errMsg = audioOutput->GetError(); 810 810 if (!errMsg.isEmpty()) 811 811 audioOutput->SetStretchFactor(audio_stretchfactor); … … void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 3718 3718 audio_passthru = passthru; 3719 3719 } 3720 3720 3721 void NuppelVideoPlayer::SetAudioCodec(void *ac)3722 {3723 audio_codec = ac;3724 }3725 3726 3721 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3727 3722 { 3728 3723 if (audioOutput) -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.h b/mythtv/libs/libmythtv/NuppelVideoPlayer.h index 5f3d2ac..a6d2d7a 100644
a b class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 685 685 int audio_bits; 686 686 int audio_samplerate; 687 687 float audio_stretchfactor; 688 void *audio_codec;689 688 bool audio_passthru; 690 689 691 690 // Picture-in-Picture -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index ead8ebf..47d137d 100644
a b AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 411 411 audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]), 412 412 allow_ac3_passthru(false), allow_dts_passthru(false), 413 413 disable_passthru(false), max_channels(2), 414 dummy_frame(NULL),414 last_ac3_channels(0), dummy_frame(NULL), 415 415 // DVD 416 416 lastdvdtitle(-1), 417 417 decodeStillFrame(false), … … static void extract_mono_channel(uint channel, AudioInfo *audioInfo, 2971 2971 bool AvFormatDecoder::GetFrame(int onlyvideo) 2972 2972 { 2973 2973 AVPacket *pkt = NULL; 2974 AC3HeaderInfo hdr; 2974 2975 int len; 2975 2976 unsigned char *ptr; 2976 2977 int data_size = 0; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3157 3158 pts = 0; 3158 3159 3159 3160 AVStream *curstream = ic->streams[pkt->stream_index]; 3161 AVCodecContext *ctx = curstream->codec; 3160 3162 3161 3163 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3162 3164 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3163 3165 3164 3166 if (ringBuffer->isDVD() && 3165 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3167 ctx->codec_type == CODEC_TYPE_VIDEO) 3166 3168 { 3167 3169 MpegPreProcessPkt(curstream, pkt); 3168 3170 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3190 3192 3191 3193 if (!d->HasMPEG2Dec()) 3192 3194 { 3193 int current_width = c urstream->codec->width;3195 int current_width = ctx->width; 3194 3196 int video_width = GetNVP()->GetVideoSize().width(); 3195 3197 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3196 3198 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3231 3233 } 3232 3234 3233 3235 if (storevideoframes && 3234 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3236 ctx->codec_type == CODEC_TYPE_VIDEO) 3235 3237 { 3236 3238 av_dup_packet(pkt); 3237 3239 storedPackets.append(pkt); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3239 3241 continue; 3240 3242 } 3241 3243 3242 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3244 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3243 3245 pkt->stream_index == selectedVideoIndex) 3244 3246 { 3245 AVCodecContext *context = curstream->codec;3246 3247 3247 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3248 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3249 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3250 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)3248 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3249 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3250 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3251 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD) 3251 3252 { 3252 3253 if (!ringBuffer->isDVD()) 3253 3254 MpegPreProcessPkt(curstream, pkt); 3254 3255 } 3255 else if (c ontext->codec_id == CODEC_ID_H264)3256 else if (ctx->codec_id == CODEC_ID_H264) 3256 3257 { 3257 3258 H264PreProcessPkt(curstream, pkt); 3258 3259 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3298 3299 } 3299 3300 3300 3301 if (len > 0 && 3301 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3302 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3302 ctx->codec_type == CODEC_TYPE_DATA && 3303 ctx->codec_id == CODEC_ID_MPEG2VBI) 3303 3304 { 3304 3305 ProcessVBIDataPacket(curstream, pkt); 3305 3306 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3308 3309 } 3309 3310 3310 3311 if (len > 0 && 3311 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3312 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3312 ctx->codec_type == CODEC_TYPE_DATA && 3313 ctx->codec_id == CODEC_ID_DVB_VBI) 3313 3314 { 3314 3315 ProcessDVBDataPacket(curstream, pkt); 3315 3316 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3318 3319 } 3319 3320 3320 3321 if (len > 0 && 3321 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3322 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3322 ctx->codec_type == CODEC_TYPE_DATA && 3323 ctx->codec_id == CODEC_ID_DSMCC_B) 3323 3324 { 3324 3325 ProcessDSMCCPacket(curstream, pkt); 3325 3326 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3339 3340 } 3340 3341 3341 3342 // we don't care about other data streams 3342 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3343 if (ctx->codec_type == CODEC_TYPE_DATA) 3343 3344 { 3344 3345 av_free_packet(pkt); 3345 3346 continue; 3346 3347 } 3347 3348 3348 if (!c urstream->codec->codec)3349 if (!ctx->codec) 3349 3350 { 3350 3351 VERBOSE(VB_PLAYBACK, LOC + 3351 3352 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3352 3353 .arg(pkt->stream_index) 3353 .arg(codec_type_string(c urstream->codec->codec_type))3354 .arg(codec_id_string(c urstream->codec->codec_id))3355 .arg(c urstream->codec->codec_id));3354 .arg(codec_type_string(ctx->codec_type)) 3355 .arg(codec_id_string(ctx->codec_id)) 3356 .arg(ctx->codec_id)); 3356 3357 av_free_packet(pkt); 3357 3358 continue; 3358 3359 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3361 3362 have_err = false; 3362 3363 3363 3364 avcodeclock.lock(); 3364 int ctype = c urstream->codec->codec_type;3365 int ctype = ctx->codec_type; 3365 3366 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3366 3367 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3367 3368 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3386 3387 3387 3388 // detect switches between stereo and dual languages 3388 3389 bool wasDual = audSubIdx != -1; 3389 bool isDual = c urstream->codec->avcodec_dual_language;3390 bool isDual = ctx->avcodec_dual_language; 3390 3391 if ((wasDual && !isDual) || (!wasDual && isDual)) 3391 3392 { 3392 3393 SetupAudioStreamSubIndexes(audIdx); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3394 3395 } 3395 3396 3396 3397 bool do_ac3_passthru = 3397 (allow_ac3_passthru && !transcoding && 3398 (curstream->codec->codec_id == CODEC_ID_AC3)); 3398 (allow_ac3_passthru && !transcoding && 3399 ctx->channels >= (int)max_channels && 3400 (ctx->codec_id == CODEC_ID_AC3)); 3399 3401 bool do_dts_passthru = 3400 3402 (allow_dts_passthru && !transcoding && 3401 (c urstream->codec->codec_id == CODEC_ID_DTS));3403 (ctx->codec_id == CODEC_ID_DTS)); 3402 3404 bool using_passthru = do_ac3_passthru || do_dts_passthru; 3403 3405 3404 3406 // detect channels on streams that need 3405 3407 // to be decoded before we can know this 3406 3408 bool already_decoded = false; 3407 if (!c urstream->codec->channels)3409 if (!ctx->channels) 3408 3410 { 3409 3411 QMutexLocker locker(&avcodeclock); 3410 3412 VERBOSE(VB_IMPORTANT, LOC + … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3415 3417 { 3416 3418 // for passthru let it select the max number 3417 3419 // of channels 3418 c urstream->codec->channels = 0;3419 c urstream->codec->request_channels = 0;3420 ctx->channels = 0; 3421 ctx->request_channels = 0; 3420 3422 } 3421 3423 else 3422 3424 { 3423 c urstream->codec->channels = audioOut.channels;3424 c urstream->codec->request_channels =3425 ctx->channels = audioOut.channels; 3426 ctx->request_channels = 3425 3427 audioOut.channels; 3426 3428 } 3427 3429 ret = avcodec_decode_audio( 3428 c urstream->codec, audioSamples,3430 ctx, audioSamples, 3429 3431 &data_size, ptr, len); 3430 3432 already_decoded = true; 3431 3433 3432 reselectAudioTrack |= curstream->codec->channels; 3434 reselectAudioTrack |= ctx->channels; 3435 } 3436 3437 if (ctx->codec_id == CODEC_ID_AC3 && 3438 !ff_ac3_parse_header(ptr, &hdr)) 3439 { 3440 if (hdr.channels != last_ac3_channels) 3441 { 3442 last_ac3_channels = ctx->channels = hdr.channels; 3443 SetupAudioStream(); 3444 } 3433 3445 } 3434 3446 3435 3447 if (reselectAudioTrack) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3445 3457 .av_stream_index; 3446 3458 audSubIdx = selectedTrack[kTrackTypeAudio] 3447 3459 .av_substream_index; 3460 ctx = curstream->codec; 3448 3461 } 3449 3462 3450 3463 if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3476 3489 if (audioOut.do_passthru) 3477 3490 { 3478 3491 data_size = pkt->size; 3479 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3492 bool dts = CODEC_ID_DTS == ctx->codec_id; 3480 3493 ret = encode_frame(dts, ptr, len, 3481 3494 audioSamples, data_size); 3482 3495 } 3483 3496 else 3484 3497 { 3485 AVCodecContext *ctx = curstream->codec;3486 3487 3498 if ((ctx->channels == 0) || 3488 3499 (ctx->channels > audioOut.channels)) 3489 3500 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3492 3503 3493 3504 if (!already_decoded) 3494 3505 { 3495 curstream->codec->request_channels = 3496 audioOut.channels; 3506 ctx->request_channels = audioOut.channels; 3497 3507 ret = avcodec_decode_audio( 3498 3508 ctx, audioSamples, &data_size, ptr, len); 3499 3509 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3510 3520 audIdx = -1; 3511 3521 AutoSelectAudioTrack(); 3512 3522 data_size = 0; 3523 ctx = curstream->codec; 3513 3524 } 3514 3525 } 3515 3526 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3527 3538 3528 3539 // calc for next frame 3529 3540 lastapts += (long long)((double)(data_size * 1000) / 3530 (curstream->codec->channels * 2) / 3531 curstream->codec->sample_rate); 3541 (ctx->channels * 2) / ctx->sample_rate); 3532 3542 3533 3543 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, 3534 3544 LOC + QString("audio timecode %1 %2 %3 %4") … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3588 3598 continue; 3589 3599 } 3590 3600 3591 AVCodecContext *context = curstream->codec;3592 3601 AVFrame mpa_pic; 3593 3602 bzero(&mpa_pic, sizeof(AVFrame)); 3594 3603 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3603 3612 // HACK 3604 3613 while (!gotpicture && count < 5) 3605 3614 { 3606 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3615 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3607 3616 &gotpicture, ptr, len); 3608 3617 count++; 3609 3618 } 3610 3619 } 3611 3620 else 3612 3621 { 3613 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3622 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3614 3623 &gotpicture, ptr, len); 3615 3624 } 3616 3625 } 3617 3626 else 3618 3627 { 3619 ret = avcodec_decode_video(c ontext, &mpa_pic,3628 ret = avcodec_decode_video(ctx, &mpa_pic, 3620 3629 &gotpicture, ptr, len); 3621 3630 // Reparse it to not drop the DVD still frame 3622 3631 if (decodeStillFrame) 3623 ret = avcodec_decode_video(c ontext, &mpa_pic,3632 ret = avcodec_decode_video(ctx, &mpa_pic, 3624 3633 &gotpicture, ptr, len); 3625 3634 } 3626 3635 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3687 3696 3688 3697 img_convert(&tmppicture, PIX_FMT_YUV420P, 3689 3698 (AVPicture *)&mpa_pic, 3690 c ontext->pix_fmt,3691 c ontext->width,3692 c ontext->height);3699 ctx->pix_fmt, 3700 ctx->width, 3701 ctx->height); 3693 3702 3694 3703 if (xf) 3695 3704 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3712 3721 (temppts + 10000 > lastvpts || temppts < 0)) 3713 3722 { 3714 3723 temppts = lastvpts; 3715 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3724 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3716 3725 // MPEG2 frames can be repeated, update pts accordingly 3717 3726 temppts += (long long)(mpa_pic.repeat_pict * 500 3718 * av_q2d(c urstream->codec->time_base));3727 * av_q2d(ctx->time_base)); 3719 3728 } 3720 3729 3721 3730 VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3751 3760 picframe->frameNumber = framesPlayed; 3752 3761 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3753 3762 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3754 c ontext->release_buffer(context, &mpa_pic);3763 ctx->release_buffer(ctx, &mpa_pic); 3755 3764 3756 3765 decoded_video_frame = picframe; 3757 3766 gotvideo = 1; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3810 3819 } 3811 3820 default: 3812 3821 { 3813 AVCodecContext *enc = curstream->codec;3814 3822 VERBOSE(VB_IMPORTANT, LOC_ERR + 3815 3823 QString("Decoding - id(%1) type(%2)") 3816 .arg(codec_id_string( enc->codec_id))3817 .arg(codec_type_string( enc->codec_type)));3824 .arg(codec_id_string(ctx->codec_id)) 3825 .arg(codec_type_string(ctx->codec_type))); 3818 3826 have_err = true; 3819 3827 break; 3820 3828 } … … bool AvFormatDecoder::SetupAudioStream(void) 3972 3980 AVStream *curstream = NULL; 3973 3981 AVCodecContext *codec_ctx = NULL; 3974 3982 AudioInfo old_in = audioIn; 3975 AudioInfo old_out = audioOut;3976 3983 bool using_passthru = false; 3977 3984 3978 3985 if ((currentTrack[kTrackTypeAudio] >= 0) && … … bool AvFormatDecoder::SetupAudioStream(void) 3985 3992 assert(curstream->codec); 3986 3993 codec_ctx = curstream->codec; 3987 3994 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 3995 codec_ctx->channels >= (int)max_channels && 3988 3996 (codec_ctx->codec_id == CODEC_ID_AC3)); 3989 3997 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 3990 3998 (codec_ctx->codec_id == CODEC_ID_DTS)); … … bool AvFormatDecoder::SetupAudioStream(void) 4002 4010 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4003 4011 4004 4012 audioOut = audioIn = info; 4005 if (using_passthru) 4006 { 4007 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4008 AudioInfo digInfo = audioOut; 4009 if (!disable_passthru) 4010 { 4011 digInfo.channels = 2; 4012 digInfo.sample_rate = 48000; 4013 digInfo.sample_size = 4; 4014 } 4015 if (audioOut.channels > (int) max_channels) 4016 { 4017 audioOut.channels = (int) max_channels; 4018 audioOut.sample_size = audioOut.channels * 2; 4019 codec_ctx->channels = audioOut.channels; 4020 } 4021 VERBOSE(VB_AUDIO, LOC + "Audio format changed digital passthrough " + 4022 QString("%1\n\t\t\tfrom %2 ; %3\n\t\t\tto %4 ; %5") 4023 .arg(digInfo.toString()) 4024 .arg(old_in.toString()).arg(old_out.toString()) 4025 .arg(audioIn.toString()).arg(audioOut.toString())); 4026 4027 if (digInfo.sample_rate > 0) 4028 GetNVP()->SetEffDsp(digInfo.sample_rate * 100); 4029 4030 GetNVP()->SetAudioParams(digInfo.bps(), digInfo.channels, 4031 digInfo.sample_rate, audioIn.do_passthru); 4032 // allow the audio stuff to reencode 4033 GetNVP()->SetAudioCodec(codec_ctx); 4034 GetNVP()->ReinitAudio(); 4035 return true; 4036 } 4037 else 4038 { 4039 if (audioOut.channels > (int) max_channels) 4040 { 4041 audioOut.channels = (int) max_channels; 4042 audioOut.sample_size = audioOut.channels * 2; 4043 codec_ctx->channels = audioOut.channels; 4044 } 4045 } 4046 4013 4047 4014 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4048 QString("\n\t\t\tfrom %1 ; %2\n\t\t\tto %3 ; %4") 4049 .arg(old_in.toString()).arg(old_out.toString()) 4050 .arg(audioIn.toString()).arg(audioOut.toString())); 4015 QString("\n\t\t\tfrom %1 to %2") 4016 .arg(old_in.toString()).arg(audioOut.toString())); 4051 4017 4052 4018 if (audioOut.sample_rate > 0) 4053 4019 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4054 4020 4055 GetNVP()->SetAudioParams(audioOut.bps(), audio Out.channels,4021 GetNVP()->SetAudioParams(audioOut.bps(), audioIn.channels, 4056 4022 audioOut.sample_rate, 4057 audio In.do_passthru);4023 audioOut.do_passthru); 4058 4024 4059 // allow the audio stuff to reencode4060 GetNVP()->SetAudioCodec(using_passthru?codec_ctx:NULL);4061 4025 QString errMsg = GetNVP()->ReinitAudio(); 4062 bool audiook = errMsg.isEmpty();4063 4026 4064 4027 return true; 4065 4028 } -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index 2f4fb43..1be9cf5 100644
a b class AvFormatDecoder : public DecoderBase 264 264 bool allow_dts_passthru; 265 265 bool disable_passthru; 266 266 uint max_channels; 267 uint last_ac3_channels; 267 268 268 269 VideoFrame *dummy_frame; 269 270 -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index de06d06..d990434 100644
a b void TV::InitKeys(void) 348 348 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 349 349 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 350 350 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 351 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 351 352 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode", 352 353 "V"); 353 354 REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B"); … … void TV::InitKeys(void) 480 481 Teletext F2,F3,F4,F5,F6,F7,F8 481 482 ITV F2,F3,F4,F5,F6,F7,F12 482 483 483 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 484 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 484 485 */ 485 486 } 486 487 … … void TV::ProcessKeypress(QKeyEvent *e) 2710 2711 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2711 2712 action == "STRETCHINC" || action == "STRETCHDEC" || 2712 2713 action == "MUTE" || action == "TOGGLEASPECT" || 2713 action == "TOGGLEFILL" )2714 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2714 2715 { 2715 2716 passThru = 1; 2716 2717 handled = false; … … void TV::ProcessKeypress(QKeyEvent *e) 2725 2726 else 2726 2727 handled = false; 2727 2728 } 2728 2729 2729 2730 if (!passThru) 2730 2731 return; 2731 2732 } 2732 2733 2733 2734 if (zoomMode) 2734 2735 { 2735 2736 int passThru = 0; … … void TV::ProcessKeypress(QKeyEvent *e) 2765 2766 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2766 2767 action == "STRETCHINC" || action == "STRETCHDEC" || 2767 2768 action == "MUTE" || action == "PAUSE" || 2768 action == "CLEAROSD" )2769 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2769 2770 { 2770 2771 passThru = 1; 2771 2772 handled = false; … … void TV::ProcessKeypress(QKeyEvent *e) 2777 2778 if (!passThru) 2778 2779 return; 2779 2780 } 2780 2781 2781 2782 if (dialogname != "" && GetOSD() && GetOSD()->DialogShowing(dialogname)) 2782 2783 { 2783 2784 for (unsigned int i = 0; i < actions.size() && !handled; i++) … … void TV::ProcessKeypress(QKeyEvent *e) 3036 3037 return; 3037 3038 } 3038 3039 } 3039 3040 3040 3041 for (unsigned int i = 0; i < actions.size() && !handled; i++) 3041 3042 { 3042 3043 QString action = actions[i]; … … void TV::ProcessKeypress(QKeyEvent *e) 3070 3071 ChangeTimeStretch(0); // just display 3071 3072 else if (action == "TOGGLESTRETCH") 3072 3073 ToggleTimeStretch(); 3074 else if (action == "TOGGLEUPMIX") 3075 ToggleUpmix(); 3073 3076 else if (action == "CYCLECOMMSKIPMODE") { 3074 3077 SetAutoCommercialSkip((enum commSkipMode) 3075 3078 ((autoCommercialSkip + 1) % CommSkipModes)); … … void TV::ChangeTimeStretch(int dir, bool allowEdit) 6054 6057 } 6055 6058 } 6056 6059 6060 void TV::ToggleUpmix() 6061 { 6062 AudioOutput *aud = nvp->getAudioOutput(); 6063 if (!aud) 6064 return; 6065 QString text; 6066 if (aud->ToggleUpmix()) 6067 text = tr("Upmixer On"); 6068 else 6069 text = tr("Upmixer Off"); 6070 6071 if (GetOSD() && !browsemode) 6072 GetOSD()->SetSettingsText(text, 5); 6073 } 6074 6075 6057 6076 // dir in 10ms jumps 6058 6077 void TV::ChangeAudioSync(int dir, bool allowEdit) 6059 6078 { … … void TV::TreeMenuSelected(OSDListTreeType *tree, OSDGenericTree *item) 7300 7319 7301 7320 ChangeTimeStretch(0, !floatRead); // just display 7302 7321 } 7322 else if (action == "TOGGLEUPMIX") 7323 ToggleUpmix(); 7303 7324 else if (action.left(11) == "SELECTSCAN_") 7304 7325 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7305 7326 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … void TV::BuildOSDTreeMenu(void) 7547 7568 subitem = new OSDGenericTree(item, tr("1.5X"), "ADJUSTSTRETCH1.5", 7548 7569 (speedX100 == 150) ? 1 : 0, NULL, 7549 7570 "STRETCHGROUP"); 7571 7572 item = new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7550 7573 7551 7574 // add scan mode override settings to menu 7552 7575 FrameScanType scan_type = kScan_Ignore; -
mythtv/libs/libmythtv/tv_play.h
diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h index 8aa048b..873da6f 100644
a b class MPUBLIC TV : public QObject 314 314 void ChangeSpeed(int direction); 315 315 void ToggleTimeStretch(void); 316 316 void ChangeTimeStretch(int dir, bool allowEdit = true); 317 void ToggleUpmix(void); 317 318 void ChangeAudioSync(int dir, bool allowEdit = true); 318 319 float StopFFRew(void); 319 320 void ChangeFFRew(int direction); -
mythtv/programs/mythtranscode/transcode.cpp
diff --git a/mythtv/programs/mythtranscode/transcode.cpp b/mythtv/programs/mythtranscode/transcode.cpp index dde8b09..c6adf51 100644
a b class AudioReencodeBuffer : public AudioOutput 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, 59 void *audio_codec = NULL) 58 int audio_samplerate, bool audio_passthru) 60 59 { 61 60 (void)audio_samplerate; 62 61 (void)audio_passthru; 63 (void)audio_codec;64 62 65 63 ClearError(); 66 64 bits = audio_bits; … … class AudioReencodeBuffer : public AudioOutput 218 216 // Do nothing 219 217 return MUTE_OFF; 220 218 } 219 virtual bool ToggleUpmix(void) 220 { 221 // Do nothing 222 return false; 223 } 221 224 222 225 // These are pure virtual in AudioOutput, but we don't need them here 223 226 virtual void bufferOutputData(bool){ return; }