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