15 #include "libavutil/avutil.h"
16 #include "libavutil/error.h"
17 #include "libavutil/intreadwrite.h"
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"
29 #ifdef USING_MEDIACODEC // Android
31 #include "libavcodec/jni.h"
33 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
34 #include <QtAndroidExtras>
36 #include <QJniEnvironment>
37 #define QAndroidJniEnvironment QJniEnvironment
65 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
68 #include <QStringDecoder>
83 #include "libmythbase/mythconfig.h"
111 using namespace std::string_view_literals;
113 #define LOC QString("AFD: ")
123 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
133 return {ctx.width >> ctx.lowres, ctx.height >> ctx.lowres};
137 float aspect_ratio = 0.0F;
139 if (ctx.sample_aspect_ratio.num && ctx.height)
141 aspect_ratio = av_q2d(ctx.sample_aspect_ratio) *
142 static_cast<double>(ctx.width);
143 aspect_ratio /= (float) ctx.height;
146 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
149 aspect_ratio = (float)ctx.width / (
float)ctx.height;
151 aspect_ratio = 4.0F / 3.0F;
158 static constexpr
float kDefaultAspect = 4.0F / 3.0F;
159 int asp =
p.aspectRatio();
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;
169 float aspect_ratio = asp * 0.000001F;
170 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
172 if (
p.pictureHeight() &&
p.pictureWidth())
175 (float)
p.pictureWidth() /(float)
p.pictureHeight();
179 aspect_ratio = kDefaultAspect;
200 #define FAIL(errmsg) do { \
201 LOG(VB_PLAYBACK, LOG_INFO, LOC + (errmsg)); \
212 switch (Stream->codecpar->codec_type)
216 case AVMEDIA_TYPE_VIDEO:
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");
229 case AVMEDIA_TYPE_AUDIO:
231 FAIL(
"No codec for audio stream");
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");
253 case AVMEDIA_TYPE_DATA:
254 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
261 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
262 FAIL(
"Unknown codec");
266 static void myth_av_log(
void *ptr,
int level,
const char* fmt, va_list vl)
274 static QString s_fullLine(
"");
275 static QMutex s_stringLock;
276 uint64_t verbose_mask = VB_LIBAV;
277 LogLevel_t verbose_level = LOG_EMERG;
283 verbose_level = LOG_EMERG;
284 verbose_mask |= VB_GENERAL;
287 verbose_level = LOG_CRIT;
288 verbose_mask |= VB_GENERAL;
291 verbose_level = LOG_ERR;
294 verbose_level = LOG_WARNING;
297 verbose_level = LOG_INFO;
301 verbose_level = LOG_DEBUG;
304 verbose_level = LOG_TRACE;
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'));
321 s_fullLine += QString::vasprintf(fmt, vl);
322 if (s_fullLine.endsWith(
"\n"))
324 LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
325 s_fullLine.truncate(0);
327 s_stringLock.unlock();
332 if (lang_cstr[0] ==
'\0' || lang_cstr[1] ==
'\0')
336 if (lang_cstr[2] ==
'\0')
338 QString tmp2 = lang_cstr;
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";
372 m_playerFlags(flags),
377 m_itv(parent->GetInteractiveTV()),
378 m_audioSamples((uint8_t *)av_mallocz(
AudioOutput::kMaxSizeBuffer))
392 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"PlayerFlags: 0x%1, AudioReadAhead: %2 msec")
401 av_packet_free(&pkt);
419 lcd->setAudioFormatLEDs(
AUDIO_AC3,
false);
420 lcd->setVideoFormatLEDs(
VIDEO_MPG,
false);
437 for (
uint i = 0; i <
m_ic->nb_streams; i++)
439 AVStream *st =
m_ic->streams[i];
455 avformat_close_input(&
m_ic);
461 static int64_t
lsb3full(int64_t lsb, int64_t base_ts,
int lsb_bits)
463 int64_t mask = (lsb_bits < 64) ? (1LL<<lsb_bits)-1 : -1LL;
464 return ((lsb - base_ts)&mask);
469 int64_t start_pts = 0;
471 AVStream *st =
nullptr;
472 for (
uint i = 0; i <
m_ic->nb_streams; i++)
474 AVStream *st1 =
m_ic->streams[i];
475 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
484 if (
m_ic->start_time != AV_NOPTS_VALUE)
486 start_pts = av_rescale(
m_ic->start_time,
488 AV_TIME_BASE * (int64_t)st->time_base.num);
491 int64_t
pts = av_rescale(timecode.count() / 1000.0,
502 std::chrono::milliseconds timecode)
504 int64_t start_pts = 0;
506 if (
m_ic->start_time != AV_NOPTS_VALUE)
508 start_pts = av_rescale(
m_ic->start_time,
510 AV_TIME_BASE * (int64_t)st->time_base.num);
513 int64_t
pts = av_rescale(timecode.count() / 1000.0,
526 return m_ic->nb_chapters;
536 for (
int i = 0; i < total; i++)
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 /
543 times.push_back(std::chrono::seconds((
long long)total_secs));
552 for (
int i = (
m_ic->nb_chapters - 1); i > -1 ; i--)
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 /
559 auto framenum = (
long long)(total_secs *
m_fps);
560 if (framesPlayed >= framenum)
562 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
563 QString(
"GetCurrentChapter(selected chapter %1 framenum %2)")
564 .arg(i + 1).arg(framenum));
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 /
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));
589 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"DoRewind(%1, %2 discard frames)")
590 .arg(desiredFrame).arg( discardFrames ?
"do" :
"don't" ));
596 return do_av_seek(desiredFrame, discardFrames, AVSEEK_FLAG_BACKWARD);
601 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
602 QString(
"DoFastForward(%1 (%2), %3 discard frames)")
604 .arg((discardFrames) ?
"do" :
"don't"));
612 if (seekDelta >= 0 && seekDelta < 2 && m_parent->GetPlaySpeed() == 0.0F)
618 return do_av_seek(desiredFrame, discardFrames, 0);
624 if (
m_ic->start_time != AV_NOPTS_VALUE)
625 ts =
m_ic->start_time;
628 long double seekts = desiredFrame * AV_TIME_BASE /
m_fps;
629 ts += (
long long)seekts;
636 flags |= AVSEEK_FLAG_BACKWARD;
639 int ret = av_seek_frame(
m_ic, -1, ts, flags);
642 LOG(VB_GENERAL, LOG_ERR,
LOC +
643 QString(
"av_seek_frame(m_ic, -1, %1, 0b%2) error: %3").arg(
645 QString::number(flags, 2),
652 reader->SeekFrame(ts, flags);
654 int normalframes = 0;
672 bool doflush,
bool discardFrames)
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"));
701 avformat_flush(
m_ic);
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;
714 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SeekReset() flushing");
715 for (
uint i = 0; i <
m_ic->nb_streams; i++)
721 if (enc && enc->internal)
722 avcodec_flush_buffers(enc);
729 av_packet_free(&pkt);
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)
760 QElapsedTimer getframetimer;
761 getframetimer.start();
763 while (retry && !getframetimer.hasExpired(100))
768 std::this_thread::sleep_for(1ms);
776 if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
778 const int giveUpPredictionMs = 400;
779 int remainingTimeMs =
780 skipFrames * (float)begin.
elapsed().count() / profileFrames;
781 if (remainingTimeMs > giveUpPredictionMs)
783 LOG(VB_PLAYBACK, LOG_DEBUG,
784 QString(
"Frame-by-frame seeking would take "
785 "%1 ms to finish, skipping.").arg(remainingTimeMs));
802 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
803 QString(
"Resetting byte context eof (livetv %1 was eof %2)")
805 m_ic->pb->eof_reached = 0;
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));
822 if (reset_video_data)
832 memset(&probe, 0,
sizeof(AVProbeData));
834 QByteArray fname =
filename.toLatin1();
835 probe.filename = fname.constData();
836 probe.buf = (
unsigned char *)testbuf.data();
837 probe.buf_size = testbuf.size();
839 int score = AVPROBE_SCORE_MAX/4;
851 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
853 return av_probe_input_format2(&probe,
static_cast<int>(
true), &score) !=
nullptr;
860 int cnt = decoder->
m_ic->nb_streams;
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)));
866 auto* program = decoder->get_current_AVProgram();
867 if (program !=
nullptr && program->id != avprogram_id)
871 decoder->m_streamsChanged =
true;
885 int retval = avformat_find_stream_info(
m_ic,
nullptr);
923 const AVInputFormat *fmt =
nullptr;
925 QByteArray fnamea = fnames.toLatin1();
926 const char *
filename = fnamea.constData();
929 memset(&probe, 0,
sizeof(AVProbeData));
931 probe.buf =
reinterpret_cast<unsigned char *
>(testbuf.data());
933 probe.buf_size = testbuf.size();
936 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
938 fmt = av_probe_input_format(&probe,
static_cast<int>(
true));
941 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Probe failed for '%1'").arg(
filename));
945 if (strcmp(fmt->name,
"mpegts") == 0 &&
948 const AVInputFormat *fmt2 = av_find_input_format(
"mpegts-ffmpeg");
952 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using FFmpeg MPEG-TS demuxer (forced)");
957 bool scancomplete =
false;
958 int remainingscans = 5;
960 while (!scancomplete && remainingscans--)
974 while (!found && --retries)
976 m_ic = avformat_alloc_context();
979 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Could not allocate format context.");
986 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
987 QString(
"Buffer size: %1 Streamed %2 Seekable %3 Available %4")
990 .arg(
m_ic->pb->seekable)
994 err = avformat_open_input(&
m_ic,
filename, fmt,
nullptr);
998 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Failed to open input ('%1')")
1006 QThread::usleep(100000);
1012 if (strcmp(fmt->name,
"mpegts") == 0)
1014 fmt = av_find_input_format(
"mpegts-ffmpeg");
1017 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to use original FFmpeg MPEG-TS demuxer.");
1030 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error opening input. Aborting");
1042 m_ic->max_analyze_duration = 60LL * AV_TIME_BASE;
1048 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Could not find codec parameters for '%1'").arg(
filename));
1055 scancomplete =
true;
1060 scancomplete =
false;
1064 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stream scan incomplete - retrying");
1065 QThread::usleep(250000);
1073 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Scan incomplete - playback may not work");
1076 m_ic->stream_change_data =
this;
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))
1108 int initialAudio = -1;
1109 int initialVideo = -1;
1110 if (
m_itv ==
nullptr)
1112 if (
m_itv !=
nullptr)
1114 if (initialAudio >= 0)
1116 if (initialVideo >= 0)
1119 #endif // USING_MHEG
1137 std::chrono::seconds dur = 0s;
1146 dur = duration_cast<std::chrono::seconds>(av_duration(
m_ic->duration));
1157 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1158 "Recording has no position -- using libavformat seeking.");
1167 float bytespersec = (float)
m_bitrate / 8 / 2;
1170 (int)(secs *
static_cast<float>(
m_fps)));
1179 if (strcmp(fmt->name,
"avi") == 0)
1192 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Position map found");
1194 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Partial position map found");
1195 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1196 QString(
"Successfully opened decoder for file: \"%1\". novideo(%2)")
1200 for (
unsigned int i=0; i <
m_ic->nb_chapters; i++)
1202 int num =
m_ic->chapters[i]->time_base.num;
1203 int den =
m_ic->chapters[i]->time_base.den;
1204 int64_t start =
m_ic->chapters[i]->start;
1205 auto total_secs =
static_cast<long double>(start) *
static_cast<long double>(num) /
1206 static_cast<long double>(den);
1208 auto framenum =
static_cast<long long>(total_secs *
static_cast<long double>(
m_fps));
1209 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1210 QString(
"Chapter %1 found @ [%2]->%3")
1213 QString::number(framenum)));
1226 Reset(
true,
true,
true);
1240 double avg_fps = (Stream->avg_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->avg_frame_rate);
1241 double codec_fps = av_q2d(Context->framerate);
1242 double container_fps = (Stream->time_base.num == 0) ? 0.0 : av_q2d(av_inv_q(Stream->time_base));
1244 double estimated_fps = (Stream->r_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->r_frame_rate);
1247 std::vector<double> rates;
1252 if (QString(
m_ic->iformat->name).contains(
"matroska") ||
1253 QString(
m_ic->iformat->name).contains(
"mov"))
1255 rates.emplace_back(avg_fps);
1259 if (QString(
m_ic->iformat->name).contains(
"avi"))
1261 rates.emplace_back(container_fps);
1264 rates.emplace_back(codec_fps);
1265 rates.emplace_back(container_fps);
1266 rates.emplace_back(avg_fps);
1268 rates.emplace_back(estimated_fps);
1270 rates.emplace_back(30000.0 / 1001.0);
1272 auto invalid_fps = [](
double rate) {
return rate < 3.0 || rate > 121.0; };
1273 rates.erase(std::remove_if(rates.begin(), rates.end(), invalid_fps), rates.end());
1275 auto FuzzyEquals = [](
double First,
double Second) {
return std::abs(First - Second) < 0.03; };
1278 if (!FuzzyEquals(rates.front(),
m_fps))
1280 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1281 QString(
"Selected FPS: %1 (Avg:%2 Mult:%3 Codec:%4 Container:%5 Estimated:%6)")
1282 .arg(
static_cast<double>(rates.front())).arg(avg_fps)
1283 .arg(
m_fpsMultiplier).arg(codec_fps).arg(container_fps).arg(estimated_fps));
1286 auto IsStandard = [&FuzzyEquals](
double Rate)
1289 static const std::set<double> k_standard_rates =
1308 if (Rate > 23.0 && Rate < 121.0)
1310 for (
auto standard_rate : k_standard_rates)
1311 if (FuzzyEquals(Rate, standard_rate))
1320 double detected = rates.front();
1321 if (Sanitise && !IsStandard(detected))
1323 for (
auto rate : rates)
1325 if (IsStandard(rate))
1327 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 is non-standard - using %2 instead.")
1328 .arg(rates.front()).arg(rate));
1336 if (rate > 33.0 && detected < 33.0)
1338 double half = rate / 2.0;
1339 if (std::abs(half - detected) < (half * 0.1))
1341 LOG(VB_GENERAL, LOG_INFO,
LOC +
1342 QString(
"Assuming %1 is a better choice than %2")
1343 .arg(half).arg(rate));
1344 return static_cast<float>(half);
1347 return static_cast<float>(rate);
1352 return static_cast<float>(detected);
1357 switch (Context->codec_id)
1359 case AV_CODEC_ID_H264:
1362 if (Context->extradata && (Context->extradata_size >= 7))
1365 if (Context->extradata[0] == 1)
1367 else if (AV_RB24(Context->extradata) == 0x01)
1369 else if (AV_RB32(Context->extradata) == 0x01)
1376 parser.parse_SPS(Context->extradata + offset,
1377 static_cast<uint>(Context->extradata_size - offset), dummy, result);
1382 case AV_CODEC_ID_H265:
return 16;
1383 case AV_CODEC_ID_VP9:
return 8;
1384 case AV_CODEC_ID_VP8:
return 3;
1390 bool selectedStream)
1392 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1393 QString(
"InitVideoCodec ID:%1 Type:%2 Size:%3x%4")
1394 .arg(avcodec_get_name(enc->codec_id),
1396 .arg(enc->width).arg(enc->height));
1401 enc->opaque =
static_cast<void*
>(
this);
1403 enc->slice_flags = 0;
1405 enc->err_recognition = AV_EF_COMPLIANT;
1406 enc->workaround_bugs = FF_BUG_AUTODETECT;
1407 enc->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
1408 enc->idct_algo = FF_IDCT_AUTO;
1412 const AVCodec *codec1 = enc->codec;
1418 const AVPacketSideData *sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1419 stream->codecpar->nb_coded_side_data, AV_PKT_DATA_DISPLAYMATRIX);
1421 m_videoRotation =
static_cast<int>(-av_display_rotation_get(
reinterpret_cast<int32_t*
>(sd->data)));
1426 sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1427 stream->codecpar->nb_coded_side_data, AV_PKT_DATA_STEREO3D);
1430 auto * avstereo =
reinterpret_cast<AVStereo3D*
>(sd->data);
1455 bool doublerate =
true;
1459 if (codec1 && ((AV_CODEC_ID_MPEG2VIDEO == codec1->id) ||
1460 (AV_CODEC_ID_MPEG1VIDEO == codec1->id)))
1464 int total_blocks = (enc->height + 15) / 16;
1465 enc->skip_top = (total_blocks + 3) / 4;
1466 enc->skip_bottom = (total_blocks + 3) / 4;
1474 enc->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
1475 enc->skip_loop_filter = AVDISCARD_ALL;
1479 enc->skip_idct = AVDISCARD_ALL;
1491 if (!width || !height)
1493 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1494 "InitVideoCodec invalid dimensions, resetting decoder.");
1502 const AVCodec *codec2 = enc->codec;
1505 codecName = codec2->name;
1513 switch (enc->codec_id)
1515 case AV_CODEC_ID_H263:
1516 case AV_CODEC_ID_MPEG4:
1517 case AV_CODEC_ID_MSMPEG4V1:
1518 case AV_CODEC_ID_MSMPEG4V2:
1519 case AV_CODEC_ID_MSMPEG4V3:
1520 case AV_CODEC_ID_H263P:
1521 case AV_CODEC_ID_H263I:
1524 case AV_CODEC_ID_WMV1:
1525 case AV_CODEC_ID_WMV2:
1529 case AV_CODEC_ID_XVID:
1538 lcd->setVideoFormatLEDs(video_format,
true);
1550 static constexpr std::array<uint8_t, 256> odd_parity_LUT
1552 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1553 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
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 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1557 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1558 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1559 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1560 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1561 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
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 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1565 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1566 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1567 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1569 bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
1570 (odd_parity_LUT[(data & 0xff00) >> 8] == 1);
1573 LOG(VB_VBI, LOG_ERR,
LOC +
1574 QString(
"VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
1581 if (program ==
nullptr)
1585 return program->pmt_section;
1590 AVProgram* program = av_find_program_from_stream(context,
nullptr, stream_index);
1604 if (!pmt_buffer.has_buffer())
1606 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1607 "ScanATSCCaptionStreams() called with no PMT");
1612 bool video_found =
false;
1636 desc_list.insert(desc_list.end(), desc_list2.begin(), desc_list2.end());
1638 for (
auto & desc : desc_list)
1680 std::array<std::map<int,uint>,2> lang_cc_cnt;
1697 else if (!pofr && sofr)
1723 LOG(VB_GENERAL, LOG_ERR,
LOC +
"in_tracks key too small");
1729 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1730 QString(
"%1 caption service #%2 is in the %3 language.")
1731 .arg((
type) ?
"EIA-708" :
"EIA-608")
1745 AVStream* st =
m_ic->streams[av_index];
1746 const AVDictionaryEntry* language_dictionary_entry =
1747 av_dict_get(st->metadata,
"language",
nullptr, 0);
1749 if (language_dictionary_entry ==
nullptr ||
1750 language_dictionary_entry->value ==
nullptr ||
1751 st->codecpar->extradata ==
nullptr
1757 std::vector<std::string_view> languages {
StringUtil::split_sv(language_dictionary_entry->value,
","sv)};
1759 if (st->codecpar->extradata_size !=
static_cast<int>(languages.size() * 2))
1763 for (
size_t i = 0; i < languages.size(); i++)
1765 if (languages[i].size() != 3)
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)
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",
1788 QString::number(teletext_magazine_number),
1789 QString::number(teletext_page_number)));
1798 AVDictionaryEntry *metatag =
1799 av_dict_get(
m_ic->streams[av_stream_index]->metadata,
"language",
nullptr,
1801 bool forced = (
m_ic->streams[av_stream_index]->disposition & AV_DISPOSITION_FORCED) != 0;
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.")
1809 StreamInfo si {av_stream_index, 0, lang, 0, forced};
1819 if (
m_itv ==
nullptr)
1821 if (
m_itv ==
nullptr)
1825 if (!pmt_buffer.has_buffer())
1836 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams Found Object Carousel in Stream %1").arg(QString::number(i)));
1842 for (
const auto *desc : desc_list)
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)
1852 while (desc != endDesc)
1854 [[maybe_unused]]
uint appTypeCode = desc[0]<<8 | desc[1];
1856 uint appSpecDataLen = *desc++;
1858 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams AppTypeCode %1").arg(QString::number(appTypeCode)));
1859 if (appTypeCode == 0x101)
1861 const unsigned char *subDescEnd = desc + appSpecDataLen;
1862 while (desc < subDescEnd)
1864 uint sub_desc_tag = *desc++;
1865 uint sub_desc_len = *desc++;
1867 if (sub_desc_tag == 1)
1869 desc += sub_desc_len;
1873 #endif // USING_MHEG
1875 desc += appSpecDataLen;
1884 const AVCodec *codec =
nullptr;
1885 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Trying to select best video track");
1899 int stream_index = av_find_best_stream(
m_ic, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
1901 if (stream_index < 0)
1903 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No video track found/selected.");
1904 return stream_index;
1907 AVStream *stream =
m_ic->streams[stream_index];
1917 if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
1918 codectype += QString(
"(%1x%2)").arg(enc->width).arg(enc->height);
1919 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1920 QString(
"Selected track #%1: ID: 0x%2 Codec ID: %3 Profile: %4 Type: %5 Bitrate: %6")
1921 .arg(stream_index).arg(
static_cast<uint64_t
>(stream->id), 0, 16)
1922 .arg(avcodec_get_name(enc->codec_id),
1923 avcodec_profile_name(enc->codec_id, enc->profile),
1925 QString::number(enc->bit_rate)));
1932 if ((enc->width != stream->codecpar->width) || (enc->height != stream->codecpar->height))
1934 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
1935 "Video resolution mismatch: Context: %1x%2 Stream: %3x%4 Codec: %5 Stream change: %6")
1936 .arg(enc->width).arg(enc->height)
1937 .arg(stream->codecpar->width).arg(stream->codecpar->height)
1944 int width = std::max(dim.width(), 16);
1945 int height = std::max(dim.height(), 16);
1946 QString dec =
"ffmpeg";
1947 uint thread_count = 1;
1950 codecName = enc->codec->name;
1955 if (enc->framerate.den && enc->framerate.num)
1956 m_fps = float(enc->framerate.num) / float(enc->framerate.den);
1960 bool foundgpudecoder =
false;
1961 QStringList unavailabledecoders;
1971 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
1972 "GPU/hardware decoder '%1' failed - forcing software decode")
1979 while (unavailabledecoders.size() < 10)
1983 if (!unavailabledecoders.isEmpty())
1985 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Unavailable decoders: %1")
1986 .arg(unavailabledecoders.join(
",")));
1992 if (!skip_loop_filter)
1993 enc->skip_loop_filter = AVDISCARD_NONKEY;
2001 if (
version && allowgpu && dec !=
"ffmpeg")
2005 enc->opaque =
static_cast<void*
>(
this);
2010 enc->opaque =
static_cast<void*
>(
this);
2012 foundgpudecoder =
true;
2017 unavailabledecoders.append(dec);
2025 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown video codec - defaulting to MPEG2");
2042 if (!foundgpudecoder)
2044 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 CPUs for decoding")
2045 .arg(HAVE_THREADS ? thread_count : 1));
2046 enc->thread_count =
static_cast<int>(thread_count);
2061 return stream_index;
2066 AVProgram* program = av_find_program_from_stream(
m_ic,
nullptr, stream_index);
2067 if (program ==
nullptr)
2072 LOG(VB_PLAYBACK, LOG_INFO,
2073 QString(
"Removing streams not in Program %1 from track selection.")
2074 .arg(QString::number(program->id)));
2076 const auto *
const begin = program->stream_index;
2077 const auto *
const end = program->stream_index + program->nb_stream_indexes;
2081 LOG(VB_PLAYBACK, LOG_DEBUG,
2082 QString(
"Size before: %1").arg(QString::number(track_list.size())));
2083 track_list.erase(std::remove_if(track_list.begin(), track_list.end(),
2086 return std::find(begin, end, i.m_av_stream_index) == end;
2087 }), track_list.end());
2088 LOG(VB_PLAYBACK, LOG_DEBUG,
2089 QString(
"Size after: %1").arg(QString::number(track_list.size())));
2095 return (ch_layout.order == AV_CHANNEL_ORDER_CUSTOM) &&
2096 (ch_layout.nb_channels == 2) &&
2097 (ch_layout.u.map[0].id == AV_CHAN_FRONT_CENTER) &&
2098 (ch_layout.u.map[1].id == AV_CHAN_FRONT_CENTER);
2106 bool unknownbitrate =
false;
2123 std::map<int,uint> lang_sub_cnt;
2124 uint subtitleStreamCount = 0;
2125 std::map<int,uint> lang_aud_cnt;
2126 uint audioStreamCount = 0;
2135 if (
m_ic ==
nullptr)
2138 for (
uint strm = 0; strm <
m_ic->nb_streams; strm++)
2140 AVCodecParameters *par =
m_ic->streams[strm]->codecpar;
2141 AVCodecContext *enc =
nullptr;
2144 if (par->codec_type == AVMEDIA_TYPE_VIDEO)
2145 codectype += QString(
"(%1x%2)").arg(par->width).arg(par->height);
2146 QString program_id =
"null";
2147 if (av_find_program_from_stream(
m_ic,
nullptr, strm) !=
nullptr)
2149 program_id = QString::number(av_find_program_from_stream(
m_ic,
nullptr, strm)->
id);
2151 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2152 QString(
"Stream #%1: ID: 0x%2 Program ID: %3 Codec ID: %4 Type: %5 Bitrate: %6").arg(
2153 QString::number(strm),
2154 QString::number(
static_cast<uint64_t
>(
m_ic->streams[strm]->id), 16),
2156 avcodec_get_name(par->codec_id),
2158 QString::number(par->bit_rate))
2161 switch (par->codec_type)
2163 case AVMEDIA_TYPE_VIDEO:
2171 if (ctx && (ctx->hw_frames_ctx || ctx->hw_device_ctx))
2178 LOG(VB_GENERAL, LOG_ERR,
LOC +
2179 QString(
"Stream #%1 has an unknown video "
2180 "codec id, skipping.").arg(strm));
2192 if (par->bit_rate == 0)
2194 static constexpr int64_t s_baseBitrate { 1000000LL };
2196 if (par->width && par->height)
2198 static const int s_baseSize = 1920 * 1080;
2199 multiplier = ((par->width * par->height) + s_baseSize - 1) / s_baseSize;
2200 multiplier = std::max(multiplier, 1);
2202 par->bit_rate = s_baseBitrate * multiplier;
2203 unknownbitrate =
true;
2209 case AVMEDIA_TYPE_AUDIO:
2212 if (enc && enc->internal)
2214 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2215 QString(
"Warning, audio codec 0x%1 id(%2) "
2216 "type (%3) already open, leaving it alone.")
2217 .arg(
reinterpret_cast<unsigned long long>(enc), 0, 16)
2218 .arg(avcodec_get_name(enc->codec_id),
2221 LOG(VB_GENERAL, LOG_INFO,
LOC +
2222 QString(
"codec %1 has %2 channels")
2223 .arg(avcodec_get_name(par->codec_id))
2224 .arg(par->ch_layout.nb_channels));
2229 case AVMEDIA_TYPE_SUBTITLE:
2231 if (par->codec_id == AV_CODEC_ID_DVB_TELETEXT)
2233 if (par->codec_id == AV_CODEC_ID_TEXT)
2237 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"subtitle codec (%1)")
2241 case AVMEDIA_TYPE_DATA:
2243 if (par->codec_id == AV_CODEC_ID_DVB_VBI)
2246 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"data codec (%1)")
2250 case AVMEDIA_TYPE_ATTACHMENT:
2252 if (par->codec_id == AV_CODEC_ID_TTF)
2255 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2256 QString(
"Attachment codec (%1)")
2263 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
2264 QString(
"Unknown codec type (%1)")
2270 if (par->codec_type != AVMEDIA_TYPE_AUDIO &&
2271 par->codec_type != AVMEDIA_TYPE_SUBTITLE)
2275 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2276 (par->codec_id == AV_CODEC_ID_DVB_TELETEXT ||
2277 par->codec_id == AV_CODEC_ID_TEXT))
2280 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Looking for decoder for %1")
2281 .arg(avcodec_get_name(par->codec_id)));
2283 if (par->codec_id == AV_CODEC_ID_PROBE)
2285 LOG(VB_GENERAL, LOG_ERR,
LOC +
2286 QString(
"Probing of stream #%1 unsuccesful, ignoring.").arg(strm));
2293 const AVCodec *codec =
nullptr;
2298 LOG(VB_GENERAL, LOG_ERR,
LOC +
2299 QString(
"Could not find decoder for codec (%1), ignoring.")
2300 .arg(avcodec_get_name(par->codec_id)));
2307 void *opaque =
nullptr;
2308 const AVCodec *
p = av_codec_iterate(&opaque);
2313 if (
p->name[0] !=
'\0')
2314 msg = QString(
"Codec %1:").arg(
p->name);
2316 msg = QString(
"Codec %1, null name,").arg(strm);
2318 LOG(VB_LIBAV, LOG_INFO,
LOC + msg);
2320 if (
p->id == par->codec_id)
2326 LOG(VB_LIBAV, LOG_INFO,
LOC +
2327 QString(
"Codec 0x%1 != 0x%2") .arg(
p->id, 0, 16)
2328 .arg(par->codec_id, 0, 16));
2329 p = av_codec_iterate(&opaque);
2340 if (enc->codec && par->codec_id != enc->codec_id)
2342 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2343 QString(
"Already opened codec not matching (%1 vs %2). Reopening")
2344 .arg(avcodec_get_name(enc->codec_id),
2345 avcodec_get_name(enc->codec->id)));
2361 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2362 QString(
"Stream 0x%1 is not valid in this context - skipping")
2363 .arg(
m_ic->streams[strm]->id, 4, 16));
2367 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2369 bool forced = (
m_ic->streams[strm]->disposition & AV_DISPOSITION_FORCED) != 0;
2371 uint lang_indx = lang_sub_cnt[lang]++;
2372 subtitleStreamCount++;
2375 static_cast<int>(strm),
m_ic->streams[strm]->id, lang, lang_indx, forced);
2377 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2378 QString(
"Subtitle track #%1 is A/V stream #%2 "
2379 "and is in the %3 language(%4).")
2384 if (par->codec_type == AVMEDIA_TYPE_AUDIO)
2388 uint lang_indx = lang_aud_cnt[lang]++;
2391 int stream_id =
m_ic->streams[strm]->id;
2395 if (stream_id == -1)
2403 static_cast<int>(strm), stream_id, lang, lang_indx,
type);
2407 lang_indx = lang_aud_cnt[lang]++;
2409 static_cast<int>(strm), stream_id, lang, lang_indx,
type);
2412 LOG(VB_AUDIO, LOG_INFO,
LOC +
2413 QString(
"Audio Track #%1, of type (%2) is A/V stream #%3 (id=0x%4) "
2414 "and has %5 channels in the %6 language(%7).")
2416 .arg(strm).arg(
m_ic->streams[strm]->id,0,16).arg(enc->ch_layout.nb_channels)
2442 QString(
m_ic->iformat->name).contains(
"matroska"));
2482 for (
unsigned i = 0; i <
m_ic->nb_programs; i++)
2494 #ifdef USING_MEDIACODEC
2495 if (QString(
"mediacodec") == codec->wrapper_name)
2496 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(),
nullptr);
2498 int ret = avcodec_open2(avctx, codec,
nullptr);
2503 LOG(VB_GENERAL, LOG_ERR,
LOC +
2504 QString(
"Could not open codec 0x%1, id(%2) type(%3) "
2505 "ignoring. reason %4").arg((uint64_t)avctx,0,16)
2506 .arg(avcodec_get_name(avctx->codec_id),
2512 LOG(VB_GENERAL, LOG_INFO,
LOC +
2513 QString(
"Opened codec 0x%1, id(%2) type(%3)")
2514 .arg((uint64_t)avctx,0,16)
2515 .arg(avcodec_get_name(avctx->codec_id),
2540 if (si.m_language_index == Index)
2541 return si.m_language;
2548 AVDictionaryEntry *metatag = av_dict_get(
m_ic->streams[StreamIndex]->metadata,
"language",
nullptr, 0);
2591 AVStream *stream =
m_ic->streams[StreamIndex];
2595 if (stream->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
2597 else if (stream->disposition & AV_DISPOSITION_COMMENT)
2599 else if (stream->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
2601 else if (stream->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
2628 if (
current->m_av_stream_index == streamIndex)
2634 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2635 QString(
"Invalid stream index passed to "
2636 "SetupAudioStreamSubIndexes: %1").arg(streamIndex));
2643 if (
current->m_av_substream_index == -1)
2656 (next->m_av_stream_index != streamIndex))
2658 QString msg = QString(
2659 "Expected substream 1 (Language I) of stream %1\n\t\t\t"
2660 "following substream 0, found end of list or another stream.")
2663 LOG(VB_GENERAL, LOG_WARNING,
LOC + msg);
2685 bool do_flush =
false;
2686 for (
uint i = 0; i <
m_ic->nb_streams; i++)
2688 AVStream *st =
m_ic->streams[i];
2691 if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2694 LOG(VB_LIBAV, LOG_DEBUG, QString(
"removing audio stream (id: 0x%1, index: %2, nb_streams: %3)")
2695 .arg(QString::number(st->id, 16),
2697 QString::number(
m_ic->nb_streams)
2701 if ((
m_ic->nb_streams - i) > 0) {
2702 std::memmove(
reinterpret_cast<void*
>(&
m_ic->streams[i]),
2703 reinterpret_cast<const void*
>(&
m_ic->streams[i + 1]),
2704 (
m_ic->nb_streams - i) *
sizeof(AVFormatContext*));
2708 m_ic->streams[i] =
nullptr;
2716 avformat_flush(
m_ic);
2725 if (!std::any_of(decoder->m_renderFormats->cbegin(), decoder->m_renderFormats->cend(),
2726 [&
type](
auto Format) { return type == Format; }))
2728 decoder->m_directRendering =
false;
2729 return avcodec_default_get_buffer2(c, pic, flags);
2732 decoder->m_directRendering =
true;
2733 MythVideoFrame *frame = decoder->GetPlayer()->GetNextVideoFrame();
2743 if ((frame->
m_type !=
type) || (pic->width > width) || (pic->height > height))
2760 for (
uint i = 0; i < 3; i++)
2766 pic->opaque = frame;
2769 AVBufferRef *buffer = av_buffer_create(
reinterpret_cast<uint8_t*
>(frame), 0,
2770 [](
void* Opaque, uint8_t* Data)
2774 if (avfd && avfd->GetPlayer())
2775 avfd->GetPlayer()->DeLimboFrame(vf);
2778 pic->buf[0] = buffer;
2789 for (
int i = 0; i < 4; i++)
2791 pic->data[i] =
nullptr;
2792 pic->linesize[i] = 0;
2794 pic->opaque = frame;
2796 pic->data[0] = (uint8_t*)frame->
m_buffer;
2797 pic->data[3] = (uint8_t*)frame->
m_buffer;
2800 AVBufferRef *buffer =
2801 av_buffer_create((uint8_t*)frame, 0,
2802 [](
void* Opaque, uint8_t* Data)
2810 pic->buf[0] = buffer;
2821 bool had_608 =
false;
2822 bool had_708 =
false;
2823 for (
uint cur = 0; cur + 2 < buf_size; cur += 3)
2825 uint cc_code = buf[cur];
2826 bool cc_valid = (cc_code & 0x04) != 0U;
2828 uint data1 = buf[cur+1];
2829 uint data2 = buf[cur+2];
2830 uint data = (data2 << 8) | data1;
2831 uint cc_type = cc_code & 0x03;
2858 bool check_608,
bool check_708)
2860 bool need_change_608 =
false;
2865 for (
uint i = 0; i < 4; i++)
2872 bool need_change_708 =
false;
2874 if (check_708 || need_change_608)
2877 for (
uint i = 1; i < 64 && !need_change_608 && !need_change_708; i++)
2882 if (need_change_708 && !check_608)
2886 if (!need_change_608 && !need_change_708)
2897 for (
int i = 1; i < 64; i++)
2906 for (
int i = 0; i < 4; i++)
2927 AVPacket *pkt,
bool can_reliably_parse_keyframes)
2932 bool reset_kfd =
false;
2936 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2937 "gopset not set, syncing positionMap");
2939 if (tempKeyFrameDist > 0 && !
m_livetv)
2941 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2942 QString(
"Initial key frame distance: %1.")
2948 else if (
m_keyframeDist != tempKeyFrameDist && tempKeyFrameDist > 0)
2950 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2951 QString(
"Key frame distance changed from %1 to %2.")
2979 if (can_reliably_parse_keyframes &&
2982 long long last_frame = 0;
2990 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
2991 QString(
"framesRead: %1 last_frame: %2 keyframedist: %3")
2998 long long startpos = pkt->pos;
3000 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3001 QString(
"positionMap[ %1 ] == %2.")
3031 float bytespersec = (float)
m_bitrate / 8;
3049 const uint8_t *bufptr = pkt->data;
3050 const uint8_t *bufend = pkt->data + pkt->size;
3052 while (bufptr < bufend)
3056 float aspect_override = -1.0F;
3065 if (bufptr + 11 >= pkt->data + pkt->size)
3067 const auto *seq =
reinterpret_cast<const SequenceHeader*
>(bufptr);
3069 int width =
static_cast<int>(seq->width()) >> context->lowres;
3070 int height =
static_cast<int>(seq->height()) >> context->lowres;
3071 float aspect = seq->
aspect(context->codec_id == AV_CODEC_ID_MPEG1VIDEO);
3072 if (stream->sample_aspect_ratio.num)
3073 aspect =
static_cast<float>(av_q2d(stream->sample_aspect_ratio) * width / height);
3074 if (aspect_override > 0.0F)
3075 aspect = aspect_override;
3076 float seqFPS = seq->fps();
3080 changed |= (seqFPS >
static_cast<float>(
m_fps)+0.01F) ||
3081 (seqFPS < static_cast<float>(
m_fps)-0.01F);
3085 bool forceaspectchange = !qFuzzyCompare(
m_currentAspect + 10.0F, aspect + 10.0F) &&
3089 if (changed || forceaspectchange)
3094 bool doublerate =
false;
3097 forceaspectchange, 2,
3100 if (context->hw_frames_ctx)
3101 if (context->internal)
3102 avcodec_flush_buffers(context);
3116 if ((seqFPS > avFPS+0.01F) || (seqFPS < avFPS-0.01F))
3118 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"avFPS(%1) != seqFPS(%2)")
3119 .arg(
static_cast<double>(avFPS)).arg(
static_cast<double>(seqFPS)));
3128 pkt->flags |= AV_PKT_FLAG_KEY;
3135 pkt->flags |= AV_PKT_FLAG_KEY;
3144 const uint8_t *buf = pkt->data;
3145 const uint8_t *buf_end = pkt->data + pkt->size;
3150 if (context->extradata && (context->extradata_size >= 7) && (context->extradata[0] == 0x01))
3152 if (pkt->flags & AV_PKT_FLAG_KEY)
3157 while (buf < buf_end)
3188 bool fps_changed = (seqFPS > 0.0) && ((seqFPS >
m_fps + 0.01) ||
3189 (seqFPS <
m_fps - 0.01));
3194 if (fps_changed || res_changed || forcechange)
3199 bool doublerate =
false;
3212 if (context->hw_frames_ctx && (forcechange || res_changed))
3213 if (context->internal)
3214 avcodec_flush_buffers(context);
3220 m_fps =
static_cast<float>(seqFPS);
3230 if ((seqFPS > avFPS + 0.01) || (seqFPS < avFPS - 0.01))
3232 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
3233 QString(
"avFPS(%1) != seqFPS(%2)").arg(avFPS).arg(seqFPS));
3238 pkt->flags |= AV_PKT_FLAG_KEY;
3259 if (pkt->flags & AV_PKT_FLAG_KEY)
3275 !(pkt->flags & AV_PKT_FLAG_KEY))
3277 av_packet_unref(pkt);
3312 bool sentPacket =
false;
3332 if (ret == AVERROR(EAGAIN))
3336 if (ret==0 && !gotpicture)
3338 ret2 = avcodec_send_packet(context, pkt);
3339 if (ret2 == AVERROR(EAGAIN))
3351 if (ret < 0 || ret2 < 0)
3356 LOG(VB_GENERAL, LOG_ERR,
LOC +
3357 QString(
"video avcodec_receive_frame error: %1 (%2) gotpicture:%3")
3359 .arg(ret).arg(gotpicture));
3364 LOG(VB_GENERAL, LOG_ERR,
LOC +
3365 QString(
"video avcodec_send_packet error: %1 (%2) gotpicture:%3")
3367 .arg(ret2).arg(gotpicture));
3381 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Decoder needs reset");
3385 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
3387 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"FFmpeg external library error - assuming streams changed");
3399 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3400 QString(
"video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4")
3401 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts)
3402 .arg(mpa_pic->pkt_dts));
3411 auto *newPkt = av_packet_clone(pkt);
3424 auto * side_data = av_frame_get_side_data(AvFrame, AV_FRAME_DATA_A53_CC);
3425 if (side_data && (side_data->size > 0))
3438 frame->m_directRendering =
false;
3449 av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
3450 frame->m_buffer, AV_PIX_FMT_YUV420P, AvFrame->width,
3451 AvFrame->height, IMAGE_ALIGN);
3452 tmppicture.data[0] = frame->m_buffer + frame->m_offsets[0];
3453 tmppicture.data[1] = frame->m_buffer + frame->m_offsets[1];
3454 tmppicture.data[2] = frame->m_buffer + frame->m_offsets[2];
3455 tmppicture.linesize[0] = frame->m_pitches[0];
3456 tmppicture.linesize[1] = frame->m_pitches[1];
3457 tmppicture.linesize[2] = frame->m_pitches[2];
3461 AvFrame->height,
static_cast<AVPixelFormat
>(AvFrame->format),
3462 AvFrame->width, AvFrame->height,
3463 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
3464 nullptr,
nullptr,
nullptr);
3467 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate sws context");
3470 sws_scale(
m_swsCtx, AvFrame->data, AvFrame->linesize, 0, dim.height(),
3471 tmppicture.data, tmppicture.linesize);
3479 oldframe->
m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3480 oldframe->
m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3506 LOG(VB_GENERAL, LOG_ERR,
LOC +
"NULL videoframe - direct rendering not "
3507 "correctly initialized.");
3512 if (AvFrame->best_effort_timestamp == AV_NOPTS_VALUE)
3514 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process video.");
3518 AvFrame->best_effort_timestamp * 1000);
3519 std::chrono::milliseconds temppts =
pts;
3536 double calcfps = 1000.0 /
ptsdiff.count();
3537 if (calcfps < 121.0 && calcfps > 3.0)
3541 double fpschange = calcfps /
m_fps;
3543 if (fpschange > 1.9 && fpschange < 2.1)
3545 if (fpschange > 0.9 && fpschange < 1.1)
3551 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3552 QString(
"video timecode %1 %2 %3 %4%5")
3553 .arg(AvFrame->best_effort_timestamp)
3554 .arg(
pts.count()).arg(temppts.count()).arg(
m_lastVPts.count())
3555 .arg((
pts != temppts) ?
" fixup" :
""));
3557 frame->m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3558 frame->m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3560 frame->m_repeatPic = AvFrame->repeat_pict != 0;
3565 frame->m_colorspace = AvFrame->colorspace;
3566 frame->m_colorrange = AvFrame->color_range;
3567 frame->m_colorprimaries = AvFrame->color_primaries;
3568 frame->m_colortransfer = AvFrame->color_trc;
3569 frame->m_chromalocation = AvFrame->chroma_location;
3570 frame->m_pixFmt = AvFrame->format;
3575 frame->m_dummy =
false;
3576 frame->m_pauseFrame =
false;
3577 frame->m_deinterlaceInuse2x =
false;
3578 frame->m_alreadyDeinterlaced =
false;
3579 frame->m_interlacedReverse =
false;
3609 [[maybe_unused]]
const AVStream *stream,
const AVPacket *pkt)
3611 const uint8_t *buf = pkt->data;
3612 uint64_t linemask = 0;
3617 if ((buf[0]==
't') && (buf[1]==
'v') && (buf[2] ==
'0'))
3620 memcpy(&linemask, buf + 3, 8);
3623 else if ((buf[0]==
'T') && (buf[1]==
'V') && (buf[2] ==
'0'))
3625 linemask = 0xffffffffffffffffLL;
3630 LOG(VB_VBI, LOG_ERR,
LOC + QString(
"Unknown VBI data stream '%1%2%3'")
3631 .arg(QChar(buf[0])).arg(QChar(buf[1])).arg(QChar(buf[2])));
3635 static constexpr
uint kMinBlank = 6;
3636 for (
uint i = 0; i < 36; i++)
3638 if (!((linemask >> i) & 0
x1))
3641 const uint line = ((i < 18) ? i : i-18) + kMinBlank;
3642 const uint field = (i<18) ? 0 : 1;
3643 const uint id2 = *buf & 0xf;
3666 int data = (buf[2] << 8) | buf[1];
3693 const AVStream* ,
const AVPacket *pkt)
3702 const uint8_t *buf = pkt->data;
3703 const uint8_t *buf_end = pkt->data + pkt->size;
3705 if (*buf >= 0x10 && *buf <= 0x1F)
3711 LOG(VB_VBI, LOG_WARNING,
LOC +
3712 QString(
"VBI: Unknown data_identier: %1 discarded").arg(*buf));
3717 while (buf < buf_end)
3722 if ((buf_end - buf) >= 42)
3726 else if (*buf == 0x03)
3729 if ((buf_end - buf) >= 42)
3733 else if (*buf == 0xff)
3739 LOG(VB_VBI, LOG_WARNING,
LOC +
3740 QString(
"VBI: Unsupported data_unit_id: %1 discarded").arg(*buf));
3750 [[maybe_unused]]
const AVPacket *pkt)
3753 if (
m_itv ==
nullptr)
3755 if (
m_itv ==
nullptr)
3759 uint8_t *data = pkt->data;
3760 int length = pkt->size;
3761 int componentTag = 0;
3762 int dataBroadcastId = 0;
3763 unsigned carouselId = 0;
3766 componentTag = str->component_tag;
3767 dataBroadcastId = str->data_id;
3768 carouselId = (unsigned) str->carousel_id;
3773 uint16_t sectionLen = (((data[1] & 0xF) << 8) | data[2]) + 3;
3775 if (sectionLen > length)
3779 componentTag, carouselId,
3781 length -= sectionLen;
3784 #endif // USING_MHEG
3792 long long pts = pkt->pts;
3793 if (
pts == AV_NOPTS_VALUE)
3795 if (
pts == AV_NOPTS_VALUE)
3797 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process subtitle.");
3800 pts =
static_cast<long long>(av_q2d(curstream->time_base) *
pts * 1000);
3806 bool isForcedTrack =
false;
3809 int gotSubtitles = 0;
3810 AVSubtitle subtitle;
3811 memset(&subtitle, 0,
sizeof(AVSubtitle));
3818 curstream->id,
pts);
3822 if (pkt->stream_index == subIdx)
3826 pkt->data, pkt->size,
pts);
3832 || pkt->stream_index == forcedSubIdx)
3836 avcodec_decode_subtitle2(ctx, &subtitle, &gotSubtitles, pkt);
3839 subtitle.start_display_time +=
pts;
3840 subtitle.end_display_time +=
pts;
3842 if (pkt->stream_index != subIdx)
3843 isForcedTrack =
true;
3850 for (
unsigned i = 0; i < subtitle.num_rects; i++)
3852 subtitle.rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
3855 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3856 QString(
"subtl timecode %1 %2 %3 %4")
3857 .arg(pkt->pts).arg(pkt->dts)
3858 .arg(subtitle.start_display_time)
3859 .arg(subtitle.end_display_time));
3862 subtitle, curstream->codecpar->codec_id == AV_CODEC_ID_XSUB,
3876 auto id =
static_cast<uint>(Packet->stream_index + 0x2000);
3880 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3881 const auto * codec = QTextCodec::codecForName(
"utf-8");
3882 auto text = codec->toUnicode(
reinterpret_cast<const char *
>(Packet->data), Packet->size - 1);
3884 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
3885 QString text = toUtf16.decode(Packet->data);
3887 auto list = text.split(
'\n', Qt::SkipEmptyParts);
3895 enum AVCodecID codec_id = curstream->codecpar->codec_id;
3899 case AV_CODEC_ID_MPEG2VBI:
3902 case AV_CODEC_ID_DVB_VBI:
3905 case AV_CODEC_ID_DSMCC_B:
3914 #endif // USING_MHEG:
3930 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio stream type " + msg +
"changed.");
3944 QString forcedString = forced ? QObject::tr(
" (forced)") :
"";
3946 int av_index =
m_tracks[
type][TrackNo].m_av_stream_index;
3947 AVStream *stream {
nullptr };
3948 if (av_index >= 0 && av_index < (
int)
m_ic->nb_streams)
3949 stream =
m_ic->streams[av_index];
3950 AVDictionaryEntry *entry =
3951 stream ? av_dict_get(stream->metadata,
"title",
nullptr, 0) :
nullptr;
3952 QString user_title = entry ? QString(R
"( "%1")").arg(entry->value) : "";
3964 AVCodecParameters *par = stream->codecpar;
3966 if (par->codec_id == AV_CODEC_ID_MP3)
3967 msg += QString(
" MP3");
3968 else if (ctx && ctx->codec)
3969 msg += QString(
" %1").arg(ctx->codec->name).toUpper();
3970 if (!user_title.isEmpty())
3973 int channels = par->ch_layout.nb_channels;
3976 msg += QString(
" ?ch");
3977 else if((channels > 4) && !(channels & 1))
3978 msg += QString(
" %1.1ch").arg(channels - 1);
3980 msg += QString(
" %1ch").arg(channels);
3990 if (!user_title.isEmpty())
3993 msg += QString(
" (%1)")
3997 return QString(
"%1: %2").arg(TrackNo + 1).arg(msg);
4001 return QObject::tr(
"Subtitle") + QString(
" %1: %2%3%4")
4002 .arg(QString::number(TrackNo + 1),
4030 return ctx ? QByteArray(
reinterpret_cast<char*
>(ctx->subtitle_header), ctx->subtitle_header_size) :
4041 AVDictionaryEntry *tag = av_dict_get(
m_ic->streams[index]->metadata,
"filename",
nullptr, 0);
4043 Filename = QByteArray(tag->value);
4044 AVCodecParameters *par =
m_ic->streams[index]->codecpar;
4045 Data = QByteArray(
reinterpret_cast<char*
>(par->extradata), par->extradata_size);
4055 if ((stream->component_tag == Tag) || ((Tag <= 0) && stream->component_tag <= 0))
4064 for (
uint i = 0; i <
m_ic->nb_streams; i++)
4066 AVStream *stream =
m_ic->streams[i];
4069 if (stream->component_tag == Tag)
4093 const std::vector<int> &ftype)
4095 std::vector<int> ret;
4097 for (
int index : ftype)
4099 if ((lang_key < 0) || tracks[index].m_language == lang_key)
4100 ret.push_back(index);
4108 std::vector<int> ret;
4110 for (
size_t i = 0; i < tracks.size(); i++)
4112 if (tracks[i].m_audio_type ==
type)
4121 const std::vector<int>&fs,
4122 enum AVCodecID codecId,
4125 int selectedTrack = -1;
4130 const int stream_index = tracks[f].m_av_stream_index;
4131 AVCodecParameters *par = ic->streams[stream_index]->codecpar;
4132 if ((codecId == AV_CODEC_ID_NONE || codecId == par->codec_id) &&
4133 (max_seen < par->ch_layout.nb_channels))
4135 if (codecId == AV_CODEC_ID_DTS &&
profile > 0)
4142 max_seen = par->ch_layout.nb_channels;
4146 return selectedTrack;
4204 uint numStreams = atracks.size();
4205 if ((ctrack >= 0) && (ctrack < (
int)numStreams))
4208 LOG(VB_AUDIO, LOG_DEBUG, QString(
"%1 available audio streams").arg(numStreams));
4209 for (
const auto & track : atracks)
4211 AVCodecParameters *codecpar =
m_ic->streams[track.m_av_stream_index]->codecpar;
4212 LOG(VB_AUDIO, LOG_DEBUG, QString(
"%1: %2 bps, %3 Hz, %4 channels, passthrough(%5)")
4213 .arg(avcodec_get_name(codecpar->codec_id), QString::number(codecpar->bit_rate),
4214 QString::number(codecpar->sample_rate), QString::number(codecpar->ch_layout.nb_channels),
4219 int selTrack = (1 == numStreams) ? 0 : -1;
4224 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio sub-stream");
4230 for (
uint i = 0; i < numStreams; i++)
4232 if (atracks[i].m_av_substream_index == substream_index)
4240 if ((selTrack < 0) && wlang >= -1 && numStreams)
4242 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio track");
4247 for (
uint i = 0; i < numStreams; i++)
4249 if (wlang == atracks[i].m_language)
4253 if (windx == atracks[i].m_language_index)
4259 if (selTrack < 0 && numStreams)
4261 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select audio track (w/lang)");
4268 LOG(VB_AUDIO, LOG_WARNING,
"No audio tracks matched the type filter, "
4269 "so trying all tracks.");
4270 for (
int i = 0; i < static_cast<int>(atracks.size()); i++)
4279 std::vector<int> flang =
filter_lang(atracks, canonical_key, ftype);
4283 FF_PROFILE_DTS_HD_MA);
4287 if (selTrack < 0 && m_audio->CanDTSHD())
4289 FF_PROFILE_DTS_HD_HRA);
4313 FF_PROFILE_DTS_HD_MA);
4316 AV_CODEC_ID_TRUEHD);
4318 if (selTrack < 0 && m_audio->CanDTSHD())
4320 FF_PROFILE_DTS_HD_HRA);
4341 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select default track");
4342 for (
size_t i = 0; i < atracks.size(); i++) {
4343 int idx = atracks[i].m_av_stream_index;
4344 if (
m_ic->streams[idx]->disposition & AV_DISPOSITION_DEFAULT)
4355 LOG(VB_AUDIO, LOG_INFO,
LOC +
4356 "Trying to select audio track (wo/lang)");
4361 FF_PROFILE_DTS_HD_MA);
4365 if (selTrack < 0 && m_audio->CanDTSHD())
4367 FF_PROFILE_DTS_HD_HRA);
4386 if (ctrack != selTrack)
4388 LOG(VB_AUDIO, LOG_INFO,
LOC +
"No suitable audio track exists.");
4395 strack = atracks[selTrack];
4400 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Selected track %1 (A/V Stream #%2)")
4409 char *buffer,
int bufsize)
4420 const uint halfsample = samplesize >> 1;
4422 const char *from = (channel == 1) ? buffer + halfsample : buffer;
4423 char *to = (channel == 0) ? buffer + halfsample : buffer;
4426 (sample++), (from += samplesize), (to += samplesize))
4428 memmove(to, from, halfsample);
4438 bool firstloop =
true;
4439 int decoded_size = -1;
4446 AVPacket *tmp_pkt = av_packet_alloc();
4447 tmp_pkt->data = pkt->data;
4448 tmp_pkt->size = pkt->size;
4449 while (tmp_pkt->size > 0)
4451 bool reselectAudioTrack =
false;
4456 LOG(VB_AUDIO, LOG_INFO,
LOC +
4457 "Audio is disabled - trying to restart it");
4458 reselectAudioTrack =
true;
4463 bool wasDual = audSubIdx != -1;
4465 if ((wasDual && !isDual) || (!wasDual && isDual))
4468 reselectAudioTrack =
true;
4473 bool already_decoded =
false;
4474 if (!ctx->ch_layout.nb_channels)
4486 AVChannelLayout channel_layout;
4488 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4490 if (ctx->codec_id == AV_CODEC_ID_AC3)
4495 decoded_size = data_size;
4496 already_decoded =
true;
4497 reselectAudioTrack |= ctx->ch_layout.nb_channels;
4501 if (reselectAudioTrack)
4511 if (!(decodetype &
kDecodeAudio) || (pkt->stream_index != audIdx)
4515 if (firstloop && pkt->pts != AV_NOPTS_VALUE)
4528 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Audio stream changed");
4531 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Number of audio channels changed from %1 to %2")
4543 if (!already_decoded)
4548 decoded_size = data_size;
4556 data_size = tmp_pkt->size;
4562 if (!already_decoded)
4566 AVChannelLayout channel_layout;
4568 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4572 decoded_size = data_size;
4579 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown audio decoding error");
4580 av_packet_free(&tmp_pkt);
4586 tmp_pkt->data += ret;
4587 tmp_pkt->size -= ret;
4591 std::chrono::milliseconds temppts =
m_lastAPts;
4598 int frames = (ctx->ch_layout.nb_channels <= 0 || decoded_size < 0 || !samplesize) ? -1 :
4599 decoded_size / (ctx->ch_layout.nb_channels * samplesize);
4608 ((
double)(frames * 1000) / ctx->sample_rate);
4611 LOG(VB_TIMESTAMP, LOG_INFO,
LOC + QString(
"audio timecode %1 %2 %3 %4")
4612 .arg(pkt->pts).arg(pkt->dts).arg(temppts.count()).arg(
m_lastAPts.count()));
4617 tmp_pkt->data += ret;
4618 tmp_pkt->size -= ret;
4622 av_packet_free(&tmp_pkt);
4629 AVPacket *pkt =
nullptr;
4630 bool have_err =
false;
4632 const DecodeType origDecodetype = decodetype;
4640 bool storevideoframes =
false;
4709 storevideoframes =
true;
4715 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4716 QString(
"Audio %1 ms behind video but already %2 "
4717 "video frames queued. AV-Sync might be broken.")
4728 av_packet_free(&pkt);
4734 pkt = av_packet_alloc();
4737 if (
m_ic !=
nullptr)
4739 if ((
m_ic ==
nullptr) || (retval < 0))
4741 if (retval == -EAGAIN)
4745 av_packet_free(&pkt);
4747 LOG(VB_GENERAL, LOG_ERR, QString(
"decoding error %1 (%2)")
4749 QString::number(retval)));
4762 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No context");
4763 av_packet_unref(pkt);
4767 if (pkt->stream_index >= (
int)
m_ic->nb_streams)
4769 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream");
4770 av_packet_unref(pkt);
4774 AVStream *curstream =
m_ic->streams[pkt->stream_index];
4778 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream (NULL)");
4779 av_packet_unref(pkt);
4783 enum AVMediaType codec_type = curstream->codecpar->codec_type;
4785 if (storevideoframes && codec_type == AVMEDIA_TYPE_VIDEO)
4793 if (codec_type == AVMEDIA_TYPE_VIDEO &&
4803 av_packet_free(&pkt);
4808 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4809 curstream->codecpar->codec_id == AV_CODEC_ID_TEXT)
4812 av_packet_unref(pkt);
4816 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4817 curstream->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT)
4820 av_packet_unref(pkt);
4824 if (codec_type == AVMEDIA_TYPE_DATA)
4827 av_packet_unref(pkt);
4834 if (codec_type != AVMEDIA_TYPE_VIDEO)
4836 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
4837 QString(
"No codec for stream index %1, type(%2) id(%3:%4)")
4838 .arg(pkt->stream_index)
4840 avcodec_get_name(curstream->codecpar->codec_id))
4841 .arg(curstream->codecpar->codec_id));
4846 av_packet_unref(pkt);
4854 case AVMEDIA_TYPE_AUDIO:
4863 case AVMEDIA_TYPE_VIDEO:
4870 if (pkt->pts != AV_NOPTS_VALUE)
4873 (av_q2d(curstream->time_base)*pkt->pts*1000000);
4888 case AVMEDIA_TYPE_SUBTITLE:
4897 LOG(VB_GENERAL, LOG_ERR,
LOC +
4898 QString(
"Decoding - id(%1) type(%2)")
4899 .arg(avcodec_get_name(ctx->codec_id),
4906 if (!have_err && !Retry)
4908 av_packet_unref(pkt);
4913 av_packet_free(&pkt);
4921 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"StreamChangeCheck skip SeekReset"));
4931 int result = av_read_frame(ctx, pkt);
4939 if (pmt_buffer.has_buffer())
4996 if (stream < 0 || !
m_ic)
4998 return avcodec_get_name(
m_ic->streams[stream]->codecpar->codec_id);
5012 QString msg = (disable) ?
"Disabling" :
"Allowing";
5013 LOG(VB_AUDIO, LOG_INFO,
LOC + msg +
" pass through");
5036 switch (ctx->codec_id)
5038 case AV_CODEC_ID_AC3:
5039 case AV_CODEC_ID_TRUEHD:
5040 case AV_CODEC_ID_EAC3:
5041 case AV_CODEC_ID_MLP:
5042 case AV_CODEC_ID_DTS:
5051 bool passthru =
false;
5055 if (!withProfile && par->codec_id == AV_CODEC_ID_DTS && !
m_audio->
CanDTSHD())
5058 par->codec_id, FF_PROFILE_DTS);
5063 par->codec_id, par->profile);
5079 AVStream *curstream =
nullptr;
5080 AVCodecContext *ctx =
nullptr;
5082 int requested_channels = 0;
5086 (
int)
m_ic->nb_streams))
5089 .m_av_stream_index];
5090 if (curstream !=
nullptr)
5097 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No codec context. Returning false");
5103 ctx->bits_per_raw_sample);
5105 if (av_sample_fmt_is_planar(ctx->sample_fmt))
5107 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Audio data is planar"));
5112 int bps = av_get_bytes_per_sample(ctx->sample_fmt) << 3;
5113 if (ctx->sample_fmt == AV_SAMPLE_FMT_S32 &&
5114 ctx->bits_per_raw_sample)
5115 bps = ctx->bits_per_raw_sample;
5116 LOG(VB_GENERAL, LOG_ERR,
LOC +
5117 QString(
"Unsupported sample format with %1 bits").arg(bps));
5121 bool using_passthru =
DoPassThrough(curstream->codecpar,
false);
5123 requested_channels = ctx->ch_layout.nb_channels;
5125 if (!using_passthru &&
5131 AVChannelLayout channel_layout;
5132 av_channel_layout_default(&channel_layout, requested_channels);
5133 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
5137 requested_channels, using_passthru, ctx->ch_layout.nb_channels,
5138 ctx->codec_id == AV_CODEC_ID_DTS ? ctx->profile : 0);
5142 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Initializing audio parms from " +
5147 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio format changed " +
5148 QString(
"\n\t\t\tfrom %1 to %2")
5164 switch (ctx->codec_id)
5166 case AV_CODEC_ID_MP2:
5169 case AV_CODEC_ID_MP3:
5172 case AV_CODEC_ID_AC3:
5175 case AV_CODEC_ID_DTS:
5178 case AV_CODEC_ID_VORBIS:
5181 case AV_CODEC_ID_WMAV1:
5184 case AV_CODEC_ID_WMAV2:
5192 lcd->setAudioFormatLEDs(audio_format,
true);
5227 int64_t start_time = INT64_MAX;
5228 int64_t end_time = INT64_MIN;
5229 AVStream *st =
nullptr;
5231 for (
uint i = 0; i < ic->nb_streams; i++)
5233 AVStream *st1 = ic->streams[i];
5234 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5243 int64_t duration = INT64_MIN;
5244 if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
5245 int64_t start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
5246 start_time = std::min(start_time1, start_time);
5247 if (st->duration != AV_NOPTS_VALUE) {
5248 int64_t end_time1 = start_time1 +
5249 av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5250 end_time = std::max(end_time1, end_time);
5253 if (st->duration != AV_NOPTS_VALUE) {
5254 int64_t duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5255 duration = std::max(duration1, duration);
5257 if (start_time != INT64_MAX) {
5258 ic->start_time = start_time;
5259 if (end_time != INT64_MIN) {
5260 duration = std::max(end_time - start_time, duration);
5263 if (duration != INT64_MIN) {
5264 ic->duration = duration;
5267 int64_t filesize = avio_size(ic->pb);
5270 ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
5271 (
double)ic->duration;
5287 if (
m_ic ==
nullptr)
5292 if (program ==
nullptr)