14 #include "libavutil/avutil.h"
15 #include "libavutil/error.h"
16 #include "libavutil/intreadwrite.h"
17 #include "libavutil/log.h"
18 #include "libavutil/opt.h"
19 #include "libavcodec/avcodec.h"
20 #include "libavformat/avformat.h"
21 #include "libavformat/avio.h"
22 #include "libswscale/swscale.h"
23 #include "libavutil/stereo3d.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/display.h"
28 #ifdef USING_MEDIACODEC // Android
30 #include "libavcodec/jni.h"
32 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
33 #include <QtAndroidExtras>
35 #include <QJniEnvironment>
36 #define QAndroidJniEnvironment QJniEnvironment
64 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
67 #include <QStringDecoder>
80 #include "libmythbase/mythconfig.h"
109 # ifdef AV_TIME_BASE_Q
110 # undef AV_TIME_BASE_Q
112 #define AV_TIME_BASE_Q GetAVTimeBaseQ()
114 __inline AVRational GetAVTimeBaseQ()
116 AVRational av = {1, AV_TIME_BASE};
121 #define LOC QString("AFD: ")
131 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
141 return {ctx.width >> ctx.lowres, ctx.height >> ctx.lowres};
145 float aspect_ratio = 0.0F;
147 if (ctx.sample_aspect_ratio.num && ctx.height)
149 aspect_ratio = av_q2d(ctx.sample_aspect_ratio) *
150 static_cast<double>(ctx.width);
151 aspect_ratio /= (float) ctx.height;
154 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
157 aspect_ratio = (float)ctx.width / (
float)ctx.height;
159 aspect_ratio = 4.0F / 3.0F;
166 static constexpr
float kDefaultAspect = 4.0F / 3.0F;
167 int asp =
p.aspectRatio();
170 case 0:
return kDefaultAspect;
171 case 2:
return 4.0F / 3.0F;
172 case 3:
return 16.0F / 9.0F;
173 case 4:
return 2.21F;
177 float aspect_ratio = asp * 0.000001F;
178 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
180 if (
p.pictureHeight() &&
p.pictureWidth())
183 (float)
p.pictureWidth() /(float)
p.pictureHeight();
187 aspect_ratio = kDefaultAspect;
211 #define FAIL(errmsg) do { \
212 LOG(VB_PLAYBACK, LOG_INFO, LOC + (errmsg)); \
223 switch (Stream->codecpar->codec_type)
227 case AVMEDIA_TYPE_VIDEO:
229 FAIL(
"No codec for video stream");
230 if (!Stream->codecpar->width || !Stream->codecpar->height)
231 FAIL(
"Unspecified video size");
232 if (Stream->codecpar->format == AV_PIX_FMT_NONE)
233 FAIL(
"Unspecified video pixel format");
240 case AVMEDIA_TYPE_AUDIO:
242 FAIL(
"No codec for audio stream");
260 case AVMEDIA_TYPE_SUBTITLE:
261 if (Stream->codecpar->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !Stream->codecpar->width)
262 FAIL(
"Unspecified subtitle size");
264 case AVMEDIA_TYPE_DATA:
265 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
272 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
273 FAIL(
"Unknown codec");
277 static void myth_av_log(
void *ptr,
int level,
const char* fmt, va_list vl)
285 static QString s_fullLine(
"");
286 static QMutex s_stringLock;
287 uint64_t verbose_mask = VB_LIBAV;
288 LogLevel_t verbose_level = LOG_EMERG;
294 verbose_level = LOG_EMERG;
295 verbose_mask |= VB_GENERAL;
298 verbose_level = LOG_CRIT;
299 verbose_mask |= VB_GENERAL;
302 verbose_level = LOG_ERR;
305 verbose_level = LOG_WARNING;
308 verbose_level = LOG_INFO;
313 verbose_level = LOG_DEBUG;
323 if (s_fullLine.isEmpty() && ptr) {
324 AVClass* avc = *(AVClass**)ptr;
325 s_fullLine = QString(
"[%1 @ %2] ")
326 .arg(avc->item_name(ptr))
327 .arg((quintptr)avc, QT_POINTER_SIZE * 2, 16, QChar(
'0'));
330 s_fullLine += QString::vasprintf(fmt, vl);
331 if (s_fullLine.endsWith(
"\n"))
333 LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
334 s_fullLine.truncate(0);
336 s_stringLock.unlock();
341 if (lang_cstr[0] ==
'\0' || lang_cstr[1] ==
'\0')
345 if (lang_cstr[2] ==
'\0')
347 QString tmp2 = lang_cstr;
365 case AVMEDIA_TYPE_UNKNOWN:
return "Unknown";
366 case AVMEDIA_TYPE_VIDEO:
return "Video";
367 case AVMEDIA_TYPE_AUDIO:
return "Audio";
368 case AVMEDIA_TYPE_DATA:
return "Data";
369 case AVMEDIA_TYPE_SUBTITLE:
return "Subtitle";
370 case AVMEDIA_TYPE_ATTACHMENT:
return "Attachment";
371 default:
return "Invalid Codec Type";
381 m_playerFlags(flags),
401 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"PlayerFlags: 0x%1, AudioReadAhead: %2 msec")
410 av_packet_free(&pkt);
428 lcd->setAudioFormatLEDs(
AUDIO_AC3,
false);
429 lcd->setVideoFormatLEDs(
VIDEO_MPG,
false);
446 for (
uint i = 0; i <
m_ic->nb_streams; i++)
448 AVStream *st =
m_ic->streams[i];
461 av_free(
m_ic->pb->buffer);
463 avformat_close_input(&
m_ic);
469 static int64_t
lsb3full(int64_t lsb, int64_t base_ts,
int lsb_bits)
471 int64_t mask = (lsb_bits < 64) ? (1LL<<lsb_bits)-1 : -1LL;
472 return ((lsb - base_ts)&mask);
477 int64_t start_pts = 0;
479 AVStream *st =
nullptr;
480 for (
uint i = 0; i <
m_ic->nb_streams; i++)
482 AVStream *st1 =
m_ic->streams[i];
483 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
492 if (
m_ic->start_time != AV_NOPTS_VALUE)
494 start_pts = av_rescale(
m_ic->start_time,
496 AV_TIME_BASE * (int64_t)st->time_base.num);
499 int64_t
pts = av_rescale(timecode.count() / 1000.0,
510 std::chrono::milliseconds timecode)
512 int64_t start_pts = 0;
514 if (
m_ic->start_time != AV_NOPTS_VALUE)
516 start_pts = av_rescale(
m_ic->start_time,
518 AV_TIME_BASE * (int64_t)st->time_base.num);
521 int64_t
pts = av_rescale(timecode.count() / 1000.0,
534 return m_ic->nb_chapters;
544 for (
int i = 0; i < total; i++)
546 int num =
m_ic->chapters[i]->time_base.num;
547 int den =
m_ic->chapters[i]->time_base.den;
548 int64_t start =
m_ic->chapters[i]->start;
549 long double total_secs = (
long double)start * (
long double)num /
551 times.push_back(std::chrono::seconds((
long long)total_secs));
560 for (
int i = (
m_ic->nb_chapters - 1); i > -1 ; i--)
562 int num =
m_ic->chapters[i]->time_base.num;
563 int den =
m_ic->chapters[i]->time_base.den;
564 int64_t start =
m_ic->chapters[i]->start;
565 long double total_secs = (
long double)start * (
long double)num /
567 auto framenum = (
long long)(total_secs *
m_fps);
568 if (framesPlayed >= framenum)
570 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
571 QString(
"GetCurrentChapter(selected chapter %1 framenum %2)")
572 .arg(i + 1).arg(framenum));
584 int num =
m_ic->chapters[chapter - 1]->time_base.num;
585 int den =
m_ic->chapters[chapter - 1]->time_base.den;
586 int64_t start =
m_ic->chapters[chapter - 1]->start;
587 long double total_secs = (
long double)start * (
long double)num /
589 auto framenum = (
long long)(total_secs *
m_fps);
590 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"GetChapter %1: framenum %2")
591 .arg(chapter).arg(framenum));
597 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"DoRewind(%1, %2 discard frames)")
598 .arg(desiredFrame).arg( discardFrames ?
"do" :
"don't" ));
611 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
612 QString(
"DoFastForward(%1 (%2), %3 discard frames)")
614 .arg((discardFrames) ?
"do" :
"don't"));
625 if (seekDelta >= 0 && seekDelta < 2 && !m_doRewind && m_parent->GetPlaySpeed() == 0.0F)
634 if (
m_ic->start_time != AV_NOPTS_VALUE)
635 ts =
m_ic->start_time;
638 long double seekts = desiredFrame * AV_TIME_BASE /
m_fps;
639 ts += (
long long)seekts;
644 int flags = (
m_doRewind || exactseeks) ? AVSEEK_FLAG_BACKWARD : 0;
646 if (av_seek_frame(
m_ic, -1, ts, flags) < 0)
648 LOG(VB_GENERAL, LOG_ERR,
LOC +
649 QString(
"av_seek_frame(ic, -1, %1, 0) -- error").arg(ts));
654 reader->SeekFrame(ts, flags);
656 int normalframes = 0;
678 bool doflush,
bool discardFrames)
683 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
684 QString(
"SeekReset(%1, %2, %3 flush, %4 discard)")
685 .arg(newKey).arg(skipFrames)
686 .arg((doflush) ?
"do" :
"don't",
687 (discardFrames) ?
"do" :
"don't"));
712 avformat_flush(
m_ic);
719 m_ic->pb->buf_ptr =
m_ic->pb->buffer;
720 m_ic->pb->buf_end =
m_ic->pb->buffer;
721 m_ic->pb->eof_reached = 0;
725 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SeekReset() flushing");
726 for (
uint i = 0; i <
m_ic->nb_streams; i++)
732 if (enc && enc->internal)
733 avcodec_flush_buffers(enc);
740 av_packet_free(&pkt);
762 static constexpr std::chrono::milliseconds maxSeekTimeMs { 200ms };
763 int profileFrames = 0;
765 for (; (skipFrames > 0 && !
m_atEof &&
766 (exactSeeks || begin.
elapsed() < maxSeekTimeMs));
767 --skipFrames, ++profileFrames)
771 QElapsedTimer getframetimer;
772 getframetimer.start();
774 while (retry && !getframetimer.hasExpired(100))
779 std::this_thread::sleep_for(1ms);
787 if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
789 const int giveUpPredictionMs = 400;
790 int remainingTimeMs =
791 skipFrames * (float)begin.
elapsed().count() / profileFrames;
792 if (remainingTimeMs > giveUpPredictionMs)
794 LOG(VB_PLAYBACK, LOG_DEBUG,
795 QString(
"Frame-by-frame seeking would take "
796 "%1 ms to finish, skipping.").arg(remainingTimeMs));
813 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
814 QString(
"Resetting byte context eof (livetv %1 was eof %2)")
816 m_ic->pb->eof_reached = 0;
824 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
825 QString(
"Reset: Video %1, Seek %2, File %3")
826 .arg(reset_video_data).arg(seek_reset).arg(reset_file));
833 if (reset_video_data)
843 memset(&probe, 0,
sizeof(AVProbeData));
845 QByteArray fname =
filename.toLatin1();
846 probe.filename = fname.constData();
847 probe.buf = (
unsigned char *)testbuf.data();
848 probe.buf_size = testbuf.size();
850 int score = AVPROBE_SCORE_MAX/4;
862 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
864 return av_probe_input_format2(&probe,
static_cast<int>(
true), &score) !=
nullptr;
876 auto *buffer = (
unsigned char *)av_malloc(buf_size);
877 m_ic->pb = avio_alloc_context(buffer, buf_size, 0,
884 m_ic->pb->seekable =
static_cast<int>(!streamed || forceseek);
885 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Buffer size: %1 Streamed %2 Seekable %3 Available %4")
893 int cnt = decoder->
m_ic->nb_streams;
895 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
896 QString(
"streams_changed 0x%1 -- stream count %2")
897 .arg((uint64_t)data,0,16).arg(cnt));
899 decoder->m_streamsChanged =
true;
905 int retval = avformat_find_stream_info(
m_ic,
nullptr);
946 const AVInputFormat *fmt =
nullptr;
948 QByteArray fnamea = fnames.toLatin1();
949 const char *
filename = fnamea.constData();
952 memset(&probe, 0,
sizeof(AVProbeData));
954 probe.buf =
reinterpret_cast<unsigned char *
>(testbuf.data());
956 probe.buf_size = testbuf.size();
959 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
961 fmt = av_probe_input_format(&probe,
static_cast<int>(
true));
964 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Probe failed for '%1'").arg(
filename));
968 if (strcmp(fmt->name,
"mpegts") == 0 &&
971 const AVInputFormat *fmt2 = av_find_input_format(
"mpegts-ffmpeg");
975 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using FFmpeg MPEG-TS demuxer (forced)");
980 bool scancomplete =
false;
981 int remainingscans = 5;
983 while (!scancomplete && remainingscans--)
997 while (!found && --retries)
999 m_ic = avformat_alloc_context();
1002 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Could not allocate format context.");
1009 err = avformat_open_input(&
m_ic,
filename, fmt,
nullptr);
1013 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Failed to open input ('%1')")
1021 QThread::usleep(100000);
1027 if (strcmp(fmt->name,
"mpegts") == 0)
1029 fmt = av_find_input_format(
"mpegts-ffmpeg");
1032 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to use original FFmpeg MPEG-TS demuxer.");
1045 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error opening input. Aborting");
1057 m_ic->max_analyze_duration = 60LL * AV_TIME_BASE;
1063 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Could not find codec parameters for '%1'").arg(
filename));
1070 scancomplete =
true;
1075 scancomplete =
false;
1079 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stream scan incomplete - retrying");
1080 QThread::usleep(250000);
1088 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Scan incomplete - playback may not work");
1091 m_ic->stream_change_data =
this;
1103 QString extension = QFileInfo(fnames).suffix();
1104 if (strcmp(fmt->name,
"mp3") == 0 || strcmp(fmt->name,
"flac") == 0 ||
1105 strcmp(fmt->name,
"ogg") == 0 ||
1106 (extension.compare(
"m4a", Qt::CaseInsensitive) == 0))
1123 int initialAudio = -1;
1124 int initialVideo = -1;
1127 if (initialAudio >= 0)
1129 if (initialVideo >= 0)
1132 #endif // USING_MHEG
1150 std::chrono::seconds dur = 0s;
1159 dur = duration_cast<std::chrono::seconds>(av_duration(
m_ic->duration));
1170 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1171 "Recording has no position -- using libavformat seeking.");
1180 float bytespersec = (float)
m_bitrate / 8 / 2;
1183 (int)(secs *
static_cast<float>(
m_fps)));
1192 if (strcmp(fmt->name,
"avi") == 0)
1205 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Position map found");
1207 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Partial position map found");
1208 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1209 QString(
"Successfully opened decoder for file: \"%1\". novideo(%2)")
1213 for (
unsigned int i=0; i <
m_ic->nb_chapters; i++)
1215 int num =
m_ic->chapters[i]->time_base.num;
1216 int den =
m_ic->chapters[i]->time_base.den;
1217 int64_t start =
m_ic->chapters[i]->start;
1218 auto total_secs =
static_cast<long double>(start) *
static_cast<long double>(num) /
1219 static_cast<long double>(den);
1221 auto framenum =
static_cast<long long>(total_secs *
static_cast<long double>(
m_fps));
1222 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1223 QString(
"Chapter %1 found @ [%2]->%3")
1226 QString::number(framenum)));
1229 if (qEnvironmentVariableIsSet(
"FORCE_DTS_TIMESTAMPS"))
1242 Reset(
true,
true,
true);
1256 double avg_fps = (Stream->avg_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->avg_frame_rate);
1257 double codec_fps = av_q2d(Context->framerate);
1258 double container_fps = (Stream->time_base.num == 0) ? 0.0 : av_q2d(av_inv_q(Stream->time_base));
1260 double estimated_fps = (Stream->r_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->r_frame_rate);
1263 std::vector<double> rates;
1268 if (QString(
m_ic->iformat->name).contains(
"matroska") ||
1269 QString(
m_ic->iformat->name).contains(
"mov"))
1271 rates.emplace_back(avg_fps);
1275 if (QString(
m_ic->iformat->name).contains(
"avi"))
1277 rates.emplace_back(container_fps);
1280 rates.emplace_back(codec_fps);
1281 rates.emplace_back(container_fps);
1282 rates.emplace_back(avg_fps);
1284 rates.emplace_back(estimated_fps);
1286 rates.emplace_back(30000.0 / 1001.0);
1288 auto invalid_fps = [](
double rate) {
return rate < 3.0 || rate > 121.0; };
1289 rates.erase(std::remove_if(rates.begin(), rates.end(), invalid_fps), rates.end());
1291 auto FuzzyEquals = [](
double First,
double Second) {
return std::abs(First - Second) < 0.03; };
1294 if (!FuzzyEquals(rates.front(),
m_fps))
1296 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1297 QString(
"Selected FPS: %1 (Avg:%2 Mult:%3 Codec:%4 Container:%5 Estimated:%6)")
1298 .arg(
static_cast<double>(rates.front())).arg(avg_fps)
1299 .arg(
m_fpsMultiplier).arg(codec_fps).arg(container_fps).arg(estimated_fps));
1302 auto IsStandard = [&FuzzyEquals](
double Rate)
1305 static const std::set<double> k_standard_rates =
1324 if (Rate > 23.0 && Rate < 121.0)
1326 for (
auto standard_rate : k_standard_rates)
1327 if (FuzzyEquals(Rate, standard_rate))
1336 double detected = rates.front();
1337 if (Sanitise && !IsStandard(detected))
1339 for (
auto rate : rates)
1341 if (IsStandard(rate))
1343 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 is non-standard - using %2 instead.")
1344 .arg(rates.front()).arg(rate));
1352 if (rate > 33.0 && detected < 33.0)
1354 double half = rate / 2.0;
1355 if (std::abs(half - detected) < (half * 0.1))
1357 LOG(VB_GENERAL, LOG_INFO,
LOC +
1358 QString(
"Assuming %1 is a better choice than %2")
1359 .arg(half).arg(rate));
1360 return static_cast<float>(half);
1363 return static_cast<float>(rate);
1368 return static_cast<float>(detected);
1374 const enum AVPixelFormat *);
1377 const enum AVPixelFormat *valid_fmts)
1382 static uint8_t *dummy[1] = {
nullptr };
1383 avctx->hwaccel_context =
1384 (dxva_context*)nd->
GetPlayer()->GetDecoderContext(
nullptr, dummy[0]);
1387 while (*valid_fmts != AV_PIX_FMT_NONE) {
1388 if (avctx->hwaccel_context and (*valid_fmts == AV_PIX_FMT_DXVA2_VLD))
1389 return AV_PIX_FMT_DXVA2_VLD;
1390 if (not avctx->hwaccel_context and (*valid_fmts == AV_PIX_FMT_YUV420P))
1391 return AV_PIX_FMT_YUV420P;
1394 return AV_PIX_FMT_NONE;
1400 switch (Context->codec_id)
1402 case AV_CODEC_ID_H264:
1405 if (Context->extradata && (Context->extradata_size >= 7))
1408 if (Context->extradata[0] == 1)
1410 else if (AV_RB24(Context->extradata) == 0x01)
1412 else if (
AV_RB32(Context->extradata) == 0x01)
1419 parser.parse_SPS(Context->extradata + offset,
1420 static_cast<uint>(Context->extradata_size - offset), dummy, result);
1425 case AV_CODEC_ID_H265:
return 16;
1426 case AV_CODEC_ID_VP9:
return 8;
1427 case AV_CODEC_ID_VP8:
return 3;
1433 bool selectedStream)
1435 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1436 QString(
"InitVideoCodec ID:%1 Type:%2 Size:%3x%4")
1437 .arg(avcodec_get_name(enc->codec_id),
1439 .arg(enc->width).arg(enc->height));
1444 enc->opaque =
static_cast<void*
>(
this);
1446 enc->slice_flags = 0;
1448 enc->err_recognition = AV_EF_COMPLIANT;
1449 enc->workaround_bugs = FF_BUG_AUTODETECT;
1450 enc->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
1451 enc->idct_algo = FF_IDCT_AUTO;
1455 const AVCodec *codec1 = enc->codec;
1461 uint8_t* displaymatrix = av_stream_get_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX,
nullptr);
1463 m_videoRotation =
static_cast<int>(-av_display_rotation_get(
reinterpret_cast<int32_t*
>(displaymatrix)));
1468 uint8_t* stereo3d = av_stream_get_side_data(stream, AV_PKT_DATA_STEREO3D,
nullptr);
1471 auto * avstereo =
reinterpret_cast<AVStereo3D*
>(stereo3d);
1496 bool doublerate =
true;
1500 if (codec1 && ((AV_CODEC_ID_MPEG2VIDEO == codec1->id) ||
1501 (AV_CODEC_ID_MPEG1VIDEO == codec1->id)))
1505 int total_blocks = (enc->height + 15) / 16;
1506 enc->skip_top = (total_blocks + 3) / 4;
1507 enc->skip_bottom = (total_blocks + 3) / 4;
1515 enc->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
1516 enc->skip_loop_filter = AVDISCARD_ALL;
1520 enc->skip_idct = AVDISCARD_ALL;
1532 if (!width || !height)
1534 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1535 "InitVideoCodec invalid dimensions, resetting decoder.");
1543 const AVCodec *codec2 = enc->codec;
1546 codecName = codec2->name;
1554 switch (enc->codec_id)
1556 case AV_CODEC_ID_H263:
1557 case AV_CODEC_ID_MPEG4:
1558 case AV_CODEC_ID_MSMPEG4V1:
1559 case AV_CODEC_ID_MSMPEG4V2:
1560 case AV_CODEC_ID_MSMPEG4V3:
1561 case AV_CODEC_ID_H263P:
1562 case AV_CODEC_ID_H263I:
1565 case AV_CODEC_ID_WMV1:
1566 case AV_CODEC_ID_WMV2:
1570 case AV_CODEC_ID_XVID:
1579 lcd->setVideoFormatLEDs(video_format,
true);
1591 static constexpr std::array<uint8_t, 256> odd_parity_LUT
1593 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1594 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1595 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1596 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1597 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1598 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1599 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1600 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1601 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1602 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1603 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1604 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1605 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1606 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1607 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1608 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1610 bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
1611 (odd_parity_LUT[(data & 0xff00) >> 8] == 1);
1614 LOG(VB_VBI, LOG_ERR,
LOC +
1615 QString(
"VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
1629 if (!
m_ic->pmt_section)
1631 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1632 "ScanATSCCaptionStreams() called with no PMT");
1637 if (!pmt_buffer.has_buffer())
1643 bool video_found =
false;
1667 desc_list.insert(desc_list.end(), desc_list2.begin(), desc_list2.end());
1669 for (
auto & desc : desc_list)
1714 std::array<std::map<int,uint>,2> lang_cc_cnt;
1731 else if (!pofr && sofr)
1757 LOG(VB_GENERAL, LOG_ERR,
LOC +
"in_tracks key too small");
1763 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1764 QString(
"%1 caption service #%2 is in the %3 language.")
1765 .arg((
type) ?
"EIA-708" :
"EIA-608")
1780 if (!pmt_buffer.has_buffer())
1795 for (
const auto *desc : desc_list)
1808 int lang_idx = (magazine << 8) | pagenum;
1809 StreamInfo si(av_index, language, lang_idx, 0, 0);
1815 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1816 QString(
"Teletext stream #%1 (%2) is in the %3 language"
1818 .arg(QString::number(k),
1819 (
type == 2) ?
"Caption" :
"Menu",
1821 QString::number(magazine),
1822 QString::number(pagenum)));
1837 AVDictionaryEntry *metatag =
1838 av_dict_get(
m_ic->streams[av_stream_index]->metadata,
"language",
nullptr,
1840 bool forced = (
m_ic->streams[av_stream_index]->disposition & AV_DISPOSITION_FORCED) != 0;
1843 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1844 QString(
"Text Subtitle track #%1 is A/V stream #%2 "
1845 "and is in the %3 language(%4), forced=%5.")
1848 StreamInfo si(av_stream_index, lang, 0, 0, 0,
false,
false, forced);
1865 if (!pmt_buffer.has_buffer())
1876 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams Found Object Carousel in Stream %1").arg(QString::number(i)));
1882 for (
const auto *desc : desc_list)
1885 uint length = *desc++;
1886 const unsigned char *endDesc = desc+length;
1887 uint dataBroadcastId = desc[0]<<8 | desc[1];
1888 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams dataBroadcastId %1").arg(QString::number(dataBroadcastId)));
1889 if (dataBroadcastId != 0x0106)
1892 while (desc != endDesc)
1894 [[maybe_unused]]
uint appTypeCode = desc[0]<<8 | desc[1];
1896 uint appSpecDataLen = *desc++;
1898 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams AppTypeCode %1").arg(QString::number(appTypeCode)));
1899 if (appTypeCode == 0x101)
1901 const unsigned char *subDescEnd = desc + appSpecDataLen;
1902 while (desc < subDescEnd)
1904 uint sub_desc_tag = *desc++;
1905 uint sub_desc_len = *desc++;
1907 if (sub_desc_tag == 1)
1909 desc += sub_desc_len;
1913 #endif // USING_MHEG
1915 desc += appSpecDataLen;
1927 bool unknownbitrate =
false;
1944 std::map<int,uint> lang_sub_cnt;
1945 uint subtitleStreamCount = 0;
1946 std::map<int,uint> lang_aud_cnt;
1947 uint audioStreamCount = 0;
1956 if (
m_ic ==
nullptr)
1959 for (
uint strm = 0; strm <
m_ic->nb_streams; strm++)
1961 AVCodecParameters *par =
m_ic->streams[strm]->codecpar;
1962 AVCodecContext *enc =
nullptr;
1965 if (par->codec_type == AVMEDIA_TYPE_VIDEO)
1966 codectype += QString(
"(%1x%2)").arg(par->width).arg(par->height);
1967 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1968 QString(
"Stream #%1: ID: 0x%2 Codec ID: %3 Type: %4 Bitrate: %5")
1969 .arg(strm).arg(
static_cast<uint64_t
>(
m_ic->streams[strm]->id), 0, 16)
1970 .arg(avcodec_get_name(par->codec_id),
1971 codectype).arg(par->bit_rate));
1973 switch (par->codec_type)
1975 case AVMEDIA_TYPE_VIDEO:
1983 if (ctx && (ctx->hw_frames_ctx || ctx->hw_device_ctx))
1990 LOG(VB_GENERAL, LOG_ERR,
LOC +
1991 QString(
"Stream #%1 has an unknown video "
1992 "codec id, skipping.").arg(strm));
2004 if (par->bit_rate == 0)
2006 static constexpr int64_t s_baseBitrate { 1000000LL };
2008 if (par->width && par->height)
2010 static const int s_baseSize = 1920 * 1080;
2011 multiplier = ((par->width * par->height) + s_baseSize - 1) / s_baseSize;
2015 par->bit_rate = s_baseBitrate * multiplier;
2016 unknownbitrate =
true;
2022 case AVMEDIA_TYPE_AUDIO:
2025 if (enc && enc->internal)
2027 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2028 QString(
"Warning, audio codec 0x%1 id(%2) "
2029 "type (%3) already open, leaving it alone.")
2030 .arg(
reinterpret_cast<unsigned long long>(enc), 0, 16)
2031 .arg(avcodec_get_name(enc->codec_id),
2034 LOG(VB_GENERAL, LOG_INFO,
LOC +
2035 QString(
"codec %1 has %2 channels")
2036 .arg(avcodec_get_name(par->codec_id))
2037 .arg(par->ch_layout.nb_channels));
2042 case AVMEDIA_TYPE_SUBTITLE:
2044 if (par->codec_id == AV_CODEC_ID_DVB_TELETEXT)
2046 if (par->codec_id == AV_CODEC_ID_TEXT)
2050 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"subtitle codec (%1)")
2054 case AVMEDIA_TYPE_DATA:
2058 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"data codec (%1)")
2062 case AVMEDIA_TYPE_ATTACHMENT:
2064 if (par->codec_id == AV_CODEC_ID_TTF)
2066 static_cast<int>(strm), 0, 0,
m_ic->streams[strm]->id, 0);
2068 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2069 QString(
"Attachment codec (%1)")
2076 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
2077 QString(
"Unknown codec type (%1)")
2083 if (par->codec_type != AVMEDIA_TYPE_AUDIO &&
2084 par->codec_type != AVMEDIA_TYPE_SUBTITLE)
2088 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2089 (par->codec_id == AV_CODEC_ID_DVB_TELETEXT ||
2090 par->codec_id == AV_CODEC_ID_TEXT))
2093 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Looking for decoder for %1")
2094 .arg(avcodec_get_name(par->codec_id)));
2096 if (par->codec_id == AV_CODEC_ID_PROBE)
2098 LOG(VB_GENERAL, LOG_ERR,
LOC +
2099 QString(
"Probing of stream #%1 unsuccesful, ignoring.").arg(strm));
2106 const AVCodec *codec =
nullptr;
2111 LOG(VB_GENERAL, LOG_ERR,
LOC +
2112 QString(
"Could not find decoder for codec (%1), ignoring.")
2113 .arg(avcodec_get_name(par->codec_id)));
2120 void *opaque =
nullptr;
2121 const AVCodec *
p = av_codec_iterate(&opaque);
2126 if (
p->name[0] !=
'\0')
2127 msg = QString(
"Codec %1:").arg(
p->name);
2129 msg = QString(
"Codec %1, null name,").arg(strm);
2131 LOG(VB_LIBAV, LOG_INFO,
LOC + msg);
2133 if (
p->id == par->codec_id)
2139 LOG(VB_LIBAV, LOG_INFO,
LOC +
2140 QString(
"Codec 0x%1 != 0x%2") .arg(
p->id, 0, 16)
2141 .arg(par->codec_id, 0, 16));
2142 p = av_codec_iterate(&opaque);
2153 if (enc->codec && par->codec_id != enc->codec_id)
2155 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2156 QString(
"Already opened codec not matching (%1 vs %2). Reopening")
2157 .arg(avcodec_get_name(enc->codec_id),
2158 avcodec_get_name(enc->codec->id)));
2174 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2175 QString(
"Stream 0x%1 is not valid in this context - skipping")
2176 .arg(
m_ic->streams[strm]->id, 4, 16));
2180 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2182 bool forced = (
m_ic->streams[strm]->disposition & AV_DISPOSITION_FORCED) != 0;
2184 uint lang_indx = lang_sub_cnt[lang]++;
2185 subtitleStreamCount++;
2188 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, 0, 0,
false,
false, forced);
2190 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2191 QString(
"Subtitle track #%1 is A/V stream #%2 "
2192 "and is in the %3 language(%4).")
2197 if (par->codec_type == AVMEDIA_TYPE_AUDIO)
2201 int channels = par->ch_layout.nb_channels;
2202 uint lang_indx = lang_aud_cnt[lang]++;
2205 if (enc->avcodec_dual_language)
2208 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, channels,
2209 false,
false,
false,
type);
2210 lang_indx = lang_aud_cnt[lang]++;
2212 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, channels,
2213 true,
false,
false,
type);
2217 int logical_stream_id = 0;
2224 logical_stream_id =
m_ic->streams[strm]->id;
2226 if (logical_stream_id == -1)
2233 static_cast<int>(strm), lang, lang_indx, logical_stream_id, channels,
2234 false,
false,
false,
type);
2237 LOG(VB_AUDIO, LOG_INFO,
LOC +
2238 QString(
"Audio Track #%1, of type (%2) is A/V stream #%3 (id=0x%4) "
2239 "and has %5 channels in the %6 language(%7).")
2241 .arg(strm).arg(
m_ic->streams[strm]->id,0,16).arg(enc->ch_layout.nb_channels)
2252 const AVCodec *codec =
nullptr;
2253 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Trying to select best video track");
2267 int selTrack = av_find_best_stream(
m_ic, AVMEDIA_TYPE_VIDEO,
2272 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No video track found/selected.");
2276 AVStream *stream =
m_ic->streams[selTrack];
2286 if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
2287 codectype += QString(
"(%1x%2)").arg(enc->width).arg(enc->height);
2288 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2289 QString(
"Selected track #%1: ID: 0x%2 Codec ID: %3 Profile: %4 Type: %5 Bitrate: %6")
2290 .arg(selTrack).arg(
static_cast<uint64_t
>(stream->id), 0, 16)
2291 .arg(avcodec_get_name(enc->codec_id),
2292 avcodec_profile_name(enc->codec_id, enc->profile),
2294 QString::number(enc->bit_rate)));
2301 if ((enc->width != stream->codecpar->width) || (enc->height != stream->codecpar->height))
2303 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
2304 "Video resolution mismatch: Context: %1x%2 Stream: %3x%4 Codec: %5 Stream change: %6")
2305 .arg(enc->width).arg(enc->height)
2306 .arg(stream->codecpar->width).arg(stream->codecpar->height)
2313 int width = std::max(dim.width(), 16);
2314 int height = std::max(dim.height(), 16);
2315 QString dec =
"ffmpeg";
2316 uint thread_count = 1;
2319 codecName = enc->codec->name;
2324 if (enc->framerate.den && enc->framerate.num)
2325 m_fps = float(enc->framerate.num) / float(enc->framerate.den);
2329 bool foundgpudecoder =
false;
2330 QStringList unavailabledecoders;
2340 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
2341 "GPU/hardware decoder '%1' failed - forcing software decode")
2348 while (unavailabledecoders.size() < 10)
2352 if (!unavailabledecoders.isEmpty())
2354 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Unavailable decoders: %1")
2355 .arg(unavailabledecoders.join(
",")));
2361 if (!skip_loop_filter)
2362 enc->skip_loop_filter = AVDISCARD_NONKEY;
2370 if (
version && allowgpu && dec !=
"ffmpeg")
2374 enc->opaque =
static_cast<void*
>(
this);
2379 enc->opaque =
static_cast<void*
>(
this);
2381 foundgpudecoder =
true;
2386 unavailabledecoders.append(dec);
2394 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown video codec - defaulting to MPEG2");
2419 if (!foundgpudecoder)
2421 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 CPUs for decoding")
2422 .arg(HAVE_THREADS ? thread_count : 1));
2423 enc->thread_count =
static_cast<int>(thread_count);
2457 QString(
m_ic->iformat->name).contains(
"matroska"));
2495 #ifdef USING_MEDIACODEC
2496 if (QString(
"mediacodec") == codec->wrapper_name)
2497 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(),
nullptr);
2499 int ret = avcodec_open2(avctx, codec,
nullptr);
2504 LOG(VB_GENERAL, LOG_ERR,
LOC +
2505 QString(
"Could not open codec 0x%1, id(%2) type(%3) "
2506 "ignoring. reason %4").arg((uint64_t)avctx,0,16)
2507 .arg(avcodec_get_name(avctx->codec_id),
2513 LOG(VB_GENERAL, LOG_INFO,
LOC +
2514 QString(
"Opened codec 0x%1, id(%2) type(%3)")
2515 .arg((uint64_t)avctx,0,16)
2516 .arg(avcodec_get_name(avctx->codec_id),
2541 if (si.m_language_index == Index)
2542 return si.m_language;
2549 AVDictionaryEntry *metatag = av_dict_get(
m_ic->streams[StreamIndex]->metadata,
"language",
nullptr, 0);
2592 AVStream *stream =
m_ic->streams[StreamIndex];
2596 if (stream->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
2598 else if (stream->disposition & AV_DISPOSITION_COMMENT)
2600 else if (stream->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
2602 else if (stream->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
2629 if (
current->m_av_stream_index == streamIndex)
2635 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2636 QString(
"Invalid stream index passed to "
2637 "SetupAudioStreamSubIndexes: %1").arg(streamIndex));
2644 if (
current->m_av_substream_index == -1)
2657 (next->m_av_stream_index != streamIndex))
2659 QString msg = QString(
2660 "Expected substream 1 (Language I) of stream %1\n\t\t\t"
2661 "following substream 0, found end of list or another stream.")
2664 LOG(VB_GENERAL, LOG_WARNING,
LOC + msg);
2686 for (
uint i = 0; i <
m_ic->nb_streams;)
2688 AVStream *st =
m_ic->streams[i];
2690 if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2693 av_remove_stream(
m_ic, st->id, 0);
2706 if (!std::any_of(decoder->m_renderFormats->cbegin(), decoder->m_renderFormats->cend(),
2707 [&
type](
auto Format) { return type == Format; }))
2709 decoder->m_directRendering =
false;
2710 return avcodec_default_get_buffer2(c, pic, flags);
2713 decoder->m_directRendering =
true;
2714 MythVideoFrame *frame = decoder->GetPlayer()->GetNextVideoFrame();
2724 if ((frame->
m_type !=
type) || (pic->width > width) || (pic->height > height))
2741 for (
uint i = 0; i < 3; i++)
2747 pic->opaque = frame;
2748 pic->reordered_opaque = c->reordered_opaque;
2751 AVBufferRef *buffer = av_buffer_create(
reinterpret_cast<uint8_t*
>(frame), 0,
2752 [](
void* Opaque, uint8_t* Data)
2756 if (avfd && avfd->GetPlayer())
2757 avfd->GetPlayer()->DeLimboFrame(vf);
2760 pic->buf[0] = buffer;
2771 for (
int i = 0; i < 4; i++)
2773 pic->data[i] =
nullptr;
2774 pic->linesize[i] = 0;
2776 pic->opaque = frame;
2777 frame->pix_fmt = c->pix_fmt;
2778 pic->reordered_opaque = c->reordered_opaque;
2779 pic->data[0] = (uint8_t*)frame->buf;
2780 pic->data[3] = (uint8_t*)frame->buf;
2783 AVBufferRef *buffer =
2784 av_buffer_create((uint8_t*)frame, 0, release_avf_buffer, nd, 0);
2785 pic->buf[0] = buffer;
2800 bool process_cc_data = (buf[0] & 0x40) != 0;
2801 if (!process_cc_data)
2807 uint cc_count = buf[0] & 0x1f;
2810 if (buf_size < 2+(3*cc_count))
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;
2840 if (scte || cc_type <= 0
x1)
2859 if (scte && field == 0 &&
2860 (data1 & 0x7f) <= 0x0f && (data1 & 0x7f) != 0x00)
2886 bool check_608,
bool check_708)
2888 bool need_change_608 =
false;
2893 for (
uint i = 0; i < 4; i++)
2900 bool need_change_708 =
false;
2902 if (check_708 || need_change_608)
2905 for (
uint i = 1; i < 64 && !need_change_608 && !need_change_708; i++)
2910 if (need_change_708 && !check_608)
2914 if (!need_change_608 && !need_change_708)
2925 for (
uint i = 1; i < 64; i++)
2929 StreamInfo si(av_index, lang, 0, i, 0,
false,
true);
2934 for (
uint i = 0; i < 4; i++)
2945 StreamInfo si(av_index, lang, 0, i+1, 0,
false,
false);
2955 AVPacket *pkt,
bool can_reliably_parse_keyframes)
2960 bool reset_kfd =
false;
2964 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2965 "gopset not set, syncing positionMap");
2967 if (tempKeyFrameDist > 0 && !
m_livetv)
2969 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2970 QString(
"Initial key frame distance: %1.")
2976 else if (
m_keyframeDist != tempKeyFrameDist && tempKeyFrameDist > 0)
2978 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2979 QString(
"Key frame distance changed from %1 to %2.")
3007 if (can_reliably_parse_keyframes &&
3010 long long last_frame = 0;
3018 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
3019 QString(
"framesRead: %1 last_frame: %2 keyframedist: %3")
3026 long long startpos = pkt->pos;
3028 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3029 QString(
"positionMap[ %1 ] == %2.")
3059 float bytespersec = (float)
m_bitrate / 8;
3077 const uint8_t *bufptr = pkt->data;
3078 const uint8_t *bufend = pkt->data + pkt->size;
3080 while (bufptr < bufend)
3084 float aspect_override = -1.0F;
3093 if (bufptr + 11 >= pkt->data + pkt->size)
3095 const auto *seq =
reinterpret_cast<const SequenceHeader*
>(bufptr);
3097 int width =
static_cast<int>(seq->width()) >> context->lowres;
3098 int height =
static_cast<int>(seq->height()) >> context->lowres;
3099 float aspect = seq->
aspect(context->codec_id == AV_CODEC_ID_MPEG1VIDEO);
3100 if (stream->sample_aspect_ratio.num)
3101 aspect =
static_cast<float>(av_q2d(stream->sample_aspect_ratio) * width / height);
3102 if (aspect_override > 0.0F)
3103 aspect = aspect_override;
3104 float seqFPS = seq->fps();
3108 changed |= (seqFPS >
static_cast<float>(
m_fps)+0.01F) ||
3109 (seqFPS < static_cast<float>(
m_fps)-0.01F);
3113 bool forceaspectchange = !qFuzzyCompare(
m_currentAspect + 10.0F, aspect + 10.0F) &&
3117 if (changed || forceaspectchange)
3122 bool doublerate =
false;
3125 forceaspectchange, 2,
3128 if (context->hw_frames_ctx)
3129 if (context->internal)
3130 avcodec_flush_buffers(context);
3149 if ((seqFPS > avFPS+0.01F) || (seqFPS < avFPS-0.01F))
3151 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"avFPS(%1) != seqFPS(%2)")
3152 .arg(
static_cast<double>(avFPS)).arg(
static_cast<double>(seqFPS)));
3161 pkt->flags |= AV_PKT_FLAG_KEY;
3168 pkt->flags |= AV_PKT_FLAG_KEY;
3177 const uint8_t *buf = pkt->data;
3178 const uint8_t *buf_end = pkt->data + pkt->size;
3183 if (context->extradata && (context->extradata_size >= 7) && (context->extradata[0] == 0x01))
3185 if (pkt->flags & AV_PKT_FLAG_KEY)
3190 while (buf < buf_end)
3221 bool fps_changed = (seqFPS > 0.0) && ((seqFPS >
static_cast<double>(
m_fps) + 0.01) ||
3222 (seqFPS < static_cast<double>(
m_fps) - 0.01));
3227 if (fps_changed || res_changed || forcechange)
3232 bool doublerate =
false;
3245 if (context->hw_frames_ctx && (forcechange || res_changed))
3246 if (context->internal)
3247 avcodec_flush_buffers(context);
3253 m_fps =
static_cast<float>(seqFPS);
3268 if ((seqFPS > avFPS + 0.01) || (seqFPS < avFPS - 0.01))
3270 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
3271 QString(
"avFPS(%1) != seqFPS(%2)").arg(avFPS).arg(seqFPS));
3276 pkt->flags |= AV_PKT_FLAG_KEY;
3297 if (pkt->flags & AV_PKT_FLAG_KEY)
3313 !(pkt->flags & AV_PKT_FLAG_KEY))
3315 av_packet_unref(pkt);
3327 pkt_dur = av_mul_q(pkt_dur, curstream->time_base);
3328 if (pkt_dur.num == 1501 && pkt_dur.den == 90000)
3349 mpa_pic->reordered_opaque = AV_NOPTS_VALUE;
3351 if (pkt->pts != AV_NOPTS_VALUE)
3354 bool sentPacket =
false;
3359 context->reordered_opaque = pkt->pts;
3376 if (ret == AVERROR(EAGAIN))
3380 if (ret==0 && !gotpicture)
3382 ret2 = avcodec_send_packet(context, pkt);
3383 if (ret2 == AVERROR(EAGAIN))
3395 if (ret < 0 || ret2 < 0)
3400 LOG(VB_GENERAL, LOG_ERR,
LOC +
3401 QString(
"video avcodec_receive_frame error: %1 (%2) gotpicture:%3")
3403 .arg(ret).arg(gotpicture));
3408 LOG(VB_GENERAL, LOG_ERR,
LOC +
3409 QString(
"video avcodec_send_packet error: %1 (%2) gotpicture:%3")
3411 .arg(ret2).arg(gotpicture));
3425 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Decoder needs reset");
3429 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
3431 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"FFmpeg external library error - assuming streams changed");
3443 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3444 QString(
"video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4")
3445 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts)
3446 .arg(mpa_pic->pkt_dts));
3453 if (pkt->dts != AV_NOPTS_VALUE)
3459 if (mpa_pic->reordered_opaque != AV_NOPTS_VALUE)
3475 if (pkt->dts != AV_NOPTS_VALUE)
3481 if (mpa_pic->reordered_opaque != AV_NOPTS_VALUE)
3482 pts = mpa_pic->reordered_opaque;
3485 else if (pkt->dts != AV_NOPTS_VALUE)
3491 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG,
LOC +
3492 QString(
"video packet timestamps reordered %1 pts %2 dts %3 (%4)")
3493 .arg(mpa_pic->reordered_opaque).arg(pkt->pts).arg(pkt->dts)
3497 mpa_pic->reordered_opaque =
pts;
3506 auto *newPkt = av_packet_clone(pkt);
3526 uint cc_len =
static_cast<uint>(std::max(AvFrame->scte_cc_len,0));
3527 uint8_t *cc_buf = AvFrame->scte_cc_buf;
3537 cc_len =
static_cast<uint>(std::max(AvFrame->atsc_cc_len, 0));
3538 cc_buf = AvFrame->atsc_cc_buf;
3546 for (
uint i = 0; i < cc_len; i += ((cc_buf[i] & 0x1f) * 3) + 2)
3552 auto * side_data = av_frame_get_side_data(AvFrame, AV_FRAME_DATA_A53_CC);
3553 if (side_data && (side_data->size > 0))
3554 DecodeCCx08(side_data->data,
static_cast<uint>(side_data->size),
false);
3567 frame->m_directRendering =
false;
3578 av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
3579 frame->m_buffer, AV_PIX_FMT_YUV420P, AvFrame->width,
3580 AvFrame->height, IMAGE_ALIGN);
3581 tmppicture.data[0] = frame->m_buffer + frame->m_offsets[0];
3582 tmppicture.data[1] = frame->m_buffer + frame->m_offsets[1];
3583 tmppicture.data[2] = frame->m_buffer + frame->m_offsets[2];
3584 tmppicture.linesize[0] = frame->m_pitches[0];
3585 tmppicture.linesize[1] = frame->m_pitches[1];
3586 tmppicture.linesize[2] = frame->m_pitches[2];
3590 AvFrame->height,
static_cast<AVPixelFormat
>(AvFrame->format),
3591 AvFrame->width, AvFrame->height,
3592 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
3593 nullptr,
nullptr,
nullptr);
3596 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate sws context");
3599 sws_scale(
m_swsCtx, AvFrame->data, AvFrame->linesize, 0, dim.height(),
3600 tmppicture.data, tmppicture.linesize);
3635 LOG(VB_GENERAL, LOG_ERR,
LOC +
"NULL videoframe - direct rendering not "
3636 "correctly initialized.");
3640 std::chrono::milliseconds
pts = 0ms;
3643 long long av_pts = AvFrame->pts;
3644 if (av_pts == AV_NOPTS_VALUE)
3645 av_pts = AvFrame->pkt_dts;
3646 if (av_pts == AV_NOPTS_VALUE)
3647 av_pts = AvFrame->reordered_opaque;
3648 if (av_pts == AV_NOPTS_VALUE)
3650 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process video.");
3658 std::chrono::milliseconds temppts =
pts;
3675 double calcfps = 1000.0 /
ptsdiff.count();
3676 if (calcfps < 121.0 && calcfps > 3.0)
3680 double fpschange = calcfps /
static_cast<double>(
m_fps);
3682 if (fpschange > 1.9 && fpschange < 2.1)
3684 if (fpschange > 0.9 && fpschange < 1.1)
3690 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3691 QString(
"video timecode %1 %2 %3 %4%5")
3693 .arg(
pts.count()).arg(temppts.count()).arg(
m_lastVPts.count())
3694 .arg((
pts != temppts) ?
" fixup" :
""));
3696 frame->m_interlaced = AvFrame->interlaced_frame;
3697 frame->m_topFieldFirst = AvFrame->top_field_first != 0;
3699 frame->m_repeatPic = AvFrame->repeat_pict != 0;
3704 frame->m_colorspace = AvFrame->colorspace;
3705 frame->m_colorrange = AvFrame->color_range;
3706 frame->m_colorprimaries = AvFrame->color_primaries;
3707 frame->m_colortransfer = AvFrame->color_trc;
3708 frame->m_chromalocation = AvFrame->chroma_location;
3709 frame->m_pixFmt = AvFrame->format;
3714 frame->m_dummy =
false;
3715 frame->m_pauseFrame =
false;
3716 frame->m_deinterlaceInuse2x =
false;
3717 frame->m_alreadyDeinterlaced =
false;
3718 frame->m_interlacedReverse =
false;
3748 [[maybe_unused]]
const AVStream *stream,
const AVPacket *pkt)
3750 const uint8_t *buf = pkt->data;
3751 uint64_t linemask = 0;
3756 if ((buf[0]==
't') && (buf[1]==
'v') && (buf[2] ==
'0'))
3759 memcpy(&linemask, buf + 3, 8);
3762 else if ((buf[0]==
'T') && (buf[1]==
'V') && (buf[2] ==
'0'))
3764 linemask = 0xffffffffffffffffLL;
3769 LOG(VB_VBI, LOG_ERR,
LOC + QString(
"Unknown VBI data stream '%1%2%3'")
3770 .arg(QChar(buf[0])).arg(QChar(buf[1])).arg(QChar(buf[2])));
3774 static constexpr
uint kMinBlank = 6;
3775 for (
uint i = 0; i < 36; i++)
3777 if (!((linemask >> i) & 0
x1))
3780 const uint line = ((i < 18) ? i : i-18) + kMinBlank;
3781 const uint field = (i<18) ? 0 : 1;
3782 const uint id2 = *buf & 0xf;
3792 StreamInfo si(pkt->stream_index, 0, 0, 0, 0);
3805 int data = (buf[2] << 8) | buf[1];
3832 const AVStream* ,
const AVPacket *pkt)
3841 const uint8_t *buf = pkt->data;
3842 const uint8_t *buf_end = pkt->data + pkt->size;
3844 if (*buf >= 0x10 && *buf <= 0x1F)
3850 LOG(VB_VBI, LOG_WARNING,
LOC +
3851 QString(
"VBI: Unknown data_identier: %1 discarded").arg(*buf));
3856 while (buf < buf_end)
3861 if ((buf_end - buf) >= 42)
3865 else if (*buf == 0x03)
3868 if ((buf_end - buf) >= 42)
3872 else if (*buf == 0xff)
3878 LOG(VB_VBI, LOG_WARNING,
LOC +
3879 QString(
"VBI: Unsupported data_unit_id: %1 discarded").arg(*buf));
3889 [[maybe_unused]]
const AVPacket *pkt)
3896 uint8_t *data = pkt->data;
3897 int length = pkt->size;
3898 int componentTag = 0;
3899 int dataBroadcastId = 0;
3900 unsigned carouselId = 0;
3903 componentTag = str->component_tag;
3904 dataBroadcastId = str->data_id;
3905 carouselId = (unsigned) str->carousel_id;
3910 uint16_t sectionLen = (((data[1] & 0xF) << 8) | data[2]) + 3;
3912 if (sectionLen > length)
3916 componentTag, carouselId,
3918 length -= sectionLen;
3921 #endif // USING_MHEG
3929 long long pts = pkt->pts;
3930 if (
pts == AV_NOPTS_VALUE)
3932 if (
pts == AV_NOPTS_VALUE)
3934 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process subtitle.");
3937 pts =
static_cast<long long>(av_q2d(curstream->time_base) *
pts * 1000);
3944 int gotSubtitles = 0;
3945 AVSubtitle subtitle;
3946 memset(&subtitle, 0,
sizeof(AVSubtitle));
3953 curstream->id,
pts);
3957 if (pkt->stream_index == subIdx)
3961 pkt->data, pkt->size,
pts);
3970 avcodec_decode_subtitle2(ctx, &subtitle, &gotSubtitles, pkt);
3973 subtitle.start_display_time +=
pts;
3974 subtitle.end_display_time +=
pts;
3981 for (
unsigned i = 0; i < subtitle.num_rects; i++)
3983 subtitle.rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
3986 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3987 QString(
"subtl timecode %1 %2 %3 %4")
3988 .arg(pkt->pts).arg(pkt->dts)
3989 .arg(subtitle.start_display_time)
3990 .arg(subtitle.end_display_time));
3993 subtitle, curstream->codecpar->codec_id == AV_CODEC_ID_XSUB,
4006 auto id =
static_cast<uint>(Packet->stream_index + 0x2000);
4010 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
4011 const auto * codec = QTextCodec::codecForName(
"utf-8");
4012 auto text = codec->toUnicode(
reinterpret_cast<const char *
>(Packet->data), Packet->size - 1);
4014 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
4015 QString text = toUtf16.decode(Packet->data);
4017 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
4018 auto list = text.split(
'\n', QString::SkipEmptyParts);
4020 auto list = text.split(
'\n', Qt::SkipEmptyParts);
4029 enum AVCodecID codec_id = curstream->codecpar->codec_id;
4033 case AV_CODEC_ID_MPEG2VBI:
4036 case AV_CODEC_ID_DVB_VBI:
4039 case AV_CODEC_ID_DSMCC_B:
4048 #endif // USING_MHEG:
4064 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio stream type " + msg +
"changed.");
4078 QString forcedString = forced ? QObject::tr(
" (forced)") :
"";
4080 int av_index =
m_tracks[
type][TrackNo].m_av_stream_index;
4081 AVStream *stream {
nullptr };
4082 if (av_index >= 0 && av_index < (
int)
m_ic->nb_streams)
4083 stream =
m_ic->streams[av_index];
4084 AVDictionaryEntry *entry =
4085 stream ? av_dict_get(stream->metadata,
"title",
nullptr, 0) :
nullptr;
4086 QString user_title = entry ? QString(R
"( "%1")").arg(entry->value) : "";
4098 AVCodecParameters *par = stream->codecpar;
4100 if (par->codec_id == AV_CODEC_ID_MP3)
4101 msg += QString(
" MP3");
4102 else if (ctx && ctx->codec)
4103 msg += QString(
" %1").arg(ctx->codec->name).toUpper();
4104 if (!user_title.isEmpty())
4112 msg += QString(
" ?ch");
4113 else if((channels > 4) && !(channels & 1))
4114 msg += QString(
" %1.1ch").arg(channels - 1);
4116 msg += QString(
" %1ch").arg(channels);
4126 if (!user_title.isEmpty())
4129 msg += QString(
" (%1)")
4133 return QString(
"%1: %2").arg(TrackNo + 1).arg(msg);
4137 return QObject::tr(
"Subtitle") + QString(
" %1: %2%3%4")
4138 .arg(QString::number(TrackNo + 1),
4166 return ctx ? QByteArray(
reinterpret_cast<char*
>(ctx->subtitle_header), ctx->subtitle_header_size) :
4177 AVDictionaryEntry *tag = av_dict_get(
m_ic->streams[index]->metadata,
"filename",
nullptr, 0);
4179 Filename = QByteArray(tag->value);
4180 AVCodecParameters *par =
m_ic->streams[index]->codecpar;
4181 Data = QByteArray(
reinterpret_cast<char*
>(par->extradata), par->extradata_size);
4191 if ((stream->component_tag == Tag) || ((Tag <= 0) && stream->component_tag <= 0))
4200 for (
uint i = 0; i <
m_ic->nb_streams; i++)
4202 AVStream *stream =
m_ic->streams[i];
4205 if (stream->component_tag == Tag)
4207 StreamInfo si(
static_cast<int>(i), 0, 0, 0, 0);
4229 const std::vector<int> &ftype)
4231 std::vector<int> ret;
4233 for (
int index : ftype)
4235 if ((lang_key < 0) || tracks[index].m_language == lang_key)
4236 ret.push_back(index);
4244 std::vector<int> ret;
4246 for (
size_t i = 0; i < tracks.size(); i++)
4248 if (tracks[i].m_audio_type ==
type)
4257 const std::vector<int>&fs,
4258 enum AVCodecID codecId,
4261 int selectedTrack = -1;
4266 const int stream_index = tracks[f].m_av_stream_index;
4267 AVCodecParameters *par = ic->streams[stream_index]->codecpar;
4268 if ((codecId == AV_CODEC_ID_NONE || codecId == par->codec_id) &&
4269 (max_seen < par->ch_layout.nb_channels))
4271 if (codecId == AV_CODEC_ID_DTS &&
profile > 0)
4278 max_seen = par->ch_layout.nb_channels;
4282 return selectedTrack;
4340 uint numStreams = atracks.size();
4341 if ((ctrack >= 0) && (ctrack < (
int)numStreams))
4346 for (
const auto & track : atracks)
4348 int idx = track.m_av_stream_index;
4349 AVCodecContext *codec_ctx =
m_ic->streams[idx]->codec;
4350 AudioInfo item(codec_ctx->codec_id, codec_ctx->bps,
4351 codec_ctx->sample_rate, codec_ctx->channels,
4357 int selTrack = (1 == numStreams) ? 0 : -1;
4362 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio sub-stream");
4368 for (
uint i = 0; i < numStreams; i++)
4370 if (atracks[i].m_av_substream_index == substream_index)
4378 if ((selTrack < 0) && wlang >= -1 && numStreams)
4380 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio track");
4385 for (
uint i = 0; i < numStreams; i++)
4387 if (wlang == atracks[i].m_language)
4391 if (windx == atracks[i].m_language_index)
4397 if (selTrack < 0 && numStreams)
4399 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select audio track (w/lang)");
4406 LOG(VB_AUDIO, LOG_WARNING,
"No audio tracks matched the type filter, "
4407 "so trying all tracks.");
4408 for (
int i = 0; i < static_cast<int>(atracks.size()); i++)
4417 std::vector<int> flang =
filter_lang(atracks, canonical_key, ftype);
4421 FF_PROFILE_DTS_HD_MA);
4425 if (selTrack < 0 && m_audio->CanDTSHD())
4427 FF_PROFILE_DTS_HD_HRA);
4451 FF_PROFILE_DTS_HD_MA);
4454 AV_CODEC_ID_TRUEHD);
4456 if (selTrack < 0 && m_audio->CanDTSHD())
4458 FF_PROFILE_DTS_HD_HRA);
4479 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select default track");
4480 for (
size_t i = 0; i < atracks.size(); i++) {
4481 int idx = atracks[i].m_av_stream_index;
4482 if (
m_ic->streams[idx]->disposition & AV_DISPOSITION_DEFAULT)
4493 LOG(VB_AUDIO, LOG_INFO,
LOC +
4494 "Trying to select audio track (wo/lang)");
4499 FF_PROFILE_DTS_HD_MA);
4503 if (selTrack < 0 && m_audio->CanDTSHD())
4505 FF_PROFILE_DTS_HD_HRA);
4524 if (ctrack != selTrack)
4526 LOG(VB_AUDIO, LOG_INFO,
LOC +
"No suitable audio track exists.");
4533 strack = atracks[selTrack];
4538 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Selected track %1 (A/V Stream #%2)")
4547 char *buffer,
int bufsize)
4558 const uint halfsample = samplesize >> 1;
4560 const char *from = (channel == 1) ? buffer + halfsample : buffer;
4561 char *to = (channel == 0) ? buffer + halfsample : buffer;
4564 (sample++), (from += samplesize), (to += samplesize))
4566 memmove(to, from, halfsample);
4576 bool firstloop =
true;
4577 int decoded_size = -1;
4584 AVPacket *tmp_pkt = av_packet_alloc();
4585 tmp_pkt->data = pkt->data;
4586 tmp_pkt->size = pkt->size;
4587 while (tmp_pkt->size > 0)
4589 bool reselectAudioTrack =
false;
4594 LOG(VB_AUDIO, LOG_INFO,
LOC +
4595 "Audio is disabled - trying to restart it");
4596 reselectAudioTrack =
true;
4601 bool wasDual = audSubIdx != -1;
4602 bool isDual = ctx->avcodec_dual_language != 0;
4603 if ((wasDual && !isDual) || (!wasDual && isDual))
4606 reselectAudioTrack =
true;
4611 bool already_decoded =
false;
4612 if (!ctx->ch_layout.nb_channels)
4624 AVChannelLayout channel_layout;
4626 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4628 if (ctx->codec_id == AV_CODEC_ID_AC3)
4633 decoded_size = data_size;
4634 already_decoded =
true;
4635 reselectAudioTrack |= ctx->ch_layout.nb_channels;
4639 if (reselectAudioTrack)
4649 if (!(decodetype &
kDecodeAudio) || (pkt->stream_index != audIdx)
4653 if (firstloop && pkt->pts != AV_NOPTS_VALUE)
4671 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
4672 QString(
"discarding early audio timecode %1 %2 %3")
4673 .arg(pkt->pts).arg(pkt->dts).arg(
m_lastAPts.count()));
4687 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Audio stream changed");
4690 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Number of audio channels changed from %1 to %2")
4702 if (!already_decoded)
4707 decoded_size = data_size;
4715 data_size = tmp_pkt->size;
4721 if (!already_decoded)
4725 AVChannelLayout channel_layout;
4727 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4731 decoded_size = data_size;
4738 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown audio decoding error");
4739 av_packet_free(&tmp_pkt);
4745 tmp_pkt->data += ret;
4746 tmp_pkt->size -= ret;
4750 std::chrono::milliseconds temppts =
m_lastAPts;
4757 int frames = (ctx->ch_layout.nb_channels <= 0 || decoded_size < 0 || !samplesize) ? -1 :
4758 decoded_size / (ctx->ch_layout.nb_channels * samplesize);
4767 ((
double)(frames * 1000) / ctx->sample_rate);
4770 LOG(VB_TIMESTAMP, LOG_INFO,
LOC + QString(
"audio timecode %1 %2 %3 %4")
4771 .arg(pkt->pts).arg(pkt->dts).arg(temppts.count()).arg(
m_lastAPts.count()));
4776 tmp_pkt->data += ret;
4777 tmp_pkt->size -= ret;
4781 av_packet_free(&tmp_pkt);
4788 AVPacket *pkt =
nullptr;
4789 bool have_err =
false;
4791 const DecodeType origDecodetype = decodetype;
4799 bool storevideoframes =
false;
4868 storevideoframes =
true;
4874 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4875 QString(
"Audio %1 ms behind video but already %2 "
4876 "video frames queued. AV-Sync might be broken.")
4887 av_packet_free(&pkt);
4893 pkt = av_packet_alloc();
4898 if (retval == -EAGAIN)
4902 av_packet_free(&pkt);
4903 std::string errbuf(256,
'\0');
4906 errmsg = QString::fromStdString(errbuf);
4910 LOG(VB_GENERAL, LOG_ERR, QString(
"decoding error %1 (%2)")
4911 .arg(errmsg).arg(retval));
4924 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No context");
4925 av_packet_unref(pkt);
4929 if (pkt->stream_index >= (
int)
m_ic->nb_streams)
4931 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream");
4932 av_packet_unref(pkt);
4936 AVStream *curstream =
m_ic->streams[pkt->stream_index];
4940 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream (NULL)");
4941 av_packet_unref(pkt);
4945 enum AVMediaType codec_type = curstream->codecpar->codec_type;
4947 if (storevideoframes && codec_type == AVMEDIA_TYPE_VIDEO)
4955 if (codec_type == AVMEDIA_TYPE_VIDEO &&
4965 av_packet_free(&pkt);
4970 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4971 curstream->codecpar->codec_id == AV_CODEC_ID_TEXT)
4974 av_packet_unref(pkt);
4978 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4979 curstream->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT)
4982 av_packet_unref(pkt);
4986 if (codec_type == AVMEDIA_TYPE_DATA)
4989 av_packet_unref(pkt);
4996 if (codec_type != AVMEDIA_TYPE_VIDEO)
4998 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
4999 QString(
"No codec for stream index %1, type(%2) id(%3:%4)")
5000 .arg(pkt->stream_index)
5002 avcodec_get_name(curstream->codecpar->codec_id))
5003 .arg(curstream->codecpar->codec_id));
5008 av_packet_unref(pkt);
5016 case AVMEDIA_TYPE_AUDIO:
5025 case AVMEDIA_TYPE_VIDEO:
5032 if (pkt->pts != AV_NOPTS_VALUE)
5035 (av_q2d(curstream->time_base)*pkt->pts*1000000);
5050 case AVMEDIA_TYPE_SUBTITLE:
5059 LOG(VB_GENERAL, LOG_ERR,
LOC +
5060 QString(
"Decoding - id(%1) type(%2)")
5061 .arg(avcodec_get_name(ctx->codec_id),
5068 if (!have_err && !Retry)
5070 av_packet_unref(pkt);
5075 av_packet_free(&pkt);
5083 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"StreamChangeCheck skip SeekReset"));
5093 int result = av_read_frame(ctx, pkt);
5100 if (ic && ic->pmt_section)
5103 if (!pmt_buffer.has_buffer())
5162 if (stream < 0 || !
m_ic)
5164 return avcodec_get_name(
m_ic->streams[stream]->codecpar->codec_id);
5178 QString msg = (disable) ?
"Disabling" :
"Allowing";
5179 LOG(VB_AUDIO, LOG_INFO,
LOC + msg +
" pass through");
5202 switch (ctx->codec_id)
5204 case AV_CODEC_ID_AC3:
5205 case AV_CODEC_ID_TRUEHD:
5206 case AV_CODEC_ID_EAC3:
5207 case AV_CODEC_ID_MLP:
5208 case AV_CODEC_ID_DTS:
5217 bool passthru =
false;
5221 if (!withProfile && par->codec_id == AV_CODEC_ID_DTS && !
m_audio->
CanDTSHD())
5224 par->codec_id, FF_PROFILE_DTS);
5229 par->codec_id, par->profile);
5245 AVStream *curstream =
nullptr;
5246 AVCodecContext *ctx =
nullptr;
5248 int requested_channels = 0;
5252 (
int)
m_ic->nb_streams) &&
5254 .m_av_stream_index]) &&
5259 ctx->bits_per_raw_sample);
5261 if (av_sample_fmt_is_planar(ctx->sample_fmt))
5263 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Audio data is planar"));
5268 int bps = av_get_bytes_per_sample(ctx->sample_fmt) << 3;
5269 if (ctx->sample_fmt == AV_SAMPLE_FMT_S32 &&
5270 ctx->bits_per_raw_sample)
5271 bps = ctx->bits_per_raw_sample;
5272 LOG(VB_GENERAL, LOG_ERR,
LOC +
5273 QString(
"Unsupported sample format with %1 bits").arg(bps));
5277 bool using_passthru =
DoPassThrough(curstream->codecpar,
false);
5279 requested_channels = ctx->ch_layout.nb_channels;
5281 if (!using_passthru &&
5287 AVChannelLayout channel_layout;
5288 av_channel_layout_default(&channel_layout, requested_channels);
5289 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
5292 info =
AudioInfo(ctx->codec_id, fmt, ctx->sample_rate,
5293 requested_channels, using_passthru, ctx->ch_layout.nb_channels,
5294 ctx->codec_id == AV_CODEC_ID_DTS ? ctx->profile : 0);
5300 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No codec context. Returning false");
5307 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Initializing audio parms from " +
5312 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio format changed " +
5313 QString(
"\n\t\t\tfrom %1 to %2")
5329 switch (ctx->codec_id)
5331 case AV_CODEC_ID_MP2:
5334 case AV_CODEC_ID_MP3:
5337 case AV_CODEC_ID_AC3:
5340 case AV_CODEC_ID_DTS:
5343 case AV_CODEC_ID_VORBIS:
5346 case AV_CODEC_ID_WMAV1:
5349 case AV_CODEC_ID_WMAV2:
5357 lcd->setAudioFormatLEDs(audio_format,
true);
5392 int64_t start_time = INT64_MAX;
5393 int64_t end_time = INT64_MIN;
5394 AVStream *st =
nullptr;
5396 for (
uint i = 0; i < ic->nb_streams; i++)
5398 AVStream *st1 = ic->streams[i];
5399 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5408 int64_t duration = INT64_MIN;
5409 if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
5410 int64_t start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
5411 if (start_time1 < start_time)
5412 start_time = start_time1;
5413 if (st->duration != AV_NOPTS_VALUE) {
5414 int64_t end_time1 = start_time1 +
5415 av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5416 if (end_time1 > end_time)
5417 end_time = end_time1;
5420 if (st->duration != AV_NOPTS_VALUE) {
5421 int64_t duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5422 if (duration1 > duration)
5423 duration = duration1;
5425 if (start_time != INT64_MAX) {
5426 ic->start_time = start_time;
5427 if (end_time != INT64_MIN) {
5428 if (end_time - start_time > duration)
5429 duration = end_time - start_time;
5432 if (duration != INT64_MIN) {
5433 int64_t filesize = 0;
5434 ic->duration = duration;
5435 if (ic->pb && (filesize = avio_size(ic->pb)) > 0) {
5437 ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
5438 (
double)ic->duration;