Ticket #5900: audioencoding-trunk-5.patch
File audioencoding-trunk-5.patch, 85.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 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..ed3d495 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 snd_ctl_elem_id_alloca(&cid); 65 snd_ctl_elem_list_get_id(clist, cidx, cid); 66 snd_ctl_elem_value_alloca(&cval); 67 snd_ctl_elem_value_set_id(cval, cid); 68 snd_ctl_elem_read(ctl,cval); 69 snd_ctl_elem_value_get_iec958(cval, &iec958); 70 71 if (!audio) 72 iec958.status[0] |= IEC958_AES0_NONAUDIO; 73 else 74 iec958.status[0] &= ~IEC958_AES0_NONAUDIO; 75 76 snd_ctl_elem_value_set_iec958(cval, &iec958); 77 snd_ctl_elem_write(ctl, cval); 78 35 79 } 36 80 37 81 bool AudioOutputALSA::OpenDevice() … … bool AudioOutputALSA::OpenDevice() 39 83 snd_pcm_format_t format; 40 84 unsigned int buffer_time, period_time; 41 85 int err; 86 QString real_device; 42 87 43 88 if (pcm_handle != NULL) 44 89 CloseDevice(); 45 90 46 91 pcm_handle = NULL; 47 92 numbadioctls = 0; 48 49 QString real_device = (audio_passthru) ? 50 audio_passthru_device : audio_main_device; 93 94 if (audio_passthru || audio_enc) 95 { 96 real_device = audio_passthru_device; 97 SetIECStatus(false); 98 } 99 else 100 { 101 real_device = audio_main_device; 102 SetIECStatus(true); 103 } 51 104 52 105 VERBOSE(VB_GENERAL, QString("Opening ALSA audio device '%1'.") 53 106 .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..2905f16 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 allow_ac3_passthru = gContext->GetNumSetting("AC3PassThru", false); 85 src_quality = gContext->GetNumSetting("SRCQuality", 3); 82 86 83 87 // You need to call Reconfigure from your concrete class. 84 88 // 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) const 183 155 return audio_stretchfactor; 184 156 } 185 157 158 bool AudioOutputBase::ToggleUpmix(void) 159 { 160 if (audio_passthru) 161 return false; 162 if (configured_audio_channels == 6) 163 configured_audio_channels = 2; 164 else 165 configured_audio_channels = 6; 166 167 const AudioSettings settings(audio_bits, source_audio_channels, 168 source_audio_samplerate, audio_passthru); 169 Reconfigure(settings); 170 return (configured_audio_channels == 6); 171 } 172 173 186 174 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 187 175 { 188 176 AudioSettings settings = orig_settings; 189 177 190 int codec_id = CODEC_ID_NONE;191 int lcodec_id = CODEC_ID_NONE;192 int lcchannels = 0;193 int cchannels = 0;194 178 int lsource_audio_channels = settings.channels; 195 179 bool lneeds_upmix = false; 180 bool laudio_reenc = false; 196 181 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 } 182 // Are we reencoding a (previously) timestretched bitstream? 183 if (settings.channels > 2 && !settings.use_passthru) 184 laudio_reenc = true; 212 185 213 if ((configured_audio_channels == 6) && 214 !(settings.codec || audio_codec)) 186 // Enough channels? Upmix if not 187 if (settings.channels < configured_audio_channels && 188 !settings.use_passthru) 215 189 { 216 190 settings.channels = configured_audio_channels; 217 191 lneeds_upmix = true; … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 224 198 settings.samplerate == audio_samplerate && !need_resampler && 225 199 settings.use_passthru == audio_passthru && 226 200 lneeds_upmix == needs_upmix && 227 l codec_id == codec_id && lcchannels == cchannels);201 laudio_reenc == audio_reenc); 228 202 bool upmix_deps = 229 203 (lsource_audio_channels == source_audio_channels); 230 204 if (general_deps && upmix_deps) … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 251 225 waud = raud = 0; 252 226 audio_actually_paused = false; 253 227 254 bool redo_stretch = (pSoundStretch && audio_channels != settings.channels);255 228 audio_channels = settings.channels; 256 229 source_audio_channels = lsource_audio_channels; 257 230 audio_bits = settings.bits; 258 audio_samplerate = settings.samplerate;259 audio_ codec = (AVCodecContext*)settings.codec;231 source_audio_samplerate = audio_samplerate = settings.samplerate; 232 audio_reenc = laudio_reenc; 260 233 audio_passthru = settings.use_passthru; 261 234 needs_upmix = lneeds_upmix; 262 235 … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 265 238 Error("AudioOutput only supports 8 or 16bit audio."); 266 239 return; 267 240 } 268 audio_bytes_per_sample = audio_channels * audio_bits / 8;269 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8;270 241 271 242 need_resampler = false; 272 243 killaudio = false; … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 275 246 internal_vol = gContext->GetNumSetting("MythControlsVolume", 0); 276 247 277 248 numlowbuffer = 0; 249 250 // Encode to AC-3 if not passing thru , there's > 2 channels 251 // and a passthru device is defined 252 if (!audio_passthru && audio_channels > 2 && allow_ac3_passthru) 253 { 254 int srate = src_quality == 0 ? audio_samplerate : 48000; 255 VERBOSE(VB_AUDIO, LOC + "Creating AC-3 Encoder"); 256 encoder = new AudioOutputDigitalEncoder(); 257 if (!encoder->Init(CODEC_ID_AC3, 448000, srate, 258 configured_audio_channels, audio_reenc)) 259 { 260 VERBOSE(VB_AUDIO, LOC + "Can't create AC-3 encoder"); 261 delete encoder; 262 encoder = NULL; 263 } 264 265 audio_enc = true; 266 } 267 268 if(audio_passthru || audio_enc) 269 // AC-3 output - soundcard expects a 2ch 48k stream 270 audio_channels = 2; 271 272 audio_bytes_per_sample = audio_channels * audio_bits / 8; 273 source_audio_bytes_per_sample = source_audio_channels * audio_bits / 8; 278 274 275 // Always resample to 48k - many cards can't do anything else 276 // and ALSA will do it with linear interpolation (yuk) if we don't anyway 277 if (src_quality != 0 && audio_samplerate != 48000) 278 { 279 int error; 280 audio_samplerate = 48000; 281 VERBOSE(VB_GENERAL, LOC + QString("Using resampler. From: %1 to %2") 282 .arg(settings.samplerate).arg(audio_samplerate)); 283 src_ctx = src_new(3-src_quality, audio_channels, &error); 284 if (error) 285 { 286 Error(QString("Error creating resampler, the error was: %1") 287 .arg(src_strerror(error)) ); 288 src_ctx = NULL; 289 return; 290 } 291 src_data.src_ratio = (double) audio_samplerate / settings.samplerate; 292 src_data.data_in = src_in; 293 src_data.data_out = src_out; 294 src_data.output_frames = 16384*6; 295 need_resampler = true; 296 } 297 279 298 VERBOSE(VB_GENERAL, QString("Opening audio device '%1'. ch %2(%3) sr %4") 280 299 .arg(audio_main_device).arg(audio_channels) 281 300 .arg(source_audio_channels).arg(audio_samplerate)); … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 309 328 current_seconds = -1; 310 329 source_bitrate = -1; 311 330 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 331 if (needs_upmix) 334 332 { 335 333 VERBOSE(VB_AUDIO, LOC + QString("create upmixer")); … … void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 344 342 (FreeSurround::SurroundMode)surround_mode); 345 343 346 344 VERBOSE(VB_AUDIO, LOC + 347 QString(" create upmixer done with surround mode %1")345 QString("Create upmixer done with surround mode %1") 348 346 .arg(surround_mode)); 349 347 } 350 348 351 349 VERBOSE(VB_AUDIO, LOC + QString("Audio Stretch Factor: %1") 352 350 .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 351 352 SetStretchFactorLocked(old_audio_stretchfactor); 353 404 354 // Setup visualisations, zero the visualisations buffers 405 355 prepareVisuals(); 406 356 … … void AudioOutputBase::KillAudio() 436 386 VERBOSE(VB_AUDIO, LOC + "Killing AudioOutputDSP"); 437 387 killaudio = true; 438 388 StopOutputThread(); 389 QMutexLocker lock1(&audio_buflock); 439 390 440 391 // Close resampler? 441 392 if (src_ctx) 393 { 442 394 src_delete(src_ctx); 395 src_ctx = NULL; 396 } 397 443 398 need_resampler = false; 444 399 445 400 // close sound stretcher … … void AudioOutputBase::KillAudio() 447 402 { 448 403 delete pSoundStretch; 449 404 pSoundStretch = NULL; 405 old_audio_stretchfactor = audio_stretchfactor; 406 audio_stretchfactor = 1.0; 450 407 } 451 408 452 409 if (encoder) … … void AudioOutputBase::KillAudio() 461 418 upmixer = NULL; 462 419 } 463 420 needs_upmix = false; 421 audio_enc = false; 464 422 465 423 CloseDevice(); 466 424 … … int AudioOutputBase::GetAudiotime(void) 562 520 ret += (now.tv_usec - audiotime_updated.tv_usec) / 1000; 563 521 ret = (long long)(ret * audio_stretchfactor); 564 522 565 #if 1566 523 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 567 524 QString("GetAudiotime now=%1.%2, set=%3.%4, ret=%5, audt=%6 sf=%7") 568 525 .arg(now.tv_sec).arg(now.tv_usec) … … int AudioOutputBase::GetAudiotime(void) 571 528 .arg(audiotime) 572 529 .arg(audio_stretchfactor) 573 530 ); 574 #endif575 531 576 532 ret += audiotime; 577 533 … … void AudioOutputBase::SetAudiotime(void) 611 567 612 568 // include algorithmic latencies 613 569 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 570 totalbuffer += (int)((pSoundStretch->numUnprocessedSamples() * 621 571 audio_bytes_per_sample) / audio_stretchfactor); 622 }623 572 624 573 if (upmixer && needs_upmix) 625 {626 574 totalbuffer += upmixer->sampleLatency() * audio_bytes_per_sample; 627 } 575 576 if (encoder) 577 totalbuffer += encoder->Buffered(); 628 578 629 579 audiotime = audbuf_timecode - (int)(totalbuffer * 100000.0 / 630 580 (audio_bytes_per_sample * effdspstretched)); 631 581 632 582 gettimeofday(&audiotime_updated, NULL); 633 #if 1 583 634 584 VERBOSE(VB_AUDIO+VB_TIMESTAMP, 635 585 QString("SetAudiotime set=%1.%2, audt=%3 atc=%4 " 636 586 "tb=%5 sb=%6 eds=%7 abps=%8 sf=%9") … … void AudioOutputBase::SetAudiotime(void) 642 592 .arg(effdspstretched) 643 593 .arg(audio_bytes_per_sample) 644 594 .arg(audio_stretchfactor)); 645 #endif646 595 } 647 596 648 597 int AudioOutputBase::GetAudioBufferedTime(void) … … bool AudioOutputBase::AddSamples(char *buffers[], int samples, 681 630 return false; // would overflow 682 631 } 683 632 633 QMutexLocker lock1(&audio_buflock); 634 684 635 // resample input if necessary 685 636 if (need_resampler && src_ctx) 686 637 { … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 725 676 int abps = (encoder) ? 726 677 encoder->audio_bytes_per_sample : audio_bytes_per_sample; 727 678 int len = samples * abps; 679 680 // Give original samples to mythmusic visualisation 681 dispatchVisual((unsigned char *)buffer, len, timecode, 682 source_audio_channels, audio_bits); 728 683 729 684 // Check we have enough space to write the data 730 685 if (need_resampler && src_ctx) … … bool AudioOutputBase::AddSamples(char *buffer, int samples, long long timecode) 749 704 return false; // would overflow 750 705 } 751 706 707 QMutexLocker lock1(&audio_buflock); 708 752 709 // resample input if necessary 753 710 if (need_resampler && src_ctx) 754 711 { … … int AudioOutputBase::WaitForFreeSpace(int samples) 808 765 if (src_ctx) 809 766 { 810 767 int error = src_reset(src_ctx); 811 if (error) 768 if (error) 769 { 812 770 VERBOSE(VB_IMPORTANT, LOC_ERR + QString( 813 771 "Error occured while resetting resampler: %1") 814 772 .arg(src_strerror(error))); 773 src_ctx = NULL; 774 } 815 775 } 816 776 } 817 777 } … … int AudioOutputBase::WaitForFreeSpace(int samples) 821 781 void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 822 782 long long timecode) 823 783 { 824 audio_buflock.lock();825 826 784 int len; // = samples * audio_bytes_per_sample; 827 785 int audio_bytes = audio_bits / 8; 828 786 int org_waud = waud; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 839 797 .arg(samples * abps) 840 798 .arg(kAudioRingBufferSize-afree).arg(afree).arg(timecode) 841 799 .arg(needs_upmix)); 842 800 801 len = WaitForFreeSpace(samples); 802 843 803 if (upmixer && needs_upmix) 844 804 { 845 805 int out_samples = 0; 806 org_waud = waud; 846 807 int step = (interleaved)?source_audio_channels:1; 847 len = WaitForFreeSpace(samples); // test 808 848 809 for (int itemp = 0; itemp < samples; ) 849 810 { 850 // just in case it does a processing cycle, release the lock851 // to allow the output loop to do output852 audio_buflock.unlock();853 811 if (audio_bytes == 2) 854 812 { 855 813 itemp += upmixer->putSamples( … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 866 824 source_audio_channels, 867 825 (interleaved) ? 0 : samples); 868 826 } 869 audio_buflock.lock();870 827 871 828 int copy_samples = upmixer->numSamples(); 872 829 if (copy_samples) … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 900 857 } 901 858 else 902 859 { 903 len = WaitForFreeSpace(samples);904 905 860 if (interleaved) 906 861 { 907 862 char *mybuf = (char*)buffer; … … void AudioOutputBase::_AddSamples(void *buffer, bool interleaved, int samples, 936 891 } 937 892 } 938 893 939 if (samples > 0) 894 if (samples <= 0) 895 return; 896 897 if (pSoundStretch) 940 898 { 941 if (pSoundStretch) 899 // does not change the timecode, only the number of samples 900 // back to orig pos 901 org_waud = waud; 902 int bdiff = kAudioRingBufferSize - org_waud; 903 int nSamplesToEnd = bdiff/abps; 904 if (bdiff < len) 905 { 906 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 907 (audiobuffer + 908 org_waud), nSamplesToEnd); 909 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*)audiobuffer, 910 (len - bdiff) / abps); 911 } 912 else 942 913 { 914 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 915 (audiobuffer + org_waud), 916 len / abps); 917 } 943 918 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); 919 int nSamples = pSoundStretch->numSamples(); 920 len = WaitForFreeSpace(nSamples); 921 922 while ((nSamples = pSoundStretch->numSamples())) 923 { 924 if (nSamples > nSamplesToEnd) 925 nSamples = nSamplesToEnd; 926 927 nSamples = pSoundStretch->receiveSamples( 928 (soundtouch::SAMPLETYPE*) 929 (audiobuffer + org_waud), nSamples 930 ); 931 932 if (nSamples == nSamplesToEnd) { 933 org_waud = 0; 934 nSamplesToEnd = kAudioRingBufferSize/abps; 956 935 } 957 else 958 { 959 pSoundStretch->putSamples((soundtouch::SAMPLETYPE*) 960 (audiobuffer + org_waud), 961 len / abps); 936 else { 937 org_waud += nSamples * abps; 938 nSamplesToEnd -= nSamples; 962 939 } 940 941 } 942 943 } 963 944 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;945 // Encode to AC-3? 946 if (encoder) 947 { 948 949 org_waud = waud; 950 int bdiff = kAudioRingBufferSize - org_waud; 951 int to_get = 0; 971 952 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 953 if (bdiff < len) 954 { 955 encoder->Encode(audiobuffer + org_waud, bdiff); 956 to_get = encoder->Encode(audiobuffer, len - bdiff); 957 } 958 else 959 to_get = encoder->Encode(audiobuffer + org_waud, len); 960 961 if (to_get > 0) 962 { 963 964 if (to_get >= bdiff) 1012 965 { 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); 966 encoder->GetFrames(audiobuffer + org_waud, bdiff); 967 to_get -= bdiff; 968 org_waud = 0; 1043 969 } 1044 } 970 if (to_get > 0) 971 encoder->GetFrames(audiobuffer + org_waud, to_get); 1045 972 1046 waud = org_waud; 1047 lastaudiolen = audiolen(false); 973 org_waud += to_get; 1048 974 1049 if (timecode < 0)1050 {1051 // mythmusic doesn't give timestamps..1052 timecode = (int)((samples_buffered * 100000.0) / effdsp);1053 975 } 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 976 1063 if (interleaved)1064 {1065 dispatchVisual((unsigned char *)buffer, len, timecode,1066 source_audio_channels, audio_bits);1067 }1068 977 } 1069 978 1070 audio_buflock.unlock(); 979 waud = org_waud; 980 lastaudiolen = audiolen(false); 981 982 if (timecode < 0) 983 // mythmusic doesn't give timestamps.. 984 timecode = (int)((samples_buffered * 100000.0) / effdsp); 985 986 samples_buffered += samples; 987 988 /* we want the time at the end -- but the file format stores 989 time at the start of the chunk. */ 990 // even with timestretch, timecode is still calculated from original 991 // sample count 992 audbuf_timecode = timecode + (int)((samples * 100000.0) / effdsp); 993 1071 994 } 1072 995 1073 996 void AudioOutputBase::Status() -
mythtv/libs/libmyth/audiooutputbase.h
diff --git a/mythtv/libs/libmyth/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h index 6e4d792..faf9631 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 src_quality; 147 150 148 151 private: 149 152 // resampler … … class AudioOutputBase : public AudioOutput, public QThread 156 159 FreeSurround *upmixer; 157 160 158 161 int source_audio_channels; 162 int source_audio_samplerate; 159 163 int source_audio_bytes_per_sample; 160 164 bool needs_upmix; 161 165 int surround_mode; 166 bool allow_ac3_passthru; 167 float old_audio_stretchfactor; 162 168 163 169 bool blocking; // do AddSamples calls block? 164 170 -
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 AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 415 415 audioSamples(NULL), 416 416 allow_ac3_passthru(false), allow_dts_passthru(false), 417 417 disable_passthru(false), max_channels(2), 418 dummy_frame(NULL),418 last_ac3_channels(0), dummy_frame(NULL), 419 419 // DVD 420 420 lastdvdtitle(-1), 421 421 decodeStillFrame(false), … … int AvFormatDecoder::AutoSelectAudioTrack(void) 2858 2858 { 2859 2859 int idx = atracks[i].av_stream_index; 2860 2860 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2861 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2862 !disable_passthru &&2863 (codec_ctx->codec_id == CODEC_ID_AC3));2864 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2865 !disable_passthru &&2866 (codec_ctx->codec_id == CODEC_ID_DTS));2867 2861 AudioInfo item(codec_ctx->codec_id, 2868 2862 codec_ctx->sample_rate, codec_ctx->channels, 2869 do_ac3_passthru || do_dts_passthru);2863 DoPassThrough(codec_ctx)); 2870 2864 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2871 2865 } 2872 2866 #endif … … static void extract_mono_channel(uint channel, AudioInfo *audioInfo, 3000 2994 bool AvFormatDecoder::GetFrame(int onlyvideo) 3001 2995 { 3002 2996 AVPacket *pkt = NULL; 2997 AC3HeaderInfo hdr; 3003 2998 int len; 3004 2999 unsigned char *ptr; 3005 3000 int data_size = 0; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3193 3188 pts = 0; 3194 3189 3195 3190 AVStream *curstream = ic->streams[pkt->stream_index]; 3191 AVCodecContext *ctx = curstream->codec; 3196 3192 3197 3193 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3198 3194 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3199 3195 3200 3196 if (ringBuffer->isDVD() && 3201 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3197 ctx->codec_type == CODEC_TYPE_VIDEO) 3202 3198 { 3203 3199 MpegPreProcessPkt(curstream, pkt); 3204 3200 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3220 3216 3221 3217 if (!d->HasMPEG2Dec()) 3222 3218 { 3223 int current_width = c urstream->codec->width;3219 int current_width = ctx->width; 3224 3220 int video_width = GetNVP()->GetVideoSize().width(); 3225 3221 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3226 3222 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3261 3257 } 3262 3258 3263 3259 if (storevideoframes && 3264 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3260 ctx->codec_type == CODEC_TYPE_VIDEO) 3265 3261 { 3266 3262 av_dup_packet(pkt); 3267 3263 storedPackets.append(pkt); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3269 3265 continue; 3270 3266 } 3271 3267 3272 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3268 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3273 3269 pkt->stream_index == selectedVideoIndex) 3274 3270 { 3275 AVCodecContext *context = curstream->codec;3276 3271 3277 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3278 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3279 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3280 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD)3272 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3273 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3274 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3275 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD) 3281 3276 { 3282 3277 if (!ringBuffer->isDVD()) 3283 3278 MpegPreProcessPkt(curstream, pkt); 3284 3279 } 3285 else if (c ontext->codec_id == CODEC_ID_H264)3280 else if (ctx->codec_id == CODEC_ID_H264) 3286 3281 { 3287 3282 H264PreProcessPkt(curstream, pkt); 3288 3283 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3327 3322 } 3328 3323 3329 3324 if (len > 0 && 3330 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3331 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3325 ctx->codec_type == CODEC_TYPE_DATA && 3326 ctx->codec_id == CODEC_ID_MPEG2VBI) 3332 3327 { 3333 3328 ProcessVBIDataPacket(curstream, pkt); 3334 3329 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3337 3332 } 3338 3333 3339 3334 if (len > 0 && 3340 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3341 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3335 ctx->codec_type == CODEC_TYPE_DATA && 3336 ctx->codec_id == CODEC_ID_DVB_VBI) 3342 3337 { 3343 3338 ProcessDVBDataPacket(curstream, pkt); 3344 3339 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3348 3343 3349 3344 #ifdef USING_MHEG 3350 3345 if (len > 0 && 3351 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3352 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3346 ctx->codec_type == CODEC_TYPE_DATA && 3347 ctx->codec_id == CODEC_ID_DSMCC_B) 3353 3348 { 3354 3349 ProcessDSMCCPacket(curstream, pkt); 3355 3350 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3370 3365 #endif // USING_MHEG 3371 3366 3372 3367 // we don't care about other data streams 3373 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3368 if (ctx->codec_type == CODEC_TYPE_DATA) 3374 3369 { 3375 3370 av_free_packet(pkt); 3376 3371 continue; 3377 3372 } 3378 3373 3379 if (!c urstream->codec->codec)3374 if (!ctx->codec) 3380 3375 { 3381 3376 VERBOSE(VB_PLAYBACK, LOC + 3382 3377 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3383 3378 .arg(pkt->stream_index) 3384 .arg(codec_type_string(c urstream->codec->codec_type))3385 .arg(codec_id_string(c urstream->codec->codec_id))3386 .arg(c urstream->codec->codec_id));3379 .arg(codec_type_string(ctx->codec_type)) 3380 .arg(codec_id_string(ctx->codec_id)) 3381 .arg(ctx->codec_id)); 3387 3382 av_free_packet(pkt); 3388 3383 continue; 3389 3384 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3392 3387 have_err = false; 3393 3388 3394 3389 avcodeclock.lock(); 3395 int ctype = c urstream->codec->codec_type;3390 int ctype = ctx->codec_type; 3396 3391 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3397 3392 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3398 3393 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3417 3412 3418 3413 // detect switches between stereo and dual languages 3419 3414 bool wasDual = audSubIdx != -1; 3420 bool isDual = c urstream->codec->avcodec_dual_language;3415 bool isDual = ctx->avcodec_dual_language; 3421 3416 if ((wasDual && !isDual) || (!wasDual && isDual)) 3422 3417 { 3423 3418 SetupAudioStreamSubIndexes(audIdx); 3424 3419 reselectAudioTrack = true; 3425 3420 } 3426 3421 3427 bool do_ac3_passthru =3428 (allow_ac3_passthru && !transcoding &&3429 (curstream->codec->codec_id == CODEC_ID_AC3));3430 bool do_dts_passthru =3431 (allow_dts_passthru && !transcoding &&3432 (curstream->codec->codec_id == CODEC_ID_DTS));3433 bool using_passthru = do_ac3_passthru || do_dts_passthru;3434 3435 3422 // detect channels on streams that need 3436 3423 // to be decoded before we can know this 3437 3424 bool already_decoded = false; 3438 if (!c urstream->codec->channels)3425 if (!ctx->channels) 3439 3426 { 3440 3427 QMutexLocker locker(&avcodeclock); 3441 3428 VERBOSE(VB_IMPORTANT, LOC + 3442 3429 QString("Setting channels to %1") 3443 3430 .arg(audioOut.channels)); 3444 3431 3445 if ( using_passthru)3432 if (DoPassThrough(ctx)) 3446 3433 { 3447 3434 // for passthru let it select the max number 3448 3435 // of channels 3449 c urstream->codec->channels = 0;3450 c urstream->codec->request_channels = 0;3436 ctx->channels = 0; 3437 ctx->request_channels = 0; 3451 3438 } 3452 3439 else 3453 3440 { 3454 c urstream->codec->channels = audioOut.channels;3455 c urstream->codec->request_channels =3441 ctx->channels = audioOut.channels; 3442 ctx->request_channels = 3456 3443 audioOut.channels; 3457 3444 } 3458 3445 ret = avcodec_decode_audio( 3459 c urstream->codec, audioSamples,3446 ctx, audioSamples, 3460 3447 &data_size, ptr, len); 3461 3448 already_decoded = true; 3462 3449 3463 reselectAudioTrack |= curstream->codec->channels; 3450 reselectAudioTrack |= ctx->channels; 3451 } 3452 3453 if (ctx->codec_id == CODEC_ID_AC3) 3454 { 3455 GetBitContext gbc; 3456 init_get_bits(&gbc, ptr, len * 8); 3457 if (!ff_ac3_parse_header(&gbc, &hdr)) 3458 { 3459 if (hdr.channels != last_ac3_channels) 3460 { 3461 last_ac3_channels = ctx->channels = hdr.channels; 3462 SetupAudioStream(); 3463 } 3464 } 3464 3465 } 3465 3466 3466 3467 if (reselectAudioTrack) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3476 3477 .av_stream_index; 3477 3478 audSubIdx = selectedTrack[kTrackTypeAudio] 3478 3479 .av_substream_index; 3480 ctx = curstream->codec; 3479 3481 } 3480 3482 3481 3483 if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3507 3509 if (audioOut.do_passthru) 3508 3510 { 3509 3511 data_size = pkt->size; 3510 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3512 bool dts = CODEC_ID_DTS == ctx->codec_id; 3511 3513 ret = encode_frame(dts, ptr, len, 3512 3514 audioSamples, data_size); 3513 3515 } 3514 3516 else 3515 3517 { 3516 AVCodecContext *ctx = curstream->codec;3517 3518 3518 if ((ctx->channels == 0) || 3519 3519 (ctx->channels > audioOut.channels)) 3520 3520 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3523 3523 3524 3524 if (!already_decoded) 3525 3525 { 3526 curstream->codec->request_channels = 3527 audioOut.channels; 3526 ctx->request_channels = audioOut.channels; 3528 3527 ret = avcodec_decode_audio( 3529 3528 ctx, audioSamples, &data_size, ptr, len); 3530 3529 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3541 3540 audIdx = -1; 3542 3541 AutoSelectAudioTrack(); 3543 3542 data_size = 0; 3543 ctx = curstream->codec; 3544 3544 } 3545 3545 } 3546 3546 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3558 3558 3559 3559 // calc for next frame 3560 3560 lastapts += (long long)((double)(data_size * 1000) / 3561 (curstream->codec->channels * 2) / 3562 curstream->codec->sample_rate); 3561 (ctx->channels * 2) / ctx->sample_rate); 3563 3562 3564 3563 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3565 3564 LOC + QString("audio timecode %1 %2 %3 %4") … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3627 3626 continue; 3628 3627 } 3629 3628 3630 AVCodecContext *context = curstream->codec;3631 3629 AVFrame mpa_pic; 3632 3630 bzero(&mpa_pic, sizeof(AVFrame)); 3633 3631 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3642 3640 // HACK 3643 3641 while (!gotpicture && count < 5) 3644 3642 { 3645 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3643 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3646 3644 &gotpicture, ptr, len); 3647 3645 count++; 3648 3646 } 3649 3647 } 3650 3648 else 3651 3649 { 3652 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3650 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3653 3651 &gotpicture, ptr, len); 3654 3652 } 3655 3653 } 3656 3654 else 3657 3655 { 3658 ret = avcodec_decode_video(c ontext, &mpa_pic,3656 ret = avcodec_decode_video(ctx, &mpa_pic, 3659 3657 &gotpicture, ptr, len); 3660 3658 // Reparse it to not drop the DVD still frame 3661 3659 if (decodeStillFrame) 3662 ret = avcodec_decode_video(c ontext, &mpa_pic,3660 ret = avcodec_decode_video(ctx, &mpa_pic, 3663 3661 &gotpicture, ptr, len); 3664 3662 } 3665 3663 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3726 3724 3727 3725 img_convert(&tmppicture, PIX_FMT_YUV420P, 3728 3726 (AVPicture *)&mpa_pic, 3729 c ontext->pix_fmt,3730 c ontext->width,3731 c ontext->height);3727 ctx->pix_fmt, 3728 ctx->width, 3729 ctx->height); 3732 3730 3733 3731 if (xf) 3734 3732 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3751 3749 (temppts + 10000 > lastvpts || temppts < 0)) 3752 3750 { 3753 3751 temppts = lastvpts; 3754 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3752 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3755 3753 // MPEG2 frames can be repeated, update pts accordingly 3756 3754 temppts += (long long)(mpa_pic.repeat_pict * 500 3757 * av_q2d(c urstream->codec->time_base));3755 * av_q2d(ctx->time_base)); 3758 3756 } 3759 3757 3760 3758 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3790 3788 picframe->frameNumber = framesPlayed; 3791 3789 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3792 3790 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3793 c ontext->release_buffer(context, &mpa_pic);3791 ctx->release_buffer(ctx, &mpa_pic); 3794 3792 3795 3793 decoded_video_frame = picframe; 3796 3794 gotvideo = 1; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3846 3844 } 3847 3845 default: 3848 3846 { 3849 AVCodecContext *enc = curstream->codec;3850 3847 VERBOSE(VB_IMPORTANT, LOC_ERR + 3851 3848 QString("Decoding - id(%1) type(%2)") 3852 .arg(codec_id_string( enc->codec_id))3853 .arg(codec_type_string( enc->codec_type)));3849 .arg(codec_id_string(ctx->codec_id)) 3850 .arg(codec_type_string(ctx->codec_type))); 3854 3851 have_err = true; 3855 3852 break; 3856 3853 } … … void AvFormatDecoder::SetDisablePassThrough(bool disable) 3995 3992 } 3996 3993 } 3997 3994 3995 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 3996 { 3997 bool passthru = false; 3998 3999 if (ctx->codec_id == CODEC_ID_AC3) 4000 passthru = allow_ac3_passthru && 4001 ctx->channels >= (int)max_channels; 4002 else if (ctx->codec_id == CODEC_ID_DTS) 4003 passthru = allow_dts_passthru; 4004 4005 passthru &= !transcoding && !disable_passthru; 4006 // Don't know any cards that support spdif clocked at < 44100 4007 // Some US cable transmissions have 2ch 32k AC-3 streams 4008 passthru &= ctx->sample_rate >= 44100; 4009 4010 return passthru; 4011 } 4012 3998 4013 /** \fn AvFormatDecoder::SetupAudioStream(void) 3999 4014 * \brief Reinitializes audio if it needs to be reinitialized. 4000 4015 * … … bool AvFormatDecoder::SetupAudioStream(void) 4008 4023 AVStream *curstream = NULL; 4009 4024 AVCodecContext *codec_ctx = NULL; 4010 4025 AudioInfo old_in = audioIn; 4011 AudioInfo old_out = audioOut;4012 4026 bool using_passthru = false; 4013 4027 4014 4028 if ((currentTrack[kTrackTypeAudio] >= 0) && … … bool AvFormatDecoder::SetupAudioStream(void) 4022 4036 codec_ctx = curstream->codec; 4023 4037 if (codec_ctx) 4024 4038 { 4025 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4026 (codec_ctx->codec_id == CODEC_ID_AC3)); 4027 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4028 (codec_ctx->codec_id == CODEC_ID_DTS)); 4029 using_passthru = do_ac3_passthru || do_dts_passthru; 4030 info = AudioInfo(codec_ctx->codec_id, 4031 codec_ctx->sample_rate, codec_ctx->channels, 4032 using_passthru && !disable_passthru); 4039 using_passthru = DoPassThrough(codec_ctx); 4040 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4041 codec_ctx->channels, using_passthru); 4033 4042 } 4034 4043 } 4035 4044 … … bool AvFormatDecoder::SetupAudioStream(void) 4046 4055 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4047 4056 4048 4057 audioOut = audioIn = info; 4049 AudioInfo tmpAudioOut = audioOut;4050 4058 4051 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4052 if (using_passthru && !disable_passthru) 4059 if (!using_passthru && audioOut.channels > (int)max_channels) 4053 4060 { 4054 tmpAudioOut.channels = 2; 4055 tmpAudioOut.sample_rate = 48000; 4056 tmpAudioOut.sample_size = 4; 4057 } 4058 4059 if (audioOut.channels > (int) max_channels) 4060 { 4061 audioOut.channels = (int) max_channels; 4061 audioOut.channels = (int)max_channels; 4062 4062 audioOut.sample_size = audioOut.channels * 2; 4063 codec_ctx->channels 4063 codec_ctx->channels = audioOut.channels; 4064 4064 } 4065 4065 4066 if (!using_passthru)4067 tmpAudioOut = audioOut;4068 4069 4066 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4070 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4071 .arg((using_passthru) ? "digital passthrough " : "") 4072 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4073 .arg(old_in.toString()).arg(old_out.toString()) 4074 .arg(audioIn.toString()).arg(audioOut.toString())); 4067 QString("\n\t\t\tfrom %1 to %2") 4068 .arg(old_in.toString()).arg(audioOut.toString())); 4075 4069 4076 if ( tmpAudioOut.sample_rate > 0)4077 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4070 if (audioOut.sample_rate > 0) 4071 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4078 4072 4079 GetNVP()->SetAudioParams( tmpAudioOut.bps(), tmpAudioOut.channels,4080 tmpAudioOut.sample_rate, audioIn.do_passthru);4073 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4074 audioOut.sample_rate, audioOut.do_passthru); 4081 4075 4082 // allow the audio stuff to reencode4083 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4084 4076 GetNVP()->ReinitAudio(); 4085 4077 4086 4078 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; }