|
MythTV
0.26-pre
|
00001 #include "mythplayer.h" 00002 #include "audiooutput.h" 00003 #include "audioplayer.h" 00004 00005 #define LOC QString("AudioPlayer: ") 00006 00007 AudioPlayer::AudioPlayer(MythPlayer *parent, bool muted) 00008 : m_parent(parent), m_audioOutput(NULL), m_channels(-1), 00009 m_orig_channels(-1), m_codec(0), m_format(FORMAT_NONE), 00010 m_samplerate(44100), m_codec_profile(0), 00011 m_stretchfactor(1.0f),m_passthru(false), 00012 m_lock(QMutex::Recursive), m_muted_on_creation(muted), 00013 m_main_device(QString::null), m_passthru_device(QString::null), 00014 m_no_audio_in(false), m_no_audio_out(false), m_controls_volume(true) 00015 { 00016 m_controls_volume = gCoreContext->GetNumSetting("MythControlsVolume", 1); 00017 } 00018 00019 AudioPlayer::~AudioPlayer() 00020 { 00021 DeleteOutput(); 00022 m_visuals.clear(); 00023 } 00024 00025 void AudioPlayer::addVisual(MythTV::Visual *vis) 00026 { 00027 if (!m_audioOutput) 00028 return; 00029 00030 QMutexLocker lock(&m_lock); 00031 Visuals::iterator it = std::find(m_visuals.begin(), m_visuals.end(), vis); 00032 if (it == m_visuals.end()) 00033 { 00034 m_visuals.push_back(vis); 00035 m_audioOutput->addVisual(vis); 00036 } 00037 } 00038 00039 void AudioPlayer::removeVisual(MythTV::Visual *vis) 00040 { 00041 if (!m_audioOutput) 00042 return; 00043 00044 QMutexLocker lock(&m_lock); 00045 Visuals::iterator it = std::find(m_visuals.begin(), m_visuals.end(), vis); 00046 if (it != m_visuals.end()) 00047 { 00048 m_visuals.erase(it); 00049 m_audioOutput->removeVisual(vis); 00050 } 00051 } 00052 00053 void AudioPlayer::AddVisuals(void) 00054 { 00055 if (!m_audioOutput) 00056 return; 00057 00058 QMutexLocker lock(&m_lock); 00059 for (uint i = 0; i < m_visuals.size(); i++) 00060 m_audioOutput->addVisual(m_visuals[i]); 00061 } 00062 00063 void AudioPlayer::RemoveVisuals(void) 00064 { 00065 if (!m_audioOutput) 00066 return; 00067 00068 QMutexLocker lock(&m_lock); 00069 for (uint i = 0; i < m_visuals.size(); i++) 00070 m_audioOutput->removeVisual(m_visuals[i]); 00071 } 00072 00073 void AudioPlayer::ResetVisuals(void) 00074 { 00075 if (!m_audioOutput) 00076 return; 00077 00078 QMutexLocker lock(&m_lock); 00079 for (uint i = 0; i < m_visuals.size(); i++) 00080 m_visuals[i]->prepare(); 00081 } 00082 00083 void AudioPlayer::Reset(void) 00084 { 00085 if (!m_audioOutput) 00086 return; 00087 00088 QMutexLocker lock(&m_lock); 00089 m_audioOutput->Reset(); 00090 } 00091 00092 void AudioPlayer::DeleteOutput(void) 00093 { 00094 RemoveVisuals(); 00095 QMutexLocker locker(&m_lock); 00096 if (m_audioOutput) 00097 { 00098 delete m_audioOutput; 00099 m_audioOutput = NULL; 00100 } 00101 m_no_audio_out = true; 00102 } 00103 00104 QString AudioPlayer::ReinitAudio(void) 00105 { 00106 bool want_audio = m_parent->IsAudioNeeded(); 00107 QString errMsg = QString::null; 00108 QMutexLocker lock(&m_lock); 00109 00110 bool firstinit = (m_format == FORMAT_NONE && 00111 m_channels < 0 && 00112 m_samplerate == 44100); 00113 00114 if ((m_format == FORMAT_NONE) || 00115 (m_channels <= 0) || 00116 (m_samplerate <= 0)) 00117 { 00118 m_no_audio_in = m_no_audio_out = true; 00119 } 00120 else 00121 m_no_audio_in = false; 00122 00123 if (want_audio && !m_audioOutput) 00124 { 00125 // AudioOutput has never been created and we will want audio 00126 AudioSettings aos = AudioSettings(m_main_device, 00127 m_passthru_device, 00128 m_format, m_channels, 00129 m_codec, m_samplerate, 00130 AUDIOOUTPUT_VIDEO, 00131 m_controls_volume, m_passthru); 00132 if (m_no_audio_in) 00133 aos.init = false; 00134 00135 m_audioOutput = AudioOutput::OpenAudio(aos); 00136 if (!m_audioOutput) 00137 { 00138 errMsg = QObject::tr("Unable to create AudioOutput."); 00139 } 00140 else 00141 { 00142 errMsg = m_audioOutput->GetError(); 00143 } 00144 AddVisuals(); 00145 } 00146 else if (!m_no_audio_in && m_audioOutput) 00147 { 00148 const AudioSettings settings(m_format, m_channels, m_codec, 00149 m_samplerate, m_passthru, 0, 00150 m_codec_profile); 00151 m_audioOutput->Reconfigure(settings); 00152 errMsg = m_audioOutput->GetError(); 00153 SetStretchFactor(m_stretchfactor); 00154 } 00155 00156 if (!errMsg.isEmpty()) 00157 { 00158 if (!firstinit) 00159 { 00160 LOG(VB_GENERAL, LOG_NOTICE, LOC + "Disabling Audio" + 00161 QString(", reason is: %1").arg(errMsg)); 00162 } 00163 m_no_audio_out = true; 00164 } 00165 else if (m_no_audio_out && m_audioOutput) 00166 { 00167 LOG(VB_GENERAL, LOG_NOTICE, LOC + "Enabling Audio"); 00168 m_no_audio_out = false; 00169 } 00170 00171 if (m_muted_on_creation) 00172 { 00173 SetMuteState(kMuteAll); 00174 m_muted_on_creation = false; 00175 } 00176 00177 ResetVisuals(); 00178 00179 return errMsg; 00180 } 00181 00182 void AudioPlayer::CheckFormat(void) 00183 { 00184 if (m_format == FORMAT_NONE) 00185 m_no_audio_in = m_no_audio_out = true; 00186 } 00187 00188 bool AudioPlayer::Pause(bool pause) 00189 { 00190 if (!m_audioOutput || m_no_audio_out) 00191 return false; 00192 00193 QMutexLocker lock(&m_lock); 00194 m_audioOutput->Pause(pause); 00195 return true; 00196 } 00197 00198 bool AudioPlayer::IsPaused(void) 00199 { 00200 if (!m_audioOutput || m_no_audio_out) 00201 return false; 00202 QMutexLocker lock(&m_lock); 00203 return m_audioOutput->IsPaused(); 00204 } 00205 00206 void AudioPlayer::PauseAudioUntilBuffered() 00207 { 00208 if (!m_audioOutput || m_no_audio_out) 00209 return; 00210 QMutexLocker lock(&m_lock); 00211 m_audioOutput->PauseUntilBuffered(); 00212 } 00213 00214 void AudioPlayer::SetAudioOutput(AudioOutput *ao) 00215 { 00216 // delete current audio class if any 00217 DeleteOutput(); 00218 m_lock.lock(); 00219 m_audioOutput = ao; 00220 AddVisuals(); 00221 m_lock.unlock(); 00222 } 00223 00224 uint AudioPlayer::GetVolume(void) 00225 { 00226 if (!m_audioOutput || m_no_audio_out) 00227 return 0; 00228 QMutexLocker lock(&m_lock); 00229 return m_audioOutput->GetCurrentVolume(); 00230 } 00231 00236 void AudioPlayer::SetAudioInfo(const QString &main_device, 00237 const QString &passthru_device, 00238 uint samplerate, 00239 int codec_profile) 00240 { 00241 m_main_device = m_passthru_device = QString::null; 00242 if (!main_device.isEmpty()) 00243 { 00244 m_main_device = main_device; 00245 m_main_device.detach(); 00246 } 00247 if (!passthru_device.isEmpty()) 00248 { 00249 m_passthru_device = passthru_device; 00250 m_passthru_device.detach(); 00251 } 00252 m_samplerate = (int)samplerate; 00253 m_codec_profile = codec_profile; 00254 } 00255 00260 void AudioPlayer::SetAudioParams(AudioFormat format, int orig_channels, 00261 int channels, int codec, 00262 int samplerate, bool passthru, 00263 int codec_profile) 00264 { 00265 m_format = format; 00266 m_orig_channels = orig_channels; 00267 m_channels = channels; 00268 m_codec = codec; 00269 m_samplerate = samplerate; 00270 m_passthru = passthru; 00271 m_codec_profile = codec_profile; 00272 00273 ResetVisuals(); 00274 } 00275 00276 void AudioPlayer::SetEffDsp(int dsprate) 00277 { 00278 if (!m_audioOutput || !m_no_audio_out) 00279 return; 00280 QMutexLocker lock(&m_lock); 00281 m_audioOutput->SetEffDsp(dsprate); 00282 } 00283 00284 bool AudioPlayer::SetMuted(bool mute) 00285 { 00286 bool is_muted = IsMuted(); 00287 QMutexLocker lock(&m_lock); 00288 00289 if (m_audioOutput && !m_no_audio_out && !is_muted && mute && 00290 (kMuteAll == SetMuteState(kMuteAll))) 00291 { 00292 LOG(VB_AUDIO, LOG_INFO, QString("muting sound %1").arg(IsMuted())); 00293 return true; 00294 } 00295 else if (m_audioOutput && !m_no_audio_out && is_muted && !mute && 00296 (kMuteOff == SetMuteState(kMuteOff))) 00297 { 00298 LOG(VB_AUDIO, LOG_INFO, QString("unmuting sound %1").arg(IsMuted())); 00299 return true; 00300 } 00301 00302 LOG(VB_AUDIO, LOG_ERR, 00303 QString("not changing sound mute state %1").arg(IsMuted())); 00304 00305 return false; 00306 } 00307 00308 MuteState AudioPlayer::SetMuteState(MuteState mstate) 00309 { 00310 if (!m_audioOutput || m_no_audio_out) 00311 return kMuteAll; 00312 QMutexLocker lock(&m_lock); 00313 return m_audioOutput->SetMuteState(mstate); 00314 } 00315 00316 MuteState AudioPlayer::IncrMuteState(void) 00317 { 00318 if (!m_audioOutput || m_no_audio_out) 00319 return kMuteAll; 00320 return SetMuteState(VolumeBase::NextMuteState(GetMuteState())); 00321 } 00322 00323 MuteState AudioPlayer::GetMuteState(void) 00324 { 00325 if (!m_audioOutput || m_no_audio_out) 00326 return kMuteAll; 00327 QMutexLocker lock(&m_lock); 00328 return m_audioOutput->GetMuteState(); 00329 } 00330 00331 uint AudioPlayer::AdjustVolume(int change) 00332 { 00333 if (!m_audioOutput || m_no_audio_out) 00334 return GetVolume(); 00335 QMutexLocker lock(&m_lock); 00336 m_audioOutput->AdjustCurrentVolume(change); 00337 return GetVolume(); 00338 } 00339 00340 uint AudioPlayer::SetVolume(int newvolume) 00341 { 00342 if (!m_audioOutput || m_no_audio_out) 00343 return GetVolume(); 00344 QMutexLocker lock(&m_lock); 00345 m_audioOutput->SetCurrentVolume(newvolume); 00346 return GetVolume(); 00347 } 00348 00349 int64_t AudioPlayer::GetAudioTime(void) 00350 { 00351 if (!m_audioOutput || m_no_audio_out) 00352 return 0LL; 00353 QMutexLocker lock(&m_lock); 00354 return m_audioOutput->GetAudiotime(); 00355 } 00356 00357 bool AudioPlayer::IsUpmixing(void) 00358 { 00359 if (!m_audioOutput) 00360 return false; 00361 QMutexLocker lock(&m_lock); 00362 return m_audioOutput->IsUpmixing(); 00363 } 00364 00365 bool AudioPlayer::EnableUpmix(bool enable, bool toggle) 00366 { 00367 if (!m_audioOutput) 00368 return false; 00369 QMutexLocker lock(&m_lock); 00370 if (toggle || (enable != IsUpmixing())) 00371 return m_audioOutput->ToggleUpmix(); 00372 return enable; 00373 } 00374 00375 bool AudioPlayer::CanUpmix(void) 00376 { 00377 if (!m_audioOutput) 00378 return false; 00379 QMutexLocker lock(&m_lock); 00380 return m_audioOutput->CanUpmix(); 00381 } 00382 00383 void AudioPlayer::SetStretchFactor(float factor) 00384 { 00385 m_stretchfactor = factor; 00386 if (!m_audioOutput) 00387 return; 00388 QMutexLocker lock(&m_lock); 00389 m_audioOutput->SetStretchFactor(m_stretchfactor); 00390 } 00391 00392 // The following methods are not locked as this hinders performance. 00393 // They are however only called from the Decoder and only the decode 00394 // thread will trigger a deletion/recreation of the AudioOutput device, hence 00395 // they should be safe. 00396 00397 inline bool TestDigitalFeature(AudioOutput *ao, DigitalFeature feature) 00398 { 00399 if (!ao) 00400 return false; 00401 00402 return ao->GetOutputSettingsUsers(true)->canFeature(feature); 00403 } 00404 00405 bool AudioPlayer::CanAC3(void) 00406 { 00407 return TestDigitalFeature(m_audioOutput, FEATURE_AC3); 00408 } 00409 00410 bool AudioPlayer::CanDTS(void) 00411 { 00412 return TestDigitalFeature(m_audioOutput, FEATURE_DTS); 00413 } 00414 00415 bool AudioPlayer::CanEAC3(void) 00416 { 00417 return TestDigitalFeature(m_audioOutput, FEATURE_EAC3); 00418 } 00419 00420 bool AudioPlayer::CanTrueHD(void) 00421 { 00422 return TestDigitalFeature(m_audioOutput, FEATURE_TRUEHD); 00423 } 00424 00425 bool AudioPlayer::CanDTSHD(void) 00426 { 00427 return TestDigitalFeature(m_audioOutput, FEATURE_DTSHD); 00428 } 00429 00430 uint AudioPlayer::GetMaxChannels(void) 00431 { 00432 if (!m_audioOutput) 00433 return 2; 00434 return m_audioOutput->GetOutputSettingsUsers(false)->BestSupportedChannels(); 00435 } 00436 00437 int AudioPlayer::GetMaxHDRate() 00438 { 00439 if (!m_audioOutput) 00440 return 0; 00441 return m_audioOutput->GetOutputSettingsUsers(true)->GetMaxHDRate(); 00442 } 00443 00444 bool AudioPlayer::CanPassthrough(int samplerate, int channels, 00445 int codec, int profile) 00446 { 00447 if (!m_audioOutput) 00448 return false; 00449 return m_audioOutput->CanPassthrough(samplerate, channels, codec, profile); 00450 } 00451 00452 bool AudioPlayer::CanDownmix(void) 00453 { 00454 if (!m_audioOutput) 00455 return false; 00456 return m_audioOutput->CanDownmix(); 00457 } 00458 00459 /* 00460 * if frames = -1 : let AudioOuput calculate value 00461 * if frames = 0 && len > 0: will calculate according to len 00462 */ 00463 void AudioPlayer::AddAudioData(char *buffer, int len, 00464 int64_t timecode, int frames) 00465 { 00466 if (!m_audioOutput || m_no_audio_out) 00467 return; 00468 00469 if (m_parent->PrepareAudioSample(timecode) && !m_no_audio_out) 00470 m_audioOutput->Drain(); 00471 int samplesize = m_audioOutput->GetBytesPerFrame(); 00472 00473 if (samplesize <= 0) 00474 return; 00475 00476 if (frames == 0 && len > 0) 00477 frames = len / samplesize; 00478 00479 if (!m_audioOutput->AddData(buffer, len, timecode, frames)) 00480 LOG(VB_PLAYBACK, LOG_ERR, LOC + "AddAudioData(): " 00481 "Audio buffer overflow, audio data lost!"); 00482 } 00483 00484 bool AudioPlayer::NeedDecodingBeforePassthrough(void) 00485 { 00486 if (!m_audioOutput) 00487 return true; 00488 else 00489 return m_audioOutput->NeedDecodingBeforePassthrough(); 00490 } 00491 00492 int64_t AudioPlayer::LengthLastData(void) 00493 { 00494 if (!m_audioOutput) 00495 return 0; 00496 else 00497 return m_audioOutput->LengthLastData(); 00498 } 00499 00500 bool AudioPlayer::GetBufferStatus(uint &fill, uint &total) 00501 { 00502 fill = total = 0; 00503 if (!m_audioOutput || m_no_audio_out) 00504 return false; 00505 m_audioOutput->GetBufferStatus(fill, total); 00506 return true; 00507 } 00508 00509 bool AudioPlayer::IsBufferAlmostFull(void) 00510 { 00511 uint ofill = 0, ototal = 0, othresh = 0; 00512 if (GetBufferStatus(ofill, ototal)) 00513 { 00514 othresh = ((ototal>>1) + (ototal>>2)); 00515 return ofill > othresh; 00516 } 00517 return false; 00518 }
1.7.6.1