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 #include <QtAndroidExtras>
59 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
62 #include <QStringDecoder>
75 #include "libmythbase/mythconfig.h"
104 # ifdef AV_TIME_BASE_Q
105 # undef AV_TIME_BASE_Q
107 #define AV_TIME_BASE_Q GetAVTimeBaseQ()
109 __inline AVRational GetAVTimeBaseQ()
111 AVRational av = {1, AV_TIME_BASE};
116 #define LOC QString("AFD: ")
126 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
136 return {ctx.width >> ctx.lowres, ctx.height >> ctx.lowres};
140 float aspect_ratio = 0.0F;
142 if (ctx.sample_aspect_ratio.num && ctx.height)
144 aspect_ratio = av_q2d(ctx.sample_aspect_ratio) *
145 static_cast<double>(ctx.width);
146 aspect_ratio /= (float) ctx.height;
149 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
152 aspect_ratio = (float)ctx.width / (
float)ctx.height;
154 aspect_ratio = 4.0F / 3.0F;
161 static constexpr
float kDefaultAspect = 4.0F / 3.0F;
162 int asp =
p.aspectRatio();
165 case 0:
return kDefaultAspect;
166 case 2:
return 4.0F / 3.0F;
167 case 3:
return 16.0F / 9.0F;
168 case 4:
return 2.21F;
172 float aspect_ratio = asp * 0.000001F;
173 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
175 if (
p.pictureHeight() &&
p.pictureWidth())
178 (float)
p.pictureWidth() /(float)
p.pictureHeight();
182 aspect_ratio = kDefaultAspect;
206 #define FAIL(errmsg) do { \
207 LOG(VB_PLAYBACK, LOG_INFO, LOC + (errmsg)); \
218 switch (Stream->codecpar->codec_type)
222 case AVMEDIA_TYPE_VIDEO:
224 FAIL(
"No codec for video stream");
225 if (!Stream->codecpar->width || !Stream->codecpar->height)
226 FAIL(
"Unspecified video size");
227 if (Stream->codecpar->format == AV_PIX_FMT_NONE)
228 FAIL(
"Unspecified video pixel format");
235 case AVMEDIA_TYPE_AUDIO:
237 FAIL(
"No codec for audio stream");
255 case AVMEDIA_TYPE_SUBTITLE:
256 if (Stream->codecpar->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !Stream->codecpar->width)
257 FAIL(
"Unspecified subtitle size");
259 case AVMEDIA_TYPE_DATA:
260 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
267 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
268 FAIL(
"Unknown codec");
272 static void myth_av_log(
void *ptr,
int level,
const char* fmt, va_list vl)
280 static QString s_fullLine(
"");
281 static QMutex s_stringLock;
282 uint64_t verbose_mask = VB_LIBAV;
283 LogLevel_t verbose_level = LOG_EMERG;
289 verbose_level = LOG_EMERG;
290 verbose_mask |= VB_GENERAL;
293 verbose_level = LOG_CRIT;
294 verbose_mask |= VB_GENERAL;
297 verbose_level = LOG_ERR;
300 verbose_level = LOG_WARNING;
303 verbose_level = LOG_INFO;
308 verbose_level = LOG_DEBUG;
318 if (s_fullLine.isEmpty() && ptr) {
319 AVClass* avc = *(AVClass**)ptr;
320 s_fullLine = QString(
"[%1 @ %2] ")
321 .arg(avc->item_name(ptr))
322 .arg((quintptr)avc, QT_POINTER_SIZE * 2, 16, QChar(
'0'));
325 s_fullLine += QString::vasprintf(fmt, vl);
326 if (s_fullLine.endsWith(
"\n"))
328 LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
329 s_fullLine.truncate(0);
331 s_stringLock.unlock();
336 if (lang_cstr[0] ==
'\0' || lang_cstr[1] ==
'\0')
340 if (lang_cstr[2] ==
'\0')
342 QString tmp2 = lang_cstr;
360 case AVMEDIA_TYPE_UNKNOWN:
return "Unknown";
361 case AVMEDIA_TYPE_VIDEO:
return "Video";
362 case AVMEDIA_TYPE_AUDIO:
return "Audio";
363 case AVMEDIA_TYPE_DATA:
return "Data";
364 case AVMEDIA_TYPE_SUBTITLE:
return "Subtitle";
365 case AVMEDIA_TYPE_ATTACHMENT:
return "Attachment";
366 default:
return "Invalid Codec Type";
376 m_playerFlags(flags),
396 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"PlayerFlags: 0x%1, AudioReadAhead: %2 msec")
405 av_packet_free(&pkt);
423 lcd->setAudioFormatLEDs(
AUDIO_AC3,
false);
424 lcd->setVideoFormatLEDs(
VIDEO_MPG,
false);
441 for (
uint i = 0; i <
m_ic->nb_streams; i++)
443 AVStream *st =
m_ic->streams[i];
456 av_free(
m_ic->pb->buffer);
458 avformat_close_input(&
m_ic);
464 static int64_t
lsb3full(int64_t lsb, int64_t base_ts,
int lsb_bits)
466 int64_t mask = (lsb_bits < 64) ? (1LL<<lsb_bits)-1 : -1LL;
467 return ((lsb - base_ts)&mask);
472 int64_t start_pts = 0;
474 AVStream *st =
nullptr;
475 for (
uint i = 0; i <
m_ic->nb_streams; i++)
477 AVStream *st1 =
m_ic->streams[i];
478 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
487 if (
m_ic->start_time != AV_NOPTS_VALUE)
489 start_pts = av_rescale(
m_ic->start_time,
491 AV_TIME_BASE * (int64_t)st->time_base.num);
494 int64_t
pts = av_rescale(timecode.count() / 1000.0,
505 std::chrono::milliseconds timecode)
507 int64_t start_pts = 0;
509 if (
m_ic->start_time != AV_NOPTS_VALUE)
511 start_pts = av_rescale(
m_ic->start_time,
513 AV_TIME_BASE * (int64_t)st->time_base.num);
516 int64_t
pts = av_rescale(timecode.count() / 1000.0,
529 return m_ic->nb_chapters;
539 for (
int i = 0; i < total; i++)
541 int num =
m_ic->chapters[i]->time_base.num;
542 int den =
m_ic->chapters[i]->time_base.den;
543 int64_t start =
m_ic->chapters[i]->start;
544 long double total_secs = (
long double)start * (
long double)num /
546 times.push_back(std::chrono::seconds((
long long)total_secs));
555 for (
int i = (
m_ic->nb_chapters - 1); i > -1 ; i--)
557 int num =
m_ic->chapters[i]->time_base.num;
558 int den =
m_ic->chapters[i]->time_base.den;
559 int64_t start =
m_ic->chapters[i]->start;
560 long double total_secs = (
long double)start * (
long double)num /
562 auto framenum = (
long long)(total_secs *
m_fps);
563 if (framesPlayed >= framenum)
565 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
566 QString(
"GetCurrentChapter(selected chapter %1 framenum %2)")
567 .arg(i + 1).arg(framenum));
579 int num =
m_ic->chapters[chapter - 1]->time_base.num;
580 int den =
m_ic->chapters[chapter - 1]->time_base.den;
581 int64_t start =
m_ic->chapters[chapter - 1]->start;
582 long double total_secs = (
long double)start * (
long double)num /
584 auto framenum = (
long long)(total_secs *
m_fps);
585 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"GetChapter %1: framenum %2")
586 .arg(chapter).arg(framenum));
592 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"DoRewind(%1, %2 discard frames)")
593 .arg(desiredFrame).arg( discardFrames ?
"do" :
"don't" ));
606 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
607 QString(
"DoFastForward(%1 (%2), %3 discard frames)")
609 .arg((discardFrames) ?
"do" :
"don't"));
620 if (seekDelta >= 0 && seekDelta < 2 && !m_doRewind && m_parent->GetPlaySpeed() == 0.0F)
629 if (
m_ic->start_time != AV_NOPTS_VALUE)
630 ts =
m_ic->start_time;
633 long double seekts = desiredFrame * AV_TIME_BASE /
m_fps;
634 ts += (
long long)seekts;
639 int flags = (
m_doRewind || exactseeks) ? AVSEEK_FLAG_BACKWARD : 0;
641 if (av_seek_frame(
m_ic, -1, ts, flags) < 0)
643 LOG(VB_GENERAL, LOG_ERR,
LOC +
644 QString(
"av_seek_frame(ic, -1, %1, 0) -- error").arg(ts));
649 int normalframes = 0;
671 bool doflush,
bool discardFrames)
676 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
677 QString(
"SeekReset(%1, %2, %3 flush, %4 discard)")
678 .arg(newKey).arg(skipFrames)
679 .arg((doflush) ?
"do" :
"don't",
680 (discardFrames) ?
"do" :
"don't"));
705 avformat_flush(
m_ic);
712 m_ic->pb->buf_ptr =
m_ic->pb->buffer;
713 m_ic->pb->buf_end =
m_ic->pb->buffer;
714 m_ic->pb->eof_reached = 0;
718 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SeekReset() flushing");
719 for (
uint i = 0; i <
m_ic->nb_streams; i++)
725 if (enc && enc->internal)
726 avcodec_flush_buffers(enc);
733 av_packet_free(&pkt);
755 static constexpr std::chrono::milliseconds maxSeekTimeMs { 200ms };
756 int profileFrames = 0;
758 for (; (skipFrames > 0 && !
m_atEof &&
759 (exactSeeks || begin.
elapsed() < maxSeekTimeMs));
760 --skipFrames, ++profileFrames)
764 QElapsedTimer getframetimer;
765 getframetimer.start();
767 while (retry && !getframetimer.hasExpired(100))
772 std::this_thread::sleep_for(1ms);
780 if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
782 const int giveUpPredictionMs = 400;
783 int remainingTimeMs =
784 skipFrames * (float)begin.
elapsed().count() / profileFrames;
785 if (remainingTimeMs > giveUpPredictionMs)
787 LOG(VB_PLAYBACK, LOG_DEBUG,
788 QString(
"Frame-by-frame seeking would take "
789 "%1 ms to finish, skipping.").arg(remainingTimeMs));
806 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
807 QString(
"Resetting byte context eof (livetv %1 was eof %2)")
809 m_ic->pb->eof_reached = 0;
817 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
818 QString(
"Reset: Video %1, Seek %2, File %3")
819 .arg(reset_video_data).arg(seek_reset).arg(reset_file));
826 if (reset_video_data)
836 memset(&probe, 0,
sizeof(AVProbeData));
838 QByteArray fname =
filename.toLatin1();
839 probe.filename = fname.constData();
840 probe.buf = (
unsigned char *)testbuf.data();
841 probe.buf_size = testbuf.size();
843 int score = AVPROBE_SCORE_MAX/4;
855 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
857 return av_probe_input_format2(&probe,
static_cast<int>(
true), &score) !=
nullptr;
869 auto *buffer = (
unsigned char *)av_malloc(buf_size);
870 m_ic->pb = avio_alloc_context(buffer, buf_size, 0,
877 m_ic->pb->seekable =
static_cast<int>(!streamed || forceseek);
878 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Buffer size: %1 Streamed %2 Seekable %3 Available %4")
886 int cnt = decoder->
m_ic->nb_streams;
888 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
889 QString(
"streams_changed 0x%1 -- stream count %2")
890 .arg((uint64_t)data,0,16).arg(cnt));
892 decoder->m_streamsChanged =
true;
898 int retval = avformat_find_stream_info(
m_ic,
nullptr);
939 const AVInputFormat *fmt =
nullptr;
941 QByteArray fnamea = fnames.toLatin1();
942 const char *
filename = fnamea.constData();
945 memset(&probe, 0,
sizeof(AVProbeData));
947 probe.buf =
reinterpret_cast<unsigned char *
>(testbuf.data());
949 probe.buf_size = testbuf.size();
952 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
954 fmt = av_probe_input_format(&probe,
static_cast<int>(
true));
957 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Probe failed for '%1'").arg(
filename));
961 if (strcmp(fmt->name,
"mpegts") == 0 &&
964 const AVInputFormat *fmt2 = av_find_input_format(
"mpegts-ffmpeg");
968 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using FFmpeg MPEG-TS demuxer (forced)");
973 bool scancomplete =
false;
974 int remainingscans = 5;
976 while (!scancomplete && remainingscans--)
990 while (!found && --retries)
992 m_ic = avformat_alloc_context();
995 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Could not allocate format context.");
1002 err = avformat_open_input(&
m_ic,
filename, fmt,
nullptr);
1006 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Failed to open input ('%1')")
1014 QThread::usleep(100000);
1020 if (strcmp(fmt->name,
"mpegts") == 0)
1022 fmt = av_find_input_format(
"mpegts-ffmpeg");
1025 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to use original FFmpeg MPEG-TS demuxer.");
1038 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error opening input. Aborting");
1050 m_ic->max_analyze_duration = 60LL * AV_TIME_BASE;
1056 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Could not find codec parameters for '%1'").arg(
filename));
1063 scancomplete =
true;
1068 scancomplete =
false;
1072 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stream scan incomplete - retrying");
1073 QThread::usleep(250000);
1081 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Scan incomplete - playback may not work");
1084 m_ic->stream_change_data =
this;
1096 QString extension = QFileInfo(fnames).suffix();
1097 if (strcmp(fmt->name,
"mp3") == 0 || strcmp(fmt->name,
"flac") == 0 ||
1098 strcmp(fmt->name,
"ogg") == 0 ||
1099 (extension.compare(
"m4a", Qt::CaseInsensitive) == 0))
1116 int initialAudio = -1;
1117 int initialVideo = -1;
1120 if (initialAudio >= 0)
1122 if (initialVideo >= 0)
1125 #endif // USING_MHEG
1143 std::chrono::seconds dur = 0s;
1152 dur = duration_cast<std::chrono::seconds>(av_duration(
m_ic->duration));
1163 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1164 "Recording has no position -- using libavformat seeking.");
1173 float bytespersec = (float)
m_bitrate / 8 / 2;
1176 (int)(secs *
static_cast<float>(
m_fps)));
1185 if (strcmp(fmt->name,
"avi") == 0)
1198 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Position map found");
1200 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Partial position map found");
1201 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1202 QString(
"Successfully opened decoder for file: \"%1\". novideo(%2)")
1206 for (
unsigned int i=0; i <
m_ic->nb_chapters; i++)
1208 int num =
m_ic->chapters[i]->time_base.num;
1209 int den =
m_ic->chapters[i]->time_base.den;
1210 int64_t start =
m_ic->chapters[i]->start;
1211 auto total_secs =
static_cast<long double>(start) *
static_cast<long double>(num) /
1212 static_cast<long double>(den);
1214 auto framenum =
static_cast<long long>(total_secs *
static_cast<long double>(
m_fps));
1215 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1216 QString(
"Chapter %1 found @ [%2]->%3")
1219 QString::number(framenum)));
1222 if (qEnvironmentVariableIsSet(
"FORCE_DTS_TIMESTAMPS"))
1235 Reset(
true,
true,
true);
1249 double avg_fps = (Stream->avg_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->avg_frame_rate);
1250 double codec_fps = av_q2d(Context->framerate);
1251 double container_fps = (Stream->time_base.num == 0) ? 0.0 : av_q2d(av_inv_q(Stream->time_base));
1253 double estimated_fps = (Stream->r_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->r_frame_rate);
1256 std::vector<double> rates;
1261 if (QString(
m_ic->iformat->name).contains(
"matroska") ||
1262 QString(
m_ic->iformat->name).contains(
"mov"))
1264 rates.emplace_back(avg_fps);
1268 if (QString(
m_ic->iformat->name).contains(
"avi"))
1270 rates.emplace_back(container_fps);
1273 rates.emplace_back(codec_fps);
1274 rates.emplace_back(container_fps);
1275 rates.emplace_back(avg_fps);
1277 rates.emplace_back(estimated_fps);
1279 rates.emplace_back(30000.0 / 1001.0);
1281 auto invalid_fps = [](
double rate) {
return rate < 3.0 || rate > 121.0; };
1282 rates.erase(std::remove_if(rates.begin(), rates.end(), invalid_fps), rates.end());
1284 auto FuzzyEquals = [](
double First,
double Second) {
return std::abs(First - Second) < 0.03; };
1287 if (!FuzzyEquals(rates.front(),
m_fps))
1289 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1290 QString(
"Selected FPS: %1 (Avg:%2 Mult:%3 Codec:%4 Container:%5 Estimated:%6)")
1291 .arg(
static_cast<double>(rates.front())).arg(avg_fps)
1292 .arg(
m_fpsMultiplier).arg(codec_fps).arg(container_fps).arg(estimated_fps));
1295 auto IsStandard = [&FuzzyEquals](
double Rate)
1298 static const std::set<double> k_standard_rates =
1317 if (Rate > 23.0 && Rate < 121.0)
1319 for (
auto standard_rate : k_standard_rates)
1320 if (FuzzyEquals(Rate, standard_rate))
1329 double detected = rates.front();
1330 if (Sanitise && !IsStandard(detected))
1332 for (
auto rate : rates)
1334 if (IsStandard(rate))
1336 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 is non-standard - using %2 instead.")
1337 .arg(rates.front()).arg(rate));
1345 if (rate > 33.0 && detected < 33.0)
1347 double half = rate / 2.0;
1348 if (std::abs(half - detected) < (half * 0.1))
1350 LOG(VB_GENERAL, LOG_INFO,
LOC +
1351 QString(
"Assuming %1 is a better choice than %2")
1352 .arg(half).arg(rate));
1353 return static_cast<float>(half);
1356 return static_cast<float>(rate);
1361 return static_cast<float>(detected);
1367 const enum AVPixelFormat *);
1370 const enum AVPixelFormat *valid_fmts)
1375 static uint8_t *dummy[1] = {
nullptr };
1376 avctx->hwaccel_context =
1377 (dxva_context*)nd->
GetPlayer()->GetDecoderContext(
nullptr, dummy[0]);
1380 while (*valid_fmts != AV_PIX_FMT_NONE) {
1381 if (avctx->hwaccel_context and (*valid_fmts == AV_PIX_FMT_DXVA2_VLD))
1382 return AV_PIX_FMT_DXVA2_VLD;
1383 if (not avctx->hwaccel_context and (*valid_fmts == AV_PIX_FMT_YUV420P))
1384 return AV_PIX_FMT_YUV420P;
1387 return AV_PIX_FMT_NONE;
1393 switch (Context->codec_id)
1395 case AV_CODEC_ID_H264:
1398 if (Context->extradata && (Context->extradata_size >= 7))
1401 if (Context->extradata[0] == 1)
1403 else if (AV_RB24(Context->extradata) == 0x01)
1405 else if (
AV_RB32(Context->extradata) == 0x01)
1412 parser.parse_SPS(Context->extradata + offset,
1413 static_cast<uint>(Context->extradata_size - offset), dummy, result);
1418 case AV_CODEC_ID_H265:
return 16;
1419 case AV_CODEC_ID_VP9:
return 8;
1420 case AV_CODEC_ID_VP8:
return 3;
1426 bool selectedStream)
1428 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1429 QString(
"InitVideoCodec ID:%1 Type:%2 Size:%3x%4")
1430 .arg(avcodec_get_name(enc->codec_id),
1432 .arg(enc->width).arg(enc->height));
1437 enc->opaque =
static_cast<void*
>(
this);
1439 enc->slice_flags = 0;
1441 enc->err_recognition = AV_EF_COMPLIANT;
1442 enc->workaround_bugs = FF_BUG_AUTODETECT;
1443 enc->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
1444 enc->idct_algo = FF_IDCT_AUTO;
1448 const AVCodec *codec1 = enc->codec;
1454 uint8_t* displaymatrix = av_stream_get_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX,
nullptr);
1456 m_videoRotation =
static_cast<int>(-av_display_rotation_get(
reinterpret_cast<int32_t*
>(displaymatrix)));
1461 uint8_t* stereo3d = av_stream_get_side_data(stream, AV_PKT_DATA_STEREO3D,
nullptr);
1464 auto * avstereo =
reinterpret_cast<AVStereo3D*
>(stereo3d);
1489 bool doublerate =
true;
1493 if (codec1 && ((AV_CODEC_ID_MPEG2VIDEO == codec1->id) ||
1494 (AV_CODEC_ID_MPEG1VIDEO == codec1->id)))
1498 int total_blocks = (enc->height + 15) / 16;
1499 enc->skip_top = (total_blocks + 3) / 4;
1500 enc->skip_bottom = (total_blocks + 3) / 4;
1508 enc->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
1509 enc->skip_loop_filter = AVDISCARD_ALL;
1513 enc->skip_idct = AVDISCARD_ALL;
1525 if (!width || !height)
1527 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1528 "InitVideoCodec invalid dimensions, resetting decoder.");
1536 const AVCodec *codec2 = enc->codec;
1539 codecName = codec2->name;
1547 switch (enc->codec_id)
1549 case AV_CODEC_ID_H263:
1550 case AV_CODEC_ID_MPEG4:
1551 case AV_CODEC_ID_MSMPEG4V1:
1552 case AV_CODEC_ID_MSMPEG4V2:
1553 case AV_CODEC_ID_MSMPEG4V3:
1554 case AV_CODEC_ID_H263P:
1555 case AV_CODEC_ID_H263I:
1558 case AV_CODEC_ID_WMV1:
1559 case AV_CODEC_ID_WMV2:
1563 case AV_CODEC_ID_XVID:
1572 lcd->setVideoFormatLEDs(video_format,
true);
1584 static constexpr std::array<uint8_t, 256> odd_parity_LUT
1586 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1587 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1588 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1589 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1590 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1591 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1592 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1593 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1594 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1595 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
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 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1600 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1601 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1603 bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
1604 (odd_parity_LUT[(data & 0xff00) >> 8] == 1);
1607 LOG(VB_VBI, LOG_ERR,
LOC +
1608 QString(
"VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
1622 if (!
m_ic->pmt_section)
1624 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1625 "ScanATSCCaptionStreams() called with no PMT");
1630 if (!pmt_buffer.has_buffer())
1636 bool video_found =
false;
1660 desc_list.insert(desc_list.end(), desc_list2.begin(), desc_list2.end());
1662 for (
auto & desc : desc_list)
1707 std::array<std::map<int,uint>,2> lang_cc_cnt;
1724 else if (!pofr && sofr)
1750 LOG(VB_GENERAL, LOG_ERR,
LOC +
"in_tracks key too small");
1756 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1757 QString(
"%1 caption service #%2 is in the %3 language.")
1758 .arg((
type) ?
"EIA-708" :
"EIA-608")
1773 if (!pmt_buffer.has_buffer())
1788 for (
const auto *desc : desc_list)
1801 int lang_idx = (magazine << 8) | pagenum;
1802 StreamInfo si(av_index, language, lang_idx, 0, 0);
1808 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1809 QString(
"Teletext stream #%1 (%2) is in the %3 language"
1811 .arg(QString::number(k),
1812 (
type == 2) ?
"Caption" :
"Menu",
1814 QString::number(magazine),
1815 QString::number(pagenum)));
1830 AVDictionaryEntry *metatag =
1831 av_dict_get(
m_ic->streams[av_stream_index]->metadata,
"language",
nullptr,
1833 bool forced = (
m_ic->streams[av_stream_index]->disposition & AV_DISPOSITION_FORCED) != 0;
1836 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1837 QString(
"Text Subtitle track #%1 is A/V stream #%2 "
1838 "and is in the %3 language(%4), forced=%5.")
1841 StreamInfo si(av_stream_index, lang, 0, 0, 0,
false,
false, forced);
1858 if (!pmt_buffer.has_buffer())
1869 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams Found Object Carousel in Stream %1").arg(QString::number(i)));
1875 for (
const auto *desc : desc_list)
1878 uint length = *desc++;
1879 const unsigned char *endDesc = desc+length;
1880 uint dataBroadcastId = desc[0]<<8 | desc[1];
1881 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams dataBroadcastId %1").arg(QString::number(dataBroadcastId)));
1882 if (dataBroadcastId != 0x0106)
1885 while (desc != endDesc)
1887 uint appTypeCode = desc[0]<<8 | desc[1];
1889 uint appSpecDataLen = *desc++;
1891 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams AppTypeCode %1").arg(QString::number(appTypeCode)));
1892 if (appTypeCode == 0x101)
1894 const unsigned char *subDescEnd = desc + appSpecDataLen;
1895 while (desc < subDescEnd)
1897 uint sub_desc_tag = *desc++;
1898 uint sub_desc_len = *desc++;
1900 if (sub_desc_tag == 1)
1902 desc += sub_desc_len;
1908 #endif // USING_MHEG
1910 desc += appSpecDataLen;
1922 bool unknownbitrate =
false;
1939 std::map<int,uint> lang_sub_cnt;
1940 uint subtitleStreamCount = 0;
1941 std::map<int,uint> lang_aud_cnt;
1942 uint audioStreamCount = 0;
1951 if (
m_ic ==
nullptr)
1954 for (
uint strm = 0; strm <
m_ic->nb_streams; strm++)
1956 AVCodecParameters *par =
m_ic->streams[strm]->codecpar;
1957 AVCodecContext *enc =
nullptr;
1960 if (par->codec_type == AVMEDIA_TYPE_VIDEO)
1961 codectype += QString(
"(%1x%2)").arg(par->width).arg(par->height);
1962 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1963 QString(
"Stream #%1: ID: 0x%2 Codec ID: %3 Type: %4 Bitrate: %5")
1964 .arg(strm).arg(
static_cast<uint64_t
>(
m_ic->streams[strm]->id), 0, 16)
1965 .arg(avcodec_get_name(par->codec_id),
1966 codectype).arg(par->bit_rate));
1968 switch (par->codec_type)
1970 case AVMEDIA_TYPE_VIDEO:
1978 if (ctx && (ctx->hw_frames_ctx || ctx->hw_device_ctx))
1985 LOG(VB_GENERAL, LOG_ERR,
LOC +
1986 QString(
"Stream #%1 has an unknown video "
1987 "codec id, skipping.").arg(strm));
1999 if (par->bit_rate == 0)
2001 static constexpr int64_t s_baseBitrate { 1000000LL };
2003 if (par->width && par->height)
2005 static const int s_baseSize = 1920 * 1080;
2006 multiplier = ((par->width * par->height) + s_baseSize - 1) / s_baseSize;
2010 par->bit_rate = s_baseBitrate * multiplier;
2011 unknownbitrate =
true;
2017 case AVMEDIA_TYPE_AUDIO:
2020 if (enc && enc->internal)
2022 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2023 QString(
"Warning, audio codec 0x%1 id(%2) "
2024 "type (%3) already open, leaving it alone.")
2025 .arg(
reinterpret_cast<unsigned long long>(enc), 0, 16)
2026 .arg(avcodec_get_name(enc->codec_id),
2029 LOG(VB_GENERAL, LOG_INFO,
LOC +
2030 QString(
"codec %1 has %2 channels")
2031 .arg(avcodec_get_name(par->codec_id))
2032 .arg(par->ch_layout.nb_channels));
2037 case AVMEDIA_TYPE_SUBTITLE:
2039 if (par->codec_id == AV_CODEC_ID_DVB_TELETEXT)
2041 if (par->codec_id == AV_CODEC_ID_TEXT)
2045 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"subtitle codec (%1)")
2049 case AVMEDIA_TYPE_DATA:
2053 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"data codec (%1)")
2057 case AVMEDIA_TYPE_ATTACHMENT:
2059 if (par->codec_id == AV_CODEC_ID_TTF)
2061 static_cast<int>(strm), 0, 0,
m_ic->streams[strm]->id, 0);
2063 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2064 QString(
"Attachment codec (%1)")
2071 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
2072 QString(
"Unknown codec type (%1)")
2078 if (par->codec_type != AVMEDIA_TYPE_AUDIO &&
2079 par->codec_type != AVMEDIA_TYPE_SUBTITLE)
2083 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2084 (par->codec_id == AV_CODEC_ID_DVB_TELETEXT ||
2085 par->codec_id == AV_CODEC_ID_TEXT))
2088 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Looking for decoder for %1")
2089 .arg(avcodec_get_name(par->codec_id)));
2091 if (par->codec_id == AV_CODEC_ID_PROBE)
2093 LOG(VB_GENERAL, LOG_ERR,
LOC +
2094 QString(
"Probing of stream #%1 unsuccesful, ignoring.").arg(strm));
2101 const AVCodec *codec =
nullptr;
2106 LOG(VB_GENERAL, LOG_ERR,
LOC +
2107 QString(
"Could not find decoder for codec (%1), ignoring.")
2108 .arg(avcodec_get_name(par->codec_id)));
2115 void *opaque =
nullptr;
2116 const AVCodec *
p = av_codec_iterate(&opaque);
2121 if (
p->name[0] !=
'\0')
2122 msg = QString(
"Codec %1:").arg(
p->name);
2124 msg = QString(
"Codec %1, null name,").arg(strm);
2126 LOG(VB_LIBAV, LOG_INFO,
LOC + msg);
2128 if (
p->id == par->codec_id)
2134 LOG(VB_LIBAV, LOG_INFO,
LOC +
2135 QString(
"Codec 0x%1 != 0x%2") .arg(
p->id, 0, 16)
2136 .arg(par->codec_id, 0, 16));
2137 p = av_codec_iterate(&opaque);
2148 if (enc->codec && par->codec_id != enc->codec_id)
2150 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2151 QString(
"Already opened codec not matching (%1 vs %2). Reopening")
2152 .arg(avcodec_get_name(enc->codec_id),
2153 avcodec_get_name(enc->codec->id)));
2169 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2170 QString(
"Stream 0x%1 is not valid in this context - skipping")
2171 .arg(
m_ic->streams[strm]->id, 4, 16));
2175 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2177 bool forced = (
m_ic->streams[strm]->disposition & AV_DISPOSITION_FORCED) != 0;
2179 uint lang_indx = lang_sub_cnt[lang]++;
2180 subtitleStreamCount++;
2183 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, 0, 0,
false,
false, forced);
2185 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2186 QString(
"Subtitle track #%1 is A/V stream #%2 "
2187 "and is in the %3 language(%4).")
2192 if (par->codec_type == AVMEDIA_TYPE_AUDIO)
2196 int channels = par->ch_layout.nb_channels;
2197 uint lang_indx = lang_aud_cnt[lang]++;
2200 if (enc->avcodec_dual_language)
2203 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, channels,
2204 false,
false,
false,
type);
2205 lang_indx = lang_aud_cnt[lang]++;
2207 static_cast<int>(strm), lang, lang_indx,
m_ic->streams[strm]->id, channels,
2208 true,
false,
false,
type);
2212 int logical_stream_id = 0;
2219 logical_stream_id =
m_ic->streams[strm]->id;
2221 if (logical_stream_id == -1)
2228 static_cast<int>(strm), lang, lang_indx, logical_stream_id, channels,
2229 false,
false,
false,
type);
2232 LOG(VB_AUDIO, LOG_INFO,
LOC +
2233 QString(
"Audio Track #%1, of type (%2) is A/V stream #%3 (id=0x%4) "
2234 "and has %5 channels in the %6 language(%7).")
2236 .arg(strm).arg(
m_ic->streams[strm]->id,0,16).arg(enc->ch_layout.nb_channels)
2247 const AVCodec *codec =
nullptr;
2248 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Trying to select best video track");
2262 int selTrack = av_find_best_stream(
m_ic, AVMEDIA_TYPE_VIDEO,
2267 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No video track found/selected.");
2271 AVStream *stream =
m_ic->streams[selTrack];
2281 if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
2282 codectype += QString(
"(%1x%2)").arg(enc->width).arg(enc->height);
2283 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2284 QString(
"Selected track #%1: ID: 0x%2 Codec ID: %3 Profile: %4 Type: %5 Bitrate: %6")
2285 .arg(selTrack).arg(
static_cast<uint64_t
>(stream->id), 0, 16)
2286 .arg(avcodec_get_name(enc->codec_id),
2287 avcodec_profile_name(enc->codec_id, enc->profile),
2289 QString::number(enc->bit_rate)));
2296 if ((enc->width != stream->codecpar->width) || (enc->height != stream->codecpar->height))
2298 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
2299 "Video resolution mismatch: Context: %1x%2 Stream: %3x%4 Codec: %5 Stream change: %6")
2300 .arg(enc->width).arg(enc->height)
2301 .arg(stream->codecpar->width).arg(stream->codecpar->height)
2308 int width = std::max(dim.width(), 16);
2309 int height = std::max(dim.height(), 16);
2310 QString dec =
"ffmpeg";
2311 uint thread_count = 1;
2314 codecName = enc->codec->name;
2319 if (enc->framerate.den && enc->framerate.num)
2320 m_fps = float(enc->framerate.num) / float(enc->framerate.den);
2324 bool foundgpudecoder =
false;
2325 QStringList unavailabledecoders;
2335 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
2336 "GPU/hardware decoder '%1' failed - forcing software decode")
2343 while (unavailabledecoders.size() < 10)
2347 if (!unavailabledecoders.isEmpty())
2349 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Unavailable decoders: %1")
2350 .arg(unavailabledecoders.join(
",")));
2356 if (!skip_loop_filter)
2357 enc->skip_loop_filter = AVDISCARD_NONKEY;
2365 if (
version && allowgpu && dec !=
"ffmpeg")
2369 enc->opaque =
static_cast<void*
>(
this);
2374 enc->opaque =
static_cast<void*
>(
this);
2376 foundgpudecoder =
true;
2381 unavailabledecoders.append(dec);
2389 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown video codec - defaulting to MPEG2");
2414 if (!foundgpudecoder)
2416 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 CPUs for decoding")
2417 .arg(HAVE_THREADS ? thread_count : 1));
2418 enc->thread_count =
static_cast<int>(thread_count);
2452 QString(
m_ic->iformat->name).contains(
"matroska"));
2490 #ifdef USING_MEDIACODEC
2491 if (QString(
"mediacodec") == codec->wrapper_name)
2492 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(),
nullptr);
2494 int ret = avcodec_open2(avctx, codec,
nullptr);
2499 LOG(VB_GENERAL, LOG_ERR,
LOC +
2500 QString(
"Could not open codec 0x%1, id(%2) type(%3) "
2501 "ignoring. reason %4").arg((uint64_t)avctx,0,16)
2502 .arg(avcodec_get_name(avctx->codec_id),
2508 LOG(VB_GENERAL, LOG_INFO,
LOC +
2509 QString(
"Opened codec 0x%1, id(%2) type(%3)")
2510 .arg((uint64_t)avctx,0,16)
2511 .arg(avcodec_get_name(avctx->codec_id),
2536 if (si.m_language_index == Index)
2537 return si.m_language;
2544 AVDictionaryEntry *metatag = av_dict_get(
m_ic->streams[StreamIndex]->metadata,
"language",
nullptr, 0);
2587 AVStream *stream =
m_ic->streams[StreamIndex];
2591 if (stream->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
2593 else if (stream->disposition & AV_DISPOSITION_COMMENT)
2595 else if (stream->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
2597 else if (stream->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
2624 if (
current->m_av_stream_index == streamIndex)
2630 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2631 QString(
"Invalid stream index passed to "
2632 "SetupAudioStreamSubIndexes: %1").arg(streamIndex));
2639 if (
current->m_av_substream_index == -1)
2652 (next->m_av_stream_index != streamIndex))
2654 QString msg = QString(
2655 "Expected substream 1 (Language I) of stream %1\n\t\t\t"
2656 "following substream 0, found end of list or another stream.")
2659 LOG(VB_GENERAL, LOG_WARNING,
LOC + msg);
2681 for (
uint i = 0; i <
m_ic->nb_streams;)
2683 AVStream *st =
m_ic->streams[i];
2685 if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2688 av_remove_stream(
m_ic, st->id, 0);
2701 if (!std::any_of(decoder->m_renderFormats->cbegin(), decoder->m_renderFormats->cend(),
2702 [&
type](
auto Format) { return type == Format; }))
2704 decoder->m_directRendering =
false;
2705 return avcodec_default_get_buffer2(c, pic, flags);
2708 decoder->m_directRendering =
true;
2709 MythVideoFrame *frame = decoder->GetPlayer()->GetNextVideoFrame();
2719 if ((frame->
m_type !=
type) || (pic->width > width) || (pic->height > height))
2736 for (
uint i = 0; i < 3; i++)
2742 pic->opaque = frame;
2743 pic->reordered_opaque = c->reordered_opaque;
2746 AVBufferRef *buffer = av_buffer_create(
reinterpret_cast<uint8_t*
>(frame), 0,
2747 [](
void* Opaque, uint8_t* Data)
2751 if (avfd && avfd->GetPlayer())
2752 avfd->GetPlayer()->DeLimboFrame(vf);
2755 pic->buf[0] = buffer;
2766 for (
int i = 0; i < 4; i++)
2768 pic->data[i] =
nullptr;
2769 pic->linesize[i] = 0;
2771 pic->opaque = frame;
2772 frame->pix_fmt = c->pix_fmt;
2773 pic->reordered_opaque = c->reordered_opaque;
2774 pic->data[0] = (uint8_t*)frame->buf;
2775 pic->data[3] = (uint8_t*)frame->buf;
2778 AVBufferRef *buffer =
2779 av_buffer_create((uint8_t*)frame, 0, release_avf_buffer, nd, 0);
2780 pic->buf[0] = buffer;
2795 bool process_cc_data = (buf[0] & 0x40) != 0;
2796 if (!process_cc_data)
2802 uint cc_count = buf[0] & 0x1f;
2805 if (buf_size < 2+(3*cc_count))
2816 bool had_608 =
false;
2817 bool had_708 =
false;
2818 for (
uint cur = 0; cur + 2 < buf_size; cur += 3)
2820 uint cc_code = buf[cur];
2821 bool cc_valid = (cc_code & 0x04) != 0U;
2823 uint data1 = buf[cur+1];
2824 uint data2 = buf[cur+2];
2825 uint data = (data2 << 8) | data1;
2826 uint cc_type = cc_code & 0x03;
2835 if (scte || cc_type <= 0
x1)
2854 if (scte && field == 0 &&
2855 (data1 & 0x7f) <= 0x0f && (data1 & 0x7f) != 0x00)
2881 bool check_608,
bool check_708)
2883 bool need_change_608 =
false;
2888 for (
uint i = 0; i < 4; i++)
2895 bool need_change_708 =
false;
2897 if (check_708 || need_change_608)
2900 for (
uint i = 1; i < 64 && !need_change_608 && !need_change_708; i++)
2905 if (need_change_708 && !check_608)
2909 if (!need_change_608 && !need_change_708)
2920 for (
uint i = 1; i < 64; i++)
2924 StreamInfo si(av_index, lang, 0, i, 0,
false,
true);
2929 for (
uint i = 0; i < 4; i++)
2940 StreamInfo si(av_index, lang, 0, i+1, 0,
false,
false);
2950 AVPacket *pkt,
bool can_reliably_parse_keyframes)
2955 bool reset_kfd =
false;
2959 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2960 "gopset not set, syncing positionMap");
2962 if (tempKeyFrameDist > 0 && !
m_livetv)
2964 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2965 QString(
"Initial key frame distance: %1.")
2971 else if (
m_keyframeDist != tempKeyFrameDist && tempKeyFrameDist > 0)
2973 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2974 QString(
"Key frame distance changed from %1 to %2.")
3002 if (can_reliably_parse_keyframes &&
3005 long long last_frame = 0;
3013 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
3014 QString(
"framesRead: %1 last_frame: %2 keyframedist: %3")
3021 long long startpos = pkt->pos;
3023 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3024 QString(
"positionMap[ %1 ] == %2.")
3054 float bytespersec = (float)
m_bitrate / 8;
3072 const uint8_t *bufptr = pkt->data;
3073 const uint8_t *bufend = pkt->data + pkt->size;
3075 while (bufptr < bufend)
3079 float aspect_override = -1.0F;
3088 if (bufptr + 11 >= pkt->data + pkt->size)
3090 const auto *seq =
reinterpret_cast<const SequenceHeader*
>(bufptr);
3092 int width =
static_cast<int>(seq->width()) >> context->lowres;
3093 int height =
static_cast<int>(seq->height()) >> context->lowres;
3094 float aspect = seq->
aspect(context->codec_id == AV_CODEC_ID_MPEG1VIDEO);
3095 if (stream->sample_aspect_ratio.num)
3096 aspect =
static_cast<float>(av_q2d(stream->sample_aspect_ratio) * width / height);
3097 if (aspect_override > 0.0F)
3098 aspect = aspect_override;
3099 float seqFPS = seq->fps();
3103 changed |= (seqFPS >
static_cast<float>(
m_fps)+0.01F) ||
3104 (seqFPS < static_cast<float>(
m_fps)-0.01F);
3108 bool forceaspectchange = !qFuzzyCompare(
m_currentAspect + 10.0F, aspect + 10.0F) &&
3112 if (changed || forceaspectchange)
3117 bool doublerate =
false;
3120 forceaspectchange, 2,
3123 if (context->hw_frames_ctx)
3124 if (context->internal)
3125 avcodec_flush_buffers(context);
3144 if ((seqFPS > avFPS+0.01F) || (seqFPS < avFPS-0.01F))
3146 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"avFPS(%1) != seqFPS(%2)")
3147 .arg(
static_cast<double>(avFPS)).arg(
static_cast<double>(seqFPS)));
3156 pkt->flags |= AV_PKT_FLAG_KEY;
3163 pkt->flags |= AV_PKT_FLAG_KEY;
3172 const uint8_t *buf = pkt->data;
3173 const uint8_t *buf_end = pkt->data + pkt->size;
3178 if (context->extradata && (context->extradata_size >= 7) && (context->extradata[0] == 0x01))
3180 if (pkt->flags & AV_PKT_FLAG_KEY)
3185 while (buf < buf_end)
3216 bool fps_changed = (seqFPS > 0.0) && ((seqFPS >
static_cast<double>(
m_fps) + 0.01) ||
3217 (seqFPS < static_cast<double>(
m_fps) - 0.01));
3222 if (fps_changed || res_changed || forcechange)
3227 bool doublerate =
false;
3240 if (context->hw_frames_ctx && (forcechange || res_changed))
3241 if (context->internal)
3242 avcodec_flush_buffers(context);
3248 m_fps =
static_cast<float>(seqFPS);
3263 if ((seqFPS > avFPS + 0.01) || (seqFPS < avFPS - 0.01))
3265 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
3266 QString(
"avFPS(%1) != seqFPS(%2)").arg(avFPS).arg(seqFPS));
3271 pkt->flags |= AV_PKT_FLAG_KEY;
3292 if (pkt->flags & AV_PKT_FLAG_KEY)
3308 !(pkt->flags & AV_PKT_FLAG_KEY))
3310 av_packet_unref(pkt);
3322 pkt_dur = av_mul_q(pkt_dur, curstream->time_base);
3323 if (pkt_dur.num == 1501 && pkt_dur.den == 90000)
3344 mpa_pic->reordered_opaque = AV_NOPTS_VALUE;
3346 if (pkt->pts != AV_NOPTS_VALUE)
3349 bool sentPacket =
false;
3354 context->reordered_opaque = pkt->pts;
3371 if (ret == AVERROR(EAGAIN))
3375 if (ret==0 && !gotpicture)
3377 ret2 = avcodec_send_packet(context, pkt);
3378 if (ret2 == AVERROR(EAGAIN))
3390 if (ret < 0 || ret2 < 0)
3395 LOG(VB_GENERAL, LOG_ERR,
LOC +
3396 QString(
"video avcodec_receive_frame error: %1 (%2) gotpicture:%3")
3398 .arg(ret).arg(gotpicture));
3403 LOG(VB_GENERAL, LOG_ERR,
LOC +
3404 QString(
"video avcodec_send_packet error: %1 (%2) gotpicture:%3")
3406 .arg(ret2).arg(gotpicture));
3420 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Decoder needs reset");
3424 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
3426 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"FFmpeg external library error - assuming streams changed");
3438 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3439 QString(
"video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4")
3440 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts)
3441 .arg(mpa_pic->pkt_dts));
3448 if (pkt->dts != AV_NOPTS_VALUE)
3454 if (mpa_pic->reordered_opaque != AV_NOPTS_VALUE)
3470 if (pkt->dts != AV_NOPTS_VALUE)
3476 if (mpa_pic->reordered_opaque != AV_NOPTS_VALUE)
3477 pts = mpa_pic->reordered_opaque;
3480 else if (pkt->dts != AV_NOPTS_VALUE)
3486 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG,
LOC +
3487 QString(
"video packet timestamps reordered %1 pts %2 dts %3 (%4)")
3488 .arg(mpa_pic->reordered_opaque).arg(pkt->pts).arg(pkt->dts)
3492 mpa_pic->reordered_opaque =
pts;
3501 auto *newPkt = av_packet_clone(pkt);
3521 uint cc_len =
static_cast<uint>(std::max(AvFrame->scte_cc_len,0));
3522 uint8_t *cc_buf = AvFrame->scte_cc_buf;
3532 cc_len =
static_cast<uint>(std::max(AvFrame->atsc_cc_len, 0));
3533 cc_buf = AvFrame->atsc_cc_buf;
3541 for (
uint i = 0; i < cc_len; i += ((cc_buf[i] & 0x1f) * 3) + 2)
3547 auto * side_data = av_frame_get_side_data(AvFrame, AV_FRAME_DATA_A53_CC);
3548 if (side_data && (side_data->size > 0))
3549 DecodeCCx08(side_data->data,
static_cast<uint>(side_data->size),
false);
3562 frame->m_directRendering =
false;
3573 av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
3574 frame->m_buffer, AV_PIX_FMT_YUV420P, AvFrame->width,
3575 AvFrame->height, IMAGE_ALIGN);
3576 tmppicture.data[0] = frame->m_buffer + frame->m_offsets[0];
3577 tmppicture.data[1] = frame->m_buffer + frame->m_offsets[1];
3578 tmppicture.data[2] = frame->m_buffer + frame->m_offsets[2];
3579 tmppicture.linesize[0] = frame->m_pitches[0];
3580 tmppicture.linesize[1] = frame->m_pitches[1];
3581 tmppicture.linesize[2] = frame->m_pitches[2];
3585 AvFrame->height,
static_cast<AVPixelFormat
>(AvFrame->format),
3586 AvFrame->width, AvFrame->height,
3587 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
3588 nullptr,
nullptr,
nullptr);
3591 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate sws context");
3594 sws_scale(
m_swsCtx, AvFrame->data, AvFrame->linesize, 0, dim.height(),
3595 tmppicture.data, tmppicture.linesize);
3630 LOG(VB_GENERAL, LOG_ERR,
LOC +
"NULL videoframe - direct rendering not "
3631 "correctly initialized.");
3635 std::chrono::milliseconds
pts = 0ms;
3638 long long av_pts = AvFrame->pts;
3639 if (av_pts == AV_NOPTS_VALUE)
3640 av_pts = AvFrame->pkt_dts;
3641 if (av_pts == AV_NOPTS_VALUE)
3642 av_pts = AvFrame->reordered_opaque;
3643 if (av_pts == AV_NOPTS_VALUE)
3645 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process video.");
3653 std::chrono::milliseconds temppts =
pts;
3670 double calcfps = 1000.0 /
ptsdiff.count();
3671 if (calcfps < 121.0 && calcfps > 3.0)
3675 double fpschange = calcfps /
static_cast<double>(
m_fps);
3677 if (fpschange > 1.9 && fpschange < 2.1)
3679 if (fpschange > 0.9 && fpschange < 1.1)
3685 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3686 QString(
"video timecode %1 %2 %3 %4%5")
3688 .arg(
pts.count()).arg(temppts.count()).arg(
m_lastVPts.count())
3689 .arg((
pts != temppts) ?
" fixup" :
""));
3691 frame->m_interlaced = AvFrame->interlaced_frame;
3692 frame->m_topFieldFirst = AvFrame->top_field_first != 0;
3694 frame->m_repeatPic = AvFrame->repeat_pict != 0;
3699 frame->m_colorspace = AvFrame->colorspace;
3700 frame->m_colorrange = AvFrame->color_range;
3701 frame->m_colorprimaries = AvFrame->color_primaries;
3702 frame->m_colortransfer = AvFrame->color_trc;
3703 frame->m_chromalocation = AvFrame->chroma_location;
3704 frame->m_pixFmt = AvFrame->format;
3709 frame->m_dummy =
false;
3710 frame->m_pauseFrame =
false;
3711 frame->m_deinterlaceInuse2x =
false;
3712 frame->m_alreadyDeinterlaced =
false;
3713 frame->m_interlacedReverse =
false;
3743 const AVStream *stream,
const AVPacket *pkt)
3747 const uint8_t *buf = pkt->data;
3748 uint64_t linemask = 0;
3753 if ((buf[0]==
't') && (buf[1]==
'v') && (buf[2] ==
'0'))
3756 memcpy(&linemask, buf + 3, 8);
3759 else if ((buf[0]==
'T') && (buf[1]==
'V') && (buf[2] ==
'0'))
3761 linemask = 0xffffffffffffffffLL;
3766 LOG(VB_VBI, LOG_ERR,
LOC + QString(
"Unknown VBI data stream '%1%2%3'")
3767 .arg(QChar(buf[0])).arg(QChar(buf[1])).arg(QChar(buf[2])));
3771 static constexpr
uint kMinBlank = 6;
3772 for (
uint i = 0; i < 36; i++)
3774 if (!((linemask >> i) & 0
x1))
3777 const uint line = ((i < 18) ? i : i-18) + kMinBlank;
3778 const uint field = (i<18) ? 0 : 1;
3779 const uint id2 = *buf & 0xf;
3789 StreamInfo si(pkt->stream_index, 0, 0, 0, 0);
3802 int data = (buf[2] << 8) | buf[1];
3829 const AVStream* ,
const AVPacket *pkt)
3831 const uint8_t *buf = pkt->data;
3832 const uint8_t *buf_end = pkt->data + pkt->size;
3835 while (buf < buf_end)
3841 else if (*buf == 0x02)
3844 if ((buf_end - buf) >= 42)
3848 else if (*buf == 0x03)
3851 if ((buf_end - buf) >= 42)
3855 else if (*buf == 0xff)
3861 LOG(VB_VBI, LOG_ERR,
LOC +
3862 QString(
"VBI: Unknown descriptor: %1").arg(*buf));
3878 uint8_t *data = pkt->data;
3879 int length = pkt->size;
3880 int componentTag = 0;
3881 int dataBroadcastId = 0;
3882 unsigned carouselId = 0;
3885 componentTag = str->component_tag;
3886 dataBroadcastId = str->data_id;
3887 carouselId = (unsigned) str->carousel_id;
3892 uint16_t sectionLen = (((data[1] & 0xF) << 8) | data[2]) + 3;
3894 if (sectionLen > length)
3898 componentTag, carouselId,
3900 length -= sectionLen;
3906 #endif // USING_MHEG
3914 long long pts = pkt->pts;
3915 if (
pts == AV_NOPTS_VALUE)
3917 if (
pts == AV_NOPTS_VALUE)
3919 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process subtitle.");
3922 pts =
static_cast<long long>(av_q2d(curstream->time_base) *
pts * 1000);
3929 int gotSubtitles = 0;
3930 AVSubtitle subtitle;
3931 memset(&subtitle, 0,
sizeof(AVSubtitle));
3938 curstream->id,
pts);
3942 if (pkt->stream_index == subIdx)
3946 pkt->data, pkt->size,
pts);
3955 avcodec_decode_subtitle2(ctx, &subtitle, &gotSubtitles, pkt);
3958 subtitle.start_display_time +=
pts;
3959 subtitle.end_display_time +=
pts;
3966 for (
unsigned i = 0; i < subtitle.num_rects; i++)
3968 subtitle.rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
3971 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3972 QString(
"subtl timecode %1 %2 %3 %4")
3973 .arg(pkt->pts).arg(pkt->dts)
3974 .arg(subtitle.start_display_time)
3975 .arg(subtitle.end_display_time));
3978 subtitle, curstream->codecpar->codec_id == AV_CODEC_ID_XSUB,
3991 auto id =
static_cast<uint>(Packet->stream_index + 0x2000);
3995 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3996 const auto * codec = QTextCodec::codecForName(
"utf-8");
3997 auto text = codec->toUnicode(
reinterpret_cast<const char *
>(Packet->data), Packet->size - 1);
3999 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
4000 QString text = toUtf16.decode(Packet->data);
4002 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
4003 auto list = text.split(
'\n', QString::SkipEmptyParts);
4005 auto list = text.split(
'\n', Qt::SkipEmptyParts);
4014 enum AVCodecID codec_id = curstream->codecpar->codec_id;
4018 case AV_CODEC_ID_MPEG2VBI:
4021 case AV_CODEC_ID_DVB_VBI:
4024 case AV_CODEC_ID_DSMCC_B:
4034 Q_UNUSED(decodetype);
4035 #endif // USING_MHEG:
4051 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio stream type " + msg +
"changed.");
4065 QString forcedString = forced ? QObject::tr(
" (forced)") :
"";
4067 int av_index =
m_tracks[
type][TrackNo].m_av_stream_index;
4068 AVStream *stream {
nullptr };
4069 if (av_index >= 0 && av_index < (
int)
m_ic->nb_streams)
4070 stream =
m_ic->streams[av_index];
4071 AVDictionaryEntry *entry =
4072 stream ? av_dict_get(stream->metadata,
"title",
nullptr, 0) :
nullptr;
4073 QString user_title = entry ? QString(R
"( "%1")").arg(entry->value) : "";
4085 AVCodecParameters *par = stream->codecpar;
4087 if (par->codec_id == AV_CODEC_ID_MP3)
4088 msg += QString(
" MP3");
4089 else if (ctx && ctx->codec)
4090 msg += QString(
" %1").arg(ctx->codec->name).toUpper();
4091 if (!user_title.isEmpty())
4099 msg += QString(
" ?ch");
4100 else if((channels > 4) && !(channels & 1))
4101 msg += QString(
" %1.1ch").arg(channels - 1);
4103 msg += QString(
" %1ch").arg(channels);
4113 if (!user_title.isEmpty())
4116 msg += QString(
" (%1)")
4120 return QString(
"%1: %2").arg(TrackNo + 1).arg(msg);
4124 return QObject::tr(
"Subtitle") + QString(
" %1: %2%3%4")
4125 .arg(QString::number(TrackNo + 1),
4153 return ctx ? QByteArray(
reinterpret_cast<char*
>(ctx->subtitle_header), ctx->subtitle_header_size) :
4164 AVDictionaryEntry *tag = av_dict_get(
m_ic->streams[index]->metadata,
"filename",
nullptr, 0);
4166 Filename = QByteArray(tag->value);
4167 AVCodecParameters *par =
m_ic->streams[index]->codecpar;
4168 Data = QByteArray(
reinterpret_cast<char*
>(par->extradata), par->extradata_size);
4178 if ((stream->component_tag == Tag) || ((Tag <= 0) && stream->component_tag <= 0))
4187 for (
uint i = 0; i <
m_ic->nb_streams; i++)
4189 AVStream *stream =
m_ic->streams[i];
4192 if (stream->component_tag == Tag)
4194 StreamInfo si(
static_cast<int>(i), 0, 0, 0, 0);
4216 const std::vector<int> &ftype)
4218 std::vector<int> ret;
4220 for (
int index : ftype)
4222 if ((lang_key < 0) || tracks[index].m_language == lang_key)
4223 ret.push_back(index);
4231 std::vector<int> ret;
4233 for (
size_t i = 0; i < tracks.size(); i++)
4235 if (tracks[i].m_audio_type ==
type)
4244 const std::vector<int>&fs,
4245 enum AVCodecID codecId,
4248 int selectedTrack = -1;
4253 const int stream_index = tracks[f].m_av_stream_index;
4254 AVCodecParameters *par = ic->streams[stream_index]->codecpar;
4255 if ((codecId == AV_CODEC_ID_NONE || codecId == par->codec_id) &&
4256 (max_seen < par->ch_layout.nb_channels))
4258 if (codecId == AV_CODEC_ID_DTS &&
profile > 0)
4265 max_seen = par->ch_layout.nb_channels;
4269 return selectedTrack;
4327 uint numStreams = atracks.size();
4328 if ((ctrack >= 0) && (ctrack < (
int)numStreams))
4333 for (
const auto & track : atracks)
4335 int idx = track.m_av_stream_index;
4336 AVCodecContext *codec_ctx =
m_ic->streams[idx]->codec;
4337 AudioInfo item(codec_ctx->codec_id, codec_ctx->bps,
4338 codec_ctx->sample_rate, codec_ctx->channels,
4344 int selTrack = (1 == numStreams) ? 0 : -1;
4349 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio sub-stream");
4355 for (
uint i = 0; i < numStreams; i++)
4357 if (atracks[i].m_av_substream_index == substream_index)
4365 if ((selTrack < 0) && wlang >= -1 && numStreams)
4367 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio track");
4372 for (
uint i = 0; i < numStreams; i++)
4374 if (wlang == atracks[i].m_language)
4378 if (windx == atracks[i].m_language_index)
4384 if (selTrack < 0 && numStreams)
4386 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select audio track (w/lang)");
4393 LOG(VB_AUDIO, LOG_WARNING,
"No audio tracks matched the type filter, "
4394 "so trying all tracks.");
4395 for (
int i = 0; i < static_cast<int>(atracks.size()); i++)
4404 std::vector<int> flang =
filter_lang(atracks, canonical_key, ftype);
4408 FF_PROFILE_DTS_HD_MA);
4412 if (selTrack < 0 && m_audio->CanDTSHD())
4414 FF_PROFILE_DTS_HD_HRA);
4438 FF_PROFILE_DTS_HD_MA);
4441 AV_CODEC_ID_TRUEHD);
4443 if (selTrack < 0 && m_audio->CanDTSHD())
4445 FF_PROFILE_DTS_HD_HRA);
4466 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select default track");
4467 for (
size_t i = 0; i < atracks.size(); i++) {
4468 int idx = atracks[i].m_av_stream_index;
4469 if (
m_ic->streams[idx]->disposition & AV_DISPOSITION_DEFAULT)
4480 LOG(VB_AUDIO, LOG_INFO,
LOC +
4481 "Trying to select audio track (wo/lang)");
4486 FF_PROFILE_DTS_HD_MA);
4490 if (selTrack < 0 && m_audio->CanDTSHD())
4492 FF_PROFILE_DTS_HD_HRA);
4511 if (ctrack != selTrack)
4513 LOG(VB_AUDIO, LOG_INFO,
LOC +
"No suitable audio track exists.");
4520 strack = atracks[selTrack];
4525 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Selected track %1 (A/V Stream #%2)")
4534 char *buffer,
int bufsize)
4545 const uint halfsample = samplesize >> 1;
4547 const char *from = (channel == 1) ? buffer + halfsample : buffer;
4548 char *to = (channel == 0) ? buffer + halfsample : buffer;
4551 (sample++), (from += samplesize), (to += samplesize))
4553 memmove(to, from, halfsample);
4563 bool firstloop =
true;
4564 int decoded_size = -1;
4571 AVPacket *tmp_pkt = av_packet_alloc();
4572 tmp_pkt->data = pkt->data;
4573 tmp_pkt->size = pkt->size;
4574 while (tmp_pkt->size > 0)
4576 bool reselectAudioTrack =
false;
4581 LOG(VB_AUDIO, LOG_INFO,
LOC +
4582 "Audio is disabled - trying to restart it");
4583 reselectAudioTrack =
true;
4588 bool wasDual = audSubIdx != -1;
4589 bool isDual = ctx->avcodec_dual_language != 0;
4590 if ((wasDual && !isDual) || (!wasDual && isDual))
4593 reselectAudioTrack =
true;
4598 bool already_decoded =
false;
4599 if (!ctx->ch_layout.nb_channels)
4611 AVChannelLayout channel_layout;
4613 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4615 if (ctx->codec_id == AV_CODEC_ID_AC3)
4620 decoded_size = data_size;
4621 already_decoded =
true;
4622 reselectAudioTrack |= ctx->ch_layout.nb_channels;
4626 if (reselectAudioTrack)
4636 if (!(decodetype &
kDecodeAudio) || (pkt->stream_index != audIdx)
4640 if (firstloop && pkt->pts != AV_NOPTS_VALUE)
4658 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
4659 QString(
"discarding early audio timecode %1 %2 %3")
4660 .arg(pkt->pts).arg(pkt->dts).arg(
m_lastAPts.count()));
4674 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Audio stream changed");
4677 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Number of audio channels changed from %1 to %2")
4689 if (!already_decoded)
4694 decoded_size = data_size;
4702 data_size = tmp_pkt->size;
4708 if (!already_decoded)
4712 AVChannelLayout channel_layout;
4714 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
4718 decoded_size = data_size;
4725 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown audio decoding error");
4726 av_packet_free(&tmp_pkt);
4732 tmp_pkt->data += ret;
4733 tmp_pkt->size -= ret;
4737 std::chrono::milliseconds temppts =
m_lastAPts;
4744 int frames = (ctx->ch_layout.nb_channels <= 0 || decoded_size < 0 || !samplesize) ? -1 :
4745 decoded_size / (ctx->ch_layout.nb_channels * samplesize);
4754 ((
double)(frames * 1000) / ctx->sample_rate);
4757 LOG(VB_TIMESTAMP, LOG_INFO,
LOC + QString(
"audio timecode %1 %2 %3 %4")
4758 .arg(pkt->pts).arg(pkt->dts).arg(temppts.count()).arg(
m_lastAPts.count()));
4763 tmp_pkt->data += ret;
4764 tmp_pkt->size -= ret;
4768 av_packet_free(&tmp_pkt);
4775 AVPacket *pkt =
nullptr;
4776 bool have_err =
false;
4778 const DecodeType origDecodetype = decodetype;
4786 bool storevideoframes =
false;
4855 storevideoframes =
true;
4861 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4862 QString(
"Audio %1 ms behind video but already %2 "
4863 "video frames queued. AV-Sync might be broken.")
4874 av_packet_free(&pkt);
4880 pkt = av_packet_alloc();
4885 if (retval == -EAGAIN)
4889 av_packet_free(&pkt);
4890 std::string errbuf(256,
'\0');
4893 errmsg = QString::fromStdString(errbuf);
4897 LOG(VB_GENERAL, LOG_ERR, QString(
"decoding error %1 (%2)")
4898 .arg(errmsg).arg(retval));
4911 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No context");
4912 av_packet_unref(pkt);
4916 if (pkt->stream_index >= (
int)
m_ic->nb_streams)
4918 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream");
4919 av_packet_unref(pkt);
4923 AVStream *curstream =
m_ic->streams[pkt->stream_index];
4927 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream (NULL)");
4928 av_packet_unref(pkt);
4932 enum AVMediaType codec_type = curstream->codecpar->codec_type;
4934 if (storevideoframes && codec_type == AVMEDIA_TYPE_VIDEO)
4942 if (codec_type == AVMEDIA_TYPE_VIDEO &&
4952 av_packet_free(&pkt);
4957 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4958 curstream->codecpar->codec_id == AV_CODEC_ID_TEXT)
4961 av_packet_unref(pkt);
4965 if (codec_type == AVMEDIA_TYPE_SUBTITLE &&
4966 curstream->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT)
4969 av_packet_unref(pkt);
4973 if (codec_type == AVMEDIA_TYPE_DATA)
4976 av_packet_unref(pkt);
4983 if (codec_type != AVMEDIA_TYPE_VIDEO)
4985 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
4986 QString(
"No codec for stream index %1, type(%2) id(%3:%4)")
4987 .arg(pkt->stream_index)
4989 avcodec_get_name(curstream->codecpar->codec_id))
4990 .arg(curstream->codecpar->codec_id));
4995 av_packet_unref(pkt);
5003 case AVMEDIA_TYPE_AUDIO:
5012 case AVMEDIA_TYPE_VIDEO:
5019 if (pkt->pts != AV_NOPTS_VALUE)
5022 (av_q2d(curstream->time_base)*pkt->pts*1000000);
5037 case AVMEDIA_TYPE_SUBTITLE:
5046 LOG(VB_GENERAL, LOG_ERR,
LOC +
5047 QString(
"Decoding - id(%1) type(%2)")
5048 .arg(avcodec_get_name(ctx->codec_id),
5055 if (!have_err && !Retry)
5057 av_packet_unref(pkt);
5062 av_packet_free(&pkt);
5079 int result = av_read_frame(ctx, pkt);
5086 if (ic && ic->pmt_section)
5089 if (!pmt_buffer.has_buffer())
5148 if (stream < 0 || !
m_ic)
5150 return avcodec_get_name(
m_ic->streams[stream]->codecpar->codec_id);
5164 QString msg = (disable) ?
"Disabling" :
"Allowing";
5165 LOG(VB_AUDIO, LOG_INFO,
LOC + msg +
" pass through");
5188 switch (ctx->codec_id)
5190 case AV_CODEC_ID_AC3:
5191 case AV_CODEC_ID_TRUEHD:
5192 case AV_CODEC_ID_EAC3:
5193 case AV_CODEC_ID_MLP:
5194 case AV_CODEC_ID_DTS:
5203 bool passthru =
false;
5207 if (!withProfile && par->codec_id == AV_CODEC_ID_DTS && !
m_audio->
CanDTSHD())
5210 par->codec_id, FF_PROFILE_DTS);
5215 par->codec_id, par->profile);
5231 AVStream *curstream =
nullptr;
5232 AVCodecContext *ctx =
nullptr;
5234 int requested_channels = 0;
5238 (
int)
m_ic->nb_streams) &&
5240 .m_av_stream_index]) &&
5245 ctx->bits_per_raw_sample);
5247 if (av_sample_fmt_is_planar(ctx->sample_fmt))
5249 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Audio data is planar"));
5254 int bps = av_get_bytes_per_sample(ctx->sample_fmt) << 3;
5255 if (ctx->sample_fmt == AV_SAMPLE_FMT_S32 &&
5256 ctx->bits_per_raw_sample)
5257 bps = ctx->bits_per_raw_sample;
5258 LOG(VB_GENERAL, LOG_ERR,
LOC +
5259 QString(
"Unsupported sample format with %1 bits").arg(bps));
5263 bool using_passthru =
DoPassThrough(curstream->codecpar,
false);
5265 requested_channels = ctx->ch_layout.nb_channels;
5267 if (!using_passthru &&
5273 AVChannelLayout channel_layout;
5274 av_channel_layout_default(&channel_layout, requested_channels);
5275 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
5278 info =
AudioInfo(ctx->codec_id, fmt, ctx->sample_rate,
5279 requested_channels, using_passthru, ctx->ch_layout.nb_channels,
5280 ctx->codec_id == AV_CODEC_ID_DTS ? ctx->profile : 0);
5286 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No codec context. Returning false");
5293 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Initializing audio parms from " +
5298 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio format changed " +
5299 QString(
"\n\t\t\tfrom %1 to %2")
5315 switch (ctx->codec_id)
5317 case AV_CODEC_ID_MP2:
5320 case AV_CODEC_ID_MP3:
5323 case AV_CODEC_ID_AC3:
5326 case AV_CODEC_ID_DTS:
5329 case AV_CODEC_ID_VORBIS:
5332 case AV_CODEC_ID_WMAV1:
5335 case AV_CODEC_ID_WMAV2:
5343 lcd->setAudioFormatLEDs(audio_format,
true);
5378 int64_t start_time = INT64_MAX;
5379 int64_t end_time = INT64_MIN;
5380 AVStream *st =
nullptr;
5382 for (
uint i = 0; i < ic->nb_streams; i++)
5384 AVStream *st1 = ic->streams[i];
5385 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5394 int64_t duration = INT64_MIN;
5395 if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
5396 int64_t start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
5397 if (start_time1 < start_time)
5398 start_time = start_time1;
5399 if (st->duration != AV_NOPTS_VALUE) {
5400 int64_t end_time1 = start_time1 +
5401 av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5402 if (end_time1 > end_time)
5403 end_time = end_time1;
5406 if (st->duration != AV_NOPTS_VALUE) {
5407 int64_t duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5408 if (duration1 > duration)
5409 duration = duration1;
5411 if (start_time != INT64_MAX) {
5412 ic->start_time = start_time;
5413 if (end_time != INT64_MIN) {
5414 if (end_time - start_time > duration)
5415 duration = end_time - start_time;
5418 if (duration != INT64_MIN) {
5419 int64_t filesize = 0;
5420 ic->duration = duration;
5421 if (ic->pb && (filesize = avio_size(ic->pb)) > 0) {
5423 ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
5424 (
double)ic->duration;