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