MythTV  master
avfdecoder.cpp
Go to the documentation of this file.
1 /*
2  MythMusic libav* Decoder
3  Originally written by Kevin Kuphal with contributions and updates from
4  many others
5 
6  Special thanks to
7  ffmpeg team for libavcodec and libavformat
8  qemacs team for their av support which I used to understand the libraries
9  getid3.sourceforget.net project for the ASF information used here
10 
11  This library decodes various media files into PCM data
12  returned to the MythMusic output buffer.
13 
14  Revision History
15  - Initial release
16  - 1/9/2004 - Improved seek support
17  - ?/?/2009 - Extended to support many more filetypes and bug fixes
18  - ?/7/2010 - Add streaming support
19 */
20 
21 // C++ headers
22 #include <chrono>
23 
24 // QT headers
25 #include <QObject>
26 #include <QIODevice>
27 #include <QFile>
28 #include <QTimer>
29 
30 // Myth headers
31 #include <mythconfig.h>
32 #include <mythcontext.h>
33 #include <audiooutput.h>
34 #include <audiooutpututil.h>
35 #include <mythlogging.h>
36 #include <decoderhandler.h>
37 #include <mythavutil.h>
38 
39 // Mythmusic Headers
40 #include "avfdecoder.h"
41 #include "metaio.h"
42 #include "metaioavfcomment.h"
43 #include "metaioid3.h"
44 #include "metaioflacvorbis.h"
45 #include "metaiooggvorbis.h"
46 #include "metaiomp4.h"
47 #include "metaiowavpack.h"
48 #include "decoderhandler.h"
49 #include "musicplayer.h"
50 
51 extern "C" {
52 #include "libavformat/avio.h"
53 #include "libavutil/opt.h"
54 }
55 
56 using namespace std::chrono_literals;
57 
58 /****************************************************************************/
59 
60 using ShoutCastMetaMap = QMap<QString,QString>;
61 
63 {
64  public:
65  ShoutCastMetaParser(void) = default;
66  ~ShoutCastMetaParser(void) = default;
67 
68  void setMetaFormat(const QString &metaformat);
69  ShoutCastMetaMap parseMeta(const QString &mdata);
70 
71  private:
72  QString m_metaFormat;
73  int m_metaArtistPos {-1};
74  int m_metaTitlePos {-1};
75  int m_metaAlbumPos {-1};
76 };
77 
78 void ShoutCastMetaParser::setMetaFormat(const QString &metaformat)
79 {
80 /*
81  We support these metatags :
82  %a - artist
83  %t - track
84  %b - album
85  %r - random bytes
86  */
87  m_metaFormat = metaformat;
88 
89  m_metaArtistPos = 0;
90  m_metaTitlePos = 0;
91  m_metaAlbumPos = 0;
92 
93  int assign_index = 1;
94  int pos = 0;
95 
96  pos = m_metaFormat.indexOf("%", pos);
97  while (pos >= 0)
98  {
99  pos++;
100 
101  QChar ch;
102 
103  if (pos < m_metaFormat.length())
104  ch = m_metaFormat.at(pos);
105 
106  if (!ch.isNull() && ch == '%')
107  {
108  pos++;
109  }
110  else if (!ch.isNull() && (ch == 'r' || ch == 'a' || ch == 'b' || ch == 't'))
111  {
112  if (ch == 'a')
113  m_metaArtistPos = assign_index;
114 
115  if (ch == 'b')
116  m_metaAlbumPos = assign_index;
117 
118  if (ch == 't')
119  m_metaTitlePos = assign_index;
120 
121  assign_index++;
122  }
123  else
124  {
125  LOG(VB_GENERAL, LOG_ERR,
126  QString("ShoutCastMetaParser: malformed metaformat '%1'")
127  .arg(m_metaFormat));
128  }
129 
130  pos = m_metaFormat.indexOf("%", pos);
131  }
132 
133  m_metaFormat.replace("%a", "(.*)");
134  m_metaFormat.replace("%t", "(.*)");
135  m_metaFormat.replace("%b", "(.*)");
136  m_metaFormat.replace("%r", "(.*)");
137  m_metaFormat.replace("%%", "%");
138 }
139 
141 {
142  ShoutCastMetaMap result;
143  int title_begin_pos = mdata.indexOf("StreamTitle='");
144 
145  if (title_begin_pos >= 0)
146  {
147  title_begin_pos += 13;
148  int title_end_pos = mdata.indexOf("';", title_begin_pos);
149  QString title = mdata.mid(title_begin_pos, title_end_pos - title_begin_pos);
150  QRegExp rx;
151  rx.setPattern(m_metaFormat);
152  if (rx.indexIn(title) != -1)
153  {
154  LOG(VB_PLAYBACK, LOG_INFO, QString("ShoutCast: Meta : '%1'")
155  .arg(mdata));
156  LOG(VB_PLAYBACK, LOG_INFO,
157  QString("ShoutCast: Parsed as: '%1' by '%2'")
158  .arg(rx.cap(m_metaTitlePos))
159  .arg(rx.cap(m_metaArtistPos)));
160 
161  if (m_metaTitlePos > 0)
162  result["title"] = rx.cap(m_metaTitlePos);
163 
164  if (m_metaArtistPos > 0)
165  result["artist"] = rx.cap(m_metaArtistPos);
166 
167  if (m_metaAlbumPos > 0)
168  result["album"] = rx.cap(m_metaAlbumPos);
169  }
170  }
171 
172  return result;
173 }
174 
175 static void myth_av_log(void *ptr, int level, const char* fmt, va_list vl)
176 {
177  if (VERBOSE_LEVEL_NONE)
178  return;
179 
180  static QString s_fullLine("");
181  static QMutex s_stringLock;
182  uint64_t verbose_mask = VB_GENERAL;
183  LogLevel_t verbose_level = LOG_DEBUG;
184 
185  // determine mythtv debug level from av log level
186  switch (level)
187  {
188  case AV_LOG_PANIC:
189  verbose_level = LOG_EMERG;
190  break;
191  case AV_LOG_FATAL:
192  verbose_level = LOG_CRIT;
193  break;
194  case AV_LOG_ERROR:
195  verbose_level = LOG_ERR;
196  verbose_mask |= VB_LIBAV;
197  break;
198  case AV_LOG_DEBUG:
199  case AV_LOG_VERBOSE:
200  case AV_LOG_INFO:
201  verbose_level = LOG_DEBUG;
202  verbose_mask |= VB_LIBAV;
203  break;
204  case AV_LOG_WARNING:
205  verbose_mask |= VB_LIBAV;
206  break;
207  default:
208  return;
209  }
210 
211  if (!VERBOSE_LEVEL_CHECK(verbose_mask, verbose_level))
212  return;
213 
214  s_stringLock.lock();
215  if (s_fullLine.isEmpty() && ptr) {
216  AVClass* avc = *(AVClass**)ptr;
217  s_fullLine = QString("[%1 @ %2] ")
218  .arg(avc->item_name(ptr))
219  .arg(reinterpret_cast<size_t>(avc),QT_POINTER_SIZE,8,QChar('0'));
220  }
221 
222  s_fullLine += QString::asprintf(fmt, vl);
223  if (s_fullLine.endsWith("\n"))
224  {
225  LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
226  s_fullLine.truncate(0);
227  }
228  s_stringLock.unlock();
229 }
230 
232  Decoder(d, o)
233 {
234  MThread::setObjectName("avfDecoder");
235  setURL(file);
236 
238  (uint8_t *)av_malloc(AudioOutput::kMaxSizeBuffer);
239 
240  bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY);
241  av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR);
242  av_log_set_callback(myth_av_log);
243 }
244 
246 {
247  delete m_mdataTimer;
248 
249  if (m_inited)
250  deinit();
251 
252  if (m_outputBuffer)
253  av_freep(&m_outputBuffer);
254 
255  delete m_inputContext;
256 }
257 
259 {
260  m_userStop = true;
261 }
262 
264 {
265  m_inited = m_userStop = m_finish = false;
266  m_freq = m_bitrate = 0;
267  m_stat = m_channels = 0;
268  m_seekTime = -1.0;
269 
270  // give up if we dont have an audiooutput set
271  if (!output())
272  {
273  error("avfDecoder: initialise called with a NULL audiooutput");
274  return false;
275  }
276 
277  if (!m_outputBuffer)
278  {
279  error("avfDecoder: couldn't allocate memory");
280  return false;
281  }
282 
284 
285  delete m_inputContext;
287 
288  if (!m_inputContext->isOpen())
289  {
290  error(QString("Could not open url (%1)").arg(m_url));
291  deinit();
292  return false;
293  }
294 
295  // if this is a ice/shoutcast or MMS stream start polling for metadata changes and buffer status
296  if (getURL().startsWith("http://") || getURL().startsWith("mmsh://"))
297  {
298  m_mdataTimer = new QTimer;
299  m_mdataTimer->setSingleShot(false);
301 
302  m_mdataTimer->start(500ms);
303 
304  // we don't get metadata updates for MMS streams so grab the metadata from the headers
305  if (getURL().startsWith("mmsh://"))
306  {
307  AVDictionaryEntry *tag = nullptr;
309 
310  tag = av_dict_get(m_inputContext->getContext()->metadata, "title", tag, AV_DICT_IGNORE_SUFFIX);
311  mdata.setTitle(tag->value);
312 
313  tag = av_dict_get(m_inputContext->getContext()->metadata, "artist", tag, AV_DICT_IGNORE_SUFFIX);
314  mdata.setArtist(tag->value);
315 
316  mdata.setAlbum("");
317  mdata.setLength(-1);
318 
320  dispatch(ev);
321  }
322  }
323 
324  // determine the stream format
325  // this also populates information needed for metadata
326  if (avformat_find_stream_info(m_inputContext->getContext(), nullptr) < 0)
327  {
328  error("Could not determine the stream format.");
329  deinit();
330  return false;
331  }
332 
333  // let FFmpeg finds the best audio stream (should only be one), also catter
334  // should the file/stream not be an audio one
335  AVCodec *codec = nullptr;
336  int selTrack = av_find_best_stream(m_inputContext->getContext(), AVMEDIA_TYPE_AUDIO,
337  -1, -1, &codec, 0);
338 
339  if (selTrack < 0)
340  {
341  error(QString("Could not find audio stream."));
342  deinit();
343  return false;
344  }
345 
346  // Store the audio codec of the stream
348  (m_inputContext->getContext()->streams[selTrack]);
349 
350  // Store the input format of the context
352 
353  if (avcodec_open2(m_audioDec, codec, nullptr) < 0)
354  {
355  error(QString("Could not open audio codec: %1")
356  .arg(m_audioDec->codec_id));
357  deinit();
358  return false;
359  }
360 
361  m_freq = m_audioDec->sample_rate;
362  m_channels = m_audioDec->channels;
363 
364  if (m_channels <= 0)
365  {
366  error(QString("AVCodecContext tells us %1 channels are "
367  "available, this is bad, bailing.")
368  .arg(m_channels));
369  deinit();
370  return false;
371  }
372 
373  AudioFormat format =
375  m_audioDec->bits_per_raw_sample);
376  if (format == FORMAT_NONE)
377  {
378  error(QString("Error: Unsupported sample format: %1")
379  .arg(av_get_sample_fmt_name(m_audioDec->sample_fmt)));
380  deinit();
381  return false;
382  }
383 
384  const AudioSettings settings(format, m_audioDec->channels,
385  m_audioDec->codec_id,
386  m_audioDec->sample_rate, false);
387 
388  output()->Reconfigure(settings);
389  output()->SetSourceBitrate(m_audioDec->bit_rate);
390 
391  m_inited = true;
392  return true;
393 }
394 
395 void avfDecoder::seek(double pos)
396 {
398  m_inputContext->getContext()->pb->seekable)
399  {
400  m_seekTime = pos;
401  }
402 }
403 
405 {
406  m_inited = m_userStop = m_finish = false;
407  m_freq = m_bitrate = 0;
408  m_stat = m_channels = 0;
409  setOutput(nullptr);
410 
411  // Cleanup here
413  {
414  for (uint i = 0; i < m_inputContext->getContext()->nb_streams; i++)
415  {
416  AVStream *st = m_inputContext->getContext()->streams[i];
418  }
419  }
420 
421  m_audioDec = nullptr;
422  m_inputFormat = nullptr;
423 }
424 
426 {
427  RunProlog();
428  if (!m_inited)
429  {
430  RunEpilog();
431  return;
432  }
433 
434  AVPacket pkt;
435  AVPacket tmp_pkt;
436  memset(&pkt, 0, sizeof(AVPacket));
437  av_init_packet(&pkt);
438 
440  {
441  DecoderEvent e((DecoderEvent::Type) m_stat);
442  dispatch(e);
443  }
444 
445  av_read_play(m_inputContext->getContext());
446 
447  while (!m_finish && !m_userStop)
448  {
449  // Look to see if user has requested a seek
450  if (m_seekTime >= 0.0)
451  {
452  LOG(VB_GENERAL, LOG_INFO, QString("avfdecoder.o: seek time %1")
453  .arg(m_seekTime));
454 
455  if (av_seek_frame(m_inputContext->getContext(), -1,
456  (int64_t)(m_seekTime * AV_TIME_BASE), 0) < 0)
457  LOG(VB_GENERAL, LOG_ERR, "Error seeking");
458 
459  m_seekTime = -1.0;
460  }
461 
462  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
463  {
464  // Read a packet from the input context
465  int res = av_read_frame(m_inputContext->getContext(), &pkt);
466  if (res < 0)
467  {
468  if (res != AVERROR_EOF)
469  {
470  LOG(VB_GENERAL, LOG_ERR, QString("Read frame failed: %1").arg(res));
471  LOG(VB_FILE, LOG_ERR, ("... for file '" + m_url) + "'");
472  }
473 
474  m_finish = true;
475  break;
476  }
477 
478  av_init_packet(&tmp_pkt);
479  tmp_pkt.data = pkt.data;
480  tmp_pkt.size = pkt.size;
481 
482  while (tmp_pkt.size > 0 && !m_finish &&
483  !m_userStop && m_seekTime <= 0.0)
484  {
485  int data_size = 0;
486 
487  int ret = output()->DecodeAudio(m_audioDec,
489  data_size,
490  &tmp_pkt);
491 
492  if (ret < 0)
493  break;
494 
495  // Increment the output pointer and count
496  tmp_pkt.size -= ret;
497  tmp_pkt.data += ret;
498 
499  if (data_size <= 0)
500  continue;
501 
502  output()->AddData(m_outputBuffer, data_size, -1, 0);
503  }
504 
505  av_packet_unref(&pkt);
506 
507  // Wait until we need to decode or supply more samples
508  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
509  {
510  int64_t buffered = output()->GetAudioBufferedTime();
511  // never go below 1s buffered
512  if (buffered < 1000)
513  break;
514  // wait
515  const struct timespec ns {0, (buffered - 1000) * 1000000};
516  nanosleep(&ns, nullptr);
517  }
518  }
519  }
520 
521  if (m_userStop)
522  {
523  m_inited = false;
524  }
525  else
526  {
527  // Drain ao buffer, making sure we play all remaining audio samples
528  output()->Drain();
529  }
530 
531  if (m_finish)
533  else if (m_userStop)
535 
536  {
537  DecoderEvent e((DecoderEvent::Type) m_stat);
538  dispatch(e);
539  }
540 
541  deinit();
542  RunEpilog();
543 }
544 
546 {
547  uint8_t *pdata = nullptr;
548 
549  if (av_opt_get(m_inputContext->getContext(), "icy_metadata_packet", AV_OPT_SEARCH_CHILDREN, &pdata) >= 0)
550  {
551  QString s = QString::fromUtf8((const char*) pdata);
552 
553  if (m_lastMetadata != s)
554  {
555  m_lastMetadata = s;
556 
557  LOG(VB_PLAYBACK, LOG_INFO, QString("avfDecoder: shoutcast metadata changed - %1").arg(m_lastMetadata));
558 
561 
562  ShoutCastMetaMap meta_map = parser.parseMeta(m_lastMetadata);
563 
565  mdata.setTitle(meta_map["title"]);
566  mdata.setArtist(meta_map["artist"]);
567  mdata.setAlbum(meta_map["album"]);
568  mdata.setLength(-1);
569 
571  dispatch(ev);
572  }
573 
574  av_free(pdata);
575  }
576 
577  if (m_inputContext->getContext()->pb)
578  {
579  int available = (int) (m_inputContext->getContext()->pb->buf_end - m_inputContext->getContext()->pb->buffer);
580  int maxSize = m_inputContext->getContext()->pb->buffer_size;
582  dispatch(ev);
583  }
584 }
585 
586 bool avfDecoderFactory::supports(const QString &source) const
587 {
588 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
589  QStringList list = extension().split("|", QString::SkipEmptyParts);
590 #else
591  QStringList list = extension().split("|", Qt::SkipEmptyParts);
592 #endif
593  return std::any_of(list.cbegin(), list.cend(),
594  [source](const auto& str)
595  { return str == source.right(str.length()).toLower(); } );
596 }
597 
598 const QString &avfDecoderFactory::extension() const
599 {
601 }
602 
603 const QString &avfDecoderFactory::description() const
604 {
605  static QString s_desc(tr("Internal Decoder"));
606  return s_desc;
607 }
608 
609 Decoder *avfDecoderFactory::create(const QString &file, AudioOutput *output, bool deletable)
610 {
611  if (deletable)
612  return new avfDecoder(file, this, output);
613 
614  static avfDecoder *s_decoder = nullptr;
615  if (!s_decoder)
616  {
617  s_decoder = new avfDecoder(file, this, output);
618  }
619  else
620  {
621  s_decoder->setOutput(output);
622  }
623 
624  return s_decoder;
625 }
avfDecoder::m_inited
bool m_inited
Definition: avfdecoder.h:36
FORMAT_NONE
@ FORMAT_NONE
Definition: audiooutputsettings.h:26
AudioOutput::kMaxSizeBuffer
static const int kMaxSizeBuffer
kMaxSizeBuffer is the maximum size of a buffer to be used with DecodeAudio
Definition: audiooutput.h:195
DecoderHandlerEvent::BufferStatus
static Type BufferStatus
Definition: decoderhandler.h:49
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
RemoteAVFormatContext::isOpen
bool isOpen() const
Definition: mytharchive/mytharchive/remoteavformatcontext.h:104
avfDecoder::m_codecMap
MythCodecMap m_codecMap
Definition: avfdecoder.h:52
gPlayer
MusicPlayer * gPlayer
Definition: musicplayer.cpp:35
AudioOutput::GetAudioBufferedTime
virtual int64_t GetAudioBufferedTime(void)
report amount of audio buffered in milliseconds.
Definition: audiooutput.h:142
AudioOutputSettings::AVSampleFormatToFormat
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
Definition: audiooutputsettings.cpp:197
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
avfDecoder::run
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: avfdecoder.cpp:425
MythCodecMap::GetCodecContext
AVCodecContext * GetCodecContext(const AVStream *Stream, const AVCodec *Codec=nullptr, bool NullCodec=false)
Definition: mythavutil.cpp:238
MusicMetadata::setLength
void setLength(int llength)
Definition: musicmetadata.h:206
audiooutpututil.h
MusicMetadata::MetadataFormat
QString MetadataFormat(void)
Definition: musicmetadata.h:277
decoderhandler.h
title
QString title
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:636
ShoutCastMetaMap
QMap< QString, QString > ShoutCastMetaMap
Definition: avfdecoder.cpp:60
RemoteAVFormatContext::getContext
AVFormatContext * getContext(void)
Definition: mythmusic/mythmusic/remoteavformatcontext.h:31
MThread::setObjectName
void setObjectName(const QString &name)
Definition: mthread.cpp:243
arg
arg(title).arg(filename).arg(doDelete))
MusicMetadata::setAlbum
void setAlbum(const QString &lalbum, const QString &lalbum_sort=nullptr)
Definition: musicmetadata.h:152
avfDecoder::m_userStop
bool m_userStop
Definition: avfdecoder.h:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:198
MusicMetadata
Definition: musicmetadata.h:80
metaioflacvorbis.h
avfDecoder::m_seekTime
double m_seekTime
Definition: avfdecoder.h:45
DecoderFactory
Definition: decoder.h:112
build_compdb.parser
parser
Definition: build_compdb.py:7
avfDecoder::m_inputFormat
AVInputFormat * m_inputFormat
Definition: avfdecoder.h:49
avfDecoder::stop
void stop() override
Definition: avfdecoder.cpp:258
DecoderHandlerEvent::Meta
static Type Meta
Definition: decoderhandler.h:48
build_compdb.file
file
Definition: build_compdb.py:55
avfdecoder.h
Decoder::m_url
QString m_url
Definition: decoder.h:100
MythObservable::dispatch
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
Definition: mythobservable.cpp:73
ShoutCastMetaParser::m_metaFormat
QString m_metaFormat
Definition: avfdecoder.cpp:72
avfDecoder::initialize
bool initialize() override
Definition: avfdecoder.cpp:263
avfDecoder::m_mdataTimer
QTimer * m_mdataTimer
Definition: avfdecoder.h:56
avfDecoder::m_inputContext
RemoteAVFormatContext * m_inputContext
Definition: avfdecoder.h:50
avfDecoder::m_outputBuffer
uint8_t * m_outputBuffer
Definition: avfdecoder.h:39
AudioOutput::Drain
virtual void Drain(void)=0
AudioSettings
Definition: audiosettings.h:28
AudioOutput
Definition: audiooutput.h:25
DecoderHandlerEvent
Events sent by the DecoderHandler and it's helper classes.
Definition: decoderhandler.h:26
Decoder
Definition: decoder.h:65
RemoteAVFormatContext
Definition: mytharchive/mytharchive/remoteavformatcontext.h:16
mythlogging.h
avfDecoder
Definition: avfdecoder.h:15
avfDecoderFactory::supports
bool supports(const QString &source) const override
Definition: avfdecoder.cpp:586
AudioOutput::SetSourceBitrate
virtual void SetSourceBitrate(int)
Definition: audiooutput.h:144
DecoderEvent
Definition: decoder.h:29
avfDecoderFactory::description
const QString & description() const override
Definition: avfdecoder.cpp:603
avfDecoder::m_finish
bool m_finish
Definition: avfdecoder.h:41
avfDecoder::deinit
void deinit()
Definition: avfdecoder.cpp:404
debug
VERBOSE_PREAMBLE Most debug(nodatabase, notimestamp, noextra)") VERBOSE_MAP(VB_GENERAL
MusicMetadata::setTitle
void setTitle(const QString &ltitle, const QString &ltitle_sort=nullptr)
Definition: musicmetadata.h:164
ShoutCastMetaParser::setMetaFormat
void setMetaFormat(const QString &metaformat)
Definition: avfdecoder.cpp:78
avfDecoder::m_freq
long m_freq
Definition: avfdecoder.h:42
MythCodecMap::FreeCodecContext
void FreeCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:286
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:211
avfDecoder::avfDecoder
avfDecoder(const QString &file, DecoderFactory *d, AudioOutput *o)
Definition: avfdecoder.cpp:231
metaioavfcomment.h
metaiowavpack.h
AudioOutput::DecodeAudio
virtual int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
Utility routine.
Definition: audiooutput.cpp:594
avfDecoderFactory::extension
const QString & extension() const override
Definition: avfdecoder.cpp:598
Decoder::getURL
QString getURL(void) const
Definition: decoder.h:86
DecoderEvent::Decoding
static Type Decoding
Definition: decoder.h:47
uint
unsigned int uint
Definition: compat.h:141
VERBOSE_LEVEL_NONE
#define VERBOSE_LEVEL_NONE
Definition: mythlogging.h:13
ShoutCastMetaParser
Definition: avfdecoder.cpp:62
AudioOutput::AddData
virtual bool AddData(void *buffer, int len, int64_t timecode, int frames)=0
Add data to the audiobuffer for playback.
Decoder::setURL
void setURL(const QString &url)
Definition: decoder.h:78
DecoderEvent::Finished
static Type Finished
Definition: decoder.h:49
avfDecoderFactory::create
Decoder * create(const QString &file, AudioOutput *output, bool deletable) override
Definition: avfdecoder.cpp:609
Decoder::error
void error(const QString &e)
Definition: decoder.cpp:53
avfDecoder::m_audioDec
AVCodecContext * m_audioDec
Definition: avfdecoder.h:51
DecoderEvent::Stopped
static Type Stopped
Definition: decoder.h:48
myth_av_log
static void myth_av_log(void *ptr, int level, const char *fmt, va_list vl)
Definition: avfdecoder.cpp:175
MusicPlayer::getDecoderHandler
DecoderHandler * getDecoderHandler(void)
Definition: musicplayer.h:116
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
MusicMetadata::setArtist
void setArtist(const QString &lartist, const QString &lartist_sort=nullptr)
Definition: musicmetadata.h:128
AudioOutput::Reconfigure
virtual void Reconfigure(const AudioSettings &settings)=0
metaio.h
ShoutCastMetaParser::parseMeta
ShoutCastMetaMap parseMeta(const QString &mdata)
Definition: avfdecoder.cpp:140
avfDecoder::m_stat
int m_stat
Definition: avfdecoder.h:38
audiooutput.h
Decoder::setOutput
void setOutput(AudioOutput *o)
Definition: decoder.cpp:46
DecoderHandler::getMetadata
MusicMetadata & getMetadata()
Definition: decoderhandler.h:95
mythavutil.h
mythcontext.h
metaioid3.h
metaiomp4.h
avfDecoder::m_channels
int m_channels
Definition: avfdecoder.h:44
avfDecoder::seek
void seek(double pos) override
Definition: avfdecoder.cpp:395
avfDecoder::m_lastMetadata
QString m_lastMetadata
Definition: avfdecoder.h:57
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
avfDecoder::m_bitrate
long m_bitrate
Definition: avfdecoder.h:43
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:25
Decoder::output
AudioOutput * output()
Definition: decoder.h:76
MetaIO::kValidFileExtensions
static const QString kValidFileExtensions
Definition: metaio.h:173
output
#define output
Definition: synaesthesia.cpp:220
avfDecoder::~avfDecoder
~avfDecoder(void) override
Definition: avfdecoder.cpp:245
AudioOutput::PauseUntilBuffered
virtual void PauseUntilBuffered(void)=0
metaiooggvorbis.h
avfDecoder::checkMetatdata
void checkMetatdata(void)
Definition: avfdecoder.cpp:545
musicplayer.h