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