Ticket #5900: audioencoding-trunk-6-r20101.patch
File audioencoding-trunk-6-r20101.patch, 86.0 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 488512f..6dc3863 100644
a b void setupKeys(void) 368 368 REG_KEY("Music", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 369 369 REG_KEY("Music", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 370 370 REG_KEY("Music", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 371 REG_KEY("Music", "TOGGLEUPMIX","Toggle upmixer", "Ctrl+U"); 371 372 REG_KEY("Music", "CYCLEVIS", "Cycle visualizer mode", "6"); 372 373 REG_KEY("Music", "BLANKSCR", "Blank screen", "5"); 373 374 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 99d51d1..2a521ab 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() 1196 1198 } 1197 1199 } 1198 1200 1201 void PlaybackBoxMusic::toggleUpmix() 1202 { 1203 if (gPlayer->getOutput()) 1204 gPlayer->getOutput()->ToggleUpmix(); 1205 } 1206 1207 1199 1208 void PlaybackBoxMusic::showProgressBar() 1200 1209 { 1201 1210 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 5bd6445..1a66dfe 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 1f636e2..9a264a7 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 2e5168a..12b9250 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 550ece8..04145eb 100644
a b NuppelVideoPlayer::NuppelVideoPlayer() 216 216 audio_passthru_device(QString::null), 217 217 audio_channels(2), audio_bits(-1), 218 218 audio_samplerate(44100), audio_stretchfactor(1.0f), 219 audio_codec(NULL),220 219 // Picture-in-Picture stuff 221 220 pip_active(false), pip_visible(true), 222 221 // Preview window support … … QString NuppelVideoPlayer::ReinitAudio(void) 906 905 if (audioOutput) 907 906 { 908 907 const AudioSettings settings( 909 audio_bits, audio_channels, audio_samplerate, 910 audio_passthru, audio_codec); 908 audio_bits, audio_channels, audio_samplerate, audio_passthru); 911 909 audioOutput->Reconfigure(settings); 910 if (audio_passthru) 911 audio_channels = 2; 912 912 errMsg = audioOutput->GetError(); 913 913 if (!errMsg.isEmpty()) 914 914 audioOutput->SetStretchFactor(audio_stretchfactor); … … void NuppelVideoPlayer::SetAudioParams(int bps, int channels, 3853 3853 audio_passthru = passthru; 3854 3854 } 3855 3855 3856 void NuppelVideoPlayer::SetAudioCodec(void *ac)3857 {3858 audio_codec = ac;3859 }3860 3861 3856 void NuppelVideoPlayer::SetEffDsp(int dsprate) 3862 3857 { 3863 3858 if (audioOutput) … … void NuppelVideoPlayer::ToggleAdjustFill(AdjustFillMode adjustfillMode) 5280 5275 } 5281 5276 } 5282 5277 5278 bool NuppelVideoPlayer::ToggleUpmix() 5279 { 5280 if (audioOutput) 5281 return audioOutput->ToggleUpmix(); 5282 return false; 5283 } 5284 5283 5285 void NuppelVideoPlayer::Zoom(ZoomDirection direction) 5284 5286 { 5285 5287 if (videoOutput) -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
diff --git a/mythtv/libs/libmythtv/NuppelVideoPlayer.h b/mythtv/libs/libmythtv/NuppelVideoPlayer.h index 2b0775c..7bc17da 100644
a b class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 181 181 // Toggle Sets 182 182 void ToggleAspectOverride(AspectOverrideMode aspectMode = kAspect_Toggle); 183 183 void ToggleAdjustFill(AdjustFillMode adjustfillMode = kAdjustFill_Toggle); 184 bool ToggleUpmix(void); 184 185 185 186 // Gets 186 187 QSize GetVideoBufferSize(void) const { return video_dim; } … … class MPUBLIC NuppelVideoPlayer : public CC608Reader, public CC708Reader 707 708 int audio_bits; 708 709 int audio_samplerate; 709 710 float audio_stretchfactor; 710 void *audio_codec;711 711 bool audio_passthru; 712 712 713 713 // Picture-in-Picture -
mythtv/libs/libmythtv/avformatdecoder.cpp
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp index b1015fd..50c2919 100644
a b AvFormatDecoder::AvFormatDecoder(NuppelVideoPlayer *parent, 428 428 audioSamples(NULL), 429 429 allow_ac3_passthru(false), allow_dts_passthru(false), 430 430 disable_passthru(false), max_channels(2), 431 dummy_frame(NULL),431 last_ac3_channels(0), dummy_frame(NULL), 432 432 // DVD 433 433 lastdvdtitle(-1), 434 434 decodeStillFrame(false), … … int AvFormatDecoder::AutoSelectAudioTrack(void) 2973 2973 { 2974 2974 int idx = atracks[i].av_stream_index; 2975 2975 AVCodecContext *codec_ctx = ic->streams[idx]->codec; 2976 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding &&2977 !disable_passthru &&2978 (codec_ctx->codec_id == CODEC_ID_AC3));2979 bool do_dts_passthru = (allow_dts_passthru && !transcoding &&2980 !disable_passthru &&2981 (codec_ctx->codec_id == CODEC_ID_DTS));2982 2976 AudioInfo item(codec_ctx->codec_id, 2983 2977 codec_ctx->sample_rate, codec_ctx->channels, 2984 do_ac3_passthru || do_dts_passthru);2978 DoPassThrough(codec_ctx)); 2985 2979 VERBOSE(VB_AUDIO, LOC + " * " + item.toString()); 2986 2980 } 2987 2981 #endif … … static void extract_mono_channel(uint channel, AudioInfo *audioInfo, 3115 3109 bool AvFormatDecoder::GetFrame(int onlyvideo) 3116 3110 { 3117 3111 AVPacket *pkt = NULL; 3112 AC3HeaderInfo hdr; 3118 3113 int len; 3119 3114 unsigned char *ptr; 3120 3115 int data_size = 0; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3311 3306 pts = 0; 3312 3307 3313 3308 AVStream *curstream = ic->streams[pkt->stream_index]; 3309 AVCodecContext *ctx = curstream->codec; 3314 3310 3315 3311 if (pkt->dts != (int64_t)AV_NOPTS_VALUE) 3316 3312 pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); 3317 3313 3318 if (ringBuffer->isDVD() && 3319 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3314 if (ringBuffer->isDVD() && 3315 ctx->codec_type == CODEC_TYPE_VIDEO) 3320 3316 { 3321 3317 MpegPreProcessPkt(curstream, pkt); 3322 3318 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3338 3334 3339 3335 if (!d->HasMPEG2Dec()) 3340 3336 { 3341 int current_width = c urstream->codec->width;3337 int current_width = ctx->width; 3342 3338 int video_width = GetNVP()->GetVideoSize().width(); 3343 3339 if (dvd_xvmc_enabled && GetNVP() && GetNVP()->getVideoOutput()) 3344 3340 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3379 3375 } 3380 3376 3381 3377 if (storevideoframes && 3382 c urstream->codec->codec_type == CODEC_TYPE_VIDEO)3378 ctx->codec_type == CODEC_TYPE_VIDEO) 3383 3379 { 3384 3380 av_dup_packet(pkt); 3385 3381 storedPackets.append(pkt); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3387 3383 continue; 3388 3384 } 3389 3385 3390 if (len > 0 && c urstream->codec->codec_type == CODEC_TYPE_VIDEO &&3386 if (len > 0 && ctx->codec_type == CODEC_TYPE_VIDEO && 3391 3387 pkt->stream_index == selectedVideoIndex) 3392 3388 { 3393 AVCodecContext *context = curstream->codec;3394 3389 3395 if (c ontext->codec_id == CODEC_ID_MPEG1VIDEO ||3396 c ontext->codec_id == CODEC_ID_MPEG2VIDEO ||3397 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC ||3398 c ontext->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD ||3399 c ontext->codec_id == CODEC_ID_MPEGVIDEO_VDPAU)3390 if (ctx->codec_id == CODEC_ID_MPEG1VIDEO || 3391 ctx->codec_id == CODEC_ID_MPEG2VIDEO || 3392 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC || 3393 ctx->codec_id == CODEC_ID_MPEG2VIDEO_XVMC_VLD || 3394 ctx->codec_id == CODEC_ID_MPEGVIDEO_VDPAU) 3400 3395 { 3401 3396 if (!ringBuffer->isDVD()) 3402 3397 MpegPreProcessPkt(curstream, pkt); 3403 3398 } 3404 else if (c ontext->codec_id == CODEC_ID_H264 ||3405 c ontext->codec_id == CODEC_ID_H264_VDPAU)3399 else if (ctx->codec_id == CODEC_ID_H264 || 3400 ctx->codec_id == CODEC_ID_H264_VDPAU) 3406 3401 { 3407 3402 H264PreProcessPkt(curstream, pkt); 3408 3403 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3447 3442 } 3448 3443 3449 3444 if (len > 0 && 3450 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3451 c urstream->codec->codec_id == CODEC_ID_MPEG2VBI)3445 ctx->codec_type == CODEC_TYPE_DATA && 3446 ctx->codec_id == CODEC_ID_MPEG2VBI) 3452 3447 { 3453 3448 ProcessVBIDataPacket(curstream, pkt); 3454 3449 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3457 3452 } 3458 3453 3459 3454 if (len > 0 && 3460 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3461 c urstream->codec->codec_id == CODEC_ID_DVB_VBI)3455 ctx->codec_type == CODEC_TYPE_DATA && 3456 ctx->codec_id == CODEC_ID_DVB_VBI) 3462 3457 { 3463 3458 ProcessDVBDataPacket(curstream, pkt); 3464 3459 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3468 3463 3469 3464 #ifdef USING_MHEG 3470 3465 if (len > 0 && 3471 c urstream->codec->codec_type == CODEC_TYPE_DATA &&3472 c urstream->codec->codec_id == CODEC_ID_DSMCC_B)3466 ctx->codec_type == CODEC_TYPE_DATA && 3467 ctx->codec_id == CODEC_ID_DSMCC_B) 3473 3468 { 3474 3469 ProcessDSMCCPacket(curstream, pkt); 3475 3470 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3490 3485 #endif // USING_MHEG 3491 3486 3492 3487 // we don't care about other data streams 3493 if (c urstream->codec->codec_type == CODEC_TYPE_DATA)3488 if (ctx->codec_type == CODEC_TYPE_DATA) 3494 3489 { 3495 3490 av_free_packet(pkt); 3496 3491 continue; 3497 3492 } 3498 3493 3499 if (!c urstream->codec->codec)3494 if (!ctx->codec) 3500 3495 { 3501 3496 VERBOSE(VB_PLAYBACK, LOC + 3502 3497 QString("No codec for stream index %1, type(%2) id(%3:%4)") 3503 3498 .arg(pkt->stream_index) 3504 .arg(codec_type_string(c urstream->codec->codec_type))3505 .arg(codec_id_string(c urstream->codec->codec_id))3506 .arg(c urstream->codec->codec_id));3499 .arg(codec_type_string(ctx->codec_type)) 3500 .arg(codec_id_string(ctx->codec_id)) 3501 .arg(ctx->codec_id)); 3507 3502 av_free_packet(pkt); 3508 3503 continue; 3509 3504 } … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3512 3507 have_err = false; 3513 3508 3514 3509 avcodeclock.lock(); 3515 int ctype = c urstream->codec->codec_type;3510 int ctype = ctx->codec_type; 3516 3511 int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; 3517 3512 int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; 3518 3513 int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3537 3532 3538 3533 // detect switches between stereo and dual languages 3539 3534 bool wasDual = audSubIdx != -1; 3540 bool isDual = c urstream->codec->avcodec_dual_language;3535 bool isDual = ctx->avcodec_dual_language; 3541 3536 if ((wasDual && !isDual) || (!wasDual && isDual)) 3542 3537 { 3543 3538 SetupAudioStreamSubIndexes(audIdx); 3544 3539 reselectAudioTrack = true; 3545 3540 } 3546 3541 3547 bool do_ac3_passthru =3548 (allow_ac3_passthru && !transcoding &&3549 (curstream->codec->codec_id == CODEC_ID_AC3));3550 bool do_dts_passthru =3551 (allow_dts_passthru && !transcoding &&3552 (curstream->codec->codec_id == CODEC_ID_DTS));3553 bool using_passthru = do_ac3_passthru || do_dts_passthru;3554 3555 3542 // detect channels on streams that need 3556 3543 // to be decoded before we can know this 3557 3544 bool already_decoded = false; 3558 if (!c urstream->codec->channels)3545 if (!ctx->channels) 3559 3546 { 3560 3547 QMutexLocker locker(&avcodeclock); 3561 3548 VERBOSE(VB_IMPORTANT, LOC + 3562 3549 QString("Setting channels to %1") 3563 3550 .arg(audioOut.channels)); 3564 3551 3565 if ( using_passthru)3552 if (DoPassThrough(ctx)) 3566 3553 { 3567 3554 // for passthru let it select the max number 3568 3555 // of channels 3569 c urstream->codec->channels = 0;3570 c urstream->codec->request_channels = 0;3556 ctx->channels = 0; 3557 ctx->request_channels = 0; 3571 3558 } 3572 3559 else 3573 3560 { 3574 c urstream->codec->channels = audioOut.channels;3575 c urstream->codec->request_channels =3561 ctx->channels = audioOut.channels; 3562 ctx->request_channels = 3576 3563 audioOut.channels; 3577 3564 } 3565 3578 3566 data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 3579 ret = avcodec_decode_audio2(curstream->codec, 3580 audioSamples, &data_size, 3581 ptr, len); 3567 ret = avcodec_decode_audio2(ctx, audioSamples, 3568 &data_size, ptr, len); 3582 3569 already_decoded = true; 3583 3570 3584 reselectAudioTrack |= curstream->codec->channels; 3571 reselectAudioTrack |= ctx->channels; 3572 } 3573 3574 if (ctx->codec_id == CODEC_ID_AC3) 3575 { 3576 GetBitContext gbc; 3577 init_get_bits(&gbc, ptr, len * 8); 3578 if (!ff_ac3_parse_header(&gbc, &hdr)) 3579 { 3580 if (hdr.channels != last_ac3_channels) 3581 { 3582 last_ac3_channels = ctx->channels = hdr.channels; 3583 SetupAudioStream(); 3584 } 3585 } 3585 3586 } 3586 3587 3587 3588 if (reselectAudioTrack) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3597 3598 .av_stream_index; 3598 3599 audSubIdx = selectedTrack[kTrackTypeAudio] 3599 3600 .av_substream_index; 3601 ctx = curstream->codec; 3600 3602 } 3601 3603 3602 3604 if ((onlyvideo > 0) || (pkt->stream_index != audIdx)) … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3628 3630 if (audioOut.do_passthru) 3629 3631 { 3630 3632 data_size = pkt->size; 3631 bool dts = CODEC_ID_DTS == c urstream->codec->codec_id;3633 bool dts = CODEC_ID_DTS == ctx->codec_id; 3632 3634 ret = encode_frame(dts, ptr, len, 3633 3635 audioSamples, data_size); 3634 3636 } 3635 3637 else 3636 3638 { 3637 AVCodecContext *ctx = curstream->codec;3638 3639 3639 if ((ctx->channels == 0) || 3640 3640 (ctx->channels > audioOut.channels)) 3641 3641 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3644 3644 3645 3645 if (!already_decoded) 3646 3646 { 3647 curstream->codec->request_channels =3648 audioOut.channels;3649 3647 data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 3650 ret = avcodec_decode_audio2(ctx, audioSamples, 3648 ctx->request_channels = audioOut.channels; 3649 ret = avcodec_decode_audio2(ctx, audioSamples, 3651 3650 &data_size, ptr, len); 3652 3651 } 3653 3652 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3663 3662 audIdx = -1; 3664 3663 AutoSelectAudioTrack(); 3665 3664 data_size = 0; 3665 ctx = curstream->codec; 3666 3666 } 3667 3667 } 3668 3668 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3680 3680 3681 3681 // calc for next frame 3682 3682 lastapts += (long long)((double)(data_size * 1000) / 3683 (curstream->codec->channels * 2) / 3684 curstream->codec->sample_rate); 3683 (ctx->channels * 2) / ctx->sample_rate); 3685 3684 3686 3685 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, 3687 3686 LOC + QString("audio timecode %1 %2 %3 %4") … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3749 3748 continue; 3750 3749 } 3751 3750 3752 AVCodecContext *context = curstream->codec;3753 3751 AVFrame mpa_pic; 3754 3752 bzero(&mpa_pic, sizeof(AVFrame)); 3755 3753 … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3764 3762 // HACK 3765 3763 while (!gotpicture && count < 5) 3766 3764 { 3767 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3765 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3768 3766 &gotpicture, ptr, len); 3769 3767 count++; 3770 3768 } 3771 3769 } 3772 3770 else 3773 3771 { 3774 ret = d->DecodeMPEG2Video(c ontext, &mpa_pic,3772 ret = d->DecodeMPEG2Video(ctx, &mpa_pic, 3775 3773 &gotpicture, ptr, len); 3776 3774 } 3777 3775 } 3778 3776 else 3779 3777 { 3780 ret = avcodec_decode_video(c ontext, &mpa_pic,3778 ret = avcodec_decode_video(ctx, &mpa_pic, 3781 3779 &gotpicture, ptr, len); 3782 3780 // Reparse it to not drop the DVD still frame 3783 3781 if (decodeStillFrame) 3784 ret = avcodec_decode_video(c ontext, &mpa_pic,3782 ret = avcodec_decode_video(ctx, &mpa_pic, 3785 3783 &gotpicture, ptr, len); 3786 3784 } 3787 3785 avcodeclock.unlock(); … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3853 3851 #endif 3854 3852 &tmppicture, PIX_FMT_YUV420P, 3855 3853 (AVPicture *)&mpa_pic, 3856 c ontext->pix_fmt,3857 c ontext->width,3858 c ontext->height);3854 ctx->pix_fmt, 3855 ctx->width, 3856 ctx->height); 3859 3857 3860 3858 if (xf) 3861 3859 { … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3878 3876 (temppts + 10000 > lastvpts || temppts < 0)) 3879 3877 { 3880 3878 temppts = lastvpts; 3881 temppts += (long long)(1000 * av_q2d(c ontext->time_base));3879 temppts += (long long)(1000 * av_q2d(ctx->time_base)); 3882 3880 // MPEG2 frames can be repeated, update pts accordingly 3883 3881 temppts += (long long)(mpa_pic.repeat_pict * 500 3884 * av_q2d(c urstream->codec->time_base));3882 * av_q2d(ctx->time_base)); 3885 3883 } 3886 3884 3887 3885 VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3917 3915 picframe->frameNumber = framesPlayed; 3918 3916 GetNVP()->ReleaseNextVideoFrame(picframe, temppts); 3919 3917 if (d->HasMPEG2Dec() && mpa_pic.data[3]) 3920 c ontext->release_buffer(context, &mpa_pic);3918 ctx->release_buffer(ctx, &mpa_pic); 3921 3919 3922 3920 decoded_video_frame = picframe; 3923 3921 gotvideo = 1; … … bool AvFormatDecoder::GetFrame(int onlyvideo) 3973 3971 } 3974 3972 default: 3975 3973 { 3976 AVCodecContext *enc = curstream->codec;3977 3974 VERBOSE(VB_IMPORTANT, LOC_ERR + 3978 3975 QString("Decoding - id(%1) type(%2)") 3979 .arg(codec_id_string( enc->codec_id))3980 .arg(codec_type_string( enc->codec_type)));3976 .arg(codec_id_string(ctx->codec_id)) 3977 .arg(codec_type_string(ctx->codec_type))); 3981 3978 have_err = true; 3982 3979 break; 3983 3980 } … … void AvFormatDecoder::SetDisablePassThrough(bool disable) 4126 4123 } 4127 4124 } 4128 4125 4126 bool AvFormatDecoder::DoPassThrough(const AVCodecContext *ctx) 4127 { 4128 bool passthru = false; 4129 4130 if (ctx->codec_id == CODEC_ID_AC3) 4131 passthru = allow_ac3_passthru && 4132 ctx->channels >= (int)max_channels; 4133 else if (ctx->codec_id == CODEC_ID_DTS) 4134 passthru = allow_dts_passthru; 4135 4136 passthru &= !transcoding && !disable_passthru; 4137 // Don't know any cards that support spdif clocked at < 44100 4138 // Some US cable transmissions have 2ch 32k AC-3 streams 4139 passthru &= ctx->sample_rate >= 44100; 4140 4141 return passthru; 4142 } 4143 4129 4144 /** \fn AvFormatDecoder::SetupAudioStream(void) 4130 4145 * \brief Reinitializes audio if it needs to be reinitialized. 4131 4146 * … … bool AvFormatDecoder::SetupAudioStream(void) 4139 4154 AVStream *curstream = NULL; 4140 4155 AVCodecContext *codec_ctx = NULL; 4141 4156 AudioInfo old_in = audioIn; 4142 AudioInfo old_out = audioOut;4143 4157 bool using_passthru = false; 4144 4158 4145 4159 if ((currentTrack[kTrackTypeAudio] >= 0) && … … bool AvFormatDecoder::SetupAudioStream(void) 4153 4167 codec_ctx = curstream->codec; 4154 4168 if (codec_ctx) 4155 4169 { 4156 bool do_ac3_passthru = (allow_ac3_passthru && !transcoding && 4157 (codec_ctx->codec_id == CODEC_ID_AC3)); 4158 bool do_dts_passthru = (allow_dts_passthru && !transcoding && 4159 (codec_ctx->codec_id == CODEC_ID_DTS)); 4160 using_passthru = do_ac3_passthru || do_dts_passthru; 4161 info = AudioInfo(codec_ctx->codec_id, 4162 codec_ctx->sample_rate, codec_ctx->channels, 4163 using_passthru && !disable_passthru); 4170 using_passthru = DoPassThrough(codec_ctx); 4171 info = AudioInfo(codec_ctx->codec_id, codec_ctx->sample_rate, 4172 codec_ctx->channels, using_passthru); 4164 4173 } 4165 4174 } 4166 4175 … … bool AvFormatDecoder::SetupAudioStream(void) 4177 4186 QString("audio track #%1").arg(currentTrack[kTrackTypeAudio]+1)); 4178 4187 4179 4188 audioOut = audioIn = info; 4180 AudioInfo tmpAudioOut = audioOut;4181 4189 4182 // A passthru stream looks like a 48KHz 2ch (@ 16bit) to the sound card 4183 if (using_passthru && !disable_passthru) 4190 if (!using_passthru && audioOut.channels > (int)max_channels) 4184 4191 { 4185 tmpAudioOut.channels = 2; 4186 tmpAudioOut.sample_rate = 48000; 4187 tmpAudioOut.sample_size = 4; 4188 } 4189 4190 if (audioOut.channels > (int) max_channels) 4191 { 4192 audioOut.channels = (int) max_channels; 4192 audioOut.channels = (int)max_channels; 4193 4193 audioOut.sample_size = audioOut.channels * 2; 4194 codec_ctx->channels 4194 codec_ctx->channels = audioOut.channels; 4195 4195 } 4196 4196 4197 if (!using_passthru)4198 tmpAudioOut = audioOut;4199 4200 4197 VERBOSE(VB_AUDIO, LOC + "Audio format changed " + 4201 QString("%1%2\n\t\t\tfrom %3 ; %4\n\t\t\tto %5 ; %6") 4202 .arg((using_passthru) ? "digital passthrough " : "") 4203 .arg((using_passthru) ? tmpAudioOut.toString() : QString("")) 4204 .arg(old_in.toString()).arg(old_out.toString()) 4205 .arg(audioIn.toString()).arg(audioOut.toString())); 4198 QString("\n\t\t\tfrom %1 to %2") 4199 .arg(old_in.toString()).arg(audioOut.toString())); 4206 4200 4207 if ( tmpAudioOut.sample_rate > 0)4208 GetNVP()->SetEffDsp( tmpAudioOut.sample_rate * 100);4201 if (audioOut.sample_rate > 0) 4202 GetNVP()->SetEffDsp(audioOut.sample_rate * 100); 4209 4203 4210 GetNVP()->SetAudioParams( tmpAudioOut.bps(), tmpAudioOut.channels,4211 tmpAudioOut.sample_rate, audioIn.do_passthru);4204 GetNVP()->SetAudioParams(audioOut.bps(), audioOut.channels, 4205 audioOut.sample_rate, audioOut.do_passthru); 4212 4206 4213 // allow the audio stuff to reencode4214 GetNVP()->SetAudioCodec((using_passthru) ? codec_ctx : NULL);4215 4207 GetNVP()->ReinitAudio(); 4216 4208 4217 4209 return true; -
mythtv/libs/libmythtv/avformatdecoder.h
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h index cb90631..57311b6 100644
a b class AvFormatDecoder : public DecoderBase 199 199 200 200 void SeekReset(long long, uint skipFrames, bool doFlush, bool discardFrames); 201 201 202 bool DoPassThrough(const AVCodecContext *ctx); 202 203 bool SetupAudioStream(void); 203 204 void SetupAudioStreamSubIndexes(int streamIndex); 204 205 void RemoveAudioStreams(); … … class AvFormatDecoder : public DecoderBase 270 271 bool allow_dts_passthru; 271 272 bool disable_passthru; 272 273 uint max_channels; 274 uint last_ac3_channels; 273 275 274 276 VideoFrame *dummy_frame; 275 277 -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index c3b79e8..1c1f8b5 100644
a b void TV::InitKeys(void) 475 475 REG_KEY("TV Playback", "VOLUMEDOWN", "Volume down", "[,{,F10,Volume Down"); 476 476 REG_KEY("TV Playback", "VOLUMEUP", "Volume up", "],},F11,Volume Up"); 477 477 REG_KEY("TV Playback", "MUTE", "Mute", "|,\\,F9,Volume Mute"); 478 REG_KEY("TV Playback", "TOGGLEUPMIX", "Toggle upmixer", "Ctrl+U"); 478 479 REG_KEY("TV Playback", "TOGGLEPIPMODE", "Toggle Picture-in-Picture view", 479 480 "V"); 480 481 REG_KEY("TV Playback", "TOGGLEPBPMODE", "Toggle Picture-by-Picture view", … … void TV::InitKeys(void) 614 615 Teletext F2,F3,F4,F5,F6,F7,F8 615 616 ITV F2,F3,F4,F5,F6,F7,F12 616 617 617 Playback: Ctrl-B,Ctrl-G,Ctrl-Y 618 Playback: Ctrl-B,Ctrl-G,Ctrl-Y,Ctrl-U 618 619 */ 619 620 } 620 621 … … bool TV::ToggleHandleAction(PlayerContext *ctx, 4231 4232 DoTogglePictureAttribute(ctx, kAdjustingPicture_Playback); 4232 4233 else if (has_action("TOGGLESTRETCH", actions)) 4233 4234 ToggleTimeStretch(ctx); 4235 else if (has_action("TOGGLEUPMIX", actions)) 4236 ToggleUpmix(ctx); 4234 4237 else if (has_action("TOGGLESLEEP", actions)) 4235 4238 ToggleSleepTimer(ctx); 4236 4239 else if (has_action("TOGGLERECORD", actions) && islivetv) … … void TV::ChangeTimeStretch(PlayerContext *ctx, int dir, bool allowEdit) 7796 7799 SetSpeedChangeTimer(0, __LINE__); 7797 7800 } 7798 7801 7802 void TV::ToggleUpmix(PlayerContext *ctx) 7803 { 7804 if (!ctx->nvp || !ctx->nvp->HasAudioOut()) 7805 return; 7806 QString text; 7807 if (ctx->nvp->ToggleUpmix()) 7808 text = tr("Upmixer On"); 7809 else 7810 text = tr("Upmixer Off"); 7811 7812 if (ctx->nvp->GetOSD() && !browsemode) 7813 ctx->nvp->GetOSD()->SetSettingsText(text, 5); 7814 } 7815 7799 7816 // dir in 10ms jumps 7800 7817 void TV::ChangeAudioSync(PlayerContext *ctx, int dir, bool allowEdit) 7801 7818 { … … void TV::TreeMenuSelected(OSDListTreeType *tree, OSDGenericTree *item) 9346 9363 SetManualZoom(actx, true, tr("Zoom Mode ON")); 9347 9364 else if (action == "TOGGLESTRETCH") 9348 9365 ToggleTimeStretch(actx); 9366 else if (action == "TOGGLEUPMIX") 9367 ToggleUpmix(actx); 9349 9368 else if (action.left(13) == "ADJUSTSTRETCH") 9350 9369 { 9351 9370 bool floatRead; … … void TV::FillOSDTreeMenu( 9646 9665 9647 9666 if (category == "AUDIOSYNC") 9648 9667 new OSDGenericTree(treeMenu, tr("Adjust Audio Sync"), "TOGGLEAUDIOSYNC"); 9668 else if (category == "TOGGLEUPMIX") 9669 new OSDGenericTree(treeMenu, tr("Toggle Upmixer"), "TOGGLEUPMIX"); 9649 9670 else if (category == "TIMESTRETCH") 9650 9671 FillMenuTimeStretch(ctx, treeMenu); 9651 9672 else if (category == "VIDEOSCAN") -
mythtv/libs/libmythtv/tv_play.h
diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h index ec085e6..5a30200 100644
a b class MPUBLIC TV : public QThread 403 403 ARBSEEK_FORWARD, 404 404 ARBSEEK_END 405 405 }; 406 406 407 void DoArbSeek(PlayerContext*, ArbSeekWhence whence); 407 408 void NormalSpeed(PlayerContext*); 408 409 void ChangeSpeed(PlayerContext*, int direction); … … class MPUBLIC TV : public QThread 411 412 bool TimeStretchHandleAction(PlayerContext*, 412 413 const QStringList &actions); 413 414 415 void ToggleUpmix(PlayerContext*); 414 416 void ChangeAudioSync(PlayerContext*, int dir, bool allowEdit = true); 415 417 bool AudioSyncHandleAction(PlayerContext*, const QStringList &actions); 416 418 -
mythtv/libs/libmythtv/tvosdmenuentry.cpp
diff --git a/mythtv/libs/libmythtv/tvosdmenuentry.cpp b/mythtv/libs/libmythtv/tvosdmenuentry.cpp index 548386d..acb65ce 100644
a b void TVOSDMenuEntryList::InitDefaultEntries(void) 230 230 curMenuEntries.append( 231 231 new TVOSDMenuEntry("AUDIOSYNC", 1, 1, 1, 1 , "Audio Sync")); 232 232 curMenuEntries.append( 233 new TVOSDMenuEntry("TOGGLEUPMIX", 1, 1, 1, 1, "Toggle Upmixer")); 234 curMenuEntries.append( 233 235 new TVOSDMenuEntry("TIMESTRETCH", 1, 1, 1, 1, "Time Stretch")); 234 236 curMenuEntries.append( 235 237 new TVOSDMenuEntry("VIDEOSCAN", 1, 1, 1, 1, "Video Scan")); -
mythtv/programs/mythfrontend/globalsettings.cpp
diff --git a/mythtv/programs/mythfrontend/globalsettings.cpp b/mythtv/programs/mythfrontend/globalsettings.cpp index 12835dc..9b711b3 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 AudioSystemSettingsGroup : public VerticalConfigurationGroup 3432 3453 3433 3454 addChild(MaxAudioChannels()); 3434 3455 addChild(AudioUpmixType()); 3456 addChild(SRCQuality()); 3435 3457 3436 3458 // General boolean settings 3437 3459 addChild(AC3PassThrough()); -
mythtv/programs/mythtranscode/transcode.cpp
diff --git a/mythtv/programs/mythtranscode/transcode.cpp b/mythtv/programs/mythtranscode/transcode.cpp index d41a0e9..f3b7f04 100644
a b class AudioReencodeBuffer : public AudioOutput 222 222 // Do nothing 223 223 return kMuteOff; 224 224 } 225 virtual bool ToggleUpmix(void) 226 { 227 // Do nothing 228 return false; 229 } 225 230 226 231 // These are pure virtual in AudioOutput, but we don't need them here 227 232 virtual void bufferOutputData(bool){ return; }