MythTV  master
audiooutput.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <cstdlib>
3 
4 // Qt utils: to parse audio list
5 #include <QtGlobal>
6 #include <QFile>
7 #include <QDateTime>
8 #include <QDir>
9 
10 #include "libmythbase/compat.h"
13 
14 #include "audiooutput.h"
15 #include "audiooutputnull.h"
16 #ifdef _WIN32
17 #include "audiooutputdx.h"
18 #include "audiooutputwin.h"
19 #endif
20 #ifdef USING_OSS
21 #include "audiooutputoss.h"
22 #endif
23 #ifdef USING_ALSA
24 #include "audiooutputalsa.h"
25 #endif
26 #ifdef Q_OS_DARWIN
27 #include "audiooutputca.h"
28 #endif
29 #ifdef USING_JACK
30 #include "audiooutputjack.h"
31 #endif
32 #ifdef USING_PULSEOUTPUT
33 #include "audiooutputpulse.h"
34 #endif
35 #ifdef USING_PULSE
36 #include "audiopulsehandler.h"
37 #endif
38 #ifdef Q_OS_ANDROID
39 #include "audiooutputopensles.h"
40 #include "audiooutputaudiotrack.h"
41 #endif
42 
43 extern "C" {
44 #include "libavcodec/avcodec.h" // to get codec id
45 }
46 #include "audioconvert.h"
47 #include "mythaverror.h"
48 
49 #define LOC QString("AO: ")
50 
52 {
53 #ifdef USING_PULSE
55 #endif
56 }
57 
59  const QString &main_device, const QString &passthru_device,
60  AudioFormat format, int channels, AVCodecID codec, int samplerate,
61  AudioOutputSource source, bool set_initial_vol, bool passthru,
62  int upmixer_startup, AudioOutputSettings *custom)
63 {
64  AudioSettings settings(
65  main_device, passthru_device, format, channels, codec, samplerate,
66  source, set_initial_vol, passthru, upmixer_startup, custom);
67 
68  return OpenAudio(settings);
69 }
70 
72  const QString &main_device, const QString &passthru_device,
73  bool willsuspendpa)
74 {
75  AudioSettings settings(main_device, passthru_device);
76 
77  return OpenAudio(settings, willsuspendpa);
78 }
79 
81  [[maybe_unused]] bool willsuspendpa)
82 {
83  QString &main_device = settings.m_mainDevice;
84  AudioOutput *ret = nullptr;
85 
86  // Don't suspend Pulse if unnecessary. This can save 100mS
87  if (settings.m_format == FORMAT_NONE || settings.m_channels <= 0)
88  willsuspendpa = false;
89 
90 #ifdef USING_PULSE
91  bool pulsestatus = false;
92 #else
93  {
94  static bool warned = false;
95  if (!warned && IsPulseAudioRunning())
96  {
97  warned = true;
98  LOG(VB_GENERAL, LOG_WARNING,
99  "WARNING: ***Pulse Audio is running***");
100  }
101  }
102 #endif // USING_PULSE
103 
104  settings.FixPassThrough();
105 
106  if (main_device.startsWith("PulseAudio:"))
107  {
108 #ifdef USING_PULSEOUTPUT
109  return new AudioOutputPulseAudio(settings);
110 #else
111  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to PulseAudio "
112  "but PulseAudio support is not compiled in!");
113  return nullptr;
114 #endif // USING_PULSEOUTPUT
115  }
116  if (main_device.startsWith("NULL"))
117  {
118  return new AudioOutputNULL(settings);
119  }
120 
121 #ifdef USING_PULSE
122  if (willsuspendpa)
123  {
124  bool ispulse = false;
125 #ifdef USING_ALSA
126  // Check if using ALSA, that the device doesn't contain the word
127  // "pulse" in its hint
128  if (main_device.startsWith("ALSA:"))
129  {
130  QString device_name = main_device;
131 
132  device_name.remove(0, 5);
133  QMap<QString, QString> *alsadevs =
135  if (!alsadevs->empty() && alsadevs->contains(device_name))
136  {
137  if (alsadevs->value(device_name).contains("pulse",
138  Qt::CaseInsensitive))
139  {
140  ispulse = true;
141  }
142  }
143  delete alsadevs;
144  }
145 #endif // USING_ALSA
146  if (main_device.contains("pulse", Qt::CaseInsensitive))
147  {
148  ispulse = true;
149  }
150  if (!ispulse)
151  {
153  }
154  }
155 #endif // USING_PULSE
156 
157  if (main_device.startsWith("ALSA:"))
158  {
159 #ifdef USING_ALSA
160  settings.TrimDeviceType();
161  ret = new AudioOutputALSA(settings);
162 #else
163  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to an ALSA device "
164  "but ALSA support is not compiled in!");
165 #endif
166  }
167  else if (main_device.startsWith("JACK:"))
168  {
169 #ifdef USING_JACK
170  settings.TrimDeviceType();
171  ret = new AudioOutputJACK(settings);
172 #else
173  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a JACK device "
174  "but JACK support is not compiled in!");
175 #endif
176  }
177  else if (main_device.startsWith("DirectX:"))
178  {
179 #ifdef _WIN32
180  ret = new AudioOutputDX(settings);
181 #else
182  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to DirectX device "
183  "but DirectX support is not compiled in!");
184 #endif
185  }
186  else if (main_device.startsWith("Windows:"))
187  {
188 #ifdef _WIN32
189  ret = new AudioOutputWin(settings);
190 #else
191  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a Windows "
192  "device but Windows support is not compiled "
193  "in!");
194 #endif
195  }
196  else if (main_device.startsWith("OpenSLES:"))
197  {
198 #ifdef Q_OS_ANDROID
199  ret = new AudioOutputOpenSLES(settings);
200 #else
201  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a OpenSLES "
202  "device but Android support is not compiled "
203  "in!");
204 #endif
205  }
206  else if (main_device.startsWith("AudioTrack:"))
207  {
208 #ifdef Q_OS_ANDROID
209  ret = new AudioOutputAudioTrack(settings);
210 #else
211  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to AudioTrack "
212  "device but Android support is not compiled "
213  "in!");
214 #endif
215  }
216 #if defined(USING_OSS)
217  else
218  {
219  ret = new AudioOutputOSS(settings);
220  }
221 #elif defined(Q_OS_DARWIN)
222  else
223  {
224  ret = new AudioOutputCA(settings);
225  }
226 #endif
227 
228  if (!ret)
229  {
230  LOG(VB_GENERAL, LOG_CRIT, "No useable audio output driver found.");
231  LOG(VB_GENERAL, LOG_ERR, "Don't disable OSS support unless you're "
232  "not running on Linux.");
233 #ifdef USING_PULSE
234  if (pulsestatus)
236 #endif
237  return nullptr;
238  }
239 #ifdef USING_PULSE
240  ret->m_pulseWasSuspended = pulsestatus;
241 #endif
242  return ret;
243 }
244 
246 {
247 #ifdef USING_PULSE
250 #endif
251  av_frame_free(&m_frame);
252 }
253 
254 void AudioOutput::SetStretchFactor(float /*factor*/)
255 {
256 }
257 
259 {
260  return new AudioOutputSettings;
261 }
262 
264 {
265  return new AudioOutputSettings;
266 }
267 
268 bool AudioOutput::CanPassthrough(int /*samplerate*/,
269  int /*channels*/,
270  AVCodecID /*codec*/,
271  int /*profile*/) const
272 {
273  return false;
274 }
275 
276 // TODO: get rid of this if possible... need to see what uses GetError() and
277 // GetWarning() and why. These would give more useful logs as macros
278 void AudioOutput::Error(const QString &msg)
279 {
280  m_lastError = msg;
281  LOG(VB_GENERAL, LOG_ERR, "AudioOutput Error: " + m_lastError);
282 }
283 
284 void AudioOutput::SilentError(const QString &msg)
285 {
286  m_lastError = msg;
287 }
288 
289 void AudioOutput::Warn(const QString &msg)
290 {
291  m_lastWarn = msg;
292  LOG(VB_GENERAL, LOG_WARNING, "AudioOutput Warning: " + m_lastWarn);
293 }
294 
296 {
297  m_lastError.clear();
298 }
299 
301 {
302  m_lastWarn.clear();
303 }
304 
306  QString &name, const QString &desc, bool willsuspendpa)
307 {
308  AudioOutputSettings aosettings(true);
309 
310  AudioOutput *ao = OpenAudio(name, QString(), willsuspendpa);
311  if (ao)
312  {
313  aosettings = *(ao->GetOutputSettingsCleaned());
314  delete ao;
315  }
316  if (aosettings.IsInvalid())
317  {
318  if (!willsuspendpa)
319  return nullptr;
320  QString msg = tr("Invalid or unuseable audio device");
321  return new AudioOutput::AudioDeviceConfig(name, msg);
322  }
323 
324  QString capabilities = desc;
325  int max_channels = aosettings.BestSupportedChannelsELD();
326  if (aosettings.hasELD())
327  {
328  if (aosettings.getELD().isValid())
329  {
330  capabilities += tr(" (%1 connected to %2)")
331  .arg(aosettings.getELD().product_name().simplified(),
332  aosettings.getELD().connection_name());
333  }
334  else
335  {
336  capabilities += tr(" (No connection detected)");
337  }
338  }
339 
340  QString speakers;
341  switch (max_channels)
342  {
343  case 6:
344  speakers = "5.1";
345  break;
346  case 8:
347  speakers = "7.1";
348  break;
349  default:
350  speakers = "2.0";
351  break;
352  }
353 
354  capabilities += tr("\nDevice supports up to %1")
355  .arg(speakers);
356  if (aosettings.canPassthrough() >= 0)
357  {
358  if (aosettings.hasELD() && aosettings.getELD().isValid())
359  {
360  // We have an ELD, show actual reported capabilities
361  capabilities += " (" + aosettings.getELD().codecs_desc() + ")";
362  }
363  else
364  {
365  // build capabilities string, in a similar fashion as reported
366  // by ELD
367  int mask = 0;
368  mask |=
369  (static_cast<int>(aosettings.canLPCM()) << 0) |
370  (static_cast<int>(aosettings.canAC3()) << 1) |
371  (static_cast<int>(aosettings.canDTS()) << 2);
372  static const std::array<const std::string,3> s_typeNames { "LPCM", "AC3", "DTS" };
373 
374  if (mask != 0)
375  {
376  capabilities += QObject::tr(" (guessing: ");
377  bool found_one = false;
378  for (unsigned int i = 0; i < 3; i++)
379  {
380  if ((mask & (1 << i)) != 0)
381  {
382  if (found_one)
383  capabilities += ", ";
384  capabilities += QString::fromStdString(s_typeNames[i]);
385  found_one = true;
386  }
387  }
388  capabilities += QString(")");
389  }
390  }
391  }
392  LOG(VB_AUDIO, LOG_INFO, QString("Found %1 (%2)") .arg(name, capabilities));
393  auto *adc = new AudioOutput::AudioDeviceConfig(name, capabilities);
394  adc->m_settings = aosettings;
395  return adc;
396 }
397 
398 #ifdef USING_OSS
399 static void fillSelectionsFromDir(const QDir &dir,
400  AudioOutput::ADCVect *list)
401 {
402  QFileInfoList entries = dir.entryInfoList();
403  for (const auto& fi : std::as_const(entries))
404  {
405  QString name = fi.absoluteFilePath();
406  QString desc = AudioOutput::tr("OSS device");
409  if (!adc)
410  continue;
411  list->append(*adc);
412  delete adc;
413  }
414 }
415 #endif
416 
418 {
419  auto *list = new ADCVect;
420 
421 #ifdef USING_PULSE
423 #endif
424 
425 #ifdef USING_ALSA
426  QMap<QString, QString> *alsadevs = AudioOutputALSA::GetDevices("pcm");
427 
428  if (!alsadevs->empty())
429  {
430  for (auto i = alsadevs->cbegin(); i != alsadevs->cend(); ++i)
431  {
432  const QString& key = i.key();
433  const QString& desc = i.value();
434  QString devname = QString("ALSA:%1").arg(key);
435 
436  auto *adc = GetAudioDeviceConfig(devname, desc);
437  if (!adc)
438  continue;
439  list->append(*adc);
440  delete adc;
441  }
442  }
443  delete alsadevs;
444 #endif
445 #ifdef USING_OSS
446  {
447  QDir dev("/dev", "dsp*", QDir::Name, QDir::System);
448  fillSelectionsFromDir(dev, list);
449  dev.setNameFilters(QStringList("adsp*"));
450  fillSelectionsFromDir(dev, list);
451 
452  dev.setPath("/dev/sound");
453  if (dev.exists())
454  {
455  dev.setNameFilters(QStringList("dsp*"));
456  fillSelectionsFromDir(dev, list);
457  dev.setNameFilters(QStringList("adsp*"));
458  fillSelectionsFromDir(dev, list);
459  }
460  }
461 #endif
462 #ifdef USING_JACK
463  {
464  QString name = "JACK:";
465  QString desc = tr("Use JACK default sound server.");
466  auto *adc = GetAudioDeviceConfig(name, desc);
467  if (adc)
468  {
469  list->append(*adc);
470  delete adc;
471  }
472  }
473 #endif
474 #ifdef Q_OS_DARWIN
475 
476  {
477  QMap<QString, QString> *devs = AudioOutputCA::GetDevices(nullptr);
478  if (!devs->empty())
479  {
480  for (QMap<QString, QString>::const_iterator i = devs->begin();
481  i != devs->end(); ++i)
482  {
483  QString key = i.key();
484  QString desc = i.value();
485  QString devname = QString("CoreAudio:%1").arg(key);
486 
487  auto adc = GetAudioDeviceConfig(devname, desc);
488  if (!adc)
489  continue;
490  list->append(*adc);
491  delete adc;
492  }
493  }
494  delete devs;
495  QString name = "CoreAudio:Default Output Device";
496  QString desc = tr("CoreAudio default output");
497  auto adc = GetAudioDeviceConfig(name, desc);
498  if (adc)
499  {
500  list->append(*adc);
501  delete adc;
502  }
503  }
504 #endif
505 #ifdef _WIN32
506  {
507  QString name = "Windows:";
508  QString desc = "Windows default output";
509  auto adc = GetAudioDeviceConfig(name, desc);
510  if (adc)
511  {
512  list->append(*adc);
513  delete adc;
514  }
515 
516  QMap<int, QString> *dxdevs = AudioOutputDX::GetDXDevices();
517 
518  if (!dxdevs->empty())
519  {
520  for (QMap<int, QString>::const_iterator i = dxdevs->begin();
521  i != dxdevs->end(); ++i)
522  {
523  QString devdesc = i.value();
524  QString devname = QString("DirectX:%1").arg(devdesc);
525 
526  adc = GetAudioDeviceConfig(devname, devdesc);
527  if (!adc)
528  continue;
529  list->append(*adc);
530  delete adc;
531  }
532  }
533  delete dxdevs;
534  }
535 #endif
536 
537 #ifdef USING_PULSE
538  if (pasuspended)
540 #endif
541 
542 #ifdef USING_PULSEOUTPUT
543  {
544  QString name = "PulseAudio:default";
545  QString desc = tr("PulseAudio default sound server.");
546  auto *adc = GetAudioDeviceConfig(name, desc);
547  if (adc)
548  {
549  list->append(*adc);
550  delete adc;
551  }
552  }
553 #endif
554 
555 #ifdef Q_OS_ANDROID
556  {
557  QString name = "OpenSLES:";
558  QString desc = tr("OpenSLES default output. Stereo support only.");
559  auto adc = GetAudioDeviceConfig(name, desc);
560  if (adc)
561  {
562  list->append(*adc);
563  delete adc;
564  }
565  }
566  {
567  QString name = "AudioTrack:";
568  QString desc = tr("Android AudioTrack output. Supports surround sound.");
569  auto adc = GetAudioDeviceConfig(name, desc);
570  if (adc)
571  {
572  list->append(*adc);
573  delete adc;
574  }
575  }
576 #endif
577 
578  QString name = "NULL";
579  QString desc = "NULL device";
580  auto *adc = GetAudioDeviceConfig(name, desc);
581  if (adc)
582  {
583  list->append(*adc);
584  delete adc;
585  }
586  return list;
587 }
588 
596 int AudioOutput::DecodeAudio(AVCodecContext *ctx,
597  uint8_t *buffer, int &data_size,
598  const AVPacket *pkt)
599 {
600  bool got_frame = false;
601 
602  data_size = 0;
603  if (!m_frame)
604  {
605  m_frame = av_frame_alloc();
606  if (m_frame == nullptr)
607  {
608  return AVERROR(ENOMEM);
609  }
610  }
611  else
612  {
613  av_frame_unref(m_frame);
614  }
615 
616 // SUGGESTION
617 // Now that avcodec_decode_audio4 is deprecated and replaced
618 // by 2 calls (receive frame and send packet), this could be optimized
619 // into separate routines or separate threads.
620 // Also now that it always consumes a whole buffer some code
621 // in the caller may be able to be optimized.
622  int ret = avcodec_receive_frame(ctx,m_frame);
623  if (ret == 0)
624  got_frame = true;
625  if (ret == AVERROR(EAGAIN))
626  ret = 0;
627  if (ret == 0)
628  ret = avcodec_send_packet(ctx, pkt);
629  if (ret == AVERROR(EAGAIN))
630  ret = 0;
631  else if (ret < 0)
632  {
633  std::string error;
634  LOG(VB_AUDIO, LOG_ERR, LOC +
635  QString("audio decode error: %1 (%2)")
636  .arg(av_make_error_stdstring(error, ret))
637  .arg(got_frame));
638  return ret;
639  }
640  else
641  {
642  ret = pkt->size;
643  }
644 
645  if (!got_frame)
646  {
647  LOG(VB_AUDIO, LOG_DEBUG, LOC +
648  QString("audio decode, no frame decoded (%1)").arg(ret));
649  return ret;
650  }
651 
652  auto format = (AVSampleFormat)m_frame->format;
653  AudioFormat fmt =
654  AudioOutputSettings::AVSampleFormatToFormat(format, ctx->bits_per_raw_sample);
655 
656  data_size = m_frame->nb_samples * m_frame->ch_layout.nb_channels * av_get_bytes_per_sample(format);
657 
658  // May need to convert audio to S16
659  AudioConvert converter(fmt, CanProcess(fmt) ? fmt : FORMAT_S16);
660  uint8_t* src = nullptr;
661 
662  if (av_sample_fmt_is_planar(format))
663  {
664  src = buffer;
665  converter.InterleaveSamples(m_frame->ch_layout.nb_channels,
666  src,
667  (const uint8_t **)m_frame->extended_data,
668  data_size);
669  }
670  else
671  {
672  // data is already compacted...
673  src = m_frame->extended_data[0];
674  }
675 
676  uint8_t* transit = buffer;
677 
678  if (!CanProcess(fmt) &&
679  av_get_bytes_per_sample(ctx->sample_fmt) < AudioOutputSettings::SampleSize(converter.Out()))
680  {
681  // this conversion can't be done in place
682  transit = (uint8_t*)av_malloc(data_size * av_get_bytes_per_sample(ctx->sample_fmt)
683  / AudioOutputSettings::SampleSize(converter.Out()));
684  if (!transit)
685  {
686  LOG(VB_AUDIO, LOG_ERR, LOC +
687  QString("audio decode, out of memory"));
688  data_size = 0;
689  return ret;
690  }
691  }
692  if (!CanProcess(fmt) || src != transit)
693  {
694  data_size = converter.Process(transit, src, data_size, true);
695  }
696  if (transit != buffer)
697  {
698  av_free(transit);
699  }
700  return ret;
701 }
audiooutputwin.h
AudioOutputSettings::AVSampleFormatToFormat
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
Definition: audiooutputsettings.cpp:198
AudioOutputDX
Definition: audiooutputdx.h:12
PulseHandler::kPulseSuspend
@ kPulseSuspend
Definition: audiopulsehandler.h:13
audiooutputoss.h
AudioOutputALSA
Definition: audiooutputalsa.h:12
PulseHandler::Suspend
static bool Suspend(enum PulseAction action)
Definition: audiopulsehandler.cpp:42
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:27
AudioOutput::Error
void Error(const QString &msg)
Definition: audiooutput.cpp:278
eld::connection_name
QString connection_name() const
Definition: eldutils.cpp:446
AudioOutputJACK
Definition: audiooutputjack.h:19
AudioOutput::Warn
void Warn(const QString &msg)
Definition: audiooutput.cpp:289
AudioOutputSettings::SampleSize
static int SampleSize(AudioFormat format)
Definition: audiooutputsettings.cpp:180
AudioOutputWin
Definition: audiooutputwin.h:9
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
AudioOutputALSA::GetDevices
static QMap< QString, QString > * GetDevices(const char *type)
Definition: audiooutputalsa.cpp:999
audiooutputalsa.h
AudioConvert::Out
AudioFormat Out(void)
Definition: audioconvert.h:49
AudioOutputPulseAudio
Definition: audiooutputpulse.h:27
OutputListeners::error
void error(const QString &e)
Definition: output.cpp:29
audiooutputaudiotrack.h
LOC
#define LOC
Definition: audiooutput.cpp:49
audiooutputjack.h
AudioOutput::OpenAudio
static AudioOutput * OpenAudio(const QString &main_device, const QString &passthru_device, AudioFormat format, int channels, AVCodecID codec, int samplerate, AudioOutputSource source, bool set_initial_vol, bool passthru, int upmixer_startup=0, AudioOutputSettings *custom=nullptr)
Definition: audiooutput.cpp:58
AudioOutputCA
Implements Core Audio (Mac OS X Hardware Abstraction Layer) output.
Definition: audiooutputca.h:13
AudioSettings::FixPassThrough
void FixPassThrough(void)
Definition: audiosettings.cpp:97
AudioOutputCA::GetDevices
static QMap< QString, QString > * GetDevices(const char *type=nullptr)
Definition: audiooutputca.cpp:1749
IsPulseAudioRunning
bool IsPulseAudioRunning(void)
Is A/V Sync destruction daemon is running on this host?
Definition: mythmiscutil.cpp:638
AudioOutputDX::GetDXDevices
static QMap< int, QString > * GetDXDevices(void)
Definition: audiooutputdx.cpp:624
AudioSettings
Definition: audiosettings.h:28
audiooutputopensles.h
AudioConvert
Definition: audioconvert.h:32
AudioOutput::CanPassthrough
virtual bool CanPassthrough(int samplerate, int channels, AVCodecID codec, int profile) const
Definition: audiooutput.cpp:268
AudioOutput
Definition: audiooutput.h:24
mythlogging.h
audiooutputnull.h
AudioOutputSettings::BestSupportedChannelsELD
int BestSupportedChannelsELD()
Reports best supported channel number, restricted to ELD range.
Definition: audiooutputsettings.cpp:548
FORMAT_NONE
@ FORMAT_NONE
Definition: audiooutputsettings.h:25
AudioOutputSettings::canPassthrough
int canPassthrough() const
Definition: audiooutputsettings.h:77
compat.h
AudioOutputOpenSLES
Definition: audiooutputopensles.h:17
AudioOutput::GetOutputSettingsCleaned
virtual AudioOutputSettings * GetOutputSettingsCleaned(bool digital=true)
Definition: audiooutput.cpp:258
audiopulsehandler.h
AudioSettings::m_mainDevice
QString m_mainDevice
Definition: audiosettings.h:70
AudioOutput::GetAudioDeviceConfig
static AudioDeviceConfig * GetAudioDeviceConfig(QString &name, const QString &desc, bool willsuspendpa=false)
Definition: audiooutput.cpp:305
AudioOutputSettings::hasELD
bool hasELD() const
get the ELD flag
Definition: audiooutputsettings.cpp:536
AudioOutputSettings::canDTS
bool canDTS() const
return true if device can or may support DTS (deprecated, see canFeature())
Definition: audiooutputsettings.h:102
AudioOutput::DecodeAudio
virtual int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
Utility routine.
Definition: audiooutput.cpp:596
eld::product_name
QString product_name() const
Definition: eldutils.cpp:441
AudioOutputSettings::IsInvalid
bool IsInvalid() const
return true if class instance is marked invalid.
Definition: audiooutputsettings.h:113
AudioOutputAudioTrack
Definition: audiooutputaudiotrack.h:16
AudioOutputOSS
Definition: audiooutputoss.h:14
AudioOutput::AudioDeviceConfig
Definition: audiooutput.h:29
AudioOutputNULL
Definition: audiooutputnull.h:21
audiooutputpulse.h
mythmiscutil.h
fillSelectionsFromDir
static void fillSelectionsFromDir(const QDir &dir, AudioOutput::ADCVect *list)
Definition: audiooutput.cpp:399
AudioOutput::SilentError
void SilentError(const QString &msg)
Definition: audiooutput.cpp:284
AudioSettings::m_format
AudioFormat m_format
Definition: audiosettings.h:72
PulseHandler::kPulseResume
@ kPulseResume
Definition: audiopulsehandler.h:14
AudioOutput::SetStretchFactor
virtual void SetStretchFactor(float factor)
Definition: audiooutput.cpp:254
AudioConvert::Process
int Process(void *out, const void *in, int bytes, bool noclip=false)
Process Parameters: out : destination buffer where converted samples will be copied in : source buffe...
Definition: audioconvert.cpp:654
AudioOutputSettings
Definition: audiooutputsettings.h:48
audiooutput.h
audiooutputdx.h
AudioOutput::CanProcess
virtual uint32_t CanProcess(void)
Definition: audiooutput.h:173
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:24
AudioOutput::ClearError
void ClearError(void)
Definition: audiooutput.cpp:295
audiooutputca.h
AudioOutputSettings::canLPCM
bool canLPCM() const
return true if device supports multichannels PCM (deprecated, see canFeature())
Definition: audiooutputsettings.h:107
AudioOutput::ClearWarning
void ClearWarning(void)
Definition: audiooutput.cpp:300
AudioConvert::InterleaveSamples
void InterleaveSamples(int channels, uint8_t *output, const uint8_t *const *input, int data_size)
Definition: audioconvert.cpp:883
AudioOutput::m_lastWarn
QString m_lastWarn
Definition: audiooutput.h:205
AudioOutput::~AudioOutput
~AudioOutput() override
Definition: audiooutput.cpp:245
AudioSettings::TrimDeviceType
void TrimDeviceType(void)
Definition: audiosettings.cpp:103
AudioOutput::Cleanup
static void Cleanup(void)
Definition: audiooutput.cpp:51
eld::codecs_desc
QString codecs_desc() const
Definition: eldutils.cpp:476
AudioOutput::ADCVect
QVector< AudioDeviceConfig > ADCVect
Definition: audiooutput.h:47
AudioOutput::GetOutputSettingsUsers
virtual AudioOutputSettings * GetOutputSettingsUsers(bool digital=true)
Definition: audiooutput.cpp:263
AudioOutputSettings::getELD
eld & getELD(void)
retrieve ELD data
Definition: audiooutputsettings.h:175
eld::isValid
bool isValid() const
Definition: eldutils.cpp:412
AudioOutput::m_pulseWasSuspended
bool m_pulseWasSuspended
Definition: audiooutput.h:206
mythaverror.h
AudioOutput::m_frame
AVFrame * m_frame
Definition: audiooutput.h:207
av_make_error_stdstring
char * av_make_error_stdstring(std::string &errbuf, int errnum)
A C++ equivalent to av_make_error_string.
Definition: mythaverror.cpp:42
AudioOutput::GetOutputList
static ADCVect * GetOutputList(void)
Definition: audiooutput.cpp:417
PulseHandler::kPulseCleanup
@ kPulseCleanup
Definition: audiopulsehandler.h:15
AudioOutput::m_lastError
QString m_lastError
Definition: audiooutput.h:204
AudioSettings::m_channels
int m_channels
Definition: audiosettings.h:73
AudioOutputSource
AudioOutputSource
Definition: audiosettings.h:21
AudioOutputSettings::canAC3
bool canAC3() const
return true if device can or may support AC3 (deprecated, see canFeature())
Definition: audiooutputsettings.h:97
audioconvert.h