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