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
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
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
00393
00394
00395
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
00461
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 }