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 typedef QMap<QString,QString> ShoutCastMetaMap;
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_meta_format;
70  int m_meta_artist_pos {-1};
71  int m_meta_title_pos {-1};
72  int m_meta_album_pos {-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_meta_format = metaformat;
85 
86  m_meta_artist_pos = 0;
87  m_meta_title_pos = 0;
88  m_meta_album_pos = 0;
89 
90  int assign_index = 1;
91  int pos = 0;
92 
93  pos = m_meta_format.indexOf("%", pos);
94  while (pos >= 0)
95  {
96  pos++;
97 
98  QChar ch;
99 
100  if (pos < m_meta_format.length())
101  ch = m_meta_format.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_meta_artist_pos = assign_index;
111 
112  if (ch == 'b')
113  m_meta_album_pos = assign_index;
114 
115  if (ch == 't')
116  m_meta_title_pos = assign_index;
117 
118  assign_index++;
119  }
120  else
121  LOG(VB_GENERAL, LOG_ERR,
122  QString("ShoutCastMetaParser: malformed metaformat '%1'")
123  .arg(m_meta_format));
124 
125  pos = m_meta_format.indexOf("%", pos);
126  }
127 
128  m_meta_format.replace("%a", "(.*)");
129  m_meta_format.replace("%t", "(.*)");
130  m_meta_format.replace("%b", "(.*)");
131  m_meta_format.replace("%r", "(.*)");
132  m_meta_format.replace("%%", "%");
133 }
134 
136 {
137  ShoutCastMetaMap result;
138  int title_begin_pos = mdata.indexOf("StreamTitle='");
139 
140  if (title_begin_pos >= 0)
141  {
142  title_begin_pos += 13;
143  int title_end_pos = mdata.indexOf("';", title_begin_pos);
144  QString title = mdata.mid(title_begin_pos, title_end_pos - title_begin_pos);
145  QRegExp rx;
146  rx.setPattern(m_meta_format);
147  if (rx.indexIn(title) != -1)
148  {
149  LOG(VB_PLAYBACK, LOG_INFO, QString("ShoutCast: Meta : '%1'")
150  .arg(mdata));
151  LOG(VB_PLAYBACK, LOG_INFO,
152  QString("ShoutCast: Parsed as: '%1' by '%2'")
153  .arg(rx.cap(m_meta_title_pos))
154  .arg(rx.cap(m_meta_artist_pos)));
155 
156  if (m_meta_title_pos > 0)
157  result["title"] = rx.cap(m_meta_title_pos);
158 
159  if (m_meta_artist_pos > 0)
160  result["artist"] = rx.cap(m_meta_artist_pos);
161 
162  if (m_meta_album_pos > 0)
163  result["album"] = rx.cap(m_meta_album_pos);
164  }
165  }
166 
167  return result;
168 }
169 
170 static void myth_av_log(void *ptr, int level, const char* fmt, va_list vl)
171 {
172  if (VERBOSE_LEVEL_NONE)
173  return;
174 
175  static QString full_line("");
176  static const int msg_len = 255;
177  static QMutex string_lock;
178  uint64_t verbose_mask = VB_GENERAL;
179  LogLevel_t verbose_level = LOG_DEBUG;
180 
181  // determine mythtv debug level from av log level
182  switch (level)
183  {
184  case AV_LOG_PANIC:
185  verbose_level = LOG_EMERG;
186  break;
187  case AV_LOG_FATAL:
188  verbose_level = LOG_CRIT;
189  break;
190  case AV_LOG_ERROR:
191  verbose_level = LOG_ERR;
192  verbose_mask |= VB_LIBAV;
193  break;
194  case AV_LOG_DEBUG:
195  case AV_LOG_VERBOSE:
196  case AV_LOG_INFO:
197  verbose_level = LOG_DEBUG;
198  verbose_mask |= VB_LIBAV;
199  break;
200  case AV_LOG_WARNING:
201  verbose_mask |= VB_LIBAV;
202  break;
203  default:
204  return;
205  }
206 
207  if (!VERBOSE_LEVEL_CHECK(verbose_mask, verbose_level))
208  return;
209 
210  string_lock.lock();
211  if (full_line.isEmpty() && ptr) {
212  AVClass* avc = *(AVClass**)ptr;
213  full_line.sprintf("[%s @ %p] ", avc->item_name(ptr), avc);
214  }
215 
216  char str[msg_len+1];
217  int bytes = vsnprintf(str, msg_len+1, fmt, vl);
218 
219  // check for truncated messages and fix them
220  if (bytes > msg_len)
221  {
222  LOG(VB_GENERAL, LOG_WARNING,
223  QString("Libav log output truncated %1 of %2 bytes written")
224  .arg(msg_len).arg(bytes));
225  str[msg_len-1] = '\n';
226  }
227 
228  full_line += QString(str);
229  if (full_line.endsWith("\n"))
230  {
231  LOG(verbose_mask, verbose_level, full_line.trimmed());
232  full_line.truncate(0);
233  }
234  string_lock.unlock();
235 }
236 
238  Decoder(d, o)
239 {
240  MThread::setObjectName("avfDecoder");
241  setURL(file);
242 
245 
246  bool debug = VERBOSE_LEVEL_CHECK(VB_LIBAV, LOG_ANY);
247  av_log_set_level((debug) ? AV_LOG_DEBUG : AV_LOG_ERROR);
248  av_log_set_callback(myth_av_log);
249 }
250 
252 {
253  delete m_mdataTimer;
254 
255  if (m_inited)
256  deinit();
257 
258  if (m_outputBuffer)
259  av_freep(&m_outputBuffer);
260 
261  delete m_inputContext;
262 }
263 
265 {
266  m_userStop = true;
267 }
268 
270 {
271  m_inited = m_userStop = m_finish = false;
272  m_freq = m_bitrate = 0;
273  m_stat = m_channels = 0;
274  m_seekTime = -1.0;
275 
276  // give up if we dont have an audiooutput set
277  if (!output())
278  {
279  error("avfDecoder: initialise called with a NULL audiooutput");
280  return false;
281  }
282 
283  if (!m_outputBuffer)
284  {
285  error("avfDecoder: couldn't allocate memory");
286  return false;
287  }
288 
290 
291  delete m_inputContext;
293 
294  if (!m_inputContext->isOpen())
295  {
296  error(QString("Could not open url (%1)").arg(m_url));
297  deinit();
298  return false;
299  }
300 
301  // if this is a ice/shoutcast or MMS stream start polling for metadata changes and buffer status
302  if (getURL().startsWith("http://") || getURL().startsWith("mmsh://"))
303  {
304  m_mdataTimer = new QTimer;
305  m_mdataTimer->setSingleShot(false);
306  connect(m_mdataTimer, SIGNAL(timeout()), this, SLOT(checkMetatdata()));
307 
308  m_mdataTimer->start(500);
309 
310  // we don't get metadata updates for MMS streams so grab the metadata from the headers
311  if (getURL().startsWith("mmsh://"))
312  {
313  AVDictionaryEntry *tag = nullptr;
315 
316  tag = av_dict_get(m_inputContext->getContext()->metadata, "title", tag, AV_DICT_IGNORE_SUFFIX);
317  mdata.setTitle(tag->value);
318 
319  tag = av_dict_get(m_inputContext->getContext()->metadata, "artist", tag, AV_DICT_IGNORE_SUFFIX);
320  mdata.setArtist(tag->value);
321 
322  mdata.setAlbum("");
323  mdata.setLength(-1);
324 
326  dispatch(ev);
327  }
328  }
329 
330  // determine the stream format
331  // this also populates information needed for metadata
332  if (avformat_find_stream_info(m_inputContext->getContext(), nullptr) < 0)
333  {
334  error("Could not determine the stream format.");
335  deinit();
336  return false;
337  }
338 
339  // let FFmpeg finds the best audio stream (should only be one), also catter
340  // should the file/stream not be an audio one
341  AVCodec *codec;
342  int selTrack = av_find_best_stream(m_inputContext->getContext(), AVMEDIA_TYPE_AUDIO,
343  -1, -1, &codec, 0);
344 
345  if (selTrack < 0)
346  {
347  error(QString("Could not find audio stream."));
348  deinit();
349  return false;
350  }
351 
352  // Store the audio codec of the stream
354  (m_inputContext->getContext()->streams[selTrack]);
355 
356  // Store the input format of the context
358 
359  if (avcodec_open2(m_audioDec, codec, nullptr) < 0)
360  {
361  error(QString("Could not open audio codec: %1")
362  .arg(m_audioDec->codec_id));
363  deinit();
364  return false;
365  }
366 
367  m_freq = m_audioDec->sample_rate;
368  m_channels = m_audioDec->channels;
369 
370  if (m_channels <= 0)
371  {
372  error(QString("AVCodecContext tells us %1 channels are "
373  "available, this is bad, bailing.")
374  .arg(m_channels));
375  deinit();
376  return false;
377  }
378 
379  AudioFormat format =
381  m_audioDec->bits_per_raw_sample);
382  if (format == FORMAT_NONE)
383  {
384  error(QString("Error: Unsupported sample format: %1")
385  .arg(av_get_sample_fmt_name(m_audioDec->sample_fmt)));
386  deinit();
387  return false;
388  }
389 
390  const AudioSettings settings(format, m_audioDec->channels,
391  m_audioDec->codec_id,
392  m_audioDec->sample_rate, false);
393 
394  output()->Reconfigure(settings);
395  output()->SetSourceBitrate(m_audioDec->bit_rate);
396 
397  m_inited = true;
398  return true;
399 }
400 
401 void avfDecoder::seek(double pos)
402 {
404  m_inputContext->getContext()->pb->seekable)
405  {
406  m_seekTime = pos;
407  }
408 }
409 
411 {
412  m_inited = m_userStop = m_finish = false;
413  m_freq = m_bitrate = 0;
414  m_stat = m_channels = 0;
415  setOutput(nullptr);
416 
417  // Cleanup here
419  {
420  for (uint i = 0; i < m_inputContext->getContext()->nb_streams; i++)
421  {
422  AVStream *st = m_inputContext->getContext()->streams[i];
424  }
425  }
426 
427  m_audioDec = nullptr;
428  m_inputFormat = nullptr;
429 }
430 
432 {
433  RunProlog();
434  if (!m_inited)
435  {
436  RunEpilog();
437  return;
438  }
439 
440  AVPacket pkt, tmp_pkt;
441  memset(&pkt, 0, sizeof(AVPacket));
442  av_init_packet(&pkt);
443 
445  {
446  DecoderEvent e((DecoderEvent::Type) m_stat);
447  dispatch(e);
448  }
449 
450  av_read_play(m_inputContext->getContext());
451 
452  while (!m_finish && !m_userStop)
453  {
454  // Look to see if user has requested a seek
455  if (m_seekTime >= 0.0)
456  {
457  LOG(VB_GENERAL, LOG_INFO, QString("avfdecoder.o: seek time %1")
458  .arg(m_seekTime));
459 
460  if (av_seek_frame(m_inputContext->getContext(), -1,
461  (int64_t)(m_seekTime * AV_TIME_BASE), 0) < 0)
462  LOG(VB_GENERAL, LOG_ERR, "Error seeking");
463 
464  m_seekTime = -1.0;
465  }
466 
467  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
468  {
469  // Read a packet from the input context
470  int res = av_read_frame(m_inputContext->getContext(), &pkt);
471  if (res < 0)
472  {
473  if (res != AVERROR_EOF)
474  {
475  LOG(VB_GENERAL, LOG_ERR, QString("Read frame failed: %1").arg(res));
476  LOG(VB_FILE, LOG_ERR, ("... for file '" + m_url) + "'");
477  }
478 
479  m_finish = true;
480  break;
481  }
482 
483  av_init_packet(&tmp_pkt);
484  tmp_pkt.data = pkt.data;
485  tmp_pkt.size = pkt.size;
486 
487  while (tmp_pkt.size > 0 && !m_finish &&
488  !m_userStop && m_seekTime <= 0.0)
489  {
490  int data_size = 0;
491 
492  int ret = output()->DecodeAudio(m_audioDec,
494  data_size,
495  &tmp_pkt);
496 
497  if (ret < 0)
498  break;
499 
500  // Increment the output pointer and count
501  tmp_pkt.size -= ret;
502  tmp_pkt.data += ret;
503 
504  if (data_size <= 0)
505  continue;
506 
507  output()->AddData(m_outputBuffer, data_size, -1, 0);
508  }
509 
510  av_packet_unref(&pkt);
511 
512  // Wait until we need to decode or supply more samples
513  while (!m_finish && !m_userStop && m_seekTime <= 0.0)
514  {
515  int64_t buffered = output()->GetAudioBufferedTime();
516  // never go below 1s buffered
517  if (buffered < 1000)
518  break;
519  // wait
520  usleep((buffered - 1000) * 1000);
521  }
522  }
523  }
524 
525  if (m_userStop)
526  {
527  m_inited = false;
528  }
529  else
530  {
531  // Drain ao buffer, making sure we play all remaining audio samples
532  output()->Drain();
533  }
534 
535  if (m_finish)
537  else if (m_userStop)
539 
540  {
541  DecoderEvent e((DecoderEvent::Type) m_stat);
542  dispatch(e);
543  }
544 
545  deinit();
546  RunEpilog();
547 }
548 
550 {
551  uint8_t *pdata = nullptr;
552 
553  if (av_opt_get(m_inputContext->getContext(), "icy_metadata_packet", AV_OPT_SEARCH_CHILDREN, &pdata) >= 0)
554  {
555  QString s = QString::fromUtf8((const char*) pdata);
556 
557  if (m_lastMetadata != s)
558  {
559  m_lastMetadata = s;
560 
561  LOG(VB_PLAYBACK, LOG_INFO, QString("avfDecoder: shoutcast metadata changed - %1").arg(m_lastMetadata));
562 
565 
566  ShoutCastMetaMap meta_map = parser.parseMeta(m_lastMetadata);
567 
569  mdata.setTitle(meta_map["title"]);
570  mdata.setArtist(meta_map["artist"]);
571  mdata.setAlbum(meta_map["album"]);
572  mdata.setLength(-1);
573 
575  dispatch(ev);
576  }
577 
578  av_free(pdata);
579  }
580 
581  if (m_inputContext->getContext()->pb)
582  {
583  int available = (int) (m_inputContext->getContext()->pb->buf_end - m_inputContext->getContext()->pb->buffer);
584  int maxSize = m_inputContext->getContext()->pb->buffer_size;
586  dispatch(ev);
587  }
588 }
589 
590 bool avfDecoderFactory::supports(const QString &source) const
591 {
592  QStringList list = extension().split("|", QString::SkipEmptyParts);
593  for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
594  {
595  if (*it == source.right((*it).length()).toLower())
596  return true;
597  }
598 
599  return false;
600 }
601 
602 const QString &avfDecoderFactory::extension() const
603 {
605 }
606 
607 const QString &avfDecoderFactory::description() const
608 {
609  static QString desc(tr("Internal Decoder"));
610  return desc;
611 }
612 
613 Decoder *avfDecoderFactory::create(const QString &file, AudioOutput *output, bool deletable)
614 {
615  if (deletable)
616  return new avfDecoder(file, this, output);
617 
618  static avfDecoder *decoder = nullptr;
619  if (!decoder)
620  {
621  decoder = new avfDecoder(file, this, output);
622  }
623  else
624  {
625  decoder->setOutput(output);
626  }
627 
628  return decoder;
629 }
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
void deinit()
Definition: avfdecoder.cpp:410
long m_freq
Definition: avfdecoder.h:42
MusicPlayer * gPlayer
Definition: musicplayer.cpp:35
static Type Finished
Definition: decoder.h:49
virtual ~avfDecoder(void)
Definition: avfdecoder.cpp:251
static Type Decoding
Definition: decoder.h:47
virtual void Drain(void)=0
void setLength(int llength)
void freeCodecContext(const AVStream *)
Definition: mythavutil.cpp:431
AVCodecContext * m_audioDec
Definition: avfdecoder.h:51
avfDecoder(const QString &file, DecoderFactory *, AudioOutput *)
Definition: avfdecoder.cpp:237
MusicMetadata & getMetadata()
QString MetadataFormat(void)
unsigned int uint
Definition: compat.h:140
Events sent by the DecoderHandler and it's helper classes.
int m_stat
Definition: avfdecoder.h:38
QString m_lastMetadata
Definition: avfdecoder.h:56
void setObjectName(const QString &name)
Definition: mthread.cpp:249
const QString & description() const override
Definition: avfdecoder.cpp:607
long m_bitrate
Definition: avfdecoder.h:43
static const QString ValidFileExtensions
Definition: metaio.h:173
int m_channels
Definition: avfdecoder.h:44
QMap< QString, QString > ShoutCastMetaMap
Definition: avfdecoder.cpp:57
#define VERBOSE_LEVEL_NONE
Definition: mythlogging.h:22
DecoderHandler * getDecoderHandler(void)
Definition: musicplayer.h:116
void checkMetatdata(void)
Definition: avfdecoder.cpp:549
Decoder * create(const QString &, AudioOutput *, bool) override
Definition: avfdecoder.cpp:613
MythCodecMap * gCodecMap
This global variable contains the MythCodecMap instance for the app.
Definition: mythavutil.cpp:381
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
static const uint16_t * d
void setAlbum(const QString &lalbum, const QString &lalbum_sort=nullptr)
const QString & extension() const override
Definition: avfdecoder.cpp:602
static Type Stopped
Definition: decoder.h:48
void error(const QString &)
Definition: decoder.cpp:53
void setOutput(AudioOutput *)
Definition: decoder.cpp:46
virtual void SetSourceBitrate(int)
Definition: audiooutput.h:141
AVCodecContext * getCodecContext(const AVStream *, const AVCodec *pCodec=nullptr, bool nullCodec=false)
Definition: mythavutil.cpp:392
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:170
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:431
virtual void Reconfigure(const AudioSettings &settings)=0
static const int MAX_SIZE_BUFFER
MAX_SIZE_BUFFER is the maximum size of a buffer to be used with DecodeAudio.
Definition: audiooutput.h:192
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
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:77
bool m_userStop
Definition: avfdecoder.h:37
static Type BufferStatus
double m_seekTime
Definition: avfdecoder.h:45
QString getURL(void) const
Definition: decoder.h:87
void stop() override
Definition: avfdecoder.cpp:264
void av_free(void *ptr)
bool initialize() override
Definition: avfdecoder.cpp:269
QString m_url
Definition: decoder.h:101
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 supports(const QString &) const override
Definition: avfdecoder.cpp:590
bool m_finish
Definition: avfdecoder.h:41
void seek(double) override
Definition: avfdecoder.cpp:401
ShoutCastMetaMap parseMeta(const QString &mdata)
Definition: avfdecoder.cpp:135
void setURL(const QString &url)
Definition: decoder.h:79
#define output
virtual int64_t GetAudioBufferedTime(void)
report amount of audio buffered in milliseconds.
Definition: audiooutput.h:139