MythTV  master
avformatdecoder.cpp
Go to the documentation of this file.
1 #include "avformatdecoder.h"
2 
3 #include <unistd.h>
4 
5 // C++ headers
6 #include <algorithm>
7 #include <array>
8 #include <cmath>
9 #include <cstdint>
10 #include <cstring>
11 #include <iostream>
12 #include <set>
13 
14 extern "C" {
15 #include "libavutil/avutil.h"
16 #include "libavutil/error.h"
17 #include "libavutil/intreadwrite.h" // for AV_RB32 and AV_RB24
18 #include "libavutil/log.h"
19 #include "libavutil/opt.h"
20 #include "libavcodec/avcodec.h"
21 #include "libavformat/avformat.h"
22 #include "libavformat/avio.h"
23 #include "libswscale/swscale.h"
24 #include "libavutil/stereo3d.h"
25 #include "libavutil/imgutils.h"
26 #include "libavutil/display.h"
27 }
28 
29 #ifdef USING_MEDIACODEC // Android
30 extern "C" {
31 #include "libavcodec/jni.h"
32 }
33 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
34 #include <QtAndroidExtras>
35 #else
36 #include <QJniEnvironment>
37 #define QAndroidJniEnvironment QJniEnvironment
38 #endif
39 #endif // Android
40 
41 // regardless of building with V4L2 or not, enable IVTV VBI data
42 // from <linux/videodev2.h> under SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause)
43 /*
44  * V4L2_MPEG_STREAM_VBI_FMT_IVTV:
45  *
46  * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an
47  * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI
48  * data
49  *
50  * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header
51  * definitions are not included here. See the MPEG-2 specifications for details
52  * on these headers.
53  */
54 
55 /* Line type IDs */
56 enum V4L2_MPEG_LINE_TYPES : std::uint8_t {
61 };
62 // comments for each ID from ivtv_myth.h
63 
64 #include <QFileInfo>
65 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
66 #include <QTextCodec>
67 #else
68 #include <QStringDecoder>
69 #endif // Qt 6
70 
71 #ifdef _WIN32
72 # undef mkdir
73 #endif
74 
75 // MythTV headers
78 #include "libmyth/mythaverror.h"
79 #include "libmyth/mythavframe.h"
80 #include "libmythbase/iso639.h"
81 #include "libmythbase/lcddevice.h"
82 #include "libmythbase/mythchrono.h"
83 #include "libmythbase/mythconfig.h"
85 #include "libmythbase/mythdate.h"
86 #include "libmythbase/mythdbcon.h"
88 #include "libmythbase/stringutil.h"
89 #include "libmythui/mythuihelper.h"
90 
91 #include "mythtvexp.h"
92 
93 #include "Bluray/mythbdbuffer.h"
94 #include "DVD/mythdvdbuffer.h"
95 #include "captions/cc608decoder.h"
96 #include "captions/cc708decoder.h"
99 #include "io/mythmediabuffer.h"
100 #include "mheg/interactivetv.h"
101 #include "mpeg/atscdescriptors.h"
102 #include "mpeg/dvbdescriptors.h"
103 #include "mpeg/mpegtables.h"
104 #include "bytereader.h"
105 #include "mythavutil.h"
106 #include "mythframe.h"
107 #include "mythhdrvideometadata.h"
108 #include "mythvideoprofile.h"
109 #include "remoteencoder.h"
110 
111 using namespace std::string_view_literals;
112 
113 #define LOC QString("AFD: ")
114 
115 // Maximum number of sequential invalid data packet errors before we try
116 // switching to software decoder. Packet errors are often seen when using
117 // hardware contexts and, for example, seeking. Hence this needs to be high and
118 // is probably best removed as it is treating the symptoms and not the cause.
119 // See also comment in MythCodecMap::freeCodecContext re trying to free an
120 // active hardware context when it is errored.
121 static constexpr int SEQ_PKT_ERR_MAX { 50 };
122 
123 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
124 static constexpr int16_t kMaxVideoQueueSize = 220;
125 #else
126 static constexpr ssize_t kMaxVideoQueueSize = 220;
127 #endif
128 
129 static bool silence_ffmpeg_logging = false;
130 
131 static QSize get_video_dim(const AVCodecContext &ctx)
132 {
133  return {ctx.width >> ctx.lowres, ctx.height >> ctx.lowres};
134 }
135 static float get_aspect(const AVCodecContext &ctx)
136 {
137  float aspect_ratio = 0.0F;
138 
139  if (ctx.sample_aspect_ratio.num && ctx.height)
140  {
141  aspect_ratio = av_q2d(ctx.sample_aspect_ratio) *
142  static_cast<double>(ctx.width);
143  aspect_ratio /= (float) ctx.height;
144  }
145 
146  if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
147  {
148  if (ctx.height)
149  aspect_ratio = (float)ctx.width / (float)ctx.height;
150  else
151  aspect_ratio = 4.0F / 3.0F;
152  }
153 
154  return aspect_ratio;
155 }
156 static float get_aspect(AVCParser &p)
157 {
158  static constexpr float kDefaultAspect = 4.0F / 3.0F;
159  int asp = p.aspectRatio();
160  switch (asp)
161  {
162  case 0: return kDefaultAspect;
163  case 2: return 4.0F / 3.0F;
164  case 3: return 16.0F / 9.0F;
165  case 4: return 2.21F;
166  default: break;
167  }
168 
169  float aspect_ratio = asp * 0.000001F;
170  if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
171  {
172  if (p.pictureHeight() && p.pictureWidth())
173  {
174  aspect_ratio =
175  (float) p.pictureWidth() /(float) p.pictureHeight();
176  }
177  else
178  {
179  aspect_ratio = kDefaultAspect;
180  }
181  }
182  return aspect_ratio;
183 }
184 
185 
186 int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags);
187 
188 // currently unused
189 //static int determinable_frame_size(struct AVCodecContext *avctx)
190 //{
191 // if (/*avctx->codec_id == AV_CODEC_ID_AAC ||*/
192 // avctx->codec_id == AV_CODEC_ID_MP1 ||
193 // avctx->codec_id == AV_CODEC_ID_MP2 ||
194 // avctx->codec_id == AV_CODEC_ID_MP3/* ||
195 // avctx->codec_id == AV_CODEC_ID_CELT*/)
196 // return 1;
197 // return 0;
198 //}
199 
200 #define FAIL(errmsg) do { \
201  LOG(VB_PLAYBACK, LOG_INFO, LOC + (errmsg)); \
202  return false; \
203 } while (false)
204 
210 static bool StreamHasRequiredParameters(AVCodecContext *Context, AVStream *Stream)
211 {
212  switch (Stream->codecpar->codec_type)
213  {
214  // We fail on video first as this is generally the most serious error
215  // and if we have video, we usually have everything else
216  case AVMEDIA_TYPE_VIDEO:
217  if (!Context)
218  FAIL("No codec for video stream");
219  if (!Stream->codecpar->width || !Stream->codecpar->height)
220  FAIL("Unspecified video size");
221  if (Stream->codecpar->format == AV_PIX_FMT_NONE)
222  FAIL("Unspecified video pixel format");
223  // The proprietary RealVideo codecs are not used for TV broadcast
224  // and codec_info_nb_frames was moved to FFStream as it is an internal, private value.
225  //if (Context->codec_id == AV_CODEC_ID_RV30 || Context->codec_id == AV_CODEC_ID_RV40)
226  // if (!Stream->sample_aspect_ratio.num && !Context->sample_aspect_ratio.num && !Stream->codec_info_nb_frames)
227  // FAIL("No frame in rv30/40 and no sar");
228  break;
229  case AVMEDIA_TYPE_AUDIO:
230  if (!Context)
231  FAIL("No codec for audio stream");
232 
233  // These checks are currently disabled as they continually fail but
234  // codec initialisation is fine - which just delays live tv startup.
235  // The worst offender appears to be audio description channel...
236 
237  //if (!Stream->codecpar->frame_size && determinable_frame_size(avctx))
238  // FAIL("Unspecified audio frame size");
239  //if (Stream->codecpar->format == AV_SAMPLE_FMT_NONE)
240  // FAIL("Unspecified audio sample format");
241  //if (!Stream->codecpar->sample_rate)
242  // FAIL("Unspecified audio sample rate");
243  //if (!Stream->codecpar->channels)
244  // FAIL("Unspecified number of audio channels");
245  // if (!Stream->internal->nb_decoded_frames && Context->codec_id == AV_CODEC_ID_DTS)
246  // FAIL("No decodable DTS frames");
247  break;
248 
249  case AVMEDIA_TYPE_SUBTITLE:
250  if (Stream->codecpar->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !Stream->codecpar->width)
251  FAIL("Unspecified subtitle size");
252  break;
253  case AVMEDIA_TYPE_DATA:
254  if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
255  return true;
256  break;
257  default:
258  break;
259  }
260 
261  if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
262  FAIL("Unknown codec");
263  return true;
264 }
265 
266 static void myth_av_log(void *ptr, int level, const char* fmt, va_list vl)
267 {
269  return;
270 
271  if (VERBOSE_LEVEL_NONE())
272  return;
273 
274  static QString s_fullLine("");
275  static QMutex s_stringLock;
276  uint64_t verbose_mask = VB_LIBAV;
277  LogLevel_t verbose_level = LOG_EMERG;
278 
279  // determine mythtv debug level from av log level
280  switch (level)
281  {
282  case AV_LOG_PANIC:
283  verbose_level = LOG_EMERG;
284  verbose_mask |= VB_GENERAL;
285  break;
286  case AV_LOG_FATAL:
287  verbose_level = LOG_CRIT;
288  verbose_mask |= VB_GENERAL;
289  break;
290  case AV_LOG_ERROR:
291  verbose_level = LOG_ERR;
292  break;
293  case AV_LOG_WARNING:
294  verbose_level = LOG_WARNING;
295  break;
296  case AV_LOG_INFO:
297  verbose_level = LOG_INFO;
298  break;
299  case AV_LOG_VERBOSE:
300  case AV_LOG_DEBUG:
301  verbose_level = LOG_DEBUG;
302  break;
303  case AV_LOG_TRACE:
304  verbose_level = LOG_TRACE;
305  break;
306  default:
307  return;
308  }
309 
310  if (!VERBOSE_LEVEL_CHECK(verbose_mask, verbose_level))
311  return;
312 
313  s_stringLock.lock();
314  if (s_fullLine.isEmpty() && ptr) {
315  AVClass* avc = *(AVClass**)ptr;
316  s_fullLine = QString("[%1 @ %2] ")
317  .arg(avc->item_name(ptr))
318  .arg((quintptr)avc, QT_POINTER_SIZE * 2, 16, QChar('0'));
319  }
320 
321  s_fullLine += QString::vasprintf(fmt, vl);
322  if (s_fullLine.endsWith("\n"))
323  {
324  LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
325  s_fullLine.truncate(0);
326  }
327  s_stringLock.unlock();
328 }
329 
330 static int get_canonical_lang(const char *lang_cstr)
331 {
332  if (lang_cstr[0] == '\0' || lang_cstr[1] == '\0')
333  {
334  return iso639_str3_to_key("und");
335  }
336  if (lang_cstr[2] == '\0')
337  {
338  QString tmp2 = lang_cstr;
339  QString tmp3 = iso639_str2_to_str3(tmp2);
340  int lang = iso639_str3_to_key(tmp3);
341  return iso639_key_to_canonical_key(lang);
342  }
343  int lang = iso639_str3_to_key(lang_cstr);
344  return iso639_key_to_canonical_key(lang);
345 }
346 
352 static const char* AVMediaTypeToString(enum AVMediaType codec_type)
353 {
354  switch (codec_type)
355  {
356  case AVMEDIA_TYPE_UNKNOWN: return "Unknown";
357  case AVMEDIA_TYPE_VIDEO: return "Video";
358  case AVMEDIA_TYPE_AUDIO: return "Audio";
359  case AVMEDIA_TYPE_DATA: return "Data";
360  case AVMEDIA_TYPE_SUBTITLE: return "Subtitle";
361  case AVMEDIA_TYPE_ATTACHMENT: return "Attachment";
362  default: return "Invalid Codec Type";
363  }
364 }
365 
367  const ProgramInfo &pginfo,
368  PlayerFlags flags)
369  : DecoderBase(parent, pginfo),
370  m_isDbIgnored(gCoreContext->IsDatabaseIgnored()),
371  m_avcParser(new AVCParser()),
372  m_playerFlags(flags),
373  // Closed Caption & Teletext decoders
374  m_ccd608(new CC608Decoder(parent->GetCC608Reader())),
375  m_ccd708(new CC708Decoder(parent->GetCC708Reader())),
376  m_ttd(new TeletextDecoder(parent->GetTeletextReader())),
377  m_itv(parent->GetInteractiveTV()),
378  m_audioSamples((uint8_t *)av_mallocz(AudioOutput::kMaxSizeBuffer))
379 {
380  // this will be deleted and recreated once decoder is set up
382 
384 
385  av_log_set_callback(myth_av_log);
386 
387  m_audioIn.m_sampleSize = -32;// force SetupAudioStream to run once
388 
390  m_audioReadAhead = gCoreContext->GetDurSetting<std::chrono::milliseconds>("AudioReadAhead", 100ms);
391 
392  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("PlayerFlags: 0x%1, AudioReadAhead: %2 msec")
393  .arg(m_playerFlags, 0, 16).arg(m_audioReadAhead.count()));
394 }
395 
397 {
398  while (!m_storedPackets.isEmpty())
399  {
400  AVPacket *pkt = m_storedPackets.takeFirst();
401  av_packet_free(&pkt);
402  }
403 
404  CloseContext();
405  delete m_ccd608;
406  delete m_ccd708;
407  delete m_ttd;
408  delete m_avcParser;
409  delete m_mythCodecCtx;
410 
411  sws_freeContext(m_swsCtx);
412 
413  av_freep(reinterpret_cast<void*>(&m_audioSamples));
414 
415  delete m_avfRingBuffer;
416 
417  if (LCD *lcd = LCD::Get())
418  {
419  lcd->setAudioFormatLEDs(AUDIO_AC3, false);
420  lcd->setVideoFormatLEDs(VIDEO_MPG, false);
421  lcd->setVariousLEDs(VARIOUS_HDTV, false);
422  lcd->setVariousLEDs(VARIOUS_SPDIF, false);
423  lcd->setSpeakerLEDs(SPEAKER_71, false); // should clear any and all speaker LEDs
424  }
425 }
426 
428 {
429  return &m_codecMap;
430 }
431 
433 {
434  if (m_ic)
435  {
436  m_avCodecLock.lock();
437  for (uint i = 0; i < m_ic->nb_streams; i++)
438  {
439  AVStream *st = m_ic->streams[i];
441  }
442  m_avCodecLock.unlock();
443  }
444 }
445 
447 {
448  if (m_ic)
449  {
450  CloseCodecs();
451 
452  delete m_avfRingBuffer;
453  m_avfRingBuffer = nullptr;
454  m_ic->pb = nullptr;
455  avformat_close_input(&m_ic);
456  m_ic = nullptr;
457  }
458  m_avcParser->Reset();
459 }
460 
461 static int64_t lsb3full(int64_t lsb, int64_t base_ts, int lsb_bits)
462 {
463  int64_t mask = (lsb_bits < 64) ? (1LL<<lsb_bits)-1 : -1LL;
464  return ((lsb - base_ts)&mask);
465 }
466 
467 std::chrono::milliseconds AvFormatDecoder::NormalizeVideoTimecode(std::chrono::milliseconds timecode)
468 {
469  int64_t start_pts = 0;
470 
471  AVStream *st = nullptr;
472  for (uint i = 0; i < m_ic->nb_streams; i++)
473  {
474  AVStream *st1 = m_ic->streams[i];
475  if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
476  {
477  st = st1;
478  break;
479  }
480  }
481  if (!st)
482  return 0ms;
483 
484  if (m_ic->start_time != AV_NOPTS_VALUE)
485  {
486  start_pts = av_rescale(m_ic->start_time,
487  st->time_base.den,
488  AV_TIME_BASE * (int64_t)st->time_base.num);
489  }
490 
491  int64_t pts = av_rescale(timecode.count() / 1000.0,
492  st->time_base.den,
493  st->time_base.num);
494 
495  // adjust for start time and wrap
496  pts = lsb3full(pts, start_pts, st->pts_wrap_bits);
497 
498  return millisecondsFromFloat(av_q2d(st->time_base) * pts * 1000);
499 }
500 
501 std::chrono::milliseconds AvFormatDecoder::NormalizeVideoTimecode(AVStream *st,
502  std::chrono::milliseconds timecode)
503 {
504  int64_t start_pts = 0;
505 
506  if (m_ic->start_time != AV_NOPTS_VALUE)
507  {
508  start_pts = av_rescale(m_ic->start_time,
509  st->time_base.den,
510  AV_TIME_BASE * (int64_t)st->time_base.num);
511  }
512 
513  int64_t pts = av_rescale(timecode.count() / 1000.0,
514  st->time_base.den,
515  st->time_base.num);
516 
517  // adjust for start time and wrap
518  pts = lsb3full(pts, start_pts, st->pts_wrap_bits);
519 
520  return millisecondsFromFloat(av_q2d(st->time_base) * pts * 1000);
521 }
522 
524 {
525  if (m_ic && m_ic->nb_chapters > 1)
526  return m_ic->nb_chapters;
527  return 0;
528 }
529 
530 void AvFormatDecoder::GetChapterTimes(QList<std::chrono::seconds> &times)
531 {
532  int total = GetNumChapters();
533  if (!total)
534  return;
535 
536  for (int i = 0; i < total; i++)
537  {
538  int num = m_ic->chapters[i]->time_base.num;
539  int den = m_ic->chapters[i]->time_base.den;
540  int64_t start = m_ic->chapters[i]->start;
541  long double total_secs = (long double)start * (long double)num /
542  (long double)den;
543  times.push_back(std::chrono::seconds((long long)total_secs));
544  }
545 }
546 
547 int AvFormatDecoder::GetCurrentChapter(long long framesPlayed)
548 {
549  if (!GetNumChapters())
550  return 0;
551 
552  for (int i = (m_ic->nb_chapters - 1); i > -1 ; i--)
553  {
554  int num = m_ic->chapters[i]->time_base.num;
555  int den = m_ic->chapters[i]->time_base.den;
556  int64_t start = m_ic->chapters[i]->start;
557  long double total_secs = (long double)start * (long double)num /
558  (long double)den;
559  auto framenum = (long long)(total_secs * m_fps);
560  if (framesPlayed >= framenum)
561  {
562  LOG(VB_PLAYBACK, LOG_INFO, LOC +
563  QString("GetCurrentChapter(selected chapter %1 framenum %2)")
564  .arg(i + 1).arg(framenum));
565  return i + 1;
566  }
567  }
568  return 0;
569 }
570 
571 long long AvFormatDecoder::GetChapter(int chapter)
572 {
573  if (chapter < 1 || chapter > GetNumChapters())
574  return -1;
575 
576  int num = m_ic->chapters[chapter - 1]->time_base.num;
577  int den = m_ic->chapters[chapter - 1]->time_base.den;
578  int64_t start = m_ic->chapters[chapter - 1]->start;
579  long double total_secs = (long double)start * (long double)num /
580  (long double)den;
581  auto framenum = (long long)(total_secs * m_fps);
582  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("GetChapter %1: framenum %2")
583  .arg(chapter).arg(framenum));
584  return framenum;
585 }
586 
587 bool AvFormatDecoder::DoRewind(long long desiredFrame, bool discardFrames)
588 {
589  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("DoRewind(%1, %2 discard frames)")
590  .arg(desiredFrame).arg( discardFrames ? "do" : "don't" ));
591 
593  return DecoderBase::DoRewind(desiredFrame, discardFrames);
594 
595  // avformat-based seeking
596  return do_av_seek(desiredFrame, discardFrames, AVSEEK_FLAG_BACKWARD);
597 }
598 
599 bool AvFormatDecoder::DoFastForward(long long desiredFrame, bool discardFrames)
600 {
601  LOG(VB_PLAYBACK, LOG_INFO, LOC +
602  QString("DoFastForward(%1 (%2), %3 discard frames)")
603  .arg(desiredFrame).arg(m_framesPlayed)
604  .arg((discardFrames) ? "do" : "don't"));
605 
607  return DecoderBase::DoFastForward(desiredFrame, discardFrames);
608 
609  int seekDelta = desiredFrame - m_framesPlayed;
610 
611  // avoid using av_frame_seek if we are seeking frame-by-frame when paused
612  if (seekDelta >= 0 && seekDelta < 2 && m_parent->GetPlaySpeed() == 0.0F)
613  {
614  SeekReset(m_framesPlayed, seekDelta, false, true);
616  return true;
617  }
618  return do_av_seek(desiredFrame, discardFrames, 0);
619 }
620 
621 bool AvFormatDecoder::do_av_seek(long long desiredFrame, bool discardFrames, int flags)
622 {
623  long long ts = 0;
624  if (m_ic->start_time != AV_NOPTS_VALUE)
625  ts = m_ic->start_time;
626 
627  // convert framenumber to normalized timestamp
628  long double seekts = desiredFrame * AV_TIME_BASE / m_fps;
629  ts += (long long)seekts;
630 
631  // XXX figure out how to do snapping in this case
632  bool exactseeks = DecoderBase::GetSeekSnap() == 0U;
633 
634  if (exactseeks)
635  {
636  flags |= AVSEEK_FLAG_BACKWARD;
637  }
638 
639  int ret = av_seek_frame(m_ic, -1, ts, flags);
640  if (ret < 0)
641  {
642  LOG(VB_GENERAL, LOG_ERR, LOC +
643  QString("av_seek_frame(m_ic, -1, %1, 0b%2) error: %3").arg(
644  QString::number(ts),
645  QString::number(flags, 2),
646  QString::fromStdString(av_make_error_stdstring(ret))
647  )
648  );
649  return false;
650  }
651  if (auto* reader = m_parent->GetSubReader(); reader)
652  reader->SeekFrame(ts, flags);
653 
654  int normalframes = 0;
655 
656  {
657  m_framesPlayed = desiredFrame;
658  m_fpsSkip = 0;
659  m_framesRead = desiredFrame;
660  normalframes = 0;
661  }
662 
663  SeekReset(m_lastKey, normalframes, true, discardFrames);
664 
665  if (discardFrames)
667 
668  return true;
669 }
670 
671 void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames,
672  bool doflush, bool discardFrames)
673 {
674  if (!m_ringBuffer)
675  return; // nothing to reset...
676 
677  LOG(VB_PLAYBACK, LOG_INFO, LOC +
678  QString("SeekReset(%1, %2, %3 flush, %4 discard)")
679  .arg(newKey).arg(skipFrames)
680  .arg((doflush) ? "do" : "don't",
681  (discardFrames) ? "do" : "don't"));
682 
683  DecoderBase::SeekReset(newKey, skipFrames, doflush, discardFrames);
684 
685  QMutexLocker locker(&m_avCodecLock);
686 
687  // Discard all the queued up decoded frames
688  if (discardFrames)
689  {
690  bool releaseall = m_mythCodecCtx ? (m_mythCodecCtx->DecoderWillResetOnFlush() ||
691  m_mythCodecCtx->DecoderNeedsReset(nullptr)) : false;
692  m_parent->DiscardVideoFrames(doflush, doflush && releaseall);
693  }
694 
695  if (doflush)
696  {
697  m_lastAPts = 0ms;
698  m_lastVPts = 0ms;
699  m_lastCcPtsu = 0us;
700 
701  avformat_flush(m_ic);
702 
703  // Only reset the internal state if we're using our seeking,
704  // not when using libavformat's seeking
706  {
707  m_ic->pb->pos = m_ringBuffer->GetReadPosition();
708  m_ic->pb->buf_ptr = m_ic->pb->buffer;
709  m_ic->pb->buf_end = m_ic->pb->buffer;
710  m_ic->pb->eof_reached = 0;
711  }
712 
713  // Flush the avcodec buffers
714  LOG(VB_PLAYBACK, LOG_INFO, LOC + "SeekReset() flushing");
715  for (uint i = 0; i < m_ic->nb_streams; i++)
716  {
717  AVCodecContext *codecContext = m_codecMap.FindCodecContext(m_ic->streams[i]);
718  // note that contexts that have not been opened have
719  // codecContext->internal = nullptr and cause a segfault in
720  // avcodec_flush_buffers
721  if (codecContext && codecContext->internal)
722  avcodec_flush_buffers(codecContext);
723  }
724 
725  // Free up the stored up packets
726  while (!m_storedPackets.isEmpty())
727  {
728  AVPacket *pkt = m_storedPackets.takeFirst();
729  av_packet_free(&pkt);
730  }
731 
732  m_prevGopPos = 0;
733  m_gopSet = false;
734  }
735 
736  // Skip all the desired number of skipFrames
737 
738  // Some seeks can be very slow. The most common example comes
739  // from HD-PVR recordings, where keyframes are 128 frames apart
740  // and decoding (even hardware decoding) may not be much faster
741  // than realtime, causing some exact seeks to take 2-4 seconds.
742  // If exact seeking is not required, we take some shortcuts.
743  // First, we impose an absolute maximum time we are willing to
744  // spend (maxSeekTimeMs) on the forward frame-by-frame skip.
745  // After that much time has elapsed, we give up and stop the
746  // frame-by-frame seeking. Second, after skipping a few frames,
747  // we predict whether the situation is hopeless, i.e. the total
748  // skipping would take longer than giveUpPredictionMs, and if so,
749  // stop skipping right away.
750  bool exactSeeks = GetSeekSnap() == 0U;
751  static constexpr std::chrono::milliseconds maxSeekTimeMs { 200ms };
752  int profileFrames = 0;
754  for (; (skipFrames > 0 && !m_atEof &&
755  (exactSeeks || begin.elapsed() < maxSeekTimeMs));
756  --skipFrames, ++profileFrames)
757  {
758  // TODO this won't work well in conjunction with the MythTimer
759  // above...
760  QElapsedTimer getframetimer;
761  getframetimer.start();
762  bool retry = true;
763  while (retry && !getframetimer.hasExpired(100))
764  {
765  retry = false;
766  GetFrame(kDecodeVideo, retry);
767  if (retry)
768  std::this_thread::sleep_for(1ms);
769  }
770 
772  {
774  m_decodedVideoFrame = nullptr;
775  }
776  if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
777  {
778  const int giveUpPredictionMs = 400;
779  int remainingTimeMs =
780  skipFrames * (float)begin.elapsed().count() / profileFrames;
781  if (remainingTimeMs > giveUpPredictionMs)
782  {
783  LOG(VB_PLAYBACK, LOG_DEBUG,
784  QString("Frame-by-frame seeking would take "
785  "%1 ms to finish, skipping.").arg(remainingTimeMs));
786  break;
787  }
788  }
789  }
790 
791  if (doflush)
792  {
793  m_firstVPts = 0ms;
794  m_firstVPtsInuse = true;
795  }
796 }
797 
799 {
800  if (!eof && m_ic && m_ic->pb)
801  {
802  LOG(VB_GENERAL, LOG_NOTICE, LOC +
803  QString("Resetting byte context eof (livetv %1 was eof %2)")
804  .arg(m_livetv).arg(m_ic->pb->eof_reached));
805  m_ic->pb->eof_reached = 0;
806  }
807  DecoderBase::SetEof(eof);
808 }
809 
810 void AvFormatDecoder::Reset(bool reset_video_data, bool seek_reset,
811  bool reset_file)
812 {
813  LOG(VB_PLAYBACK, LOG_INFO, LOC +
814  QString("Reset: Video %1, Seek %2, File %3")
815  .arg(reset_video_data).arg(seek_reset).arg(reset_file));
816 
817  if (seek_reset)
818  SeekReset(0, 0, true, false);
819 
820  DecoderBase::Reset(reset_video_data, false, reset_file);
821 
822  if (reset_video_data)
823  {
824  m_seenGop = false;
825  m_seqCount = 0;
826  }
827 }
828 
829 bool AvFormatDecoder::CanHandle(TestBufferVec & testbuf, const QString &filename)
830 {
831  AVProbeData probe;
832  memset(&probe, 0, sizeof(AVProbeData));
833 
834  QByteArray fname = filename.toLatin1();
835  probe.filename = fname.constData();
836  probe.buf = (unsigned char *)testbuf.data();
837  probe.buf_size = testbuf.size();
838 
839  int score = AVPROBE_SCORE_MAX/4;
840 
841  if (testbuf.size() + AVPROBE_PADDING_SIZE > kDecoderProbeBufferSize)
842  {
843  probe.buf_size = kDecoderProbeBufferSize - AVPROBE_PADDING_SIZE;
844  score = 0;
845  }
846  else if (testbuf.size()*2 >= kDecoderProbeBufferSize)
847  {
848  score--;
849  }
850 
851  memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
852 
853  return av_probe_input_format2(&probe, static_cast<int>(true), &score) != nullptr;
854 }
855 
856 void AvFormatDecoder::streams_changed(void *data, int avprogram_id)
857 {
858  auto *decoder = reinterpret_cast<AvFormatDecoder*>(data);
859 
860  int cnt = decoder->m_ic->nb_streams;
861 
862  LOG(VB_PLAYBACK, LOG_INFO, LOC +
863  QString("streams_changed 0x%1 -- program_number %2 stream count %3")
864  .arg((uint64_t)data,0,16).arg(QString::number(avprogram_id), QString::number(cnt)));
865 
866  auto* program = decoder->get_current_AVProgram();
867  if (program != nullptr && program->id != avprogram_id)
868  {
869  return;
870  }
871  decoder->m_streamsChanged = true;
872 }
873 
874 extern "C"
875 {
876  static void HandleStreamChange(void *data, int avprogram_id)
877  {
878  AvFormatDecoder::streams_changed(data, avprogram_id);
879  }
880 }
881 
883 {
884  m_avCodecLock.lock();
885  int retval = avformat_find_stream_info(m_ic, nullptr);
886  m_avCodecLock.unlock();
887  silence_ffmpeg_logging = false;
888  // ffmpeg 3.0 is returning -1 code when there is a channel
889  // change or some encoding error just after the start
890  // of the file, but is has found the correct stream info
891  // Set rc to 0 so that playing can continue.
892  if (retval == -1)
893  retval = 0;
894  return retval;
895 }
896 
912  TestBufferVec & testbuf)
913 {
914  CloseContext();
915 
917 
918  // Process frames immediately unless we're decoding
919  // a DVD, in which case don't so that we don't show
920  // anything whilst probing the data streams.
922 
923  const AVInputFormat *fmt = nullptr;
924  QString fnames = m_ringBuffer->GetFilename();
925  QByteArray fnamea = fnames.toLatin1();
926  const char *filename = fnamea.constData();
927 
928  AVProbeData probe;
929  memset(&probe, 0, sizeof(AVProbeData));
930  probe.filename = filename;
931  probe.buf = reinterpret_cast<unsigned char *>(testbuf.data());
932  if (testbuf.size() + AVPROBE_PADDING_SIZE <= kDecoderProbeBufferSize)
933  probe.buf_size = testbuf.size();
934  else
935  probe.buf_size = kDecoderProbeBufferSize - AVPROBE_PADDING_SIZE;
936  memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
937 
938  fmt = av_probe_input_format(&probe, static_cast<int>(true));
939  if (!fmt)
940  {
941  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Probe failed for '%1'").arg(filename));
942  return -1;
943  }
944 
945  if (strcmp(fmt->name, "mpegts") == 0 &&
946  gCoreContext->GetBoolSetting("FFMPEGTS", false))
947  {
948  const AVInputFormat *fmt2 = av_find_input_format("mpegts-ffmpeg");
949  if (fmt2)
950  {
951  fmt = fmt2;
952  LOG(VB_GENERAL, LOG_INFO, LOC + "Using FFmpeg MPEG-TS demuxer (forced)");
953  }
954  }
955 
956  int err = 0;
957  bool scancomplete = false;
958  int remainingscans = 5;
959 
960  while (!scancomplete && remainingscans--)
961  {
962  bool found = false;
963 
964  // With live tv, the ringbufer may contain insufficient data for complete
965  // initialisation so we try a few times with a slight pause each time to
966  // allow extra data to become available. In the worst case scenarios, the
967  // stream may not have a keyframe for 4-5 seconds.
968  // As a last resort, we will try and fallback to the original FFmpeg MPEG-TS
969  // demuxer if it is not already used.
970  // For regular videos, this shouldn't be an issue as the complete file
971  // should be available - though we try a little harder for streamed formats
972  int retries = m_livetv || m_ringBuffer->IsStreamed() ? 50 : 10;
973 
974  while (!found && --retries)
975  {
976  m_ic = avformat_alloc_context();
977  if (!m_ic)
978  {
979  LOG(VB_GENERAL, LOG_ERR, LOC + "Could not allocate format context.");
980  return -1;
981  }
982 
983  delete m_avfRingBuffer;
986  LOG(VB_PLAYBACK, LOG_INFO, LOC +
987  QString("Buffer size: %1 Streamed %2 Seekable %3 Available %4")
989  .arg(m_ringBuffer->IsStreamed())
990  .arg(m_ic->pb->seekable)
991  .arg(m_ringBuffer->GetReadBufAvail()));
992  m_avfRingBuffer->SetInInit(false);
993 
994  err = avformat_open_input(&m_ic, filename, fmt, nullptr);
995  if (err < 0)
996  {
997  std::string error;
998  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Failed to open input ('%1')")
999  .arg(av_make_error_stdstring(error, err)));
1000 
1001  // note - m_ic (AVFormatContext) is freed on failure
1002  if (retries > 2)
1003  {
1004  // wait a little to buffer more data
1005  // 50*0.1 = 5 seconds max
1006  QThread::usleep(100000);
1007  // resets the read position
1008  m_avfRingBuffer->SetInInit(false);
1009  continue;
1010  }
1011 
1012  if (strcmp(fmt->name, "mpegts") == 0)
1013  {
1014  fmt = av_find_input_format("mpegts-ffmpeg");
1015  if (fmt)
1016  {
1017  LOG(VB_GENERAL, LOG_ERR, LOC + "Attempting to use original FFmpeg MPEG-TS demuxer.");
1018  // resets the read position
1019  m_avfRingBuffer->SetInInit(false);
1020  continue;
1021  }
1022  break;
1023  }
1024  }
1025  found = true;
1026  }
1027 
1028  if (err < 0)
1029  {
1030  LOG(VB_GENERAL, LOG_ERR, LOC + "Fatal error opening input. Aborting");
1031  m_ic = nullptr;
1032  return -1;
1033  }
1034 
1035  // With certain streams, we don't get a complete stream analysis and the video
1036  // codec/frame format is not fully detected. This can have various consequences - from
1037  // failed playback to not enabling hardware decoding (as the frame formt is not valid).
1038  // Bump the duration (FFmpeg defaults to 5 seconds) to 60 seconds. This should
1039  // not impact performance as in the vast majority of cases the scan is completed
1040  // within a second or two (seconds in this case referring to stream duration - not the time
1041  // it takes to complete the scan).
1042  m_ic->max_analyze_duration = 60LL * AV_TIME_BASE;
1043 
1045  err = FindStreamInfo();
1046  if (err < 0)
1047  {
1048  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find codec parameters for '%1'").arg(filename));
1049  CloseContext();
1050  return -1;
1051  }
1052  m_avfRingBuffer->SetInInit(false);
1053 
1054  // final sanity check that scanned streams are valid for live tv
1055  scancomplete = true;
1056  for (uint i = 0; m_livetv && (i < m_ic->nb_streams); i++)
1057  {
1058  if (!StreamHasRequiredParameters(m_codecMap.GetCodecContext(m_ic->streams[i]), m_ic->streams[i]))
1059  {
1060  scancomplete = false;
1061  if (remainingscans)
1062  {
1063  CloseContext();
1064  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Stream scan incomplete - retrying");
1065  QThread::usleep(250000); // wait 250ms
1066  }
1067  break;
1068  }
1069  }
1070  }
1071 
1072  if (!scancomplete)
1073  LOG(VB_GENERAL, LOG_WARNING, LOC + "Scan incomplete - playback may not work");
1074 
1075  m_ic->streams_changed = HandleStreamChange;
1076  m_ic->stream_change_data = this;
1077 
1078  if (!m_livetv && !m_ringBuffer->IsDisc())
1079  {
1080  // generate timings based on the video stream to avoid bogus ffmpeg
1081  // values for duration and bitrate
1083  }
1084 
1085  // FLAC, MP3 or M4A file may contains an artwork image, a single frame MJPEG,
1086  // we need to ignore it as we don't handle single frames or images in place of video
1087  // TODO: display single frame
1088  QString extension = QFileInfo(fnames).suffix();
1089  if (strcmp(fmt->name, "mp3") == 0 || strcmp(fmt->name, "flac") == 0 ||
1090  strcmp(fmt->name, "ogg") == 0 ||
1091  (extension.compare("m4a", Qt::CaseInsensitive) == 0))
1092  {
1093  novideo = true;
1094  }
1095 
1096  // Scan for the initial A/V streams
1097  err = ScanStreams(novideo);
1098  if (-1 == err)
1099  {
1100  CloseContext();
1101  return err;
1102  }
1103 
1104 #ifdef USING_MHEG
1105  {
1106  int initialAudio = -1;
1107  int initialVideo = -1;
1108  if (m_itv == nullptr)
1110  if (m_itv != nullptr)
1111  m_itv->GetInitialStreams(initialAudio, initialVideo);
1112  if (initialAudio >= 0)
1113  SetAudioByComponentTag(initialAudio);
1114  if (initialVideo >= 0)
1115  SetVideoByComponentTag(initialVideo);
1116  }
1117 #endif // USING_MHEG
1118 
1119  // Try to get a position map from the recorder if we don't have one yet.
1121  {
1123  {
1126  {
1127  m_hasFullPositionMap = true;
1128  m_gopSet = true;
1129  }
1130  }
1131  }
1132 
1133  // If watching pre-recorded television or video use the marked duration
1134  // from the db if it exists, else ffmpeg duration
1135  std::chrono::seconds dur = 0s;
1136 
1137  if (m_playbackInfo)
1138  {
1139  dur = duration_cast<std::chrono::seconds>(m_playbackInfo->QueryTotalDuration());
1140  }
1141 
1142  if (dur == 0s)
1143  {
1144  dur = duration_cast<std::chrono::seconds>(av_duration(m_ic->duration));
1145  }
1146 
1147  if (dur > 0s && !m_livetv && !m_watchingRecording)
1148  {
1149  m_parent->SetDuration(dur);
1150  }
1151 
1152  // If we don't have a position map, set up ffmpeg for seeking
1154  {
1155  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1156  "Recording has no position -- using libavformat seeking.");
1157 
1158  if (dur > 0s)
1159  {
1160  m_parent->SetFileLength(dur, (int)(dur.count() * m_fps));
1161  }
1162  else
1163  {
1164  // the pvr-250 seems to over report the bitrate by * 2
1165  float bytespersec = (float)m_bitrate / 8 / 2;
1166  float secs = m_ringBuffer->GetRealFileSize() * 1.0F / bytespersec;
1168  (int)(secs * static_cast<float>(m_fps)));
1169  }
1170 
1171  // we will not see a position map from db or remote encoder,
1172  // set the gop interval to 15 frames. if we guess wrong, the
1173  // auto detection will change it.
1174  m_keyframeDist = 15;
1176 
1177  if (strcmp(fmt->name, "avi") == 0)
1178  {
1179  // avi keyframes are too irregular
1180  m_keyframeDist = 1;
1181  }
1182 
1183  m_dontSyncPositionMap = true;
1184  }
1185 
1186  av_dump_format(m_ic, 0, filename, 0);
1187 
1188  // print some useful information if playback debugging is on
1190  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Position map found");
1191  else if (m_recordingHasPositionMap)
1192  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Partial position map found");
1193  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1194  QString("Successfully opened decoder for file: \"%1\". novideo(%2)")
1195  .arg(filename).arg(novideo));
1196 
1197  // Print AVChapter information
1198  for (unsigned int i=0; i < m_ic->nb_chapters; i++)
1199  {
1200  int num = m_ic->chapters[i]->time_base.num;
1201  int den = m_ic->chapters[i]->time_base.den;
1202  int64_t start = m_ic->chapters[i]->start;
1203  auto total_secs = static_cast<long double>(start) * static_cast<long double>(num) /
1204  static_cast<long double>(den);
1205  auto msec = millisecondsFromFloat(total_secs * 1000);
1206  auto framenum = static_cast<long long>(total_secs * static_cast<long double>(m_fps));
1207  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1208  QString("Chapter %1 found @ [%2]->%3")
1209  .arg(StringUtil::intToPaddedString(i + 1),
1210  MythDate::formatTime(msec, "HH:mm:ss.zzz"),
1211  QString::number(framenum)));
1212  }
1213 
1214  if (m_ringBuffer->IsDVD())
1215  {
1216  // Reset DVD playback and clear any of
1217  // our buffers so that none of the data
1218  // parsed so far to determine decoders
1219  // gets shown.
1221  return -1;
1223 
1224  Reset(true, true, true);
1225 
1226  // Now we're ready to process and show frames
1227  m_processFrames = true;
1228  }
1229 
1230 
1231  // Return true if recording has position map
1232  return static_cast<int>(m_recordingHasPositionMap);
1233 }
1234 
1235 float AvFormatDecoder::GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise)
1236 {
1237  // MKV default_duration
1238  double avg_fps = (Stream->avg_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->avg_frame_rate);
1239  double codec_fps = av_q2d(Context->framerate); // {0, 1} when unknown
1240  double container_fps = (Stream->time_base.num == 0) ? 0.0 : av_q2d(av_inv_q(Stream->time_base));
1241  // least common multiple of all framerates in a stream; this is a guess
1242  double estimated_fps = (Stream->r_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->r_frame_rate);
1243 
1244  // build a list of possible rates, best first
1245  std::vector<double> rates;
1246  rates.reserve(7);
1247 
1248  // matroska demuxer sets the default_duration to avg_frame_rate
1249  // mov,mp4,m4a,3gp,3g2,mj2 demuxer sets avg_frame_rate
1250  if (QString(m_ic->iformat->name).contains("matroska") ||
1251  QString(m_ic->iformat->name).contains("mov"))
1252  {
1253  rates.emplace_back(avg_fps);
1254  }
1255 
1256  // avi uses container fps for timestamps
1257  if (QString(m_ic->iformat->name).contains("avi"))
1258  {
1259  rates.emplace_back(container_fps);
1260  }
1261 
1262  rates.emplace_back(codec_fps);
1263  rates.emplace_back(container_fps);
1264  rates.emplace_back(avg_fps);
1265  // certain H.264 interlaced streams are detected at 2x using estimated (i.e. wrong)
1266  rates.emplace_back(estimated_fps);
1267  // last resort, default to NTSC
1268  rates.emplace_back(30000.0 / 1001.0);
1269 
1270  auto invalid_fps = [](double rate) { return rate < 3.0 || rate > 121.0; };
1271  rates.erase(std::remove_if(rates.begin(), rates.end(), invalid_fps), rates.end());
1272 
1273  auto FuzzyEquals = [](double First, double Second) { return std::abs(First - Second) < 0.03; };
1274 
1275  // debug
1276  if (!FuzzyEquals(rates.front(), m_fps))
1277  {
1278  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1279  QString("Selected FPS: %1 (Avg:%2 Mult:%3 Codec:%4 Container:%5 Estimated:%6)")
1280  .arg(static_cast<double>(rates.front())).arg(avg_fps)
1281  .arg(m_fpsMultiplier).arg(codec_fps).arg(container_fps).arg(estimated_fps));
1282  }
1283 
1284  auto IsStandard = [&FuzzyEquals](double Rate)
1285  {
1286  // List of known, standards based frame rates
1287  static const std::set<double> k_standard_rates =
1288  {
1289  24000.0 / 1001.0,
1290  23.976,
1291  24.0,
1292  25.0,
1293  30000.0 / 1001.0,
1294  29.97,
1295  30.0,
1296  50.0,
1297  60000.0 / 1001.0,
1298  59.94,
1299  60.0,
1300  100.0,
1301  120000.0 / 1001.0,
1302  119.88,
1303  120.0
1304  };
1305 
1306  if (Rate > 23.0 && Rate < 121.0)
1307  {
1308  for (auto standard_rate : k_standard_rates)
1309  if (FuzzyEquals(Rate, standard_rate))
1310  return true;
1311  }
1312  return false;
1313  // TODO do not convert AVRational to double
1314  //return k_standard_rates.find(rate) != k_standard_rates.end();
1315  };
1316 
1317  // If the first choice rate is unusual, see if there is something more 'usual'
1318  double detected = rates.front();
1319  if (Sanitise && !IsStandard(detected))
1320  {
1321  for (auto rate : rates)
1322  {
1323  if (IsStandard(rate))
1324  {
1325  LOG(VB_GENERAL, LOG_INFO, LOC + QString("%1 is non-standard - using %2 instead.")
1326  .arg(rates.front()).arg(rate));
1327 
1328  // The most common problem here is mpegts files where the average
1329  // rate is slightly out and the estimated rate is the fallback.
1330  // As noted above, however, the estimated rate is sometimes twice
1331  // the actual for interlaced content. Try and detect and fix this
1332  // so that we don't throw out deinterlacing and video mode switching.
1333  // Assume anything under 30 may be interlaced - with +-10% error.
1334  if (rate > 33.0 && detected < 33.0)
1335  {
1336  double half = rate / 2.0;
1337  if (std::abs(half - detected) < (half * 0.1))
1338  {
1339  LOG(VB_GENERAL, LOG_INFO, LOC +
1340  QString("Assuming %1 is a better choice than %2")
1341  .arg(half).arg(rate));
1342  return static_cast<float>(half);
1343  }
1344  }
1345  return static_cast<float>(rate);
1346  }
1347  }
1348  }
1349 
1350  return static_cast<float>(detected);
1351 }
1352 
1353 int AvFormatDecoder::GetMaxReferenceFrames(AVCodecContext *Context)
1354 {
1355  switch (Context->codec_id)
1356  {
1357  case AV_CODEC_ID_H264:
1358  {
1359  int result = 16;
1360  if (Context->extradata && (Context->extradata_size >= 7))
1361  {
1362  uint8_t offset = 0;
1363  if (Context->extradata[0] == 1)
1364  offset = 9; // avCC
1365  else if (AV_RB24(Context->extradata) == 0x01) // Annex B - 3 byte startcode 0x000001
1366  offset = 4;
1367  else if (AV_RB32(Context->extradata) == 0x01) // Annex B - 4 byte startcode 0x00000001
1368  offset= 5;
1369 
1370  if (offset)
1371  {
1372  AVCParser parser;
1373  bool dummy = false;
1374  parser.parse_SPS(Context->extradata + offset,
1375  static_cast<uint>(Context->extradata_size - offset), dummy, result);
1376  }
1377  }
1378  return result;
1379  }
1380  case AV_CODEC_ID_H265: return 16;
1381  case AV_CODEC_ID_VP9: return 8;
1382  case AV_CODEC_ID_VP8: return 3;
1383  default: return 2;
1384  }
1385 }
1386 
1387 void AvFormatDecoder::InitVideoCodec(AVStream *stream, AVCodecContext *codecContext,
1388  bool selectedStream)
1389 {
1390  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1391  QString("InitVideoCodec ID:%1 Type:%2 Size:%3x%4")
1392  .arg(avcodec_get_name(codecContext->codec_id),
1393  AVMediaTypeToString(codecContext->codec_type))
1394  .arg(codecContext->width).arg(codecContext->height));
1395 
1396  if (m_ringBuffer && m_ringBuffer->IsDVD())
1397  m_directRendering = false;
1398 
1399  codecContext->opaque = static_cast<void*>(this);
1400  codecContext->get_buffer2 = get_avf_buffer;
1401  codecContext->slice_flags = 0;
1402 
1403  codecContext->err_recognition = AV_EF_COMPLIANT;
1404  codecContext->workaround_bugs = FF_BUG_AUTODETECT;
1405  codecContext->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
1406  codecContext->idct_algo = FF_IDCT_AUTO;
1407  codecContext->debug = 0;
1408  // codecContext->error_rate = 0;
1409 
1410  const AVCodec *codec1 = codecContext->codec;
1411 
1412  if (selectedStream)
1413  m_directRendering = true;
1414 
1415  // retrieve rotation information
1416  const AVPacketSideData *sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1417  stream->codecpar->nb_coded_side_data, AV_PKT_DATA_DISPLAYMATRIX);
1418  if (sd)
1419  m_videoRotation = static_cast<int>(-av_display_rotation_get(reinterpret_cast<int32_t*>(sd->data)));
1420  else
1421  m_videoRotation = 0;
1422 
1423  // retrieve 3D type
1424  sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1425  stream->codecpar->nb_coded_side_data, AV_PKT_DATA_STEREO3D);
1426  if (sd)
1427  {
1428  auto * avstereo = reinterpret_cast<AVStereo3D*>(sd->data);
1429  m_stereo3D = avstereo->type;
1430  }
1431 
1432  delete m_mythCodecCtx;
1434  m_mythCodecCtx->InitVideoCodec(codecContext, selectedStream, m_directRendering);
1435  if (m_mythCodecCtx->HwDecoderInit(codecContext) < 0)
1436  {
1437  // force it to switch to software decoding
1439  m_streamsChanged = true;
1440  }
1441  else
1442  {
1443  // Note: This is never going to work as expected in all circumstances.
1444  // It will not account for changes in the stream and/or display. For
1445  // MediaCodec, Android will do its own thing (and judging by the Android logs,
1446  // shouldn't double rate the deinterlacing if the display cannot support it).
1447  // NVDEC will probably move to the FFmpeg YADIF CUDA deinterlacer - which
1448  // will avoid the issue (video player deinterlacing) and maybe disable
1449  // decoder VAAPI deinterlacing. If we get it wrong and the display cannot
1450  // keep up, the player should just drop frames.
1451 
1452  // FIXME - need a better way to handle this
1453  bool doublerate = true;//m_parent->CanSupportDoubleRate();
1454  m_mythCodecCtx->SetDeinterlacing(codecContext, &m_videoDisplayProfile, doublerate);
1455  }
1456 
1457  if (codec1 && ((AV_CODEC_ID_MPEG2VIDEO == codec1->id) ||
1458  (AV_CODEC_ID_MPEG1VIDEO == codec1->id)))
1459  {
1461  {
1462  int total_blocks = (codecContext->height + 15) / 16;
1463  codecContext->skip_top = (total_blocks + 3) / 4;
1464  codecContext->skip_bottom = (total_blocks + 3) / 4;
1465  }
1466 
1467  if (FlagIsSet(kDecodeLowRes))
1468  codecContext->lowres = 2; // 1 = 1/2 size, 2 = 1/4 size
1469  }
1470  else if (codec1 && (AV_CODEC_ID_H264 == codec1->id) && FlagIsSet(kDecodeNoLoopFilter))
1471  {
1472  codecContext->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
1473  codecContext->skip_loop_filter = AVDISCARD_ALL;
1474  }
1475 
1477  codecContext->skip_idct = AVDISCARD_ALL;
1478 
1479  if (selectedStream)
1480  {
1481  // m_fps is now set 'correctly' in ScanStreams so this additional call
1482  // to GetVideoFrameRate may now be redundant
1483  m_fps = GetVideoFrameRate(stream, codecContext, true);
1484  QSize dim = get_video_dim(*codecContext);
1485  int width = m_currentWidth = dim.width();
1486  int height = m_currentHeight = dim.height();
1487  m_currentAspect = get_aspect(*codecContext);
1488 
1489  if (!width || !height)
1490  {
1491  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1492  "InitVideoCodec invalid dimensions, resetting decoder.");
1493  width = 640;
1494  height = 480;
1495  m_fps = 29.97F;
1496  m_currentAspect = 4.0F / 3.0F;
1497  }
1498 
1500  const AVCodec *codec2 = codecContext->codec;
1501  QString codecName;
1502  if (codec2)
1503  codecName = codec2->name;
1504  m_parent->SetVideoParams(width, height, m_fps,
1505  m_currentAspect, false, GetMaxReferenceFrames(codecContext),
1506  kScan_Detect, codecName);
1507  if (LCD *lcd = LCD::Get())
1508  {
1509  LCDVideoFormatSet video_format = VIDEO_MPG;
1510 
1511  switch (codecContext->codec_id)
1512  {
1513  case AV_CODEC_ID_H263:
1514  case AV_CODEC_ID_MPEG4:
1515  case AV_CODEC_ID_MSMPEG4V1:
1516  case AV_CODEC_ID_MSMPEG4V2:
1517  case AV_CODEC_ID_MSMPEG4V3:
1518  case AV_CODEC_ID_H263P:
1519  case AV_CODEC_ID_H263I:
1520  video_format = VIDEO_DIVX;
1521  break;
1522  case AV_CODEC_ID_WMV1:
1523  case AV_CODEC_ID_WMV2:
1524  video_format = VIDEO_WMV;
1525  break;
1526 #if 0
1527  case AV_CODEC_ID_XVID:
1528  video_format = VIDEO_XVID;
1529  break;
1530 #endif
1531  default:
1532  video_format = VIDEO_MPG;
1533  break;
1534  }
1535 
1536  lcd->setVideoFormatLEDs(video_format, true);
1537 
1538  if(height >= 720)
1539  lcd->setVariousLEDs(VARIOUS_HDTV, true);
1540  else
1541  lcd->setVariousLEDs(VARIOUS_HDTV, false);
1542  }
1543  }
1544 }
1545 
1546 static bool cc608_good_parity(uint16_t data)
1547 {
1548  static constexpr std::array<uint8_t, 256> odd_parity_LUT
1549  {
1550  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1551  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1552  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1553  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1554  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1555  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1556  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1557  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1558  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1559  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1560  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1561  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1562  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1563  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1564  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1565  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1566  };
1567  bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
1568  (odd_parity_LUT[(data & 0xff00) >> 8] == 1);
1569  if (!ret)
1570  {
1571  LOG(VB_VBI, LOG_ERR, LOC +
1572  QString("VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
1573  }
1574  return ret;
1575 }
1576 
1577 static AVBufferRef* get_pmt_section_from_AVProgram(const AVProgram *program)
1578 {
1579  if (program == nullptr)
1580  {
1581  return nullptr;
1582  }
1583  return program->pmt_section;
1584 }
1585 
1586 static AVBufferRef* get_pmt_section_for_AVStream_index(AVFormatContext *context, int stream_index)
1587 {
1588  AVProgram* program = av_find_program_from_stream(context, nullptr, stream_index);
1589  return get_pmt_section_from_AVProgram(program);
1590 }
1591 
1593 {
1594  QMutexLocker locker(&m_trackLock);
1595 
1596  m_ccX08InPmt.fill(false);
1597  m_pmtTracks.clear();
1598  m_pmtTrackTypes.clear();
1599 
1600  // Figure out languages of ATSC captions
1602  if (!pmt_buffer.has_buffer())
1603  {
1604  LOG(VB_GENERAL, LOG_DEBUG, LOC +
1605  "ScanATSCCaptionStreams() called with no PMT");
1606  return;
1607  }
1608  const ProgramMapTable pmt(PSIPTable(pmt_buffer.data()));
1609 
1610  bool video_found = false;
1611  uint i = 0;
1612  for (i = 0; i < pmt.StreamCount(); i++)
1613  {
1614  // MythTV remaps OpenCable Video to normal video during recording
1615  // so "dvb" is the safest choice for system info type, since this
1616  // will ignore other uses of the same stream id in DVB countries.
1617  if (pmt.IsVideo(i, "dvb"))
1618  {
1619  video_found = true;
1620  break;
1621  }
1622  }
1623  if (!video_found)
1624  return;
1625 
1627  pmt.StreamInfo(i), pmt.StreamInfoLength(i),
1629 
1630  const desc_list_t desc_list2 = MPEGDescriptor::ParseOnlyInclude(
1631  pmt.ProgramInfo(), pmt.ProgramInfoLength(),
1633 
1634  desc_list.insert(desc_list.end(), desc_list2.begin(), desc_list2.end());
1635 
1636  for (auto & desc : desc_list)
1637  {
1638  const CaptionServiceDescriptor csd(desc);
1639  if (!csd.IsValid())
1640  continue;
1641 
1642  LOG(VB_VBI, LOG_DEBUG, LOC + csd.toString());
1643 
1644  for (uint k = 0; k < csd.ServicesCount(); k++)
1645  {
1646  int lang = csd.CanonicalLanguageKey(k);
1647  int type = csd.Type(k) ? 1 : 0;
1648  if (type)
1649  {
1650  StreamInfo si {av_index, csd.CaptionServiceNumber(k), lang};
1651  uint key = csd.CaptionServiceNumber(k) + 4;
1652  m_ccX08InPmt[key] = true;
1653  m_pmtTracks.push_back(si);
1654  m_pmtTrackTypes.push_back(kTrackTypeCC708);
1655  }
1656  else
1657  {
1658  int line21 = csd.Line21Field(k) ? 3 : 1;
1659  StreamInfo si {av_index, line21, lang};
1660  m_ccX08InPmt[line21-1] = true;
1661  m_pmtTracks.push_back(si);
1662  m_pmtTrackTypes.push_back(kTrackTypeCC608);
1663  }
1664  }
1665  }
1666 }
1667 
1669 {
1670  QMutexLocker locker(&m_trackLock);
1671 
1672  m_tracks[kTrackTypeCC608].clear();
1673  m_tracks[kTrackTypeCC708].clear();
1674  m_ccX08InTracks.fill(false);
1675 
1676  uint pidx = 0;
1677  uint sidx = 0;
1678  std::array<std::map<int,uint>,2> lang_cc_cnt;
1679  while (true)
1680  {
1681  bool pofr = pidx >= (uint)m_pmtTracks.size();
1682  bool sofr = sidx >= (uint)m_streamTracks.size();
1683  if (pofr && sofr)
1684  break;
1685 
1686  // choose lowest available next..
1687  // stream_id's of 608 and 708 streams alias, but this
1688  // is ok as we just want each list to be ordered.
1689  StreamInfo const *si = nullptr;
1690  int type = 0; // 0 if 608, 1 if 708
1691  bool isp = true; // if true use m_pmtTracks next, else stream_tracks
1692 
1693  if (pofr && !sofr)
1694  isp = false; // NOLINT(bugprone-branch-clone)
1695  else if (!pofr && sofr)
1696  isp = true;
1697  else if (m_streamTracks[sidx] < m_pmtTracks[pidx])
1698  isp = false;
1699 
1700  if (isp)
1701  {
1702  si = &m_pmtTracks[pidx];
1703  type = kTrackTypeCC708 == m_pmtTrackTypes[pidx] ? 1 : 0;
1704  pidx++;
1705  }
1706  else
1707  {
1708  si = &m_streamTracks[sidx];
1709  type = kTrackTypeCC708 == m_streamTrackTypes[sidx] ? 1 : 0;
1710  sidx++;
1711  }
1712 
1713  StreamInfo nsi(*si);
1714  int lang_indx = lang_cc_cnt[type][nsi.m_language];
1715  lang_cc_cnt[type][nsi.m_language]++;
1716  nsi.m_language_index = lang_indx;
1717  m_tracks[(type) ? kTrackTypeCC708 : kTrackTypeCC608].push_back(nsi);
1718  int key = nsi.m_stream_id + ((type) ? 4 : -1);
1719  if (key < 0)
1720  {
1721  LOG(VB_GENERAL, LOG_ERR, LOC + "in_tracks key too small");
1722  }
1723  else
1724  {
1725  m_ccX08InTracks[key] = true;
1726  }
1727  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1728  QString("%1 caption service #%2 is in the %3 language.")
1729  .arg((type) ? "EIA-708" : "EIA-608")
1730  .arg(nsi.m_stream_id)
1731  .arg(iso639_key_toName(nsi.m_language)));
1732  }
1735 }
1736 
1738 {
1739  QMutexLocker locker(&m_trackLock);
1740 
1741  // ScanStreams() calls m_tracks[kTrackTypeTeletextCaptions].clear()
1742  if (!m_tracks[kTrackTypeTeletextCaptions].empty())
1743  return;
1744 
1745  AVStream* st = m_ic->streams[av_index];
1746  const AVDictionaryEntry* language_dictionary_entry =
1747  av_dict_get(st->metadata, "language", nullptr, 0);
1748 
1749  if (language_dictionary_entry == nullptr ||
1750  language_dictionary_entry->value == nullptr ||
1751  st->codecpar->extradata == nullptr
1752  )
1753  {
1754  return;
1755  }
1756 
1757  std::vector<std::string_view> languages {StringUtil::split_sv(language_dictionary_entry->value, ","sv)};
1758 
1759  if (st->codecpar->extradata_size != static_cast<int>(languages.size() * 2))
1760  {
1761  return;
1762  }
1763  for (size_t i = 0; i < languages.size(); i++)
1764  {
1765  if (languages[i].size() != 3)
1766  {
1767  continue;
1768  }
1769  //NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
1770  int language = iso639_str3_to_key(languages[i].data());
1771  uint8_t teletext_type = st->codecpar->extradata[i * 2] >> 3;
1772  uint8_t teletext_magazine_number = st->codecpar->extradata[i * 2] & 0x7;
1773  if (teletext_magazine_number == 0)
1774  teletext_magazine_number = 8;
1775  uint8_t teletext_page_number = st->codecpar->extradata[(i * 2) + 1];
1776  if (teletext_type == 2 || teletext_type == 1)
1777  {
1778  TrackType track = (teletext_type == 2) ?
1781  m_tracks[track].emplace_back(av_index, 0, language,
1782  (static_cast<unsigned>(teletext_magazine_number) << 8) | teletext_page_number);
1783  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1784  QString("Teletext stream #%1 (%2) is in the %3 language on page %4 %5.")
1785  .arg(QString::number(i),
1786  (teletext_type == 2) ? "Caption" : "Menu",
1787  iso639_key_toName(language),
1788  QString::number(teletext_magazine_number),
1789  QString::number(teletext_page_number)));
1790  }
1791  }
1792 }
1793 
1794 void AvFormatDecoder::ScanRawTextCaptions(int av_stream_index)
1795 {
1796  QMutexLocker locker(&m_trackLock);
1797 
1798  AVDictionaryEntry *metatag =
1799  av_dict_get(m_ic->streams[av_stream_index]->metadata, "language", nullptr,
1800  0);
1801  bool forced = (m_ic->streams[av_stream_index]->disposition & AV_DISPOSITION_FORCED) != 0;
1802  int lang = metatag ? get_canonical_lang(metatag->value) :
1803  iso639_str3_to_key("und");
1804  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1805  QString("Text Subtitle track #%1 is A/V stream #%2 "
1806  "and is in the %3 language(%4), forced=%5.")
1807  .arg(m_tracks[kTrackTypeRawText].size()).arg(av_stream_index)
1808  .arg(iso639_key_toName(lang)).arg(lang).arg(forced));
1809  StreamInfo si {av_stream_index, 0, lang, 0, forced};
1810  m_tracks[kTrackTypeRawText].push_back(si);
1811 }
1812 
1817 void AvFormatDecoder::ScanDSMCCStreams(AVBufferRef* pmt_section)
1818 {
1819  if (m_itv == nullptr)
1821  if (m_itv == nullptr)
1822  return;
1823 
1824  MythAVBufferRef pmt_buffer {pmt_section};
1825  if (!pmt_buffer.has_buffer())
1826  {
1827  return;
1828  }
1829  const ProgramMapTable pmt(PSIPTable(pmt_buffer.data()));
1830 
1831  for (uint i = 0; i < pmt.StreamCount(); i++)
1832  {
1833  if (! StreamID::IsObjectCarousel(pmt.StreamType(i)))
1834  continue;
1835 
1836  LOG(VB_DSMCC, LOG_NOTICE, QString("ScanDSMCCStreams Found Object Carousel in Stream %1").arg(QString::number(i)));
1837 
1839  pmt.StreamInfo(i), pmt.StreamInfoLength(i),
1841 
1842  for (const auto *desc : desc_list)
1843  {
1844  desc++; // Skip tag
1845  uint length = *desc++;
1846  const unsigned char *endDesc = desc+length;
1847  uint dataBroadcastId = desc[0]<<8 | desc[1];
1848  LOG(VB_DSMCC, LOG_NOTICE, QString("ScanDSMCCStreams dataBroadcastId %1").arg(QString::number(dataBroadcastId)));
1849  if (dataBroadcastId != 0x0106) // ETSI/UK Profile
1850  continue;
1851  desc += 2; // Skip data ID
1852  while (desc != endDesc)
1853  {
1854  [[maybe_unused]] uint appTypeCode = desc[0]<<8 | desc[1];
1855  desc += 3; // Skip app type code and boot priority hint
1856  uint appSpecDataLen = *desc++;
1857 #ifdef USING_MHEG
1858  LOG(VB_DSMCC, LOG_NOTICE, QString("ScanDSMCCStreams AppTypeCode %1").arg(QString::number(appTypeCode)));
1859  if (appTypeCode == 0x101) // UK MHEG profile
1860  {
1861  const unsigned char *subDescEnd = desc + appSpecDataLen;
1862  while (desc < subDescEnd)
1863  {
1864  uint sub_desc_tag = *desc++;
1865  uint sub_desc_len = *desc++;
1866  // Network boot info sub-descriptor.
1867  if (sub_desc_tag == 1)
1868  m_itv->SetNetBootInfo(desc, sub_desc_len);
1869  desc += sub_desc_len;
1870  }
1871  }
1872  else
1873 #endif // USING_MHEG
1874  {
1875  desc += appSpecDataLen;
1876  }
1877  }
1878  }
1879  }
1880 }
1881 
1883 {
1884  m_tracks[kTrackTypeVideo].clear();
1885  m_selectedTrack[kTrackTypeVideo].m_av_stream_index = -1;
1887  m_fps = 0;
1888 
1889  const AVCodec *codec = nullptr;
1890  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Trying to select best video track");
1891 
1892  /*
1893  * Find the "best" stream in the file.
1894  *
1895  * The best stream is determined according to various heuristics as
1896  * the most likely to be what the user expects. If the decoder parameter
1897  * is not nullptr, av_find_best_stream will find the default decoder
1898  * for the stream's codec; streams for which no decoder can be found
1899  * are ignored.
1900  *
1901  * If av_find_best_stream returns successfully and decoder_ret is not nullptr,
1902  * then *decoder_ret is guaranteed to be set to a valid AVCodec.
1903  */
1904  int stream_index = av_find_best_stream(m_ic, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
1905 
1906  if (stream_index < 0)
1907  {
1908  LOG(VB_PLAYBACK, LOG_INFO, LOC + "No video track found/selected.");
1909  return stream_index;
1910  }
1911 
1912  AVStream *stream = m_ic->streams[stream_index];
1914  m_codecMap.FreeCodecContext(stream);
1915  AVCodecContext *codecContext = m_codecMap.GetCodecContext(stream, codec);
1916  StreamInfo si {stream_index, 0};
1917 
1918  m_tracks[kTrackTypeVideo].push_back(si);
1921 
1922  QString codectype(AVMediaTypeToString(codecContext->codec_type));
1923  if (codecContext->codec_type == AVMEDIA_TYPE_VIDEO)
1924  codectype += QString("(%1x%2)").arg(codecContext->width).arg(codecContext->height);
1925  LOG(VB_PLAYBACK, LOG_INFO, LOC +
1926  QString("Selected track #%1: ID: 0x%2 Codec ID: %3 Profile: %4 Type: %5 Bitrate: %6")
1927  .arg(stream_index).arg(static_cast<uint64_t>(stream->id), 0, 16)
1928  .arg(avcodec_get_name(codecContext->codec_id),
1929  avcodec_profile_name(codecContext->codec_id, codecContext->profile),
1930  codectype,
1931  QString::number(codecContext->bit_rate)));
1932 
1933  // If ScanStreams has been called on a stream change triggered by a
1934  // decoder error - because the decoder does not handle resolution
1935  // changes gracefully (NVDEC and maybe MediaCodec) - then the stream/codec
1936  // will still contain the old resolution but the AVCodecContext will
1937  // have been updated. This causes mayhem for a second or two.
1938  if ((codecContext->width != stream->codecpar->width) || (codecContext->height != stream->codecpar->height))
1939  {
1940  LOG(VB_GENERAL, LOG_INFO, LOC + QString(
1941  "Video resolution mismatch: Context: %1x%2 Stream: %3x%4 Codec: %5 Stream change: %6")
1942  .arg(codecContext->width).arg(codecContext->height)
1943  .arg(stream->codecpar->width).arg(stream->codecpar->height)
1945  }
1946 
1947  m_avcParser->Reset();
1948 
1949  QSize dim = get_video_dim(*codecContext);
1950  int width = std::max(dim.width(), 16);
1951  int height = std::max(dim.height(), 16);
1952  QString dec = "ffmpeg";
1953  uint thread_count = 1;
1954  QString codecName;
1955  if (codecContext->codec)
1956  codecName = codecContext->codec->name;
1957  // framerate appears to never be set - which is probably why
1958  // GetVideoFrameRate never uses it:)
1959  // So fallback to the GetVideoFrameRate call which should then ensure
1960  // the video display profile gets an accurate frame rate - instead of 0
1961  if (codecContext->framerate.den && codecContext->framerate.num)
1962  m_fps = float(codecContext->framerate.num) / float(codecContext->framerate.den);
1963  else
1964  m_fps = GetVideoFrameRate(stream, codecContext, true);
1965 
1966  bool foundgpudecoder = false;
1967  QStringList unavailabledecoders;
1968  bool allowgpu = FlagIsSet(kDecodeAllowGPU);
1969 
1971  {
1972  // TODO this could be improved by appending the decoder that has
1973  // failed to the unavailable list - but that could lead to circular
1974  // failures if there are 2 or more hardware decoders that fail
1975  if (FlagIsSet(kDecodeAllowGPU) && (dec != "ffmpeg"))
1976  {
1977  LOG(VB_GENERAL, LOG_WARNING, LOC + QString(
1978  "GPU/hardware decoder '%1' failed - forcing software decode")
1979  .arg(dec));
1980  }
1981  m_averrorCount = 0;
1982  allowgpu = false;
1983  }
1984 
1985  while (unavailabledecoders.size() < 10)
1986  {
1987  if (!m_isDbIgnored)
1988  {
1989  if (!unavailabledecoders.isEmpty())
1990  {
1991  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Unavailable decoders: %1")
1992  .arg(unavailabledecoders.join(",")));
1993  }
1994  m_videoDisplayProfile.SetInput(QSize(width, height), m_fps, codecName, unavailabledecoders);
1996  thread_count = m_videoDisplayProfile.GetMaxCPUs();
1997  bool skip_loop_filter = m_videoDisplayProfile.IsSkipLoopEnabled();
1998  if (!skip_loop_filter)
1999  codecContext->skip_loop_filter = AVDISCARD_NONKEY;
2000  }
2001 
2003  uint version = mpeg_version(codecContext->codec_id);
2004  if (version)
2005  m_videoCodecId = static_cast<MythCodecID>(kCodec_MPEG1 + version - 1);
2006 
2007  if (version && allowgpu && dec != "ffmpeg")
2008  {
2009  // We need to set this so that MythyCodecContext can callback
2010  // to the player in use to check interop support.
2011  codecContext->opaque = static_cast<void*>(this);
2012  MythCodecID hwcodec = MythCodecContext::FindDecoder(dec, stream, &codecContext, &codec);
2013  if (hwcodec != kCodec_NONE)
2014  {
2015  // the context may have changed
2016  codecContext->opaque = static_cast<void*>(this);
2017  m_videoCodecId = hwcodec;
2018  foundgpudecoder = true;
2019  }
2020  else
2021  {
2022  // hardware decoder is not available - try the next best profile
2023  unavailabledecoders.append(dec);
2024  continue;
2025  }
2026  }
2027 
2028  // default to mpeg2
2029  if (m_videoCodecId == kCodec_NONE)
2030  {
2031  LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown video codec - defaulting to MPEG2");
2033  }
2034 
2035  break;
2036  }
2037 
2039  thread_count = 1;
2040 
2041  if (HAVE_THREADS)
2042  {
2043  // Only use a single thread for hardware decoding. There is no
2044  // performance improvement with multithreaded hardware decode
2045  // and asynchronous callbacks create issues with decoders that
2046  // use AVHWFrameContext where we need to release video resources
2047  // before they are recreated
2048  if (!foundgpudecoder)
2049  {
2050  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Using %1 CPUs for decoding")
2051  .arg(HAVE_THREADS ? thread_count : 1));
2052  codecContext->thread_count = static_cast<int>(thread_count);
2053  }
2054  }
2055 
2056  InitVideoCodec(stream, codecContext, true);
2057 
2058  ScanATSCCaptionStreams(stream_index);
2060 
2061  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Using %1 for video decoding").arg(GetCodecDecoderName()));
2062  m_mythCodecCtx->SetDecoderOptions(codecContext, codec);
2063  if (!OpenAVCodec(codecContext, codec))
2064  {
2065  scanerror = -1;
2066  }
2067  return stream_index;
2068 }
2069 
2071 {
2072  AVProgram* program = av_find_program_from_stream(m_ic, nullptr, stream_index);
2073  if (program == nullptr)
2074  {
2075  return;
2076  }
2077 
2078  LOG(VB_PLAYBACK, LOG_INFO,
2079  QString("Removing streams not in Program %1 from track selection.")
2080  .arg(QString::number(program->id)));
2081 
2082  const auto * const begin = program->stream_index;
2083  const auto * const end = program->stream_index + program->nb_stream_indexes;
2084 
2085  for (auto & track_list : m_tracks)
2086  {
2087  LOG(VB_PLAYBACK, LOG_DEBUG,
2088  QString("Size before: %1").arg(QString::number(track_list.size())));
2089  track_list.erase(std::remove_if(track_list.begin(), track_list.end(),
2090  [&](const StreamInfo& i)
2091  {
2092  return std::find(begin, end, i.m_av_stream_index) == end;
2093  }), track_list.end());
2094  LOG(VB_PLAYBACK, LOG_DEBUG,
2095  QString("Size after: %1").arg(QString::number(track_list.size())));
2096  }
2097 }
2098 
2099 static bool is_dual_mono(const AVChannelLayout& ch_layout)
2100 {
2101  return (ch_layout.order == AV_CHANNEL_ORDER_CUSTOM) &&
2102  (ch_layout.nb_channels == 2) &&
2103  (ch_layout.u.map[0].id == AV_CHAN_FRONT_CENTER) &&
2104  (ch_layout.u.map[1].id == AV_CHAN_FRONT_CENTER);
2105 }
2106 
2108 {
2109  QMutexLocker avlocker(&m_avCodecLock);
2110  QMutexLocker locker(&m_trackLock);
2111 
2112  bool unknownbitrate = false;
2113  int scanerror = 0;
2114  m_bitrate = 0;
2115 
2116  constexpr std::array<TrackType, 6> types {
2123  };
2124  for (const auto type : types)
2125  {
2126  m_tracks[type].clear();
2127  m_currentTrack[type] = -1;
2128  }
2129 
2130  std::map<int,uint> lang_sub_cnt;
2131  uint subtitleStreamCount = 0;
2132  std::map<int,uint> lang_aud_cnt;
2133  uint audioStreamCount = 0;
2134 
2135  if (m_ringBuffer && m_ringBuffer->IsDVD() &&
2137  {
2140  }
2141 
2142  if (m_ic == nullptr)
2143  return -1;
2144 
2145  for (uint strm = 0; strm < m_ic->nb_streams; strm++)
2146  {
2147  AVCodecParameters *par = m_ic->streams[strm]->codecpar;
2148 
2149  QString codectype(AVMediaTypeToString(par->codec_type));
2150  if (par->codec_type == AVMEDIA_TYPE_VIDEO)
2151  codectype += QString("(%1x%2)").arg(par->width).arg(par->height);
2152  QString program_id = "null";
2153  if (av_find_program_from_stream(m_ic, nullptr, strm) != nullptr)
2154  {
2155  program_id = QString::number(av_find_program_from_stream(m_ic, nullptr, strm)->id);
2156  }
2157  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2158  QString("Stream #%1: ID: 0x%2 Program ID: %3 Codec ID: %4 Type: %5 Bitrate: %6").arg(
2159  QString::number(strm),
2160  QString::number(static_cast<uint64_t>(m_ic->streams[strm]->id), 16),
2161  program_id,
2162  avcodec_get_name(par->codec_id),
2163  codectype,
2164  QString::number(par->bit_rate))
2165  );
2166 
2167  switch (par->codec_type)
2168  {
2169  case AVMEDIA_TYPE_VIDEO:
2170  {
2171  // reset any potentially errored hardware decoders
2173  {
2174  if (m_codecMap.FindCodecContext(m_ic->streams[strm]))
2175  {
2176  AVCodecContext* ctx = m_codecMap.GetCodecContext(m_ic->streams[strm]);
2177  if (ctx && (ctx->hw_frames_ctx || ctx->hw_device_ctx))
2178  m_codecMap.FreeCodecContext(m_ic->streams[strm]);
2179  }
2180  }
2181 
2182  if (!par->codec_id)
2183  {
2184  LOG(VB_GENERAL, LOG_ERR, LOC +
2185  QString("Stream #%1 has an unknown video "
2186  "codec id, skipping.").arg(strm));
2187  continue;
2188  }
2189 
2190  // ffmpeg does not return a bitrate for several codecs and
2191  // formats. Typically the same streams do not have a duration either
2192  // - so we cannot estimate a bitrate (which would be subject
2193  // to significant error anyway if there were multiple video streams).
2194  // So we need to guesstimate a value that avoids low bitrate optimisations
2195  // (which typically kick in around 500,000) and provides a read
2196  // chunk size large enough to avoid starving the decoder of data.
2197  // Trying to read a 20Mbs stream with a 16KB chunk size does not work:)
2198  if (par->bit_rate == 0)
2199  {
2200  static constexpr int64_t s_baseBitrate { 1000000LL };
2201  int multiplier = 1;
2202  if (par->width && par->height)
2203  {
2204  static const int s_baseSize = 1920 * 1080;
2205  multiplier = ((par->width * par->height) + s_baseSize - 1) / s_baseSize;
2206  multiplier = std::max(multiplier, 1);
2207  }
2208  par->bit_rate = s_baseBitrate * multiplier;
2209  unknownbitrate = true;
2210  }
2211  m_bitrate += par->bit_rate;
2212 
2213  break;
2214  }
2215  case AVMEDIA_TYPE_AUDIO:
2216  {
2217  LOG(VB_GENERAL, LOG_INFO, LOC +
2218  QString("codec %1 has %2 channels")
2219  .arg(avcodec_get_name(par->codec_id))
2220  .arg(par->ch_layout.nb_channels));
2221 
2222  m_bitrate += par->bit_rate;
2223  break;
2224  }
2225  case AVMEDIA_TYPE_SUBTITLE:
2226  {
2227  if (par->codec_id == AV_CODEC_ID_DVB_TELETEXT)
2228  ScanTeletextCaptions(static_cast<int>(strm));
2229  if (par->codec_id == AV_CODEC_ID_TEXT)
2230  ScanRawTextCaptions(static_cast<int>(strm));
2231  m_bitrate += par->bit_rate;
2232 
2233  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("subtitle codec (%1)")
2234  .arg(AVMediaTypeToString(par->codec_type)));
2235  break;
2236  }
2237  case AVMEDIA_TYPE_DATA:
2238  {
2239  if (par->codec_id == AV_CODEC_ID_DVB_VBI)
2240  ScanTeletextCaptions(static_cast<int>(strm));
2241  m_bitrate += par->bit_rate;
2242  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("data codec (%1)")
2243  .arg(AVMediaTypeToString(par->codec_type)));
2244  break;
2245  }
2246  case AVMEDIA_TYPE_ATTACHMENT:
2247  {
2248  if (par->codec_id == AV_CODEC_ID_TTF)
2249  m_tracks[kTrackTypeAttachment].emplace_back(static_cast<int>(strm), m_ic->streams[strm]->id);
2250  m_bitrate += par->bit_rate;
2251  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2252  QString("Attachment codec (%1)")
2253  .arg(AVMediaTypeToString(par->codec_type)));
2254  break;
2255  }
2256  default:
2257  {
2258  m_bitrate += par->bit_rate;
2259  LOG(VB_PLAYBACK, LOG_ERR, LOC +
2260  QString("Unknown codec type (%1)")
2261  .arg(AVMediaTypeToString(par->codec_type)));
2262  break;
2263  }
2264  }
2265 
2266  if (par->codec_type != AVMEDIA_TYPE_AUDIO &&
2267  par->codec_type != AVMEDIA_TYPE_SUBTITLE)
2268  continue;
2269 
2270  // skip DVB teletext and text subs, there is no libavcodec decoder
2271  if (par->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2272  (par->codec_id == AV_CODEC_ID_DVB_TELETEXT ||
2273  par->codec_id == AV_CODEC_ID_TEXT))
2274  continue;
2275 
2276  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Looking for decoder for %1")
2277  .arg(avcodec_get_name(par->codec_id)));
2278 
2279  if (par->codec_id == AV_CODEC_ID_PROBE)
2280  {
2281  LOG(VB_GENERAL, LOG_ERR, LOC +
2282  QString("Probing of stream #%1 unsuccesful, ignoring.").arg(strm));
2283  continue;
2284  }
2285 
2286  AVCodecContext* codecContext = m_codecMap.GetCodecContext(m_ic->streams[strm]);
2287 
2288  if (codecContext == nullptr)
2289  {
2290  LOG(VB_GENERAL, LOG_WARNING, LOC +
2291  QString("Could not find decoder for codec (%1), ignoring.")
2292  .arg(avcodec_get_name(par->codec_id)));
2293  LOG(VB_LIBAV, LOG_INFO, "For a list of all codecs, run `mythffmpeg -codecs`.");
2294  continue;
2295  }
2296 
2297  if (codecContext->codec && par->codec_id != codecContext->codec_id)
2298  {
2299  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2300  QString("Already opened codec not matching (%1 vs %2). Reopening")
2301  .arg(avcodec_get_name(codecContext->codec_id),
2302  avcodec_get_name(codecContext->codec->id)));
2303  m_codecMap.FreeCodecContext(m_ic->streams[strm]);
2304  codecContext = m_codecMap.GetCodecContext(m_ic->streams[strm]);
2305  }
2306  if (!OpenAVCodec(codecContext, codecContext->codec))
2307  continue;
2308  if (!codecContext)
2309  continue;
2310 
2311  if (!IsValidStream(m_ic->streams[strm]->id))
2312  {
2313  /* Hide this stream if it's not valid in this context.
2314  * This can happen, for example, on a Blu-ray disc if there
2315  * are more physical streams than there is metadata about them.
2316  * (e.g. Despicable Me)
2317  */
2318  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2319  QString("Stream 0x%1 is not valid in this context - skipping")
2320  .arg(m_ic->streams[strm]->id, 4, 16));
2321  continue;
2322  }
2323 
2324  if (par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2325  {
2326  bool forced = (m_ic->streams[strm]->disposition & AV_DISPOSITION_FORCED) != 0;
2327  int lang = GetSubtitleLanguage(subtitleStreamCount, strm);
2328  uint lang_indx = lang_sub_cnt[lang]++;
2329  subtitleStreamCount++;
2330 
2331  m_tracks[kTrackTypeSubtitle].emplace_back(
2332  static_cast<int>(strm), m_ic->streams[strm]->id, lang, lang_indx, forced);
2333 
2334  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2335  QString("Subtitle track #%1 is A/V stream #%2 "
2336  "and is in the %3 language(%4).")
2337  .arg(m_tracks[kTrackTypeSubtitle].size()).arg(strm)
2338  .arg(iso639_key_toName(lang)).arg(lang));
2339  }
2340 
2341  if (par->codec_type == AVMEDIA_TYPE_AUDIO)
2342  {
2343  int lang = GetAudioLanguage(audioStreamCount, strm);
2345  uint lang_indx = lang_aud_cnt[lang]++;
2346  audioStreamCount++;
2347 
2348  int stream_id = m_ic->streams[strm]->id;
2349  if (m_ringBuffer && m_ringBuffer->IsDVD())
2350  {
2351  stream_id = m_ringBuffer->DVD()->GetAudioTrackNum(stream_id);
2352  if (stream_id == -1)
2353  {
2354  // This stream isn't mapped, so skip it
2355  continue;
2356  }
2357  }
2358 
2359  m_tracks[kTrackTypeAudio].emplace_back(
2360  static_cast<int>(strm), stream_id, lang, lang_indx, type);
2361 
2362  if (is_dual_mono(codecContext->ch_layout))
2363  {
2364  lang_indx = lang_aud_cnt[lang]++;
2365  m_tracks[kTrackTypeAudio].emplace_back(
2366  static_cast<int>(strm), stream_id, lang, lang_indx, type);
2367  }
2368 
2369  LOG(VB_AUDIO, LOG_INFO, LOC +
2370  QString("Audio Track #%1, of type (%2) is A/V stream #%3 (id=0x%4) "
2371  "and has %5 channels in the %6 language(%7).")
2372  .arg(m_tracks[kTrackTypeAudio].size()).arg(toString(type))
2373  .arg(strm).arg(m_ic->streams[strm]->id,0,16).arg(codecContext->ch_layout.nb_channels)
2374  .arg(iso639_key_toName(lang)).arg(lang));
2375  }
2376  }
2377 
2378  // Now find best video track to play
2379  m_resetHardwareDecoders = false;
2380  if (!novideo)
2381  {
2382  int stream_index = autoSelectVideoTrack(scanerror);
2384  }
2385 
2386  m_bitrate = std::max(static_cast<uint>(m_ic->bit_rate), m_bitrate);
2387 
2388  if (m_bitrate > 0)
2389  {
2390  m_bitrate = (m_bitrate + 999) / 1000;
2391  if (m_ringBuffer)
2393  }
2394 
2395  // update RingBuffer buffer size
2396  if (m_ringBuffer)
2397  {
2398  m_ringBuffer->SetBufferSizeFactors(unknownbitrate,
2399  QString(m_ic->iformat->name).contains("matroska"));
2400  }
2401 
2403 
2404  for (const auto type : types)
2405  {
2407  }
2408 
2409  // We have to do this here to avoid the NVP getting stuck
2410  // waiting on audio.
2411  if (m_audio->HasAudioIn() && m_tracks[kTrackTypeAudio].empty())
2412  {
2413  m_audio->SetAudioParams(FORMAT_NONE, -1, -1, AV_CODEC_ID_NONE, -1, false);
2414  m_audio->ReinitAudio();
2415  if (m_ringBuffer && m_ringBuffer->IsDVD())
2416  m_audioIn = AudioInfo();
2417  }
2418 
2419  // if we don't have a video stream we still need to make sure some
2420  // video params are set properly
2421  if (m_selectedTrack[kTrackTypeVideo].m_av_stream_index == -1)
2422  {
2423  m_fps = 23.97F; // minimum likey display refresh rate
2424  // N.B. we know longer need a 'dummy' frame to render overlays into
2425  m_parent->SetVideoParams(0, 0, 23.97, 1.0F, false, 0);
2426  }
2427 
2428  if (m_parent->IsErrored())
2429  scanerror = -1;
2430 
2431  if (!novideo && m_selectedTrack[kTrackTypeVideo].m_av_stream_index != -1)
2432  {
2435  }
2436  else
2437  {
2438  /* We don't yet know which AVProgram we want, so iterate through them
2439  all. This should be no more incorrect than using the last PMT when
2440  there are multiple programs. */
2441  for (unsigned i = 0; i < m_ic->nb_programs; i++)
2442  {
2443  ScanDSMCCStreams(m_ic->programs[i]->pmt_section);
2444  }
2445  }
2446 
2447  return scanerror;
2448 }
2449 
2450 bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
2451 {
2452  m_avCodecLock.lock();
2453 #ifdef USING_MEDIACODEC
2454  if (QString("mediacodec") == codec->wrapper_name)
2455  av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(), nullptr);
2456 #endif
2457  int ret = avcodec_open2(avctx, codec, nullptr);
2458  m_avCodecLock.unlock();
2459  if (ret < 0)
2460  {
2461  std::string error;
2462  LOG(VB_GENERAL, LOG_ERR, LOC +
2463  QString("Could not open codec 0x%1, id(%2) type(%3) "
2464  "ignoring. reason %4").arg((uint64_t)avctx,0,16)
2465  .arg(avcodec_get_name(avctx->codec_id),
2466  AVMediaTypeToString(avctx->codec_type),
2468  return false;
2469  }
2470 
2471  LOG(VB_GENERAL, LOG_INFO, LOC +
2472  QString("Opened codec 0x%1, id(%2) type(%3)")
2473  .arg((uint64_t)avctx,0,16)
2474  .arg(avcodec_get_name(avctx->codec_id),
2475  AVMediaTypeToString(avctx->codec_type)));
2476  return true;
2477 }
2478 
2480 {
2482 }
2483 
2484 bool AvFormatDecoder::DoRewindSeek(long long desiredFrame)
2485 {
2486  return DecoderBase::DoRewindSeek(desiredFrame);
2487 }
2488 
2489 void AvFormatDecoder::DoFastForwardSeek(long long desiredFrame, bool &needflush)
2490 {
2491  DecoderBase::DoFastForwardSeek(desiredFrame, needflush);
2492 }
2493 
2496 {
2497  QMutexLocker locker(&m_trackLock);
2498  for (const auto & si : m_tracks[kTrackTypeTeletextCaptions])
2499  if (si.m_language_index == Index)
2500  return si.m_language;
2501  return iso639_str3_to_key("und");
2502 }
2503 
2505 int AvFormatDecoder::GetSubtitleLanguage(uint /*unused*/, uint StreamIndex)
2506 {
2507  AVDictionaryEntry *metatag = av_dict_get(m_ic->streams[StreamIndex]->metadata, "language", nullptr, 0);
2508  return metatag ? get_canonical_lang(metatag->value) : iso639_str3_to_key("und");
2509 }
2510 
2513 {
2514  // This doesn't strictly need write lock but it is called internally while
2515  // write lock is held. All other (external) uses are safe
2516  QMutexLocker locker(&m_trackLock);
2517 
2518  int ret = -1;
2519  for (int i = 0; i < m_pmtTrackTypes.size(); i++)
2520  {
2521  if ((m_pmtTrackTypes[i] == TrackType) && (m_pmtTracks[i].m_stream_id == ServiceNum))
2522  {
2523  ret = m_pmtTracks[i].m_language;
2524  if (!iso639_is_key_undefined(ret))
2525  return ret;
2526  }
2527  }
2528 
2529  for (int i = 0; i < m_streamTrackTypes.size(); i++)
2530  {
2531  if ((m_streamTrackTypes[i] == TrackType) && (m_streamTracks[i].m_stream_id == ServiceNum))
2532  {
2533  ret = m_streamTracks[i].m_language;
2534  if (!iso639_is_key_undefined(ret))
2535  return ret;
2536  }
2537  }
2538 
2539  return ret;
2540 }
2541 
2542 int AvFormatDecoder::GetAudioLanguage(uint AudioIndex, uint StreamIndex)
2543 {
2544  return GetSubtitleLanguage(AudioIndex, StreamIndex);
2545 }
2546 
2548 {
2550  AVStream *stream = m_ic->streams[StreamIndex];
2551 
2552  {
2553  // We only support labelling/filtering of these two types for now
2554  if (stream->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
2556  else if (stream->disposition & AV_DISPOSITION_COMMENT)
2558  else if (stream->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
2560  else if (stream->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
2562  }
2563 
2564  return type;
2565 }
2566 
2580 {
2581  QMutexLocker locker(&m_trackLock);
2582 
2583  // Find the position of the streaminfo in m_tracks[kTrackTypeAudio]
2584  auto current = m_tracks[kTrackTypeAudio].begin();
2585  for (; current != m_tracks[kTrackTypeAudio].end(); ++current)
2586  {
2587  if (current->m_av_stream_index == streamIndex)
2588  break;
2589  }
2590 
2591  if (current == m_tracks[kTrackTypeAudio].end())
2592  {
2593  LOG(VB_GENERAL, LOG_WARNING, LOC +
2594  QString("Invalid stream index passed to "
2595  "SetupAudioStreamSubIndexes: %1").arg(streamIndex));
2596 
2597  return;
2598  }
2599 
2600  // Remove the extra substream or duplicate the current substream
2601  auto next = current + 1;
2602  if (current->m_av_substream_index == -1)
2603  {
2604  // Split stream in two (Language I + Language II)
2605  StreamInfo lang1 = *current;
2606  StreamInfo lang2 = *current;
2607  lang1.m_av_substream_index = 0;
2608  lang2.m_av_substream_index = 1;
2609  *current = lang1;
2610  m_tracks[kTrackTypeAudio].insert(next, lang2);
2611  return;
2612  }
2613 
2614  if ((next == m_tracks[kTrackTypeAudio].end()) ||
2615  (next->m_av_stream_index != streamIndex))
2616  {
2617  QString msg = QString(
2618  "Expected substream 1 (Language I) of stream %1\n\t\t\t"
2619  "following substream 0, found end of list or another stream.")
2620  .arg(streamIndex);
2621 
2622  LOG(VB_GENERAL, LOG_WARNING, LOC + msg);
2623 
2624  return;
2625  }
2626 
2627  // Remove extra stream info
2628  StreamInfo stream = *current;
2629  stream.m_av_substream_index = -1;
2630  *current = stream;
2631  m_tracks[kTrackTypeAudio].erase(next);
2632 }
2633 
2639 {
2640  if (!m_audio->HasAudioIn())
2641  return;
2642 
2643  m_avCodecLock.lock();
2644  bool do_flush = false;
2645  for (uint i = 0; i < m_ic->nb_streams; i++)
2646  {
2647  AVStream *st = m_ic->streams[i];
2648  st->index = i;
2649  AVCodecContext *avctx = m_codecMap.FindCodecContext(st);
2650  if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2651  {
2653  LOG(VB_LIBAV, LOG_DEBUG, QString("removing audio stream (id: 0x%1, index: %2, nb_streams: %3)")
2654  .arg(QString::number(st->id, 16),
2655  QString::number(i),
2656  QString::number(m_ic->nb_streams)
2657  )
2658  );
2659  m_ic->nb_streams--;
2660  if ((m_ic->nb_streams - i) > 0) {
2661  std::memmove(reinterpret_cast<void*>(&m_ic->streams[i]),
2662  reinterpret_cast<const void*>(&m_ic->streams[i + 1]),
2663  (m_ic->nb_streams - i) * sizeof(AVFormatContext*));
2664  }
2665  else
2666  {
2667  m_ic->streams[i] = nullptr;
2668  }
2669  do_flush = true;
2670  i--;
2671  }
2672  }
2673  if (do_flush)
2674  {
2675  avformat_flush(m_ic);
2676  }
2677  m_avCodecLock.unlock();
2678 }
2679 
2680 int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
2681 {
2682  auto *decoder = static_cast<AvFormatDecoder*>(c->opaque);
2684  if (!std::any_of(decoder->m_renderFormats->cbegin(), decoder->m_renderFormats->cend(),
2685  [&type](auto Format) { return type == Format; }))
2686  {
2687  decoder->m_directRendering = false;
2688  return avcodec_default_get_buffer2(c, pic, flags);
2689  }
2690 
2691  decoder->m_directRendering = true;
2692  MythVideoFrame *frame = decoder->GetPlayer()->GetNextVideoFrame();
2693  if (!frame)
2694  return -1;
2695 
2696  // We pre-allocate frames to certain alignments. If the coded size differs from
2697  // those alignments then re-allocate the frame. Changes in frame type (e.g.
2698  // YV12 to NV12) are always reallocated.
2699  int width = (frame->m_width + MYTH_WIDTH_ALIGNMENT - 1) & ~(MYTH_WIDTH_ALIGNMENT - 1);
2700  int height = (frame->m_height + MYTH_HEIGHT_ALIGNMENT - 1) & ~(MYTH_HEIGHT_ALIGNMENT - 1);
2701 
2702  if ((frame->m_type != type) || (pic->width > width) || (pic->height > height))
2703  {
2704  if (!VideoBuffers::ReinitBuffer(frame, type, decoder->m_videoCodecId, pic->width, pic->height))
2705  return -1;
2706  // NB the video frame may now have a new size which is currenly not an issue
2707  // as the underlying size has already been passed through to the player.
2708  // But may cause issues down the line. We should add coded_width/height to
2709  // VideoFrame as well to ensure consistentency through the rendering
2710  // pipeline.
2711  // NB remember to compare coded width/height - not 'true' values - otherwsie
2712  // we continually re-allocate the frame.
2713  //frame->width = c->width;
2714  //frame->height = c->height;
2715  }
2716 
2717  frame->m_colorshifted = false;
2719  for (uint i = 0; i < 3; i++)
2720  {
2721  pic->data[i] = (i < max) ? (frame->m_buffer + frame->m_offsets[i]) : nullptr;
2722  pic->linesize[i] = frame->m_pitches[i];
2723  }
2724 
2725  pic->opaque = frame;
2726 
2727  // Set release method
2728  AVBufferRef *buffer = av_buffer_create(reinterpret_cast<uint8_t*>(frame), 0,
2729  [](void* Opaque, uint8_t* Data)
2730  {
2731  auto *avfd = static_cast<AvFormatDecoder*>(Opaque);
2732  auto *vf = reinterpret_cast<MythVideoFrame*>(Data);
2733  if (avfd && avfd->GetPlayer())
2734  avfd->GetPlayer()->DeLimboFrame(vf);
2735  }
2736  , decoder, 0);
2737  pic->buf[0] = buffer;
2738 
2739  return 0;
2740 }
2741 
2742 #ifdef USING_DXVA2
2743 int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic, int /*flags*/)
2744 {
2745  AvFormatDecoder *nd = (AvFormatDecoder *)(c->opaque);
2746  MythVideoFrame *frame = nd->GetPlayer()->GetNextVideoFrame();
2747 
2748  for (int i = 0; i < 4; i++)
2749  {
2750  pic->data[i] = nullptr;
2751  pic->linesize[i] = 0;
2752  }
2753  pic->opaque = frame;
2754  frame->m_pixFmt = c->pix_fmt;
2755  pic->data[0] = (uint8_t*)frame->m_buffer;
2756  pic->data[3] = (uint8_t*)frame->m_buffer;
2757 
2758  // Set release method
2759  AVBufferRef *buffer =
2760  av_buffer_create((uint8_t*)frame, 0,
2761  [](void* Opaque, uint8_t* Data)
2762  {
2763  AvFormatDecoder *avfd = static_cast<AvFormatDecoder*>(Opaque);
2764  MythVideoFrame *vf = reinterpret_cast<MythVideoFrame*>(Data);
2765  if (avfd && avfd->GetPlayer())
2766  avfd->GetPlayer()->DeLimboFrame(vf);
2767  }
2768  , nd, 0);
2769  pic->buf[0] = buffer;
2770 
2771  return 0;
2772 }
2773 #endif
2774 
2775 void AvFormatDecoder::DecodeCCx08(const uint8_t *buf, uint buf_size)
2776 {
2777  if (buf_size < 3)
2778  return;
2779 
2780  bool had_608 = false;
2781  bool had_708 = false;
2782  for (uint cur = 0; cur + 2 < buf_size; cur += 3)
2783  {
2784  uint cc_code = buf[cur];
2785  bool cc_valid = (cc_code & 0x04) != 0U;
2786 
2787  uint data1 = buf[cur+1];
2788  uint data2 = buf[cur+2];
2789  uint data = (data2 << 8) | data1;
2790  uint cc_type = cc_code & 0x03;
2791 
2792  if (!cc_valid)
2793  {
2794  if (cc_type >= 0x2)
2796  continue;
2797  }
2798 
2799  if (cc_type <= 0x1) // EIA-608 field-1/2
2800  {
2801  if (cc608_good_parity(data))
2802  {
2803  had_608 = true;
2804  m_ccd608->FormatCCField(duration_cast<std::chrono::milliseconds>(m_lastCcPtsu), cc_type, data);
2805  }
2806  }
2807  else
2808  {
2809  had_708 = true;
2810  m_ccd708->decode_cc_data(cc_type, data1, data2);
2811  }
2812  }
2813  UpdateCaptionTracksFromStreams(had_608, had_708);
2814 }
2815 
2817  bool check_608, bool check_708)
2818 {
2819  bool need_change_608 = false;
2820  CC608Seen seen_608;
2821  if (check_608)
2822  {
2823  m_ccd608->GetServices(15s, seen_608);
2824  for (uint i = 0; i < 4; i++)
2825  {
2826  need_change_608 |= (seen_608[i] && !m_ccX08InTracks[i]) ||
2827  (!seen_608[i] && m_ccX08InTracks[i] && !m_ccX08InPmt[i]);
2828  }
2829  }
2830 
2831  bool need_change_708 = false;
2832  cc708_seen_flags seen_708;
2833  if (check_708 || need_change_608)
2834  {
2835  m_ccd708->services(15s, seen_708);
2836  for (uint i = 1; i < 64 && !need_change_608 && !need_change_708; i++)
2837  {
2838  need_change_708 |= (seen_708[i] && !m_ccX08InTracks[i+4]) ||
2839  (!seen_708[i] && m_ccX08InTracks[i+4] && !m_ccX08InPmt[i+4]);
2840  }
2841  if (need_change_708 && !check_608)
2842  m_ccd608->GetServices(15s, seen_608);
2843  }
2844 
2845  if (!need_change_608 && !need_change_708)
2846  return;
2847 
2848  m_trackLock.lock();
2849 
2851 
2852  m_streamTracks.clear();
2853  m_streamTrackTypes.clear();
2854  int av_index = m_selectedTrack[kTrackTypeVideo].m_av_stream_index;
2855  int lang = iso639_str3_to_key("und");
2856  for (int i = 1; i < 64; i++)
2857  {
2858  if (seen_708[i] && !m_ccX08InPmt[i+4])
2859  {
2860  StreamInfo si {av_index, i, lang};
2861  m_streamTracks.push_back(si);
2863  }
2864  }
2865  for (int i = 0; i < 4; i++)
2866  {
2867  if (seen_608[i] && !m_ccX08InPmt[i])
2868  {
2869  if (0==i)
2871  else if (2==i)
2873  else
2874  lang = iso639_str3_to_key("und");
2875 
2876  StreamInfo si {av_index, i+1, lang};
2877  m_streamTracks.push_back(si);
2879  }
2880  }
2881  m_trackLock.unlock();
2883 }
2884 
2886  AVPacket *pkt, bool can_reliably_parse_keyframes)
2887 {
2888  if (m_prevGopPos != 0 && m_keyframeDist != 1)
2889  {
2890  int tempKeyFrameDist = m_framesRead - 1 - m_prevGopPos;
2891  bool reset_kfd = false;
2892 
2893  if (!m_gopSet || m_livetv) // gopset: we've seen 2 keyframes
2894  {
2895  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2896  "gopset not set, syncing positionMap");
2897  SyncPositionMap();
2898  if (tempKeyFrameDist > 0 && !m_livetv)
2899  {
2900  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2901  QString("Initial key frame distance: %1.")
2902  .arg(m_keyframeDist));
2903  m_gopSet = true;
2904  reset_kfd = true;
2905  }
2906  }
2907  else if (m_keyframeDist != tempKeyFrameDist && tempKeyFrameDist > 0)
2908  {
2909  LOG(VB_PLAYBACK, LOG_INFO, LOC +
2910  QString("Key frame distance changed from %1 to %2.")
2911  .arg(m_keyframeDist).arg(tempKeyFrameDist));
2912  reset_kfd = true;
2913  }
2914 
2915  if (reset_kfd)
2916  {
2917  m_keyframeDist = tempKeyFrameDist;
2919 
2921 
2922 #if 0
2923  // also reset length
2924  QMutexLocker locker(&m_positionMapLock);
2925  if (!m_positionMap.empty())
2926  {
2927  long long index = m_positionMap.back().index;
2928  long long totframes = index * m_keyframeDist;
2929  uint length = (uint)((totframes * 1.0F) / m_fps);
2930  m_parent->SetFileLength(length, totframes);
2931  }
2932 #endif
2933  }
2934  }
2935 
2937 
2938  if (can_reliably_parse_keyframes &&
2940  {
2941  long long last_frame = 0;
2942  {
2943  QMutexLocker locker(&m_positionMapLock);
2944  if (!m_positionMap.empty())
2945  last_frame = m_positionMap.back().index;
2946  }
2947 
2948 #if 0
2949  LOG(VB_PLAYBACK, LOG_DEBUG, LOC +
2950  QString("framesRead: %1 last_frame: %2 keyframedist: %3")
2951  .arg(m_framesRead) .arg(last_frame) .arg(m_keyframeDist));
2952 #endif
2953 
2954  // if we don't have an entry, fill it in with what we've just parsed
2955  if (m_framesRead > last_frame && m_keyframeDist > 0)
2956  {
2957  long long startpos = pkt->pos;
2958 
2959  LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +
2960  QString("positionMap[ %1 ] == %2.")
2961  .arg(m_framesRead).arg(startpos));
2962 
2963  PosMapEntry entry = {m_framesRead, m_framesRead, startpos};
2964 
2965  QMutexLocker locker(&m_positionMapLock);
2966  // Create a dummy positionmap entry for frame 0 so that
2967  // seeking will work properly. (See
2968  // DecoderBase::FindPosition() which subtracts
2969  // DecoderBase::indexOffset from each frame number.)
2970  if (m_positionMap.empty())
2971  {
2972  PosMapEntry dur = {0, 0, 0};
2973  m_positionMap.push_back(dur);
2974  }
2975  m_positionMap.push_back(entry);
2977  {
2978  long long duration = m_totalDuration.toFixed(1000LL);
2979  m_frameToDurMap[m_framesRead] = duration;
2980  m_durToFrameMap[duration] = m_framesRead;
2981  }
2982  }
2983 
2984 #if 0
2985  // If we are > 150 frames in and saw no positionmap at all, reset
2986  // length based on the actual bitrate seen so far
2988  {
2989  m_bitrate = (int)((pkt->pos * 8 * m_fps) / (m_framesRead - 1));
2990  float bytespersec = (float)m_bitrate / 8;
2991  float secs = m_ringBuffer->GetRealFileSize() * 1.0F / bytespersec;
2992  m_parent->SetFileLength((int)(secs), (int)(secs * m_fps));
2993  }
2994 #endif
2995  }
2996 }
2997 
2998 static constexpr uint32_t SEQ_START { 0x000001b3 };
2999 static constexpr uint32_t GOP_START { 0x000001b8 };
3000 //static constexpr uint32_t PICTURE_START { 0x00000100 };
3001 static constexpr uint32_t SLICE_MIN { 0x00000101 };
3002 static constexpr uint32_t SLICE_MAX { 0x000001af };
3003 //static constexpr uint32_t SEQ_END_CODE { 0x000001b7 };
3004 
3005 void AvFormatDecoder::MpegPreProcessPkt(AVCodecContext* context, AVStream *stream, AVPacket *pkt)
3006 {
3007  const uint8_t *bufptr = pkt->data;
3008  const uint8_t *bufend = pkt->data + pkt->size;
3009 
3010  while (bufptr < bufend)
3011  {
3012  bufptr = ByteReader::find_start_code_truncated(bufptr, bufend, &m_startCodeState);
3013 
3014  float aspect_override = -1.0F;
3015  if (m_ringBuffer->IsDVD())
3016  aspect_override = m_ringBuffer->DVD()->GetAspectOverride();
3017 
3019  continue;
3020 
3021  if (SEQ_START == m_startCodeState)
3022  {
3023  if (bufptr + 11 >= pkt->data + pkt->size)
3024  continue; // not enough valid data...
3025  const auto *seq = reinterpret_cast<const SequenceHeader*>(bufptr);
3026 
3027  int width = static_cast<int>(seq->width()) >> context->lowres;
3028  int height = static_cast<int>(seq->height()) >> context->lowres;
3029  float aspect = seq->aspect(context->codec_id == AV_CODEC_ID_MPEG1VIDEO);
3030  if (stream->sample_aspect_ratio.num)
3031  aspect = static_cast<float>(av_q2d(stream->sample_aspect_ratio) * width / height);
3032  if (aspect_override > 0.0F)
3033  aspect = aspect_override;
3034  float seqFPS = seq->fps();
3035 
3036  bool changed = (width != m_currentWidth );
3037  changed |= (height != m_currentHeight);
3038  changed |= (seqFPS > static_cast<float>(m_fps)+0.01F) ||
3039  (seqFPS < static_cast<float>(m_fps)-0.01F);
3040 
3041  // some hardware decoders (e.g. VAAPI MPEG2) will reset when the aspect
3042  // ratio changes
3043  bool forceaspectchange = !qFuzzyCompare(m_currentAspect + 10.0F, aspect + 10.0F) &&
3045  m_currentAspect = aspect;
3046 
3047  if (changed || forceaspectchange)
3048  {
3049  // N.B. We now set the default scan to kScan_Ignore as interlaced detection based on frame
3050  // size and rate is extremely error prone and FFmpeg gets it right far more often.
3051  // As for H.264, if a decoder deinterlacer is in operation - the stream must be progressive
3052  bool doublerate = false;
3053  bool decoderdeint = m_mythCodecCtx && m_mythCodecCtx->IsDeinterlacing(doublerate, true);
3054  m_parent->SetVideoParams(width, height, static_cast<double>(seqFPS), m_currentAspect,
3055  forceaspectchange, 2,
3056  decoderdeint ? kScan_Progressive : kScan_Ignore);
3057 
3058  if (context->hw_frames_ctx)
3059  if (context->internal)
3060  avcodec_flush_buffers(context);
3061 
3062  m_currentWidth = width;
3063  m_currentHeight = height;
3064  m_fps = seqFPS;
3065 
3066  m_gopSet = false;
3067  m_prevGopPos = 0;
3068  m_firstVPts = m_lastAPts = m_lastVPts = 0ms;
3069  m_lastCcPtsu = 0us;
3070  m_firstVPtsInuse = true;
3071 
3072  // fps debugging info
3073  float avFPS = GetVideoFrameRate(stream, context);
3074  if ((seqFPS > avFPS+0.01F) || (seqFPS < avFPS-0.01F))
3075  {
3076  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("avFPS(%1) != seqFPS(%2)")
3077  .arg(static_cast<double>(avFPS)).arg(static_cast<double>(seqFPS)));
3078  }
3079  }
3080 
3081  m_seqCount++;
3082 
3083  if (!m_seenGop && m_seqCount > 1)
3084  {
3085  HandleGopStart(pkt, true);
3086  pkt->flags |= AV_PKT_FLAG_KEY;
3087  }
3088  }
3089  else if (GOP_START == m_startCodeState)
3090  {
3091  HandleGopStart(pkt, true);
3092  m_seenGop = true;
3093  pkt->flags |= AV_PKT_FLAG_KEY;
3094  }
3095  }
3096 }
3097 
3098 // Returns the number of frame starts identified in the packet.
3099 int AvFormatDecoder::H264PreProcessPkt(AVCodecContext* context, AVStream *stream, AVPacket *pkt)
3100 {
3101  const uint8_t *buf = pkt->data;
3102  const uint8_t *buf_end = pkt->data + pkt->size;
3103  int num_frames = 0;
3104 
3105  // The parser only understands Annex B/bytestream format - so check for avCC
3106  // format (starts with 0x01) and rely on FFmpeg keyframe detection
3107  if (context->extradata && (context->extradata_size >= 7) && (context->extradata[0] == 0x01))
3108  {
3109  if (pkt->flags & AV_PKT_FLAG_KEY)
3110  HandleGopStart(pkt, false);
3111  return 1;
3112  }
3113 
3114  while (buf < buf_end)
3115  {
3116  buf += m_avcParser->addBytes(buf, static_cast<unsigned int>(buf_end - buf), 0);
3117 
3118  if (m_avcParser->stateChanged())
3119  {
3121  {
3122  if (m_avcParser->onFrameStart())
3123  ++num_frames;
3124 
3125  if (!m_avcParser->onKeyFrameStart())
3126  continue;
3127  }
3128  else
3129  {
3130  continue;
3131  }
3132  }
3133  else
3134  {
3135  continue;
3136  }
3137 
3139  float aspect = get_aspect(*m_avcParser);
3140  int width = static_cast<int>(m_avcParser->pictureWidthCropped());
3141  int height = static_cast<int>(m_avcParser->pictureHeightCropped());
3142  double seqFPS = m_avcParser->frameRate();
3143 
3144  bool res_changed = ((width != m_currentWidth) || (height != m_currentHeight));
3145  bool fps_changed = (seqFPS > 0.0) && ((seqFPS > m_fps + 0.01) ||
3146  (seqFPS < m_fps - 0.01));
3147  bool forcechange = !qFuzzyCompare(aspect + 10.0F, m_currentAspect) &&
3149  m_currentAspect = aspect;
3150 
3151  if (fps_changed || res_changed || forcechange)
3152  {
3153  // N.B. we now set the default scan to kScan_Ignore as interlaced detection based on frame
3154  // size and rate is extremely error prone and FFmpeg gets it right far more often.
3155  // N.B. if a decoder deinterlacer is in use - the stream must be progressive
3156  bool doublerate = false;
3157  bool decoderdeint = m_mythCodecCtx ? m_mythCodecCtx->IsDeinterlacing(doublerate, true) : false;
3158  m_parent->SetVideoParams(width, height, seqFPS, m_currentAspect, forcechange,
3159  static_cast<int>(m_avcParser->getRefFrames()),
3160  decoderdeint ? kScan_Progressive : kScan_Ignore);
3161 
3162  // the SetVideoParams call above will have released all held frames
3163  // when using a hardware frames context - but for H264 (as opposed to mpeg2)
3164  // the codec will still hold references for reference frames (decoded picture buffer).
3165  // Flushing the context will release these references and the old
3166  // hardware context is released correctly before a new one is created.
3167  // TODO check what is needed here when a device context is used
3168  // TODO check whether any codecs need to be flushed for a frame rate change (e.g. mediacodec?)
3169  if (context->hw_frames_ctx && (forcechange || res_changed))
3170  if (context->internal)
3171  avcodec_flush_buffers(context);
3172 
3173  m_currentWidth = width;
3174  m_currentHeight = height;
3175 
3176  if (seqFPS > 0.0)
3177  m_fps = static_cast<float>(seqFPS);
3178 
3179  m_gopSet = false;
3180  m_prevGopPos = 0;
3181  m_firstVPts = m_lastAPts = m_lastVPts = 0ms;
3182  m_lastCcPtsu = 0us;
3183  m_firstVPtsInuse = true;
3184 
3185  // fps debugging info
3186  auto avFPS = static_cast<double>(GetVideoFrameRate(stream, context));
3187  if ((seqFPS > avFPS + 0.01) || (seqFPS < avFPS - 0.01))
3188  {
3189  LOG(VB_PLAYBACK, LOG_INFO, LOC +
3190  QString("avFPS(%1) != seqFPS(%2)").arg(avFPS).arg(seqFPS));
3191  }
3192  }
3193 
3194  HandleGopStart(pkt, true);
3195  pkt->flags |= AV_PKT_FLAG_KEY;
3196  }
3197 
3198  return num_frames;
3199 }
3200 
3201 bool AvFormatDecoder::PreProcessVideoPacket(AVCodecContext* context, AVStream *curstream, AVPacket *pkt)
3202 {
3203  int num_frames = 1;
3204 
3205  if (CODEC_IS_MPEG(context->codec_id))
3206  {
3207  MpegPreProcessPkt(context, curstream, pkt);
3208  }
3209  else if (CODEC_IS_H264(context->codec_id))
3210  {
3211  num_frames = H264PreProcessPkt(context, curstream, pkt);
3212  }
3213  else
3214  {
3215  if (pkt->flags & AV_PKT_FLAG_KEY)
3216  {
3217  HandleGopStart(pkt, false);
3218  m_seenGop = true;
3219  }
3220  else
3221  {
3222  m_seqCount++;
3223  if (!m_seenGop && m_seqCount > 1)
3224  {
3225  HandleGopStart(pkt, false);
3226  }
3227  }
3228  }
3229 
3230  if (m_framesRead == 0 && !m_justAfterChange &&
3231  !(pkt->flags & AV_PKT_FLAG_KEY))
3232  {
3233  av_packet_unref(pkt);
3234  return false;
3235  }
3236 
3237  m_framesRead += num_frames;
3238 
3240  {
3241  // The ffmpeg libraries represent a frame interval of a
3242  // 59.94fps video as 1501/90000 seconds, when it should
3243  // actually be 1501.5/90000 seconds.
3244  MythAVRational pkt_dur {static_cast<int>(pkt->duration)};
3245  pkt_dur *= MythAVRational(curstream->time_base);
3246  if (pkt_dur == MythAVRational(1501, 90000))
3247  pkt_dur = MythAVRational(1001, 60000); // 1501.5/90000
3248  m_totalDuration += pkt_dur;
3249  }
3250 
3251  m_justAfterChange = false;
3252 
3253  if (m_exitAfterDecoded)
3254  m_gotVideoFrame = true;
3255 
3256  return true;
3257 }
3258 
3259 bool AvFormatDecoder::ProcessVideoPacket(AVCodecContext* context, AVStream *curstream, AVPacket *pkt, bool &Retry)
3260 {
3261  int ret = 0;
3262  int gotpicture = 0;
3263  MythAVFrame mpa_pic;
3264  if (!mpa_pic)
3265  return false;
3266 
3267  bool sentPacket = false;
3268  int ret2 = 0;
3269 
3270  m_avCodecLock.lock();
3271 
3272  // SUGGESTION
3273  // Now that avcodec_decode_video2 is deprecated and replaced
3274  // by 2 calls (receive frame and send packet), this could be optimized
3275  // into separate routines or separate threads.
3276  // Also now that it always consumes a whole buffer some code
3277  // in the caller may be able to be optimized.
3278 
3279  // FilteredReceiveFrame will call avcodec_receive_frame and
3280  // apply any codec-dependent filtering
3281  ret = m_mythCodecCtx->FilteredReceiveFrame(context, mpa_pic);
3282 
3283  if (ret == 0)
3284  gotpicture = 1;
3285  else
3286  gotpicture = 0;
3287  if (ret == AVERROR(EAGAIN))
3288  ret = 0;
3289  // If we got a picture do not send the packet until we have
3290  // all available pictures
3291  if (ret==0 && !gotpicture)
3292  {
3293  ret2 = avcodec_send_packet(context, pkt);
3294  if (ret2 == AVERROR(EAGAIN))
3295  {
3296  Retry = true;
3297  ret2 = 0;
3298  }
3299  else
3300  {
3301  sentPacket = true;
3302  }
3303  }
3304  m_avCodecLock.unlock();
3305 
3306  if (ret < 0 || ret2 < 0)
3307  {
3308  std::string error;
3309  if (ret < 0)
3310  {
3311  LOG(VB_GENERAL, LOG_ERR, LOC +
3312  QString("video avcodec_receive_frame error: %1 (%2) gotpicture:%3")
3313  .arg(av_make_error_stdstring(error, ret))
3314  .arg(ret).arg(gotpicture));
3315  }
3316 
3317  if (ret2 < 0)
3318  {
3319  LOG(VB_GENERAL, LOG_ERR, LOC +
3320  QString("video avcodec_send_packet error: %1 (%2) gotpicture:%3")
3321  .arg(av_make_error_stdstring(error, ret2))
3322  .arg(ret2).arg(gotpicture));
3323  }
3324 
3326  {
3327  // If erroring on GPU assist, try switching to software decode
3329  m_parent->SetErrored(QObject::tr("Video Decode Error"));
3330  else
3331  m_streamsChanged = true;
3332  }
3333 
3334  if (m_mythCodecCtx->DecoderNeedsReset(context))
3335  {
3336  LOG(VB_GENERAL, LOG_INFO, LOC + "Decoder needs reset");
3338  }
3339 
3340  if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
3341  {
3342  LOG(VB_PLAYBACK, LOG_INFO, LOC + "FFmpeg external library error - assuming streams changed");
3343  m_streamsChanged = true;
3344  }
3345 
3346  return false;
3347  }
3348 
3349  // averror_count counts sequential errors, so if you have a successful
3350  // packet then reset it
3351  m_averrorCount = 0;
3352  if (gotpicture)
3353  {
3354  LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +
3355  QString("video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4")
3356  .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts)
3357  .arg(mpa_pic->pkt_dts));
3358 
3359  ProcessVideoFrame(context, curstream, mpa_pic);
3360  }
3361 
3362  if (!sentPacket)
3363  {
3364  // MythTV logic expects that only one frame is processed
3365  // Save the packet for later and return.
3366  auto *newPkt = av_packet_clone(pkt);
3367  if (newPkt)
3368  m_storedPackets.prepend(newPkt);
3369  }
3370  return true;
3371 }
3372 
3373 bool AvFormatDecoder::ProcessVideoFrame(AVCodecContext* context, AVStream *Stream, AVFrame *AvFrame)
3374 {
3375  // look for A53 captions
3376  auto * side_data = av_frame_get_side_data(AvFrame, AV_FRAME_DATA_A53_CC);
3377  if (side_data && (side_data->size > 0))
3378  DecodeCCx08(side_data->data, static_cast<uint>(side_data->size));
3379 
3380  auto * frame = static_cast<MythVideoFrame*>(AvFrame->opaque);
3381  if (frame)
3383 
3385  {
3386  // Do nothing, we just want the pts, captions, subtites, etc.
3387  // So we can release the unconverted blank video frame to the
3388  // display queue.
3389  if (frame)
3390  frame->m_directRendering = false;
3391  }
3392  else if (!m_directRendering)
3393  {
3394  MythVideoFrame *oldframe = frame;
3395  frame = m_parent->GetNextVideoFrame();
3396  frame->m_directRendering = false;
3397 
3398  if (!m_mythCodecCtx->RetrieveFrame(context, frame, AvFrame))
3399  {
3400  AVFrame tmppicture;
3401  av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
3402  frame->m_buffer, AV_PIX_FMT_YUV420P, AvFrame->width,
3403  AvFrame->height, IMAGE_ALIGN);
3404  tmppicture.data[0] = frame->m_buffer + frame->m_offsets[0];
3405  tmppicture.data[1] = frame->m_buffer + frame->m_offsets[1];
3406  tmppicture.data[2] = frame->m_buffer + frame->m_offsets[2];
3407  tmppicture.linesize[0] = frame->m_pitches[0];
3408  tmppicture.linesize[1] = frame->m_pitches[1];
3409  tmppicture.linesize[2] = frame->m_pitches[2];
3410 
3411  QSize dim = get_video_dim(*context);
3412  m_swsCtx = sws_getCachedContext(m_swsCtx, AvFrame->width,
3413  AvFrame->height, static_cast<AVPixelFormat>(AvFrame->format),
3414  AvFrame->width, AvFrame->height,
3415  AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
3416  nullptr, nullptr, nullptr);
3417  if (!m_swsCtx)
3418  {
3419  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate sws context");
3420  return false;
3421  }
3422  sws_scale(m_swsCtx, AvFrame->data, AvFrame->linesize, 0, dim.height(),
3423  tmppicture.data, tmppicture.linesize);
3424  }
3425 
3426  // Discard any old VideoFrames
3427  if (oldframe)
3428  {
3429  // Set the frame flags, but then discard it
3430  // since we are not using it for display.
3431  oldframe->m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3432  oldframe->m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3433  oldframe->m_colorspace = AvFrame->colorspace;
3434  oldframe->m_colorrange = AvFrame->color_range;
3435  oldframe->m_colorprimaries = AvFrame->color_primaries;
3436  oldframe->m_colortransfer = AvFrame->color_trc;
3437  oldframe->m_chromalocation = AvFrame->chroma_location;
3438  oldframe->m_frameNumber = m_framesPlayed;
3439  oldframe->m_frameCounter = m_frameCounter++;
3440  oldframe->m_aspect = m_currentAspect;
3441  oldframe->m_rotation = m_videoRotation;
3442  oldframe->m_stereo3D = m_stereo3D;
3443 
3444  oldframe->m_dummy = false;
3445  oldframe->m_pauseFrame = false;
3446  oldframe->m_interlacedReverse = false;
3447  oldframe->m_newGOP = false;
3448  oldframe->m_deinterlaceInuse = DEINT_NONE;
3449  oldframe->m_deinterlaceInuse2x = false;
3450  oldframe->m_alreadyDeinterlaced = false;
3451 
3452  m_parent->DiscardVideoFrame(oldframe);
3453  }
3454  }
3455 
3456  if (!frame)
3457  {
3458  LOG(VB_GENERAL, LOG_ERR, LOC + "NULL videoframe - direct rendering not "
3459  "correctly initialized.");
3460  return false;
3461  }
3462 
3463 
3464  if (AvFrame->best_effort_timestamp == AV_NOPTS_VALUE)
3465  {
3466  LOG(VB_GENERAL, LOG_ERR, LOC + "No PTS found - unable to process video.");
3467  return false;
3468  }
3469  std::chrono::milliseconds pts = millisecondsFromFloat(av_q2d(Stream->time_base) *
3470  AvFrame->best_effort_timestamp * 1000);
3471  std::chrono::milliseconds temppts = pts;
3472  // Validate the video pts against the last pts. If it's
3473  // a little bit smaller, equal or missing, compute
3474  // it from the last. Otherwise assume a wraparound.
3475  if (!m_ringBuffer->IsDVD() &&
3476  temppts <= m_lastVPts &&
3477  (temppts + millisecondsFromFloat(1000 / m_fps) > m_lastVPts ||
3478  temppts <= 0ms))
3479  {
3480  temppts = m_lastVPts;
3481  temppts += millisecondsFromFloat(1000 / m_fps);
3482  // MPEG2/H264 frames can be repeated, update pts accordingly
3483  temppts += millisecondsFromFloat(AvFrame->repeat_pict * 500 / m_fps);
3484  }
3485 
3486  // Calculate actual fps from the pts values.
3487  std::chrono::milliseconds ptsdiff = temppts - m_lastVPts;
3488  double calcfps = 1000.0 / ptsdiff.count();
3489  if (calcfps < 121.0 && calcfps > 3.0)
3490  {
3491  // If fps has doubled due to frame-doubling deinterlace
3492  // Set fps to double value.
3493  double fpschange = calcfps / m_fps;
3494  int prior = m_fpsMultiplier;
3495  if (fpschange > 1.9 && fpschange < 2.1)
3496  m_fpsMultiplier = 2;
3497  if (fpschange > 0.9 && fpschange < 1.1)
3498  m_fpsMultiplier = 1;
3499  if (m_fpsMultiplier != prior)
3501  }
3502 
3503  LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +
3504  QString("video timecode %1 %2 %3 %4%5")
3505  .arg(AvFrame->best_effort_timestamp)
3506  .arg(pts.count()).arg(temppts.count()).arg(m_lastVPts.count())
3507  .arg((pts != temppts) ? " fixup" : ""));
3508 
3509  frame->m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3510  frame->m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3511  frame->m_newGOP = m_nextDecodedFrameIsKeyFrame;
3512  frame->m_repeatPic = AvFrame->repeat_pict != 0;
3513  frame->m_displayTimecode = NormalizeVideoTimecode(Stream, std::chrono::milliseconds(temppts));
3514  frame->m_frameNumber = m_framesPlayed;
3515  frame->m_frameCounter = m_frameCounter++;
3516  frame->m_aspect = m_currentAspect;
3517  frame->m_colorspace = AvFrame->colorspace;
3518  frame->m_colorrange = AvFrame->color_range;
3519  frame->m_colorprimaries = AvFrame->color_primaries;
3520  frame->m_colortransfer = AvFrame->color_trc;
3521  frame->m_chromalocation = AvFrame->chroma_location;
3522  frame->m_pixFmt = AvFrame->format;
3523  frame->m_deinterlaceInuse = DEINT_NONE;
3524  frame->m_rotation = m_videoRotation;
3525  frame->m_stereo3D = m_stereo3D;
3526 
3527  frame->m_dummy = false;
3528  frame->m_pauseFrame = false;
3529  frame->m_deinterlaceInuse2x = false;
3530  frame->m_alreadyDeinterlaced = false;
3531  frame->m_interlacedReverse = false;
3532 
3533  // Retrieve HDR metadata
3534  MythHDRVideoMetadata::Populate(frame, AvFrame);
3535 
3536  m_parent->ReleaseNextVideoFrame(frame, std::chrono::milliseconds(temppts));
3537  m_mythCodecCtx->PostProcessFrame(context, frame);
3538 
3540  m_decodedVideoFrame = frame;
3541  m_gotVideoFrame = true;
3542  if (++m_fpsSkip >= m_fpsMultiplier)
3543  {
3544  ++m_framesPlayed;
3545  m_fpsSkip = 0;
3546  }
3547 
3548  m_lastVPts = temppts;
3549  if ((m_firstVPts == 0ms) && m_firstVPtsInuse)
3550  m_firstVPts = temppts;
3551 
3552  return true;
3553 }
3554 
3561  [[maybe_unused]] const AVStream *stream, const AVPacket *pkt)
3562 {
3563  const uint8_t *buf = pkt->data;
3564  uint64_t linemask = 0;
3565  std::chrono::microseconds utc = m_lastCcPtsu;
3566 
3567  // [i]tv0 means there is a linemask
3568  // [I]TV0 means there is no linemask and all lines are present
3569  if ((buf[0]=='t') && (buf[1]=='v') && (buf[2] == '0'))
3570  {
3572  memcpy(&linemask, buf + 3, 8);
3573  buf += 11;
3574  }
3575  else if ((buf[0]=='T') && (buf[1]=='V') && (buf[2] == '0'))
3576  {
3577  linemask = 0xffffffffffffffffLL;
3578  buf += 3;
3579  }
3580  else
3581  {
3582  LOG(VB_VBI, LOG_ERR, LOC + QString("Unknown VBI data stream '%1%2%3'")
3583  .arg(QChar(buf[0])).arg(QChar(buf[1])).arg(QChar(buf[2])));
3584  return;
3585  }
3586 
3587  static constexpr uint kMinBlank = 6;
3588  for (uint i = 0; i < 36; i++)
3589  {
3590  if (!((linemask >> i) & 0x1))
3591  continue;
3592 
3593  const uint line = ((i < 18) ? i : i-18) + kMinBlank;
3594  const uint field = (i<18) ? 0 : 1;
3595  const uint id2 = *buf & 0xf;
3596  switch (id2)
3597  {
3599  // SECAM lines 6-23
3600  // PAL lines 6-22
3601  // NTSC lines 10-21 (rare)
3602  m_trackLock.lock();
3603  if (m_tracks[kTrackTypeTeletextMenu].empty())
3604  {
3605  StreamInfo si {pkt->stream_index, 0};
3606  m_trackLock.lock();
3607  m_tracks[kTrackTypeTeletextMenu].push_back(si);
3608  m_trackLock.unlock();
3610  }
3611  m_trackLock.unlock();
3612  m_ttd->Decode(buf+1, VBI_IVTV);
3613  break;
3615  // PAL line 22 (rare)
3616  // NTSC line 21
3617  if (21 == line)
3618  {
3619  int data = (buf[2] << 8) | buf[1];
3620  if (cc608_good_parity(data))
3621  m_ccd608->FormatCCField(duration_cast<std::chrono::milliseconds>(utc), field, data);
3622  utc += 33367us;
3623  }
3624  break;
3625  case V4L2_MPEG_VBI_IVTV_VPS: // Video Programming System
3626  // PAL line 16
3627  m_ccd608->DecodeVPS(buf+1); // a.k.a. PDC
3628  break;
3629  case V4L2_MPEG_VBI_IVTV_WSS_625: // Wide Screen Signal
3630  // PAL line 23
3631  // NTSC line 20
3632  m_ccd608->DecodeWSS(buf+1);
3633  break;
3634  }
3635  buf += 43;
3636  }
3637  m_lastCcPtsu = utc;
3638  UpdateCaptionTracksFromStreams(true, false);
3639 }
3640 
3646  const AVStream* /*stream*/, const AVPacket *pkt)
3647 {
3648  // ETSI EN 301 775 V1.2.1 (2003-05)
3649  // Check data_identifier value
3650  // Defined in 4.4.2 Semantics for PES data field, Table 2
3651  // Support only the "low range" 0x10-0x1F because they have
3652  // the fixed data_unit_length of 0x2C (44) that the teletext
3653  // decoder expects.
3654  //
3655  const uint8_t *buf = pkt->data;
3656  const uint8_t *buf_end = pkt->data + pkt->size;
3657 
3658  if (*buf >= 0x10 && *buf <= 0x1F)
3659  {
3660  buf++;
3661  }
3662  else
3663  {
3664  LOG(VB_VBI, LOG_WARNING, LOC +
3665  QString("VBI: Unknown data_identier: %1 discarded").arg(*buf));
3666  return;
3667  }
3668 
3669  // Process data packets in the PES packet payload
3670  while (buf < buf_end)
3671  {
3672  if (*buf == 0x02) // data_unit_id 0x02 EBU Teletext non-subtitle data
3673  {
3674  buf += 4; // Skip data_unit_id, data_unit_length (0x2C, 44) and first two data bytes
3675  if ((buf_end - buf) >= 42)
3676  m_ttd->Decode(buf, VBI_DVB);
3677  buf += 42;
3678  }
3679  else if (*buf == 0x03) // data_unit_id 0x03 EBU Teletext subtitle data
3680  {
3681  buf += 4;
3682  if ((buf_end - buf) >= 42)
3683  m_ttd->Decode(buf, VBI_DVB_SUBTITLE);
3684  buf += 42;
3685  }
3686  else if (*buf == 0xff) // data_unit_id 0xff stuffing
3687  {
3688  buf += 46; // data_unit_id, data_unit_length and 44 data bytes
3689  }
3690  else
3691  {
3692  LOG(VB_VBI, LOG_WARNING, LOC +
3693  QString("VBI: Unsupported data_unit_id: %1 discarded").arg(*buf));
3694  buf += 46;
3695  }
3696  }
3697 }
3698 
3702 void AvFormatDecoder::ProcessDSMCCPacket([[maybe_unused]] const AVStream *str,
3703  [[maybe_unused]] const AVPacket *pkt)
3704 {
3705 #ifdef USING_MHEG
3706  if (m_itv == nullptr)
3708  if (m_itv == nullptr)
3709  return;
3710 
3711  // The packet may contain several tables.
3712  uint8_t *data = pkt->data;
3713  int length = pkt->size;
3714  int componentTag = 0;
3715  int dataBroadcastId = 0;
3716  unsigned carouselId = 0;
3717  {
3718  m_avCodecLock.lock();
3719  componentTag = str->component_tag;
3720  dataBroadcastId = str->data_id;
3721  carouselId = (unsigned) str->carousel_id;
3722  m_avCodecLock.unlock();
3723  }
3724  while (length > 3)
3725  {
3726  uint16_t sectionLen = (((data[1] & 0xF) << 8) | data[2]) + 3;
3727 
3728  if (sectionLen > length) // This may well be filler
3729  return;
3730 
3731  m_itv->ProcessDSMCCSection(data, sectionLen,
3732  componentTag, carouselId,
3733  dataBroadcastId);
3734  length -= sectionLen;
3735  data += sectionLen;
3736  }
3737 #endif // USING_MHEG
3738 }
3739 
3740 bool AvFormatDecoder::ProcessSubtitlePacket(AVCodecContext* codecContext, AVStream *curstream, AVPacket *pkt)
3741 {
3742  if (!m_parent->GetSubReader(pkt->stream_index))
3743  return true;
3744 
3745  long long pts = pkt->pts;
3746  if (pts == AV_NOPTS_VALUE)
3747  pts = pkt->dts;
3748  if (pts == AV_NOPTS_VALUE)
3749  {
3750  LOG(VB_GENERAL, LOG_ERR, LOC + "No PTS found - unable to process subtitle.");
3751  return false;
3752  }
3753  pts = static_cast<long long>(av_q2d(curstream->time_base) * pts * 1000);
3754 
3755  m_trackLock.lock();
3756  int subIdx = m_selectedTrack[kTrackTypeSubtitle].m_av_stream_index;
3757  int forcedSubIdx = m_selectedForcedTrack[kTrackTypeSubtitle].m_av_stream_index;
3758  bool mainTrackIsForced = m_selectedTrack[kTrackTypeSubtitle].m_forced;
3759  bool isForcedTrack = false;
3760  m_trackLock.unlock();
3761 
3762  int gotSubtitles = 0;
3763  AVSubtitle subtitle;
3764  memset(&subtitle, 0, sizeof(AVSubtitle));
3765 
3766  if (m_ringBuffer->IsDVD())
3767  {
3768  if (m_ringBuffer->DVD()->NumMenuButtons() > 0)
3769  {
3770  m_ringBuffer->DVD()->GetMenuSPUPkt(pkt->data, pkt->size,
3771  curstream->id, pts);
3772  }
3773  else
3774  {
3775  if (pkt->stream_index == subIdx)
3776  {
3777  m_avCodecLock.lock();
3778  m_ringBuffer->DVD()->DecodeSubtitles(&subtitle, &gotSubtitles,
3779  pkt->data, pkt->size, pts);
3780  m_avCodecLock.unlock();
3781  }
3782  }
3783  }
3784  else if (m_decodeAllSubtitles || pkt->stream_index == subIdx
3785  || pkt->stream_index == forcedSubIdx)
3786  {
3787  m_avCodecLock.lock();
3788  avcodec_decode_subtitle2(codecContext, &subtitle, &gotSubtitles, pkt);
3789  m_avCodecLock.unlock();
3790 
3791  subtitle.start_display_time += pts;
3792  subtitle.end_display_time += pts;
3793 
3794  if (pkt->stream_index != subIdx)
3795  isForcedTrack = true;
3796  }
3797 
3798  if (gotSubtitles)
3799  {
3800  if (isForcedTrack)
3801  {
3802  for (unsigned i = 0; i < subtitle.num_rects; i++)
3803  {
3804  subtitle.rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
3805  }
3806  }
3807  LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC +
3808  QString("subtl timecode %1 %2 %3 %4")
3809  .arg(pkt->pts).arg(pkt->dts)
3810  .arg(subtitle.start_display_time)
3811  .arg(subtitle.end_display_time));
3812 
3813  bool forcedon = m_parent->GetSubReader(pkt->stream_index)->AddAVSubtitle(
3814  subtitle, curstream->codecpar->codec_id == AV_CODEC_ID_XSUB,
3815  isForcedTrack,
3816  (m_parent->GetAllowForcedSubtitles() && !mainTrackIsForced), false);
3817  m_parent->EnableForcedSubtitles(forcedon || isForcedTrack);
3818  }
3819 
3820  return true;
3821 }
3822 
3824 {
3825  if (!m_decodeAllSubtitles && m_selectedTrack[kTrackTypeRawText].m_av_stream_index != Packet->stream_index)
3826  return false;
3827 
3828  auto id = static_cast<uint>(Packet->stream_index + 0x2000);
3829  if (!m_parent->GetSubReader(id))
3830  return false;
3831 
3832 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3833  const auto * codec = QTextCodec::codecForName("utf-8");
3834  auto text = codec->toUnicode(reinterpret_cast<const char *>(Packet->data), Packet->size - 1);
3835 #else
3836  auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
3837  QString text = toUtf16.decode(Packet->data);
3838 #endif
3839  auto list = text.split('\n', Qt::SkipEmptyParts);
3840  m_parent->GetSubReader(id)->AddRawTextSubtitle(list, std::chrono::milliseconds(Packet->duration));
3841  return true;
3842 }
3843 
3844 bool AvFormatDecoder::ProcessDataPacket(AVStream *curstream, AVPacket *pkt,
3845  [[maybe_unused]] DecodeType decodetype)
3846 {
3847  enum AVCodecID codec_id = curstream->codecpar->codec_id;
3848 
3849  switch (codec_id)
3850  {
3851  case AV_CODEC_ID_MPEG2VBI:
3852  ProcessVBIDataPacket(curstream, pkt);
3853  break;
3854  case AV_CODEC_ID_DVB_VBI:
3855  ProcessDVBDataPacket(curstream, pkt);
3856  break;
3857  case AV_CODEC_ID_DSMCC_B:
3858  {
3859  ProcessDSMCCPacket(curstream, pkt);
3861  // Have to return regularly to ensure that the OSD is updated.
3862  // This applies both to MHEG and also channel browsing.
3863 #ifdef USING_MHEG
3864  if (!(decodetype & kDecodeVideo))
3866 #endif // USING_MHEG:
3867  break;
3868  }
3869  default:
3870  break;
3871  }
3872  return true;
3873 }
3874 
3875 int AvFormatDecoder::SetTrack(uint Type, int TrackNo)
3876 {
3877  QMutexLocker locker(&m_trackLock);
3878  int ret = DecoderBase::SetTrack(Type, TrackNo);
3879  if (kTrackTypeAudio == Type)
3880  {
3881  QString msg = SetupAudioStream() ? "" : "not ";
3882  LOG(VB_AUDIO, LOG_INFO, LOC + "Audio stream type " + msg + "changed.");
3883  }
3884  return ret;
3885 }
3886 
3888 {
3889  QMutexLocker locker(&m_trackLock);
3890 
3891  if (!m_ic || TrackNo >= m_tracks[type].size())
3892  return "";
3893 
3894  bool forced = m_tracks[type][TrackNo].m_forced;
3895  int lang_key = m_tracks[type][TrackNo].m_language;
3896  QString forcedString = forced ? QObject::tr(" (forced)") : "";
3897 
3898  int av_index = m_tracks[type][TrackNo].m_av_stream_index;
3899  AVStream *stream { nullptr };
3900  if (av_index >= 0 && av_index < (int)m_ic->nb_streams)
3901  stream = m_ic->streams[av_index];
3902  AVDictionaryEntry *entry =
3903  stream ? av_dict_get(stream->metadata, "title", nullptr, 0) : nullptr;
3904  QString user_title = entry ? QString(R"( "%1")").arg(entry->value) : "";
3905 
3906  if (kTrackTypeAudio == type)
3907  {
3908  QString msg = iso639_key_toName(lang_key);
3909 
3910  switch (m_tracks[type][TrackNo].m_audio_type)
3911  {
3912  case kAudioTypeNormal :
3913  {
3914  if (stream)
3915  {
3916  AVCodecParameters *par = stream->codecpar;
3917  AVCodecContext *ctx = m_codecMap.GetCodecContext(stream);
3918  if (par->codec_id == AV_CODEC_ID_MP3)
3919  msg += QString(" MP3");
3920  else if (ctx && ctx->codec)
3921  msg += QString(" %1").arg(ctx->codec->name).toUpper();
3922  if (!user_title.isEmpty())
3923  msg += user_title;
3924 
3925  int channels = par->ch_layout.nb_channels;
3926 
3927  if (channels == 0)
3928  msg += QString(" ?ch");
3929  else if((channels > 4) && !(channels & 1))
3930  msg += QString(" %1.1ch").arg(channels - 1);
3931  else
3932  msg += QString(" %1ch").arg(channels);
3933  }
3934  break;
3935  }
3937  case kAudioTypeCommentary :
3939  case kAudioTypeCleanEffects :
3940  case kAudioTypeSpokenSubs :
3941  default :
3942  if (!user_title.isEmpty())
3943  msg += user_title;
3944  else
3945  msg += QString(" (%1)")
3946  .arg(toString(m_tracks[type][TrackNo].m_audio_type));
3947  break;
3948  }
3949  return QString("%1: %2").arg(TrackNo + 1).arg(msg);
3950  }
3951  if (kTrackTypeSubtitle == type)
3952  {
3953  return QObject::tr("Subtitle") + QString(" %1: %2%3%4")
3954  .arg(QString::number(TrackNo + 1),
3955  iso639_key_toName(lang_key),
3956  user_title,
3957  forcedString);
3958  }
3959  if (forced && kTrackTypeRawText == type)
3960  return DecoderBase::GetTrackDesc(type, TrackNo) + forcedString;
3961  return DecoderBase::GetTrackDesc(type, TrackNo);
3962 }
3963 
3965 {
3966  return m_ttd->GetDecoderType();
3967 }
3968 
3969 QString AvFormatDecoder::GetXDS(const QString &Key) const
3970 {
3971  return m_ccd608->GetXDS(Key);
3972 }
3973 
3975 {
3976  QMutexLocker locker(&m_trackLock);
3977  if (TrackNo >= m_tracks[kTrackTypeSubtitle].size())
3978  return {};
3979 
3980  int index = m_tracks[kTrackTypeSubtitle][TrackNo].m_av_stream_index;
3981  AVCodecContext *ctx = m_codecMap.GetCodecContext(m_ic->streams[index]);
3982  return ctx ? QByteArray(reinterpret_cast<char*>(ctx->subtitle_header), ctx->subtitle_header_size) :
3983  QByteArray();
3984 }
3985 
3986 void AvFormatDecoder::GetAttachmentData(uint TrackNo, QByteArray &Filename, QByteArray &Data)
3987 {
3988  QMutexLocker locker(&m_trackLock);
3989  if (TrackNo >= m_tracks[kTrackTypeAttachment].size())
3990  return;
3991 
3992  int index = m_tracks[kTrackTypeAttachment][TrackNo].m_av_stream_index;
3993  AVDictionaryEntry *tag = av_dict_get(m_ic->streams[index]->metadata, "filename", nullptr, 0);
3994  if (tag)
3995  Filename = QByteArray(tag->value);
3996  AVCodecParameters *par = m_ic->streams[index]->codecpar;
3997  Data = QByteArray(reinterpret_cast<char*>(par->extradata), par->extradata_size);
3998 }
3999 
4001 {
4002  QMutexLocker locker(&m_trackLock);
4003  for (size_t i = 0; i < m_tracks[kTrackTypeAudio].size(); i++)
4004  {
4005  AVStream *stream = m_ic->streams[m_tracks[kTrackTypeAudio][i].m_av_stream_index];
4006  if (stream)
4007  if ((stream->component_tag == Tag) || ((Tag <= 0) && stream->component_tag <= 0))
4008  return SetTrack(kTrackTypeAudio, static_cast<int>(i)) != -1;
4009  }
4010  return false;
4011 }
4012 
4014 {
4015  QMutexLocker locker(&m_trackLock);
4016  for (uint i = 0; i < m_ic->nb_streams; i++)
4017  {
4018  AVStream *stream = m_ic->streams[i];
4019  if (stream)
4020  {
4021  if (stream->component_tag == Tag)
4022  {
4023  StreamInfo si {static_cast<int>(i), 0};
4025  return true;
4026  }
4027  }
4028  }
4029  return false;
4030 }
4031 
4032 // documented in decoderbase.cpp
4034 {
4035  if (kTrackTypeAudio == type)
4036  return AutoSelectAudioTrack();
4037 
4039  return -1;
4040 
4042 }
4043 
4044 static std::vector<int> filter_lang(const sinfo_vec_t &tracks, int lang_key,
4045  const std::vector<int> &ftype)
4046 {
4047  std::vector<int> ret;
4048 
4049  for (int index : ftype)
4050  {
4051  if ((lang_key < 0) || tracks[index].m_language == lang_key)
4052  ret.push_back(index);
4053  }
4054 
4055  return ret;
4056 }
4057 
4058 static std::vector<int> filter_type(const sinfo_vec_t &tracks, AudioTrackType type)
4059 {
4060  std::vector<int> ret;
4061 
4062  for (size_t i = 0; i < tracks.size(); i++)
4063  {
4064  if (tracks[i].m_audio_type == type)
4065  ret.push_back(i);
4066  }
4067 
4068  return ret;
4069 }
4070 
4071 int AvFormatDecoder::filter_max_ch(const AVFormatContext *ic,
4072  const sinfo_vec_t &tracks,
4073  const std::vector<int>&fs,
4074  enum AVCodecID codecId,
4075  int profile)
4076 {
4077  int selectedTrack = -1;
4078  int max_seen = -1;
4079 
4080  for (int f : fs)
4081  {
4082  const int stream_index = tracks[f].m_av_stream_index;
4083  AVCodecParameters *par = ic->streams[stream_index]->codecpar;
4084  if ((codecId == AV_CODEC_ID_NONE || codecId == par->codec_id) &&
4085  (max_seen < par->ch_layout.nb_channels))
4086  {
4087  if (codecId == AV_CODEC_ID_DTS && profile > 0)
4088  {
4089  // we cannot decode dts-hd, so only select it if passthrough
4090  if (!DoPassThrough(par, true) || par->profile != profile)
4091  continue;
4092  }
4093  selectedTrack = f;
4094  max_seen = par->ch_layout.nb_channels;
4095  }
4096  }
4097 
4098  return selectedTrack;
4099 }
4100 
4101 int AvFormatDecoder::selectBestAudioTrack(int lang_key, const std::vector<int> &ftype)
4102 {
4103  const sinfo_vec_t &atracks = m_tracks[kTrackTypeAudio];
4104  int selTrack = -1;
4105 
4106  std::vector<int> flang = filter_lang(atracks, lang_key, ftype);
4107 
4108  if (m_audio->CanDTSHD())
4109  {
4110  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_DTS,
4111  FF_PROFILE_DTS_HD_MA);
4112  if (selTrack >= 0)
4113  return selTrack;
4114  }
4115  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_TRUEHD);
4116  if (selTrack >= 0)
4117  return selTrack;
4118 
4119  if (m_audio->CanDTSHD())
4120  {
4121  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_DTS,
4122  FF_PROFILE_DTS_HD_HRA);
4123  if (selTrack >= 0)
4124  return selTrack;
4125  }
4126  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_EAC3);
4127  if (selTrack >= 0)
4128  return selTrack;
4129 
4130  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_DTS);
4131  if (selTrack >= 0)
4132  return selTrack;
4133 
4134  selTrack = filter_max_ch(m_ic, atracks, flang, AV_CODEC_ID_AC3);
4135  if (selTrack >= 0)
4136  return selTrack;
4137 
4138  selTrack = filter_max_ch(m_ic, atracks, flang);
4139 
4140  return selTrack;
4141 }
4142 
4190 {
4191  QMutexLocker locker(&m_trackLock);
4192 
4193  const sinfo_vec_t &atracks = m_tracks[kTrackTypeAudio];
4196  int &ctrack = m_currentTrack[kTrackTypeAudio];
4197 
4198  uint numStreams = atracks.size();
4199  int selTrack = -1;
4200  if (numStreams > 0)
4201  {
4202  if ((ctrack >= 0) && (ctrack < (int)numStreams))
4203  return ctrack; // audio already selected
4204 
4205  LOG(VB_AUDIO, LOG_DEBUG, QString("%1 available audio streams").arg(numStreams));
4206  for (const auto & track : atracks)
4207  {
4208  AVCodecParameters *codecpar = m_ic->streams[track.m_av_stream_index]->codecpar;
4209  LOG(VB_AUDIO, LOG_DEBUG, QString("%1: %2 bps, %3 Hz, %4 channels, passthrough(%5)")
4210  .arg(avcodec_get_name(codecpar->codec_id), QString::number(codecpar->bit_rate),
4211  QString::number(codecpar->sample_rate), QString::number(codecpar->ch_layout.nb_channels),
4212  (DoPassThrough(codecpar, true)) ? "true" : "false")
4213  );
4214  }
4215 
4216  if (1 == numStreams)
4217  {
4218  selTrack = 0;
4219  }
4220  else
4221  {
4222  int wlang = wtrack.m_language;
4223 
4224  if ((selTrack < 0) && (wtrack.m_av_substream_index >= 0))
4225  {
4226  LOG(VB_AUDIO, LOG_INFO, LOC + "Trying to reselect audio sub-stream");
4227  // Dual stream without language information: choose
4228  // the previous substream that was kept in wtrack,
4229  // ignoring the stream index (which might have changed).
4230  int substream_index = wtrack.m_av_substream_index;
4231 
4232  for (uint i = 0; i < numStreams; i++)
4233  {
4234  if (atracks[i].m_av_substream_index == substream_index)
4235  {
4236  selTrack = i;
4237  break;
4238  }
4239  }
4240  }
4241 
4242  if ((selTrack < 0) && wlang >= -1)
4243  {
4244  LOG(VB_AUDIO, LOG_INFO, LOC + "Trying to reselect audio track");
4245  // Try to reselect user selected audio stream.
4246  // This should find the stream after a commercial
4247  // break and in some cases after a channel change.
4248  uint windx = wtrack.m_language_index;
4249  for (uint i = 0; i < numStreams; i++)
4250  {
4251  if (wlang == atracks[i].m_language)
4252  {
4253  selTrack = i;
4254 
4255  if (windx == atracks[i].m_language_index)
4256  break;
4257  }
4258  }
4259  }
4260 
4261  if (selTrack < 0)
4262  {
4263  LOG(VB_AUDIO, LOG_INFO, LOC + "Trying to select audio track (w/lang)");
4264 
4265  // Filter out commentary and audio description tracks
4266  std::vector<int> ftype = filter_type(atracks, kAudioTypeNormal);
4267 
4268  if (ftype.empty())
4269  {
4270  LOG(VB_AUDIO, LOG_WARNING, "No audio tracks matched the type filter, "
4271  "so trying all tracks.");
4272  for (int i = 0; i < static_cast<int>(atracks.size()); i++)
4273  ftype.push_back(i);
4274  }
4275 
4276  // Try to get the language track for the preferred language for audio
4277  QString language_key_convert = iso639_str2_to_str3(gCoreContext->GetAudioLanguage());
4278  uint language_key = iso639_str3_to_key(language_key_convert);
4279  uint canonical_key = iso639_key_to_canonical_key(language_key);
4280 
4281  selTrack = selectBestAudioTrack(canonical_key, ftype);
4282 
4283  // Try to get best track for most preferred language for audio.
4284  // Set by the "Guide Data" "Audio Language" preference in Appearance.
4285  if (selTrack < 0)
4286  {
4287  auto it = m_languagePreference.begin();
4288  for (; it != m_languagePreference.end() && selTrack < 0; ++it)
4289  {
4290  selTrack = selectBestAudioTrack(*it, ftype);
4291  }
4292  }
4293 
4294  // Could not select track based on user preferences (audio language)
4295  // Try to select the default track
4296  if (selTrack < 0)
4297  {
4298  LOG(VB_AUDIO, LOG_INFO, LOC + "Trying to select default track");
4299  for (size_t i = 0; i < atracks.size(); i++) {
4300  int idx = atracks[i].m_av_stream_index;
4301  if (m_ic->streams[idx]->disposition & AV_DISPOSITION_DEFAULT)
4302  {
4303  selTrack = i;
4304  break;
4305  }
4306  }
4307  }
4308 
4309  // Try to get best track for any language
4310  if (selTrack < 0)
4311  {
4312  LOG(VB_AUDIO, LOG_INFO, LOC +
4313  "Trying to select audio track (wo/lang)");
4314  selTrack = selectBestAudioTrack(-1, ftype);
4315  }
4316  }
4317  }
4318  }
4319 
4320  if (selTrack < 0)
4321  {
4322  strack.m_av_stream_index = -1;
4323  if (ctrack != selTrack)
4324  {
4325  LOG(VB_AUDIO, LOG_INFO, LOC + "No suitable audio track exists.");
4326  ctrack = selTrack;
4327  }
4328  }
4329  else
4330  {
4331  ctrack = selTrack;
4332  strack = atracks[selTrack];
4333 
4334  if (wtrack.m_av_stream_index < 0)
4335  wtrack = strack;
4336 
4337  LOG(VB_AUDIO, LOG_INFO, LOC + QString("Selected track %1 (A/V Stream #%2)")
4338  .arg(static_cast<uint>(ctrack)).arg(strack.m_av_stream_index));
4339  }
4340 
4341  SetupAudioStream();
4342  return selTrack;
4343 }
4344 
4345 static void extract_mono_channel(uint channel, AudioInfo *audioInfo,
4346  char *buffer, int bufsize)
4347 {
4348  // Only stereo -> mono (left or right) is supported
4349  if (audioInfo->m_channels != 2)
4350  return;
4351 
4352  if (channel >= (uint)audioInfo->m_channels)
4353  return;
4354 
4355  const uint samplesize = audioInfo->m_sampleSize;
4356  const uint samples = bufsize / samplesize;
4357  const uint halfsample = samplesize >> 1;
4358 
4359  const char *from = (channel == 1) ? buffer + halfsample : buffer;
4360  char *to = (channel == 0) ? buffer + halfsample : buffer;
4361 
4362  for (uint sample = 0; sample < samples;
4363  (sample++), (from += samplesize), (to += samplesize))
4364  {
4365  memmove(to, from, halfsample);
4366  }
4367 }
4368 
4369 bool AvFormatDecoder::ProcessAudioPacket(AVCodecContext* context, AVStream *curstream, AVPacket *pkt,
4370  DecodeType decodetype)
4371 {
4372  int ret = 0;
4373  int data_size = 0;
4374  bool firstloop = true;
4375  int decoded_size = -1;
4376 
4377  m_trackLock.lock();
4378  int audIdx = m_selectedTrack[kTrackTypeAudio].m_av_stream_index;
4379  int audSubIdx = m_selectedTrack[kTrackTypeAudio].m_av_substream_index;
4380  m_trackLock.unlock();
4381 
4382  AVPacket *tmp_pkt = av_packet_alloc();
4383  tmp_pkt->data = pkt->data;
4384  tmp_pkt->size = pkt->size;
4385  while (tmp_pkt->size > 0)
4386  {
4387  bool reselectAudioTrack = false;
4388 
4390  if (!m_audio->HasAudioIn())
4391  {
4392  LOG(VB_AUDIO, LOG_INFO, LOC +
4393  "Audio is disabled - trying to restart it");
4394  reselectAudioTrack = true;
4395  }
4397 
4398  // detect switches between stereo and dual languages
4399  bool wasDual = audSubIdx != -1;
4400  bool isDual = is_dual_mono(context->ch_layout);
4401  if ((wasDual && !isDual) || (!wasDual && isDual))
4402  {
4404  reselectAudioTrack = true;
4405  }
4406 
4407  // detect channels on streams that need
4408  // to be decoded before we can know this
4409  bool already_decoded = false;
4410  if (!context->ch_layout.nb_channels)
4411  {
4412  m_avCodecLock.lock();
4413  if (DoPassThrough(curstream->codecpar, false) || !DecoderWillDownmix(context))
4414  {
4415  // for passthru or codecs for which the decoder won't downmix
4416  // let the decoder set the number of channels. For other codecs
4417  // we downmix if necessary in audiooutputbase
4418  ;
4419  }
4420  else // No passthru, the decoder will downmix
4421  {
4422  AVChannelLayout channel_layout;
4423  av_channel_layout_default(&channel_layout, m_audio->GetMaxChannels());
4424  av_opt_set_chlayout(context->priv_data, "downmix", &channel_layout, 0);
4425 
4426  if (context->codec_id == AV_CODEC_ID_AC3)
4427  context->ch_layout.nb_channels = m_audio->GetMaxChannels();
4428  }
4429 
4430  ret = m_audio->DecodeAudio(context, m_audioSamples, data_size, tmp_pkt);
4431  decoded_size = data_size;
4432  already_decoded = true;
4433  reselectAudioTrack |= context->ch_layout.nb_channels;
4434  m_avCodecLock.unlock();
4435  }
4436 
4437  if (reselectAudioTrack)
4438  {
4439  QMutexLocker locker(&m_trackLock);
4441  m_selectedTrack[kTrackTypeAudio].m_av_stream_index = -1;
4443  audIdx = m_selectedTrack[kTrackTypeAudio].m_av_stream_index;
4444  audSubIdx = m_selectedTrack[kTrackTypeAudio].m_av_substream_index;
4445  }
4446 
4447  if (!(decodetype & kDecodeAudio) || (pkt->stream_index != audIdx)
4448  || !m_audio->HasAudioOut())
4449  break;
4450 
4451  if (firstloop && pkt->pts != AV_NOPTS_VALUE)
4452  m_lastAPts = millisecondsFromFloat(av_q2d(curstream->time_base) * pkt->pts * 1000);
4453 
4454  m_firstVPtsInuse = false;
4455  m_avCodecLock.lock();
4456  data_size = 0;
4457 
4458  // Check if the number of channels or sampling rate have changed
4459  if (context->sample_rate != m_audioOut.m_sampleRate ||
4460  context->ch_layout.nb_channels != m_audioOut.m_channels ||
4461  AudioOutputSettings::AVSampleFormatToFormat(context->sample_fmt,
4462  context->bits_per_raw_sample) != m_audioOut.format)
4463  {
4464  LOG(VB_GENERAL, LOG_INFO, LOC + "Audio stream changed");
4465  if (context->ch_layout.nb_channels != m_audioOut.m_channels)
4466  {
4467  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Number of audio channels changed from %1 to %2")
4468  .arg(m_audioOut.m_channels).arg(context->ch_layout.nb_channels));
4469  }
4470  QMutexLocker locker(&m_trackLock);
4472  m_selectedTrack[kTrackTypeAudio].m_av_stream_index = -1;
4473  audIdx = -1;
4475  }
4476 
4478  {
4479  if (!already_decoded)
4480  {
4482  {
4483  ret = m_audio->DecodeAudio(context, m_audioSamples, data_size, tmp_pkt);
4484  decoded_size = data_size;
4485  }
4486  else
4487  {
4488  decoded_size = -1;
4489  }
4490  }
4491  memcpy(m_audioSamples, tmp_pkt->data, tmp_pkt->size);
4492  data_size = tmp_pkt->size;
4493  // We have processed all the data, there can't be any left
4494  tmp_pkt->size = 0;
4495  }
4496  else
4497  {
4498  if (!already_decoded)
4499  {
4500  if (DecoderWillDownmix(context))
4501  {
4502  AVChannelLayout channel_layout;
4503  av_channel_layout_default(&channel_layout, m_audio->GetMaxChannels());
4504  av_opt_set_chlayout(context->priv_data, "downmix", &channel_layout, 0);
4505  }
4506 
4507  ret = m_audio->DecodeAudio(context, m_audioSamples, data_size, tmp_pkt);
4508  decoded_size = data_size;
4509  }
4510  }
4511  m_avCodecLock.unlock();
4512 
4513  if (ret < 0)
4514  {
4515  LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown audio decoding error");
4516  av_packet_free(&tmp_pkt);
4517  return false;
4518  }
4519 
4520  if (data_size <= 0)
4521  {
4522  tmp_pkt->data += ret;
4523  tmp_pkt->size -= ret;
4524  continue;
4525  }
4526 
4527  std::chrono::milliseconds temppts = m_lastAPts;
4528 
4529  if (audSubIdx != -1 && !m_audioOut.m_doPassthru)
4530  extract_mono_channel(audSubIdx, &m_audioOut,
4531  (char *)m_audioSamples, data_size);
4532 
4533  int samplesize = AudioOutputSettings::SampleSize(m_audio->GetFormat());
4534  int frames = (context->ch_layout.nb_channels <= 0 || decoded_size < 0 || !samplesize) ? -1 :
4535  decoded_size / (context->ch_layout.nb_channels * samplesize);
4536  m_audio->AddAudioData((char *)m_audioSamples, data_size, temppts, frames);
4538  {
4540  }
4541  else
4542  {
4544  ((double)(frames * 1000) / context->sample_rate);
4545  }
4546 
4547  LOG(VB_TIMESTAMP, LOG_INFO, LOC + QString("audio timecode %1 %2 %3 %4")
4548  .arg(pkt->pts).arg(pkt->dts).arg(temppts.count()).arg(m_lastAPts.count()));
4549 
4552 
4553  tmp_pkt->data += ret;
4554  tmp_pkt->size -= ret;
4555  firstloop = false;
4556  }
4557 
4558  av_packet_free(&tmp_pkt);
4559  return true;
4560 }
4561 
4562 // documented in decoderbase.h
4563 bool AvFormatDecoder::GetFrame(DecodeType decodetype, bool &Retry)
4564 {
4565  AVPacket *pkt = nullptr;
4566  bool have_err = false;
4567 
4568  const DecodeType origDecodetype = decodetype;
4569 
4570  m_gotVideoFrame = false;
4571 
4572  m_frameDecoded = 0;
4573  m_decodedVideoFrame = nullptr;
4574 
4575  m_allowedQuit = false;
4576  bool storevideoframes = false;
4577 
4578  m_skipAudio = (m_lastVPts == 0ms);
4579 
4580  if( !m_processFrames )
4581  {
4582  return false;
4583  }
4584 
4585  m_hasVideo = HasVideo();
4586  m_needDummyVideoFrames = false;
4587 
4588  if (!m_hasVideo && (decodetype & kDecodeVideo))
4589  {
4590  // NB This could be an issue if the video stream is not
4591  // detected initially as the video buffers will be filled.
4592  m_needDummyVideoFrames = true;
4593  decodetype = (DecodeType)((int)decodetype & ~kDecodeVideo);
4594  m_skipAudio = false;
4595  }
4596 
4598 
4599  while (!m_allowedQuit)
4600  {
4601  if (decodetype & kDecodeAudio)
4602  {
4603  if (((m_currentTrack[kTrackTypeAudio] < 0) ||
4604  (m_selectedTrack[kTrackTypeAudio].m_av_stream_index < 0)))
4605  {
4606  // disable audio request if there are no audio streams anymore
4607  // and we have video, otherwise allow decoding to stop
4608  if (m_hasVideo)
4609  decodetype = (DecodeType)((int)decodetype & ~kDecodeAudio);
4610  else
4611  m_allowedQuit = true;
4612  }
4613  }
4614  else if ((origDecodetype & kDecodeAudio) &&
4615  (m_currentTrack[kTrackTypeAudio] >= 0) &&
4616  (m_selectedTrack[kTrackTypeAudio].m_av_stream_index >= 0))
4617  {
4618  // Turn on audio decoding again if it was on originally
4619  // and an audio stream has now appeared. This can happen
4620  // in still DVD menus with audio
4621  decodetype = (DecodeType)((int)decodetype | kDecodeAudio);
4622  }
4623 
4625 
4626  if (m_gotVideoFrame)
4627  {
4628  if (decodetype == kDecodeNothing)
4629  {
4630  // no need to buffer audio or video if we
4631  // only care about building a keyframe map.
4632  // NB but allow for data only (MHEG) streams
4633  m_allowedQuit = true;
4634  }
4635  else if ((decodetype & kDecodeAV) == kDecodeAV &&
4636  (m_storedPackets.count() < kMaxVideoQueueSize) &&
4637  // buffer audio to prevent audio buffer
4638  // underruns in case you are setting negative values
4639  // in Adjust Audio Sync.
4642  {
4643  storevideoframes = true;
4644  }
4645  else if (decodetype & kDecodeVideo)
4646  {
4647  if (m_storedPackets.count() >= kMaxVideoQueueSize)
4648  {
4649  LOG(VB_GENERAL, LOG_WARNING, LOC +
4650  QString("Audio %1 ms behind video but already %2 "
4651  "video frames queued. AV-Sync might be broken.")
4652  .arg((m_lastVPts-m_lastAPts).count()).arg(m_storedPackets.count()));
4653  }
4654  m_allowedQuit = true;
4655  continue;
4656  }
4657  }
4658 
4659  if (!storevideoframes && m_storedPackets.count() > 0)
4660  {
4661  if (pkt)
4662  av_packet_free(&pkt);
4663  pkt = m_storedPackets.takeFirst();
4664  }
4665  else
4666  {
4667  if (!pkt)
4668  pkt = av_packet_alloc();
4669 
4670  int retval = 0;
4671  if (m_ic != nullptr)
4672  retval = ReadPacket(m_ic, pkt, storevideoframes);
4673  if ((m_ic == nullptr) || (retval < 0))
4674  {
4675  if (retval == -EAGAIN)
4676  continue;
4677 
4678  SetEof(true);
4679  av_packet_free(&pkt);
4680 
4681  LOG(VB_GENERAL, LOG_ERR, QString("decoding error %1 (%2)")
4682  .arg(QString::fromStdString(av_make_error_stdstring_unknown(retval)),
4683  QString::number(retval)));
4684  return false;
4685  }
4686 
4687  if (m_waitingForChange && pkt->pos >= m_readAdjust)
4688  FileChanged();
4689 
4690  if (pkt->pos > m_readAdjust)
4691  pkt->pos -= m_readAdjust;
4692  }
4693 
4694  if (!m_ic)
4695  {
4696  LOG(VB_GENERAL, LOG_ERR, LOC + "No context");
4697  av_packet_unref(pkt);
4698  continue;
4699  }
4700 
4701  if (pkt->stream_index >= (int)m_ic->nb_streams)
4702  {
4703  LOG(VB_GENERAL, LOG_ERR, LOC + "Bad stream");
4704  av_packet_unref(pkt);
4705  continue;
4706  }
4707 
4708  AVStream *curstream = m_ic->streams[pkt->stream_index];
4709 
4710  if (!curstream)
4711  {
4712  LOG(VB_GENERAL, LOG_ERR, LOC + "Bad stream (NULL)");
4713  av_packet_unref(pkt);
4714  continue;
4715  }
4716 
4717  enum AVMediaType codec_type = curstream->codecpar->codec_type;
4718  const AVCodecID codec_id = curstream->codecpar->codec_id;
4719 
4720  // Handle AVCodecID values that don't have an AVCodec decoder and
4721  // store video packets
4722  switch (codec_type)
4723  {
4724  case AVMEDIA_TYPE_VIDEO:
4725  if (storevideoframes)
4726  {
4727  m_storedPackets.append(pkt);
4728  pkt = nullptr;
4729  continue;
4730  }
4731  break;
4732  case AVMEDIA_TYPE_AUDIO:
4733  // FFmpeg does not currently have an AC-4 decoder
4734  if (codec_id == AV_CODEC_ID_AC4)
4735  {
4736  av_packet_unref(pkt);
4737  continue;
4738  }
4739  break;
4740  case AVMEDIA_TYPE_SUBTITLE:
4741  switch (codec_id)
4742  {
4743  case AV_CODEC_ID_TEXT:
4744  ProcessRawTextPacket(pkt);
4745  av_packet_unref(pkt);
4746  continue;
4747  case AV_CODEC_ID_DVB_TELETEXT:
4748  ProcessDVBDataPacket(curstream, pkt);
4749  av_packet_unref(pkt);
4750  continue;
4751  default:
4752  break;
4753  }
4754  break;
4755  case AVMEDIA_TYPE_DATA:
4756  ProcessDataPacket(curstream, pkt, decodetype);
4757  av_packet_unref(pkt);
4758  continue;
4759  default:
4760  break;
4761  }
4762 
4763  // ensure there is an AVCodecContext for this stream
4764  AVCodecContext *context = m_codecMap.GetCodecContext(curstream);
4765  if (context == nullptr)
4766  {
4767  if (codec_type != AVMEDIA_TYPE_VIDEO)
4768  {
4769  LOG(VB_PLAYBACK, LOG_ERR, LOC +
4770  QString("No codec for stream index %1, type(%2) id(%3:%4)")
4771  .arg(QString::number(pkt->stream_index),
4772  AVMediaTypeToString(codec_type),
4773  avcodec_get_name(codec_id),
4774  QString::number(codec_id)
4775  )
4776  );
4777  // Process Stream Change in case we have no audio
4778  if (codec_type == AVMEDIA_TYPE_AUDIO && !m_audio->HasAudioIn())
4779  m_streamsChanged = true;
4780  }
4781  av_packet_unref(pkt);
4782  continue;
4783  }
4784 
4785  have_err = false;
4786 
4787  switch (codec_type)
4788  {
4789  case AVMEDIA_TYPE_AUDIO:
4790  {
4791  if (!ProcessAudioPacket(context, curstream, pkt, decodetype))
4792  have_err = true;
4793  else
4795  break;
4796  }
4797 
4798  case AVMEDIA_TYPE_VIDEO:
4799  {
4800  if (pkt->stream_index != m_selectedTrack[kTrackTypeVideo].m_av_stream_index)
4801  {
4802  break;
4803  }
4804 
4805  if (!PreProcessVideoPacket(context, curstream, pkt))
4806  continue;
4807 
4808  // If the resolution changed in XXXPreProcessPkt, we may
4809  // have a fatal error, so check for this before continuing.
4810  if (m_parent->IsErrored())
4811  {
4812  av_packet_free(&pkt);
4813  return false;
4814  }
4815 
4816  if (pkt->pts != AV_NOPTS_VALUE)
4817  {
4819  (av_q2d(curstream->time_base)*pkt->pts*1000000);
4820  }
4821 
4822  if (!(decodetype & kDecodeVideo))
4823  {
4824  m_framesPlayed++;
4825  m_gotVideoFrame = true;
4826  break;
4827  }
4828 
4829  if (!ProcessVideoPacket(context, curstream, pkt, Retry))
4830  have_err = true;
4831  break;
4832  }
4833 
4834  case AVMEDIA_TYPE_SUBTITLE:
4835  {
4836  if (!ProcessSubtitlePacket(context, curstream, pkt))
4837  have_err = true;
4838  break;
4839  }
4840 
4841  default:
4842  {
4843  LOG(VB_GENERAL, LOG_ERR, LOC +
4844  QString("Decoding - id(%1) type(%2)")
4845  .arg(avcodec_get_name(codec_id),
4846  AVMediaTypeToString(codec_type)));
4847  have_err = true;
4848  break;
4849  }
4850  }
4851 
4852  if (!have_err && !Retry)
4853  m_frameDecoded = 1;
4854  av_packet_unref(pkt);
4855  if (Retry)
4856  break;
4857  }
4858 
4859  av_packet_free(&pkt);
4860  return true;
4861 }
4862 
4864 {
4865  if (m_streamsChanged)
4866  {
4867  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("StreamChangeCheck skip SeekReset"));
4868  // SeekReset(0, 0, true, true);
4869  ScanStreams(false);
4870  m_streamsChanged = false;
4871  }
4872 }
4873 
4874 int AvFormatDecoder::ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &/*storePacket*/)
4875 {
4876  m_avCodecLock.lock();
4877  int result = av_read_frame(ctx, pkt);
4878  m_avCodecLock.unlock();
4879  return result;
4880 }
4881 
4883 {
4885  if (pmt_buffer.has_buffer())
4886  {
4887  const ProgramMapTable pmt(PSIPTable(pmt_buffer.data()));
4888 
4889  for (uint i = 0; i < pmt.StreamCount(); i++)
4890  {
4891  // MythTV remaps OpenCable Video to normal video during recording
4892  // so "dvb" is the safest choice for system info type, since this
4893  // will ignore other uses of the same stream id in DVB countries.
4894  if (pmt.IsVideo(i, "dvb"))
4895  return true;
4896 
4897  // MHEG may explicitly select a private stream as video
4898  if ((i == (uint)m_selectedTrack[kTrackTypeVideo].m_av_stream_index) &&
4899  (pmt.StreamType(i) == StreamID::PrivData))
4900  {
4901  return true;
4902  }
4903  }
4904  }
4905 
4906  return GetTrackCount(kTrackTypeVideo) != 0U;
4907 }
4908 
4910 {
4912  {
4914  if (!frame)
4915  return false;
4916 
4917  frame->ClearMetadata();
4918  frame->ClearBufferToBlank();
4919 
4920  frame->m_dummy = true;
4921  frame->m_frameNumber = m_framesPlayed;
4922  frame->m_frameCounter = m_frameCounter++;
4923 
4925  m_parent->DeLimboFrame(frame);
4926 
4927  m_decodedVideoFrame = frame;
4928  m_framesPlayed++;
4929  m_gotVideoFrame = true;
4930  }
4931  return true;
4932 }
4933 
4935 {
4937 }
4938 
4940 {
4941  int stream = m_selectedTrack[kTrackTypeVideo].m_av_stream_index;
4942  if (stream < 0 || !m_ic)
4943  return {};
4944  return avcodec_get_name(m_ic->streams[stream]->codecpar->codec_id);
4945 }
4946 
4948 {
4949  if (m_selectedTrack[kTrackTypeAudio].m_av_stream_index < 0)
4950  {
4951  m_disablePassthru = disable;
4952  return;
4953  }
4954 
4955  if (disable != m_disablePassthru)
4956  {
4957  m_disablePassthru = disable;
4958  QString msg = (disable) ? "Disabling" : "Allowing";
4959  LOG(VB_AUDIO, LOG_INFO, LOC + msg + " pass through");
4960 
4961  // Force pass through state to be reanalyzed
4963  }
4964 }
4965 
4967 {
4968  QMutexLocker locker(&m_trackLock);
4969  SetupAudioStream();
4970 }
4971 
4972 inline bool AvFormatDecoder::DecoderWillDownmix(const AVCodecContext *ctx)
4973 {
4974  // Until ffmpeg properly implements dialnorm
4975  // use Myth internal downmixer if machine has SSE2
4977  return false;
4978  // use ffmpeg only for dolby codecs if we have to
4979  //return av_opt_find(ctx->priv_data, "downmix", nullptr, 0, 0);
4980  // av_opt_find was causing segmentation faults, so explicitly list the
4981  // compatible decoders
4982  switch (ctx->codec_id)
4983  {
4984  case AV_CODEC_ID_AC3:
4985  case AV_CODEC_ID_TRUEHD:
4986  case AV_CODEC_ID_EAC3:
4987  case AV_CODEC_ID_MLP:
4988  case AV_CODEC_ID_DTS:
4989  return true;
4990  default:
4991  return false;
4992  }
4993 }
4994 
4995 bool AvFormatDecoder::DoPassThrough(const AVCodecParameters *par, bool withProfile)
4996 {
4997  bool passthru = false;
4998 
4999  // if withProfile == false, we will accept any DTS stream regardless
5000  // of its profile. We do so, so we can bitstream DTS-HD as DTS core
5001  if (!withProfile && par->codec_id == AV_CODEC_ID_DTS && !m_audio->CanDTSHD())
5002  {
5003  passthru = m_audio->CanPassthrough(par->sample_rate, par->ch_layout.nb_channels,
5004  par->codec_id, FF_PROFILE_DTS);
5005  }
5006  else
5007  {
5008  passthru = m_audio->CanPassthrough(par->sample_rate, par->ch_layout.nb_channels,
5009  par->codec_id, par->profile);
5010  }
5011 
5012  passthru &= !m_disablePassthru;
5013 
5014  return passthru;
5015 }
5016 
5023 {
5024  AudioInfo info; // no_audio
5025  AVStream *curstream = nullptr;
5026  AVCodecContext *ctx = nullptr;
5027  AudioInfo old_in = m_audioIn;
5028  int requested_channels = 0;
5029 
5030  if ((m_currentTrack[kTrackTypeAudio] >= 0) && m_ic &&
5031  (m_selectedTrack[kTrackTypeAudio].m_av_stream_index <=
5032  (int) m_ic->nb_streams))
5033  {
5034  curstream = m_ic->streams[m_selectedTrack[kTrackTypeAudio]
5035  .m_av_stream_index];
5036  if (curstream != nullptr)
5037  ctx = m_codecMap.GetCodecContext(curstream);
5038  }
5039 
5040  if (ctx == nullptr)
5041  {
5042  if (!m_tracks[kTrackTypeAudio].empty())
5043  LOG(VB_PLAYBACK, LOG_INFO, LOC + "No codec context. Returning false");
5044  return false;
5045  }
5046 
5047  AudioFormat fmt =
5049  ctx->bits_per_raw_sample);
5050 
5051  if (av_sample_fmt_is_planar(ctx->sample_fmt))
5052  {
5053  LOG(VB_AUDIO, LOG_INFO, LOC + QString("Audio data is planar"));
5054  }
5055 
5056  if (fmt == FORMAT_NONE)
5057  {
5058  int bps = av_get_bytes_per_sample(ctx->sample_fmt) << 3;
5059  if (ctx->sample_fmt == AV_SAMPLE_FMT_S32 &&
5060  ctx->bits_per_raw_sample)
5061  bps = ctx->bits_per_raw_sample;
5062  LOG(VB_GENERAL, LOG_ERR, LOC +
5063  QString("Unsupported sample format with %1 bits").arg(bps));
5064  return false;
5065  }
5066 
5067  bool using_passthru = DoPassThrough(curstream->codecpar, false);
5068 
5069  requested_channels = ctx->ch_layout.nb_channels;
5070 
5071  if (!using_passthru &&
5072  ctx->ch_layout.nb_channels > (int)m_audio->GetMaxChannels() &&
5073  DecoderWillDownmix(ctx))
5074  {
5075  requested_channels = m_audio->GetMaxChannels();
5076 
5077  AVChannelLayout channel_layout;
5078  av_channel_layout_default(&channel_layout, requested_channels);
5079  av_opt_set_chlayout(ctx->priv_data, "downmix", &channel_layout, 0);
5080  }
5081 
5082  info = AudioInfo(ctx->codec_id, fmt, ctx->sample_rate,
5083  requested_channels, using_passthru, ctx->ch_layout.nb_channels,
5084  ctx->codec_id == AV_CODEC_ID_DTS ? ctx->profile : 0);
5085  if (info == m_audioIn)
5086  return false;
5087 
5088  LOG(VB_AUDIO, LOG_INFO, LOC + "Initializing audio parms from " +
5089  QString("audio track #%1").arg(m_currentTrack[kTrackTypeAudio]+1));
5090 
5092 
5093  LOG(VB_AUDIO, LOG_INFO, LOC + "Audio format changed " +
5094  QString("\n\t\t\tfrom %1 to %2")
5095  .arg(old_in.toString(), m_audioOut.toString()));
5096 
5097  m_audio->SetAudioParams(m_audioOut.format, ctx->ch_layout.nb_channels,
5098  requested_channels,
5101  m_audio->ReinitAudio();
5102  AudioOutput *audioOutput = m_audio->GetAudioOutput();
5103  if (audioOutput)
5104  audioOutput->SetSourceBitrate(ctx->bit_rate);
5105 
5106  if (LCD *lcd = LCD::Get())
5107  {
5108  LCDAudioFormatSet audio_format = AUDIO_MP3;
5109 
5110  switch (ctx->codec_id)
5111  {
5112  case AV_CODEC_ID_MP2:
5113  audio_format = AUDIO_MPEG2;
5114  break;
5115  case AV_CODEC_ID_MP3:
5116  audio_format = AUDIO_MP3;
5117  break;
5118  case AV_CODEC_ID_AC3:
5119  audio_format = AUDIO_AC3;
5120  break;
5121  case AV_CODEC_ID_DTS:
5122  audio_format = AUDIO_DTS;
5123  break;
5124  case AV_CODEC_ID_VORBIS:
5125  audio_format = AUDIO_OGG;
5126  break;
5127  case AV_CODEC_ID_WMAV1:
5128  audio_format = AUDIO_WMA;
5129  break;
5130  case AV_CODEC_ID_WMAV2:
5131  audio_format = AUDIO_WMA2;
5132  break;
5133  default:
5134  audio_format = AUDIO_WAV;
5135  break;
5136  }
5137 
5138  lcd->setAudioFormatLEDs(audio_format, true);
5139 
5141  lcd->setVariousLEDs(VARIOUS_SPDIF, true);
5142  else
5143  lcd->setVariousLEDs(VARIOUS_SPDIF, false);
5144 
5145  switch (m_audioIn.m_channels)
5146  {
5147  case 0:
5148  /* nb: aac and mp3 seem to be coming up 0 here, may point to an
5149  * avformatdecoder audio channel handling bug, per janneg */
5150  case 1:
5151  case 2:
5152  /* all audio codecs have at *least* one channel, but
5153  * LR is the fewest LED we can light up */
5154  lcd->setSpeakerLEDs(SPEAKER_LR, true);
5155  break;
5156  case 3:
5157  case 4:
5158  case 5:
5159  case 6:
5160  lcd->setSpeakerLEDs(SPEAKER_51, true);
5161  break;
5162  default:
5163  lcd->setSpeakerLEDs(SPEAKER_71, true);
5164  break;
5165  }
5166 
5167  }
5168  return true;
5169 }
5170 
5172 {
5173  int64_t start_time = INT64_MAX;
5174  int64_t end_time = INT64_MIN;
5175  AVStream *st = nullptr;
5176 
5177  for (uint i = 0; i < ic->nb_streams; i++)
5178  {
5179  AVStream *st1 = ic->streams[i];
5180  if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5181  {
5182  st = st1;
5183  break;
5184  }
5185  }
5186  if (!st)
5187  return;
5188 
5189  int64_t duration = INT64_MIN;
5190  if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
5191  int64_t start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
5192  start_time = std::min(start_time1, start_time);
5193  if (st->duration != AV_NOPTS_VALUE) {
5194  int64_t end_time1 = start_time1 +
5195  av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5196  end_time = std::max(end_time1, end_time);
5197  }
5198  }
5199  if (st->duration != AV_NOPTS_VALUE) {
5200  int64_t duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5201  duration = std::max(duration1, duration);
5202  }
5203  if (start_time != INT64_MAX) {
5204  ic->start_time = start_time;
5205  if (end_time != INT64_MIN) {
5206  duration = std::max(end_time - start_time, duration);
5207  }
5208  }
5209  if (duration != INT64_MIN) {
5210  ic->duration = duration;
5211  if (!ic->pb)
5212  return;
5213  int64_t filesize = avio_size(ic->pb);
5214  if (filesize > 0) {
5215  /* compute the bitrate */
5216  ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
5217  (double)ic->duration;
5218  }
5219  }
5220 }
5221 
5223 {
5224  if (m_currentTrack[type] < 0 || static_cast<size_t>(m_currentTrack[type]) >= m_tracks[type].size())
5225  {
5226  return -1;
5227  }
5228  return m_tracks[type][m_currentTrack[type]].m_av_stream_index;
5229 }
5230 
5232 {
5233  if (m_ic == nullptr)
5234  {
5235  return nullptr;
5236  }
5237  AVProgram* program = av_find_program_from_stream(m_ic, nullptr, get_current_AVStream_index(kTrackTypeAudio));
5238  if (program == nullptr)
5239  {
5240  program = av_find_program_from_stream(m_ic, nullptr, get_current_AVStream_index(kTrackTypeVideo));
5241  }
5242  return program;
5243 }
5244 
5245 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythHDRVideoMetadata::Populate
static void Populate(class MythVideoFrame *Frame, struct AVFrame *AvFrame)
Create, update or destroy HDR metadata for the given MythVideoFrame.
Definition: mythhdrvideometadata.cpp:47
ProgramMapTable::ProgramInfo
const unsigned char * ProgramInfo(void) const
Definition: mpegtables.h:737
AvFormatDecoder::get_avf_buffer
friend int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
Definition: avformatdecoder.cpp:2680
AvFormatDecoder::GetTrackDesc
QString GetTrackDesc(uint Type, uint TrackNo) override
Definition: avformatdecoder.cpp:3887
bytereader.h
AudioInfo::m_channels
int m_channels
Definition: avformatdecoder.h:56
AVCParser
Definition: AVCParser.h:30
DecoderBase::DoFastForward
virtual bool DoFastForward(long long desiredFrame, bool discardFrames=true)
Skips ahead or rewinds to desiredFrame.
Definition: decoderbase.cpp:709
kTrackTypeAttachment
@ kTrackTypeAttachment
Definition: decoderbase.h:38
secondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::seconds > secondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:80
MythAVFormatBuffer::getAVIOContext
AVIOContext * getAVIOContext()
Definition: mythavformatbuffer.h:21
MythTimer::elapsed
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:91
kTrackTypeCC708
@ kTrackTypeCC708
Definition: decoderbase.h:34
iso639_key_to_canonical_key
int iso639_key_to_canonical_key(int iso639_2)
Definition: iso639.cpp:118
SLICE_MIN
static constexpr uint32_t SLICE_MIN
Definition: avformatdecoder.cpp:3001
CC608Decoder::SetIgnoreTimecode
void SetIgnoreTimecode(bool val)
Definition: cc608decoder.h:104
DecoderBase::SetTrack
virtual int SetTrack(uint Type, int TrackNo)
Definition: decoderbase.cpp:951
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
DecoderBase::m_readAdjust
long long m_readAdjust
Definition: decoderbase.h:333
AudioOutputSettings::AVSampleFormatToFormat
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
Definition: audiooutputsettings.cpp:198
AvFormatDecoder::GetRawEncodingType
QString GetRawEncodingType(void) override
Definition: avformatdecoder.cpp:4939
VIDEO_WMV
@ VIDEO_WMV
Definition: lcddevice.h:123
kDecoderProbeBufferSize
const int kDecoderProbeBufferSize
Definition: decoderbase.h:23
MythMediaBuffer::BestBufferSize
virtual int BestBufferSize(void)
Definition: mythmediabuffer.h:137
MythVideoFrame::m_colorspace
int m_colorspace
Definition: mythframe.h:147
kAudioTypeNormal
@ kAudioTypeNormal
Definition: decoderbase.h:58
AudioInfo::m_codecProfile
int m_codecProfile
Definition: avformatdecoder.h:57
MythPlayer::SetFileLength
void SetFileLength(std::chrono::seconds total, int frames)
Definition: mythplayer.cpp:384
MythMediaBuffer::SetBufferSizeFactors
void SetBufferSizeFactors(bool EstBitrate, bool Matroska)
Tells RingBuffer that the raw bitrate may be inaccurate and the underlying container is matroska,...
Definition: mythmediabuffer.cpp:330
SLICE_MAX
static constexpr uint32_t SLICE_MAX
Definition: avformatdecoder.cpp:3002
InteractiveTV::ImageHasChanged
bool ImageHasChanged(void)
Definition: interactivetv.cpp:42
AudioInfo::m_codecId
AVCodecID m_codecId
Definition: avformatdecoder.h:52
MythVideoFrame::m_colortransfer
int m_colortransfer
Definition: mythframe.h:150
DecoderBase::m_selectedTrack
std::array< StreamInfo, kTrackTypeCount > m_selectedTrack
Definition: decoderbase.h:343
kScan_Ignore
@ kScan_Ignore
Definition: videoouttypes.h:96
AvFormatDecoder::av_update_stream_timings_video
static void av_update_stream_timings_video(AVFormatContext *ic)
Definition: avformatdecoder.cpp:5171
AvFormatDecoder::GetChapterTimes
void GetChapterTimes(QList< std::chrono::seconds > &times) override
Definition: avformatdecoder.cpp:530
SPEAKER_71
@ SPEAKER_71
Definition: lcddevice.h:99
DecoderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: decoderbase.h:281
MythDVDBuffer::GetAspectOverride
float GetAspectOverride(void) const
Definition: mythdvdbuffer.cpp:1162
StreamInfo::m_language_index
uint m_language_index
Audio, Subtitle, Teletext.
Definition: decoderbase.h:108
DecoderBase::PosMapEntry
Definition: decoderbase.h:270
kDecodeAudio
@ kDecodeAudio
Definition: decoderbase.h:52
AvFormatDecoder::SetTrack
int SetTrack(uint Type, int TrackNo) override
Definition: avformatdecoder.cpp:3875
kTrackTypeSubtitle
@ kTrackTypeSubtitle
Definition: decoderbase.h:32
MythVideoFrame::m_newGOP
bool m_newGOP
Definition: mythframe.h:136
ProgramMapTable::StreamCount
uint StreamCount(void) const
Definition: mpegtables.h:752
AvFormatDecoder::GetCurrentChapter
int GetCurrentChapter(long long framesPlayed) override
Definition: avformatdecoder.cpp:547
DecoderBase::m_currentWidth
int m_currentWidth
Definition: decoderbase.h:287
AudioInfo::m_sampleSize
int m_sampleSize
Definition: avformatdecoder.h:54
DecodeType
DecodeType
Definition: decoderbase.h:48
AvFormatDecoder::m_skipAudio
bool m_skipAudio
Definition: avformatdecoder.h:268
MythCodecMap::GetCodecContext
AVCodecContext * GetCodecContext(const AVStream *Stream, const AVCodec *Codec=nullptr, bool NullCodec=false)
Definition: mythavutil.cpp:288
SubtitleReader::AddAVSubtitle
bool AddAVSubtitle(AVSubtitle &subtitle, bool fix_position, bool is_selected_forced_track, bool allow_forced, bool isExternal)
Definition: subtitlereader.cpp:58
AudioPlayer::ReinitAudio
QString ReinitAudio(void)
Definition: audioplayer.cpp:105
AvFormatDecoder::do_av_seek
bool do_av_seek(long long desiredFrame, bool discardFrames, int flags)
Definition: avformatdecoder.cpp:621
cc708_seen_flags
std::array< bool, 64 > cc708_seen_flags
Definition: cc708decoder.h:13
AvFormatDecoder::AutoSelectAudioTrack
int AutoSelectAudioTrack(void)
Selects the best audio track.
Definition: avformatdecoder.cpp:4189
DecoderBase::m_fps
double m_fps
Definition: decoderbase.h:283
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
MythCodecID
MythCodecID
Definition: mythcodecid.h:11
audiooutpututil.h
AvFormatDecoder::m_gotVideoFrame
bool m_gotVideoFrame
Definition: avformatdecoder.h:265
AvFormatDecoder::UpdateFramesPlayed
void UpdateFramesPlayed(void) override
Definition: avformatdecoder.cpp:2479
AvFormatDecoder::m_storedPackets
QList< AVPacket * > m_storedPackets
Definition: avformatdecoder.h:260
AvFormatDecoder::SetEof
void SetEof(bool eof) override
Definition: avformatdecoder.cpp:798
TeletextDecoder::Decode
void Decode(const unsigned char *buf, int vbimode)
Decodes teletext data.
Definition: teletextdecoder.cpp:40
MythVideoFrame::ClearBufferToBlank
void ClearBufferToBlank()
Definition: mythframe.cpp:205
MythVideoFrame::m_chromalocation
int m_chromalocation
Definition: mythframe.h:151
InteractiveTV::SetNetBootInfo
void SetNetBootInfo(const unsigned char *data, uint length)
Definition: interactivetv.cpp:78
DecoderBase::m_videoRotation
int m_videoRotation
Definition: decoderbase.h:334
AvFormatDecoder::GetAttachmentData
void GetAttachmentData(uint TrackNo, QByteArray &Filename, QByteArray &Data) override
Definition: avformatdecoder.cpp:3986
AvFormatDecoder::ProcessAudioPacket
bool ProcessAudioPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt, DecodeType decodetype)
Definition: avformatdecoder.cpp:4369
DecoderBase::m_stereo3D
uint m_stereo3D
Definition: decoderbase.h:335
CaptionServiceDescriptor
Definition: atscdescriptors.h:74
AvFormatDecoder::m_itv
InteractiveTV * m_itv
MHEG/MHP decoder.
Definition: avformatdecoder.h:309
StreamInfo::m_av_stream_index
int m_av_stream_index
Definition: decoderbase.h:104
AudioInfo::toString
QString toString() const
Definition: avformatdecoder.h:69
AvFormatDecoder::m_maxKeyframeDist
int m_maxKeyframeDist
Definition: avformatdecoder.h:282
HandleStreamChange
static void HandleStreamChange(void *data, int avprogram_id)
Definition: avformatdecoder.cpp:876
DecoderBase::AutoSelectTrack
virtual int AutoSelectTrack(uint Type)
Select best track.
Definition: decoderbase.cpp:1089
AvFormatDecoder::RemoveAudioStreams
void RemoveAudioStreams()
remove audio streams from the context used by dvd code during title transitions to remove stale audio...
Definition: avformatdecoder.cpp:2638
VBI_IVTV
@ VBI_IVTV
Definition: vbilut.h:23
x2
static int x2
Definition: mythsocket.cpp:51
MythCodecContext::SetDecoderOptions
virtual void SetDecoderOptions(AVCodecContext *, const AVCodec *)
Definition: mythcodeccontext.h:157
MythPlayer::GetInteractiveTV
virtual InteractiveTV * GetInteractiveTV()
Definition: mythplayer.h:163
DecoderBase::m_atEof
EofState m_atEof
Definition: decoderbase.h:301
ProgramMapTable::StreamInfo
const unsigned char * StreamInfo(uint i) const
Definition: mpegtables.h:749
DecoderBase::m_bitrate
uint m_bitrate
Definition: decoderbase.h:286
DecoderBase::m_parent
MythPlayer * m_parent
Definition: decoderbase.h:278
kScan_Progressive
@ kScan_Progressive
Definition: videoouttypes.h:100
AvFormatDecoder::NormalizeVideoTimecode
std::chrono::milliseconds NormalizeVideoTimecode(std::chrono::milliseconds timecode) override
Definition: avformatdecoder.cpp:467
MythVideoFrame::m_frameCounter
uint64_t m_frameCounter
Definition: mythframe.h:129
DescriptorID::data_broadcast_id
@ data_broadcast_id
Definition: mpegdescriptors.h:112
AvFormatDecoder::DecoderWillDownmix
bool DecoderWillDownmix(const AVCodecContext *ctx)
Definition: avformatdecoder.cpp:4972
V4L2_MPEG_LINE_TYPES
V4L2_MPEG_LINE_TYPES
Definition: avformatdecoder.cpp:56
mythtvexp.h
MythCoreContext::GetAudioLanguage
QString GetAudioLanguage(void)
Returns two character ISO-639 language descriptor for audio language.
Definition: mythcorecontext.cpp:1804
StreamInfo::m_stream_id
int m_stream_id
Definition: decoderbase.h:105
MythDVDBuffer::DecodeSubtitles
bool DecodeSubtitles(AVSubtitle *Subtitle, int *GotSubtitles, const uint8_t *SpuPkt, int BufSize, uint32_t StartTime)
generate dvd subtitle bitmap or dvd menu bitmap.
Definition: mythdvdbuffer.cpp:1468
cc708decoder.h
AvFormatDecoder::SetAudioByComponentTag
bool SetAudioByComponentTag(int Tag) override
Definition: avformatdecoder.cpp:4000
AVMediaTypeToString
static const char * AVMediaTypeToString(enum AVMediaType codec_type)
returns a human readable string for the AVMediaType enum.
Definition: avformatdecoder.cpp:352
CC608Decoder
Definition: cc608decoder.h:90
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:694
MythAVFrame
MythAVFrame little utility class that act as a safe way to allocate an AVFrame which can then be allo...
Definition: mythavframe.h:26
TeletextDecoder
Definition: teletextdecoder.h:8
AvFormatDecoder::autoSelectVideoTrack
int autoSelectVideoTrack(int &scanerror)
Definition: avformatdecoder.cpp:1882
mythdvdbuffer.h
kDecodeNothing
@ kDecodeNothing
Definition: decoderbase.h:50
DecoderBase::m_livetv
bool m_livetv
Definition: decoderbase.h:324
AvFormatDecoder::HasVideo
bool HasVideo()
Definition: avformatdecoder.cpp:4882
SEQ_START
static constexpr uint32_t SEQ_START
Definition: avformatdecoder.cpp:2998
AvFormatDecoder::SetIdrOnlyKeyframes
void SetIdrOnlyKeyframes(bool value) override
Definition: avformatdecoder.h:131
VERBOSE_LEVEL_CHECK
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
MythCodecContext::CreateContext
static MythCodecContext * CreateContext(DecoderBase *Parent, MythCodecID Codec)
Definition: mythcodeccontext.cpp:77
V4L2_MPEG_VBI_IVTV_CAPTION_525
@ V4L2_MPEG_VBI_IVTV_CAPTION_525
Closed Captions (line 21 NTSC, line 22 PAL)
Definition: avformatdecoder.cpp:58
microsecondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::microseconds > microsecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:102
DecoderBase::GetSeekSnap
uint64_t GetSeekSnap(void) const
Definition: decoderbase.h:139
mythdbcon.h
AvFormatDecoder::m_ccX08InTracks
std::array< bool, 68 > m_ccX08InTracks
Lookup table for whether a stream is represented in the UI entries 0-3 correspond to CEA-608 CC1 thro...
Definition: avformatdecoder.h:296
MythDate::formatTime
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
Definition: mythdate.cpp:242
AudioOutputSettings::SampleSize
static int SampleSize(AudioFormat format)
Definition: audiooutputsettings.cpp:180
DescriptorID::caption_service
@ caption_service
Definition: mpegdescriptors.h:163
ProgramMapTable::IsVideo
bool IsVideo(uint i, const QString &sistandard) const
Returns true iff the stream at index i is a video stream.
Definition: mpegtables.cpp:513
AvFormatDecoder::m_audioSamples
uint8_t * m_audioSamples
Definition: avformatdecoder.h:312
DecoderBase::m_hasFullPositionMap
bool m_hasFullPositionMap
Definition: decoderbase.h:311
AudioPlayer::IsBufferAlmostFull
bool IsBufferAlmostFull(void)
Definition: audioplayer.cpp:494
av_make_error_stdstring_unknown
MPUBLIC std::string av_make_error_stdstring_unknown(int errnum)
Definition: mythaverror.h:47
types
static const struct wl_interface * types[]
Definition: idle_inhibit_unstable_v1.c:39
mythhdrvideometadata.h
MythCodecContext::InitVideoCodec
virtual void InitVideoCodec(AVCodecContext *Context, bool SelectedStream, bool &DirectRendering)
Definition: mythcodeccontext.cpp:307
MythDate::Format
Format
Definition: mythdate.h:15
MythVideoFrame::m_width
int m_width
Definition: mythframe.h:120
CC708Decoder::decode_cc_data
void decode_cc_data(uint cc_type, uint data1, uint data2)
Definition: cc708decoder.cpp:41
AvFormatDecoder::GetTeletextDecoderType
int GetTeletextDecoderType(void) const override
Definition: avformatdecoder.cpp:3964
MythMediaBuffer
Definition: mythmediabuffer.h:59
MythMediaBuffer::IgnoreWaitStates
virtual void IgnoreWaitStates(bool)
Definition: mythmediabuffer.h:139
MythPlayer::IsErrored
bool IsErrored(void) const
Definition: mythplayer.cpp:1941
MythMediaBuffer::IsDVD
bool IsDVD(void) const
Definition: mythmediabuffer.cpp:1840
AvFormatDecoder::IsValidStream
virtual bool IsValidStream(int)
Definition: avformatdecoder.h:221
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
VIDEO_XVID
@ VIDEO_XVID
Definition: lcddevice.h:122
AvFormatDecoder::ProcessVideoFrame
virtual bool ProcessVideoFrame(AVCodecContext *codecContext, AVStream *Stream, AVFrame *AvFrame)
Definition: avformatdecoder.cpp:3373
DecoderBase::m_videoDisplayProfile
MythVideoProfile m_videoDisplayProfile
Definition: decoderbase.h:349
myth_av_log
static void myth_av_log(void *ptr, int level, const char *fmt, va_list vl)
Definition: avformatdecoder.cpp:266
AudioPlayer::HasAudioOut
bool HasAudioOut(void) const
Definition: audioplayer.h:52
MythMediaBuffer::GetReadBufAvail
int GetReadBufAvail(void) const
Returns number of bytes available for reading from buffer.
Definition: mythmediabuffer.cpp:462
AvFormatDecoder::m_seenGop
bool m_seenGop
A flag to indicate that we've seen a GOP frame. Used in junction with seq_count.
Definition: avformatdecoder.h:256
DecoderBase::m_trackLock
QRecursiveMutex m_trackLock
Definition: decoderbase.h:338
MYTH_WIDTH_ALIGNMENT
static constexpr uint8_t MYTH_WIDTH_ALIGNMENT
Definition: mythframe.h:16
LOC
#define LOC
Definition: avformatdecoder.cpp:113
CC708Decoder
Definition: cc708decoder.h:27
DecoderBase::m_positionMapType
MarkTypes m_positionMapType
Definition: decoderbase.h:314
MythCodecContext::DecoderWillResetOnFlush
virtual bool DecoderWillResetOnFlush(void)
Definition: mythcodeccontext.h:158
mythframe.h
AUDIO_WMA2
@ AUDIO_WMA2
Definition: lcddevice.h:108
build_compdb.parser
parser
Definition: build_compdb.py:7
PlayerFlags
PlayerFlags
Definition: mythplayer.h:64
SPEAKER_LR
@ SPEAKER_LR
Definition: lcddevice.h:97
MythVideoFrame::m_interlaced
bool m_interlaced
Definition: mythframe.h:133
subtitlereader.h
MythPlayer
Definition: mythplayer.h:83
AvFormatDecoder::SeekReset
void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override
Definition: avformatdecoder.cpp:671
mythavframe.h
kAudioTypeCommentary
@ kAudioTypeCommentary
Definition: decoderbase.h:63
kDecodeLowRes
@ kDecodeLowRes
Definition: mythplayer.h:67
MythVideoFrame::m_offsets
FrameOffsets m_offsets
Definition: mythframe.h:142
DecoderBase::m_exitAfterDecoded
bool m_exitAfterDecoded
Definition: decoderbase.h:308
AvFormatDecoder::GetChapter
long long GetChapter(int chapter) override
Definition: avformatdecoder.cpp:571
MythMediaBuffer::UpdateRawBitrate
void UpdateRawBitrate(uint RawBitrate)
Set the raw bit rate, to allow RingBuffer adjust effective bitrate.
Definition: mythmediabuffer.cpp:279
V4L2_MPEG_VBI_IVTV_VPS
@ V4L2_MPEG_VBI_IVTV_VPS
Video Programming System (PAL) (line 16)
Definition: avformatdecoder.cpp:60
AvFormatDecoder::FindStreamInfo
int FindStreamInfo(void)
Definition: avformatdecoder.cpp:882
AvFormatDecoder::ScanATSCCaptionStreams
void ScanATSCCaptionStreams(int av_index)
Definition: avformatdecoder.cpp:1592
iso639_key_toName
QString iso639_key_toName(int iso639_2)
Converts a canonical key to language name in English.
Definition: iso639.cpp:109
sinfo_vec_t
std::vector< StreamInfo > sinfo_vec_t
Definition: decoderbase.h:119
CC608Seen
std::array< bool, 4 > CC608Seen
Definition: cc608decoder.h:60
DecoderBase::m_frameToDurMap
frm_pos_map_t m_frameToDurMap
Definition: decoderbase.h:318
AvFormatDecoder::ProcessVideoPacket
virtual bool ProcessVideoPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt, bool &Retry)
Definition: avformatdecoder.cpp:3259
InteractiveTV::GetInitialStreams
void GetInitialStreams(int &audioTag, int &videoTag)
Definition: interactivetv.cpp:73
AvFormatDecoder::GetSubHeader
QByteArray GetSubHeader(uint TrackNo) override
Definition: avformatdecoder.cpp:3974
MythVideoFrame::m_interlacedReverse
bool m_interlacedReverse
Definition: mythframe.h:135
AudioPlayer::AddAudioData
void AddAudioData(char *buffer, int len, std::chrono::milliseconds timecode, int frames)
Definition: audioplayer.cpp:450
LCDAudioFormatSet
LCDAudioFormatSet
Definition: lcddevice.h:103
AvFormatDecoder::m_playerFlags
PlayerFlags m_playerFlags
Definition: avformatdecoder.h:279
LCD::Get
static LCD * Get(void)
Definition: lcddevice.cpp:69
DecoderBase::m_currentTrack
std::array< int, kTrackTypeCount > m_currentTrack
Definition: decoderbase.h:340
MythMediaBuffer::StartFromBeginning
virtual bool StartFromBeginning(void)
Definition: mythmediabuffer.h:138
MythCodecContext::DecoderWillResetOnAspect
virtual bool DecoderWillResetOnAspect(void)
Definition: mythcodeccontext.h:159
extract_mono_channel
static void extract_mono_channel(uint channel, AudioInfo *audioInfo, char *buffer, int bufsize)
Definition: avformatdecoder.cpp:4345
AUDIO_MPEG2
@ AUDIO_MPEG2
Definition: lcddevice.h:111
iso639_is_key_undefined
static bool iso639_is_key_undefined(int code)
Returns true if the key is 0, 0xFFFFFF, or 'und'.
Definition: iso639.h:54
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
atscdescriptors.h
MythPlayer::SetErrored
void SetErrored(const QString &reason)
Definition: mythplayer.cpp:1917
AvFormatDecoder::m_streamTracks
QList< StreamInfo > m_streamTracks
StreamInfo for 608 and 708 Captions seen in the caption stream itself but not seen in the PMT.
Definition: avformatdecoder.h:303
MythPlayer::DiscardVideoFrames
void DiscardVideoFrames(bool KeyFrame, bool Flushed)
Places frames in the available frames queue.
Definition: mythplayer.cpp:645
AvFormatDecoder::CloseCodecs
void CloseCodecs()
Definition: avformatdecoder.cpp:432
AudioPlayer::GetFormat
AudioFormat GetFormat(void) const
Definition: audioplayer.h:79
kCodec_NONE
@ kCodec_NONE
Definition: mythcodecid.h:15
filter_type
static std::vector< int > filter_type(const sinfo_vec_t &tracks, AudioTrackType type)
Definition: avformatdecoder.cpp:4058
AvFormatDecoder::m_allowedQuit
bool m_allowedQuit
Definition: avformatdecoder.h:269
DecoderBase::m_dontSyncPositionMap
bool m_dontSyncPositionMap
Definition: decoderbase.h:323
AvFormatDecoder::CodecMap
MythCodecMap * CodecMap(void)
Definition: avformatdecoder.cpp:427
AvFormatDecoder::GetAudioLanguage
virtual int GetAudioLanguage(uint AudioIndex, uint StreamIndex)
Definition: avformatdecoder.cpp:2542
DecoderBase::m_tracks
std::array< sinfo_vec_t, kTrackTypeCount > m_tracks
Definition: decoderbase.h:341
ptsdiff
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
Definition: pes.cpp:78
AvFormatDecoder::m_streamsChanged
bool m_streamsChanged
Definition: avformatdecoder.h:320
AvFormatDecoder::m_firstVPts
std::chrono::milliseconds m_firstVPts
Definition: avformatdecoder.h:276
AvFormatDecoder::Reset
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
Definition: avformatdecoder.cpp:810
MythVideoFrame::m_dummy
bool m_dummy
Definition: mythframe.h:139
AvFormatDecoder::SetDisablePassThrough
void SetDisablePassThrough(bool disable) override
Disables AC3/DTS pass through.
Definition: avformatdecoder.cpp:4947
AvFormatDecoder::OpenFile
int OpenFile(MythMediaBuffer *Buffer, bool novideo, TestBufferVec &testbuf) override
Open our file and set up or audio and video parameters.
Definition: avformatdecoder.cpp:911
SEQ_PKT_ERR_MAX
static constexpr int SEQ_PKT_ERR_MAX
Definition: avformatdecoder.cpp:121
StreamHasRequiredParameters
static bool StreamHasRequiredParameters(AVCodecContext *Context, AVStream *Stream)
Determine if we have enough live TV data to initialize hardware decoders.
Definition: avformatdecoder.cpp:210
AvFormatDecoder::m_avfRingBuffer
MythAVFormatBuffer * m_avfRingBuffer
Definition: avformatdecoder.h:249
CaptionServiceDescriptor::Line21Field
bool Line21Field(int i) const
Definition: atscdescriptors.h:106
PSIPTable
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:409
MythVideoFrame::m_rotation
int m_rotation
Definition: mythframe.h:154
AvFormatDecoder::m_directRendering
bool m_directRendering
Definition: avformatdecoder.h:252
MPEGDescriptor::IsValid
bool IsValid(void) const
Definition: mpegdescriptors.h:342
MythCodecMap::FindCodecContext
AVCodecContext * FindCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:325
MythVideoFrame::m_colorrange
int m_colorrange
Definition: mythframe.h:148
AVFrame
struct AVFrame AVFrame
Definition: BorderDetector.h:15
DecoderBase::GetTrackDesc
virtual QString GetTrackDesc(uint Type, uint TrackNo)
Definition: decoderbase.cpp:927
MythMediaBuffer::GetFilename
QString GetFilename(void) const
Definition: mythmediabuffer.cpp:1749
DecoderBase::GetTrackCount
virtual uint GetTrackCount(uint Type)
Definition: decoderbase.cpp:897
lsb3full
static int64_t lsb3full(int64_t lsb, int64_t base_ts, int lsb_bits)
Definition: avformatdecoder.cpp:461
AvFormatDecoder::MpegPreProcessPkt
void MpegPreProcessPkt(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
Preprocess a packet, setting the video parms if necessary.
Definition: avformatdecoder.cpp:3005
MythMediaBuffer::GetRealFileSize
long long GetRealFileSize(void) const
Definition: mythmediabuffer.cpp:468
mythdate.h
AudioOutput
Definition: audiooutput.h:25
cc608decoder.h
DecoderBase::m_keyframeDist
int m_keyframeDist
Definition: decoderbase.h:295
AUDIO_AC3
@ AUDIO_AC3
Definition: lcddevice.h:112
AvFormatDecoder::ScanDSMCCStreams
void ScanDSMCCStreams(AVBufferRef *pmt_section)
Check to see whether there is a Network Boot Ifo sub-descriptor in the PMT which requires the MHEG ap...
Definition: avformatdecoder.cpp:1817
mythlogging.h
AvFormatDecoder::m_processFrames
bool m_processFrames
Definition: avformatdecoder.h:318
AvFormatDecoder::m_decodedVideoFrame
MythVideoFrame * m_decodedVideoFrame
Definition: avformatdecoder.h:248
AudioPlayer::DecodeAudio
int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
DecodeAudio Utility routine.
Definition: audioplayer.cpp:538
MythCodecContext::SetDeinterlacing
virtual void SetDeinterlacing(AVCodecContext *, MythVideoProfile *, bool)
Definition: mythcodeccontext.h:154
hardwareprofile.scan.profile
profile
Definition: scan.py:97
CC608Decoder::DecodeWSS
void DecodeWSS(const unsigned char *buf)
Definition: cc608decoder.cpp:927
StreamInfo
Definition: decoderbase.h:75
DecoderBase::m_languagePreference
std::vector< int > m_languagePreference
language preferences for auto-selection of streams
Definition: decoderbase.h:347
MythVideoFrame::m_colorshifted
bool m_colorshifted
Definition: mythframe.h:152
cc608_good_parity
static bool cc608_good_parity(uint16_t data)
Definition: avformatdecoder.cpp:1546
SPEAKER_51
@ SPEAKER_51
Definition: lcddevice.h:98
MythVideoProfile::GetDecoder
QString GetDecoder() const
Definition: mythvideoprofile.cpp:360
DecoderBase::DoRewindSeek
virtual bool DoRewindSeek(long long desiredFrame)
Definition: decoderbase.cpp:588
MythCodecContext::PostProcessFrame
virtual void PostProcessFrame(AVCodecContext *, MythVideoFrame *)
Definition: mythcodeccontext.h:155
AVCParser::pictureHeightCropped
uint pictureHeightCropped(void) const override
Definition: AVCParser.cpp:1039
MythMediaBuffer::IsInDiscMenuOrStillFrame
virtual bool IsInDiscMenuOrStillFrame(void) const
Definition: mythmediabuffer.h:142
AvFormatDecoder::GetMaxReferenceFrames
static int GetMaxReferenceFrames(AVCodecContext *Context)
Definition: avformatdecoder.cpp:1353
FORMAT_NONE
@ FORMAT_NONE
Definition: audiooutputsettings.h:25
DecoderBase::m_totalDuration
MythAVRational m_totalDuration
Definition: decoderbase.h:294
hardwareprofile.config.p
p
Definition: config.py:33
AudioPlayer::SetAudioParams
void SetAudioParams(AudioFormat format, int orig_channels, int channels, AVCodecID codec, int samplerate, bool passthru, int codec_profile=-1)
Set audio output parameters.
Definition: audioplayer.cpp:247
MythVideoFrame::m_pixFmt
int m_pixFmt
Definition: mythframe.h:143
MythVideoFrame::m_alreadyDeinterlaced
bool m_alreadyDeinterlaced
Definition: mythframe.h:153
AudioOutput::SetSourceBitrate
virtual void SetSourceBitrate(int)
Definition: audiooutput.h:145
MythDVDBuffer::GetAudioTrackNum
int GetAudioTrackNum(uint StreamId)
get the logical track index (into PGC_AST_CTL) of the element that maps the given physical stream id.
Definition: mythdvdbuffer.cpp:1756
AudioPlayer::LengthLastData
std::chrono::milliseconds LengthLastData(void)
Definition: audioplayer.cpp:478
MythPlayer::SetDuration
void SetDuration(std::chrono::seconds duration)
Definition: mythplayer.cpp:390
DecoderBase::m_audio
AudioPlayer * m_audio
Definition: decoderbase.h:280
AudioPlayer::CanPassthrough
bool CanPassthrough(int samplerate, int channels, AVCodecID codec, int profile)
Definition: audioplayer.cpp:431
ProgramMapTable::StreamType
uint StreamType(uint i) const
Definition: mpegtables.h:740
MythCodecContext::IsDeinterlacing
virtual bool IsDeinterlacing(bool &, bool=false)
Definition: mythcodeccontext.h:156
MythAVBufferRef
C++ wrapper for AVBufferRef.
Definition: mythavutil.h:115
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:168
x1
static int x1
Definition: mythsocket.cpp:50
DecoderBase::m_positionMap
std::vector< PosMapEntry > m_positionMap
Definition: decoderbase.h:317
AudioInfo::m_sampleRate
int m_sampleRate
Definition: avformatdecoder.h:55
AUDIO_OGG
@ AUDIO_OGG
Definition: lcddevice.h:107
desc_list_t
std::vector< const unsigned char * > desc_list_t
Definition: mpegdescriptors.h:18
kDecodeAV
@ kDecodeAV
Definition: decoderbase.h:53
AvFormatDecoder::ProcessRawTextPacket
bool ProcessRawTextPacket(AVPacket *Packet)
Definition: avformatdecoder.cpp:3823
GOP_START
static constexpr uint32_t GOP_START
Definition: avformatdecoder.cpp:2999
H2645Parser::onFrameStart
bool onFrameStart(void) const
Definition: H2645Parser.h:62
get_pmt_section_from_AVProgram
static AVBufferRef * get_pmt_section_from_AVProgram(const AVProgram *program)
Definition: avformatdecoder.cpp:1577
AudioTrackType
AudioTrackType
Definition: decoderbase.h:56
is_dual_mono
static bool is_dual_mono(const AVChannelLayout &ch_layout)
Definition: avformatdecoder.cpp:2099
MPEGDescriptor::ParseOnlyInclude
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
Definition: mpegdescriptors.cpp:57
AvFormatDecoder::m_ccd708
CC708Decoder * m_ccd708
Definition: avformatdecoder.h:287
AvFormatDecoder::StreamChangeCheck
virtual void StreamChangeCheck(void)
Definition: avformatdecoder.cpp:4863
kTrackTypeTeletextMenu
@ kTrackTypeTeletextMenu
Definition: decoderbase.h:36
AudioPlayer::HasAudioIn
bool HasAudioIn(void) const
Definition: audioplayer.h:51
MythVideoFrame::m_frameNumber
long long m_frameNumber
Definition: mythframe.h:128
stringutil.h
VideoFrameType
VideoFrameType
Definition: mythframe.h:19
AvFormatDecoder::SetVideoByComponentTag
bool SetVideoByComponentTag(int Tag) override
Definition: avformatdecoder.cpp:4013
AVCParser::getFieldType
field_type getFieldType(void) const override
Definition: AVCParser.cpp:1050
MythCodecContext::DecoderNeedsReset
virtual bool DecoderNeedsReset(AVCodecContext *)
Definition: mythcodeccontext.h:160
AvFormatDecoder::m_pmtTracks
QList< StreamInfo > m_pmtTracks
StreamInfo for 608 and 708 Captions seen in the PMT descriptor.
Definition: avformatdecoder.h:298
kDecodeAllowGPU
@ kDecodeAllowGPU
Definition: mythplayer.h:72
AUDIO_MP3
@ AUDIO_MP3
Definition: lcddevice.h:106
DecoderBase::SetEof
virtual void SetEof(bool eof)
Definition: decoderbase.h:133
AvFormatDecoder::m_lastVPts
std::chrono::milliseconds m_lastVPts
Definition: avformatdecoder.h:273
MythCodecMap::FreeCodecContext
void FreeCodecContext(const AVStream *Stream)
Definition: mythavutil.cpp:333
kDecodeVideo
@ kDecodeVideo
Definition: decoderbase.h:51
AvFormatDecoder::ProcessDSMCCPacket
void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt)
Process DSMCC object carousel packet.
Definition: avformatdecoder.cpp:3702
AvFormatDecoder::m_ic
AVFormatContext * m_ic
Definition: avformatdecoder.h:242
kTrackTypeCC608
@ kTrackTypeCC608
Definition: decoderbase.h:33
AvFormatDecoder::get_current_AVProgram
AVProgram * get_current_AVProgram()
Definition: avformatdecoder.cpp:5231
hardwareprofile.smolt.long
long
Definition: smolt.py:75
AvFormatDecoder::GetCaptionLanguage
virtual int GetCaptionLanguage(TrackType TrackType, int ServiceNum)
Return ATSC Closed Caption Language.
Definition: avformatdecoder.cpp:2512
MythVideoFrame::m_colorprimaries
int m_colorprimaries
Definition: mythframe.h:149
MythVideoFrame::m_pauseFrame
bool m_pauseFrame
Definition: mythframe.h:140
mpegtables.h
AvFormatDecoder::GenerateDummyVideoFrames
bool GenerateDummyVideoFrames(void)
Definition: avformatdecoder.cpp:4909
TestBufferVec
std::vector< char > TestBufferVec
Definition: decoderbase.h:24
InteractiveTV::ProcessDSMCCSection
void ProcessDSMCCSection(unsigned char *data, int length, int componentTag, unsigned carouselId, int dataBroadcastId)
Definition: interactivetv.cpp:55
DecoderBase::m_durToFrameMap
frm_pos_map_t m_durToFrameMap
Definition: decoderbase.h:319
MythDVDBuffer::AudioStreamsChanged
bool AudioStreamsChanged(void) const
Definition: mythdvdbuffer.cpp:1188
MythVideoFrame::m_directRendering
bool m_directRendering
Definition: mythframe.h:145
MythCodecContext::HwDecoderInit
virtual int HwDecoderInit(AVCodecContext *)
Definition: mythcodeccontext.h:151
mpeg_version
uint mpeg_version(AVCodecID codec_id)
Definition: mythcodecid.cpp:455
StringUtil::intToPaddedString
QString intToPaddedString(int n, int width=2)
Creates a zero padded string representation of an integer.
Definition: stringutil.h:27
CC708Decoder::services
void services(std::chrono::seconds seconds, cc708_seen_flags &seen) const
Definition: cc708decoder.cpp:77
DecoderBase::m_playbackInfo
ProgramInfo * m_playbackInfo
Definition: decoderbase.h:279
MythPlayer::DeLimboFrame
void DeLimboFrame(MythVideoFrame *frame)
Definition: mythplayer.cpp:670
AudioPlayer::CanDTSHD
bool CanDTSHD(void)
Definition: audioplayer.cpp:412
AvFormatDecoder::remove_tracks_not_in_same_AVProgram
void remove_tracks_not_in_same_AVProgram(int stream_index)
Definition: avformatdecoder.cpp:2070
mythvideoprofile.h
VBI_DVB_SUBTITLE
@ VBI_DVB_SUBTITLE
< DVB packet
Definition: vbilut.h:25
AvFormatDecoder
A decoder for media files.
Definition: avformatdecoder.h:79
VARIOUS_SPDIF
@ VARIOUS_SPDIF
Definition: lcddevice.h:151
get_canonical_lang
static int get_canonical_lang(const char *lang_cstr)
Definition: avformatdecoder.cpp:330
AvFormatDecoder::DoRewind
bool DoRewind(long long desiredFrame, bool discardFrames=true) override
Definition: avformatdecoder.cpp:587
StreamID::PrivData
@ PrivData
ISO 13818-1 PES private data & ITU H.222.0.
Definition: mpegtables.h:147
MythPlayer::EnableForcedSubtitles
void EnableForcedSubtitles(bool enable)
Definition: mythplayer.cpp:676
MythCodecMap
Definition: mythavutil.h:27
get_avf_buffer
int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
Definition: avformatdecoder.cpp:2680
kDecodeNoDecode
@ kDecodeNoDecode
Definition: mythplayer.h:71
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:68
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
SequenceHeader::aspect
float aspect(bool mpeg1) const
Returns the screen aspect ratio.
Definition: pespacket.cpp:234
kAudioTypeCleanEffects
@ kAudioTypeCleanEffects
Definition: decoderbase.h:60
CaptionServiceDescriptor::CaptionServiceNumber
int CaptionServiceNumber(int i) const
Definition: atscdescriptors.h:110
DecoderBase::FileChanged
void FileChanged(void)
Definition: decoderbase.cpp:869
AvFormatDecoder::ReadPacket
virtual int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket)
Definition: avformatdecoder.cpp:4874
MythPlayer::GetAllowForcedSubtitles
bool GetAllowForcedSubtitles(void) const
Definition: mythplayer.h:204
VBI_DVB
@ VBI_DVB
< IVTV packet
Definition: vbilut.h:24
AvFormatDecoder::GetTeletextLanguage
virtual int GetTeletextLanguage(uint Index)
Returns TeleText language.
Definition: avformatdecoder.cpp:2495
DecoderBase::m_wantedTrack
std::array< StreamInfo, kTrackTypeCount > m_wantedTrack
Definition: decoderbase.h:342
DecoderBase::m_waitingForChange
bool m_waitingForChange
Definition: decoderbase.h:331
AUDIO_WMA
@ AUDIO_WMA
Definition: lcddevice.h:114
AvFormatDecoder::ProcessDataPacket
virtual bool ProcessDataPacket(AVStream *curstream, AVPacket *pkt, DecodeType decodetype)
Definition: avformatdecoder.cpp:3844
kAudioTypeHearingImpaired
@ kAudioTypeHearingImpaired
Definition: decoderbase.h:61
CC608Decoder::FormatCCField
void FormatCCField(std::chrono::milliseconds tc, size_t field, int data)
Definition: cc608decoder.cpp:100
DecoderBase::m_justAfterChange
bool m_justAfterChange
Definition: decoderbase.h:332
AvFormatDecoder::m_lastAPts
std::chrono::milliseconds m_lastAPts
Definition: avformatdecoder.h:274
V4L2_MPEG_VBI_IVTV_TELETEXT_B
@ V4L2_MPEG_VBI_IVTV_TELETEXT_B
Teletext (uses lines 6-22 for PAL, 10-21 for NTSC)
Definition: avformatdecoder.cpp:57
AVCParser::frameRate
double frameRate(void) const
Definition: AVCParser.cpp:1069
MythPlayer::GetSubReader
virtual SubtitleReader * GetSubReader(uint=0)
Definition: mythplayer.h:195
DecoderBase::m_currentAspect
float m_currentAspect
Definition: decoderbase.h:289
mythmediabuffer.h
DecoderBase::SyncPositionMap
virtual bool SyncPositionMap(void)
Updates the position map used for skipping frames.
Definition: decoderbase.cpp:321
AvFormatDecoder::m_seqCount
int m_seqCount
A counter used to determine if we need to force a call to HandleGopStart.
Definition: avformatdecoder.h:258
AUDIO_WAV
@ AUDIO_WAV
Definition: lcddevice.h:109
hardwareprofile.smolt.error
def error(message)
Definition: smolt.py:410
MARK_GOP_BYFRAME
@ MARK_GOP_BYFRAME
Definition: programtypes.h:63
AvFormatDecoder::m_videoCodecId
MythCodecID m_videoCodecId
Definition: avformatdecoder.h:280
AudioInfo
Definition: avformatdecoder.h:38
MythAVUtil::PixelFormatToFrameType
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
Definition: mythavutil.cpp:72
DecoderBase::m_fpsMultiplier
int m_fpsMultiplier
Definition: decoderbase.h:284
AvFormatDecoder::m_prevGopPos
int m_prevGopPos
Definition: avformatdecoder.h:262
kDecodeSingleThreaded
@ kDecodeSingleThreaded
Definition: mythplayer.h:68
MythVideoFrame::m_pitches
FramePitches m_pitches
Definition: mythframe.h:141
AvFormatDecoder::ProcessVBIDataPacket
void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt)
Process ivtv proprietary embedded vertical blanking interval captions.
Definition: avformatdecoder.cpp:3560
MythPlayer::SetVideoParams
virtual void SetVideoParams(int w, int h, double fps, float aspect, bool ForceUpdate, int ReferenceFrames, FrameScanType=kScan_Ignore, const QString &codecName=QString())
Definition: mythplayer.cpp:321
MythCodecContext::FilteredReceiveFrame
virtual int FilteredReceiveFrame(AVCodecContext *Context, AVFrame *Frame)
Retrieve and process/filter AVFrame.
Definition: mythcodeccontext.cpp:623
MythVideoFrame::m_topFieldFirst
bool m_topFieldFirst
Definition: mythframe.h:134
silence_ffmpeg_logging
static bool silence_ffmpeg_logging
Definition: avformatdecoder.cpp:129
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:910
AvFormatDecoder::m_isDbIgnored
bool m_isDbIgnored
Definition: avformatdecoder.h:238
AudioPlayer::GetMaxChannels
uint GetMaxChannels(void)
Definition: audioplayer.cpp:417
AvFormatDecoder::PreProcessVideoPacket
bool PreProcessVideoPacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
Definition: avformatdecoder.cpp:3201
StreamInfo::m_av_substream_index
int m_av_substream_index
Audio only; -1 for no substream, 0 for first dual audio stream, 1 for second dual.
Definition: decoderbase.h:112
DecoderBase::m_selectedForcedTrack
std::array< StreamInfo, kTrackTypeCount > m_selectedForcedTrack
Definition: decoderbase.h:344
mythuihelper.h
TeletextDecoder::GetDecoderType
int GetDecoderType(void) const
Definition: teletextdecoder.h:15
DecoderBase::DoFastForwardSeek
virtual void DoFastForwardSeek(long long desiredFrame, bool &needflush)
Seeks to the keyframe just before the desiredFrame if exact seeks is enabled, or the frame just after...
Definition: decoderbase.cpp:818
kCodec_MPEG2
@ kCodec_MPEG2
Definition: mythcodecid.h:23
mythbdbuffer.h
kMaxVideoQueueSize
static constexpr ssize_t kMaxVideoQueueSize
Definition: avformatdecoder.cpp:126
AvFormatDecoder::m_audioReadAhead
std::chrono::milliseconds m_audioReadAhead
Definition: avformatdecoder.h:324
CaptionServiceDescriptor::toString
QString toString() const override
Definition: atscdescriptors.cpp:186
AudioPlayer::GetAudioOutput
AudioOutput * GetAudioOutput(void) const
Return internal AudioOutput object.
Definition: audioplayer.h:102
AvFormatDecoder::FlagIsSet
bool FlagIsSet(PlayerFlags arg)
Definition: avformatdecoder.h:228
MythPlayer::SetKeyframeDistance
void SetKeyframeDistance(int keyframedistance)
Definition: mythplayer.cpp:316
ProgramMapTable::ProgramInfoLength
uint ProgramInfoLength(void) const
Definition: mpegtables.h:734
DecoderBase::UpdateFramesPlayed
virtual void UpdateFramesPlayed(void)
Definition: decoderbase.cpp:864
DecoderBase::m_currentHeight
int m_currentHeight
Definition: decoderbase.h:288
MythVideoFrame::m_stereo3D
uint m_stereo3D
Definition: mythframe.h:155
Buffer
Definition: MythExternControl.h:36
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
MythCodecContext::RetrieveFrame
virtual bool RetrieveFrame(AVCodecContext *, MythVideoFrame *, AVFrame *)
Definition: mythcodeccontext.h:152
MythVideoProfile::SetInput
void SetInput(QSize Size, float Framerate=0, const QString &CodecName=QString(), const QStringList &DisallowedDecoders=QStringList())
Definition: mythvideoprofile.cpp:320
CODEC_IS_H264
static bool CODEC_IS_H264(AVCodecID id)
Definition: mythcodecid.h:382
AvFormatDecoder::m_audioIn
AudioInfo m_audioIn
Definition: avformatdecoder.h:315
AvFormatDecoder::GetAudioTrackType
virtual AudioTrackType GetAudioTrackType(uint StreamIndex)
Definition: avformatdecoder.cpp:2547
AudioInfo::m_doPassthru
bool m_doPassthru
Definition: avformatdecoder.h:58
AudioPlayer::NeedDecodingBeforePassthrough
bool NeedDecodingBeforePassthrough(void)
Definition: audioplayer.cpp:471
DecoderBase::m_framesPlayed
long long m_framesPlayed
Definition: decoderbase.h:291
MythAVFormatBuffer::SetInInit
void SetInInit(bool State)
Definition: mythavformatbuffer.cpp:103
kCodec_MPEG1
@ kCodec_MPEG1
Definition: mythcodecid.h:22
AvFormatDecoder::m_averrorCount
int m_averrorCount
Definition: avformatdecoder.h:283
mythcorecontext.h
MythMediaBuffer::IsInStillFrame
virtual bool IsInStillFrame(void) const
Definition: mythmediabuffer.h:141
AvFormatDecoder::ScanRawTextCaptions
void ScanRawTextCaptions(int av_stream_index)
Definition: avformatdecoder.cpp:1794
DecoderBase::m_mythCodecCtx
MythCodecContext * m_mythCodecCtx
Definition: decoderbase.h:348
MythPlayer::SetFramesPlayed
void SetFramesPlayed(uint64_t played)
Definition: mythplayer.cpp:559
AvFormatDecoder::m_hasVideo
bool m_hasVideo
Definition: avformatdecoder.h:266
DecoderBase::m_positionMapLock
QRecursiveMutex m_positionMapLock
Definition: decoderbase.h:316
AudioOutputUtil::has_optimized_SIMD
static bool has_optimized_SIMD()
Returns true if the processor supports MythTV's optimized SIMD for AudioOutputUtil/AudioConvert.
Definition: audiooutpututil.cpp:52
AvFormatDecoder::m_needDummyVideoFrames
bool m_needDummyVideoFrames
Definition: avformatdecoder.h:267
MythVideoFrame::m_type
VideoFrameType m_type
Definition: mythframe.h:118
AvFormatDecoder::ForceSetupAudioStream
void ForceSetupAudioStream(void) override
Definition: avformatdecoder.cpp:4966
AvFormatDecoder::m_lastCcPtsu
std::chrono::microseconds m_lastCcPtsu
Definition: avformatdecoder.h:275
AvFormatDecoder::DoFastForward
bool DoFastForward(long long desiredFrame, bool discardFrames=true) override
Skips ahead or rewinds to desiredFrame.
Definition: avformatdecoder.cpp:599
MythPlayer::GetFreeVideoFrames
int GetFreeVideoFrames(void) const
Returns the number of frames available for decoding onto.
Definition: mythplayer.cpp:569
kTrackTypeVideo
@ kTrackTypeVideo
Definition: decoderbase.h:31
avformatdecoder.h
AvFormatDecoder::HandleGopStart
void HandleGopStart(AVPacket *pkt, bool can_reliably_parse_keyframes)
Update our position map, keyframe distance, and the like.
Definition: avformatdecoder.cpp:2885
DecoderBase::m_decodeAllSubtitles
bool m_decodeAllSubtitles
Definition: decoderbase.h:339
LCDVideoFormatSet
LCDVideoFormatSet
Definition: lcddevice.h:118
AvFormatDecoder::GetXDS
QString GetXDS(const QString &Key) const override
Definition: avformatdecoder.cpp:3969
AUDIO_DTS
@ AUDIO_DTS
Definition: lcddevice.h:113
get_avf_buffer_dxva2
int get_avf_buffer_dxva2(struct AVCodecContext *c, AVFrame *pic, int)
Definition: avformatdecoder.cpp:2743
AvFormatDecoder::m_avCodecLock
QRecursiveMutex m_avCodecLock
Definition: avformatdecoder.h:326
AudioInfo::format
AudioFormat format
Definition: avformatdecoder.h:53
filter_lang
static std::vector< int > filter_lang(const sinfo_vec_t &tracks, int lang_key, const std::vector< int > &ftype)
Definition: avformatdecoder.cpp:4044
AvFormatDecoder::DoRewindSeek
bool DoRewindSeek(long long desiredFrame) override
Definition: avformatdecoder.cpp:2484
VIDEO_MPG
@ VIDEO_MPG
Definition: lcddevice.h:120
MythTimer::kStartRunning
@ kStartRunning
Definition: mythtimer.h:17
StreamInfo::m_language
int m_language
ISO639 canonical language key; Audio, Subtitle, CC, Teletext, RawText.
Definition: decoderbase.h:107
audiooutput.h
AvFormatDecoder::m_audioOut
AudioInfo m_audioOut
Definition: avformatdecoder.h:316
DecoderBase::m_watchingRecording
bool m_watchingRecording
Definition: decoderbase.h:325
get_pmt_section_for_AVStream_index
static AVBufferRef * get_pmt_section_for_AVStream_index(AVFormatContext *context, int stream_index)
Definition: avformatdecoder.cpp:1586
AvFormatDecoder::GetSubtitleLanguage
virtual int GetSubtitleLanguage(uint, uint StreamIndex)
Returns DVD Subtitle language.
Definition: avformatdecoder.cpp:2505
AvFormatDecoder::m_avcParser
AVCParser * m_avcParser
Definition: avformatdecoder.h:240
AvFormatDecoder::m_resetHardwareDecoders
bool m_resetHardwareDecoders
Definition: avformatdecoder.h:321
mythavutil.h
AvFormatDecoder::UpdateCaptionTracksFromStreams
void UpdateCaptionTracksFromStreams(bool check_608, bool check_708)
Definition: avformatdecoder.cpp:2816
AvFormatDecoder::m_streamTrackTypes
QList< TrackType > m_streamTrackTypes
TrackType (608 or 708) for Captions seen in the caption stream itself but not seen in the PMT.
Definition: avformatdecoder.h:306
CC708Decoder::decode_cc_null
void decode_cc_null(void)
Definition: cc708decoder.cpp:70
AvFormatDecoder::PostProcessTracks
virtual void PostProcessTracks(void)
Definition: avformatdecoder.h:220
MythPlayer::GetNextVideoFrame
MythVideoFrame * GetNextVideoFrame(void)
Removes a frame from the available queue for decoding onto.
Definition: mythplayer.cpp:585
H2645Parser::FIELD_BOTTOM
@ FIELD_BOTTOM
Definition: H2645Parser.h:46
kScan_Detect
@ kScan_Detect
Definition: videoouttypes.h:97
AvFormatDecoder::GetCodecDecoderName
QString GetCodecDecoderName(void) const override
Definition: avformatdecoder.cpp:4934
kTrackTypeTeletextCaptions
@ kTrackTypeTeletextCaptions
Definition: decoderbase.h:35
ProgramInfo::QueryTotalDuration
std::chrono::milliseconds QueryTotalDuration(void) const
If present this loads the total duration in milliseconds of the main video stream from recordedmarkup...
Definition: programinfo.cpp:4642
MythMediaBuffer::IsDisc
bool IsDisc(void) const
Definition: mythmediabuffer.cpp:1835
MythMediaBuffer::GetReadPosition
virtual long long GetReadPosition(void) const =0
H2645Parser::onKeyFrameStart
bool onKeyFrameStart(void) const
Definition: H2645Parser.h:63
CaptionServiceDescriptor::Type
bool Type(int i) const
Definition: atscdescriptors.h:100
get_decoder_name
QString get_decoder_name(MythCodecID codec_id)
Definition: mythcodecid.cpp:714
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:24
AvFormatDecoder::CanHandle
static bool CanHandle(TestBufferVec &testbuf, const QString &filename)
Perform an av_probe_input_format on the passed data to see if we can decode it with this class.
Definition: avformatdecoder.cpp:829
MythPlayer::SetFrameRate
void SetFrameRate(double fps)
Definition: mythplayer.cpp:374
kDecodeNoLoopFilter
@ kDecodeNoLoopFilter
Definition: mythplayer.h:70
AvFormatDecoder::DecodeCCx08
void DecodeCCx08(const uint8_t *buf, uint buf_size)
Definition: avformatdecoder.cpp:2775
mythchrono.h
V4L2_MPEG_VBI_IVTV_WSS_625
@ V4L2_MPEG_VBI_IVTV_WSS_625
Wide Screen Signal (line 20 NTSC, line 23 PAL)
Definition: avformatdecoder.cpp:59
MythVideoFrame::GetNumPlanes
static uint GetNumPlanes(VideoFrameType Type)
Definition: mythframe.h:213
AvFormatDecoder::AutoSelectTrack
int AutoSelectTrack(uint type) override
Select best track.
Definition: avformatdecoder.cpp:4033
AvFormatDecoder::H264PreProcessPkt
int H264PreProcessPkt(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
Definition: avformatdecoder.cpp:3099
SubtitleReader::AddRawTextSubtitle
void AddRawTextSubtitle(const QStringList &list, std::chrono::milliseconds duration)
Definition: subtitlereader.cpp:196
AvFormatDecoder::m_firstVPtsInuse
bool m_firstVPtsInuse
Definition: avformatdecoder.h:277
AvFormatDecoder::m_codecMap
MythCodecMap m_codecMap
Definition: avformatdecoder.h:243
DecoderBase::m_nextDecodedFrameIsKeyFrame
bool m_nextDecodedFrameIsKeyFrame
Definition: decoderbase.h:299
VERBOSE_LEVEL_NONE
static bool VERBOSE_LEVEL_NONE()
Definition: mythlogging.h:28
MythDVDBuffer::NumMenuButtons
int NumMenuButtons(void) const
Definition: mythdvdbuffer.cpp:1721
remoteencoder.h
AvFormatDecoder::m_gopSet
bool m_gopSet
Definition: avformatdecoder.h:254
iso639_str2_to_str3
QString iso639_str2_to_str3(const QString &str2)
Definition: iso639.cpp:68
mpeg::chrono::pts
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
StringUtil::split_sv
std::vector< std::string_view > split_sv(const std::string_view s, const std::string_view delimiter)
Split a std::string_view into a std::vector of std::string_views.
Definition: stringutil.h:74
MythVideoFrame::m_height
int m_height
Definition: mythframe.h:121
CaptionServiceDescriptor::ServicesCount
uint ServicesCount() const
Definition: atscdescriptors.h:88
interactivetv.h
AvFormatDecoder::selectBestAudioTrack
int selectBestAudioTrack(int lang_key, const std::vector< int > &ftype)
Definition: avformatdecoder.cpp:4101
iso639.h
ISO 639-1 and ISO 639-2 support functions.
MythVideoFrame::ClearMetadata
void ClearMetadata()
Definition: mythframe.cpp:149
kTrackTypeAudio
@ kTrackTypeAudio
Definition: decoderbase.h:30
MythAVRational
C++ wrapper for FFmpeg libavutil AVRational.
Definition: mythavrational.h:14
VideoBuffers::ReinitBuffer
static bool ReinitBuffer(MythVideoFrame *Frame, VideoFrameType Type, MythCodecID CodecID, int Width, int Height)
Definition: videobuffers.cpp:982
AvFormatDecoder::m_pmtTrackTypes
QList< TrackType > m_pmtTrackTypes
TrackType (608 or 708) for Captions seen in the PMT descriptor.
Definition: avformatdecoder.h:300
MYTH_HEIGHT_ALIGNMENT
static constexpr uint8_t MYTH_HEIGHT_ALIGNMENT
Definition: mythframe.h:17
VIDEO_DIVX
@ VIDEO_DIVX
Definition: lcddevice.h:121
AvFormatDecoder::ProcessDVBDataPacket
void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt)
Process DVB Teletext.
Definition: avformatdecoder.cpp:3645
codec_is_std
static bool codec_is_std(MythCodecID id)
Definition: mythcodecid.h:294
AVCParser::getRefFrames
uint getRefFrames(void) const
Definition: AVCParser.h:131
AvFormatDecoder::SetupAudioStream
bool SetupAudioStream(void)
Reinitializes audio if it needs to be reinitialized.
Definition: avformatdecoder.cpp:5022
DecoderBase::m_lastKey
long long m_lastKey
Definition: decoderbase.h:296
kTrackTypeRawText
@ kTrackTypeRawText
Definition: decoderbase.h:37
AvFormatDecoder::GetNumChapters
int GetNumChapters() override
Definition: avformatdecoder.cpp:523
MythMediaBuffer::DVD
const MythDVDBuffer * DVD(void) const
Definition: mythmediabuffer.cpp:1850
AvFormatDecoder::m_swsCtx
struct SwsContext * m_swsCtx
Definition: avformatdecoder.h:251
MythCodecContext
Definition: mythcodeccontext.h:52
FAIL
#define FAIL(errmsg)
Definition: avformatdecoder.cpp:200
uint16_t
unsigned short uint16_t
Definition: iso6937tables.h:3
AvFormatDecoder::filter_max_ch
int filter_max_ch(const AVFormatContext *ic, const sinfo_vec_t &tracks, const std::vector< int > &fs, enum AVCodecID codecId=AV_CODEC_ID_NONE, int profile=-1)
Definition: avformatdecoder.cpp:4071
CC608Decoder::DecodeVPS
void DecodeVPS(const unsigned char *buf)
Definition: cc608decoder.cpp:889
AvFormatDecoder::ScanTeletextCaptions
void ScanTeletextCaptions(int av_index)
Definition: avformatdecoder.cpp:1737
AvFormatDecoder::m_disablePassthru
bool m_disablePassthru
Definition: avformatdecoder.h:313
azlyrics.info
dictionary info
Definition: azlyrics.py:7
AvFormatDecoder::InitVideoCodec
void InitVideoCodec(AVStream *stream, AVCodecContext *codecContext, bool selectedStream=false)
Definition: avformatdecoder.cpp:1387
AvFormatDecoder::AvFormatDecoder
AvFormatDecoder(MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
Definition: avformatdecoder.cpp:366
get_video_dim
static QSize get_video_dim(const AVCodecContext &ctx)
Definition: avformatdecoder.cpp:131
AvFormatDecoder::GetVideoFrameRate
float GetVideoFrameRate(AVStream *Stream, AVCodecContext *Context, bool Sanitise=false)
Definition: avformatdecoder.cpp:1235
AudioPlayer::CanDownmix
bool CanDownmix(void)
Definition: audioplayer.cpp:439
DecoderBase::m_trackTotalDuration
bool m_trackTotalDuration
Definition: decoderbase.h:306
AvFormatDecoder::OpenAVCodec
bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
Definition: avformatdecoder.cpp:2450
kAudioTypeSpokenSubs
@ kAudioTypeSpokenSubs
Definition: decoderbase.h:62
StreamID::IsObjectCarousel
static bool IsObjectCarousel(uint type)
Returns true iff stream contains DSMCC Object Carousel.
Definition: mpegtables.h:190
CC608Decoder::GetXDS
QString GetXDS(const QString &key) const
Definition: cc608decoder.cpp:1081
AVCParser::pictureWidthCropped
uint pictureWidthCropped(void) const override
Definition: AVCParser.cpp:1027
DecoderBase::m_framesRead
long long m_framesRead
Definition: decoderbase.h:292
AvFormatDecoder::~AvFormatDecoder
~AvFormatDecoder() override
Definition: avformatdecoder.cpp:396
TrackType
TrackType
Track types.
Definition: decoderbase.h:27
AvFormatDecoder::CloseContext
void CloseContext()
Definition: avformatdecoder.cpp:446
get_aspect
static float get_aspect(const AVCodecContext &ctx)
Definition: avformatdecoder.cpp:135
MythVideoFrame
Definition: mythframe.h:87
AvFormatDecoder::m_ttd
TeletextDecoder * m_ttd
Definition: avformatdecoder.h:288
DecoderBase::Reset
virtual void Reset(bool reset_video_data, bool seek_reset, bool reset_file)
Definition: decoderbase.cpp:47
AvFormatDecoder::SetupAudioStreamSubIndexes
void SetupAudioStreamSubIndexes(int streamIndex)
Reacts to DUAL/STEREO changes on the fly and fix streams.
Definition: avformatdecoder.cpp:2579
ProgramMapTable::StreamInfoLength
uint StreamInfoLength(uint i) const
Definition: mpegtables.h:746
lcddevice.h
kAudioTypeAudioDescription
@ kAudioTypeAudioDescription
Definition: decoderbase.h:59
MythMediaBuffer::IsStreamed
virtual bool IsStreamed(void)
Definition: mythmediabuffer.h:134
MythAVFormatBuffer
Definition: mythavformatbuffer.h:12
MythVideoFrame::m_deinterlaceInuse
MythDeintType m_deinterlaceInuse
Definition: mythframe.h:160
iso639_str3_to_key
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:60
DecoderBase::m_fpsSkip
int m_fpsSkip
Definition: decoderbase.h:285
AvFormatDecoder::GetFrame
bool GetFrame(DecodeType Type, bool &Retry) override
Demux, preprocess and possibly decode a frame of video/audio.
Definition: avformatdecoder.cpp:4563
AvFormatDecoder::m_ccX08InPmt
std::array< bool, 68 > m_ccX08InPmt
Lookup table for whether a stream was seen in the PMT entries 0-3 correspond to CEA-608 CC1 through C...
Definition: avformatdecoder.h:292
build_compdb.filename
filename
Definition: build_compdb.py:21
SequenceHeader
Definition: pespacket.h:238
AvFormatDecoder::get_current_AVStream_index
int get_current_AVStream_index(TrackType type)
Definition: avformatdecoder.cpp:5222
AvFormatDecoder::DoFastForwardSeek
void DoFastForwardSeek(long long desiredFrame, bool &needflush) override
Seeks to the keyframe just before the desiredFrame if exact seeks is enabled, or the frame just after...
Definition: avformatdecoder.cpp:2489
MythVideoProfile::IsSkipLoopEnabled
bool IsSkipLoopEnabled() const
Definition: mythvideoprofile.cpp:385
MythDVDBuffer::GetMenuSPUPkt
void GetMenuSPUPkt(uint8_t *Buffer, int Size, int StreamID, uint32_t StartTime)
Get SPU pkt from dvd menu subtitle stream.
Definition: mythdvdbuffer.cpp:1404
CC608Decoder::GetServices
void GetServices(std::chrono::seconds seconds, CC608Seen &seen) const
Definition: cc608decoder.cpp:55
AvFormatDecoder::m_frameDecoded
int m_frameDecoded
Definition: avformatdecoder.h:247
AvFormatDecoder::ScanStreams
int ScanStreams(bool novideo)
Definition: avformatdecoder.cpp:2107
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:77
MythVideoProfile::GetMaxCPUs
uint GetMaxCPUs() const
Definition: mythvideoprofile.cpp:380
CODEC_IS_MPEG
static bool CODEC_IS_MPEG(AVCodecID id)
Definition: mythcodecid.h:384
DecoderBase::SeekReset
virtual void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames)
Definition: decoderbase.cpp:74
AVCParser::Reset
void Reset(void) override
Definition: AVCParser.cpp:88
AVCParser::addBytes
uint32_t addBytes(const uint8_t *bytes, uint32_t byte_count, uint64_t stream_offset) override
Definition: AVCParser.cpp:285
samples
static const std::array< const uint64_t, 4 > samples
Definition: element.cpp:46
AvFormatDecoder::ProcessSubtitlePacket
bool ProcessSubtitlePacket(AVCodecContext *codecContext, AVStream *stream, AVPacket *pkt)
Definition: avformatdecoder.cpp:3740
DecoderBase::DoRewind
virtual bool DoRewind(long long desiredFrame, bool discardFrames=true)
Definition: decoderbase.cpp:554
mythaverror.h
AvFormatDecoder::UpdateATSCCaptionTracks
void UpdateATSCCaptionTracks(void)
Definition: avformatdecoder.cpp:1668
ByteReader::find_start_code_truncated
const MTV_PUBLIC uint8_t * find_start_code_truncated(const uint8_t *p, const uint8_t *end, uint32_t *start_code)
By preserving the start_code value between subsequent calls, the caller can detect start codes across...
Definition: bytereader.cpp:74
MythAVRational::toFixed
long long toFixed(long long base) const
Convert the rational number to fixed point.
Definition: mythavrational.h:32
LCD
Definition: lcddevice.h:169
MythVideoFrame::m_deinterlaceInuse2x
bool m_deinterlaceInuse2x
Definition: mythframe.h:161
MythVideoFrame::m_aspect
float m_aspect
Definition: mythframe.h:126
CaptionServiceDescriptor::CanonicalLanguageKey
int CanonicalLanguageKey(int i) const
Definition: atscdescriptors.h:95
av_make_error_stdstring
char * av_make_error_stdstring(std::string &errbuf, int errnum)
A C++ equivalent to av_make_error_string.
Definition: mythaverror.cpp:42
DecoderBase
Definition: decoderbase.h:121
AvFormatDecoder::m_ccd608
CC608Decoder * m_ccd608
Definition: avformatdecoder.h:286
AvFormatDecoder::DoPassThrough
bool DoPassThrough(const AVCodecParameters *par, bool withProfile=true)
Definition: avformatdecoder.cpp:4995
kDecodeFewBlocks
@ kDecodeFewBlocks
Definition: mythplayer.h:69
DecoderBase::GetPlayer
MythPlayer * GetPlayer()
Definition: decoderbase.h:153
DecoderBase::m_recordingHasPositionMap
bool m_recordingHasPositionMap
Definition: decoderbase.h:312
VARIOUS_HDTV
@ VARIOUS_HDTV
Definition: lcddevice.h:150
AvFormatDecoder::streams_changed
static void streams_changed(void *data, int avprogram_id)
Definition: avformatdecoder.cpp:856
MythPlayer::ReleaseNextVideoFrame
virtual void ReleaseNextVideoFrame(MythVideoFrame *buffer, std::chrono::milliseconds timecode, bool wrap=true)
Places frame on the queue of frames ready for display.
Definition: mythplayer.cpp:595
uint
unsigned int uint
Definition: freesurround.h:24
AvFormatDecoder::m_startCodeState
uint32_t m_startCodeState
Definition: avformatdecoder.h:271
MythCodecContext::FindDecoder
static MythCodecID FindDecoder(const QString &Decoder, AVStream *Stream, AVCodecContext **Context, const AVCodec **Codec)
Definition: mythcodeccontext.cpp:250
dvbdescriptors.h
millisecondsFromFloat
std::enable_if_t< std::is_floating_point_v< T >, std::chrono::milliseconds > millisecondsFromFloat(T value)
Helper function for convert a floating point number to a duration.
Definition: mythchrono.h:91
MythVideoFrame::m_buffer
uint8_t * m_buffer
Definition: mythframe.h:119
DecoderBase::m_frameCounter
uint64_t m_frameCounter
Definition: decoderbase.h:293
H2645Parser::stateChanged
bool stateChanged(void) const
Definition: H2645Parser.h:60
MythPlayer::DiscardVideoFrame
void DiscardVideoFrame(MythVideoFrame *buffer)
Places frame in the available frames queue.
Definition: mythplayer.cpp:626
teletextdecoder.h