15 #include "libavutil/avutil.h"
16 #include "libavutil/error.h"
17 #include "libavutil/intreadwrite.h"
18 #include "libavutil/log.h"
19 #include "libavutil/opt.h"
20 #include "libavcodec/avcodec.h"
21 #include "libavformat/avformat.h"
22 #include "libavformat/avio.h"
23 #include "libswscale/swscale.h"
24 #include "libavutil/stereo3d.h"
25 #include "libavutil/imgutils.h"
26 #include "libavutil/display.h"
29 #ifdef USING_MEDIACODEC // Android
31 #include "libavcodec/jni.h"
33 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
34 #include <QtAndroidExtras>
36 #include <QJniEnvironment>
37 #define QAndroidJniEnvironment QJniEnvironment
65 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
68 #include <QStringDecoder>
83 #include "libmythbase/mythconfig.h"
111 using namespace std::string_view_literals;
113 #define LOC QString("AFD: ")
123 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
133 return {ctx.width >> ctx.lowres, ctx.height >> ctx.lowres};
137 float aspect_ratio = 0.0F;
139 if (ctx.sample_aspect_ratio.num && ctx.height)
141 aspect_ratio = av_q2d(ctx.sample_aspect_ratio) *
142 static_cast<double>(ctx.width);
143 aspect_ratio /= (float) ctx.height;
146 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
149 aspect_ratio = (float)ctx.width / (
float)ctx.height;
151 aspect_ratio = 4.0F / 3.0F;
158 static constexpr
float kDefaultAspect = 4.0F / 3.0F;
159 int asp =
p.aspectRatio();
162 case 0:
return kDefaultAspect;
163 case 2:
return 4.0F / 3.0F;
164 case 3:
return 16.0F / 9.0F;
165 case 4:
return 2.21F;
169 float aspect_ratio = asp * 0.000001F;
170 if (aspect_ratio <= 0.0F || aspect_ratio > 6.0F)
172 if (
p.pictureHeight() &&
p.pictureWidth())
175 (float)
p.pictureWidth() /(float)
p.pictureHeight();
179 aspect_ratio = kDefaultAspect;
200 #define FAIL(errmsg) do { \
201 LOG(VB_PLAYBACK, LOG_INFO, LOC + (errmsg)); \
212 switch (Stream->codecpar->codec_type)
216 case AVMEDIA_TYPE_VIDEO:
218 FAIL(
"No codec for video stream");
219 if (!Stream->codecpar->width || !Stream->codecpar->height)
220 FAIL(
"Unspecified video size");
221 if (Stream->codecpar->format == AV_PIX_FMT_NONE)
222 FAIL(
"Unspecified video pixel format");
229 case AVMEDIA_TYPE_AUDIO:
231 FAIL(
"No codec for audio stream");
249 case AVMEDIA_TYPE_SUBTITLE:
250 if (Stream->codecpar->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !Stream->codecpar->width)
251 FAIL(
"Unspecified subtitle size");
253 case AVMEDIA_TYPE_DATA:
254 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
261 if (Stream->codecpar->codec_id == AV_CODEC_ID_NONE)
262 FAIL(
"Unknown codec");
266 static void myth_av_log(
void *ptr,
int level,
const char* fmt, va_list vl)
274 static QString s_fullLine(
"");
275 static QMutex s_stringLock;
276 uint64_t verbose_mask = VB_LIBAV;
277 LogLevel_t verbose_level = LOG_EMERG;
283 verbose_level = LOG_EMERG;
284 verbose_mask |= VB_GENERAL;
287 verbose_level = LOG_CRIT;
288 verbose_mask |= VB_GENERAL;
291 verbose_level = LOG_ERR;
294 verbose_level = LOG_WARNING;
297 verbose_level = LOG_INFO;
301 verbose_level = LOG_DEBUG;
304 verbose_level = LOG_TRACE;
314 if (s_fullLine.isEmpty() && ptr) {
315 AVClass* avc = *(AVClass**)ptr;
316 s_fullLine = QString(
"[%1 @ %2] ")
317 .arg(avc->item_name(ptr))
318 .arg((quintptr)avc, QT_POINTER_SIZE * 2, 16, QChar(
'0'));
321 s_fullLine += QString::vasprintf(fmt, vl);
322 if (s_fullLine.endsWith(
"\n"))
324 LOG(verbose_mask, verbose_level, s_fullLine.trimmed());
325 s_fullLine.truncate(0);
327 s_stringLock.unlock();
332 if (lang_cstr[0] ==
'\0' || lang_cstr[1] ==
'\0')
336 if (lang_cstr[2] ==
'\0')
338 QString tmp2 = lang_cstr;
356 case AVMEDIA_TYPE_UNKNOWN:
return "Unknown";
357 case AVMEDIA_TYPE_VIDEO:
return "Video";
358 case AVMEDIA_TYPE_AUDIO:
return "Audio";
359 case AVMEDIA_TYPE_DATA:
return "Data";
360 case AVMEDIA_TYPE_SUBTITLE:
return "Subtitle";
361 case AVMEDIA_TYPE_ATTACHMENT:
return "Attachment";
362 default:
return "Invalid Codec Type";
372 m_playerFlags(flags),
377 m_itv(parent->GetInteractiveTV()),
378 m_audioSamples((uint8_t *)av_mallocz(
AudioOutput::kMaxSizeBuffer))
392 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"PlayerFlags: 0x%1, AudioReadAhead: %2 msec")
401 av_packet_free(&pkt);
419 lcd->setAudioFormatLEDs(
AUDIO_AC3,
false);
420 lcd->setVideoFormatLEDs(
VIDEO_MPG,
false);
437 for (
uint i = 0; i <
m_ic->nb_streams; i++)
439 AVStream *st =
m_ic->streams[i];
455 avformat_close_input(&
m_ic);
461 static int64_t
lsb3full(int64_t lsb, int64_t base_ts,
int lsb_bits)
463 int64_t mask = (lsb_bits < 64) ? (1LL<<lsb_bits)-1 : -1LL;
464 return ((lsb - base_ts)&mask);
469 int64_t start_pts = 0;
471 AVStream *st =
nullptr;
472 for (
uint i = 0; i <
m_ic->nb_streams; i++)
474 AVStream *st1 =
m_ic->streams[i];
475 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
484 if (
m_ic->start_time != AV_NOPTS_VALUE)
486 start_pts = av_rescale(
m_ic->start_time,
488 AV_TIME_BASE * (int64_t)st->time_base.num);
491 int64_t
pts = av_rescale(timecode.count() / 1000.0,
502 std::chrono::milliseconds timecode)
504 int64_t start_pts = 0;
506 if (
m_ic->start_time != AV_NOPTS_VALUE)
508 start_pts = av_rescale(
m_ic->start_time,
510 AV_TIME_BASE * (int64_t)st->time_base.num);
513 int64_t
pts = av_rescale(timecode.count() / 1000.0,
526 return m_ic->nb_chapters;
536 for (
int i = 0; i < total; i++)
538 int num =
m_ic->chapters[i]->time_base.num;
539 int den =
m_ic->chapters[i]->time_base.den;
540 int64_t start =
m_ic->chapters[i]->start;
541 long double total_secs = (
long double)start * (
long double)num /
543 times.push_back(std::chrono::seconds((
long long)total_secs));
552 for (
int i = (
m_ic->nb_chapters - 1); i > -1 ; i--)
554 int num =
m_ic->chapters[i]->time_base.num;
555 int den =
m_ic->chapters[i]->time_base.den;
556 int64_t start =
m_ic->chapters[i]->start;
557 long double total_secs = (
long double)start * (
long double)num /
559 auto framenum = (
long long)(total_secs *
m_fps);
560 if (framesPlayed >= framenum)
562 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
563 QString(
"GetCurrentChapter(selected chapter %1 framenum %2)")
564 .arg(i + 1).arg(framenum));
576 int num =
m_ic->chapters[chapter - 1]->time_base.num;
577 int den =
m_ic->chapters[chapter - 1]->time_base.den;
578 int64_t start =
m_ic->chapters[chapter - 1]->start;
579 long double total_secs = (
long double)start * (
long double)num /
581 auto framenum = (
long long)(total_secs *
m_fps);
582 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"GetChapter %1: framenum %2")
583 .arg(chapter).arg(framenum));
589 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"DoRewind(%1, %2 discard frames)")
590 .arg(desiredFrame).arg( discardFrames ?
"do" :
"don't" ));
596 return do_av_seek(desiredFrame, discardFrames, AVSEEK_FLAG_BACKWARD);
601 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
602 QString(
"DoFastForward(%1 (%2), %3 discard frames)")
604 .arg((discardFrames) ?
"do" :
"don't"));
612 if (seekDelta >= 0 && seekDelta < 2 && m_parent->GetPlaySpeed() == 0.0F)
618 return do_av_seek(desiredFrame, discardFrames, 0);
624 if (
m_ic->start_time != AV_NOPTS_VALUE)
625 ts =
m_ic->start_time;
628 long double seekts = desiredFrame * AV_TIME_BASE /
m_fps;
629 ts += (
long long)seekts;
636 flags |= AVSEEK_FLAG_BACKWARD;
639 int ret = av_seek_frame(
m_ic, -1, ts, flags);
642 LOG(VB_GENERAL, LOG_ERR,
LOC +
643 QString(
"av_seek_frame(m_ic, -1, %1, 0b%2) error: %3").arg(
645 QString::number(flags, 2),
652 reader->SeekFrame(ts, flags);
654 int normalframes = 0;
672 bool doflush,
bool discardFrames)
677 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
678 QString(
"SeekReset(%1, %2, %3 flush, %4 discard)")
679 .arg(newKey).arg(skipFrames)
680 .arg((doflush) ?
"do" :
"don't",
681 (discardFrames) ?
"do" :
"don't"));
701 avformat_flush(
m_ic);
708 m_ic->pb->buf_ptr =
m_ic->pb->buffer;
709 m_ic->pb->buf_end =
m_ic->pb->buffer;
710 m_ic->pb->eof_reached = 0;
714 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SeekReset() flushing");
715 for (
uint i = 0; i <
m_ic->nb_streams; i++)
721 if (codecContext && codecContext->internal)
722 avcodec_flush_buffers(codecContext);
729 av_packet_free(&pkt);
751 static constexpr std::chrono::milliseconds maxSeekTimeMs { 200ms };
752 int profileFrames = 0;
754 for (; (skipFrames > 0 && !
m_atEof &&
755 (exactSeeks || begin.
elapsed() < maxSeekTimeMs));
756 --skipFrames, ++profileFrames)
760 QElapsedTimer getframetimer;
761 getframetimer.start();
763 while (retry && !getframetimer.hasExpired(100))
768 std::this_thread::sleep_for(1ms);
776 if (!exactSeeks && profileFrames >= 5 && profileFrames < 10)
778 const int giveUpPredictionMs = 400;
779 int remainingTimeMs =
780 skipFrames * (float)begin.
elapsed().count() / profileFrames;
781 if (remainingTimeMs > giveUpPredictionMs)
783 LOG(VB_PLAYBACK, LOG_DEBUG,
784 QString(
"Frame-by-frame seeking would take "
785 "%1 ms to finish, skipping.").arg(remainingTimeMs));
802 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
803 QString(
"Resetting byte context eof (livetv %1 was eof %2)")
805 m_ic->pb->eof_reached = 0;
813 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
814 QString(
"Reset: Video %1, Seek %2, File %3")
815 .arg(reset_video_data).arg(seek_reset).arg(reset_file));
822 if (reset_video_data)
832 memset(&probe, 0,
sizeof(AVProbeData));
834 QByteArray fname =
filename.toLatin1();
835 probe.filename = fname.constData();
836 probe.buf = (
unsigned char *)testbuf.data();
837 probe.buf_size = testbuf.size();
839 int score = AVPROBE_SCORE_MAX/4;
851 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
853 return av_probe_input_format2(&probe,
static_cast<int>(
true), &score) !=
nullptr;
860 int cnt = decoder->
m_ic->nb_streams;
862 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
863 QString(
"streams_changed 0x%1 -- program_number %2 stream count %3")
864 .arg((uint64_t)data,0,16).arg(QString::number(avprogram_id), QString::number(cnt)));
866 auto* program = decoder->get_current_AVProgram();
867 if (program !=
nullptr && program->id != avprogram_id)
871 decoder->m_streamsChanged =
true;
885 int retval = avformat_find_stream_info(
m_ic,
nullptr);
923 const AVInputFormat *fmt =
nullptr;
925 QByteArray fnamea = fnames.toLatin1();
926 const char *
filename = fnamea.constData();
929 memset(&probe, 0,
sizeof(AVProbeData));
931 probe.buf =
reinterpret_cast<unsigned char *
>(testbuf.data());
933 probe.buf_size = testbuf.size();
936 memset(probe.buf + probe.buf_size, 0, AVPROBE_PADDING_SIZE);
938 fmt = av_probe_input_format(&probe,
static_cast<int>(
true));
941 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Probe failed for '%1'").arg(
filename));
945 if (strcmp(fmt->name,
"mpegts") == 0 &&
948 const AVInputFormat *fmt2 = av_find_input_format(
"mpegts-ffmpeg");
952 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using FFmpeg MPEG-TS demuxer (forced)");
957 bool scancomplete =
false;
958 int remainingscans = 5;
960 while (!scancomplete && remainingscans--)
974 while (!found && --retries)
976 m_ic = avformat_alloc_context();
979 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Could not allocate format context.");
986 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
987 QString(
"Buffer size: %1 Streamed %2 Seekable %3 Available %4")
990 .arg(
m_ic->pb->seekable)
994 err = avformat_open_input(&
m_ic,
filename, fmt,
nullptr);
998 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Failed to open input ('%1')")
1006 QThread::usleep(100000);
1012 if (strcmp(fmt->name,
"mpegts") == 0)
1014 fmt = av_find_input_format(
"mpegts-ffmpeg");
1017 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Attempting to use original FFmpeg MPEG-TS demuxer.");
1030 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error opening input. Aborting");
1042 m_ic->max_analyze_duration = 60LL * AV_TIME_BASE;
1048 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Could not find codec parameters for '%1'").arg(
filename));
1055 scancomplete =
true;
1060 scancomplete =
false;
1064 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Stream scan incomplete - retrying");
1065 QThread::usleep(250000);
1073 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Scan incomplete - playback may not work");
1076 m_ic->stream_change_data =
this;
1088 QString extension = QFileInfo(fnames).suffix();
1089 if (strcmp(fmt->name,
"mp3") == 0 || strcmp(fmt->name,
"flac") == 0 ||
1090 strcmp(fmt->name,
"ogg") == 0 ||
1091 (extension.compare(
"m4a", Qt::CaseInsensitive) == 0))
1106 int initialAudio = -1;
1107 int initialVideo = -1;
1108 if (
m_itv ==
nullptr)
1110 if (
m_itv !=
nullptr)
1112 if (initialAudio >= 0)
1114 if (initialVideo >= 0)
1117 #endif // USING_MHEG
1135 std::chrono::seconds dur = 0s;
1144 dur = duration_cast<std::chrono::seconds>(av_duration(
m_ic->duration));
1155 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1156 "Recording has no position -- using libavformat seeking.");
1165 float bytespersec = (float)
m_bitrate / 8 / 2;
1168 (int)(secs *
static_cast<float>(
m_fps)));
1177 if (strcmp(fmt->name,
"avi") == 0)
1190 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Position map found");
1192 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Partial position map found");
1193 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1194 QString(
"Successfully opened decoder for file: \"%1\". novideo(%2)")
1198 for (
unsigned int i=0; i <
m_ic->nb_chapters; i++)
1200 int num =
m_ic->chapters[i]->time_base.num;
1201 int den =
m_ic->chapters[i]->time_base.den;
1202 int64_t start =
m_ic->chapters[i]->start;
1203 auto total_secs =
static_cast<long double>(start) *
static_cast<long double>(num) /
1204 static_cast<long double>(den);
1206 auto framenum =
static_cast<long long>(total_secs *
static_cast<long double>(
m_fps));
1207 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1208 QString(
"Chapter %1 found @ [%2]->%3")
1211 QString::number(framenum)));
1224 Reset(
true,
true,
true);
1238 double avg_fps = (Stream->avg_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->avg_frame_rate);
1239 double codec_fps = av_q2d(Context->framerate);
1240 double container_fps = (Stream->time_base.num == 0) ? 0.0 : av_q2d(av_inv_q(Stream->time_base));
1242 double estimated_fps = (Stream->r_frame_rate.den == 0) ? 0.0 : av_q2d(Stream->r_frame_rate);
1245 std::vector<double> rates;
1250 if (QString(
m_ic->iformat->name).contains(
"matroska") ||
1251 QString(
m_ic->iformat->name).contains(
"mov"))
1253 rates.emplace_back(avg_fps);
1257 if (QString(
m_ic->iformat->name).contains(
"avi"))
1259 rates.emplace_back(container_fps);
1262 rates.emplace_back(codec_fps);
1263 rates.emplace_back(container_fps);
1264 rates.emplace_back(avg_fps);
1266 rates.emplace_back(estimated_fps);
1268 rates.emplace_back(30000.0 / 1001.0);
1270 auto invalid_fps = [](
double rate) {
return rate < 3.0 || rate > 121.0; };
1271 rates.erase(std::remove_if(rates.begin(), rates.end(), invalid_fps), rates.end());
1273 auto FuzzyEquals = [](
double First,
double Second) {
return std::abs(First - Second) < 0.03; };
1276 if (!FuzzyEquals(rates.front(),
m_fps))
1278 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1279 QString(
"Selected FPS: %1 (Avg:%2 Mult:%3 Codec:%4 Container:%5 Estimated:%6)")
1280 .arg(
static_cast<double>(rates.front())).arg(avg_fps)
1281 .arg(
m_fpsMultiplier).arg(codec_fps).arg(container_fps).arg(estimated_fps));
1284 auto IsStandard = [&FuzzyEquals](
double Rate)
1287 static const std::set<double> k_standard_rates =
1306 if (Rate > 23.0 && Rate < 121.0)
1308 for (
auto standard_rate : k_standard_rates)
1309 if (FuzzyEquals(Rate, standard_rate))
1318 double detected = rates.front();
1319 if (Sanitise && !IsStandard(detected))
1321 for (
auto rate : rates)
1323 if (IsStandard(rate))
1325 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 is non-standard - using %2 instead.")
1326 .arg(rates.front()).arg(rate));
1334 if (rate > 33.0 && detected < 33.0)
1336 double half = rate / 2.0;
1337 if (std::abs(half - detected) < (half * 0.1))
1339 LOG(VB_GENERAL, LOG_INFO,
LOC +
1340 QString(
"Assuming %1 is a better choice than %2")
1341 .arg(half).arg(rate));
1342 return static_cast<float>(half);
1345 return static_cast<float>(rate);
1350 return static_cast<float>(detected);
1355 switch (Context->codec_id)
1357 case AV_CODEC_ID_H264:
1360 if (Context->extradata && (Context->extradata_size >= 7))
1363 if (Context->extradata[0] == 1)
1365 else if (AV_RB24(Context->extradata) == 0x01)
1367 else if (AV_RB32(Context->extradata) == 0x01)
1374 parser.parse_SPS(Context->extradata + offset,
1375 static_cast<uint>(Context->extradata_size - offset), dummy, result);
1380 case AV_CODEC_ID_H265:
return 16;
1381 case AV_CODEC_ID_VP9:
return 8;
1382 case AV_CODEC_ID_VP8:
return 3;
1388 bool selectedStream)
1390 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1391 QString(
"InitVideoCodec ID:%1 Type:%2 Size:%3x%4")
1392 .arg(avcodec_get_name(codecContext->codec_id),
1394 .arg(codecContext->width).arg(codecContext->height));
1399 codecContext->opaque =
static_cast<void*
>(
this);
1401 codecContext->slice_flags = 0;
1403 codecContext->err_recognition = AV_EF_COMPLIANT;
1404 codecContext->workaround_bugs = FF_BUG_AUTODETECT;
1405 codecContext->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
1406 codecContext->idct_algo = FF_IDCT_AUTO;
1407 codecContext->debug = 0;
1410 const AVCodec *codec1 = codecContext->codec;
1416 const AVPacketSideData *sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1417 stream->codecpar->nb_coded_side_data, AV_PKT_DATA_DISPLAYMATRIX);
1419 m_videoRotation =
static_cast<int>(-av_display_rotation_get(
reinterpret_cast<int32_t*
>(sd->data)));
1424 sd = av_packet_side_data_get(stream->codecpar->coded_side_data,
1425 stream->codecpar->nb_coded_side_data, AV_PKT_DATA_STEREO3D);
1428 auto * avstereo =
reinterpret_cast<AVStereo3D*
>(sd->data);
1453 bool doublerate =
true;
1457 if (codec1 && ((AV_CODEC_ID_MPEG2VIDEO == codec1->id) ||
1458 (AV_CODEC_ID_MPEG1VIDEO == codec1->id)))
1462 int total_blocks = (codecContext->height + 15) / 16;
1463 codecContext->skip_top = (total_blocks + 3) / 4;
1464 codecContext->skip_bottom = (total_blocks + 3) / 4;
1468 codecContext->lowres = 2;
1472 codecContext->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
1473 codecContext->skip_loop_filter = AVDISCARD_ALL;
1477 codecContext->skip_idct = AVDISCARD_ALL;
1489 if (!width || !height)
1491 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1492 "InitVideoCodec invalid dimensions, resetting decoder.");
1500 const AVCodec *codec2 = codecContext->codec;
1503 codecName = codec2->name;
1511 switch (codecContext->codec_id)
1513 case AV_CODEC_ID_H263:
1514 case AV_CODEC_ID_MPEG4:
1515 case AV_CODEC_ID_MSMPEG4V1:
1516 case AV_CODEC_ID_MSMPEG4V2:
1517 case AV_CODEC_ID_MSMPEG4V3:
1518 case AV_CODEC_ID_H263P:
1519 case AV_CODEC_ID_H263I:
1522 case AV_CODEC_ID_WMV1:
1523 case AV_CODEC_ID_WMV2:
1527 case AV_CODEC_ID_XVID:
1536 lcd->setVideoFormatLEDs(video_format,
true);
1548 static constexpr std::array<uint8_t, 256> odd_parity_LUT
1550 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1551 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1552 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1553 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1554 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1555 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1556 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1557 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1558 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1559 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1560 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1561 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1562 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1563 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1564 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1565 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1567 bool ret = (odd_parity_LUT[data & 0xff] == 1) &&
1568 (odd_parity_LUT[(data & 0xff00) >> 8] == 1);
1571 LOG(VB_VBI, LOG_ERR,
LOC +
1572 QString(
"VBI: Bad parity in EIA-608 data (%1)") .arg(data,0,16));
1579 if (program ==
nullptr)
1583 return program->pmt_section;
1588 AVProgram* program = av_find_program_from_stream(context,
nullptr, stream_index);
1602 if (!pmt_buffer.has_buffer())
1604 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
1605 "ScanATSCCaptionStreams() called with no PMT");
1610 bool video_found =
false;
1634 desc_list.insert(desc_list.end(), desc_list2.begin(), desc_list2.end());
1636 for (
auto & desc : desc_list)
1678 std::array<std::map<int,uint>,2> lang_cc_cnt;
1695 else if (!pofr && sofr)
1721 LOG(VB_GENERAL, LOG_ERR,
LOC +
"in_tracks key too small");
1727 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1728 QString(
"%1 caption service #%2 is in the %3 language.")
1729 .arg((
type) ?
"EIA-708" :
"EIA-608")
1745 AVStream* st =
m_ic->streams[av_index];
1746 const AVDictionaryEntry* language_dictionary_entry =
1747 av_dict_get(st->metadata,
"language",
nullptr, 0);
1749 if (language_dictionary_entry ==
nullptr ||
1750 language_dictionary_entry->value ==
nullptr ||
1751 st->codecpar->extradata ==
nullptr
1757 std::vector<std::string_view> languages {
StringUtil::split_sv(language_dictionary_entry->value,
","sv)};
1759 if (st->codecpar->extradata_size !=
static_cast<int>(languages.size() * 2))
1763 for (
size_t i = 0; i < languages.size(); i++)
1765 if (languages[i].size() != 3)
1771 uint8_t teletext_type = st->codecpar->extradata[i * 2] >> 3;
1772 uint8_t teletext_magazine_number = st->codecpar->extradata[i * 2] & 0x7;
1773 if (teletext_magazine_number == 0)
1774 teletext_magazine_number = 8;
1775 uint8_t teletext_page_number = st->codecpar->extradata[(i * 2) + 1];
1776 if (teletext_type == 2 || teletext_type == 1)
1778 TrackType track = (teletext_type == 2) ?
1781 m_tracks[track].emplace_back(av_index, 0, language,
1782 (
static_cast<unsigned>(teletext_magazine_number) << 8) | teletext_page_number);
1783 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1784 QString(
"Teletext stream #%1 (%2) is in the %3 language on page %4 %5.")
1785 .arg(QString::number(i),
1786 (teletext_type == 2) ?
"Caption" :
"Menu",
1788 QString::number(teletext_magazine_number),
1789 QString::number(teletext_page_number)));
1798 AVDictionaryEntry *metatag =
1799 av_dict_get(
m_ic->streams[av_stream_index]->metadata,
"language",
nullptr,
1801 bool forced = (
m_ic->streams[av_stream_index]->disposition & AV_DISPOSITION_FORCED) != 0;
1804 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1805 QString(
"Text Subtitle track #%1 is A/V stream #%2 "
1806 "and is in the %3 language(%4), forced=%5.")
1809 StreamInfo si {av_stream_index, 0, lang, 0, forced};
1819 if (
m_itv ==
nullptr)
1821 if (
m_itv ==
nullptr)
1825 if (!pmt_buffer.has_buffer())
1836 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams Found Object Carousel in Stream %1").arg(QString::number(i)));
1842 for (
const auto *desc : desc_list)
1845 uint length = *desc++;
1846 const unsigned char *endDesc = desc+length;
1847 uint dataBroadcastId = desc[0]<<8 | desc[1];
1848 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams dataBroadcastId %1").arg(QString::number(dataBroadcastId)));
1849 if (dataBroadcastId != 0x0106)
1852 while (desc != endDesc)
1854 [[maybe_unused]]
uint appTypeCode = desc[0]<<8 | desc[1];
1856 uint appSpecDataLen = *desc++;
1858 LOG(VB_DSMCC, LOG_NOTICE, QString(
"ScanDSMCCStreams AppTypeCode %1").arg(QString::number(appTypeCode)));
1859 if (appTypeCode == 0x101)
1861 const unsigned char *subDescEnd = desc + appSpecDataLen;
1862 while (desc < subDescEnd)
1864 uint sub_desc_tag = *desc++;
1865 uint sub_desc_len = *desc++;
1867 if (sub_desc_tag == 1)
1869 desc += sub_desc_len;
1873 #endif // USING_MHEG
1875 desc += appSpecDataLen;
1889 const AVCodec *codec =
nullptr;
1890 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Trying to select best video track");
1904 int stream_index = av_find_best_stream(
m_ic, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
1906 if (stream_index < 0)
1908 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No video track found/selected.");
1909 return stream_index;
1912 AVStream *stream =
m_ic->streams[stream_index];
1923 if (codecContext->codec_type == AVMEDIA_TYPE_VIDEO)
1924 codectype += QString(
"(%1x%2)").arg(codecContext->width).arg(codecContext->height);
1925 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
1926 QString(
"Selected track #%1: ID: 0x%2 Codec ID: %3 Profile: %4 Type: %5 Bitrate: %6")
1927 .arg(stream_index).arg(
static_cast<uint64_t
>(stream->id), 0, 16)
1928 .arg(avcodec_get_name(codecContext->codec_id),
1929 avcodec_profile_name(codecContext->codec_id, codecContext->profile),
1931 QString::number(codecContext->bit_rate)));
1938 if ((codecContext->width != stream->codecpar->width) || (codecContext->height != stream->codecpar->height))
1940 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
1941 "Video resolution mismatch: Context: %1x%2 Stream: %3x%4 Codec: %5 Stream change: %6")
1942 .arg(codecContext->width).arg(codecContext->height)
1943 .arg(stream->codecpar->width).arg(stream->codecpar->height)
1950 int width = std::max(dim.width(), 16);
1951 int height = std::max(dim.height(), 16);
1952 QString dec =
"ffmpeg";
1953 uint thread_count = 1;
1955 if (codecContext->codec)
1956 codecName = codecContext->codec->name;
1961 if (codecContext->framerate.den && codecContext->framerate.num)
1962 m_fps = float(codecContext->framerate.num) / float(codecContext->framerate.den);
1966 bool foundgpudecoder =
false;
1967 QStringList unavailabledecoders;
1977 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
1978 "GPU/hardware decoder '%1' failed - forcing software decode")
1985 while (unavailabledecoders.size() < 10)
1989 if (!unavailabledecoders.isEmpty())
1991 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Unavailable decoders: %1")
1992 .arg(unavailabledecoders.join(
",")));
1998 if (!skip_loop_filter)
1999 codecContext->skip_loop_filter = AVDISCARD_NONKEY;
2007 if (
version && allowgpu && dec !=
"ffmpeg")
2011 codecContext->opaque =
static_cast<void*
>(
this);
2016 codecContext->opaque =
static_cast<void*
>(
this);
2018 foundgpudecoder =
true;
2023 unavailabledecoders.append(dec);
2031 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown video codec - defaulting to MPEG2");
2048 if (!foundgpudecoder)
2050 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Using %1 CPUs for decoding")
2051 .arg(HAVE_THREADS ? thread_count : 1));
2052 codecContext->thread_count =
static_cast<int>(thread_count);
2067 return stream_index;
2072 AVProgram* program = av_find_program_from_stream(
m_ic,
nullptr, stream_index);
2073 if (program ==
nullptr)
2078 LOG(VB_PLAYBACK, LOG_INFO,
2079 QString(
"Removing streams not in Program %1 from track selection.")
2080 .arg(QString::number(program->id)));
2082 const auto *
const begin = program->stream_index;
2083 const auto *
const end = program->stream_index + program->nb_stream_indexes;
2087 LOG(VB_PLAYBACK, LOG_DEBUG,
2088 QString(
"Size before: %1").arg(QString::number(track_list.size())));
2089 track_list.erase(std::remove_if(track_list.begin(), track_list.end(),
2092 return std::find(begin, end, i.m_av_stream_index) == end;
2093 }), track_list.end());
2094 LOG(VB_PLAYBACK, LOG_DEBUG,
2095 QString(
"Size after: %1").arg(QString::number(track_list.size())));
2101 return (ch_layout.order == AV_CHANNEL_ORDER_CUSTOM) &&
2102 (ch_layout.nb_channels == 2) &&
2103 (ch_layout.u.map[0].id == AV_CHAN_FRONT_CENTER) &&
2104 (ch_layout.u.map[1].id == AV_CHAN_FRONT_CENTER);
2112 bool unknownbitrate =
false;
2116 constexpr std::array<TrackType, 6>
types {
2130 std::map<int,uint> lang_sub_cnt;
2131 uint subtitleStreamCount = 0;
2132 std::map<int,uint> lang_aud_cnt;
2133 uint audioStreamCount = 0;
2142 if (
m_ic ==
nullptr)
2145 for (
uint strm = 0; strm <
m_ic->nb_streams; strm++)
2147 AVCodecParameters *par =
m_ic->streams[strm]->codecpar;
2150 if (par->codec_type == AVMEDIA_TYPE_VIDEO)
2151 codectype += QString(
"(%1x%2)").arg(par->width).arg(par->height);
2152 QString program_id =
"null";
2153 if (av_find_program_from_stream(
m_ic,
nullptr, strm) !=
nullptr)
2155 program_id = QString::number(av_find_program_from_stream(
m_ic,
nullptr, strm)->
id);
2157 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2158 QString(
"Stream #%1: ID: 0x%2 Program ID: %3 Codec ID: %4 Type: %5 Bitrate: %6").arg(
2159 QString::number(strm),
2160 QString::number(
static_cast<uint64_t
>(
m_ic->streams[strm]->id), 16),
2162 avcodec_get_name(par->codec_id),
2164 QString::number(par->bit_rate))
2167 switch (par->codec_type)
2169 case AVMEDIA_TYPE_VIDEO:
2177 if (ctx && (ctx->hw_frames_ctx || ctx->hw_device_ctx))
2184 LOG(VB_GENERAL, LOG_ERR,
LOC +
2185 QString(
"Stream #%1 has an unknown video "
2186 "codec id, skipping.").arg(strm));
2198 if (par->bit_rate == 0)
2200 static constexpr int64_t s_baseBitrate { 1000000LL };
2202 if (par->width && par->height)
2204 static const int s_baseSize = 1920 * 1080;
2205 multiplier = ((par->width * par->height) + s_baseSize - 1) / s_baseSize;
2206 multiplier = std::max(multiplier, 1);
2208 par->bit_rate = s_baseBitrate * multiplier;
2209 unknownbitrate =
true;
2215 case AVMEDIA_TYPE_AUDIO:
2217 LOG(VB_GENERAL, LOG_INFO,
LOC +
2218 QString(
"codec %1 has %2 channels")
2219 .arg(avcodec_get_name(par->codec_id))
2220 .arg(par->ch_layout.nb_channels));
2225 case AVMEDIA_TYPE_SUBTITLE:
2227 if (par->codec_id == AV_CODEC_ID_DVB_TELETEXT)
2229 if (par->codec_id == AV_CODEC_ID_TEXT)
2233 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"subtitle codec (%1)")
2237 case AVMEDIA_TYPE_DATA:
2239 if (par->codec_id == AV_CODEC_ID_DVB_VBI)
2242 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"data codec (%1)")
2246 case AVMEDIA_TYPE_ATTACHMENT:
2248 if (par->codec_id == AV_CODEC_ID_TTF)
2251 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2252 QString(
"Attachment codec (%1)")
2259 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
2260 QString(
"Unknown codec type (%1)")
2266 if (par->codec_type != AVMEDIA_TYPE_AUDIO &&
2267 par->codec_type != AVMEDIA_TYPE_SUBTITLE)
2271 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE &&
2272 (par->codec_id == AV_CODEC_ID_DVB_TELETEXT ||
2273 par->codec_id == AV_CODEC_ID_TEXT))
2276 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Looking for decoder for %1")
2277 .arg(avcodec_get_name(par->codec_id)));
2279 if (par->codec_id == AV_CODEC_ID_PROBE)
2281 LOG(VB_GENERAL, LOG_ERR,
LOC +
2282 QString(
"Probing of stream #%1 unsuccesful, ignoring.").arg(strm));
2288 if (codecContext ==
nullptr)
2290 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2291 QString(
"Could not find decoder for codec (%1), ignoring.")
2292 .arg(avcodec_get_name(par->codec_id)));
2293 LOG(VB_LIBAV, LOG_INFO,
"For a list of all codecs, run `mythffmpeg -codecs`.");
2297 if (codecContext->codec && par->codec_id != codecContext->codec_id)
2299 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2300 QString(
"Already opened codec not matching (%1 vs %2). Reopening")
2301 .arg(avcodec_get_name(codecContext->codec_id),
2302 avcodec_get_name(codecContext->codec->id)));
2306 if (!
OpenAVCodec(codecContext, codecContext->codec))
2318 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2319 QString(
"Stream 0x%1 is not valid in this context - skipping")
2320 .arg(
m_ic->streams[strm]->id, 4, 16));
2324 if (par->codec_type == AVMEDIA_TYPE_SUBTITLE)
2326 bool forced = (
m_ic->streams[strm]->disposition & AV_DISPOSITION_FORCED) != 0;
2328 uint lang_indx = lang_sub_cnt[lang]++;
2329 subtitleStreamCount++;
2332 static_cast<int>(strm),
m_ic->streams[strm]->id, lang, lang_indx, forced);
2334 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2335 QString(
"Subtitle track #%1 is A/V stream #%2 "
2336 "and is in the %3 language(%4).")
2341 if (par->codec_type == AVMEDIA_TYPE_AUDIO)
2345 uint lang_indx = lang_aud_cnt[lang]++;
2348 int stream_id =
m_ic->streams[strm]->id;
2352 if (stream_id == -1)
2360 static_cast<int>(strm), stream_id, lang, lang_indx,
type);
2364 lang_indx = lang_aud_cnt[lang]++;
2366 static_cast<int>(strm), stream_id, lang, lang_indx,
type);
2369 LOG(VB_AUDIO, LOG_INFO,
LOC +
2370 QString(
"Audio Track #%1, of type (%2) is A/V stream #%3 (id=0x%4) "
2371 "and has %5 channels in the %6 language(%7).")
2373 .arg(strm).arg(
m_ic->streams[strm]->id,0,16).arg(codecContext->ch_layout.nb_channels)
2399 QString(
m_ic->iformat->name).contains(
"matroska"));
2441 for (
unsigned i = 0; i <
m_ic->nb_programs; i++)
2453 #ifdef USING_MEDIACODEC
2454 if (QString(
"mediacodec") == codec->wrapper_name)
2455 av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(),
nullptr);
2457 int ret = avcodec_open2(avctx, codec,
nullptr);
2462 LOG(VB_GENERAL, LOG_ERR,
LOC +
2463 QString(
"Could not open codec 0x%1, id(%2) type(%3) "
2464 "ignoring. reason %4").arg((uint64_t)avctx,0,16)
2465 .arg(avcodec_get_name(avctx->codec_id),
2471 LOG(VB_GENERAL, LOG_INFO,
LOC +
2472 QString(
"Opened codec 0x%1, id(%2) type(%3)")
2473 .arg((uint64_t)avctx,0,16)
2474 .arg(avcodec_get_name(avctx->codec_id),
2499 if (si.m_language_index == Index)
2500 return si.m_language;
2507 AVDictionaryEntry *metatag = av_dict_get(
m_ic->streams[StreamIndex]->metadata,
"language",
nullptr, 0);
2550 AVStream *stream =
m_ic->streams[StreamIndex];
2554 if (stream->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
2556 else if (stream->disposition & AV_DISPOSITION_COMMENT)
2558 else if (stream->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
2560 else if (stream->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
2587 if (
current->m_av_stream_index == streamIndex)
2593 LOG(VB_GENERAL, LOG_WARNING,
LOC +
2594 QString(
"Invalid stream index passed to "
2595 "SetupAudioStreamSubIndexes: %1").arg(streamIndex));
2602 if (
current->m_av_substream_index == -1)
2615 (next->m_av_stream_index != streamIndex))
2617 QString msg = QString(
2618 "Expected substream 1 (Language I) of stream %1\n\t\t\t"
2619 "following substream 0, found end of list or another stream.")
2622 LOG(VB_GENERAL, LOG_WARNING,
LOC + msg);
2644 bool do_flush =
false;
2645 for (
uint i = 0; i <
m_ic->nb_streams; i++)
2647 AVStream *st =
m_ic->streams[i];
2650 if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO)
2653 LOG(VB_LIBAV, LOG_DEBUG, QString(
"removing audio stream (id: 0x%1, index: %2, nb_streams: %3)")
2654 .arg(QString::number(st->id, 16),
2656 QString::number(
m_ic->nb_streams)
2660 if ((
m_ic->nb_streams - i) > 0) {
2661 std::memmove(
reinterpret_cast<void*
>(&
m_ic->streams[i]),
2662 reinterpret_cast<const void*
>(&
m_ic->streams[i + 1]),
2663 (
m_ic->nb_streams - i) *
sizeof(AVFormatContext*));
2667 m_ic->streams[i] =
nullptr;
2675 avformat_flush(
m_ic);
2684 if (!std::any_of(decoder->m_renderFormats->cbegin(), decoder->m_renderFormats->cend(),
2685 [&
type](
auto Format) { return type == Format; }))
2687 decoder->m_directRendering =
false;
2688 return avcodec_default_get_buffer2(c, pic, flags);
2691 decoder->m_directRendering =
true;
2692 MythVideoFrame *frame = decoder->GetPlayer()->GetNextVideoFrame();
2702 if ((frame->
m_type !=
type) || (pic->width > width) || (pic->height > height))
2719 for (
uint i = 0; i < 3; i++)
2725 pic->opaque = frame;
2728 AVBufferRef *buffer = av_buffer_create(
reinterpret_cast<uint8_t*
>(frame), 0,
2729 [](
void* Opaque, uint8_t* Data)
2733 if (avfd && avfd->GetPlayer())
2734 avfd->GetPlayer()->DeLimboFrame(vf);
2737 pic->buf[0] = buffer;
2748 for (
int i = 0; i < 4; i++)
2750 pic->data[i] =
nullptr;
2751 pic->linesize[i] = 0;
2753 pic->opaque = frame;
2755 pic->data[0] = (uint8_t*)frame->
m_buffer;
2756 pic->data[3] = (uint8_t*)frame->
m_buffer;
2759 AVBufferRef *buffer =
2760 av_buffer_create((uint8_t*)frame, 0,
2761 [](
void* Opaque, uint8_t* Data)
2769 pic->buf[0] = buffer;
2780 bool had_608 =
false;
2781 bool had_708 =
false;
2782 for (
uint cur = 0; cur + 2 < buf_size; cur += 3)
2784 uint cc_code = buf[cur];
2785 bool cc_valid = (cc_code & 0x04) != 0U;
2787 uint data1 = buf[cur+1];
2788 uint data2 = buf[cur+2];
2789 uint data = (data2 << 8) | data1;
2790 uint cc_type = cc_code & 0x03;
2817 bool check_608,
bool check_708)
2819 bool need_change_608 =
false;
2824 for (
uint i = 0; i < 4; i++)
2831 bool need_change_708 =
false;
2833 if (check_708 || need_change_608)
2836 for (
uint i = 1; i < 64 && !need_change_608 && !need_change_708; i++)
2841 if (need_change_708 && !check_608)
2845 if (!need_change_608 && !need_change_708)
2856 for (
int i = 1; i < 64; i++)
2865 for (
int i = 0; i < 4; i++)
2886 AVPacket *pkt,
bool can_reliably_parse_keyframes)
2891 bool reset_kfd =
false;
2895 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2896 "gopset not set, syncing positionMap");
2898 if (tempKeyFrameDist > 0 && !
m_livetv)
2900 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2901 QString(
"Initial key frame distance: %1.")
2907 else if (
m_keyframeDist != tempKeyFrameDist && tempKeyFrameDist > 0)
2909 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
2910 QString(
"Key frame distance changed from %1 to %2.")
2938 if (can_reliably_parse_keyframes &&
2941 long long last_frame = 0;
2949 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
2950 QString(
"framesRead: %1 last_frame: %2 keyframedist: %3")
2957 long long startpos = pkt->pos;
2959 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
2960 QString(
"positionMap[ %1 ] == %2.")
2990 float bytespersec = (float)
m_bitrate / 8;
3007 const uint8_t *bufptr = pkt->data;
3008 const uint8_t *bufend = pkt->data + pkt->size;
3010 while (bufptr < bufend)
3014 float aspect_override = -1.0F;
3023 if (bufptr + 11 >= pkt->data + pkt->size)
3025 const auto *seq =
reinterpret_cast<const SequenceHeader*
>(bufptr);
3027 int width =
static_cast<int>(seq->width()) >> context->lowres;
3028 int height =
static_cast<int>(seq->height()) >> context->lowres;
3029 float aspect = seq->
aspect(context->codec_id == AV_CODEC_ID_MPEG1VIDEO);
3030 if (stream->sample_aspect_ratio.num)
3031 aspect =
static_cast<float>(av_q2d(stream->sample_aspect_ratio) * width / height);
3032 if (aspect_override > 0.0F)
3033 aspect = aspect_override;
3034 float seqFPS = seq->fps();
3038 changed |= (seqFPS >
static_cast<float>(
m_fps)+0.01F) ||
3039 (seqFPS < static_cast<float>(
m_fps)-0.01F);
3043 bool forceaspectchange = !qFuzzyCompare(
m_currentAspect + 10.0F, aspect + 10.0F) &&
3047 if (changed || forceaspectchange)
3052 bool doublerate =
false;
3055 forceaspectchange, 2,
3058 if (context->hw_frames_ctx)
3059 if (context->internal)
3060 avcodec_flush_buffers(context);
3074 if ((seqFPS > avFPS+0.01F) || (seqFPS < avFPS-0.01F))
3076 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"avFPS(%1) != seqFPS(%2)")
3077 .arg(
static_cast<double>(avFPS)).arg(
static_cast<double>(seqFPS)));
3086 pkt->flags |= AV_PKT_FLAG_KEY;
3093 pkt->flags |= AV_PKT_FLAG_KEY;
3101 const uint8_t *buf = pkt->data;
3102 const uint8_t *buf_end = pkt->data + pkt->size;
3107 if (context->extradata && (context->extradata_size >= 7) && (context->extradata[0] == 0x01))
3109 if (pkt->flags & AV_PKT_FLAG_KEY)
3114 while (buf < buf_end)
3145 bool fps_changed = (seqFPS > 0.0) && ((seqFPS >
m_fps + 0.01) ||
3146 (seqFPS <
m_fps - 0.01));
3151 if (fps_changed || res_changed || forcechange)
3156 bool doublerate =
false;
3169 if (context->hw_frames_ctx && (forcechange || res_changed))
3170 if (context->internal)
3171 avcodec_flush_buffers(context);
3177 m_fps =
static_cast<float>(seqFPS);
3187 if ((seqFPS > avFPS + 0.01) || (seqFPS < avFPS - 0.01))
3189 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
3190 QString(
"avFPS(%1) != seqFPS(%2)").arg(avFPS).arg(seqFPS));
3195 pkt->flags |= AV_PKT_FLAG_KEY;
3215 if (pkt->flags & AV_PKT_FLAG_KEY)
3231 !(pkt->flags & AV_PKT_FLAG_KEY))
3233 av_packet_unref(pkt);
3267 bool sentPacket =
false;
3287 if (ret == AVERROR(EAGAIN))
3291 if (ret==0 && !gotpicture)
3293 ret2 = avcodec_send_packet(context, pkt);
3294 if (ret2 == AVERROR(EAGAIN))
3306 if (ret < 0 || ret2 < 0)
3311 LOG(VB_GENERAL, LOG_ERR,
LOC +
3312 QString(
"video avcodec_receive_frame error: %1 (%2) gotpicture:%3")
3314 .arg(ret).arg(gotpicture));
3319 LOG(VB_GENERAL, LOG_ERR,
LOC +
3320 QString(
"video avcodec_send_packet error: %1 (%2) gotpicture:%3")
3322 .arg(ret2).arg(gotpicture));
3336 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Decoder needs reset");
3340 if (ret == AVERROR_EXTERNAL || ret2 == AVERROR_EXTERNAL)
3342 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"FFmpeg external library error - assuming streams changed");
3354 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3355 QString(
"video timecodes packet-pts:%1 frame-pts:%2 packet-dts: %3 frame-dts:%4")
3356 .arg(pkt->pts).arg(mpa_pic->pts).arg(pkt->pts)
3357 .arg(mpa_pic->pkt_dts));
3366 auto *newPkt = av_packet_clone(pkt);
3376 auto * side_data = av_frame_get_side_data(AvFrame, AV_FRAME_DATA_A53_CC);
3377 if (side_data && (side_data->size > 0))
3390 frame->m_directRendering =
false;
3401 av_image_fill_arrays(tmppicture.data, tmppicture.linesize,
3402 frame->m_buffer, AV_PIX_FMT_YUV420P, AvFrame->width,
3403 AvFrame->height, IMAGE_ALIGN);
3404 tmppicture.data[0] = frame->m_buffer + frame->m_offsets[0];
3405 tmppicture.data[1] = frame->m_buffer + frame->m_offsets[1];
3406 tmppicture.data[2] = frame->m_buffer + frame->m_offsets[2];
3407 tmppicture.linesize[0] = frame->m_pitches[0];
3408 tmppicture.linesize[1] = frame->m_pitches[1];
3409 tmppicture.linesize[2] = frame->m_pitches[2];
3413 AvFrame->height,
static_cast<AVPixelFormat
>(AvFrame->format),
3414 AvFrame->width, AvFrame->height,
3415 AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR,
3416 nullptr,
nullptr,
nullptr);
3419 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate sws context");
3422 sws_scale(
m_swsCtx, AvFrame->data, AvFrame->linesize, 0, dim.height(),
3423 tmppicture.data, tmppicture.linesize);
3431 oldframe->
m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3432 oldframe->
m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3458 LOG(VB_GENERAL, LOG_ERR,
LOC +
"NULL videoframe - direct rendering not "
3459 "correctly initialized.");
3464 if (AvFrame->best_effort_timestamp == AV_NOPTS_VALUE)
3466 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process video.");
3470 AvFrame->best_effort_timestamp * 1000);
3471 std::chrono::milliseconds temppts =
pts;
3488 double calcfps = 1000.0 /
ptsdiff.count();
3489 if (calcfps < 121.0 && calcfps > 3.0)
3493 double fpschange = calcfps /
m_fps;
3495 if (fpschange > 1.9 && fpschange < 2.1)
3497 if (fpschange > 0.9 && fpschange < 1.1)
3503 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3504 QString(
"video timecode %1 %2 %3 %4%5")
3505 .arg(AvFrame->best_effort_timestamp)
3506 .arg(
pts.count()).arg(temppts.count()).arg(
m_lastVPts.count())
3507 .arg((
pts != temppts) ?
" fixup" :
""));
3509 frame->m_interlaced = (AvFrame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
3510 frame->m_topFieldFirst = (AvFrame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0;
3512 frame->m_repeatPic = AvFrame->repeat_pict != 0;
3517 frame->m_colorspace = AvFrame->colorspace;
3518 frame->m_colorrange = AvFrame->color_range;
3519 frame->m_colorprimaries = AvFrame->color_primaries;
3520 frame->m_colortransfer = AvFrame->color_trc;
3521 frame->m_chromalocation = AvFrame->chroma_location;
3522 frame->m_pixFmt = AvFrame->format;
3527 frame->m_dummy =
false;
3528 frame->m_pauseFrame =
false;
3529 frame->m_deinterlaceInuse2x =
false;
3530 frame->m_alreadyDeinterlaced =
false;
3531 frame->m_interlacedReverse =
false;
3561 [[maybe_unused]]
const AVStream *stream,
const AVPacket *pkt)
3563 const uint8_t *buf = pkt->data;
3564 uint64_t linemask = 0;
3569 if ((buf[0]==
't') && (buf[1]==
'v') && (buf[2] ==
'0'))
3572 memcpy(&linemask, buf + 3, 8);
3575 else if ((buf[0]==
'T') && (buf[1]==
'V') && (buf[2] ==
'0'))
3577 linemask = 0xffffffffffffffffLL;
3582 LOG(VB_VBI, LOG_ERR,
LOC + QString(
"Unknown VBI data stream '%1%2%3'")
3583 .arg(QChar(buf[0])).arg(QChar(buf[1])).arg(QChar(buf[2])));
3587 static constexpr
uint kMinBlank = 6;
3588 for (
uint i = 0; i < 36; i++)
3590 if (!((linemask >> i) & 0
x1))
3593 const uint line = ((i < 18) ? i : i-18) + kMinBlank;
3594 const uint field = (i<18) ? 0 : 1;
3595 const uint id2 = *buf & 0xf;
3619 int data = (buf[2] << 8) | buf[1];
3646 const AVStream* ,
const AVPacket *pkt)
3655 const uint8_t *buf = pkt->data;
3656 const uint8_t *buf_end = pkt->data + pkt->size;
3658 if (*buf >= 0x10 && *buf <= 0x1F)
3664 LOG(VB_VBI, LOG_WARNING,
LOC +
3665 QString(
"VBI: Unknown data_identier: %1 discarded").arg(*buf));
3670 while (buf < buf_end)
3675 if ((buf_end - buf) >= 42)
3679 else if (*buf == 0x03)
3682 if ((buf_end - buf) >= 42)
3686 else if (*buf == 0xff)
3692 LOG(VB_VBI, LOG_WARNING,
LOC +
3693 QString(
"VBI: Unsupported data_unit_id: %1 discarded").arg(*buf));
3703 [[maybe_unused]]
const AVPacket *pkt)
3706 if (
m_itv ==
nullptr)
3708 if (
m_itv ==
nullptr)
3712 uint8_t *data = pkt->data;
3713 int length = pkt->size;
3714 int componentTag = 0;
3715 int dataBroadcastId = 0;
3716 unsigned carouselId = 0;
3719 componentTag = str->component_tag;
3720 dataBroadcastId = str->data_id;
3721 carouselId = (unsigned) str->carousel_id;
3726 uint16_t sectionLen = (((data[1] & 0xF) << 8) | data[2]) + 3;
3728 if (sectionLen > length)
3732 componentTag, carouselId,
3734 length -= sectionLen;
3737 #endif // USING_MHEG
3745 long long pts = pkt->pts;
3746 if (
pts == AV_NOPTS_VALUE)
3748 if (
pts == AV_NOPTS_VALUE)
3750 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No PTS found - unable to process subtitle.");
3753 pts =
static_cast<long long>(av_q2d(curstream->time_base) *
pts * 1000);
3759 bool isForcedTrack =
false;
3762 int gotSubtitles = 0;
3763 AVSubtitle subtitle;
3764 memset(&subtitle, 0,
sizeof(AVSubtitle));
3771 curstream->id,
pts);
3775 if (pkt->stream_index == subIdx)
3779 pkt->data, pkt->size,
pts);
3785 || pkt->stream_index == forcedSubIdx)
3788 avcodec_decode_subtitle2(codecContext, &subtitle, &gotSubtitles, pkt);
3791 subtitle.start_display_time +=
pts;
3792 subtitle.end_display_time +=
pts;
3794 if (pkt->stream_index != subIdx)
3795 isForcedTrack =
true;
3802 for (
unsigned i = 0; i < subtitle.num_rects; i++)
3804 subtitle.rects[i]->flags |= AV_SUBTITLE_FLAG_FORCED;
3807 LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO,
LOC +
3808 QString(
"subtl timecode %1 %2 %3 %4")
3809 .arg(pkt->pts).arg(pkt->dts)
3810 .arg(subtitle.start_display_time)
3811 .arg(subtitle.end_display_time));
3814 subtitle, curstream->codecpar->codec_id == AV_CODEC_ID_XSUB,
3828 auto id =
static_cast<uint>(Packet->stream_index + 0x2000);
3832 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
3833 const auto * codec = QTextCodec::codecForName(
"utf-8");
3834 auto text = codec->toUnicode(
reinterpret_cast<const char *
>(Packet->data), Packet->size - 1);
3836 auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
3837 QString text = toUtf16.decode(Packet->data);
3839 auto list = text.split(
'\n', Qt::SkipEmptyParts);
3847 enum AVCodecID codec_id = curstream->codecpar->codec_id;
3851 case AV_CODEC_ID_MPEG2VBI:
3854 case AV_CODEC_ID_DVB_VBI:
3857 case AV_CODEC_ID_DSMCC_B:
3866 #endif // USING_MHEG:
3882 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio stream type " + msg +
"changed.");
3896 QString forcedString = forced ? QObject::tr(
" (forced)") :
"";
3898 int av_index =
m_tracks[
type][TrackNo].m_av_stream_index;
3899 AVStream *stream {
nullptr };
3900 if (av_index >= 0 && av_index < (
int)
m_ic->nb_streams)
3901 stream =
m_ic->streams[av_index];
3902 AVDictionaryEntry *entry =
3903 stream ? av_dict_get(stream->metadata,
"title",
nullptr, 0) :
nullptr;
3904 QString user_title = entry ? QString(R
"( "%1")").arg(entry->value) : "";
3916 AVCodecParameters *par = stream->codecpar;
3918 if (par->codec_id == AV_CODEC_ID_MP3)
3919 msg += QString(
" MP3");
3920 else if (ctx && ctx->codec)
3921 msg += QString(
" %1").arg(ctx->codec->name).toUpper();
3922 if (!user_title.isEmpty())
3925 int channels = par->ch_layout.nb_channels;
3928 msg += QString(
" ?ch");
3929 else if((channels > 4) && !(channels & 1))
3930 msg += QString(
" %1.1ch").arg(channels - 1);
3932 msg += QString(
" %1ch").arg(channels);
3942 if (!user_title.isEmpty())
3945 msg += QString(
" (%1)")
3949 return QString(
"%1: %2").arg(TrackNo + 1).arg(msg);
3953 return QObject::tr(
"Subtitle") + QString(
" %1: %2%3%4")
3954 .arg(QString::number(TrackNo + 1),
3982 return ctx ? QByteArray(
reinterpret_cast<char*
>(ctx->subtitle_header), ctx->subtitle_header_size) :
3993 AVDictionaryEntry *tag = av_dict_get(
m_ic->streams[index]->metadata,
"filename",
nullptr, 0);
3995 Filename = QByteArray(tag->value);
3996 AVCodecParameters *par =
m_ic->streams[index]->codecpar;
3997 Data = QByteArray(
reinterpret_cast<char*
>(par->extradata), par->extradata_size);
4007 if ((stream->component_tag == Tag) || ((Tag <= 0) && stream->component_tag <= 0))
4016 for (
uint i = 0; i <
m_ic->nb_streams; i++)
4018 AVStream *stream =
m_ic->streams[i];
4021 if (stream->component_tag == Tag)
4045 const std::vector<int> &ftype)
4047 std::vector<int> ret;
4049 for (
int index : ftype)
4051 if ((lang_key < 0) || tracks[index].m_language == lang_key)
4052 ret.push_back(index);
4060 std::vector<int> ret;
4062 for (
size_t i = 0; i < tracks.size(); i++)
4064 if (tracks[i].m_audio_type ==
type)
4073 const std::vector<int>&fs,
4074 enum AVCodecID codecId,
4077 int selectedTrack = -1;
4082 const int stream_index = tracks[f].m_av_stream_index;
4083 AVCodecParameters *par = ic->streams[stream_index]->codecpar;
4084 if ((codecId == AV_CODEC_ID_NONE || codecId == par->codec_id) &&
4085 (max_seen < par->ch_layout.nb_channels))
4087 if (codecId == AV_CODEC_ID_DTS &&
profile > 0)
4094 max_seen = par->ch_layout.nb_channels;
4098 return selectedTrack;
4106 std::vector<int> flang =
filter_lang(atracks, lang_key, ftype);
4111 FF_PROFILE_DTS_HD_MA);
4122 FF_PROFILE_DTS_HD_HRA);
4198 uint numStreams = atracks.size();
4202 if ((ctrack >= 0) && (ctrack < (
int)numStreams))
4205 LOG(VB_AUDIO, LOG_DEBUG, QString(
"%1 available audio streams").arg(numStreams));
4206 for (
const auto & track : atracks)
4208 AVCodecParameters *codecpar =
m_ic->streams[track.m_av_stream_index]->codecpar;
4209 LOG(VB_AUDIO, LOG_DEBUG, QString(
"%1: %2 bps, %3 Hz, %4 channels, passthrough(%5)")
4210 .arg(avcodec_get_name(codecpar->codec_id), QString::number(codecpar->bit_rate),
4211 QString::number(codecpar->sample_rate), QString::number(codecpar->ch_layout.nb_channels),
4216 if (1 == numStreams)
4226 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio sub-stream");
4232 for (
uint i = 0; i < numStreams; i++)
4234 if (atracks[i].m_av_substream_index == substream_index)
4242 if ((selTrack < 0) && wlang >= -1)
4244 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to reselect audio track");
4249 for (
uint i = 0; i < numStreams; i++)
4251 if (wlang == atracks[i].m_language)
4255 if (windx == atracks[i].m_language_index)
4263 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select audio track (w/lang)");
4270 LOG(VB_AUDIO, LOG_WARNING,
"No audio tracks matched the type filter, "
4271 "so trying all tracks.");
4272 for (
int i = 0; i < static_cast<int>(atracks.size()); i++)
4298 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Trying to select default track");
4299 for (
size_t i = 0; i < atracks.size(); i++) {
4300 int idx = atracks[i].m_av_stream_index;
4301 if (
m_ic->streams[idx]->disposition & AV_DISPOSITION_DEFAULT)
4312 LOG(VB_AUDIO, LOG_INFO,
LOC +
4313 "Trying to select audio track (wo/lang)");
4323 if (ctrack != selTrack)
4325 LOG(VB_AUDIO, LOG_INFO,
LOC +
"No suitable audio track exists.");
4332 strack = atracks[selTrack];
4337 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Selected track %1 (A/V Stream #%2)")
4346 char *buffer,
int bufsize)
4357 const uint halfsample = samplesize >> 1;
4359 const char *from = (channel == 1) ? buffer + halfsample : buffer;
4360 char *to = (channel == 0) ? buffer + halfsample : buffer;
4363 (sample++), (from += samplesize), (to += samplesize))
4365 memmove(to, from, halfsample);
4374 bool firstloop =
true;
4375 int decoded_size = -1;
4382 AVPacket *tmp_pkt = av_packet_alloc();
4383 tmp_pkt->data = pkt->data;
4384 tmp_pkt->size = pkt->size;
4385 while (tmp_pkt->size > 0)
4387 bool reselectAudioTrack =
false;
4392 LOG(VB_AUDIO, LOG_INFO,
LOC +
4393 "Audio is disabled - trying to restart it");
4394 reselectAudioTrack =
true;
4399 bool wasDual = audSubIdx != -1;
4401 if ((wasDual && !isDual) || (!wasDual && isDual))
4404 reselectAudioTrack =
true;
4409 bool already_decoded =
false;
4410 if (!context->ch_layout.nb_channels)
4422 AVChannelLayout channel_layout;
4424 av_opt_set_chlayout(context->priv_data,
"downmix", &channel_layout, 0);
4426 if (context->codec_id == AV_CODEC_ID_AC3)
4431 decoded_size = data_size;
4432 already_decoded =
true;
4433 reselectAudioTrack |= context->ch_layout.nb_channels;
4437 if (reselectAudioTrack)
4447 if (!(decodetype &
kDecodeAudio) || (pkt->stream_index != audIdx)
4451 if (firstloop && pkt->pts != AV_NOPTS_VALUE)
4464 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Audio stream changed");
4467 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Number of audio channels changed from %1 to %2")
4479 if (!already_decoded)
4484 decoded_size = data_size;
4492 data_size = tmp_pkt->size;
4498 if (!already_decoded)
4502 AVChannelLayout channel_layout;
4504 av_opt_set_chlayout(context->priv_data,
"downmix", &channel_layout, 0);
4508 decoded_size = data_size;
4515 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown audio decoding error");
4516 av_packet_free(&tmp_pkt);
4522 tmp_pkt->data += ret;
4523 tmp_pkt->size -= ret;
4527 std::chrono::milliseconds temppts =
m_lastAPts;
4534 int frames = (context->ch_layout.nb_channels <= 0 || decoded_size < 0 || !samplesize) ? -1 :
4535 decoded_size / (context->ch_layout.nb_channels * samplesize);
4544 ((
double)(frames * 1000) / context->sample_rate);
4547 LOG(VB_TIMESTAMP, LOG_INFO,
LOC + QString(
"audio timecode %1 %2 %3 %4")
4548 .arg(pkt->pts).arg(pkt->dts).arg(temppts.count()).arg(
m_lastAPts.count()));
4553 tmp_pkt->data += ret;
4554 tmp_pkt->size -= ret;
4558 av_packet_free(&tmp_pkt);
4565 AVPacket *pkt =
nullptr;
4566 bool have_err =
false;
4568 const DecodeType origDecodetype = decodetype;
4576 bool storevideoframes =
false;
4643 storevideoframes =
true;
4649 LOG(VB_GENERAL, LOG_WARNING,
LOC +
4650 QString(
"Audio %1 ms behind video but already %2 "
4651 "video frames queued. AV-Sync might be broken.")
4662 av_packet_free(&pkt);
4668 pkt = av_packet_alloc();
4671 if (
m_ic !=
nullptr)
4673 if ((
m_ic ==
nullptr) || (retval < 0))
4675 if (retval == -EAGAIN)
4679 av_packet_free(&pkt);
4681 LOG(VB_GENERAL, LOG_ERR, QString(
"decoding error %1 (%2)")
4683 QString::number(retval)));
4696 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No context");
4697 av_packet_unref(pkt);
4701 if (pkt->stream_index >= (
int)
m_ic->nb_streams)
4703 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream");
4704 av_packet_unref(pkt);
4708 AVStream *curstream =
m_ic->streams[pkt->stream_index];
4712 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Bad stream (NULL)");
4713 av_packet_unref(pkt);
4717 enum AVMediaType codec_type = curstream->codecpar->codec_type;
4718 const AVCodecID codec_id = curstream->codecpar->codec_id;
4724 case AVMEDIA_TYPE_VIDEO:
4725 if (storevideoframes)
4732 case AVMEDIA_TYPE_AUDIO:
4734 if (codec_id == AV_CODEC_ID_AC4)
4736 av_packet_unref(pkt);
4740 case AVMEDIA_TYPE_SUBTITLE:
4743 case AV_CODEC_ID_TEXT:
4745 av_packet_unref(pkt);
4747 case AV_CODEC_ID_DVB_TELETEXT:
4749 av_packet_unref(pkt);
4755 case AVMEDIA_TYPE_DATA:
4757 av_packet_unref(pkt);
4765 if (context ==
nullptr)
4767 if (codec_type != AVMEDIA_TYPE_VIDEO)
4769 LOG(VB_PLAYBACK, LOG_ERR,
LOC +
4770 QString(
"No codec for stream index %1, type(%2) id(%3:%4)")
4771 .arg(QString::number(pkt->stream_index),
4773 avcodec_get_name(codec_id),
4774 QString::number(codec_id)
4781 av_packet_unref(pkt);
4789 case AVMEDIA_TYPE_AUDIO:
4798 case AVMEDIA_TYPE_VIDEO:
4812 av_packet_free(&pkt);
4816 if (pkt->pts != AV_NOPTS_VALUE)
4819 (av_q2d(curstream->time_base)*pkt->pts*1000000);
4834 case AVMEDIA_TYPE_SUBTITLE:
4843 LOG(VB_GENERAL, LOG_ERR,
LOC +
4844 QString(
"Decoding - id(%1) type(%2)")
4845 .arg(avcodec_get_name(codec_id),
4852 if (!have_err && !Retry)
4854 av_packet_unref(pkt);
4859 av_packet_free(&pkt);
4867 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"StreamChangeCheck skip SeekReset"));
4877 int result = av_read_frame(ctx, pkt);
4885 if (pmt_buffer.has_buffer())
4942 if (stream < 0 || !
m_ic)
4944 return avcodec_get_name(
m_ic->streams[stream]->codecpar->codec_id);
4958 QString msg = (disable) ?
"Disabling" :
"Allowing";
4959 LOG(VB_AUDIO, LOG_INFO,
LOC + msg +
" pass through");
4982 switch (ctx->codec_id)
4984 case AV_CODEC_ID_AC3:
4985 case AV_CODEC_ID_TRUEHD:
4986 case AV_CODEC_ID_EAC3:
4987 case AV_CODEC_ID_MLP:
4988 case AV_CODEC_ID_DTS:
4997 bool passthru =
false;
5001 if (!withProfile && par->codec_id == AV_CODEC_ID_DTS && !
m_audio->
CanDTSHD())
5004 par->codec_id, FF_PROFILE_DTS);
5009 par->codec_id, par->profile);
5025 AVStream *curstream =
nullptr;
5026 AVCodecContext *ctx =
nullptr;
5028 int requested_channels = 0;
5032 (
int)
m_ic->nb_streams))
5035 .m_av_stream_index];
5036 if (curstream !=
nullptr)
5043 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"No codec context. Returning false");
5049 ctx->bits_per_raw_sample);
5051 if (av_sample_fmt_is_planar(ctx->sample_fmt))
5053 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Audio data is planar"));
5058 int bps = av_get_bytes_per_sample(ctx->sample_fmt) << 3;
5059 if (ctx->sample_fmt == AV_SAMPLE_FMT_S32 &&
5060 ctx->bits_per_raw_sample)
5061 bps = ctx->bits_per_raw_sample;
5062 LOG(VB_GENERAL, LOG_ERR,
LOC +
5063 QString(
"Unsupported sample format with %1 bits").arg(bps));
5067 bool using_passthru =
DoPassThrough(curstream->codecpar,
false);
5069 requested_channels = ctx->ch_layout.nb_channels;
5071 if (!using_passthru &&
5077 AVChannelLayout channel_layout;
5078 av_channel_layout_default(&channel_layout, requested_channels);
5079 av_opt_set_chlayout(ctx->priv_data,
"downmix", &channel_layout, 0);
5083 requested_channels, using_passthru, ctx->ch_layout.nb_channels,
5084 ctx->codec_id == AV_CODEC_ID_DTS ? ctx->profile : 0);
5088 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Initializing audio parms from " +
5093 LOG(VB_AUDIO, LOG_INFO,
LOC +
"Audio format changed " +
5094 QString(
"\n\t\t\tfrom %1 to %2")
5110 switch (ctx->codec_id)
5112 case AV_CODEC_ID_MP2:
5115 case AV_CODEC_ID_MP3:
5118 case AV_CODEC_ID_AC3:
5121 case AV_CODEC_ID_DTS:
5124 case AV_CODEC_ID_VORBIS:
5127 case AV_CODEC_ID_WMAV1:
5130 case AV_CODEC_ID_WMAV2:
5138 lcd->setAudioFormatLEDs(audio_format,
true);
5173 int64_t start_time = INT64_MAX;
5174 int64_t end_time = INT64_MIN;
5175 AVStream *st =
nullptr;
5177 for (
uint i = 0; i < ic->nb_streams; i++)
5179 AVStream *st1 = ic->streams[i];
5180 if (st1 && st1->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
5189 int64_t duration = INT64_MIN;
5190 if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
5191 int64_t start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
5192 start_time = std::min(start_time1, start_time);
5193 if (st->duration != AV_NOPTS_VALUE) {
5194 int64_t end_time1 = start_time1 +
5195 av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5196 end_time = std::max(end_time1, end_time);
5199 if (st->duration != AV_NOPTS_VALUE) {
5200 int64_t duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
5201 duration = std::max(duration1, duration);
5203 if (start_time != INT64_MAX) {
5204 ic->start_time = start_time;
5205 if (end_time != INT64_MIN) {
5206 duration = std::max(end_time - start_time, duration);
5209 if (duration != INT64_MIN) {
5210 ic->duration = duration;
5213 int64_t filesize = avio_size(ic->pb);
5216 ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
5217 (
double)ic->duration;
5233 if (
m_ic ==
nullptr)
5238 if (program ==
nullptr)