36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wconversion"
38#pragma GCC diagnostic ignored "-Wsign-conversion"
39#include <libswscale/swscale.h>
40#include <libavutil/imgutils.h>
41#include <libavutil/opt.h>
42#include <libavutil/audio_fifo.h>
43#include <libavfilter/avfilter.h>
44#include <libavfilter/buffersink.h>
45#include <libavfilter/buffersrc.h>
46#include <libavcodec/avcodec.h>
47#include <libavformat/avformat.h>
48#include <libavformat/avio.h>
49#include <libavutil/file.h>
50#include <libswresample/swresample.h>
51#pragma GCC diagnostic pop
67#define FRAME_SEEK_THRESHOLD 25
72 { 720, 486, { { 24,
false } }, { 10, 23, 34, 50, 75, 113 } },
73 { 720, 486, { { 60,
true }, { 30,
false } }, { 12, 29, 42, 63, 94, 141 } },
75 { 720, 576, { { 50,
true }, { 25,
false } }, { 12, 28, 41, 61, 92, 138 } },
77 { 960, 720, { { 24,
false } }, { 15, 35, 50, 75, 113, 170 } },
78 { 960, 720, { { 25,
false } }, { 16, 36, 52, 79, 118, 177 } },
79 { 960, 720, { { 30,
false } }, { 19, 44, 63, 94, 141, 212 } },
80 { 960, 720, { { 50,
false } }, { 32, 73, 105, 157, 236, 354 } },
81 { 960, 720, { { 60,
false } }, { 38, 87, 126, 189, 283, 424 } },
83 { 1280, 720, { { 24,
false } }, { 18, 41, 59, 88, 132, 198 } },
84 { 1280, 720, { { 25,
false } }, { 19, 42, 61, 92, 138, 206 } },
85 { 1280, 720, { { 30,
false } }, { 23, 51, 73, 110, 165, 247 } },
86 { 1280, 720, { { 50,
false } }, { 38, 84, 122, 184, 275, 413 } },
87 { 1280, 720, { { 60,
false } }, { 45, 101, 147, 220, 330, 495 } },
89 { 1280, 1080, { { 24,
false } }, { 31, 70, 101, 151, 226, 339 } },
90 { 1280, 1080, { { 60,
true }, { 30,
false } }, { 38, 87, 126, 189, 283, 424 } },
92 { 1440, 1080, { { 24,
false } }, { 31, 70, 101, 151, 226, 339 } },
93 { 1440, 1080, { { 50,
true }, { 25,
false } }, { 32, 73, 105, 157, 236, 354 } },
94 { 1440, 1080, { { 60,
true }, { 30,
false } }, { 38, 87, 126, 189, 283, 424 } },
96 { 1920, 1080, { { 24,
false } }, { 36, 82, 117, 176, 264, 396 } },
97 { 1920, 1080, { { 50,
true }, { 25,
false } }, { 38, 85, 122, 184, 275, 413 } },
98 { 1920, 1080, { { 60,
true }, { 30,
false } }, { 45, 102, 147, 220, 330, 495 } },
99 { 1920, 1080, { { 50,
false } }, { 76, 170, 245, 367, 551, 826 } },
100 { 1920, 1080, { { 60,
false } }, { 91, 204, 293, 440, 660, 990 } },
102 { 2048, 1080, { { 24,
false } }, { 41, 93, 134, 201, 302, 453 } },
103 { 2048, 1080, { { 25,
false } }, { 43, 97, 140, 210, 315, 472 } },
104 { 2048, 1080, { { 30,
false } }, { 52, 116, 168, 251, 377, 566 } },
105 { 2048, 1080, { { 50,
false } }, { 86, 194, 280, 419, 629, 944 } },
106 { 2048, 1080, { { 60,
false } }, { 103, 232, 335, 503, 754, 1131 } },
108 { 2048, 1556, { { 24,
false } }, { 56, 126, 181, 272, 407, 611 } },
109 { 2048, 1556, { { 25,
false } }, { 58, 131, 189, 283, 425, 637 } },
110 { 2048, 1556, { { 30,
false } }, { 70, 157, 226, 340, 509, 764 } },
111 { 2048, 1556, { { 50,
false } }, { 117, 262, 377, 567, 850, 1275 } },
112 { 2048, 1556, { { 60,
false } }, { 140, 314, 452, 679, 1019, 1528 } },
114 { 3840, 2160, { { 24,
false } }, { 145, 328, 471, 707, 1061, 1591 } },
115 { 3840, 2160, { { 25,
false } }, { 151, 342, 492, 737, 1106, 1659 } },
116 { 3840, 2160, { { 30,
false } }, { 182, 410, 589, 884, 1326, 1989 } },
117 { 3840, 2160, { { 50,
false } }, { 303, 684, 983, 1475, 2212, 3318 } },
118 { 3840, 2160, { { 60,
false } }, { 363, 821, 1178, 1768, 2652, 3977 } },
120 { 4096, 2160, { { 24,
false } }, { 155, 350, 503, 754, 1131, 1697 } },
121 { 4096, 2160, { { 25,
false } }, { 162, 365, 524, 786, 1180, 1769 } },
122 { 4096, 2160, { { 30,
false } }, { 194, 437, 629, 943, 1414, 2121 } },
123 { 4096, 2160, { { 50,
false } }, { 323, 730, 1049, 1573, 2359, 3539 } },
124 { 4096, 2160, { { 60,
false } }, { 388, 875, 1257, 1886, 2828, 4242 } },
126 { 5120, 2700, { { 24,
false } }, { 243, 547, 786, 1178, 1768, 2652 } },
127 { 5120, 2700, { { 25,
false } }, { 253, 570, 819, 1229, 1843, 2765 } },
128 { 5120, 2700, { { 30,
false } }, { 304, 684, 982, 1473, 2210, 3314 } },
129 { 5120, 2700, { { 50,
false } }, { 507, 1140, 1638, 2458, 3686, 5530 } },
130 { 5120, 2700, { { 60,
false } }, { 608, 1367, 1964, 2946, 4419, 6629 } },
132 { 6144, 3240, { { 24,
false } }, { 350, 788, 1131, 1697, 2545, 3818 } },
133 { 6144, 3240, { { 25,
false } }, { 365, 821, 1180, 1769, 2654, 3981 } },
134 { 6144, 3240, { { 30,
false } }, { 437, 985, 1414, 2121, 3182, 4772 } },
135 { 6144, 3240, { { 50,
false } }, { 730, 1643, 2359, 3539, 5308, 7962 } },
136 { 6144, 3240, { { 60,
false } }, { 875, 1969, 2828, 4242, 6364, 9545 } },
138 { 8192, 4320, { { 24,
false } }, { 622, 1400, 2011, 3017, 4525, 6788 } },
139 { 8192, 4320, { { 25,
false } }, { 649, 1460, 2097, 3146, 4719, 7078 } },
140 { 8192, 4320, { { 30,
false } }, { 778, 1750, 2514, 3771, 5657, 8485 } },
141 { 8192, 4320, { { 50,
false } }, { 1298, 2920, 4194, 6291, 9437, 14156 } },
142 { 8192, 4320, { { 60,
false } }, { 1556, 3500, 5028, 7542, 11313, 16970 } }
147 { AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_NV12 },
149 { AV_HWDEVICE_TYPE_CUDA, AV_PIX_FMT_CUDA },
150 { AV_HWDEVICE_TYPE_VDPAU, AV_PIX_FMT_YUV420P },
151 { AV_HWDEVICE_TYPE_QSV, AV_PIX_FMT_QSV },
152 { AV_HWDEVICE_TYPE_OPENCL, AV_PIX_FMT_OPENCL },
153 #if HAVE_VULKAN_HWACCEL
154 { AV_HWDEVICE_TYPE_VULKAN, AV_PIX_FMT_VULKAN },
157 { AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX },
160 { AV_HWDEVICE_TYPE_MEDIACODEC, AV_PIX_FMT_MEDIACODEC },
163 { AV_HWDEVICE_TYPE_DRM, AV_PIX_FMT_DRM_PRIME },
164 { AV_HWDEVICE_TYPE_DXVA2, AV_PIX_FMT_DXVA2_VLD },
165 { AV_HWDEVICE_TYPE_D3D11VA, AV_PIX_FMT_D3D11VA_VLD },
170FFmpeg_Transcoder::StreamRef::StreamRef() :
171 m_codec_ctx(nullptr),
178FFmpeg_Transcoder::StreamRef::~StreamRef()
183template<
typename T >
190 void operator ()( T * p)
const
192 avcodec_free_context(&p);
198 if (codec_ctx !=
nullptr)
215#pragma GCC diagnostic push
216#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
231 ,
m_pts(AV_NOPTS_VALUE)
232 ,
m_pos(AV_NOPTS_VALUE)
254#pragma GCC diagnostic pop
255 Logging::trace(
nullptr,
"The FFmpeg trancoder is ready to initialise.");
259#if LAVU_DEP_OLD_CHANNEL_LAYOUT
274 Logging::trace(
nullptr,
"The FFmpeg transcoder object was destroyed.");
296 AVDictionary * opt =
nullptr;
299 if (virtualfile ==
nullptr)
302 return AVERROR(EINVAL);
360 int orgerrno = errno;
362 return AVERROR(orgerrno);
375 return AVERROR(ENOMEM);
379 if (iobuffer ==
nullptr)
384 return AVERROR(ENOMEM);
387 AVIOContext * pb = avio_alloc_context(
389 static_cast<int>(
m_fileio->bufsize()),
391 static_cast<void *
>(
m_fileio.get()),
398 const AVInputFormat * infmt =
nullptr;
400 AVInputFormat * infmt =
nullptr;
407 infmt = av_find_input_format(
"mpeg");
414 infmt = av_find_input_format(
"mpeg");
421 infmt = av_find_input_format(
"mpegts");
457#if HAVE_AV_FORMAT_INJECT_GLOBAL_SIDE_DATA
534 return AVERROR(EINVAL);
587 AVCodecContext * codec_ctx =
nullptr;
589 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
600 std::string hw_encoder_codec_name;
617 Logging::info(
virtname(),
"Hardware encoder acceleration and frame buffering are active using codec '%1'.", hw_encoder_codec_name.c_str());
624 else if (!hw_encoder_codec_name.empty())
627 Logging::info(
virtname(),
"Hardware encoder acceleration is active using codec '%1'.", hw_encoder_codec_name.c_str());
651#if !LAVC_DEP_FLAG_TRUNCATED
652#ifdef AV_CODEC_CAP_TRUNCATED
658#warning "Your FFMPEG distribution is missing AV_CODEC_CAP_TRUNCATED flag. Probably requires fixing!"
671 AVCodecContext * codec_ctx =
nullptr;
673 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
708 for (
int stream_idx = 0; stream_idx < static_cast<int>(
m_in.
m_format_ctx->nb_streams); stream_idx++)
712 if (avcodec_get_type(stream->codecpar->codec_id) != AVMEDIA_TYPE_SUBTITLE)
723 AVCodecContext * codec_ctx =
nullptr;
733 codec_ctx->pkt_timebase = codec_ctx->time_base = stream->time_base;
754 for (
int stream_idx = 0; stream_idx < static_cast<int>(
m_in.
m_format_ctx->nb_streams); stream_idx++)
758 if (
is_album_art(input_stream->codecpar->codec_id, &input_stream->r_frame_rate))
761 AVCodecContext * input_codec_ctx;
792 if (stream ==
nullptr)
798 AVMediaType codec_type = stream->codecpar->codec_type;
799 AVCodecID codec_in = stream->codecpar->codec_id;
800 std::string codec_type_str;
803 if (codec_type == AVMEDIA_TYPE_VIDEO)
805 codec_type_str =
"video";
809 else if (codec_type == AVMEDIA_TYPE_AUDIO)
811 codec_type_str =
"audio";
824 const AVOutputFormat* oformat = av_guess_format(
nullptr,
virtname(),
nullptr);
825 if (oformat->codec_tag ==
nullptr || av_codec_get_tag(oformat->codec_tag, stream->codecpar->codec_id) <= 0)
834 Logging::debug(
virtname(),
"Check autocopy strict: %1: %2 -> %3", codec_type_str.c_str(), avcodec_get_name(codec_in), avcodec_get_name(codec_out));
835 if (codec_in != codec_out)
844 BITRATE orig_bit_rate = (stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate :
m_in.
m_format_ctx->bit_rate;
858 if (buffer ==
nullptr)
860 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::open_output_file()! buffer == nullptr in open_output_file()");
861 return AVERROR(EINVAL);
870 Logging::error(
virtname(),
"Unable to transcode. The source contains no audio stream, but the target just supports audio.");
872 return AVERROR(ENOENT);
892 const AVCodec *input_codec =
nullptr;
894 AVCodec *input_codec =
nullptr;
898 *codec_ctx =
nullptr;
904 if (ret != AVERROR_STREAM_NOT_FOUND)
913 return open_decoder(format_ctx, codec_ctx, *stream_idx, input_codec, type);
922 AVPixelFormat hw_pix_fmt = AV_PIX_FMT_NONE;
924 if (codec !=
nullptr && dev_type != AV_HWDEVICE_TYPE_NONE)
926 int method = use_device_ctx ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX : AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX;
928 for (
int i = 0;; i++)
930 const AVCodecHWConfig *config = avcodec_get_hw_config(codec, i);
933 Logging::error(av_codec_is_decoder(codec) ? filename() : virtname(),
"%1 '%2' does not support device type %3.\n", av_codec_is_encoder(codec) ?
"Encoder" :
"Decoder", codec->name,
hwdevice_get_type_name(dev_type));
937 if ((config->methods & method) && (config->device_type == dev_type))
939 hw_pix_fmt = config->pix_fmt;
940 Logging::debug(av_codec_is_decoder(codec) ? filename() : virtname(),
"%1 '%2' requests %3 for device type %4.\n", av_codec_is_encoder(codec) ?
"Encoder" :
"Decoder", codec->name, av_get_pix_fmt_name(hw_pix_fmt),
hwdevice_get_type_name(dev_type));
952int FFmpeg_Transcoder::open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx,
int stream_idx, AVCodec *input_codec, AVMediaType mediatype)
957 AVCodecContext *input_codec_ctx =
nullptr;
958 AVStream * input_stream =
nullptr;
959 AVDictionary * opt =
nullptr;
960 AVCodecID codec_id = AV_CODEC_ID_NONE;
963 input_stream = format_ctx->streams[stream_idx];
969 input_codec_ctx = avcodec_alloc_context3(
nullptr);
970 if (input_codec_ctx ==
nullptr)
972 Logging::error(filename(),
"Decoding context could not be allocated.");
973 return AVERROR(ENOMEM);
977 ret = avcodec_parameters_to_context(input_codec_ctx, input_stream->codecpar);
983 codec_id = input_stream->codecpar->codec_id;
987 if (mediatype == AVMEDIA_TYPE_VIDEO)
991 const char *profile = ::avcodec_profile_name(codec_id, input_stream->codecpar->profile);
992 Logging::info(filename(),
"Codec '%1' profile '%2' is blocked from hardware decoding. Reverting to software decoder.",
::get_codec_name(codec_id), profile !=
nullptr ? profile :
"unknown");
993 m_hwaccel_dec_mode = HWACCELMODE::FALLBACK;
997 if (mediatype == AVMEDIA_TYPE_VIDEO && m_hwaccel_dec_mode != HWACCELMODE::FALLBACK)
1001 std::string hw_decoder_codec_name;
1002 if (!get_hw_decoder_name(input_codec_ctx->codec_id, &hw_decoder_codec_name))
1014 if (m_hwaccel_enable_dec_buffering)
1025 Logging::info(filename(),
"Hardware decoder acceleration and frame buffering are active using codec '%1'.", (input_codec !=
nullptr) ? input_codec->name :
"unknown");
1027 m_hwaccel_dec_mode = HWACCELMODE::ENABLED;
1034 else if (!hw_decoder_codec_name.empty())
1038 input_codec = avcodec_find_decoder_by_name(hw_decoder_codec_name.c_str());
1040 if (input_codec ==
nullptr)
1042 Logging::error(filename(),
"Decoder '%1' could not be found.", hw_decoder_codec_name.c_str());
1043 return AVERROR(EINVAL);
1046 Logging::info(filename(),
"Hardware decoder acceleration is active using codec '%1'.", input_codec->name);
1048 m_hwaccel_dec_mode = HWACCELMODE::ENABLED;
1051 if (m_hwaccel_enable_dec_buffering)
1053 ret = hwdevice_ctx_add_ref(input_codec_ctx);
1062 if (input_codec ==
nullptr)
1065 input_codec = avcodec_find_decoder(codec_id);
1067 if (input_codec ==
nullptr)
1070 return AVERROR(EINVAL);
1074 input_codec_ctx->codec_id = input_codec->id;
1078 ret = avcodec_open2(input_codec_ctx, input_codec, &opt);
1084 if (m_hwaccel_dec_mode == HWACCELMODE::ENABLED)
1086 Logging::info(filename(),
"Unable to use %1 input codec '%2' with hardware acceleration. Falling back to software.",
get_media_type_string(mediatype), avcodec_get_name(codec_id));
1088 m_hwaccel_dec_mode = HWACCELMODE::FALLBACK;
1089 m_hwaccel_enable_dec_buffering =
false;
1090 m_dec_hw_pix_fmt = AV_PIX_FMT_NONE;
1093 hwdevice_ctx_free(&m_hwaccel_dec_device_ctx);
1095 m_in.m_video.reset();
1107 *codec_ctx = input_codec_ctx;
1115 const AVCodec * output_codec =
nullptr;
1116 AVCodecContext *output_codec_ctx =
nullptr;
1117 AVDictionary * opt =
nullptr;
1131 if (output_codec ==
nullptr)
1134 return AVERROR(EINVAL);
1137 output_codec_ctx = avcodec_alloc_context3(output_codec);
1138 if (output_codec_ctx ==
nullptr)
1141 return AVERROR(ENOMEM);
1144 output_codec_ctx->bit_rate = 400000;
1147 output_codec_ctx->time_base = {1, 25};
1152 output_codec_ctx->pix_fmt = avcodec_find_best_pix_fmt_of_list(output_codec->pix_fmts,
m_in.
m_video.
m_codec_ctx->pix_fmt, (dst_desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 1 : 0, &loss);
1154 if (output_codec_ctx->pix_fmt == AV_PIX_FMT_NONE)
1159 case AV_CODEC_ID_MJPEG:
1161 output_codec_ctx->pix_fmt = AV_PIX_FMT_YUVJ444P;
1164 case AV_CODEC_ID_PNG:
1166 output_codec_ctx->pix_fmt = AV_PIX_FMT_RGB24;
1169 case AV_CODEC_ID_BMP:
1171 output_codec_ctx->pix_fmt = AV_PIX_FMT_BGR24;
1189 case AV_CODEC_ID_MJPEG:
1195 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
1198 case AV_CODEC_ID_PNG:
1200 output_codec_ctx->pix_fmt = AV_PIX_FMT_RGB24;
1203 case AV_CODEC_ID_BMP:
1205 output_codec_ctx->pix_fmt = AV_PIX_FMT_BGR24;
1217 ret = avcodec_open2(output_codec_ctx, output_codec, &opt);
1257 return AVERROR(EPERM);
1333 return AVERROR(EPERM);
1381 if (out_streamref !=
nullptr)
1383 value.m_start_time = value.m_stream->start_time;
1419 if (input_sample_rate > max_sample_rate)
1421 if (output_sample_rate !=
nullptr)
1423 *output_sample_rate = max_sample_rate;
1429 if (output_sample_rate !=
nullptr)
1431 *output_sample_rate = input_sample_rate;
1439 if (!input_bit_rate || input_bit_rate > max_bit_rate)
1441 if (output_bit_rate !=
nullptr)
1443 *output_bit_rate = max_bit_rate;
1449 if (output_bit_rate !=
nullptr)
1451 *output_bit_rate = input_bit_rate;
1462 ::av_reduce(&dar.num, &dar.den,
1463 static_cast<int64_t
>(width) * sar.num,
1464 static_cast<int64_t
>(height) * sar.den,
1467 ar->num = ar->den = 0;
1469 if (dar.num && dar.den)
1475 if (!ar->den && sar.num != 0 && sar.den != 0)
1481 if (!ar->den && height)
1493 ::av_reduce(&ar->num, &ar->den,
1528 *output_height = input_height;
1533 *output_height &= ~(
static_cast<int>(0x1));
1543 *output_width = input_width;
1548 *output_width &= ~(
static_cast<int>(0x1));
1553 return (input_width > *output_width || input_height > *output_height);
1567 Logging::trace(
virtname(),
"Profile codec option -%1%2%3.", profile_option.m_key, *profile_option.m_value ?
" " :
"", profile_option.m_value);
1584 if (profile.m_filetype == filetype && profile.m_profile ==
params.
m_profile)
1596 if (in_pix_fmt != out_pix_fmt || in_width != out_width || in_height != out_height)
1599 if (in_pix_fmt != out_pix_fmt)
1604 if (in_width != out_width || in_height != out_height)
1607 in_width, in_height,
1608 out_width, out_height);
1620 SWS_FAST_BILINEAR,
nullptr,
nullptr,
nullptr);
1624 return AVERROR(ENOMEM);
1633 AVCodecContext *output_codec_ctx =
nullptr;
1634 AVStream * output_stream =
nullptr;
1635#if IF_DECLARED_CONST
1636 const AVCodec * output_codec =
nullptr;
1638 AVCodec * output_codec =
nullptr;
1640 AVDictionary * opt =
nullptr;
1643 std::string codec_name;
1648 output_codec = avcodec_find_encoder(codec_id);
1650 if (output_codec ==
nullptr)
1653 return AVERROR(EINVAL);
1658 output_codec = avcodec_find_encoder_by_name(codec_name.c_str());
1660 if (output_codec ==
nullptr)
1663 return AVERROR(EINVAL);
1672 if (output_stream ==
nullptr)
1675 return AVERROR(ENOMEM);
1679 output_codec_ctx = avcodec_alloc_context3(output_codec);
1680 if (output_codec_ctx ==
nullptr)
1683 return AVERROR(ENOMEM);
1686 switch (output_codec->type)
1688 case AVMEDIA_TYPE_AUDIO:
1691 int orig_sample_rate;
1715#if LAVU_DEP_OLD_CHANNEL_LAYOUT
1716 av_channel_layout_default(&output_codec_ctx->ch_layout, output_codec_ctx->ch_layout.nb_channels);
1718 output_codec_ctx->channel_layout =
static_cast<uint64_t
>(av_get_default_channel_layout(output_codec_ctx->channels));
1729 orig_sample_rate = output_codec_ctx->sample_rate;
1732 if (output_codec->supported_samplerates !=
nullptr)
1735 bool supported =
false;
1737 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1739 if (output_codec->supported_samplerates[n] == output_codec_ctx->sample_rate)
1749 int min_samplerate = 0;
1750 int max_samplerate = INT_MAX;
1753 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1755 if (min_samplerate <= output_codec->supported_samplerates[n] && output_codec_ctx->sample_rate >= output_codec->supported_samplerates[n])
1757 min_samplerate = output_codec->supported_samplerates[n];
1762 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1764 if (max_samplerate >= output_codec->supported_samplerates[n] && output_codec_ctx->sample_rate <= output_codec->supported_samplerates[n])
1766 max_samplerate = output_codec->supported_samplerates[n];
1770 if (min_samplerate != 0 && max_samplerate != INT_MAX)
1773 if (output_codec_ctx->sample_rate - min_samplerate < max_samplerate - output_codec_ctx->sample_rate)
1775 output_codec_ctx->sample_rate = min_samplerate;
1779 output_codec_ctx->sample_rate = max_samplerate;
1782 else if (min_samplerate != 0)
1785 output_codec_ctx->sample_rate = min_samplerate;
1787 else if (max_samplerate != INT_MAX)
1790 output_codec_ctx->sample_rate = max_samplerate;
1796 return AVERROR(EINVAL);
1799 Logging::debug(
virtname(),
"Because the requested value is not supported by codec, the audio sample rate was changed from %1 to %2.",
1807 if (output_codec->sample_fmts !=
nullptr)
1810 AVSampleFormat input_fmt_planar = av_get_planar_sample_fmt(in_sample_format);
1812 output_codec_ctx->sample_fmt = AV_SAMPLE_FMT_NONE;
1814 for (
const AVSampleFormat *sample_fmt = output_codec->sample_fmts; *sample_fmt != -1; sample_fmt++)
1816 AVSampleFormat output_fmt_planar = av_get_planar_sample_fmt(*sample_fmt);
1818 if (*sample_fmt == in_sample_format ||
1819 (input_fmt_planar != AV_SAMPLE_FMT_NONE &&
1820 input_fmt_planar == output_fmt_planar))
1822 output_codec_ctx->sample_fmt = *sample_fmt;
1828 if (output_codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE)
1830 output_codec_ctx->sample_fmt = output_codec->sample_fmts[0];
1836 output_codec_ctx->sample_fmt = in_sample_format;
1840 output_stream->time_base.den = output_codec_ctx->sample_rate;
1841 output_stream->time_base.num = 1;
1842 output_codec_ctx->time_base = output_stream->time_base;
1848 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1873 case AVMEDIA_TYPE_VIDEO:
1890 output_codec_ctx->codec_id = codec_id;
1912 Logging::trace(
virtname(),
"Changing video size from %1/%2 to %3/%4.", output_codec_ctx->width, output_codec_ctx->height, width, height);
1913 output_codec_ctx->width = width;
1914 output_codec_ctx->height = height;
1926 if (output_codec_ctx->codec_id != AV_CODEC_ID_VP9 &&
m_out.
m_filetype != FILETYPE::MKV)
1928 output_codec_ctx->sample_aspect_ratio = sample_aspect_ratio;
1929 output_stream->codecpar->sample_aspect_ratio = sample_aspect_ratio;
1941 output_codec_ctx->sample_aspect_ratio = { 1, 1 };
1942 output_stream->codecpar->sample_aspect_ratio = { 1, 1 };
1945 if (sample_aspect_ratio.num && sample_aspect_ratio.den)
1947 output_codec_ctx->width = output_codec_ctx->width * sample_aspect_ratio.num / sample_aspect_ratio.den;
1953 switch (output_codec_ctx->codec_id)
1955 case AV_CODEC_ID_H264:
1972 output_codec_ctx->global_quality = 40;
1977 ret = av_opt_get(output_codec_ctx->priv_data,
"profile", 0, &out_val);
1980 if (!
strcasecmp(
reinterpret_cast<const char *
>(out_val),
"high"))
1982 switch (output_codec_ctx->pix_fmt)
1984 case AV_PIX_FMT_YUYV422:
1985 case AV_PIX_FMT_YUV422P:
1986 case AV_PIX_FMT_YUVJ422P:
1987 case AV_PIX_FMT_UYVY422:
1988 case AV_PIX_FMT_YUV422P16LE:
1989 case AV_PIX_FMT_YUV422P16BE:
1990 case AV_PIX_FMT_YUV422P10BE:
1991 case AV_PIX_FMT_YUV422P10LE:
1992 case AV_PIX_FMT_YUV422P9BE:
1993 case AV_PIX_FMT_YUV422P9LE:
1994 case AV_PIX_FMT_YUVA422P9BE:
1995 case AV_PIX_FMT_YUVA422P9LE:
1996 case AV_PIX_FMT_YUVA422P10BE:
1997 case AV_PIX_FMT_YUVA422P10LE:
1998 case AV_PIX_FMT_YUVA422P16BE:
1999 case AV_PIX_FMT_YUVA422P16LE:
2000 case AV_PIX_FMT_NV16:
2001 case AV_PIX_FMT_NV20LE:
2002 case AV_PIX_FMT_NV20BE:
2003 case AV_PIX_FMT_YVYU422:
2004 case AV_PIX_FMT_YUVA422P:
2005 case AV_PIX_FMT_YUV422P12BE:
2006 case AV_PIX_FMT_YUV422P12LE:
2007 case AV_PIX_FMT_YUV422P14BE:
2008 case AV_PIX_FMT_YUV422P14LE:
2010 ret = av_opt_set(output_codec_ctx->priv_data,
"profile",
"high422", 0);
2018 case AV_PIX_FMT_YUV444P:
2019 case AV_PIX_FMT_YUVJ444P:
2020 case AV_PIX_FMT_YUV444P16LE:
2021 case AV_PIX_FMT_YUV444P16BE:
2022 case AV_PIX_FMT_RGB444LE:
2023 case AV_PIX_FMT_RGB444BE:
2024 case AV_PIX_FMT_BGR444LE:
2025 case AV_PIX_FMT_BGR444BE:
2026 case AV_PIX_FMT_YUV444P9BE:
2027 case AV_PIX_FMT_YUV444P9LE:
2028 case AV_PIX_FMT_YUV444P10BE:
2029 case AV_PIX_FMT_YUV444P10LE:
2030 case AV_PIX_FMT_GBRP:
2031 case AV_PIX_FMT_GBRP9BE:
2032 case AV_PIX_FMT_GBRP9LE:
2033 case AV_PIX_FMT_GBRP10BE:
2034 case AV_PIX_FMT_GBRP10LE:
2035 case AV_PIX_FMT_GBRP16BE:
2036 case AV_PIX_FMT_GBRP16LE:
2037 case AV_PIX_FMT_YUVA444P9BE:
2038 case AV_PIX_FMT_YUVA444P9LE:
2039 case AV_PIX_FMT_YUVA444P10BE:
2040 case AV_PIX_FMT_YUVA444P10LE:
2041 case AV_PIX_FMT_YUVA444P16BE:
2042 case AV_PIX_FMT_YUVA444P16LE:
2043 case AV_PIX_FMT_XYZ12LE:
2044 case AV_PIX_FMT_XYZ12BE:
2045 case AV_PIX_FMT_YUVA444P:
2046 case AV_PIX_FMT_GBRAP:
2047 case AV_PIX_FMT_GBRAP16BE:
2048 case AV_PIX_FMT_GBRAP16LE:
2049 case AV_PIX_FMT_YUV444P12BE:
2050 case AV_PIX_FMT_YUV444P12LE:
2051 case AV_PIX_FMT_YUV444P14BE:
2052 case AV_PIX_FMT_YUV444P14LE:
2053 case AV_PIX_FMT_GBRP12BE:
2054 case AV_PIX_FMT_GBRP12LE:
2055 case AV_PIX_FMT_GBRP14BE:
2056 case AV_PIX_FMT_GBRP14LE:
2057 case AV_PIX_FMT_AYUV64LE:
2058 case AV_PIX_FMT_AYUV64BE:
2060 ret = av_opt_set(output_codec_ctx->priv_data,
"profile",
"high444", 0);
2078 case AV_CODEC_ID_VP9:
2080 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::WEBM);
2088 case AV_CODEC_ID_PRORES:
2090 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::PRORES);
2101 output_codec_ctx->profile =
static_cast<int>(
params.
m_level);
2104 case AV_CODEC_ID_ALAC:
2106 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::ALAC);
2133 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
2183 if (!av_dict_get(opt,
"threads",
nullptr, 0))
2190 ret = avcodec_open2(output_codec_ctx, output_codec, &opt);
2199 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2206 return (output_stream->index);
2211 AVCodecContext *output_codec_ctx =
nullptr;
2212 AVStream * output_stream =
nullptr;
2213#if IF_DECLARED_CONST
2214 const AVCodec * output_codec =
nullptr;
2216 AVCodec * output_codec =
nullptr;
2218 AVDictionary * opt =
nullptr;
2222 output_codec = avcodec_find_encoder(codec_id);
2224 if (output_codec ==
nullptr)
2227 return AVERROR(EINVAL);
2231 if (output_stream ==
nullptr)
2234 return AVERROR(ENOMEM);
2238 output_codec_ctx = avcodec_alloc_context3(output_codec);
2239 if (output_codec_ctx ==
nullptr)
2241 Logging::error(
virtname(),
"Could not allocate an encoding context for encoder '%1'.", avcodec_get_name(codec_id));
2242 return AVERROR(ENOMEM);
2245 output_stream->time_base = input_streamref.
m_stream->time_base;
2246 output_codec_ctx->time_base = output_stream->time_base;
2252 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
2268 AVCodecContext * input_codec_ctx = input_streamref.
m_codec_ctx.get();
2270 if (input_codec_ctx !=
nullptr && input_codec_ctx->subtitle_header !=
nullptr)
2273 output_codec_ctx->subtitle_header =
static_cast<uint8_t *
>(av_mallocz(
static_cast<size_t>(input_codec_ctx->subtitle_header_size) + 1));
2274 if (output_codec_ctx->subtitle_header ==
nullptr)
2276 return AVERROR(ENOMEM);
2278 std::memcpy(output_codec_ctx->subtitle_header, input_codec_ctx->subtitle_header,
static_cast<size_t>(input_codec_ctx->subtitle_header_size));
2279 output_codec_ctx->subtitle_header_size = input_codec_ctx->subtitle_header_size;
2281 else if (output_codec_ctx->codec_id == AV_CODEC_ID_WEBVTT || output_codec_ctx->codec_id == AV_CODEC_ID_SUBRIP)
2293 Logging::error(
virtname(),
"Could not create ASS script info for encoder '%1'.", avcodec_get_name(codec_id));
2299 ret = avcodec_open2(output_codec_ctx, output_codec, &opt);
2308 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2318 AVDictionaryEntry *tag =
nullptr;
2320 tag = av_dict_get(input_streamref.
m_stream->metadata,
"language",
nullptr, AV_DICT_IGNORE_SUFFIX);
2323 av_dict_set(&output_stream->metadata,
"language", tag->value, AV_DICT_IGNORE_SUFFIX);
2329 av_dict_set(&output_stream->metadata,
"language", language->c_str(), AV_DICT_IGNORE_SUFFIX);
2339 output_streamref.
m_stream = output_stream;
2351 AVStream * output_stream =
nullptr;
2355 if (output_stream ==
nullptr)
2358 return AVERROR(ENOMEM);
2364 case AVMEDIA_TYPE_AUDIO:
2390 case AVMEDIA_TYPE_VIDEO:
2423 output_stream->codecpar->codec_tag = 0;
2430 AVCodecContext * output_codec_ctx =
nullptr;
2431 AVStream * output_stream =
nullptr;
2432 const AVCodec * input_codec = input_codec_ctx->codec;
2433 const AVCodec * output_codec =
nullptr;
2434 AVDictionary * opt =
nullptr;
2438 output_codec = avcodec_find_encoder(input_codec->id);
2439 if (output_codec ==
nullptr)
2442 return AVERROR(EINVAL);
2446 if (output_codec->type != AVMEDIA_TYPE_VIDEO)
2448 Logging::error(
virtname(),
"INTERNAL TROUBLE! Encoder '%1' is not a video codec.", avcodec_get_name(input_codec->id));
2449 return AVERROR(EINVAL);
2453 if (output_stream ==
nullptr)
2455 Logging::error(
virtname(),
"Could not allocate stream for encoder '%1'.", avcodec_get_name(input_codec->id));
2456 return AVERROR(ENOMEM);
2460 output_codec_ctx = avcodec_alloc_context3(output_codec);
2461 if (output_codec_ctx ==
nullptr)
2464 return AVERROR(ENOMEM);
2468#if !IF_DECLARED_CONST
2487 output_stream->disposition = AV_DISPOSITION_ATTACHED_PIC;
2495 output_codec_ctx->time_base = { 1, 90000 };
2496 output_stream->time_base = { 1, 90000 };
2498 output_codec_ctx->pix_fmt = input_codec_ctx->pix_fmt;
2499 output_codec_ctx->width = input_codec_ctx->width;
2500 output_codec_ctx->height = input_codec_ctx->height;
2509 ret = avcodec_open2(output_codec_ctx, output_codec, &opt);
2516 Logging::debug(
virtname(),
"Opened album art output codec %1 for stream #%2 (dimensions %3x%4).",
get_codec_name(input_codec->id,
true), output_stream->index, output_codec_ctx->width, output_codec_ctx->height);
2518 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2528 streamref.
m_stream = output_stream;
2541 tmp_pkt = av_packet_clone(pkt_in);
2542 if (tmp_pkt ==
nullptr)
2544 ret = AVERROR(ENOMEM);
2551 tmp_pkt->stream_index = output_stream->index;
2552 tmp_pkt->flags |= AV_PKT_FLAG_KEY;
2558 av_packet_unref(tmp_pkt);
2590 return AVERROR(ENOMEM);
2706 const int buf_size = 5*1024*1024;
2708 if (iobuffer ==
nullptr)
2711 return AVERROR(ENOMEM);
2719 static_cast<void *
>(buffer),
2727 return AVERROR(ENOMEM);
2739 if (codec_id == AV_CODEC_ID_NONE)
2767#if LAVU_DEP_OLD_CHANNEL_LAYOUT
2785#if LAVU_DEP_OLD_CHANNEL_LAYOUT
2811#if LAVU_DEP_OLD_CHANNEL_LAYOUT
2833#if LAVU_DEP_OLD_CHANNEL_LAYOUT
2841#if SWR_DEP_ALLOC_SET_OPTS
2867 return AVERROR(ENOMEM);
2891 return AVERROR(ENOMEM);
2914 Logging::trace(
virtname(),
"Profile format option -%1%2%3.", option.m_key, *option.m_value ?
" " :
"", option.m_value);
2931 if (profile.m_filetype == filetype && profile.m_profile ==
params.
m_profile)
2938 if (filetype == FILETYPE::MP4 || filetype == FILETYPE::PRORES || filetype == FILETYPE::TS || filetype == FILETYPE::HLS)
2951 AVIOContext * output_io_context =
static_cast<AVIOContext *
>(
m_out.
m_format_ctx->pb);
2952 Buffer *buffer =
static_cast<Buffer *
>(output_io_context->opaque);
2953 size_t current_offset = buffer->
tell();
2954 size_t read_offset = 0;
2959 buffer->
copy(
reinterpret_cast<uint8_t*
>(&wav_header), 0,
sizeof(
WAV_HEADER));
2971 buffer->
copy(
reinterpret_cast<uint8_t*
>(&wav_fact), read_offset,
sizeof(
WAV_FACT));
2979 buffer->
copy(
reinterpret_cast<uint8_t*
>(&list_header), read_offset,
sizeof(
WAV_LIST_HEADER));
2982 buffer->
copy(
reinterpret_cast<uint8_t*
>(&data_header), read_offset,
sizeof(
WAV_DATA_HEADER));
2987#if __BYTE_ORDER == __BIG_ENDIAN
2993 buffer->
seek(0, SEEK_SET);
2997 buffer->
seek(
static_cast<long>(read_offset), SEEK_SET);
3001 buffer->
seek(
static_cast<long>(current_offset), SEEK_SET);
3009 size_t buffsize = *size;
3013 if (!buffer->
copy(chunk, *buffoffset, buffsize))
3031#if __BYTE_ORDER == __BIG_ENDIAN
3034 *size = __builtin_bswap32(p->
m_ckSize) + 8;
3045 *buffoffset += *size;
3054 AVIOContext * output_io_context =
static_cast<AVIOContext *
>(
m_out.
m_format_ctx->pb);
3055 Buffer *buffer =
static_cast<Buffer *
>(output_io_context->opaque);
3056 size_t current_offset = buffer->
tell();
3057 size_t read_offset = 0;
3062 size =
sizeof(form_chunk);
3068 read_offset += size;
3071#if __BYTE_ORDER != __BIG_ENDIAN
3075 size =
sizeof(common_chunk);
3081 read_offset += size;
3085 size =
sizeof(sounddata_chunk);
3092#if __BYTE_ORDER != __BIG_ENDIAN
3097 buffer->
seek(0, SEEK_SET);
3098 buffer->
writeio(
reinterpret_cast<uint8_t*
>(&form_chunk),
sizeof(form_chunk));
3101 buffer->
seek(
static_cast<long>(read_offset), SEEK_SET);
3102 buffer->
writeio(
reinterpret_cast<uint8_t*
>(&sounddata_chunk),
sizeof(sounddata_chunk));
3105 buffer->
seek(
static_cast<long>(current_offset), SEEK_SET);
3112 AVDictionary* dict =
nullptr;
3135 case FILETYPE::AIFF:
3153 frame->format = pix_fmt;
3154 frame->width = width;
3155 frame->height = height;
3158 ret = av_frame_get_buffer(frame, 32);
3176 ret = avcodec_send_packet(codec_ctx, pkt);
3177 if (ret < 0 && ret != AVERROR_EOF)
3182 if (ret == AVERROR(EAGAIN))
3184 ret = AVERROR_EXTERNAL;
3204 ret = avcodec_receive_frame(codec_ctx, frame);
3205 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
3217 *got_frame = (ret >= 0) ? 1 : 0;
3224 int data_present = 0;
3266 *decoded += pkt->size;
3269 if (frame->nb_samples)
3272 uint8_t **converted_input_samples =
nullptr;
3275 int nb_output_samples;
3296 ret =
convert_samples(frame->extended_data, frame->nb_samples, converted_input_samples, &nb_output_samples);
3315 if (converted_input_samples !=
nullptr)
3317 av_freep(&converted_input_samples[0]);
3318 av_free(converted_input_samples);
3380 ret = sw_frame.
res();
3391 ret = av_hwframe_transfer_data(sw_frame, frame, 0);
3401 *decoded += pkt->size;
3404 if (pkt->dts != AV_NOPTS_VALUE)
3406 int64_t pkt_dts = pkt->dts;
3407 if (pkt_dts >
m_pts)
3412 else if (pkt->pts != AV_NOPTS_VALUE)
3414 int64_t pkt_pts = pkt->pts;
3415 if (pkt_pts >
m_pts)
3426 if (frame !=
nullptr)
3428 if (!(frame->flags & AV_FRAME_FLAG_CORRUPT || frame->flags & AV_FRAME_FLAG_DISCARD))
3440 ret = tmp_frame.
res();
3456 static_cast<const uint8_t *
const *
>(frame->data), frame->linesize,
3458 tmp_frame->data, tmp_frame->linesize);
3460 tmp_frame->pts = frame->pts;
3461 tmp_frame->best_effort_timestamp = frame->best_effort_timestamp;
3466 int64_t best_effort_timestamp = frame->best_effort_timestamp;
3468 if (best_effort_timestamp != AV_NOPTS_VALUE)
3470 frame->pts = best_effort_timestamp;
3473 if (frame->pts == AV_NOPTS_VALUE)
3496#if !LAVU_ADD_NEW_FRAME_FLAGS
3497 frame->key_frame = 0;
3499 frame->pict_type = AV_PICTURE_TYPE_NONE;
3501 if (frame->pts != AV_NOPTS_VALUE)
3503 int64_t tmp_pts = frame->pts - video_start_time;
3519#if LAVU_ADD_NEW_FRAME_FLAGS
3520 frame->flags |= AV_FRAME_FLAG_KEY;
3522 frame->key_frame = 1;
3524 frame->pict_type = AV_PICTURE_TYPE_I;
3544 StreamRef_map::const_iterator it =
m_in.
m_subtitle.find(pkt->stream_index);
3551 int ret = AVERROR_STREAM_NOT_FOUND;
3567 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::decode_subtitle()! Unable to map input subtitle stream #%1 to output stream.", it->first);
3568 throw AVERROR(EINVAL);
3571 return decode_subtitle(it->second.m_codec_ctx.get(), pkt, decoded, out_stream_idx);
3577 int data_present = 0;
3582 ret = subtitle.
res();
3589 ret = avcodec_decode_subtitle2(codec_ctx, subtitle, &data_present, pkt);
3591 if (ret < 0 && ret != AVERROR(EINVAL))
3606 m_frame_map.insert(std::make_pair(subtitle->pts, subtitle));
3614 if (
is_hls() && pkt->pts != AV_NOPTS_VALUE)
3618 case AVMEDIA_TYPE_AUDIO:
3641 case AVMEDIA_TYPE_VIDEO:
3664 case AVMEDIA_TYPE_SUBTITLE:
3668 if (subtitle !=
nullptr && subtitle->
m_stream !=
nullptr)
3698 if (mediatype != AVMEDIA_TYPE_ATTACHMENT)
3700 type = av_get_media_type_string(mediatype);
3702 if (type ==
nullptr)
3720 if (pkt->pts != AV_NOPTS_VALUE)
3722 *cur_ts = pkt->pts + pkt->duration;
3724 else if (pkt->dts != AV_NOPTS_VALUE)
3731 if (pkt->pts == AV_NOPTS_VALUE)
3736 *cur_ts += pkt->duration;
3738 if (pkt->dts == AV_NOPTS_VALUE)
3825 if ((ret == AVERROR(EAGAIN) && ret == lastret) || ret == AVERROR_EOF)
3833 if (ret < 0 && ret != AVERROR(EAGAIN))
3841 pkt->data += decoded;
3842 pkt->size -= decoded;
3844 while (pkt->size > 0 && (ret == 0 || ret == AVERROR(EAGAIN)));
3875 switch (
m_in.
m_format_ctx->streams[pkt->stream_index]->codecpar->codec_type)
3877 case AVMEDIA_TYPE_VIDEO:
3884 if (pkt->stream_index == input_stream->index && !(input_stream->disposition & AV_DISPOSITION_ATTACHED_PIC))
3924 if (*converted_input_samples ==
nullptr)
3927 return AVERROR(ENOMEM);
3932 ret = av_samples_alloc(*converted_input_samples,
nullptr,
3939 av_freep(&(*converted_input_samples)[0]);
3940 av_free(*converted_input_samples);
3953 ret = swr_convert(
m_audio_resample_ctx, converted_data, *out_samples,
const_cast<const uint8_t **
>(input_data), in_samples);
3964 *out_samples = in_samples;
3971 std::memcpy(converted_data[0], input_data[0],
static_cast<size_t>(samples));
3979 std::memcpy(converted_data[n], input_data[n],
static_cast<size_t>(samples));
4001 ret = av_audio_fifo_write(
m_audio_fifo,
reinterpret_cast<void **
>(converted_input_samples), frame_size);
4002 if (ret < frame_size)
4012 return AVERROR_EXIT;
4049 int (
FFmpeg_Transcoder::*decode_frame_ptr)(AVPacket *pkt,
int *decoded) =
nullptr;
4060 if (decode_frame_ptr !=
nullptr)
4062#if !LAVC_DEP_AV_INIT_PACKET
4065 AVPacket *flush_packet =
nullptr;
4067 if (use_flush_packet)
4069#if LAVC_DEP_AV_INIT_PACKET
4070 flush_packet = av_packet_alloc();
4072 flush_packet = &pkt;
4074 init_packet(flush_packet);
4077 flush_packet->data =
nullptr;
4078 flush_packet->size = 0;
4079 flush_packet->stream_index = stream_idx;
4083 for (
int decoded = 1; decoded;)
4085 ret = (this->*decode_frame_ptr)(flush_packet, &decoded);
4086 if (ret < 0 && ret != AVERROR(EAGAIN))
4092 av_packet_unref(flush_packet);
4093#if LAVC_DEP_AV_INIT_PACKET
4094 av_packet_free(&flush_packet);
4114 if (ret == AVERROR_EOF)
4150 if (ret < 0 && ret != AVERROR(EAGAIN))
4168 av_packet_unref(&pkt);
4184 frame->nb_samples = frame_size;
4185#if LAVU_DEP_OLD_CHANNEL_LAYOUT
4202 ret = av_frame_get_buffer(frame, 0);
4214 if (pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
4218 int64_t pkt_duration;
4224 pkt_duration = pkt->duration;
4226#if !LAVC_DEP_TICKSPERFRAME
4259#if !LAVC_DEP_AV_INIT_PACKET
4265#if LAVC_DEP_AV_INIT_PACKET
4266 pkt = av_packet_alloc();
4281 if (ret < 0 && ret != AVERROR_EOF)
4293 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4319 av_packet_unref(pkt);
4323 av_packet_unref(pkt);
4327#if LAVC_DEP_AV_INIT_PACKET
4328 av_packet_free(&pkt);
4349 return AVERROR(EINVAL);
4355 return AVERROR(EINVAL);
4358#if !LAVC_DEP_AV_INIT_PACKET
4361 AVPacket *pkt =
nullptr;
4368 ret = cloned_frame.
res();
4375#if LAVC_DEP_AV_INIT_PACKET
4376 pkt = av_packet_alloc();
4394 if (ret < 0 && ret != AVERROR_EOF)
4406 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4408 av_packet_unref(pkt);
4422 if (pkt->pts != AV_NOPTS_VALUE)
4435 av_packet_unref(pkt);
4440 av_packet_unref(pkt);
4444#if LAVC_DEP_AV_INIT_PACKET
4445 av_packet_free(&pkt);
4459 if (frame !=
nullptr)
4461#if LAVU_ADD_NEW_FRAME_FLAGS
4462 if (frame->flags & AV_FRAME_FLAG_INTERLACED)
4466 m_out.
m_video.
m_stream->codecpar->field_order = (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? AV_FIELD_TT : AV_FIELD_BB;
4470 m_out.
m_video.
m_stream->codecpar->field_order = (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? AV_FIELD_TB : AV_FIELD_BT;
4474 if (frame->interlaced_frame)
4478 m_out.
m_video.
m_stream->codecpar->field_order = frame->top_field_first ? AV_FIELD_TT : AV_FIELD_BB;
4482 m_out.
m_video.
m_stream->codecpar->field_order = frame->top_field_first ? AV_FIELD_TB : AV_FIELD_BT;
4491#if !LAVC_DEP_AV_INIT_PACKET
4495 AVPacket *pkt =
nullptr;
4503 if (hw_frame ==
nullptr)
4505 ret = AVERROR(ENOMEM);
4510 ret = hw_frame->
res();
4526#if LAVC_DEP_AV_INIT_PACKET
4527 pkt = av_packet_alloc();
4540 if (ret < 0 && ret != AVERROR_EOF)
4552 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4554 av_packet_unref(pkt);
4572 if (pkt->dts != AV_NOPTS_VALUE &&
4573 pkt->pts != AV_NOPTS_VALUE &&
4574 pkt->dts > pkt->pts &&
4594 Logging::trace(
virtname(),
"Non-monotonous DTS in video output stream; previous: %1, current: %2; changing to %3. This may result in incorrect timestamps in the output.",
m_out.
m_last_mux_dts, pkt->dts, max);
4596 if (pkt->pts >= pkt->dts)
4598 pkt->pts = FFMAX(pkt->pts, max);
4605 if (frame !=
nullptr && !pkt->duration)
4607#if !LAVU_DEP_PKT_DURATION
4608 pkt->duration = frame->pkt_duration;
4610 pkt->duration = frame->duration;
4614 if (pkt->pts != AV_NOPTS_VALUE)
4617 m_out.
m_last_mux_dts = (pkt->dts != AV_NOPTS_VALUE) ? pkt->dts : (pkt->pts - pkt->duration);
4628 av_packet_unref(pkt);
4635 av_packet_unref(pkt);
4642#if LAVC_DEP_AV_INIT_PACKET
4643 av_packet_free(&pkt);
4655 if (out_streamref ==
nullptr)
4657 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::encode_subtitle()! Invalid stream index #%1.", out_stream_idx);
4658 return AVERROR(EINVAL);
4662#if !LAVC_DEP_AV_INIT_PACKET
4668#if LAVC_DEP_AV_INIT_PACKET
4669 pkt = av_packet_alloc();
4678 std::memcpy(&subtmp, sub,
sizeof(AVSubtitle));
4685 if (subtmp.pts == AV_NOPTS_VALUE)
4688 throw AVERROR(EINVAL);
4692 ret = av_new_packet(pkt, 1024 * 1024);
4700 if (out_streamref->
m_codec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
4710 sub_pts = subtmp.pts;
4717 for (
int i = 0; i < nb; i++)
4719 unsigned save_num_rects = subtmp.num_rects;
4720 subtmp.pts = sub_pts;
4722 if (subtmp.end_display_time == UINT32_MAX)
4724 subtmp.end_display_time = 0;
4728 subtmp.pts +=
ffmpeg_rescale_q(subtmp.start_display_time, AVRational({ 1, 1000 }));
4729 subtmp.end_display_time -= subtmp.start_display_time;
4730 subtmp.start_display_time = 0;
4733 subtmp.num_rects = 0;
4737 ret = avcodec_encode_subtitle(out_streamref->
m_codec_ctx.get(), pkt->data, pkt->size, &subtmp);
4740 subtmp.num_rects = save_num_rects;
4751 pkt->duration =
ffmpeg_rescale_q(subtmp.end_display_time, AVRational({ 1, 1000 }), out_streamref->
m_stream->time_base);
4754 if (out_streamref->
m_codec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
4759 pkt->pts +=
ffmpeg_rescale_q(subtmp.end_display_time, AVRational({ 1, 1000 }), out_streamref->
m_stream->time_base);
4762 pkt->dts = pkt->pts;
4772 av_packet_unref(pkt);
4776 av_packet_unref(pkt);
4780#if LAVC_DEP_AV_INIT_PACKET
4781 av_packet_free(&pkt);
4793 ret = output_frame.
res();
4804 frame_size = FFMIN(av_audio_fifo_size(
m_audio_fifo), frame_size);
4816 ret = av_audio_fifo_read(
m_audio_fifo,
reinterpret_cast<void **
>(output_frame->data), frame_size);
4817 if (ret < frame_size)
4832 if (output_frame->sample_rate)
4849 int64_t sample_duration = av_rescale(AV_TIME_BASE, output_frame->nb_samples, output_frame->sample_rate);
4858 m_frame_map.insert(std::make_pair(pos, output_frame));
4882template <
size_t size>
4885 std::memset(out,
' ', size);
4886 std::memcpy(out, in.c_str(), std::min(size, in.size()));
4894 std::memcpy(out.data(), in.c_str(), std::min(out.size(), in.size()));
4903 AVDictionaryEntry *tag =
nullptr;
4905 while ((tag = av_dict_get(metadata_in,
"", tag, AV_DICT_IGNORE_SUFFIX)) !=
nullptr)
4907 std::string value(tag->value);
4997 if (av_dict_get(
m_out.
m_format_ctx->metadata,
"ALBUM_ARTIST",
nullptr, 0) ==
nullptr)
5019 if (input_stream->disposition & AV_DISPOSITION_ATTACHED_PIC)
5070 uint32_t next_frame_no = frame_no;
5075 std::this_thread::yield();
5100 if (forced_seek || (frame_no != next_frame_no && next_frame_no > 1))
5121 int data_written = 0;
5126 if (ret == AVERROR_EOF)
5132 if (ret < 0 && ret != AVERROR(EAGAIN))
5138 while (data_written);
5151 int data_written = 0;
5165 if (ret == AVERROR_EOF)
5170 if (ret < 0 && ret != AVERROR(EAGAIN))
5176 while (data_written);
5189 int output_frame_size;
5194 output_frame_size = 10000;
5208 while (av_audio_fifo_size(
m_audio_fifo) < output_frame_size)
5234 while (av_audio_fifo_size(
m_audio_fifo) >= output_frame_size || (*finished && av_audio_fifo_size(
m_audio_fifo) > 0))
5265 if (ret == AVERROR_EOF)
5319 delay = 6 * AV_TIME_BASE;
5330 MULTIFRAME_MAP::const_iterator it =
m_frame_map.cbegin();
5350 if (std::holds_alternative<FFmpeg_Frame>(multiframe))
5353 const FFmpeg_Frame & frame = std::get<FFmpeg_Frame>(multiframe);
5359 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::process_single_fr()! Invalid stream index in audio/video buffer skipped.");
5372 if (ret < 0 && ret != AVERROR(EAGAIN))
5381 int data_written = 0;
5384 if (ret < 0 && ret != AVERROR(EAGAIN))
5390 else if (std::holds_alternative<FFmpeg_Subtitle>(multiframe))
5393 const FFmpeg_Subtitle & subtitle = std::get<FFmpeg_Subtitle>(multiframe);
5399 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::process_single_fr()! Invalid stream index in subtitle buffer skipped.");
5406 int data_written = 0;
5410 if (ret < 0 && ret != AVERROR(EAGAIN))
5428 int data_written = 0;
5433 if (ret < 0 && ret != AVERROR(EAGAIN))
5506#ifdef PRESCAN_FRAMES
5507 if (seek_frame_no > PRESCAN_FRAMES)
5509 seek_frame_no -= PRESCAN_FRAMES;
5530 bool opened =
false;
5547 if (min_seek_segments && segment_no >= next_segment && segment_no <= next_segment + min_seek_segments)
5605 next_segment = segment_no;
5624 return AVERROR(errno);
5654 av_packet_unref(pkt);
5661 unsigned int mindist;
5662 size_t match = UINT_MAX;
5668 unsigned int x =
static_cast<unsigned int>(width -
m_prores_bitrate[i].m_width);
5669 unsigned int y =
static_cast<unsigned int>(height -
m_prores_bitrate[i].m_height);
5670 unsigned int dist = (x * x) + (y * y);
5685 if (match == UINT_MAX)
5694 double framerateX = av_q2d(framerate);
5698 unsigned int dist = UINT_MAX;
5701 unsigned int x =
static_cast<unsigned int>(framerateX -
m_prores_bitrate[i].m_framerate[j].m_framerate);
5702 unsigned int y =
static_cast<unsigned int>(interleaved -
m_prores_bitrate[i].m_framerate[j].m_interleaved);
5704 dist = (x * x) + (y * y);
5726 if (match == UINT_MAX)
5731 return m_prores_bitrate[match].m_bitrate[
static_cast<size_t>(profile)] * (1000 * 1000);
5736 BITRATE output_audio_bit_rate;
5737 int output_sample_rate;
5738 bool success =
true;
5745 case AV_CODEC_ID_AAC:
5748 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
5749 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
5752 case AV_CODEC_ID_MP3:
5763 case AV_CODEC_ID_PCM_U8:
5764 case AV_CODEC_ID_PCM_S8:
5766 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_U8);
5772 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5775 case AV_CODEC_ID_PCM_S8_PLANAR:
5777 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_U8P);
5783 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5786 case AV_CODEC_ID_PCM_U16LE:
5787 case AV_CODEC_ID_PCM_U16BE:
5788 case AV_CODEC_ID_PCM_S16LE:
5789 case AV_CODEC_ID_PCM_S16BE:
5791 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
5797 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5800 case AV_CODEC_ID_PCM_S16LE_PLANAR:
5801 case AV_CODEC_ID_PCM_S16BE_PLANAR:
5803 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P);
5809 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5812 case AV_CODEC_ID_PCM_U24LE:
5813 case AV_CODEC_ID_PCM_U24BE:
5814 case AV_CODEC_ID_PCM_S24LE:
5815 case AV_CODEC_ID_PCM_S24BE:
5816 case AV_CODEC_ID_PCM_U32LE:
5817 case AV_CODEC_ID_PCM_U32BE:
5818 case AV_CODEC_ID_PCM_S32LE:
5819 case AV_CODEC_ID_PCM_S32BE:
5821 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S32);
5827 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5830 case AV_CODEC_ID_PCM_S24LE_PLANAR:
5831 case AV_CODEC_ID_PCM_S32LE_PLANAR:
5833 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S32P);
5839 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5842 case AV_CODEC_ID_PCM_S64LE:
5843 case AV_CODEC_ID_PCM_S64BE:
5845 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S64);
5851 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5854 case AV_CODEC_ID_PCM_F16LE:
5855 case AV_CODEC_ID_PCM_F24LE:
5856 case AV_CODEC_ID_PCM_F32BE:
5857 case AV_CODEC_ID_PCM_F32LE:
5858 case AV_CODEC_ID_PCM_F64BE:
5859 case AV_CODEC_ID_PCM_F64LE:
5861 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT);
5867 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5870 case AV_CODEC_ID_VORBIS:
5873 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
5874 *filesize =
static_cast<size_t>(900 * (*filesize) / 1000);
5877 case AV_CODEC_ID_OPUS:
5880 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
5881 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
5884 case AV_CODEC_ID_ALAC:
5886 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
5891 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5892 *filesize =
static_cast<size_t>(620 * (*filesize) / 1000);
5895 case AV_CODEC_ID_AC3:
5898 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
5899 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
5902 case AV_CODEC_ID_FLAC:
5904 int bytes_per_sample = av_get_bytes_per_sample(sample_format != AV_SAMPLE_FMT_NONE ? sample_format : AV_SAMPLE_FMT_S16);
5909 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
5910 *filesize =
static_cast<size_t>(600 * (*filesize) / 1000);
5913 case AV_CODEC_ID_NONE:
5929 bool success =
true;
5935 case AV_CODEC_ID_MPEG1VIDEO:
5937 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5938 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
5941 case AV_CODEC_ID_MPEG2VIDEO:
5943 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5944 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
5947 case AV_CODEC_ID_H264:
5949 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5950 *filesize =
static_cast<size_t>(1050 * (*filesize) / 1000);
5953 case AV_CODEC_ID_H265:
5955 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5956 *filesize =
static_cast<size_t>(1250 * (*filesize) / 1000);
5959 case AV_CODEC_ID_THEORA:
5961 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5962 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
5965 case AV_CODEC_ID_VP8:
5967 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5968 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
5971 case AV_CODEC_ID_VP9:
5973 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5974 *filesize =
static_cast<size_t>(1450 * (*filesize) / 1000);
5977 case AV_CODEC_ID_AV1:
5979 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
5983 case AV_CODEC_ID_PRORES:
5988 case AV_CODEC_ID_PNG:
5989 case AV_CODEC_ID_BMP:
5990 case AV_CODEC_ID_MJPEG:
5994 *filesize +=
static_cast<size_t>(width * height * 24 / 8);
5997 case AV_CODEC_ID_NONE:
6012 bool success =
true;
6023 *filesize += 250000;
6034 case FILETYPE::AIFF:
6041 case FILETYPE::OPUS:
6042 case FILETYPE::ALAC:
6043 case FILETYPE::FLAC:
6053 *filesize += 1600000;
6058 case FILETYPE::WEBM:
6060 case FILETYPE::PRORES:
6077 case FILETYPE::UNKNOWN:
6100 size_t filesize = 0;
6103 BITRATE input_audio_bit_rate = 0;
6104 int input_sample_rate = 0;
6105 BITRATE input_video_bit_rate = 0;
6107 if (
m_fileio->duration() != AV_NOPTS_VALUE)
6109 file_duration =
m_fileio->duration();
6123 if (input_audio_bit_rate)
6133 if (input_video_bit_rate)
6199 if (virtualfile !=
nullptr)
6226 Logging::error(
nullptr,
"input_read(): Internal error: FileIO is NULL!");
6227 return AVERROR(EINVAL);
6236 int read =
static_cast<int>(io->
readio(
reinterpret_cast<char *
>(data),
static_cast<size_t>(size)));
6238 if (read != size && io->
error())
6241 return AVERROR(io->
error());
6247#if LAVF_WRITEPACKET_CONST
6255 if (buffer ==
nullptr)
6257 Logging::error(
nullptr,
"input_write(): Internal error: FileIO is NULL!");
6258 return AVERROR(EINVAL);
6261#if LAVF_WRITEPACKET_CONST
6262 int written =
static_cast<int>(buffer->
writeio(data,
static_cast<size_t>(size)));
6264 int written =
static_cast<int>(buffer->
writeio(
static_cast<const uint8_t*
>(data),
static_cast<size_t>(size)));
6266 if (written != size)
6269 return (AVERROR(errno));
6277 int64_t res_offset = 0;
6281 Logging::error(
nullptr,
"seek(): Internal error: FileIO is NULL!");
6282 return AVERROR(EINVAL);
6285 if (whence & AVSEEK_SIZE)
6288 res_offset =
static_cast<int64_t
>(io->
size());
6292 whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE);
6294 if (!io->
seek(offset, whence))
6297 res_offset = offset;
6302 res_offset = AVERROR(errno);
6323 int audio_samples_left = 0;
6332 return audio_samples_left;
6353 av_packet_unref(pkt);
6356 return hls_packets_left;
6361 std::string outfile;
6375 const char *p = outfile.empty() ? nullptr : outfile.c_str();
6376 if (audio_samples_left)
6378 Logging::warning(p,
"%1 audio samples left in buffer and not written to target file!", audio_samples_left);
6383 Logging::warning(p,
"%1 frames left in buffer and not written to target file!", frames_left);
6386 if (hls_packets_left)
6388 Logging::warning(p,
"%1 HLS packets left in buffer and not written to target file!", hls_packets_left);
6394 bool closed =
false;
6418#if (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 80, 0))
6437 bool closed =
false;
6459#if (LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 80, 0))
6478 bool closed =
false;
6515 const AVFilter * buffer_src = avfilter_get_by_name(
"buffer");
6516 const AVFilter * buffer_sink = avfilter_get_by_name(
"buffersink");
6517 AVFilterInOut * outputs = avfilter_inout_alloc();
6518 AVFilterInOut * inputs = avfilter_inout_alloc();
6528 if (!avg_frame_rate.den && !avg_frame_rate.num)
6531 throw static_cast<int>(AVERROR(EINVAL));
6536 if (outputs ==
nullptr || inputs ==
nullptr ||
m_filter_graph ==
nullptr)
6538 throw static_cast<int>(AVERROR(ENOMEM));
6544 strsprintf(&args,
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
6545 codec_ctx->width, codec_ctx->height, pix_fmt,
6546 time_base.num, time_base.den,
6547 codec_ctx->sample_aspect_ratio.num, FFMAX(codec_ctx->sample_aspect_ratio.den, 1));
6570 std::array<enum AVPixelFormat, 3> pixel_fmts;
6572 pixel_fmts[0] = pix_fmt;
6573 pixel_fmts[1] = AV_PIX_FMT_NONE;
6584#pragma GCC diagnostic push
6585#pragma GCC diagnostic ignored "-Wconversion"
6586#pragma GCC diagnostic ignored "-Wsign-conversion"
6587 ret = av_opt_set_int_list(
m_buffer_sink_context,
"pix_fmts", pixel_fmts.data(), AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
6588#pragma GCC diagnostic pop
6597 outputs->name = av_strdup(
"in");
6599 outputs->pad_idx = 0;
6600 outputs->next =
nullptr;
6601 inputs->name = av_strdup(
"out");
6603 inputs->pad_idx = 0;
6604 inputs->next =
nullptr;
6610 const char * filters;
6612 filters =
"yadif=mode=send_frame:parity=auto:deint=all";
6622 ret = avfilter_graph_parse_ptr(
m_filter_graph, filters, &inputs, &outputs,
nullptr);
6643 if (inputs !=
nullptr)
6645 avfilter_inout_free(&inputs);
6647 if (outputs !=
nullptr)
6649 avfilter_inout_free(&outputs);
6665 ret = filterframe.
res();
6682 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
6695 filterframe->pts = (*srcframe)->pts;
6696 filterframe->best_effort_timestamp = (*srcframe)->best_effort_timestamp;
6698 *srcframe = filterframe;
6745 return AVERROR(EINVAL);
6761 return AVERROR(EINVAL);
6810 return pThis->
get_format(input_codec_ctx, pix_fmts);
6818 Logging::error(
filename(),
"Unable to decode this file using hardware acceleration: Internal error! No hardware device type set.");
6819 return AV_PIX_FMT_NONE;
6824 for (
const AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++)
6826 if (*p == pix_fmt_expected)
6828 return pix_fmt_expected;
6834 return AV_PIX_FMT_NONE;
6839 std::string active_device(device);
6842 if (active_device ==
"AUTO" && dev_type == AV_HWDEVICE_TYPE_VAAPI)
6844 active_device =
"/dev/dri/renderD128";
6847 ret = av_hwdevice_ctx_create(hwaccel_enc_device_ctx, dev_type, !active_device.empty() ? active_device.c_str() :
nullptr,
nullptr, 0);
6860 int ret = AVERROR(EINVAL);
6866 if (input_codec_ctx->hw_device_ctx ==
nullptr)
6868 int ret = AVERROR(ENOMEM);
6873 input_codec_ctx->opaque =
static_cast<void*
>(
this);
6881 if (*hwaccel_device_ctx !=
nullptr)
6883 av_buffer_unref(hwaccel_device_ctx);
6884 *hwaccel_device_ctx =
nullptr;
6890 AVBufferRef *hw_new_frames_ref;
6891 AVHWFramesContext *frames_ctx =
nullptr;
6894 hw_new_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
6895 if (hw_new_frames_ref ==
nullptr)
6897 ret = AVERROR(ENOMEM);
6902 frames_ctx =
reinterpret_cast<AVHWFramesContext *
>(hw_new_frames_ref->data);
6905 frames_ctx->width = input_codec_ctx->width;
6906 frames_ctx->height = input_codec_ctx->height;
6908 frames_ctx->initial_pool_size = 20;
6910 ret = av_hwframe_ctx_init(hw_new_frames_ref);
6914 av_buffer_unref(&hw_new_frames_ref);
6918 output_codec_ctx->hw_frames_ctx = av_buffer_ref(hw_new_frames_ref);
6919 if (output_codec_ctx->hw_frames_ctx ==
nullptr)
6921 ret = AVERROR(ENOMEM);
6925 av_buffer_unref(&hw_new_frames_ref);
6997 ret = av_frame_copy_props(*sw_frame, hw_frame);
7004 ret = av_hwframe_transfer_data(*sw_frame, hw_frame, 0);
7018 ret = av_frame_copy_props(*hw_frame, sw_frame);
7025 ret = av_hwframe_get_buffer(output_codec_ctx->hw_frames_ctx, *hw_frame, 0);
7032 if ((*hw_frame)->hw_frames_ctx ==
nullptr)
7034 ret = AVERROR(ENOMEM);
7039 ret = av_hwframe_transfer_data(*hw_frame, sw_frame, 0);
7062 std::string codec_name_buf;
7082 case HWACCELAPI::NONE:
7085 ret = AVERROR_DECODER_NOT_FOUND;
7090 if (codec_name !=
nullptr)
7094 *codec_name = codec_name_buf;
7098 codec_name->clear();
7107 std::string codec_name_buf;
7127 case HWACCELAPI::NONE:
7130 ret = AVERROR_DECODER_NOT_FOUND;
7135 if (codec_name !=
nullptr)
7139 *codec_name = codec_name_buf;
7143 codec_name->clear();
7167 case AV_CODEC_ID_H264:
7169 *codec_name =
"h264_vaapi";
7203 case AV_CODEC_ID_MPEG2VIDEO:
7205 *codec_name =
"mpeg2_vaapi";
7208 case AV_CODEC_ID_HEVC:
7210 *codec_name =
"hevc_vaapi";
7213 case AV_CODEC_ID_VC1:
7215 *codec_name =
"vc1_vaapi";
7218 case AV_CODEC_ID_VP8:
7220 *codec_name =
"vp9_vaapi";
7223 case AV_CODEC_ID_VP9:
7225 *codec_name =
"vp9_vaapi";
7230 ret = AVERROR_DECODER_NOT_FOUND;
7252 case AV_CODEC_ID_H264:
7254 *codec_name =
"h264_mmal";
7274 case AV_CODEC_ID_MPEG2VIDEO:
7276 *codec_name =
"mpeg2_mmal";
7279 case AV_CODEC_ID_MPEG4:
7281 *codec_name =
"mpeg4_mmal";
7297 case AV_CODEC_ID_VC1:
7299 *codec_name =
"vc1_mmal";
7304 ret = AVERROR_DECODER_NOT_FOUND;
7395 case AV_CODEC_ID_H264:
7397 *codec_name =
"h264_omx";
7402 ret = AVERROR_DECODER_NOT_FOUND;
7424 case AV_CODEC_ID_H263:
7426 *codec_name =
"h263_v4l2m2m";
7429 case AV_CODEC_ID_H264:
7431 *codec_name =
"h264_v4l2m2m";
7434 case AV_CODEC_ID_H265:
7436 *codec_name =
"hevc_v4l2m2m";
7439 case AV_CODEC_ID_MPEG4:
7441 *codec_name =
"mpeg4_v4l2m2m";
7444 case AV_CODEC_ID_VP8:
7446 *codec_name =
"vp8_v4l2m2m";
7451 ret = AVERROR_DECODER_NOT_FOUND;
7465 return AV_PIX_FMT_NONE;
7480 if (output_codec_ctx ==
nullptr)
7486 *out_pix_fmt = (output_codec_ctx !=
nullptr) ? output_codec_ctx->pix_fmt : AV_PIX_FMT_YUV420P;
7488 if (*in_pix_fmt == AV_PIX_FMT_NONE)
7491 *in_pix_fmt = *out_pix_fmt;
7498 output_codec_ctx !=
nullptr &&
7499 output_codec_ctx->hw_frames_ctx !=
nullptr &&
7500 output_codec_ctx->hw_frames_ctx->data !=
nullptr)
7502 *out_pix_fmt =
reinterpret_cast<AVHWFramesContext*
>(output_codec_ctx->hw_frames_ctx->data)->sw_format;
7513 return (next_segment ==
m_current_segment + 1 && next_segment <= m_virtualfile->get_segment_count());
7528 StreamRef_map::const_iterator it =
m_in.
m_subtitle.find(stream_idx);
7554 m_stream_map.insert(std::make_pair(in_stream_idx, out_stream_idx));
7560 STREAM_MAP::const_iterator it =
m_stream_map.find(in_stream_idx);
7567 return (it->second);
7576 const std::filesystem::directory_iterator end;
7577 for (std::filesystem::directory_iterator iter{ search_path }; iter != end && ret == 0; iter++)
7579 const std::string subtitle_filename(iter->path().filename().string());
7580 if (std::filesystem::is_regular_file(*iter))
7582 if (std::regex_match(subtitle_filename, regex))
7585 if (std::regex_search(subtitle_filename.cbegin(), subtitle_filename.cend(), res, regex))
7587 if (res[2].length())
7589 ret = f(iter->path().string(), res[2]);
7593 ret = f(iter->path().string(), std::nullopt);
7598 else if (std::filesystem::is_directory(*iter) && depth > 0)
7604 catch (std::filesystem::filesystem_error& e)
7606 ret = AVERROR(e.code().value());
7609 catch (std::bad_alloc & e)
7611 ret = AVERROR(ENOMEM);
7621 buf_size = FFMIN(buf_size,
static_cast<int>(bd->
size));
7629 std::memcpy(buf, bd->
ptr,
static_cast<size_t>(buf_size));
7630 bd->
ptr += buf_size;
7631 bd->
size -=
static_cast<size_t>(buf_size);
7638 AVFormatContext *format_ctx =
nullptr;
7639 AVIOContext *avio_ctx =
nullptr;
7640 uint8_t *buffer =
nullptr;
7646 Logging::debug(
filename(),
"Adding external subtitle stream: %1 [%2]", subtitle_file.c_str(), language->c_str());
7655 uint8_t *avio_ctx_buffer =
nullptr;
7656 int avio_ctx_buffer_size = 4096;
7660 ret = av_file_map(subtitle_file.c_str(), &buffer, &buffer_size, 0,
nullptr);
7668 bd.
size = buffer_size;
7670 format_ctx = avformat_alloc_context();
7671 if (format_ctx ==
nullptr)
7673 throw AVERROR(ENOMEM);
7676 avio_ctx_buffer =
reinterpret_cast<uint8_t *
>(av_malloc(
static_cast<size_t>(avio_ctx_buffer_size)));
7677 if (avio_ctx_buffer ==
nullptr)
7679 throw AVERROR(ENOMEM);
7682 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, &bd, &
read_packet,
nullptr,
nullptr);
7683 if (avio_ctx ==
nullptr)
7685 throw AVERROR(ENOMEM);
7687 format_ctx->pb = avio_ctx;
7689 ret = avformat_open_input(&format_ctx,
nullptr,
nullptr,
nullptr);
7696 ret = avformat_find_stream_info(format_ctx,
nullptr);
7705 AVCodecContext * codec_ctx =
nullptr;
7709 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
7715 if (ret != AVERROR_STREAM_NOT_FOUND)
7719 if (codec_id != AV_CODEC_ID_NONE)
7723 codec_ctx->pkt_timebase = codec_ctx->time_base = format_ctx->streams[0]->time_base;
7727 input_streamref.
m_stream = format_ctx->streams[0];
7739 int output_stream_index = ret;
7741 while ((ret = av_read_frame(format_ctx, &pkt)) == 0)
7744 ret =
decode_subtitle(codec_ctx, &pkt, &decoded, output_stream_index);
7753 if (ret == AVERROR_EOF)
7763 avformat_close_input(&format_ctx);
7766 if (avio_ctx !=
nullptr)
7768 av_freep(&avio_ctx->buffer);
7771 avio_context_free(&avio_ctx);
7773 av_file_unmap(buffer, buffer_size);
7784 std::filesystem::path file(
filename());
7785 std::string stem(file.stem().string());
7790 std::string regex_string(
"^(" + stem +
"[.])(.*)([.]srt|[.]vtt)|^(" + stem +
")([.]srt|[.]vtt)");
7791 std::regex regex(regex_string, std::regex::ECMAScript);
7801 file.parent_path().string(),
7804 [
this](
const std::string & subtitle_file,
const std::optional<std::string> & language)
7806 add_external_subtitle_stream(std::forward<decltype(subtitle_file)>(subtitle_file), std::forward<decltype(language)>(language));
7828 catch (std::regex_error & e)
7831 Logging::error(
filename(),
"INTERNAL ERROR: FFmpeg_Transcoder::add_external_subtitle_streams()! Unable to create reg exp: %1", e.what());
7839 MULTIFRAME_MAP::const_reverse_iterator it =
m_frame_map.crbegin();
AIFF file structures http://paulbourke.net/dataformats/audio/.
#define AIFF_SOUNDATAID
ckID for Sound Data Chunk
#define AIFF_COMMONID
ckID for Common Chunk
#define AIFF_FORMID
ckID for Form Chunk
#define CACHE_FLAG_RW
Mark cache file writeable, implies read permissions.
@ NONE
No result code available.
virtual bool eof() const override
Check if at end of file.
bool segment_exists(uint32_t segment_no)
Check if segment exists.
void finished_segment()
Complete the segment decoding.
virtual int seek(int64_t offset, int whence) override
Seek to position in file.
size_t writeio(const uint8_t *data, size_t length)
Write data to the current position in the buffer. The position pointer will be updated.
size_t write_frame(const uint8_t *data, size_t length, uint32_t frame_no)
Write image data for the frame number into the buffer.
bool have_frame(uint32_t frame_no)
Check if we have the requested frame number. Works only when processing a frame set.
bool copy(std::vector< uint8_t > *out_data, size_t offset, uint32_t segment_no=0)
Copy buffered data into output buffer.
virtual size_t tell() const override
Get the value of the internal read position pointer.
bool set_segment(uint32_t segment_no, size_t size)
Set the current segment.
bool open_file(uint32_t segment_no, uint32_t flags, size_t defaultsize=0)
Open the cache file if not already open.
size_t buffer_watermark(uint32_t segment_no=0) const
Return the current watermark of the file while transcoding.
static std::string get_sample_fmt_name(AVSampleFormat sample_fmt)
Calls av_get_sample_fmt_name and returns a std::string with the format name.
int get_channels(const AVCodecParameters *codecpar) const
Get the number of channels from AVCodecParameters.
int opt_set_with_check(void *obj, const char *key, const char *value, int flags, const char *filename=nullptr) const
Call av_opt_set and check result code. Displays an error message if appropriate.
int get_script_info(AVCodecContext *codec_ctx, int play_res_x, int play_res_y, const char *font, int font_size, int primary_color, int secondary_color, int outline_color, int back_color, int bold, int italic, int underline, int border_style, int alignment) const
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. Nicked from the FFmpeg API funct...
void audio_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) const
Print data from the audio stream to log.
int64_t frame_to_pts(AVStream *stream, uint32_t frame_no) const
Convert frame number to PTS value.
uint32_t pts_to_frame(AVStream *stream, int64_t pts) const
Convert PTS value to frame number.
void video_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) const
Print data from the video stream to a log.
void subtitle_info(bool out_file, const AVFormatContext *format_ctx, const AVStream *stream) const
Print data from the subtitle stream to log.
VIRTUALFILE * m_virtualfile
Underlying virtual file object.
void video_stream_setup(AVCodecContext *output_codec_ctx, AVStream *output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt) const
Set up a video stream.
static std::string get_channel_layout_name(const AVChannelLayout *ch_layout)
Calls av_channel_layout_describe and returns a std::string with the channel layout.
static std::string get_pix_fmt_name(AVPixelFormat pix_fmt)
Calls av_get_pix_fmt_name and returns a std::string with the pix format name.
int dict_set_with_check(AVDictionary **pm, const char *key, const char *value, int flags, const char *filename=nullptr, bool nodelete=false) const
Call av_dict_set and check the result code. It displays an error message if appropriate.
void set_channels(AVCodecParameters *codecpar_out, const AVCodecParameters *codecpar_in) const
Set the number of channels from AVCodecParameters.
int m_stream_idx
Stream index frame belongs to, or -1 (INVALID_STREAM)
int res() const
Get result of last operation.
static const PROFILE_LIST_VEC m_profile
List of profile options.
std::vector< PROFILE_OPTION > PROFILE_OPTION_VEC
PROFILE_OPTION array.
The FFmpeg_Subtitle class.
int m_stream_idx
Stream index frame belongs to, or -1 (INVALID_STREAM)
int res() const
Get result of last operation.
In/output stream reference data.
int m_stream_idx
Stream index in AVFormatContext.
int64_t m_start_time
Start time of the stream in stream time base units, may be 0.
AVStream * m_stream
AVStream for this encoder stream.
void reset()
Close (reset) AVCodecContext pointer.
void set_codec_ctx(AVCodecContext *codec_ctx)
Set the AVCodecContext pointer. Will be shared and deleted after the last consumer freed it.
std::shared_ptr< AVCodecContext > m_codec_ctx
AVCodecContext for this encoder stream.
The FFmpeg_Transcoder class.
int add_samples_to_fifo(uint8_t **converted_input_samples, int frame_size)
Add converted input audio samples to the FIFO buffer for later processing.
uint32_t m_current_segment
HLS only: Segment file number currently being encoded.
static bool video_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int width, int height, bool interleaved, const AVRational &framerate)
Predict video file size. This may (better will surely) be inaccurate.
int add_subtitle_stream(AVCodecID codec_id, StreamRef &input_streamref, const std::optional< std::string > &language=std::nullopt)
Add new subtitle stream to output file.
HWACCELMODE
Currently active hardware acceleration mode.
@ ENABLED
Hardware acceleration is active.
@ FALLBACK
Hardware acceleration selected, but fell back to software.
bool m_hwaccel_enable_enc_buffering
Enable hardware acceleration frame buffers for encoder.
int open_albumarts()
open_albumarts
static const DEVICETYPE_MAP m_devicetype_map
List of AVPixelFormats mapped to hardware acceleration types.
int open_output(Buffer *buffer)
Open output file. Data will actually be written to buffer and copied by FUSE when accessed.
int flush_frames_all(bool use_flush_packet)
Flush the remaining frames for all streams.
int stack_seek_frame(uint32_t frame_no)
Seek to a specific frame. Does not actually perform the seek, this is done asynchronously by the tran...
int get_hw_vaapi_codec_name(AVCodecID codec_id, std::string *codec_name) const
Determine VAAPI codec name.
int purge_audio_fifo()
Purge all samples in audio FIFO.
int open_bestmatch_audio()
Open the best match audio stream.
virtual const char * filename() const override
Return source filename.
int get_hw_omx_encoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine OMX encoder codec name.
int process_single_fr(DECODER_STATUS *status)
AVAudioFifo * m_audio_fifo
Audio sample FIFO.
bool can_copy_stream(const AVStream *stream) const
Check if stream can be copied from input to output (AUTOCOPY option).
static int input_read(void *opaque, unsigned char *data, int size)
Custom read function for FFmpeg.
size_t purge_multiframe_map()
Purge all frames in buffer.
int get_hw_mmal_decoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine MMAL decoder codec name.
bool m_hwaccel_enable_dec_buffering
Enable hardware acceleration frame buffers for decoder.
AVSampleFormat m_cur_sample_fmt
Currently selected audio sample format.
int store_packet(AVPacket *pkt, AVMediaType mediatype)
Store packet in output stream.
void purge()
Purge FIFO and map buffers and report lost packets/frames/samples.
int add_stream_copy(AVCodecID codec_id, AVMediaType codec_type)
Add new stream copy to output file.
const FFmpegfs_Format * m_current_format
Currently used output format(s)
int map_in_to_out_stream(int in_stream_idx) const
Map input stream index to output stream index.
static bool audio_size(size_t *filesize, AVCodecID codec_id, BITRATE bit_rate, int64_t duration, int channels, int sample_rate, AVSampleFormat sample_format)
Predict audio file size. This may (better will surely) be inaccurate.
bool have_seeked() const
Check if we made a seek operation.
int add_external_subtitle_streams()
Scan for external subtitle files.
int init_deinterlace_filters(AVCodecContext *codec_ctx, AVPixelFormat pix_fmt, const AVRational &avg_frame_rate, const AVRational &time_base)
Initialise video filters.
int prepare_format(AVDictionary **dict, FILETYPE filetype) const
Prepare format optimisations.
StreamRef * get_out_subtitle_stream(int stream_idx)
Get subtitle stream for the stream index.
INPUTFILE m_in
Input file information.
int decode_video_frame(AVPacket *pkt, int *decoded)
Decode one video frame.
int decode_subtitle(AVPacket *pkt, int *decoded)
Decode one subtitle.
bool m_copy_video
If true, copy video stream from source to target (just remux, no recode).
uint32_t m_inhibit_stream_msk
HLS: Currently inhibited streams bit mask. Packets temporarly go to m_hls_packet_fifo and will be pre...
std::queue< uint32_t > m_seek_to_fifo
Stack of seek requests. Will be processed FIFO.
uint32_t get_next_segment(int64_t pos) const
Calculate next HLS segment from position.
int open_subtitles()
Open all subtitles streams, if present in input file and if supported by output file....
std::queue< AVPacket * > m_hls_packet_fifo
HLS packet FIFO.
int open_bestmatch_video()
Open the best match video stream, if present in input file.
static AVPixelFormat find_sw_fmt_by_hw_type(AVHWDeviceType type)
Get the software pixel format for the given hardware acceleration.
int send_filters(FFmpeg_Frame *srcframe, int &ret)
Send video frame to the filters.
bool m_insert_keyframe
HLS only: Allow insertion of 1 keyframe.
int init_converted_samples(uint8_t ***converted_input_samples, int frame_size)
Initialise a temporary storage for the specified number of audio samples. The conversion requires tem...
static int output_write(void *opaque, const uint8_t *data, int size)
Custom write function for FFmpeg.
static bool get_output_sample_rate(int input_sample_rate, int max_sample_rate, int *output_sample_rate=nullptr)
Calculate output sample rate based on user option.
bool close_input_file()
Closes the input file if open. Can safely be called again after the file was already closed or if the...
void copy_metadata(AVDictionary **metadata_out, const AVDictionary *metadata_in, bool contentstream=true)
Process the metadata in the FFmpeg file. This should be called at the beginning, before reading audio...
int update_codec(void *opt, const PROFILE_OPTION_VEC &profile_option_vec) const
Prepare codec options.
void flush_buffers()
Flush FFmpeg's input buffers.
int add_external_subtitle_stream(const std::string &subtitle_file, const std::optional< std::string > &language)
add_external_subtitle_stream
AVFilterGraph * m_filter_graph
Video filter graph.
bool get_aspect_ratio(int width, int height, const AVRational &sar, AVRational *ar) const
Calculate aspect ratio for width/height and sample aspect ratio (sar).
enum AVPixelFormat get_format(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts) const
uint32_t m_reset_pts
We have to reset audio/video pts to the new position.
AVBufferRef * m_hwaccel_dec_device_ctx
Hardware acceleration device context for decoder.
int init_resampler()
Initialize the audio resampler based on the input and output codec settings. If the input and output ...
Buffer * m_buffer
Pointer to cache buffer object.
int encode_video_frame(const AVFrame *frame, int *data_present)
Encode one frame worth of video to the output file.
std::shared_ptr< FileIO > m_fileio
FileIO object of input file.
bool m_skip_next_frame
After seek, skip next video frame.
void closeio()
Close transcoder, free all ressources.
int read_decode_convert_and_store(int *finished)
Read frame from source file, decode and store in FIFO.
int add_albumart_frame(AVStream *output_stream, AVPacket *pkt_in)
Add album art to stream.
int get_hw_encoder_name(AVCodecID codec_id, std::string *codec_name=nullptr) const
Get the hardware codec name as string. This is required, because e.g. the name for the software codec...
uint32_t video_frame_count() const
Get the number of video frames in file.
bool is_hls() const
Check for HLS format.
int copy_audio_to_frame_buffer(int *finished)
Copy data from audio FIFO to frame buffer. Divides WAV data into proper chunks to be fed into the enc...
int create_fake_aiff_header() const
Create a fake AIFF header Create a fake AIFF header. Inserts predicted file sizes to allow playback t...
int read_aiff_chunk(Buffer *buffer, size_t *buffoffset, const char *ID, uint8_t *chunk, size_t *size) const
Read AIFF chunk.
bool is_audio_stream(int stream_idx) const
Check for audio stream.
MULTIFRAME_MAP m_frame_map
Audio/video/subtitle frame map.
bool goto_next_segment(uint32_t next_segment) const
Check if segment number is next designated segment.
size_t predicted_filesize() const
Try to predict the recoded file size. This may (better will surely) be inaccurate.
bool is_video_stream(int stream_idx) const
Check for video stream.
static bool total_overhead(size_t *filesize, FILETYPE filetype)
Predict overhead in file size. This may (better will surely) be inaccurate.
bool is_subtitle_stream(int stream_idx) const
Check for subtitle stream.
int add_albumart_stream(const AVCodecContext *input_codec_ctx)
Add a stream for an album art.
int64_t m_pos
Generated position.
bool m_have_seeked
After seek operations this is set to make sure the trancoding result is marked RESULTCODE_INCOMPLETE ...
AVPixelFormat get_hw_pix_fmt(const AVCodec *codec, AVHWDeviceType dev_type, bool use_device_ctx) const
Determine the hardware pixel format for the codec, if applicable.
int flush_delayed_audio()
Flush delayed audio packets, if there are any.
int do_seek_frame(uint32_t frame_no)
Actually perform seek for frame. This function ensures that it is positioned at a key frame,...
int decode(AVCodecContext *codec_ctx, AVFrame *frame, int *got_frame, const AVPacket *pkt) const
const ID3v1 * id3v1tag() const
Assemble an ID3v1 file tag.
size_t calculate_predicted_filesize() const
Try to predict final file size.
int init_audio_output_frame(AVFrame *frame, int frame_size) const
Initialise one input frame for writing to the output file. The frame will be exactly frame_size sampl...
int encode_image_frame(const AVFrame *frame, int *data_present)
Encode frame to image.
static BITRATE get_prores_bitrate(int width, int height, const AVRational &framerate, bool interleaved, PRORESLEVEL profile)
Calculate the appropriate bitrate for a ProRes file given several parameters.
static int64_t seek(void *opaque, int64_t offset, int whence)
Custom seek function for FFmpeg.
uint32_t segment_count() const
Get the number of HLS segments of file.
int get_hw_v4l2m2m_encoder_name(AVCodecID codec_id, std::string *codec_name) const
Determine video for linux encoder codec name.
bool m_is_video
true if input is a video file
int alloc_picture(AVFrame *frame, AVPixelFormat pix_fmt, int width, int height) const
Allocate memory for one picture.
AVBufferRef * m_hwaccel_enc_device_ctx
Hardware acceleration device context for encoder.
static const std::vector< PRORES_BITRATE > m_prores_bitrate
ProRes bitrate table. Used for file size prediction.
int prepare_codec(void *opt, FILETYPE filetype) const
Prepare codec options for a file type.
void add_stream_map(int in_stream_idx, int out_stream_idx)
Add entry to input stream to output stream map.
int decode_frame(AVPacket *pkt)
Decode one frame.
int add_subtitle_streams()
Add all subtitle streams. Already existing streams are not added again.
int open_output_filestreams(Buffer *buffer)
Open an output file and the required encoder. Also set some basic encoder parameters....
int64_t m_cur_video_ts
If the video stream is copied and the time stamps are absent from the input stream,...
bool stream_exists(int stream_idx) const
Check if stream exists.
std::variant< FFmpeg_Frame, FFmpeg_Subtitle > MULTIFRAME
Combined audio/videoframe and subtitle.
bool is_multiformat() const
Check for an export frame format.
HWACCELMODE m_hwaccel_dec_mode
Current hardware acceleration mode for decoder.
int skip_decoded_frames(uint32_t frame_no, bool forced_seek)
Skip decoded frames or force seek to frame_no.
STREAM_MAP m_stream_map
Input stream to output stream map.
int create_audio_frame(int frame_size)
Load one audio frame from the FIFO buffer and store in frame buffer.
int write_output_file_header()
Write the header of the output file container.
int hwdevice_ctx_create(AVBufferRef **hwaccel_enc_device_ctx, AVHWDeviceType dev_type, const std::string &device) const
virtual const char * virtname() const override
Return virtual filename. Same as destination filename, but with virtual (mount) path....
void free_filters()
Free filter sinks.
virtual const char * destname() const override
Return destination filename.
uint32_t m_fake_frame_no
The MJEPG codec requires monotonically growing PTS values so we fake some to avoid them going backwar...
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
FFmpeg_Transcoder::read_packet.
int flush_frames_single(int stream_idx, bool use_flush_packet)
Flush the remaining frames.
AVFilterContext * m_buffer_sink_context
Video filter sink context.
int open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int stream_idx, const AVCodec *input_codec, AVMediaType mediatype)
Open codec context for stream_idx.
int open_output_frame_set(Buffer *buffer)
Open output frame set. Data will actually be written to buffer and copied by FUSE when accessed.
int write_output_file_trailer()
Write the trailer of the output file container.
int create_fake_wav_header() const
Create a fake WAV header Create a fake WAV header. Inserts predicted file sizes to allow playback to ...
bool close_resample()
Close and free the resampler context.
int process_albumarts()
Copy all album arts from source to target.
int get_hw_decoder_name(AVCodecID codec_id, std::string *codec_name=nullptr) const
Get the hardware codec name as string. This is required, because e.g. the name for the software codec...
int64_t m_pts
Generated PTS.
int decode_audio_frame(AVPacket *pkt, int *decoded)
Decode one audio frame.
AVPixelFormat m_enc_hw_pix_fmt
Requested encoder hardware pixel format.
OUTPUTFILE m_out
Output file information.
int64_t m_cur_audio_ts
If the audio stream is copied and the time stamps are absent from the input stream,...
std::atomic_uint32_t m_last_seek_frame_no
If not 0, this is the last frame that we seeked to. Video sources only.
AVPixelFormat m_dec_hw_pix_fmt
Requested decoder hardware pixel format.
uint32_t last_seek_frame_no() const
Current seek frame if available.
int flush_delayed_subtitles()
Flush delayed subtitle packets, if there are any.
AVChannelLayout m_cur_ch_layout
Currently selected audio channel layout.
int process_metadata()
Copy metadata from source to target.
int init_rescaler(AVPixelFormat in_pix_fmt, int in_width, int in_height, AVPixelFormat out_pix_fmt, int out_width, int out_height)
Init image size rescaler and pixel format converter.
const char * tagcpy(char(&out)[size], const std::string &in) const
Safely copy a tag to a target buffer. If the input buffer size is larger than output the data will be...
int hwframe_copy_to_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *hw_frame, const AVFrame *sw_frame) const
int hwframe_ctx_set(AVCodecContext *output_codec_ctx, AVCodecContext *input_codec_ctx, AVBufferRef *hw_device_ctx) const
Adds a reference to an existing decoder hardware frame context or allocates a new AVHWFramesContext t...
int open_output_file(Buffer *buffer)
Open output file. Data will actually be written to buffer and copied by FUSE when accessed.
int open_bestmatch_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx, int *stream_idx, AVMediaType type)
Find best match stream and open codec context for it.
time_t mtime() const
Get last modification time of file.
bool close_output_file()
Closes the output file if open and reports lost packets. Can safely be called again after the file wa...
static enum AVPixelFormat get_format_static(AVCodecContext *input_codec_ctx, const enum AVPixelFormat *pix_fmts)
std::map< AVHWDeviceType, AVPixelFormat > DEVICETYPE_MAP
Map device types to pixel formats.
int64_t duration() const
Get the file duration.
size_t purge_hls_fifo()
Purge all packets in HLS FIFO buffer.
int init_audio_fifo()
Initialise a FIFO buffer for the audio samples to be encoded.
bool is_frameset() const
Check for an export frame format.
int process_output()
Process headers of output file Write file header, process meta data and add album arts.
int start_new_segment()
HLS only: start a new HLS segment.
AVFilterContext * m_buffer_source_context
Video filter source context.
int convert_samples(uint8_t **input_data, int in_samples, uint8_t **converted_data, int *out_samples)
Convert the input audio samples into the output sample format. The conversion happens on a per-frame ...
int64_t pts() const
Get PTS (presentation time stamp) of decoded audio/video so far.
std::recursive_mutex m_seek_to_fifo_mutex
Access mutex for seek FIFO.
int flush_delayed_video()
Flush delayed video packets, if there are any.
int hwdevice_ctx_add_ref(AVCodecContext *input_codec_ctx)
Add reference to hardware device context.
int m_cur_sample_rate
Currently selected audio sample rate.
int update_format(AVDictionary **dict, const PROFILE_OPTION_VEC &option_vec) const
Update format options.
SwrContext * m_audio_resample_ctx
SwResample context for audio resampling.
bool m_copy_audio
If true, copy audio stream from source to target (just remux, no recode).
int open_input_file(LPVIRTUALFILE virtualfile, std::shared_ptr< FileIO > fio=nullptr)
void make_pts(AVPacket *pkt, int64_t *cur_ts) const
Create PTS/DTS and update the packet. If the update packet lacks time stamps, create a fictitious PTS...
int stack_seek_segment(uint32_t segment_no)
Seek to a specific HLS segment. Does not actually perform the seek, this is done asynchronously by th...
SwsContext * m_sws_ctx
Context for video filtering.
time_t m_mtime
Modified time of input file.
void produce_audio_dts(AVPacket *pkt)
Produce audio dts/pts. This is required because the target codec usually has a different frame size t...
int hwframe_copy_from_hw(AVCodecContext *output_codec_ctx, FFmpeg_Frame *sw_frame, const AVFrame *hw_frame) const
int foreach_subtitle_file(const std::string &search_path, const std::regex ®ex, int depth, const std::function< int(const std::string &, const std::optional< std::string > &)> &f)
foreach_subititle_file
uint32_t m_active_stream_msk
HLS: Currently active streams bit mask. Set FFMPEGFS_AUDIO and/or FFMPEGFS_VIDEO.
virtual ~FFmpeg_Transcoder()
static bool get_output_bit_rate(BITRATE input_bit_rate, BITRATE max_bit_rate, BITRATE *output_bit_rate=nullptr)
Calculate output bit rate based on user option.
void get_pix_formats(AVPixelFormat *in_pix_fmt, AVPixelFormat *out_pix_fmt, AVCodecContext *output_codec_ctx=nullptr) const
Get correct input and output pixel format.
int seek_frame()
Frame sets only: perform seek to a certain frame.
HWACCELMODE m_hwaccel_enc_mode
Current hardware acceleration mode for encoder.
void hwdevice_ctx_free(AVBufferRef **hwaccel_device_ctx)
Free (remove reference) to hardware device context.
bool get_video_size(int *output_width, int *output_height) const
Get the size of the output video based on user selection and apsect ratio.
int add_stream(AVCodecID codec_id)
Add new stream to output file.
int encode_subtitle(const AVSubtitle *sub, int out_stream_idx, int *data_present)
Encode one subtitle frame to the output file.
int encode_audio_frame(const AVFrame *frame, int *data_present)
Create one frame worth of audio to the output file.
virtual int seek(int64_t offset, int whence)=0
Seek to position in file.
virtual size_t size() const =0
Get the file size.
LPVIRTUALFILE virtualfile()
Get virtual file object.
virtual size_t readio(void *data, size_t size)=0
Read data from a file.
virtual int error() const =0
Get last error.
static std::shared_ptr< FileIO > alloc(VIRTUALTYPE type)
Allocate the correct object for type().
virtual bool eof() const =0
Check if at end of file.
static void warning(const T filename, const std::string &format_string, Args &&...args)
Write warning level log entry.
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
static void info(const T filename, const std::string &format_string, Args &&...args)
Write info level log entry.
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
#define ASS_DEFAULT_PLAYRESY
Default Y resolution.
#define ASS_DEFAULT_ALIGNMENT
Default alignment: bottom centre Alignment values are based on the numeric keypad....
#define ASS_DEFAULT_PLAYRESX
Default X resolution.
#define ASS_DEFAULT_COLOUR
Default foreground colour: white.
#define ASS_DEFAULT_BACK_COLOUR
Default background colour.
#define ASS_DEFAULT_FONT_SIZE
Default font size.
#define ASS_DEFAULT_BORDERSTYLE
Default border style: outline with shadow 1 - Outline with shadow, 3 - Rendered with an opaque box.
#define ASS_DEFAULT_FONT
Default font name.
#define ASS_DEFAULT_BOLD
Default no bold font.
#define ASS_DEFAULT_UNDERLINE
Default no underline.
#define ASS_DEFAULT_ITALIC
Default no italics.
#define LAVU_DEP_OLD_CHANNEL_LAYOUT
#define OPT_VIDEO
For videos (not audio only)
#define OPT_HW_ONLY
Use this option for hardware encoding only.
#define OPT_AUDIO
For audio only files.
#define OPT_SW_ONLY
Use this option for software encoding only.
#define FRAME_SEEK_THRESHOLD
Ignore seek if target is within the next n frames.
#define MAX_PRORES_FRAMERATE
Number of selectable fram rates.
#define FFMPEGFS_AUDIO
Denote an audio stream.
#define FFMPEGFS_VIDEO
Denote a video stream.
DECODER_STATUS
Decoder status codes. Can be error, success or end of file.
@ DEC_ERROR
Decoder error, see return code.
@ DEC_EOF
Read to end of file.
@ DEC_SUCCESS
Frame decoded successfully.
const char * get_codec_name(AVCodecID codec_id, bool long_name)
Safe way to get the codec name. Function never fails, will return "unknown" on error.
std::string format_duration(int64_t value, uint32_t fracs)
Format a time in format HH:MM:SS.fract.
int strcasecmp(const std::string &s1, const std::string &s2)
strcasecmp() equivalent for std::string.
bool is_album_art(AVCodecID codec_id, const AVRational *frame_rate)
Minimal check if codec is an album art. Requires frame_rate to decide whether this is a video stream ...
const char * get_media_type_string(enum AVMediaType media_type)
av_get_media_type_string is missing, so we provide our own.
const std::string & regex_escape(std::string *str)
Escape characters that are meaningful to regexp.
const char * hwdevice_get_type_name(AVHWDeviceType dev_type)
int64_t ffmpeg_rescale_q_rnd(int64_t ts, const AVRational &timebase_in, const AVRational &timebase_out)
Convert a FFmpeg time from in timebase to out timebase with rounding.
std::string format_samplerate(int value)
Format a samplerate.
std::string make_filename(uint32_t file_no, const std::string &fileext)
Make a file name from file number and file extension.
std::string format_bitrate(BITRATE value)
Format a bit rate.
int print_stream_info(const AVStream *stream)
Print info about an AVStream.
void stat_set_size(struct stat *st, size_t size)
Properly fill in all size related members in stat struct.
void init_id3v1(ID3v1 *id3v1)
Initialise ID3v1 tag.
FILETYPE get_filetype_from_list(const std::string &desttypelist)
Get the FFmpegfs filetype, desttypelist must be a comma separated list of FFmpeg's "official" short n...
int64_t ffmpeg_rescale_q(int64_t ts, const AVRational &timebase_in, const AVRational &timebase_out)
Convert a FFmpeg time from in timebase to outtime base.
std::string ffmpeg_geterror(int errnum)
Get FFmpeg error string for errnum. Internally calls av_strerror().
#define BITRATE
For FFmpeg bit rate is an int.
#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE
AV_CODEC_CAP_VARIABLE_FRAME_SIZE is missing in older FFmpeg versions.
#define FF_INPUT_BUFFER_PADDING_SIZE
FF_INPUT_BUFFER_PADDING_SIZE is missing in newer FFmpeg versions.
#define AV_CODEC_FLAG_GLOBAL_HEADER
AV_CODEC_FLAG_GLOBAL_HEADER is missing in older FFmpeg versions.
@ STRICT
Copy stream if codec matches desired target, transcode otherwise.
@ MATCH
Copy stream if target supports codec.
@ MATCHLIMIT
Same as MATCH, only copy if target not larger transcode otherwise.
@ OFF
Never copy streams, transcode always.
@ STRICTLIMIT
Same as STRICT, only copy if target not larger, transcode otherwise.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
#define INVALID_STREAM
Denote an invalid stream.
#define SAFE_VALUE(p, v, d)
Access struct/class pointer safely, return default if nullptr.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
bool check_hwaccel_dec_blocked(AVCodecID codec_id, int profile)
Check if codec_id and the optional profile are in the block list.
std::string get_hwaccel_API_text(HWACCELAPI hwaccel_API)
Get the selected hardware acceleration as text.
Main include for FFmpegfs project.
LPVIRTUALFILE find_file(const std::string &virtfile)
Find file in cache.
@ BLURAY
Blu-ray disk file.
#define VIRTUALFLAG_CUESHEET
File is part of a set of cue sheet tracks or the directory.
#define VIRTUALFLAG_HIDDEN
File is not transcodable or should otherwise show in listings.
#define ID3V1_TAG_LENGTH
Fixed 128 bytes.
Provide various log facilities to stderr, disk or syslog.
uint32_t m_ckSize
Size of this chunk - 8.
uint32_t m_ckSize
Total size of sound data chunk - 8.
std::string m_hwaccel_enc_device
Encoder device. May be AUTO to auto detect or empty.
AVHWDeviceType m_hwaccel_dec_device_type
Enable hardware acceleration buffering for decoder.
int m_deinterlace
1: deinterlace video, 0: no deinterlace
int m_decoding_errors
Break transcoding on decoding error.
AVHWDeviceType m_hwaccel_enc_device_type
Enable hardware acceleration buffering for encoder.
int m_no_subtitles
0: allow subtitles, 1: do no transcode subtitles
std::string m_hwaccel_dec_device
Decoder device. May be AUTO to auto detect or empty.
const FFmpegfs_Format * current_format(LPCVIRTUALFILE virtualfile) const
Get FFmpegfs_Format for a virtual file.
int m_audiochannels
Max. number of audio channels.
int64_t m_min_seek_time_diff
Minimum time diff from current to next requested segment to perform a seek, in AV_TIME_BASE fractiona...
int m_videowidth
Output video width.
BITRATE m_videobitrate
Output video bit rate (bits per second)
HWACCELAPI m_hwaccel_dec_API
Decoder API.
int m_videoheight
Output video height.
int64_t m_segment_duration
Duration of one HLS segment file, in AV_TIME_BASE fractional seconds.
BITRATE m_audiobitrate
Output audio bit rate (bits per second)
PROFILE m_profile
Target profile: Firefox, MS Edge/IE or other.
int m_audiosamplerate
Output audio sample rate (in Hz)
PRORESLEVEL m_level
Level, currently proxy/hq/lt/HQ (ProRes only)
int m_noalbumarts
Skip album arts.
HWACCELAPI m_hwaccel_enc_API
Encoder API.
AUTOCOPY m_autocopy
Copy streams if codec matches.
Buffer structure, used in FFmpeg_Transcoder::read_packet.
size_t size
Size left in the buffer.
uint8_t * ptr
Pointer to buffer.
int64_t m_video_pts
Global timestamp for the video frames in output video stream time base units
ID3v1 m_id3v1
mp3 only, can be referenced at any time
int64_t m_audio_pts
Global timestamp for the audio frames in output audio stream time base units
int64_t m_last_mux_dts
Last muxed DTS.
std::array< char, 30 > m_title
Title of sound track.
std::array< char, 30 > m_artist
Artist name.
std::array< char, 30 > m_album
Album name.
char m_title_no
Title number.
std::array< char, 4 > m_year
Year of publishing.
std::array< char, 28 > m_comment
Any user comments.
std::string m_artist
Track artist.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
std::string m_album
Album title.
std::string m_title
Track title.
int64_t m_start
Track start time, in AV_TIME_BASE fractional seconds.
int m_trackno
Track number.
int m_tracktotal
Total number of tracks in cue sheet.
std::string m_genre
Album genre.
std::string m_date
Publishing date.
std::string m_destfile
Name and path of destination file.
size_t m_predicted_size
Use this as the size instead of computing it over and over.
VIRTUALTYPE m_type
Type of this virtual file.
std::string m_origfile
Sanitised name and path of original file.
int m_flags
One of the VIRTUALFLAG_* flags.
int m_width
Video width - Filled in for the DVD/Blu-ray directory.
int m_height
Video height - Filled in for the DVD/Blu-ray directory.
std::string m_virtfile
Name and path of virtual file.
AVRational m_framerate
Video frame rate - Filled in for the DVD/Blu-ray directory.
struct stat m_st
stat structure with size etc.
struct VIRTUALFILE::CUESHEET_TRACK m_cuesheet_track
Cue sheet data for track.
uint32_t get_segment_count() const
Number of HLS segments in set.
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
WAVE "fact" header structure.
std::array< uint8_t, 4 > m_chunk_id
Chunk ID 4 0x66 0x61 0x63 0x74 (i.e. "fact")
Delete helper struct for std::shared_ptr<AVCodecContext>
WAVE file structures https://wavefilegem.com/how_wave_files_work.html.
struct WAV_LIST_HEADER WAV_LIST_HEADER
WAVE list header structure.
struct WAV_HEADER WAV_HEADER
WAVE header structure.
struct WAV_DATA_HEADER WAV_DATA_HEADER
WAVE data header structure.
struct WAV_FACT WAV_FACT
WAVE "fact" header structure.
struct WAV_HEADER_EX WAV_HEADER_EX
WAVE extended header structure.