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 constexpr int kMsgLen = 255;
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.sprintf("[%s @ %p] ", avc->item_name(ptr), avc);
216  }
217 
218  char str[kMsgLen+1];
219  int bytes = vsnprintf(str, kMsgLen+1, fmt, vl);
220 
221  // check for truncated messages and fix them
222  if (bytes > kMsgLen)
223  {
224  LOG(VB_GENERAL, LOG_WARNING,
225  QString("Libav log output truncated %1 of %2 bytes written")
226  .arg(kMsgLen).arg(bytes));
227  str[kMsgLen-1] = '\n';
228  }
229 
230  s_fullLine += QString(str);
231  if (s_fullLine.endsWith("\n"))
232  {
233  LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
234  s_fullLine.truncate(0);
235  }
236  s_stringLock.unlock();
237 }
238 
240  Decoder(d, o)
241 {
242  MThread::setObjectName("avfDecoder");
243  setURL(file);
244 
247 
248  bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY);
249  av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR);
250  av_log_set_callback(myth_av_log);
251 }
252 
254 {
255  delete m_mdataTimer;
256 
257  if (m_inited)
258  deinit();
259 
260  if (m_outputBuffer)
261  av_freep(&m_outputBuffer);
262 
263  delete m_inputContext;
264 }
265 
267 {
268  m_userStop = true;
269 }
270 
272 {
273  m_inited = m_userStop = m_finish = false;
274  m_freq = m_bitrate = 0;
275  m_stat = m_channels = 0;
276  m_seekTime = -1.0;
277 
278  // give up if we dont have an audiooutput set
279  if (!output())
280  {
281  error("avfDecoder: initialise called with a NULL audiooutput");
282  return false;
283  }
284 
285  if (!m_outputBuffer)
286  {
287  error("avfDecoder: couldn't allocate memory");
288  return false;
289  }
290 
292 
293  delete m_inputContext;
295 
296  if (!m_inputContext->isOpen())
297  {
298  error(QString("Could not open url (%1)").arg(m_url));
299  deinit();
300  return false;
301  }
302 
303  // if this is a ice/shoutcast or MMS stream start polling for metadata changes and buffer status
304  if (getURL().startsWith("http://") || getURL().startsWith("mmsh://"))
305  {
306  m_mdataTimer = new QTimer;
307  m_mdataTimer->setSingleShot(false);
308  connect(m_mdataTimer, SIGNAL(timeout()), this, SLOT(checkMetatdata()));
309 
310  m_mdataTimer->start(500);
311 
312  // we don't get metadata updates for MMS streams so grab the metadata from the headers
313  if (getURL().startsWith("mmsh://"))
314  {
315  AVDictionaryEntry *tag = nullptr;
317 
318  tag = av_dict_get(m_inputContext->getContext()->metadata, "title", tag, AV_DICT_IGNORE_SUFFIX);
319  mdata.setTitle(tag->value);
320 
321  tag = av_dict_get(m_inputContext->getContext()->metadata, "artist", tag, AV_DICT_IGNORE_SUFFIX);
322  mdata.setArtist(tag->value);
323 
324  mdata.setAlbum("");
325  mdata.setLength(-1);
326 
328  dispatch(ev);
329  }
330  }
331 
332  // determine the stream format
333  // this also populates information needed for metadata
334  if (avformat_find_stream_info(m_inputContext->getContext(), nullptr) < 0)
335  {
336  error("Could not determine the stream format.");
337  deinit();
338  return false;
339  }
340 
341  // let FFmpeg finds the best audio stream (should only be one), also catter
342  // should the file/stream not be an audio one
343  AVCodec *codec = nullptr;
344  int selTrack = av_find_best_stream(m_inputContext->getContext(), AVMEDIA_TYPE_AUDIO,
345  -1, -1, &codec, 0);
346 
347  if (selTrack < 0)
348  {
349  error(QString("Could not find audio stream."));
350  deinit();
351  return false;
352  }
353 
354  // Store the audio codec of the stream
356  (m_inputContext->getContext()->streams[selTrack]);
357 
358  // Store the input format of the context
360 
361  if (avcodec_open2(m_audioDec, codec, nullptr) < 0)
362  {
363  error(QString("Could not open audio codec: %1")
364  .arg(m_audioDec->codec_id));
365  deinit();
366  return false;
367  }
368 
369  m_freq = m_audioDec->sample_rate;
370  m_channels = m_audioDec->channels;
371 
372  if (m_channels <= 0)
373  {
374  error(QString("AVCodecContext tells us %1 channels are "
375  "available, this is bad, bailing.")
376  .arg(m_channels));
377  deinit();
378  return false;
379  }
380 
381  AudioFormat format =
383  m_audioDec->bits_per_raw_sample);
384  if (format == FORMAT_NONE)
385  {
386  error(QString("Error: Unsupported sample format: %1")
387  .arg(av_get_sample_fmt_name(m_audioDec->sample_fmt)));
388  deinit();
389  return false;
390  }
391 
392  const AudioSettings settings(format, m_audioDec->channels,
393  m_audioDec->codec_id,
394  m_audioDec->sample_rate, false);
395 
396  output()->Reconfigure(settings);
397  output()->SetSourceBitrate(m_audioDec->bit_rate);
398 
399  m_inited = true;
400  return true;
401 }
402 
403 void avfDecoder::seek(double pos)
404 {
406  m_inputContext->getContext()->pb->seekable)
407  {
408  m_seekTime = pos;
409  }
410 }
411 
413 {
414  m_inited = m_userStop = m_finish = false;
415  m_freq = m_bitrate = 0;
416  m_stat = m_channels = 0;
417  setOutput(nullptr);
418 
419  // Cleanup here
421  {
422  for (uint i = 0; i < m_inputContext->getContext()->nb_streams; i++)
423  {
424  AVStream *st = m_inputContext->getContext()->streams[i];
426  }
427  }
428 
429  m_audioDec = nullptr;
430  m_inputFormat = nullptr;
431 }
432 
434 {
435  RunProlog();
436  if (!m_inited)
437  {
438  RunEpilog();
439  return;
440  }
441 
442  AVPacket pkt;
443  AVPacket tmp_pkt;
444  memset(&pkt, 0, sizeof(AVPacket));
445  av_init_packet(&pkt);
446 
448  {
449  DecoderEvent e((DecoderEvent::Type) m_stat);
450  dispatch(e);
451  }
452 
453  av_read_play(m_inputContext->getContext());
454 
455  while (!m_finish && !m_userStop)
456  {
457  // Look to see if user has requested a seek
458  if (m_seekTime >= 0.0)
459  {
460  LOG(VB_GENERAL, LOG_INFO, QString("avfdecoder.o: seek time %1")
461  .arg(m_seekTime));
462 
463  if (av_seek_frame(m_inputContext->getContext(), -1,
464  (int64_t)(m_seekTime * AV_TIME_BASE), 0) < 0)
465  LOG(VB_GENERAL, LOG_ERR, "Error seeking");
466 
467  m_seekTime = -1.0;
468  }
469 
470  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
471  {
472  // Read a packet from the input context
473  int res = av_read_frame(m_inputContext->getContext(), &pkt);
474  if (res < 0)
475  {
476  if (res != AVERROR_EOF)
477  {
478  LOG(VB_GENERAL, LOG_ERR, QString("Read frame failed: %1").arg(res));
479  LOG(VB_FILE, LOG_ERR, ("... for file '" + m_url) + "'");
480  }
481 
482  m_finish = true;
483  break;
484  }
485 
486  av_init_packet(&tmp_pkt);
487  tmp_pkt.data = pkt.data;
488  tmp_pkt.size = pkt.size;
489 
490  while (tmp_pkt.size > 0 && !m_finish &&
491  !m_userStop && m_seekTime <= 0.0)
492  {
493  int data_size = 0;
494 
495  int ret = output()->DecodeAudio(m_audioDec,
497  data_size,
498  &tmp_pkt);
499 
500  if (ret < 0)
501  break;
502 
503  // Increment the output pointer and count
504  tmp_pkt.size -= ret;
505  tmp_pkt.data += ret;
506 
507  if (data_size <= 0)
508  continue;
509 
510  output()->AddData(m_outputBuffer, data_size, -1, 0);
511  }
512 
513  av_packet_unref(&pkt);
514 
515  // Wait until we need to decode or supply more samples
516  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
517  {
518  int64_t buffered = output()->GetAudioBufferedTime();
519  // never go below 1s buffered
520  if (buffered < 1000)
521  break;
522  // wait
523  usleep((buffered - 1000) * 1000);
524  }
525  }
526  }
527 
528  if (m_userStop)
529  {
530  m_inited = false;
531  }
532  else
533  {
534  // Drain ao buffer, making sure we play all remaining audio samples
535  output()->Drain();
536  }
537 
538  if (m_finish)
540  else if (m_userStop)
542 
543  {
544  DecoderEvent e((DecoderEvent::Type) m_stat);
545  dispatch(e);
546  }
547 
548  deinit();
549  RunEpilog();
550 }
551 
553 {
554  uint8_t *pdata = nullptr;
555 
556  if (av_opt_get(m_inputContext->getContext(), "icy_metadata_packet", AV_OPT_SEARCH_CHILDREN, &pdata) >= 0)
557  {
558  QString s = QString::fromUtf8((const char*) pdata);
559 
560  if (m_lastMetadata != s)
561  {
562  m_lastMetadata = s;
563 
564  LOG(VB_PLAYBACK, LOG_INFO, QString("avfDecoder: shoutcast metadata changed - %1").arg(m_lastMetadata));
565 
568 
569  ShoutCastMetaMap meta_map = parser.parseMeta(m_lastMetadata);
570 
572  mdata.setTitle(meta_map["title"]);
573  mdata.setArtist(meta_map["artist"]);
574  mdata.setAlbum(meta_map["album"]);
575  mdata.setLength(-1);
576 
578  dispatch(ev);
579  }
580 
581  av_free(pdata);
582  }
583 
584  if (m_inputContext->getContext()->pb)
585  {
586  int available = (int) (m_inputContext->getContext()->pb->buf_end - m_inputContext->getContext()->pb->buffer);
587  int maxSize = m_inputContext->getContext()->pb->buffer_size;
589  dispatch(ev);
590  }
591 }
592 
593 bool avfDecoderFactory::supports(const QString &source) const
594 {
595  QStringList list = extension().split("|", QString::SkipEmptyParts);
596  for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
597  {
598  if (*it == source.right((*it).length()).toLower())
599  return true;
600  }
601 
602  return false;
603 }
604 
605 const QString &avfDecoderFactory::extension() const
606 {
608 }
609 
610 const QString &avfDecoderFactory::description() const
611 {
612  static QString s_desc(tr("Internal Decoder"));
613  return s_desc;
614 }
615 
616 Decoder *avfDecoderFactory::create(const QString &file, AudioOutput *output, bool deletable)
617 {
618  if (deletable)
619  return new avfDecoder(file, this, output);
620 
621  static avfDecoder *s_decoder = nullptr;
622  if (!s_decoder)
623  {
624  s_decoder = new avfDecoder(file, this, output);
625  }
626  else
627  {
628  s_decoder->setOutput(output);
629  }
630 
631  return s_decoder;
632 }
QMap< QString, QString > ShoutCastMetaMap
Definition: avfdecoder.cpp:57
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
void deinit()
Definition: avfdecoder.cpp:412
long m_freq
Definition: avfdecoder.h:42
static const int kMaxSizeBuffer
kMaxSizeBuffer is the maximum size of a buffer to be used with DecodeAudio
Definition: audiooutput.h:194
MusicPlayer * gPlayer
Definition: musicplayer.cpp:35
static Type Finished
Definition: decoder.h:48
avfDecoder(const QString &file, DecoderFactory *d, AudioOutput *o)
Definition: avfdecoder.cpp:239
static Type Decoding
Definition: decoder.h:46
virtual void Drain(void)=0
void setLength(int llength)
AVCodecContext * m_audioDec
Definition: avfdecoder.h:51
MusicMetadata & getMetadata()
QString MetadataFormat(void)
Events sent by the DecoderHandler and it's helper classes.
void setOutput(AudioOutput *o)
Definition: decoder.cpp:46
int m_stat
Definition: avfdecoder.h:38
void freeCodecContext(const AVStream *stream)
Definition: mythavutil.cpp:557
QString m_lastMetadata
Definition: avfdecoder.h:56
void setObjectName(const QString &name)
Definition: mthread.cpp:249
const QString & description() const override
Definition: avfdecoder.cpp:610
long m_bitrate
Definition: avfdecoder.h:43
static const QString kValidFileExtensions
Definition: metaio.h:173
bool supports(const QString &source) const override
Definition: avfdecoder.cpp:593
~avfDecoder(void) override
Definition: avfdecoder.cpp:253
int m_channels
Definition: avfdecoder.h:44
void seek(double pos) override
Definition: avfdecoder.cpp:403
#define VERBOSE_LEVEL_NONE
Definition: mythlogging.h:22
DecoderHandler * getDecoderHandler(void)
Definition: musicplayer.h:116
void checkMetatdata(void)
Definition: avfdecoder.cpp:552
MythCodecMap * gCodecMap
This global variable contains the MythCodecMap instance for the app.
Definition: mythavutil.cpp:508
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:24
bool m_inited
Definition: avfdecoder.h:36
AVCodecContext * getCodecContext(const AVStream *stream, const AVCodec *pCodec=nullptr, bool nullCodec=false)
Definition: mythavutil.cpp:515
static const uint16_t * d
void setAlbum(const QString &lalbum, const QString &lalbum_sort=nullptr)
const QString & extension() const override
Definition: avfdecoder.cpp:605
static Type Stopped
Definition: decoder.h:47
unsigned int uint
Definition: compat.h:140
virtual void SetSourceBitrate(int)
Definition: audiooutput.h:143
virtual int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
Utility routine.
void * av_malloc(unsigned int size)
void setTitle(const QString &ltitle, const QString &ltitle_sort=nullptr)
static void myth_av_log(void *ptr, int level, const char *fmt, va_list vl)
Definition: avfdecoder.cpp:172
void setArtist(const QString &lartist, const QString &lartist_sort=nullptr)
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:433
virtual void Reconfigure(const AudioSettings &settings)=0
virtual bool AddData(void *buffer, int len, int64_t timecode, int frames)=0
Add data to the audiobuffer for playback.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
Decoder * create(const QString &file, AudioOutput *output, bool deletable) override
Definition: avfdecoder.cpp:616
AVInputFormat * m_inputFormat
Definition: avfdecoder.h:49
VERBOSE_PREAMBLE Most debug(nodatabase, notimestamp, noextra)") VERBOSE_MAP(VB_GENERAL
uint8_t * m_outputBuffer
Definition: avfdecoder.h:39
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:202
AudioOutput * output()
Definition: decoder.h:76
bool m_userStop
Definition: avfdecoder.h:37
static Type BufferStatus
double m_seekTime
Definition: avfdecoder.h:45
QString getURL(void) const
Definition: decoder.h:86
void stop() override
Definition: avfdecoder.cpp:266
void av_free(void *ptr)
bool initialize() override
Definition: avfdecoder.cpp:271
QString m_url
Definition: decoder.h:100
static void usleep(unsigned long time)
Definition: mthread.cpp:348
QTimer * m_mdataTimer
Definition: avfdecoder.h:55
RemoteAVFormatContext * m_inputContext
Definition: avfdecoder.h:50
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
virtual void PauseUntilBuffered(void)=0
void setMetaFormat(const QString &metaformat)
Definition: avfdecoder.cpp:75
bool m_finish
Definition: avfdecoder.h:41
void error(const QString &e)
Definition: decoder.cpp:53
ShoutCastMetaMap parseMeta(const QString &mdata)
Definition: avfdecoder.cpp:137
void setURL(const QString &url)
Definition: decoder.h:78
#define output
virtual int64_t GetAudioBufferedTime(void)
report amount of audio buffered in milliseconds.
Definition: audiooutput.h:141