Ticket #5900: 00-5900-audioencoding-trunk-6.1.patch
File 00-5900-audioencoding-trunk-6.1.patch, 84.5 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 f10ca1e..747d60e 100644
a b void setupKeys(void) 370 370 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 371 371 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 372 372 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 373 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 373 374 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 374 375 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 375 376 REG_KEY("Music", "THMBUP", "Increase rating", "9"); -
mythplugins/mythmusic/mythmusic/musicplayer.cpp
diff --git a/mythplugins/mythmusic/mythmusic/musicplayer.cpp b/mythplugins/mythmusic/mythmusic/musicplayer.cpp index 96352c3..55608e1 100644
a b void MusicPlayer::stopDecoder(void) 354 354 355 355 void MusicPlayer::openOutputDevice(void) 356 356 { 357 QString adevice ;357 QString adevice, pdevice; 358 358 359 359 if (gContext->GetSetting("MusicAudioDevice") == "default") 360 360 adevice = gContext->GetSetting("AudioOutputDevice"); 361 361 else 362 362 adevice = gContext->GetSetting("MusicAudioDevice"); 363 363 364 pdevice = gContext->GetSetting("PassThruOutputDevice"); 365 364 366 // TODO: Error checking that device is opened correctly! 365 m_output = AudioOutput::OpenAudio(adevice, "default", 16, 2, 44100,367 m_output = AudioOutput::OpenAudio(adevice, pdevice, 16, 2, 44100, 366 368 AUDIOOUTPUT_MUSIC, true, false); 367 369 m_output->setBufferSize(256 * 1024); 368 370 m_output->SetBlocking(false); -
mythplugins/mythmusic/mythmusic/playbackbox.cpp
diff --git a/mythplugins/mythmusic/mythmusic/playbackbox.cpp b/mythplugins/mythmusic/mythmusic/playbackbox.cpp index d4b3e97..6db9bc9 100644
a b void PlaybackBoxMusic::keyPressEvent(QKeyEvent *e) 365 365 changeSpeed(true); 366 366 else if (action == "MUTE") 367 367 toggleMute(); 368 else if (action == "TOGGLEUPMIX") 369 toggleUpmix(); 368 370 else if (action == "MENU" && visualizer_status != 2) 369 371 { 370 372 menufilters = false; … … void PlaybackBoxMusic::toggleMute() 1193 1195 } 1194 1196 } 1195 1197 1198 void PlaybackBoxMusic::toggleUpmix() 1199 { 1200 if (gPlayer->getOutput()) 1201 gPlayer->getOutput()->ToggleUpmix(); 1202 } 1203 1204 1196 1205 void PlaybackBoxMusic::showProgressBar() 1197 1206 { 1198 1207 if (progress_bar && visualizer_status != 2) -
mythplugins/mythmusic/mythmusic/playbackbox.h
diff --git a/mythplugins/mythmusic/mythmusic/playbackbox.h b/mythplugins/mythmusic/mythmusic/playbackbox.h index fc9b65d..66e4ef9 100644
a b class PlaybackBoxMusic : public MythThemedDialog 70 70 void changeVolume(bool up_or_down); 71 71 void changeSpeed(bool up_or_down); 72 72 void toggleMute(); 73 void toggleUpmix(); 73 74 void resetTimer(); 74 75 void hideVolume(){showVolume(false);} 75 76 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 943bd77..740edb8 100644
a b class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners 68 68 69 69 virtual void bufferOutputData(bool y) = 0; 70 70 virtual int readOutputData(unsigned char *read_buffer, int max_length) = 0; 71 virtual bool ToggleUpmix(void) = 0; 71 72 72 73 protected: 73 74 void Error(const QString &msg); -
mythtv/libs/libmyth/audiooutputalsa.cpp
diff --git a/mythtv/libs/libmyth/audiooutputalsa.cpp b/mythtv/libs/libmyth/audiooutputalsa.cpp index 34174c4..5674acb 100644
a b AudioOutputALSA::AudioOutputALSA(const AudioSettings &settings) : 32 32 AudioOutputALSA::~AudioOutputALSA() 33 33 { 34 34 KillAudio(); 35 SetIECStatus(true); 36 } 37 38 void AudioOutputALSA::SetIECStatus(bool audio) { 39 40 snd_ctl_t *ctl; 41 const char *spdif_str = SND_CTL_NAME_IEC958("", PLAYBACK, DEFAULT); 42 int spdif_index = -1; 43 snd_ctl_elem_list_t *clist; 44 snd_ctl_elem_id_t *cid; 45 snd_ctl_elem_value_t *cval; 46 snd_aes_iec958_t iec958; 47 int cidx, controls; 48 49 VERBOSE(VB_AUDIO, QString("Setting IEC958 status: %1") 50 .arg(audio ? "audio" : "non-audio")); 51 52 snd_ctl_open(&ctl, "default", 0); 53 snd_ctl_elem_list_alloca(&clist); 54 snd_ctl_elem_list(ctl, clist); 55 snd_ctl_elem_list_alloc_space(clist, snd_ctl_elem_list_get_count(clist)); 56 snd_ctl_elem_list(ctl, clist); 57 controls = snd_ctl_elem_list_get_used(clist); 58 for (cidx = 0; cidx < controls; cidx++) { 59 if (!strcmp(snd_ctl_elem_list_get_name(clist, cidx), spdif_str)) 60 if (spdif_index < 0 || 61 snd_ctl_elem_list_get_index(clist, cidx) == (uint)spdif_index) 62 break; 63 } 64 65 if (cidx >= controls) 66 return; 67 68 snd_ctl_elem_id_alloca(&cid); 69 snd_ctl_elem_list_get_id(clist, cidx, cid); 70 snd_ctl_elem_value_alloca(&cval); 71 snd_ctl_elem_value_set_id(cval, cid); 72 snd_ctl_elem_read(ctl,cval); 73 snd_ctl_elem_value_get_iec958(cval, &iec958); 74 75 if (!audio) 76 iec958.status[0] |= IEC958_AES0_NONAUDIO; 77 else 78 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 79 80 snd_ctl_elem_value_set_iec958(cval, &iec958); 81 snd_ctl_elem_write(ctl, cval); 82 35 83 } 36 84 37 85 bool AudioOutputALSA::OpenDevice() … … bool AudioOutputALSA::OpenDevice() 39 87 snd_pcm_format_t format; 40 88 unsigned int buffer_time, period_time; 41 89 int err; 90 QString real_device; 42 91 43 92 if (pcm_handle != NULL) 44 93 CloseDevice(); 45 94 46 95 pcm_handle = NULL; 47 96 numbadioctls = 0; 48 49 QString real_device = (audio_passthru) ? 50 audio_passthru_device : audio_main_device; 97 98 if (audio_passthru || audio_enc) 99 { 100 real_device = audio_passthru_device; 101 SetIECStatus(false); 102 } 103 else 104 { 105 real_device = audio_main_device; 106 SetIECStatus(true); 107 } 51 108 52 109 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 110 .arg(real_device)); -
mythtv/libs/libmyth/audiooutputalsa.h
diff --git a/mythtv/libs/libmyth/audiooutputalsa.h b/mythtv/libs/libmyth/audiooutputalsa.h index a156edd..43536ac 100644
a b class AudioOutputALSA : public AudioOutputBase 67 67 virtual int GetBufferedOnSoundcard(void) const; 68 68 69 69 private: 70 void SetIECStatus(bool audio); 70 71 inline int SetParameters(snd_pcm_t *handle, 71 72 snd_pcm_format_t format, unsigned int channels, 72 73 unsigned int rate, unsigned int buffer_time, -
mythtv/libs/libmyth/audiooutputbase.cpp
diff --git a/mythtv/libs/libmyth/audiooutputbase.cpp b/mythtv/libs/libmyth/audiooutputbase.cpp index ef2f3d5..112f554 100644
a b AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 28 28 29 29 audio_main_device(settings.GetMainDevice()), 30 30 audio_passthru_device(settings.GetPassthruDevice()), 31 audio_passthru(false), audio_stretchfactor(1.0f), 31 audio_passthru(false), audio_enc(false), 32 audio_reenc(false), audio_stretchfactor(1.0f), 32 33 33 audio_codec(NULL),34 34 source(settings.source), killaudio(false), 35 35 36 36 pauseaudio(false), audio_actually_paused(false), … … AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 48 48 encoder(NULL), 49 49 upmixer(NULL), 50 50 source_audio_channels(-1), 51 source_audio_samplerate(0), 51 52 source_audio_bytes_per_sample(0), 52 53 needs_upmix(false), 53 54 surround_mode(FreeSurround::SurroundModePassive), 55 old_audio_stretchfactor(1.0), 54 56 55 57 blocking(false), 56 58 … … AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 79 81 memset(&audiotime_updated, 0, sizeof(audiotime_updated)); 80 82 memset(audiobuffer, 0, sizeof(char) * kAudioRingBufferSize); 81 83 configured_audio_channels = gContext->GetNumSetting("MaxChannels", 2); 84 orig_config_channels = configured_audio_channels; 85 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 86 src_quality = gContext->GetNumSetting("SRCQuality", 3); 82 87 83 88 // You need to call Reconfigure from your concrete class. 84 89 // Reconfigure(laudio_bits, laudio_channels, … … void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 124 129 VERBOSE(VB_GENERAL, LOC + QString("Using time stretch %1") 125 130 .arg(audio_stretchfactor)); 126 131 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 } 132 pSoundStretch->setSampleRate(audio_samplerate); 133 pSoundStretch->setChannels(upmixer ? 134 configured_audio_channels : source_audio_channels); 161 135 162 136 pSoundStretch->setTempo(audio_stretchfactor); 163 137 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35); … … void AudioOutputBase::SetStretchFactorLocked(float laudio_stretchfactor) 165 139 // dont need these with only tempo change 166 140 //pSoundStretch->setPitch(1.0); 167 141 //pSoundStretch->setRate(1.0); 168 169 142 //pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, true); 170 143 //pSoundStretch->setSetting(SETTING_USE_AA_FILTER, false); 171 144 } … … float AudioOutputBase::GetStretchFactor(void) const 183 156 return audio_stretchfactor; 184 157 } 185 158 159 bool AudioOutputBase::ToggleUpmix(void) 160 { 161 if (orig_config_channels == 2 || 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 const AudioSettings settings(audio_bits, source_audio_channels, 169 source_audio_samplerate, audio_passthru); 170 Reconfigure(settings); 171 return (configured_audio_channels == 6); 172 } 173 174 186 175 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 176 { 188 177 AudioSettings settings = orig_settings; 189 178 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 179 int lsource_audio_channels = settings.channels; 195 180 bool lneeds_upmix = false; 181 bool laudio_reenc = false; 196 182 197 if (settings.codec) 198 { 199 lcodec_id = ((AVCodecContext*)settings.codec)->codec_id; 200 settings.bits = 16; 201 settings.channels = 2; 202 lsource_audio_channels = settings.channels; 203 settings.samplerate = 48000; 204 lcchannels = ((AVCodecContext*)settings.codec)->channels; 205 } 206 207 if (audio_codec) 208 { 209 codec_id = audio_codec->codec_id; 210 cchannels = ((AVCodecContext*)audio_codec)->channels; 211 } 183 // Are we reencoding a (previously) timestretched bitstream? 184 if (settings.channels > 2 && !settings.use_passthru) 185 laudio_reenc = true; 212 186 213 if ((configured_audio_channels == 6) && 214 !(settings.codec || audio_codec)) 187 // Enough channels? Upmix if not 188 if (settings.channels < configured_audio_channels && 189 !settings.use_passthru) 215 190 { 216 191 settings.channels = configured_audio_channels; 217 192 lneeds_upmix = true; … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 224 199 settings.samplerate == audio_samplerate && !need_resampler && 225 200 settings.use_passthru == audio_passthru && 226 201 lneeds_upmix == needs_upmix && 227 l codec_id == codec_id && lcchannels == cchannels);202 laudio_reenc == audio_reenc); 228 203 bool upmix_deps = 229 204 (lsource_audio_channels == source_audio_channels); 230 205 if (general_deps && upmix_deps) … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 251 226 waud = raud = 0; 252 227 audio_actually_paused = false; 253 228 254 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);255 229 audio_channels = settings.channels; 256 230 source_audio_channels = lsource_audio_channels; 257 231 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate;259 audio_ codec = (AVCodecContext*)settings.codec;232 source_audio_samplerate = audio_samplerate = settings.samplerate; 233 audio_reenc = laudio_reenc; 260 234 audio_passthru = settings.use_passthru; 261 235 needs_upmix = lneeds_upmix; 262 236 … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 265 239 Error("AudioOutput only supports 8 or 16bit audio."); 266 240 return; 267 241 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8;269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;270 242 271 243 need_resampler = false; 272 244 killaudio = false; … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 275 247 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 248 277 249 numlowbuffer = 0; 250 251 // Encode to AC-3 if not passing thru , there's > 2 channels 252 // and a passthru device is defined 253 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 254 { 255 int srate = src_quality == 0 ? 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 configured_audio_channels, audio_reenc)) 260 { 261 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 262 delete encoder; 263 encoder = NULL; 264 } 265 266 audio_enc = true; 267 } 268 269 if(audio_passthru || audio_enc) 270 // AC-3 output - 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; 278 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 (src_quality != 0 && 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(settings.samplerate).arg(audio_samplerate)); 284 src_ctx = src_new(3-src_quality, audio_channels, &error); 285 if (error) 286 { 287 Error(QString("Error creating resampler, the error was: %1") 288 .arg(src_strerror(error)) ); 289 src_ctx = NULL; 290 return; 291 } 292 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 293 src_data.data_in = src_in; 294 src_data.data_out = src_out; 295 src_data.output_frames = 16384*6; 296 need_resampler = true; 297 } 298 279 299 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 300 .arg(audio_main_device).arg(audio_channels) 281 301 .arg(source_audio_channels).arg(audio_samplerate)); … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 309 329 current_seconds = -1; 310 330 source_bitrate = -1; 311 331 312 // NOTE: this won't do anything as above samplerate vars are set equal313 // Check if we need the resampler314 if (audio_samplerate != settings.samplerate)315 {316 int error;317 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2")318 .arg(settings.samplerate).arg(audio_samplerate));319 src_ctx = src_new (SRC_SINC_BEST_QUALITY, audio_channels, &error);320 if (error)321 {322 Error(QString("Error creating resampler, the error was: %1")323 .arg(src_strerror(error)) );324 return;325 }326 src_data.src_ratio = (double) audio_samplerate / settings.samplerate;327 src_data.data_in = src_in;328 src_data.data_out = src_out;329 src_data.output_frames = 16384*6;330 need_resampler = true;331 }332 333 332 if (needs_upmix) 334 333 { 335 334 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 344 343 (FreeSurround::SurroundMode)surround_mode); 345 344 346 345 VERBOSE(VB_AUDIO, LOC + 347 QString(" create upmixer done with surround mode %1")346 QString("Create upmixer done with surround mode %1") 348 347 .arg(surround_mode)); 349 348 } 350 349 351 350 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 351 .arg(audio_stretchfactor)); 353 VERBOSE(VB_AUDIO, QString("Audio Codec Used: %1")354 .arg((audio_codec) ?355 codec_id_string(audio_codec->codec_id) : "not set"));356 357 if (redo_stretch)358 {359 delete pSoundStretch;360 pSoundStretch = NULL;361 SetStretchFactorLocked(audio_stretchfactor);362 }363 else364 {365 SetStretchFactorLocked(audio_stretchfactor);366 if (pSoundStretch)367 {368 // if its passthru then we need to reencode369 if (audio_codec)370 {371 if (!encoder)372 {373 VERBOSE(VB_AUDIO, LOC +374 QString("Creating Encoder for codec %1")375 .arg(audio_codec->codec_id));376 377 encoder = new AudioOutputDigitalEncoder();378 if (!encoder->Init(audio_codec->codec_id,379 audio_codec->bit_rate,380 audio_codec->sample_rate,381 audio_codec->channels382 ))383 {384 // eeks385 delete encoder;386 encoder = NULL;387 VERBOSE(VB_AUDIO, LOC + "Failed to Create Encoder");388 }389 }390 }391 if (audio_codec && encoder)392 {393 pSoundStretch->setSampleRate(audio_codec->sample_rate);394 pSoundStretch->setChannels(audio_codec->channels);395 }396 else397 {398 pSoundStretch->setSampleRate(audio_samplerate);399 pSoundStretch->setChannels(audio_channels);400 }401 }402 }403 352 353 SetStretchFactorLocked(old_audio_stretchfactor); 354 404 355 // Setup visualisations, zero the visualisations buffers 405 356 prepareVisuals(); 406 357 … … void AudioOutputBase::KillAudio() 436 387 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 437 388 killaudio = true; 438 389 StopOutputThread(); 390 QMutexLocker lock1(&audio_buflock); 439 391 440 392 // Close resampler? 441 393 if (src_ctx) 394 { 442 395 src_delete(src_ctx); 396 src_ctx = NULL; 397 } 398 443 399 need_resampler = false; 444 400 445 401 // close sound stretcher … … void AudioOutputBase::KillAudio() 447 403 { 448 404 delete pSoundStretch; 449 405 pSoundStretch = NULL; 406 old_audio_stretchfactor = audio_stretchfactor; 407 audio_stretchfactor = 1.0; 450 408 } 451 409 452 410 if (encoder) … … void AudioOutputBase::KillAudio() 461 419 upmixer = NULL; 462 420 } 463 421 needs_upmix = false; 422 audio_enc = false; 464 423 465 424 CloseDevice(); 466 425 … … int AudioOutputBase::GetAudiotime(void) 562 521 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 563 522 ret = (long long)(ret * audio_stretchfactor); 564 523 565 #if 1566 524 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 567 525 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 568 526 .arg(now.tv_sec).arg(now.tv_usec) … … int AudioOutputBase::GetAudiotime(void) 571 529 .arg(audiotime) 572 530 .arg(audio_stretchfactor) 573 531 ); 574 #endif575 532 576 533 ret += audiotime; 577 534 … … void AudioOutputBase::SetAudiotime(void) 611 568 612 569 // include algorithmic latencies 613 570 if (pSoundStretch) 614 {615 // add the effect of any unused but processed samples,616 // AC3 reencode does this617 totalbuffer += (int)(pSoundStretch->numSamples() *618 audio_bytes_per_sample);619 // add the effect of unprocessed samples in time stretch algo620 571 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 572 audio_bytes_per_sample) / audio_stretchfactor); 622 }623 573 624 574 if (upmixer && needs_upmix) 625 {626 575 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 } 576 577 if (encoder) 578 totalbuffer += encoder->Buffered(); 628 579 629 580 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 581 (audio_bytes_per_sample * effdspstretched)); 631 582 632 583 gettimeofday(&audiotime_updated, NULL); 633 #if 1 584 634 585 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 635 586 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 636 587 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … void AudioOutputBase::SetAudiotime(void) 642 593 .arg(effdspstretched) 643 594 .arg(audio_bytes_per_sample) 644 595 .arg(audio_stretchfactor)); 645 #endif646 596 } 647 597 648 598 int AudioOutputBase::GetAudioBufferedTime(void) … … bool AudioOutputBase::AddSamples(char *buffers[], int samples, 681 631 return false; // would overflow 682 632 } 683 633 634 QMutexLocker lock1(&audio_buflock); 635 684 636 // resample input if necessary 685 637 if (need_resampler && src_ctx) 686 638 { … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 725 677 int abps = (encoder) ? 726 678 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 727 679 int len = samples * abps; 680 681 // Give original samples to mythmusic visualisation 682 dispatchVisual((unsigned char *)buffer, len, timecode, 683 source_audio_channels, audio_bits); 728 684 729 685 // Check we have enough space to write the data 730 686 if (need_resampler && src_ctx) … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 749 705 return false; // would overflow 750 706 } 751 707 708 QMutexLocker lock1(&audio_buflock); 709 752 710 // resample input if necessary 753 711 if (need_resampler && src_ctx) 754 712 { … … int AudioOutputBase::WaitForFreeSpace(int samples) 808 766 if (src_ctx) 809 767 { 810 768 int error = src_reset(src_ctx); 811 if (error) 769 if (error) 770 { 812 771 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 772 "Error occured while resetting resampler: %1") 814 773 .arg(src_strerror(error))); 774 src_ctx = NULL; 775 } 815 776 } 816 777 } 817 778 } … … int AudioOutputBase::WaitForFreeSpace(int samples) 821 782 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 783 long long timecode) 823 784 { 824 audio_buflock.lock();825 826 785 int len; // = samples * audio_bytes_per_sample; 827 786 int audio_bytes = audio_bits / 8; 828 787 int org_waud = waud; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 839 798 .arg(samples * abps) 840 799 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 841 800 .arg(needs_upmix)); 842 801 802 len = WaitForFreeSpace(samples); 803 843 804 if (upmixer && needs_upmix) 844 805 { 845 806 int out_samples = 0; 807 org_waud = waud; 846 808 int step = (interleaved)?source_audio_channels:1; 847 len = WaitForFreeSpace(samples); // test 809 848 810 for (int itemp = 0; itemp < samples; ) 849 811 { 850 // just in case it does a processing cycle, release the lock851 // to allow the output loop to do output852 audio_buflock.unlock();853 812 if (audio_bytes == 2) 854 813 { 855 814 itemp += upmixer->putSamples( … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 866 825 source_audio_channels, 867 826 (interleaved) ? 0 : samples); 868 827 } 869 audio_buflock.lock();870 828 871 829 int copy_samples = upmixer->numSamples(); 872 830 if (copy_samples) … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 900 858 } 901 859 else 902 860 { 903 len = WaitForFreeSpace(samples);904 905 861 if (interleaved) 906 862 { 907 863 char *mybuf = (char*)buffer; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 936 892 } 937 893 } 938 894 939 if (samples > 0) 895 if (samples <= 0) 896 return; 897 898 if (pSoundStretch) 940 899 { 941 if (pSoundStretch) 900 // does not change the timecode, only the number of samples 901 // back to orig pos 902 org_waud = waud; 903 int bdiff = kAudioRingBufferSize - org_waud; 904 int nSamplesToEnd = bdiff/abps; 905 if (bdiff < len) 906 { 907 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 908 (audiobuffer + 909 org_waud), nSamplesToEnd); 910 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 911 (len - bdiff) / abps); 912 } 913 else 942 914 { 915 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 916 (audiobuffer + org_waud), 917 len / abps); 918 } 943 919 944 // does not change the timecode, only the number of samples 945 // back to orig pos 946 org_waud = waud; 947 int bdiff = kAudioRingBufferSize - org_waud; 948 int nSamplesToEnd = bdiff/abps; 949 if (bdiff < len) 950 { 951 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 952 (audiobuffer + 953 org_waud), nSamplesToEnd); 954 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 955 (len - bdiff) / abps); 920 int nSamples = pSoundStretch->numSamples(); 921 len = WaitForFreeSpace(nSamples); 922 923 while ((nSamples = pSoundStretch->numSamples())) 924 { 925 if (nSamples > nSamplesToEnd) 926 nSamples = nSamplesToEnd; 927 928 nSamples = pSoundStretch->receiveSamples( 929 (soundtouch::SAMPLETYPE*) 930 (audiobuffer + org_waud), nSamples 931 ); 932 933 if (nSamples == nSamplesToEnd) { 934 org_waud = 0; 935 nSamplesToEnd = kAudioRingBufferSize/abps; 956 936 } 957 else 958 { 959 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 960 (audiobuffer + org_waud), 961 len / abps); 937 else { 938 org_waud += nSamples * abps; 939 nSamplesToEnd -= nSamples; 962 940 } 941 942 } 943 944 } 963 945 964 if (encoder)965 {966 // pull out a packet's worth and reencode it until we967 // don't have enough for any more packets968 soundtouch::SAMPLETYPE *temp_buff =969 (soundtouch::SAMPLETYPE*)encoder->GetFrameBuffer();970 size_t frameSize = encoder->FrameSize()/abps;946 // Encode to AC-3? 947 if (encoder) 948 { 949 950 org_waud = waud; 951 int bdiff = kAudioRingBufferSize - org_waud; 952 int to_get = 0; 971 953 972 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 973 QString("_AddSamples Enc sfs=%1 bfs=%2 sss=%3") 974 .arg(frameSize) 975 .arg(encoder->FrameSize()) 976 .arg(pSoundStretch->numSamples())); 977 978 // process the same number of samples as it creates 979 // a full encoded buffer just like before 980 while (pSoundStretch->numSamples() >= frameSize) 981 { 982 int got = pSoundStretch->receiveSamples( 983 temp_buff, frameSize); 984 int amount = encoder->Encode(temp_buff); 985 986 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 987 QString("_AddSamples Enc bytes=%1 got=%2 left=%3") 988 .arg(amount) 989 .arg(got) 990 .arg(pSoundStretch->numSamples())); 991 992 if (!amount) 993 continue; 994 995 //len = WaitForFreeSpace(amount); 996 char *ob = encoder->GetOutBuff(); 997 if (amount >= bdiff) 998 { 999 memcpy(audiobuffer + org_waud, ob, bdiff); 1000 ob += bdiff; 1001 amount -= bdiff; 1002 org_waud = 0; 1003 } 1004 if (amount > 0) 1005 memcpy(audiobuffer + org_waud, ob, amount); 1006 1007 bdiff = kAudioRingBufferSize - amount; 1008 org_waud = (org_waud + amount) % kAudioRingBufferSize; 1009 } 1010 } 1011 else 954 if (bdiff < len) 955 { 956 encoder->Encode(audiobuffer + org_waud, bdiff); 957 to_get = encoder->Encode(audiobuffer, len - bdiff); 958 } 959 else 960 to_get = encoder->Encode(audiobuffer + org_waud, len); 961 962 if (to_get > 0) 963 { 964 965 if (to_get >= bdiff) 1012 966 { 1013 int newLen = 0; 1014 int nSamples; 1015 len = WaitForFreeSpace(pSoundStretch->numSamples() * 1016 audio_bytes_per_sample); 1017 do 1018 { 1019 int samplesToGet = len/audio_bytes_per_sample; 1020 if (samplesToGet > nSamplesToEnd) 1021 { 1022 samplesToGet = nSamplesToEnd; 1023 } 1024 1025 nSamples = pSoundStretch->receiveSamples( 1026 (soundtouch::SAMPLETYPE*) 1027 (audiobuffer + org_waud), samplesToGet); 1028 if (nSamples == nSamplesToEnd) 1029 { 1030 org_waud = 0; 1031 nSamplesToEnd = kAudioRingBufferSize/audio_bytes_per_sample; 1032 } 1033 else 1034 { 1035 int bufsz = nSamples * audio_bytes_per_sample; 1036 org_waud = (org_waud + bufsz) % kAudioRingBufferSize; 1037 nSamplesToEnd -= nSamples; 1038 } 1039 1040 newLen += nSamples * audio_bytes_per_sample; 1041 len -= nSamples * audio_bytes_per_sample; 1042 } while (nSamples > 0); 967 encoder->GetFrames(audiobuffer + org_waud, bdiff); 968 to_get -= bdiff; 969 org_waud = 0; 1043 970 } 1044 } 971 if (to_get > 0) 972 encoder->GetFrames(audiobuffer + org_waud, to_get); 1045 973 1046 waud = org_waud; 1047 lastaudiolen = audiolen(false); 974 org_waud += to_get; 1048 975 1049 if (timecode < 0)1050 {1051 // mythmusic doesn't give timestamps..1052 timecode = (int)((samples_buffered * 100000.0) / effdsp);1053 976 } 1054 1055 samples_buffered += samples;1056 1057 /* we want the time at the end -- but the file format stores1058 time at the start of the chunk. */1059 // even with timestretch, timecode is still calculated from original1060 // sample count1061 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp);1062 977 1063 if (interleaved)1064 {1065 dispatchVisual((unsigned char *)buffer, len, timecode,1066 source_audio_channels, audio_bits);1067 }1068 978 } 1069 979 1070 audio_buflock.unlock(); 980 waud = org_waud; 981 lastaudiolen = audiolen(false); 982 983 if (timecode < 0) 984 // mythmusic doesn't give timestamps.. 985 timecode = (int)((samples_buffered * 100000.0) / effdsp); 986 987 samples_buffered += samples; 988 989 /* we want the time at the end -- but the file format stores 990 time at the start of the chunk. */ 991 // even with timestretch, timecode is still calculated from original 992 // sample count 993 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 994 1071 995 } 1072 996 1073 997 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiooutputbase.h
diff --git a/mythtv/libs/libmyth/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h index 6e4d792..715eff1 100644
a b class AudioOutputBase : public AudioOutput, public QThread 43 43 44 44 virtual void SetStretchFactor(float factor); 45 45 virtual float GetStretchFactor(void) const; 46 virtual bool ToggleUpmix(void); 46 47 47 48 virtual void Reset(void); 48 49 … … class AudioOutputBase : public AudioOutput, public QThread 132 133 QString audio_passthru_device; 133 134 134 135 bool audio_passthru; 136 bool audio_enc; 137 bool audio_reenc; 135 138 136 139 float audio_stretchfactor; 137 AVCodecContext *audio_codec;138 140 AudioOutputSource source; 139 141 140 142 bool killaudio; … … class AudioOutputBase : public AudioOutput, public QThread 144 146 bool buffer_output_data_for_use; // used by AudioOutputNULL 145 147 146 148 int configured_audio_channels; 149 int orig_config_channels; 150 int src_quality; 147 151 148 152 private: 149 153 // resampler … … class AudioOutputBase : public AudioOutput, public QThread 156 160 FreeSurround *upmixer; 157 161 158 162 int source_audio_channels; 163 int source_audio_samplerate; 159 164 int source_audio_bytes_per_sample; 160 165 bool needs_upmix; 161 166 int surround_mode; 167 bool allow_ac3_passthru; 168 float old_audio_stretchfactor; 162 169 163 170 bool blocking; // do AddSamples calls block? 164 171 -
mythtv/libs/libmyth/audiooutputdigitalencoder.cpp
diff --git a/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp b/mythtv/libs/libmyth/audiooutputdigitalencoder.cpp index 82fc8cc..bcd5155 100644
a b extern "C" { 29 29 AudioOutputDigitalEncoder::AudioOutputDigitalEncoder(void) : 30 30 audio_bytes_per_sample(0), 31 31 av_context(NULL), 32 outbuf (NULL),33 outbuf_size(0),34 frame_buffer(NULL),35 one_frame_bytes(0)32 outbuflen(0), 33 inbuflen(0), 34 one_frame_bytes(0), 35 reorder(true) 36 36 { 37 37 } 38 38 … … void AudioOutputDigitalEncoder::Dispose() 49 49 av_free(av_context); 50 50 av_context = NULL; 51 51 } 52 53 if (outbuf)54 {55 delete [] outbuf;56 outbuf = NULL;57 outbuf_size = 0;58 }59 60 if (frame_buffer)61 {62 delete [] frame_buffer;63 frame_buffer = NULL;64 one_frame_bytes = 0;65 }66 52 } 67 53 68 54 //CODEC_ID_AC3 69 55 bool AudioOutputDigitalEncoder::Init( 70 CodecID codec_id, int bitrate, int samplerate, int channels )56 CodecID codec_id, int bitrate, int samplerate, int channels, bool reencoding) 71 57 { 72 58 AVCodec *codec; 73 59 int ret; 74 60 75 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 ")61 VERBOSE(VB_AUDIO, LOC + QString("Init codecid=%1, br=%2, sr=%3, ch=%4 re=%5") 76 62 .arg(codec_id_string(codec_id)) 77 63 .arg(bitrate) 78 64 .arg(samplerate) 79 .arg(channels)); 80 81 //codec = avcodec_find_encoder(codec_id); 65 .arg(channels) 66 .arg(reencoding)); 67 68 reorder = !reencoding; 69 70 // We need to do this when called from mythmusic 71 avcodec_init(); 72 avcodec_register_all(); 82 73 // always AC3 as there is no DTS encoder at the moment 2005/1/9 83 74 codec = avcodec_find_encoder(CODEC_ID_AC3); 84 75 if (!codec) … … bool AudioOutputDigitalEncoder::Init( 107 98 audio_bytes_per_sample = bytes_per_frame; 108 99 one_frame_bytes = bytes_per_frame * av_context->frame_size; 109 100 110 outbuf_size = 16384; // ok for AC3 but DTS?111 outbuf = new char [outbuf_size];112 101 VERBOSE(VB_AUDIO, QString("DigitalEncoder::Init fs=%1, bpf=%2 ofb=%3") 113 102 .arg(av_context->frame_size) 114 103 .arg(bytes_per_frame) … … typedef struct { 253 242 254 243 } AESHeader; 255 244 245 void reorder_6ch_ac3(void *buf, unsigned int len) { 246 unsigned short *src = (unsigned short *)buf; 247 unsigned short tmp; 248 unsigned int samples = len >> 1; 249 250 for (uint i = 0; i < samples; i += 6) { 251 tmp = src[i+4]; 252 src[i+4] = src[i+3]; 253 src[i+3] = src[i+2]; 254 src[i+2] = src[i+1]; 255 src[i+1] = tmp; 256 } 257 } 258 256 259 static int encode_frame( 257 260 bool dts, 258 261 unsigned char *data, 259 size_t &len)262 size_t enc_len) 260 263 { 261 264 unsigned char *payload = data + 8; // skip header, currently 52 or 54bits 262 size_t enc_len;263 265 int flags, sample_rate, bit_rate; 264 266 265 267 // we don't do any length/crc validation of the AC3 frame here; presumably … … static int encode_frame( 270 272 // ignore, and if so, may as well just assume that it will ignore 271 273 // anything with a bad CRC... 272 274 273 uint nr_samples = 0, block_len; 275 uint nr_samples = 0, block_len = 0; 276 274 277 if (dts) 275 278 { 276 279 enc_len = dts_syncinfo(payload, &flags, &sample_rate, &bit_rate); … … static int encode_frame( 305 308 #endif 306 309 } 307 310 308 if (enc_len == 0 || enc_len > len)309 {310 int l = len;311 len = 0;312 return l;313 }314 315 311 enc_len = std::min((uint)enc_len, block_len - 8); 316 312 317 313 //uint32_t x = *(uint32_t*)payload; … … static int encode_frame( 364 360 data[6] = (enc_len << 3) & 0xFF; 365 361 data[7] = (enc_len >> 5) & 0xFF; 366 362 memset(payload + enc_len, 0, block_len - 8 - enc_len); 367 len = block_len;368 363 369 364 return enc_len; 370 365 } 371 366 372 367 // must have exactly 1 frames worth of data 373 size_t AudioOutputDigitalEncoder::Encode( short *buff)368 size_t AudioOutputDigitalEncoder::Encode(void *buf, int len) 374 369 { 375 int encsize = 0;376 370 size_t outsize = 0; 377 371 378 // put data in the correct spot for encode frame 379 outsize = avcodec_encode_audio( 380 av_context, ((uchar*)outbuf) + 8, outbuf_size - 8, buff); 381 382 size_t tmpsize = outsize; 383 384 outsize = MAX_AC3_FRAME_SIZE; 385 encsize = encode_frame( 386 /*av_context->codec_id==CODEC_ID_DTS*/ false, 387 (unsigned char*)outbuf, outsize); 372 int fs = FrameSize(); 373 memcpy(inbuf+inbuflen, buf, len); 374 inbuflen += len; 375 int frames = inbuflen / fs; 388 376 389 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 390 QString("DigitalEncoder::Encode len1=%1 len2=%2 finallen=%3") 391 .arg(tmpsize).arg(encsize).arg(outsize)); 377 while (frames--) 378 { 379 if (reorder) 380 reorder_6ch_ac3(inbuf, fs); 381 382 // put data in the correct spot for encode frame 383 outsize = avcodec_encode_audio( 384 av_context, ((uchar*)outbuf) + outbuflen + 8, OUTBUFSIZE - 8, (short int *)inbuf); 385 386 encode_frame( 387 /*av_context->codec_id==CODEC_ID_DTS*/ false, 388 (unsigned char*)outbuf + outbuflen, outsize 389 ); 390 391 outbuflen += MAX_AC3_FRAME_SIZE; 392 inbuflen -= fs; 393 memmove(inbuf, inbuf+fs, inbuflen); 394 } 395 396 return outbuflen; 397 } 392 398 393 return outsize; 399 void AudioOutputDigitalEncoder::GetFrames(void *ptr, int maxlen) 400 { 401 int len = (maxlen < outbuflen ? maxlen : outbuflen); 402 memcpy(ptr, outbuf, len); 403 outbuflen -= len; 404 memmove(outbuf, outbuf+len, outbuflen); 394 405 } -
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/libmyth/audiosettings.cpp
diff --git a/mythtv/libs/libmyth/audiosettings.cpp b/mythtv/libs/libmyth/audiosettings.cpp index 68e515b..00518ec 100644
a b AudioSettings::AudioSettings() : 15 15 samplerate(-1), 16 16 set_initial_vol(false), 17 17 use_passthru(false), 18 codec(NULL),19 18 source(AUDIOOUTPUT_UNKNOWN) 20 19 { 21 20 } … … AudioSettings::AudioSettings(const AudioSettings &other) : 28 27 samplerate(other.samplerate), 29 28 set_initial_vol(other.set_initial_vol), 30 29 use_passthru(other.use_passthru), 31 codec(other.codec),32 30 source(other.source) 33 31 { 34 32 } … … AudioSettings::AudioSettings( 41 39 int audio_samplerate, 42 40 AudioOutputSource audio_source, 43 41 bool audio_set_initial_vol, 44 bool audio_use_passthru, 45 void *audio_codec) : 42 bool audio_use_passthru) : 46 43 main_device(audio_main_device), 47 44 passthru_device(audio_passthru_device), 48 45 bits(audio_bits), … … AudioSettings::AudioSettings( 50 47 samplerate(audio_samplerate), 51 48 set_initial_vol(audio_set_initial_vol), 52 49 use_passthru(audio_use_passthru), 53 codec(audio_codec),54 50 source(audio_source) 55 51 { 56 52 } … … AudioSettings::AudioSettings( 59 55 int audio_bits, 60 56 int audio_channels, 61 57 int audio_samplerate, 62 bool audio_use_passthru, 63 void *audio_codec) : 58 bool audio_use_passthru) : 64 59 main_device(QString::null), 65 60 passthru_device(QString::null), 66 61 bits(audio_bits), … … AudioSettings::AudioSettings( 68 63 samplerate(audio_samplerate), 69 64 set_initial_vol(false), 70 65 use_passthru(audio_use_passthru), 71 codec(audio_codec),72 66 source(AUDIOOUTPUT_UNKNOWN) 73 67 { 74 68 } -
mythtv/libs/libmyth/audiosettings.h
diff --git a/mythtv/libs/libmyth/audiosettings.h b/mythtv/libs/libmyth/audiosettings.h index f9349f4..bd8cb6f 100644
a b class MPUBLIC AudioSettings 32 32 int audio_samplerate, 33 33 AudioOutputSource audio_source, 34 34 bool audio_set_initial_vol, 35 bool audio_use_passthru, 36 void *audio_codec = NULL); 35 bool audio_use_passthru); 37 36 38 37 AudioSettings(int audio_bits, 39 38 int audio_channels, 40 39 int audio_samplerate, 41 bool audio_use_passthru, 42 void *audio_codec = NULL); 40 bool audio_use_passthru); 43 41 44 42 void FixPassThrough(void); 45 43 void TrimDeviceType(void); … … class MPUBLIC AudioSettings 57 55 int samplerate; 58 56 bool set_initial_vol; 59 57 bool use_passthru; 60 void *codec;61 58 AudioOutputSource source; 62 59 }; 63 60 -
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 fc7ed8f..bf93d28 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) : 192 191 if (moviemode) 193 192 { 194 193 params.phasemode = 1; 195 params.center_width = 0;196 params. gain = 1.0;194 params.center_width = 25; 195 params.dimension = 0.5; 197 196 } 198 197 else 199 198 { 200 params.center_width = 70; 201 // for 50, gain should be about 1.9, c/lr about 2.7 202 // for 70, gain should be about 3.1, c/lr about 1.5 203 params.gain = 3.1; 199 params.center_width = 65; 200 params.dimension = 0.3; 204 201 } 205 202 switch (surround_mode) 206 203 { … … void FreeSurround::SetParams() 236 233 decoder->phase_mode(params.phasemode); 237 234 decoder->surround_coefficients(params.coeff_a, params.coeff_b); 238 235 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0); 239 decoder->gain(params.gain);240 236 } 241 237 } 242 238 … … FreeSurround::fsurround_params::fsurround_params( 250 246 phasemode(0), 251 247 steering(1), 252 248 front_sep(100), 253 rear_sep(100), 254 gain(1.0) 249 rear_sep(100) 255 250 { 256 251 } 257 252 … … void FreeSurround::process_block() 655 650 { 656 651 if (decoder) 657 652 { 658 // actually these params need only be set when they change... but it doesn't hurt659 #if 0660 decoder->steering_mode(params.steering);661 decoder->phase_mode(params.phasemode);662 decoder->surround_coefficients(params.coeff_a, params.coeff_b);663 decoder->separation(params.front_sep/100.0,params.rear_sep/100.0);664 #endif665 // decode the bufs->block666 //decoder->decode(input,output,params.center_width/100.0,params.dimension/100.0);667 //decoder->decode(output,params.center_width/100.0,params.dimension/100.0);668 653 decoder->decode(params.center_width/100.0,params.dimension/100.0); 669 654 } 670 655 } -
mythtv/libs/libmythsamplerate/samplerate.c
diff --git a/mythtv/libs/libmythsamplerate/samplerate.c b/mythtv/libs/libmythsamplerate/samplerate.c index adaccf0..a53a942 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 1f97dd5..b977f81 100644
a b NuppelVideoPlayer::NuppelVideoPlayer(QString inUseID, const ProgramInfo *info) 212 212 audio_passthru_device(QString::null), 213 213 audio_channels(2), audio_bits(-1), 214 214 audio_samplerate(44100), audio_stretchfactor(1.0f), 215 audio_codec(NULL),216 215 // Picture-in-Picture 217 216 pipplayer(NULL), setpipplayer(NULL), needsetpipplayer(false), 218 217 // Preview window support … … QString NuppelVideoPlayer::ReinitAudio(void) 885 884 if (audioOutput) 886 885 { 887 886 const AudioSettings settings( 888 audio_bits, audio_channels, audio_samplerate, 889 audio_passthru, audio_codec); 887 audio_bits, audio_channels, audio_samplerate, audio_passthru); 890 888 audioOutput->Reconfigure(settings); 889 if (audio_passthru) 890 audio_channels = 2; 891 891 errMsg = audioOutput->GetError(); 892 892 if (!errMsg.isEmpty()) 893 893 audioOutput->SetStretchFactor(audio_stretchfactor); … … void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 3822 3822 audio_passthru = passthru; 3823 3823 } 3824 3824 3825 void NuppelVideoPlayer::SetAudioCodec(void *ac)3826 {3827 audio_codec = ac;3828 }3829 3830 3825 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3831 3826 { 3832 3827 if (audioOutput) … … void NuppelVideoPlayer::ToggleAdjustFill(AdjustFillMode adjustfillMode) 5039 5034 } 5040 5035 } 5041 5036 5037 bool NuppelVideoPlayer::ToggleUpmix() 5038 { 5039 if (audioOutput) 5040 return audioOutput->ToggleUpmix(); 5041 return false; 5042 } 5043 5042 5044 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5043 5045 { 5044 5046 if (videoOutput) -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.h b/mythtv/libs/libmythtv/NuppelVideoPlayer.h index 89c0b05..dd1a77b 100644
a b class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 178 178 // Toggle Sets 179 179 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 180 180 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 181 bool ToggleUpmix(void); 181 182 182 183 // Gets 183 184 QSize GetVideoBufferSize(void) const { return video_dim; } … … class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 690 691 int audio_bits; 691 692 int audio_samplerate; 692 693 float audio_stretchfactor; 693 void *audio_codec;694 694 bool audio_passthru; 695 695 696 696 // Picture-in-Picture -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index 2950e1c..3cd429f 100644
a b 427 427 audioSamples(NULL), 428 428 allow_ac3_passthru(false), allow_dts_passthru(false), 429 429 disable_passthru(false), max_channels(2), 430 dummy_frame(NULL),430 last_ac3_channels(0), dummy_frame(NULL), 431 431 // DVD 432 432 lastdvdtitle(-1), 433 433 decodeStillFrame(false), … … 2969 2969 { 2970 2970 int idx = atracks[i].av_stream_index; 2971 2971 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2972 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2973 !disable_passthru &&2974 (codec_ctx->codec_id == CODEC_ID_AC3));2975 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2976 !disable_passthru &&2977 (codec_ctx->codec_id == CODEC_ID_DTS));2978 2972 AudioInfo item(codec_ctx->codec_id, 2979 2973 codec_ctx->sample_rate, codec_ctx->channels, 2980 do_ac3_passthru || do_dts_passthru);2974 DoPassThrough(codec_ctx)); 2981 2975 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2982 2976 } 2983 2977 #endif … … 3111 3105 bool AvFormatDecoder::GetFrame(int onlyvideo) 3112 3106 { 3113 3107 AVPacket *pkt = NULL; 3108 AC3HeaderInfo hdr; 3114 3109 int len; 3115 3110 unsigned char *ptr; 3116 3111 int data_size = 0; … … 3304 3299 pts = 0; 3305 3300 3306 3301 AVStream *curstream = ic->streams[pkt->stream_index]; 3302 AVCodecContext *ctx = curstream->codec; 3307 3303 3308 3304 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3309 3305 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3310 3306 3311 3307 if (ringBuffer->isDVD() && 3312 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3308 ctx->codec_type == CODEC_TYPE_VIDEO) 3313 3309 { 3314 3310 MpegPreProcessPkt(curstream, pkt); 3315 3311 … … 3331 3327 3332 3328 if (!d->HasMPEG2Dec()) 3333 3329 { 3334 int current_width = c urstream->codec->width;3330 int current_width = ctx->width; 3335 3331 int video_width = GetNVP()->GetVideoSize().width(); 3336 3332 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3337 3333 { … … 3372 3368 } 3373 3369 3374 3370 if (storevideoframes && 3375 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3371 ctx->codec_type == CODEC_TYPE_VIDEO) 3376 3372 { 3377 3373 av_dup_packet(pkt); 3378 3374 storedPackets.append(pkt); … … 3380 3376 continue; 3381 3377 } 3382 3378 3383 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3379 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3384 3380 pkt->stream_index == selectedVideoIndex) 3385 3381 { 3386 3382 AVCodecContext *context = curstream->codec; 3387 3383 3388 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3389 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3390 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3391 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||3392 c ontext->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)3384 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3385 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3386 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3387 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD || 3388 ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU) 3393 3389 { 3394 3390 if (!ringBuffer->isDVD()) 3395 3391 MpegPreProcessPkt(curstream, pkt); 3396 3392 } 3397 else if (c ontext->codec_id == CODEC_ID_H264 ||3398 c ontext->codec_id == CODEC_ID_H264_VDPAU)3393 else if (ctx->codec_id == CODEC_ID_H264 || 3394 ctx->codec_id == CODEC_ID_H264_VDPAU) 3399 3395 { 3400 3396 H264PreProcessPkt(curstream, pkt); 3401 3397 } … … 3440 3436 } 3441 3437 3442 3438 if (len > 0 && 3443 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3444 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3439 ctx->codec_type == CODEC_TYPE_DATA && 3440 ctx->codec_id == CODEC_ID_MPEG2VBI) 3445 3441 { 3446 3442 ProcessVBIDataPacket(curstream, pkt); 3447 3443 … … 3450 3446 } 3451 3447 3452 3448 if (len > 0 && 3453 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3454 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3449 ctx->codec_type == CODEC_TYPE_DATA && 3450 ctx->codec_id == CODEC_ID_DVB_VBI) 3455 3451 { 3456 3452 ProcessDVBDataPacket(curstream, pkt); 3457 3453 … … 3461 3457 3462 3458 #ifdef USING_MHEG 3463 3459 if (len > 0 && 3464 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3465 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3460 ctx->codec_type == CODEC_TYPE_DATA && 3461 ctx->codec_id == CODEC_ID_DSMCC_B) 3466 3462 { 3467 3463 ProcessDSMCCPacket(curstream, pkt); 3468 3464 … … 3483 3479 #endif // USING_MHEG 3484 3480 3485 3481 // we don't care about other data streams 3486 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3482 if (ctx->codec_type == CODEC_TYPE_DATA) 3487 3483 { 3488 3484 av_free_packet(pkt); 3489 3485 continue; 3490 3486 } 3491 3487 3492 if (!c urstream->codec->codec)3488 if (!ctx->codec) 3493 3489 { 3494 3490 VERBOSE(VB_PLAYBACK, LOC + 3495 3491 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3496 3492 .arg(pkt->stream_index) 3497 .arg(codec_type_string(c urstream->codec->codec_type))3498 .arg(codec_id_string(c urstream->codec->codec_id))3499 .arg(c urstream->codec->codec_id));3493 .arg(codec_type_string(ctx->codec_type)) 3494 .arg(codec_id_string(ctx->codec_id)) 3495 .arg(ctx->codec_id)); 3500 3496 av_free_packet(pkt); 3501 3497 continue; 3502 3498 } … … 3505 3501 have_err = false; 3506 3502 3507 3503 avcodeclock.lock(); 3508 int ctype = c urstream->codec->codec_type;3504 int ctype = ctx->codec_type; 3509 3505 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3510 3506 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3511 3507 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … 3530 3526 3531 3527 // detect switches between stereo and dual languages 3532 3528 bool wasDual = audSubIdx != -1; 3533 bool isDual = c urstream->codec->avcodec_dual_language;3529 bool isDual = ctx->avcodec_dual_language; 3534 3530 if ((wasDual && !isDual) || (!wasDual && isDual)) 3535 3531 { 3536 3532 SetupAudioStreamSubIndexes(audIdx); 3537 3533 reselectAudioTrack = true; 3538 3534 } 3539 3535 3540 bool do_ac3_passthru =3541 (allow_ac3_passthru && !transcoding &&3542 (curstream->codec->codec_id == CODEC_ID_AC3));3543 bool do_dts_passthru =3544 (allow_dts_passthru && !transcoding &&3545 (curstream->codec->codec_id == CODEC_ID_DTS));3546 bool using_passthru = do_ac3_passthru || do_dts_passthru;3547 3548 3536 // detect channels on streams that need 3549 3537 // to be decoded before we can know this 3550 3538 bool already_decoded = false; 3551 if (!c urstream->codec->channels)3539 if (!ctx->channels) 3552 3540 { 3553 3541 QMutexLocker locker(&avcodeclock); 3554 3542 VERBOSE(VB_IMPORTANT, LOC + 3555 3543 QString("Setting channels to %1") 3556 3544 .arg(audioOut.channels)); 3557 3545 3558 if ( using_passthru)3546 if (DoPassThrough(ctx)) 3559 3547 { 3560 3548 // for passthru let it select the max number 3561 3549 // of channels 3562 c urstream->codec->channels = 0;3563 c urstream->codec->request_channels = 0;3550 ctx->channels = 0; 3551 ctx->request_channels = 0; 3564 3552 } 3565 3553 else 3566 3554 { 3567 c urstream->codec->channels = audioOut.channels;3568 c urstream->codec->request_channels =3555 ctx->channels = audioOut.channels; 3556 ctx->request_channels = 3569 3557 audioOut.channels; 3570 3558 } 3571 3559 ret = avcodec_decode_audio( 3572 c urstream->codec, audioSamples,3560 ctx, audioSamples, 3573 3561 &data_size, ptr, len); 3574 3562 already_decoded = true; 3575 3563 3576 reselectAudioTrack |= c urstream->codec->channels;3564 reselectAudioTrack |= ctx->channels; 3577 3565 } 3578 3566 3567 if (ctx->codec_id == CODEC_ID_AC3) 3568 { 3569 GetBitContext gbc; 3570 init_get_bits(&gbc, ptr, len * 8); 3571 if (!ff_ac3_parse_header(&gbc, &hdr)) 3572 { 3573 if (hdr.channels != last_ac3_channels) 3574 { 3575 last_ac3_channels = ctx->channels = hdr.channels; 3576 SetupAudioStream(); 3577 } 3578 } 3579 } 3580 3579 3581 if (reselectAudioTrack) 3580 3582 { 3581 3583 QMutexLocker locker(&avcodeclock); … … 3589 3591 .av_stream_index; 3590 3592 audSubIdx = selectedTrack[kTrackTypeAudio] 3591 3593 .av_substream_index; 3594 ctx = curstream->codec; 3592 3595 } 3593 3596 3594 3597 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … 3620 3623 if (audioOut.do_passthru) 3621 3624 { 3622 3625 data_size = pkt->size; 3623 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3626 bool dts = CODEC_ID_DTS == ctx->codec_id; 3624 3627 ret = encode_frame(dts, ptr, len, 3625 3628 audioSamples, data_size); 3626 3629 } 3627 3630 else 3628 3631 { 3629 AVCodecContext *ctx = curstream->codec;3630 3631 3632 if ((ctx->channels == 0) || 3632 3633 (ctx->channels > audioOut.channels)) 3633 3634 { … … 3636 3637 3637 3638 if (!already_decoded) 3638 3639 { 3639 curstream->codec->request_channels = 3640 audioOut.channels; 3640 ctx->request_channels = audioOut.channels; 3641 3641 ret = avcodec_decode_audio( 3642 3642 ctx, audioSamples, &data_size, ptr, len); 3643 3643 } … … 3654 3654 audIdx = -1; 3655 3655 AutoSelectAudioTrack(); 3656 3656 data_size = 0; 3657 ctx = curstream->codec; 3657 3658 } 3658 3659 } 3659 3660 avcodeclock.unlock(); … … 3671 3672 3672 3673 // calc for next frame 3673 3674 lastapts += (long long)((double)(data_size * 1000) / 3674 (curstream->codec->channels * 2) / 3675 curstream->codec->sample_rate); 3675 (ctx->channels * 2) / ctx->sample_rate); 3676 3676 3677 3677 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3678 3678 LOC + QString("audio timecode %1 %2 %3 %4") … … 3740 3740 continue; 3741 3741 } 3742 3742 3743 AVCodecContext *context = curstream->codec;3744 3743 AVFrame mpa_pic; 3745 3744 bzero(&mpa_pic, sizeof(AVFrame)); 3746 3745 … … 3755 3754 // HACK 3756 3755 while (!gotpicture && count < 5) 3757 3756 { 3758 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3757 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3759 3758 &gotpicture, ptr, len); 3760 3759 count++; 3761 3760 } 3762 3761 } 3763 3762 else 3764 3763 { 3765 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3764 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3766 3765 &gotpicture, ptr, len); 3767 3766 } 3768 3767 } 3769 3768 else 3770 3769 { 3771 ret = avcodec_decode_video(c ontext, &mpa_pic,3770 ret = avcodec_decode_video(ctx, &mpa_pic, 3772 3771 &gotpicture, ptr, len); 3773 3772 // Reparse it to not drop the DVD still frame 3774 3773 if (decodeStillFrame) 3775 ret = avcodec_decode_video(c ontext, &mpa_pic,3774 ret = avcodec_decode_video(ctx, &mpa_pic, 3776 3775 &gotpicture, ptr, len); 3777 3776 } 3778 3777 avcodeclock.unlock(); … … 3839 3838 3840 3839 img_convert(&tmppicture, PIX_FMT_YUV420P, 3841 3840 (AVPicture *)&mpa_pic, 3842 c ontext->pix_fmt,3843 c ontext->width,3844 c ontext->height);3841 ctx->pix_fmt, 3842 ctx->width, 3843 ctx->height); 3845 3844 3846 3845 if (xf) 3847 3846 { … … 3864 3863 (temppts + 10000 > lastvpts || temppts < 0)) 3865 3864 { 3866 3865 temppts = lastvpts; 3867 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3866 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3868 3867 // MPEG2 frames can be repeated, update pts accordingly 3869 3868 temppts += (long long)(mpa_pic.repeat_pict * 500 3870 * av_q2d(c urstream->codec->time_base));3869 * av_q2d(ctx->time_base)); 3871 3870 } 3872 3871 3873 3872 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … 3903 3902 picframe->frameNumber = framesPlayed; 3904 3903 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3905 3904 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3906 c ontext->release_buffer(context, &mpa_pic);3905 ctx->release_buffer(ctx, &mpa_pic); 3907 3906 3908 3907 decoded_video_frame = picframe; 3909 3908 gotvideo = 1; … … 3959 3958 } 3960 3959 default: 3961 3960 { 3962 AVCodecContext *enc = curstream->codec;3963 3961 VERBOSE(VB_IMPORTANT, LOC_ERR + 3964 3962 QString("Decoding - id(%1) type(%2)") 3965 .arg(codec_id_string( enc->codec_id))3966 .arg(codec_type_string( enc->codec_type)));3963 .arg(codec_id_string(ctx->codec_id)) 3964 .arg(codec_type_string(ctx->codec_type))); 3967 3965 have_err = true; 3968 3966 break; 3969 3967 } … … 4112 4110 } 4113 4111 } 4114 4112 4113 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4114 { 4115 bool passthru = false; 4116 4117 if (ctx->codec_id == CODEC_ID_AC3) 4118 passthru = allow_ac3_passthru && 4119 ctx->channels >= (int)max_channels; 4120 else if (ctx->codec_id == CODEC_ID_DTS) 4121 passthru = allow_dts_passthru; 4122 4123 passthru &= !transcoding && !disable_passthru; 4124 // Don't know any cards that support spdif clocked at < 44100 4125 // Some US cable transmissions have 2ch 32k AC-3 streams 4126 passthru &= ctx->sample_rate >= 44100; 4127 4128 return passthru; 4129 } 4130 4115 4131 /** \fn AvFormatDecoder::SetupAudioStream(void) 4116 4132 * \brief Reinitializes audio if it needs to be reinitialized. 4117 4133 * … … 4125 4141 AVStream *curstream = NULL; 4126 4142 AVCodecContext *codec_ctx = NULL; 4127 4143 AudioInfo old_in = audioIn; 4128 AudioInfo old_out = audioOut;4129 4144 bool using_passthru = false; 4130 4145 4131 4146 if ((currentTrack[kTrackTypeAudio] >= 0) && … … 4139 4154 codec_ctx = curstream->codec; 4140 4155 if (codec_ctx) 4141 4156 { 4142 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4143 (codec_ctx->codec_id == CODEC_ID_AC3)); 4144 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4145 (codec_ctx->codec_id == CODEC_ID_DTS)); 4146 using_passthru = do_ac3_passthru || do_dts_passthru; 4147 info = AudioInfo(codec_ctx->codec_id, 4148 codec_ctx->sample_rate, codec_ctx->channels, 4149 using_passthru && !disable_passthru); 4157 using_passthru = DoPassThrough(codec_ctx); 4158 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4159 codec_ctx->channels, using_passthru); 4150 4160 } 4151 4161 } 4152 4162 … … 4163 4173 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4164 4174 4165 4175 audioOut = audioIn = info; 4166 AudioInfo tmpAudioOut = audioOut;4167 4176 4168 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4169 if (using_passthru && !disable_passthru) 4177 if (!using_passthru && audioOut.channels > (int)max_channels) 4170 4178 { 4171 tmpAudioOut.channels = 2; 4172 tmpAudioOut.sample_rate = 48000; 4173 tmpAudioOut.sample_size = 4; 4174 } 4175 4176 if (audioOut.channels > (int) max_channels) 4177 { 4178 audioOut.channels = (int) max_channels; 4179 audioOut.channels = (int)max_channels; 4179 4180 audioOut.sample_size = audioOut.channels * 2; 4180 codec_ctx->channels 4181 codec_ctx->channels = audioOut.channels; 4181 4182 } 4182 4183 4183 if (!using_passthru)4184 tmpAudioOut = audioOut;4185 4186 4184 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4187 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4188 .arg((using_passthru) ? "digital passthrough " : "") 4189 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4190 .arg(old_in.toString()).arg(old_out.toString()) 4191 .arg(audioIn.toString()).arg(audioOut.toString())); 4185 QString("\n\t\t\tfrom %1 to %2") 4186 .arg(old_in.toString()).arg(audioOut.toString())); 4192 4187 4193 if ( tmpAudioOut.sample_rate > 0)4194 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4188 if (audioOut.sample_rate > 0) 4189 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4195 4190 4196 GetNVP()->SetAudioParams( tmpAudioOut.bps(), tmpAudioOut.channels,4197 tmpAudioOut.sample_rate, audioIn.do_passthru);4191 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4192 audioOut.sample_rate, audioOut.do_passthru); 4198 4193 4199 // allow the audio stuff to reencode4200 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4201 4194 GetNVP()->ReinitAudio(); 4202 4195 4203 4196 return true; -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index bdfed17..4c89fda 100644
a b class AvFormatDecoder : public DecoderBase 197 197 198 198 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 199 199 200 bool DoPassThrough(const AVCodecContext *ctx); 200 201 bool SetupAudioStream(void); 201 202 void SetupAudioStreamSubIndexes(int streamIndex); 202 203 void RemoveAudioStreams(); … … class AvFormatDecoder : public DecoderBase 268 269 bool allow_dts_passthru; 269 270 bool disable_passthru; 270 271 uint max_channels; 272 uint last_ac3_channels; 271 273 272 274 VideoFrame *dummy_frame; 273 275 -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index 10a1420..57cb02e 100644
a b void TV::InitKeys(void) 378 378 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 379 379 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 380 380 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 381 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 381 382 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture mode", 382 383 "V"); 383 384 REG_KEY("TV Playback", "TOGGLEPIPWINDOW", "Toggle active PiP window", "B"); … … void TV::InitKeys(void) 510 511 Teletext F2,F3,F4,F5,F6,F7,F8 511 512 ITV F2,F3,F4,F5,F6,F7,F12 512 513 513 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 514 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 514 515 */ 515 516 } 516 517 … … void TV::ProcessKeypress(QKeyEvent *e) 2776 2777 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2777 2778 action == "STRETCHINC" || action == "STRETCHDEC" || 2778 2779 action == "MUTE" || action == "TOGGLEASPECT" || 2779 action == "TOGGLEFILL" )2780 action == "TOGGLEFILL" || action == "TOGGLEUPMIX") 2780 2781 { 2781 2782 passThru = 1; 2782 2783 handled = false; … … void TV::ProcessKeypress(QKeyEvent *e) 2831 2832 else if (action == "VOLUMEDOWN" || action == "VOLUMEUP" || 2832 2833 action == "STRETCHINC" || action == "STRETCHDEC" || 2833 2834 action == "MUTE" || action == "PAUSE" || 2834 action == "CLEAROSD" )2835 action == "CLEAROSD" || action == "TOGGLEUPMIX") 2835 2836 { 2836 2837 passThru = 1; 2837 2838 handled = false; … … void TV::ProcessKeypress(QKeyEvent *e) 3159 3160 ChangeTimeStretch(0); // just display 3160 3161 else if (action == "TOGGLESTRETCH") 3161 3162 ToggleTimeStretch(); 3163 else if (action == "TOGGLEUPMIX") 3164 ToggleUpmix(); 3162 3165 else if (action == "CYCLECOMMSKIPMODE") { 3163 3166 SetAutoCommercialSkip((enum commSkipMode) 3164 3167 ((autoCommercialSkip + 1) % CommSkipModes)); … … void TV::ChangeTimeStretch(int dir, bool allowEdit) 6062 6065 } 6063 6066 } 6064 6067 6068 void TV::ToggleUpmix() 6069 { 6070 if (!activenvp || !activenvp->HasAudioOut()) 6071 return; 6072 QString text; 6073 if (activenvp->ToggleUpmix()) 6074 text = tr("Upmixer On"); 6075 else 6076 text = tr("Upmixer Off"); 6077 6078 if (GetOSD() && !browsemode) 6079 GetOSD()->SetSettingsText(text, 5); 6080 } 6081 6065 6082 // dir in 10ms jumps 6066 6083 void TV::ChangeAudioSync(int dir, bool allowEdit) 6067 6084 { … … void TV::TreeMenuSelected(OSDListTreeType *tree, OSDGenericTree *item) 7375 7392 7376 7393 ChangeTimeStretch(0, !floatRead); // just display 7377 7394 } 7395 else if (action == "TOGGLEUPMIX") 7396 ToggleUpmix(); 7378 7397 else if (action.left(11) == "SELECTSCAN_") 7379 7398 activenvp->SetScanType((FrameScanType) action.right(1).toInt()); 7380 7399 else if (action.left(15) == "TOGGLEAUDIOSYNC") … … void TV::BuildOSDTreeMenu(void) 7629 7648 new OSDGenericTree(ats_item, tr("1.5X"), "ADJUSTSTRETCH1.5", 7630 7649 (speedX100 == 150) ? 1 : 0, NULL, 7631 7650 "STRETCHGROUP"); 7651 7652 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 7632 7653 7633 7654 // add scan mode override settings to menu 7634 7655 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 0780eb0..2941d3e 100644
a b class MPUBLIC TV : public QThread 333 333 void ChangeSpeed(int direction); 334 334 void ToggleTimeStretch(void); 335 335 void ChangeTimeStretch(int dir, bool allowEdit = true); 336 void ToggleUpmix(void); 336 337 void ChangeAudioSync(int dir, bool allowEdit = true); 337 338 float StopFFRew(void); 338 339 void ChangeFFRew(int direction); -
mythtv/programs/mythfrontend/globalsettings.cpp
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index b880160..0b7814d 100644
a b static HostComboBox *AudioUpmixType() 119 119 return gc; 120 120 } 121 121 122 static HostComboBox *SRCQuality() 123 { 124 HostComboBox *gc = new HostComboBox("SRCQuality", false); 125 gc->setLabel(QObject::tr("Sample Rate Conversion")); 126 gc->addSelection(QObject::tr("Best"), "3", true); // default 127 gc->addSelection(QObject::tr("Medium"), "2"); 128 gc->addSelection(QObject::tr("Fastest"), "1"); 129 gc->addSelection(QObject::tr("Disabled"), "0"); 130 gc->setHelpText( 131 QObject::tr( 132 "Set the quality of audio sample rate conversion. " 133 "This only affects non 48000Hz PCM audio. " 134 "All three options offer a worst-case SNR of 97dB. " 135 "'Best' at a bandwidth of 97%. " 136 "'Medium' at a bandwidth of 90%. " 137 "'Fastest' at a bandwidth of 80%. " 138 "Set 'Disabled' only if you know what you are doing.")); 139 return gc; 140 } 141 142 122 143 static HostComboBox *PassThroughOutputDevice() 123 144 { 124 145 HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); … … class AudioSettingsGroup : public TriggeredConfigurationGroup 3387 3408 agrp->addChild(AudioUpmixType()); 3388 3409 addChild(agrp); 3389 3410 3411 HorizontalConfigurationGroup *agrp1 = 3412 new HorizontalConfigurationGroup(false, false, true, true); 3413 agrp1->addChild(SRCQuality()); 3414 addChild(agrp1); 3415 3390 3416 VerticalConfigurationGroup *vgrp1 = 3391 3417 new VerticalConfigurationGroup(false, false, true, true); 3392 3418 vgrp1->addChild(AggressiveBuffer()); -
mythtv/programs/mythtranscode/transcode.cpp
diff --git a/mythtv/programs/mythtranscode/transcode.cpp b/mythtv/programs/mythtranscode/transcode.cpp index dc8c4b0..f035eb5 100644
a b class AudioReencodeBuffer : public AudioOutput 215 215 // Do nothing 216 216 return kMuteOff; 217 217 } 218 virtual bool ToggleUpmix(void) 219 { 220 // Do nothing 221 return false; 222 } 218 223 219 224 // These are pure virtual in AudioOutput, but we don't need them here 220 225 virtual void bufferOutputData(bool){ return; }