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
68#define FRAME_SEEK_THRESHOLD 25
73 { 720, 486, { { 24,
false } }, { 10, 23, 34, 50, 75, 113 } },
74 { 720, 486, { { 60,
true }, { 30,
false } }, { 12, 29, 42, 63, 94, 141 } },
76 { 720, 576, { { 50,
true }, { 25,
false } }, { 12, 28, 41, 61, 92, 138 } },
78 { 960, 720, { { 24,
false } }, { 15, 35, 50, 75, 113, 170 } },
79 { 960, 720, { { 25,
false } }, { 16, 36, 52, 79, 118, 177 } },
80 { 960, 720, { { 30,
false } }, { 19, 44, 63, 94, 141, 212 } },
81 { 960, 720, { { 50,
false } }, { 32, 73, 105, 157, 236, 354 } },
82 { 960, 720, { { 60,
false } }, { 38, 87, 126, 189, 283, 424 } },
84 { 1280, 720, { { 24,
false } }, { 18, 41, 59, 88, 132, 198 } },
85 { 1280, 720, { { 25,
false } }, { 19, 42, 61, 92, 138, 206 } },
86 { 1280, 720, { { 30,
false } }, { 23, 51, 73, 110, 165, 247 } },
87 { 1280, 720, { { 50,
false } }, { 38, 84, 122, 184, 275, 413 } },
88 { 1280, 720, { { 60,
false } }, { 45, 101, 147, 220, 330, 495 } },
90 { 1280, 1080, { { 24,
false } }, { 31, 70, 101, 151, 226, 339 } },
91 { 1280, 1080, { { 60,
true }, { 30,
false } }, { 38, 87, 126, 189, 283, 424 } },
93 { 1440, 1080, { { 24,
false } }, { 31, 70, 101, 151, 226, 339 } },
94 { 1440, 1080, { { 50,
true }, { 25,
false } }, { 32, 73, 105, 157, 236, 354 } },
95 { 1440, 1080, { { 60,
true }, { 30,
false } }, { 38, 87, 126, 189, 283, 424 } },
97 { 1920, 1080, { { 24,
false } }, { 36, 82, 117, 176, 264, 396 } },
98 { 1920, 1080, { { 50,
true }, { 25,
false } }, { 38, 85, 122, 184, 275, 413 } },
99 { 1920, 1080, { { 60,
true }, { 30,
false } }, { 45, 102, 147, 220, 330, 495 } },
100 { 1920, 1080, { { 50,
false } }, { 76, 170, 245, 367, 551, 826 } },
101 { 1920, 1080, { { 60,
false } }, { 91, 204, 293, 440, 660, 990 } },
103 { 2048, 1080, { { 24,
false } }, { 41, 93, 134, 201, 302, 453 } },
104 { 2048, 1080, { { 25,
false } }, { 43, 97, 140, 210, 315, 472 } },
105 { 2048, 1080, { { 30,
false } }, { 52, 116, 168, 251, 377, 566 } },
106 { 2048, 1080, { { 50,
false } }, { 86, 194, 280, 419, 629, 944 } },
107 { 2048, 1080, { { 60,
false } }, { 103, 232, 335, 503, 754, 1131 } },
109 { 2048, 1556, { { 24,
false } }, { 56, 126, 181, 272, 407, 611 } },
110 { 2048, 1556, { { 25,
false } }, { 58, 131, 189, 283, 425, 637 } },
111 { 2048, 1556, { { 30,
false } }, { 70, 157, 226, 340, 509, 764 } },
112 { 2048, 1556, { { 50,
false } }, { 117, 262, 377, 567, 850, 1275 } },
113 { 2048, 1556, { { 60,
false } }, { 140, 314, 452, 679, 1019, 1528 } },
115 { 3840, 2160, { { 24,
false } }, { 145, 328, 471, 707, 1061, 1591 } },
116 { 3840, 2160, { { 25,
false } }, { 151, 342, 492, 737, 1106, 1659 } },
117 { 3840, 2160, { { 30,
false } }, { 182, 410, 589, 884, 1326, 1989 } },
118 { 3840, 2160, { { 50,
false } }, { 303, 684, 983, 1475, 2212, 3318 } },
119 { 3840, 2160, { { 60,
false } }, { 363, 821, 1178, 1768, 2652, 3977 } },
121 { 4096, 2160, { { 24,
false } }, { 155, 350, 503, 754, 1131, 1697 } },
122 { 4096, 2160, { { 25,
false } }, { 162, 365, 524, 786, 1180, 1769 } },
123 { 4096, 2160, { { 30,
false } }, { 194, 437, 629, 943, 1414, 2121 } },
124 { 4096, 2160, { { 50,
false } }, { 323, 730, 1049, 1573, 2359, 3539 } },
125 { 4096, 2160, { { 60,
false } }, { 388, 875, 1257, 1886, 2828, 4242 } },
127 { 5120, 2700, { { 24,
false } }, { 243, 547, 786, 1178, 1768, 2652 } },
128 { 5120, 2700, { { 25,
false } }, { 253, 570, 819, 1229, 1843, 2765 } },
129 { 5120, 2700, { { 30,
false } }, { 304, 684, 982, 1473, 2210, 3314 } },
130 { 5120, 2700, { { 50,
false } }, { 507, 1140, 1638, 2458, 3686, 5530 } },
131 { 5120, 2700, { { 60,
false } }, { 608, 1367, 1964, 2946, 4419, 6629 } },
133 { 6144, 3240, { { 24,
false } }, { 350, 788, 1131, 1697, 2545, 3818 } },
134 { 6144, 3240, { { 25,
false } }, { 365, 821, 1180, 1769, 2654, 3981 } },
135 { 6144, 3240, { { 30,
false } }, { 437, 985, 1414, 2121, 3182, 4772 } },
136 { 6144, 3240, { { 50,
false } }, { 730, 1643, 2359, 3539, 5308, 7962 } },
137 { 6144, 3240, { { 60,
false } }, { 875, 1969, 2828, 4242, 6364, 9545 } },
139 { 8192, 4320, { { 24,
false } }, { 622, 1400, 2011, 3017, 4525, 6788 } },
140 { 8192, 4320, { { 25,
false } }, { 649, 1460, 2097, 3146, 4719, 7078 } },
141 { 8192, 4320, { { 30,
false } }, { 778, 1750, 2514, 3771, 5657, 8485 } },
142 { 8192, 4320, { { 50,
false } }, { 1298, 2920, 4194, 6291, 9437, 14156 } },
143 { 8192, 4320, { { 60,
false } }, { 1556, 3500, 5028, 7542, 11313, 16970 } }
148 { AV_HWDEVICE_TYPE_VAAPI, AV_PIX_FMT_NV12 },
150 { AV_HWDEVICE_TYPE_CUDA, AV_PIX_FMT_CUDA },
151 { AV_HWDEVICE_TYPE_VDPAU, AV_PIX_FMT_YUV420P },
152 { AV_HWDEVICE_TYPE_QSV, AV_PIX_FMT_QSV },
153 { AV_HWDEVICE_TYPE_OPENCL, AV_PIX_FMT_OPENCL },
154 #if HAVE_VULKAN_HWACCEL
155 { AV_HWDEVICE_TYPE_VULKAN, AV_PIX_FMT_VULKAN },
158 { AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX },
161 { AV_HWDEVICE_TYPE_MEDIACODEC, AV_PIX_FMT_MEDIACODEC },
164 { AV_HWDEVICE_TYPE_DRM, AV_PIX_FMT_DRM_PRIME },
165 { AV_HWDEVICE_TYPE_DXVA2, AV_PIX_FMT_DXVA2_VLD },
166 { AV_HWDEVICE_TYPE_D3D11VA, AV_PIX_FMT_D3D11VA_VLD },
171FFmpeg_Transcoder::StreamRef::StreamRef() :
172 m_codec_ctx(nullptr),
179FFmpeg_Transcoder::StreamRef::~StreamRef()
184template<
typename T >
191 void operator ()( T * p)
const
193 avcodec_free_context(&p);
199 if (codec_ctx !=
nullptr)
216#pragma GCC diagnostic push
217#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
229 ,
m_pts(AV_NOPTS_VALUE)
230 ,
m_pos(AV_NOPTS_VALUE)
252#pragma GCC diagnostic pop
253 Logging::trace(
nullptr,
"The FFmpeg trancoder is ready to initialise.");
257#if LAVU_DEP_OLD_CHANNEL_LAYOUT
272 Logging::trace(
nullptr,
"The FFmpeg transcoder object was destroyed.");
297 if (virtualfile ==
nullptr)
300 return AVERROR(EINVAL);
358 int orgerrno = errno;
360 return AVERROR(orgerrno);
377 if (iobuffer ==
nullptr)
381 return AVERROR(ENOMEM);
384 AVIOContext * pb = avio_alloc_context(
386 static_cast<int>(
m_fileio->bufsize()),
388 static_cast<void *
>(
m_fileio.get()),
397 return AVERROR(ENOMEM);
403 const AVInputFormat * infmt =
nullptr;
405 AVInputFormat * infmt =
nullptr;
412 infmt = av_find_input_format(
"mpeg");
419 infmt = av_find_input_format(
"mpeg");
426 infmt = av_find_input_format(
"mpegts");
462#if HAVE_AV_FORMAT_INJECT_GLOBAL_SIDE_DATA
539 return AVERROR(EINVAL);
592 AVCodecContext * codec_ctx =
nullptr;
594 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
605 std::string hw_encoder_codec_name;
622 Logging::info(
virtname(),
"Hardware encoder acceleration and frame buffering are active using codec '%1'.", hw_encoder_codec_name.c_str());
629 else if (!hw_encoder_codec_name.empty())
632 Logging::info(
virtname(),
"Hardware encoder acceleration is active using codec '%1'.", hw_encoder_codec_name.c_str());
656#if !LAVC_DEP_FLAG_TRUNCATED
657#ifdef AV_CODEC_CAP_TRUNCATED
663#warning "Your FFMPEG distribution is missing AV_CODEC_CAP_TRUNCATED flag. Probably requires fixing!"
676 AVCodecContext * codec_ctx =
nullptr;
678 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
713 for (
int stream_idx = 0; stream_idx < static_cast<int>(
m_in.
m_format_ctx->nb_streams); stream_idx++)
717 if (avcodec_get_type(stream->codecpar->codec_id) != AVMEDIA_TYPE_SUBTITLE)
728 AVCodecContext * codec_ctx =
nullptr;
738 codec_ctx->pkt_timebase = codec_ctx->time_base = stream->time_base;
759 for (
int stream_idx = 0; stream_idx < static_cast<int>(
m_in.
m_format_ctx->nb_streams); stream_idx++)
763 if (
is_album_art(input_stream->codecpar->codec_id, &input_stream->r_frame_rate))
766 AVCodecContext * input_codec_ctx;
797 if (stream ==
nullptr)
803 AVMediaType codec_type = stream->codecpar->codec_type;
804 AVCodecID codec_in = stream->codecpar->codec_id;
805 std::string codec_type_str;
808 if (codec_type == AVMEDIA_TYPE_VIDEO)
810 codec_type_str =
"video";
814 else if (codec_type == AVMEDIA_TYPE_AUDIO)
816 codec_type_str =
"audio";
829 const AVOutputFormat* oformat = av_guess_format(
nullptr,
virtname(),
nullptr);
830 if (oformat->codec_tag ==
nullptr || av_codec_get_tag(oformat->codec_tag, stream->codecpar->codec_id) <= 0)
839 Logging::debug(
virtname(),
"Check autocopy strict: %1: %2 -> %3", codec_type_str.c_str(), avcodec_get_name(codec_in), avcodec_get_name(codec_out));
840 if (codec_in != codec_out)
849 BITRATE orig_bit_rate = (stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate :
m_in.
m_format_ctx->bit_rate;
863 if (buffer ==
nullptr)
865 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::open_output_file()! buffer == nullptr in open_output_file()");
866 return AVERROR(EINVAL);
875 Logging::error(
virtname(),
"Unable to transcode. The source contains no audio stream, but the target just supports audio.");
877 return AVERROR(ENOENT);
897 const AVCodec *input_codec =
nullptr;
899 AVCodec *input_codec =
nullptr;
903 *codec_ctx =
nullptr;
909 if (ret != AVERROR_STREAM_NOT_FOUND)
918 return open_decoder(format_ctx, codec_ctx, *stream_idx, input_codec, type);
927 AVPixelFormat hw_pix_fmt = AV_PIX_FMT_NONE;
929 if (codec !=
nullptr && dev_type != AV_HWDEVICE_TYPE_NONE)
931 int method = use_device_ctx ? AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX : AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX;
933 for (
int i = 0;; i++)
935 const AVCodecHWConfig *config = avcodec_get_hw_config(codec, i);
938 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));
942 if ((config->methods & method) && (config->device_type == dev_type))
944 hw_pix_fmt = config->pix_fmt;
945 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));
957int FFmpeg_Transcoder::open_decoder(AVFormatContext *format_ctx, AVCodecContext **codec_ctx,
int stream_idx, AVCodec *input_codec, AVMediaType mediatype)
962 AVCodecContext *input_codec_ctx =
nullptr;
963 AVStream * input_stream =
nullptr;
965 AVCodecID codec_id = AV_CODEC_ID_NONE;
968 input_stream = format_ctx->streams[stream_idx];
974 input_codec_ctx = avcodec_alloc_context3(
nullptr);
975 if (input_codec_ctx ==
nullptr)
977 Logging::error(filename(),
"Decoding context could not be allocated.");
978 return AVERROR(ENOMEM);
982 ret = avcodec_parameters_to_context(input_codec_ctx, input_stream->codecpar);
988 codec_id = input_stream->codecpar->codec_id;
992 if (mediatype == AVMEDIA_TYPE_VIDEO)
996 const char *profile = ::avcodec_profile_name(codec_id, input_stream->codecpar->profile);
997 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");
998 m_hwaccel_dec_mode = HWACCELMODE::FALLBACK;
1002 if (mediatype == AVMEDIA_TYPE_VIDEO && m_hwaccel_dec_mode != HWACCELMODE::FALLBACK)
1006 std::string hw_decoder_codec_name;
1007 if (!get_hw_decoder_name(input_codec_ctx->codec_id, &hw_decoder_codec_name))
1019 if (m_hwaccel_enable_dec_buffering)
1030 Logging::info(filename(),
"Hardware decoder acceleration and frame buffering are active using codec '%1'.", (input_codec !=
nullptr) ? input_codec->name :
"unknown");
1032 m_hwaccel_dec_mode = HWACCELMODE::ENABLED;
1039 else if (!hw_decoder_codec_name.empty())
1043 input_codec = avcodec_find_decoder_by_name(hw_decoder_codec_name.c_str());
1045 if (input_codec ==
nullptr)
1047 Logging::error(filename(),
"Decoder '%1' could not be found.", hw_decoder_codec_name.c_str());
1048 return AVERROR(EINVAL);
1051 Logging::info(filename(),
"Hardware decoder acceleration is active using codec '%1'.", input_codec->name);
1053 m_hwaccel_dec_mode = HWACCELMODE::ENABLED;
1056 if (m_hwaccel_enable_dec_buffering)
1058 ret = hwdevice_ctx_add_ref(input_codec_ctx);
1067 if (input_codec ==
nullptr)
1070 input_codec = avcodec_find_decoder(codec_id);
1072 if (input_codec ==
nullptr)
1075 return AVERROR(EINVAL);
1079 input_codec_ctx->codec_id = input_codec->id;
1083 ret = avcodec_open2(input_codec_ctx, input_codec, opt.
address());
1087 if (m_hwaccel_dec_mode == HWACCELMODE::ENABLED)
1089 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));
1091 m_hwaccel_dec_mode = HWACCELMODE::FALLBACK;
1092 m_hwaccel_enable_dec_buffering =
false;
1093 m_dec_hw_pix_fmt = AV_PIX_FMT_NONE;
1096 hwdevice_ctx_free(&m_hwaccel_dec_device_ctx);
1098 m_in.m_video.reset();
1110 *codec_ctx = input_codec_ctx;
1118 const AVCodec * output_codec =
nullptr;
1119 AVCodecContext *output_codec_ctx =
nullptr;
1134 if (output_codec ==
nullptr)
1137 return AVERROR(EINVAL);
1140 output_codec_ctx = avcodec_alloc_context3(output_codec);
1141 if (output_codec_ctx ==
nullptr)
1144 return AVERROR(ENOMEM);
1147 output_codec_ctx->bit_rate = 400000;
1150 output_codec_ctx->time_base = {1, 25};
1155#if LAVC_USE_SUPPORTED_CFG
1157 const enum AVPixelFormat *pix_list =
nullptr;
1159 int ret_cfg = avcodec_get_supported_config(output_codec_ctx, output_codec,
1160 AV_CODEC_CONFIG_PIX_FORMAT,
1161 0, (
const void**)&pix_list, &npix);
1162 if (ret_cfg >= 0 && pix_list && npix > 0)
1164 output_codec_ctx->pix_fmt = avcodec_find_best_pix_fmt_of_list(pix_list,
m_in.
m_video.
m_codec_ctx->pix_fmt, (dst_desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 1 : 0, &loss);
1172 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);
1175 if (output_codec_ctx->pix_fmt == AV_PIX_FMT_NONE)
1180 case AV_CODEC_ID_MJPEG:
1182 output_codec_ctx->pix_fmt = AV_PIX_FMT_YUVJ444P;
1185 case AV_CODEC_ID_PNG:
1187 output_codec_ctx->pix_fmt = AV_PIX_FMT_RGB24;
1190 case AV_CODEC_ID_BMP:
1192 output_codec_ctx->pix_fmt = AV_PIX_FMT_BGR24;
1210 case AV_CODEC_ID_MJPEG:
1216 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
1219 case AV_CODEC_ID_PNG:
1221 output_codec_ctx->pix_fmt = AV_PIX_FMT_RGB24;
1224 case AV_CODEC_ID_BMP:
1226 output_codec_ctx->pix_fmt = AV_PIX_FMT_BGR24;
1238 ret = avcodec_open2(output_codec_ctx, output_codec, opt.
address());
1278 return AVERROR(EPERM);
1295 if (!hls_segment_preselected)
1304 uint32_t initial_seek_segment = 0;
1314 initial_seek_segment = segment_no;
1320 if (initial_seek_segment)
1376 return AVERROR(EINVAL);
1380 if (!segment_buffsize)
1382 segment_buffsize =
static_cast<size_t>(sysconf(_SC_PAGESIZE));
1387 return AVERROR(errno);
1453 return AVERROR(EPERM);
1502 if (out_streamref !=
nullptr)
1504 value.m_start_time = value.m_stream->start_time;
1540 if (input_sample_rate > max_sample_rate)
1542 if (output_sample_rate !=
nullptr)
1544 *output_sample_rate = max_sample_rate;
1550 if (output_sample_rate !=
nullptr)
1552 *output_sample_rate = input_sample_rate;
1560 if (!input_bit_rate || input_bit_rate > max_bit_rate)
1562 if (output_bit_rate !=
nullptr)
1564 *output_bit_rate = max_bit_rate;
1570 if (output_bit_rate !=
nullptr)
1572 *output_bit_rate = input_bit_rate;
1583 ::av_reduce(&dar.num, &dar.den,
1584 static_cast<int64_t
>(width) * sar.num,
1585 static_cast<int64_t
>(height) * sar.den,
1588 ar->num = ar->den = 0;
1590 if (dar.num && dar.den)
1596 if (!ar->den && sar.num != 0 && sar.den != 0)
1602 if (!ar->den && height)
1614 ::av_reduce(&ar->num, &ar->den,
1649 *output_height = input_height;
1654 *output_height &= ~(
static_cast<int>(0x1));
1664 *output_width = input_width;
1669 *output_width &= ~(
static_cast<int>(0x1));
1674 return (input_width > *output_width || input_height > *output_height);
1688 Logging::trace(
virtname(),
"Profile codec option -%1%2%3.", profile_option.m_key, *profile_option.m_value ?
" " :
"", profile_option.m_value);
1705 if (profile.m_filetype == filetype)
1707 ret = AVERROR_OPTION_NOT_FOUND;
1721 if (in_pix_fmt != out_pix_fmt || in_width != out_width || in_height != out_height)
1724 if (in_pix_fmt != out_pix_fmt)
1729 if (in_width != out_width || in_height != out_height)
1732 in_width, in_height,
1733 out_width, out_height);
1745 SWS_FAST_BILINEAR,
nullptr,
nullptr,
nullptr));
1749 return AVERROR(ENOMEM);
1758 AVCodecContext *output_codec_ctx =
nullptr;
1759 AVStream * output_stream =
nullptr;
1760#if IF_DECLARED_CONST
1761 const AVCodec * output_codec =
nullptr;
1763 AVCodec * output_codec =
nullptr;
1768 std::string codec_name;
1773 output_codec = avcodec_find_encoder(codec_id);
1775 if (output_codec ==
nullptr)
1778 return AVERROR(EINVAL);
1783 output_codec = avcodec_find_encoder_by_name(codec_name.c_str());
1785 if (output_codec ==
nullptr)
1788 return AVERROR(EINVAL);
1797 if (output_stream ==
nullptr)
1800 return AVERROR(ENOMEM);
1804 output_codec_ctx = avcodec_alloc_context3(output_codec);
1805 if (output_codec_ctx ==
nullptr)
1808 return AVERROR(ENOMEM);
1811 switch (output_codec->type)
1813 case AVMEDIA_TYPE_AUDIO:
1816 int orig_sample_rate;
1840#if LAVU_DEP_OLD_CHANNEL_LAYOUT
1841 av_channel_layout_default(&output_codec_ctx->ch_layout, output_codec_ctx->ch_layout.nb_channels);
1843 output_codec_ctx->channel_layout =
static_cast<uint64_t
>(av_get_default_channel_layout(output_codec_ctx->channels));
1854 orig_sample_rate = output_codec_ctx->sample_rate;
1857#if LAVC_USE_SUPPORTED_CFG
1859 const int *supported_samplerates =
nullptr;
1860 int num_samplerates = 0;
1861 int ret_cfg = avcodec_get_supported_config(output_codec_ctx, output_codec,
1862 AV_CODEC_CONFIG_SAMPLE_RATE,
1863 0, (
const void**)&supported_samplerates,
1865 if (ret_cfg >= 0 && supported_samplerates && num_samplerates > 0)
1867 bool exact_match =
false;
1868 for (
int n = 0; n < num_samplerates; n++)
1870 if (supported_samplerates[n] == output_codec_ctx->sample_rate)
1878 int min_samplerate = 0, max_samplerate = INT_MAX;
1879 for (
int n = 0; n < num_samplerates; n++)
1881 int s = supported_samplerates[n];
1882 if (min_samplerate <= s && output_codec_ctx->sample_rate >= s)
1886 for (
int n = 0; n < num_samplerates; n++)
1888 int s = supported_samplerates[n];
1889 if (max_samplerate >= s && output_codec_ctx->sample_rate <= s)
1893 if (min_samplerate != 0 && max_samplerate != INT_MAX)
1895 if (output_codec_ctx->sample_rate - min_samplerate < max_samplerate - output_codec_ctx->sample_rate)
1896 output_codec_ctx->sample_rate = min_samplerate;
1898 output_codec_ctx->sample_rate = max_samplerate;
1900 else if (min_samplerate != 0)
1902 output_codec_ctx->sample_rate = min_samplerate;
1904 else if (max_samplerate != INT_MAX)
1906 output_codec_ctx->sample_rate = max_samplerate;
1910 for (
int n = 0; n < num_samplerates; n++)
1911 if (supported_samplerates[n] == 48000)
1913 output_codec_ctx->sample_rate = 48000;
1917 if (output_codec_ctx->sample_rate <= 0)
1918 output_codec_ctx->sample_rate = supported_samplerates[0];
1924 if (output_codec->supported_samplerates !=
nullptr)
1927 bool supported =
false;
1929 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1931 if (output_codec->supported_samplerates[n] == output_codec_ctx->sample_rate)
1941 int min_samplerate = 0;
1942 int max_samplerate = INT_MAX;
1945 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1947 if (min_samplerate <= output_codec->supported_samplerates[n] && output_codec_ctx->sample_rate >= output_codec->supported_samplerates[n])
1949 min_samplerate = output_codec->supported_samplerates[n];
1954 for (
int n = 0; output_codec->supported_samplerates[n] != 0; n++)
1956 if (max_samplerate >= output_codec->supported_samplerates[n] && output_codec_ctx->sample_rate <= output_codec->supported_samplerates[n])
1958 max_samplerate = output_codec->supported_samplerates[n];
1962 if (min_samplerate != 0 && max_samplerate != INT_MAX)
1965 if (output_codec_ctx->sample_rate - min_samplerate < max_samplerate - output_codec_ctx->sample_rate)
1967 output_codec_ctx->sample_rate = min_samplerate;
1971 output_codec_ctx->sample_rate = max_samplerate;
1974 else if (min_samplerate != 0)
1977 output_codec_ctx->sample_rate = min_samplerate;
1979 else if (max_samplerate != INT_MAX)
1982 output_codec_ctx->sample_rate = max_samplerate;
1988 return AVERROR(EINVAL);
1991 Logging::debug(
virtname(),
"Because the requested value is not supported by codec, the audio sample rate was changed from %1 to %2.",
2000#if LAVC_USE_SUPPORTED_CFG
2003 const enum AVSampleFormat *sample_fmts =
nullptr;
2005 int ret_cfg = avcodec_get_supported_config(output_codec_ctx, output_codec,
2006 AV_CODEC_CONFIG_SAMPLE_FORMAT,
2007 0, (
const void**)&sample_fmts,
2009 if (ret_cfg >= 0 && sample_fmts && num_fmts > 0)
2011 AVSampleFormat input_fmt_planar = av_get_planar_sample_fmt(in_sample_format);
2012 for (
int i = 0; i < num_fmts; i++)
2014 AVSampleFormat output_fmt_planar = av_get_planar_sample_fmt(sample_fmts[i]);
2015 if (sample_fmts[i] == in_sample_format ||
2016 (input_fmt_planar != AV_SAMPLE_FMT_NONE && input_fmt_planar == output_fmt_planar))
2018 output_codec_ctx->sample_fmt = sample_fmts[i];
2022 if (output_codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE)
2025 output_codec_ctx->sample_fmt = sample_fmts[0];
2031 output_codec_ctx->sample_fmt = in_sample_format;
2035 if (output_codec->sample_fmts !=
nullptr)
2038 AVSampleFormat input_fmt_planar = av_get_planar_sample_fmt(in_sample_format);
2040 output_codec_ctx->sample_fmt = AV_SAMPLE_FMT_NONE;
2042 for (
const AVSampleFormat *sample_fmt = output_codec->sample_fmts; *sample_fmt != -1; sample_fmt++)
2044 AVSampleFormat output_fmt_planar = av_get_planar_sample_fmt(*sample_fmt);
2046 if (*sample_fmt == in_sample_format ||
2047 (input_fmt_planar != AV_SAMPLE_FMT_NONE &&
2048 input_fmt_planar == output_fmt_planar))
2050 output_codec_ctx->sample_fmt = *sample_fmt;
2056 if (output_codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE)
2058 output_codec_ctx->sample_fmt = output_codec->sample_fmts[0];
2064 output_codec_ctx->sample_fmt = in_sample_format;
2068 output_stream->time_base.den = output_codec_ctx->sample_rate;
2069 output_stream->time_base.num = 1;
2070 output_codec_ctx->time_base = output_stream->time_base;
2076 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
2101 case AVMEDIA_TYPE_VIDEO:
2118 output_codec_ctx->codec_id = codec_id;
2140 Logging::trace(
virtname(),
"Changing video size from %1/%2 to %3/%4.", output_codec_ctx->width, output_codec_ctx->height, width, height);
2141 output_codec_ctx->width = width;
2142 output_codec_ctx->height = height;
2155 output_codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
2160 if (output_codec_ctx->codec_id != AV_CODEC_ID_VP9 &&
m_out.
m_filetype != FILETYPE::MKV)
2162 output_codec_ctx->sample_aspect_ratio = sample_aspect_ratio;
2163 output_stream->codecpar->sample_aspect_ratio = sample_aspect_ratio;
2175 output_codec_ctx->sample_aspect_ratio = { 1, 1 };
2176 output_stream->codecpar->sample_aspect_ratio = { 1, 1 };
2179 if (sample_aspect_ratio.num && sample_aspect_ratio.den)
2181 output_codec_ctx->width = output_codec_ctx->width * sample_aspect_ratio.num / sample_aspect_ratio.den;
2187 switch (output_codec_ctx->codec_id)
2189 case AV_CODEC_ID_H264:
2206 output_codec_ctx->global_quality = 40;
2228 ret = av_opt_set(output_codec_ctx->priv_data,
"rc_mode",
"CQP", AV_OPT_SEARCH_CHILDREN);
2240 ret = av_opt_set(output_codec_ctx->priv_data,
"qp",
"30", AV_OPT_SEARCH_CHILDREN);
2259 ret = av_opt_set(output_codec_ctx->priv_data,
"qp",
"30", AV_OPT_SEARCH_CHILDREN);
2271 ret = av_opt_set(output_codec_ctx->priv_data,
"crf",
"30", AV_OPT_SEARCH_CHILDREN);
2283 ret = av_opt_get(output_codec_ctx->priv_data,
"profile", 0, &out_val);
2286 if (!
strcasecmp(
reinterpret_cast<const char *
>(out_val),
"high"))
2288 switch (output_codec_ctx->pix_fmt)
2290 case AV_PIX_FMT_YUV420P9BE:
2291 case AV_PIX_FMT_YUV420P9LE:
2292 case AV_PIX_FMT_YUV420P10BE:
2293 case AV_PIX_FMT_YUV420P10LE:
2295 ret = av_opt_set(output_codec_ctx->priv_data,
"profile",
"high10", 0);
2303 case AV_PIX_FMT_YUYV422:
2304 case AV_PIX_FMT_YUV422P:
2305 case AV_PIX_FMT_YUVJ422P:
2306 case AV_PIX_FMT_UYVY422:
2307 case AV_PIX_FMT_YUV422P16LE:
2308 case AV_PIX_FMT_YUV422P16BE:
2309 case AV_PIX_FMT_YUV422P10BE:
2310 case AV_PIX_FMT_YUV422P10LE:
2311 case AV_PIX_FMT_YUV422P9BE:
2312 case AV_PIX_FMT_YUV422P9LE:
2313 case AV_PIX_FMT_YUVA422P9BE:
2314 case AV_PIX_FMT_YUVA422P9LE:
2315 case AV_PIX_FMT_YUVA422P10BE:
2316 case AV_PIX_FMT_YUVA422P10LE:
2317 case AV_PIX_FMT_YUVA422P16BE:
2318 case AV_PIX_FMT_YUVA422P16LE:
2319 case AV_PIX_FMT_NV16:
2320 case AV_PIX_FMT_NV20LE:
2321 case AV_PIX_FMT_NV20BE:
2322 case AV_PIX_FMT_YVYU422:
2323 case AV_PIX_FMT_YUVA422P:
2324 case AV_PIX_FMT_YUV422P12BE:
2325 case AV_PIX_FMT_YUV422P12LE:
2326 case AV_PIX_FMT_YUV422P14BE:
2327 case AV_PIX_FMT_YUV422P14LE:
2329 ret = av_opt_set(output_codec_ctx->priv_data,
"profile",
"high422", 0);
2337 case AV_PIX_FMT_YUV444P:
2338 case AV_PIX_FMT_YUVJ444P:
2339 case AV_PIX_FMT_YUV444P16LE:
2340 case AV_PIX_FMT_YUV444P16BE:
2341 case AV_PIX_FMT_RGB444LE:
2342 case AV_PIX_FMT_RGB444BE:
2343 case AV_PIX_FMT_BGR444LE:
2344 case AV_PIX_FMT_BGR444BE:
2345 case AV_PIX_FMT_YUV444P9BE:
2346 case AV_PIX_FMT_YUV444P9LE:
2347 case AV_PIX_FMT_YUV444P10BE:
2348 case AV_PIX_FMT_YUV444P10LE:
2349 case AV_PIX_FMT_GBRP:
2350 case AV_PIX_FMT_GBRP9BE:
2351 case AV_PIX_FMT_GBRP9LE:
2352 case AV_PIX_FMT_GBRP10BE:
2353 case AV_PIX_FMT_GBRP10LE:
2354 case AV_PIX_FMT_GBRP16BE:
2355 case AV_PIX_FMT_GBRP16LE:
2356 case AV_PIX_FMT_YUVA444P9BE:
2357 case AV_PIX_FMT_YUVA444P9LE:
2358 case AV_PIX_FMT_YUVA444P10BE:
2359 case AV_PIX_FMT_YUVA444P10LE:
2360 case AV_PIX_FMT_YUVA444P16BE:
2361 case AV_PIX_FMT_YUVA444P16LE:
2362 case AV_PIX_FMT_XYZ12LE:
2363 case AV_PIX_FMT_XYZ12BE:
2364 case AV_PIX_FMT_YUVA444P:
2365 case AV_PIX_FMT_GBRAP:
2366 case AV_PIX_FMT_GBRAP16BE:
2367 case AV_PIX_FMT_GBRAP16LE:
2368 case AV_PIX_FMT_YUV444P12BE:
2369 case AV_PIX_FMT_YUV444P12LE:
2370 case AV_PIX_FMT_YUV444P14BE:
2371 case AV_PIX_FMT_YUV444P14LE:
2372 case AV_PIX_FMT_GBRP12BE:
2373 case AV_PIX_FMT_GBRP12LE:
2374 case AV_PIX_FMT_GBRP14BE:
2375 case AV_PIX_FMT_GBRP14LE:
2376 case AV_PIX_FMT_AYUV64LE:
2377 case AV_PIX_FMT_AYUV64BE:
2379 ret = av_opt_set(output_codec_ctx->priv_data,
"profile",
"high444", 0);
2397 case AV_CODEC_ID_VP9:
2399 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::WEBM);
2407 case AV_CODEC_ID_PRORES:
2409 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::PRORES);
2420 output_codec_ctx->profile =
static_cast<int>(
params.
m_level);
2423 case AV_CODEC_ID_ALAC:
2425 ret =
prepare_codec(output_codec_ctx->priv_data, FILETYPE::ALAC);
2452 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
2502 if (!av_dict_get(opt,
"threads",
nullptr, 0))
2509 ret = avcodec_open2(output_codec_ctx, output_codec, opt.
address());
2518 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2525 return (output_stream->index);
2530 AVCodecContext *output_codec_ctx =
nullptr;
2531 AVStream * output_stream =
nullptr;
2532#if IF_DECLARED_CONST
2533 const AVCodec * output_codec =
nullptr;
2535 AVCodec * output_codec =
nullptr;
2541 output_codec = avcodec_find_encoder(codec_id);
2543 if (output_codec ==
nullptr)
2546 return AVERROR(EINVAL);
2550 if (output_stream ==
nullptr)
2553 return AVERROR(ENOMEM);
2557 output_codec_ctx = avcodec_alloc_context3(output_codec);
2558 if (output_codec_ctx ==
nullptr)
2560 Logging::error(
virtname(),
"Could not allocate an encoding context for encoder '%1'.", avcodec_get_name(codec_id));
2561 return AVERROR(ENOMEM);
2564 output_stream->time_base = input_streamref.
m_stream->time_base;
2565 output_codec_ctx->time_base = output_stream->time_base;
2571 output_codec_ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
2587 AVCodecContext * input_codec_ctx = input_streamref.
m_codec_ctx.get();
2589 if (input_codec_ctx !=
nullptr && input_codec_ctx->subtitle_header !=
nullptr)
2592 output_codec_ctx->subtitle_header =
static_cast<uint8_t *
>(av_mallocz(
static_cast<size_t>(input_codec_ctx->subtitle_header_size) + 1));
2593 if (output_codec_ctx->subtitle_header ==
nullptr)
2595 return AVERROR(ENOMEM);
2597 std::memcpy(output_codec_ctx->subtitle_header, input_codec_ctx->subtitle_header,
static_cast<size_t>(input_codec_ctx->subtitle_header_size));
2598 output_codec_ctx->subtitle_header_size = input_codec_ctx->subtitle_header_size;
2600 else if (output_codec_ctx->codec_id == AV_CODEC_ID_WEBVTT || output_codec_ctx->codec_id == AV_CODEC_ID_SUBRIP)
2612 Logging::error(
virtname(),
"Could not create ASS script info for encoder '%1'.", avcodec_get_name(codec_id));
2618 ret = avcodec_open2(output_codec_ctx, output_codec, opt.
address());
2627 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2637 AVDictionaryEntry *tag =
nullptr;
2639 tag = av_dict_get(input_streamref.
m_stream->metadata,
"language",
nullptr, AV_DICT_IGNORE_SUFFIX);
2642 av_dict_set(&output_stream->metadata,
"language", tag->value, AV_DICT_IGNORE_SUFFIX);
2648 av_dict_set(&output_stream->metadata,
"language", language->c_str(), AV_DICT_IGNORE_SUFFIX);
2658 output_streamref.
m_stream = output_stream;
2670 AVStream * output_stream =
nullptr;
2674 if (output_stream ==
nullptr)
2677 return AVERROR(ENOMEM);
2683 case AVMEDIA_TYPE_AUDIO:
2709 case AVMEDIA_TYPE_VIDEO:
2742 output_stream->codecpar->codec_tag = 0;
2749 AVCodecContext * output_codec_ctx =
nullptr;
2750 AVStream * output_stream =
nullptr;
2751 const AVCodec * input_codec = input_codec_ctx->codec;
2752 const AVCodec * output_codec =
nullptr;
2757 output_codec = avcodec_find_encoder(input_codec->id);
2758 if (output_codec ==
nullptr)
2761 return AVERROR(EINVAL);
2765 if (output_codec->type != AVMEDIA_TYPE_VIDEO)
2767 Logging::error(
virtname(),
"INTERNAL TROUBLE! Encoder '%1' is not a video codec.", avcodec_get_name(input_codec->id));
2768 return AVERROR(EINVAL);
2772 if (output_stream ==
nullptr)
2774 Logging::error(
virtname(),
"Could not allocate stream for encoder '%1'.", avcodec_get_name(input_codec->id));
2775 return AVERROR(ENOMEM);
2779 output_codec_ctx = avcodec_alloc_context3(output_codec);
2780 if (output_codec_ctx ==
nullptr)
2783 return AVERROR(ENOMEM);
2787#if !IF_DECLARED_CONST
2806 output_stream->disposition = AV_DISPOSITION_ATTACHED_PIC;
2814 output_codec_ctx->time_base = { 1, 90000 };
2815 output_stream->time_base = { 1, 90000 };
2817 output_codec_ctx->pix_fmt = input_codec_ctx->pix_fmt;
2818 output_codec_ctx->width = input_codec_ctx->width;
2819 output_codec_ctx->height = input_codec_ctx->height;
2828 ret = avcodec_open2(output_codec_ctx, output_codec, opt.
address());
2835 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);
2837 ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx);
2847 streamref.
m_stream = output_stream;
2858 int ret = tmp_pkt.
res();
2868 tmp_pkt->stream_index = output_stream->index;
2869 tmp_pkt->flags |= AV_PKT_FLAG_KEY;
2904 return (ret < 0) ? ret : AVERROR(ENOMEM);
3020 const int buf_size = 5*1024*1024;
3022 if (iobuffer ==
nullptr)
3025 return AVERROR(ENOMEM);
3033 static_cast<void *
>(buffer),
3041 av_freep(&iobuffer);
3042 return AVERROR(ENOMEM);
3055 if (codec_id == AV_CODEC_ID_NONE)
3083#if LAVU_DEP_OLD_CHANNEL_LAYOUT
3101#if LAVU_DEP_OLD_CHANNEL_LAYOUT
3127#if LAVU_DEP_OLD_CHANNEL_LAYOUT
3149#if LAVU_DEP_OLD_CHANNEL_LAYOUT
3157#if SWR_DEP_ALLOC_SET_OPTS
3183 return AVERROR(ENOMEM);
3229 Logging::trace(
virtname(),
"Profile format option -%1%2%3.", option.m_key, *option.m_value ?
" " :
"", option.m_value);
3246 if (profile.m_filetype == filetype)
3248 ret = AVERROR_OPTION_NOT_FOUND;
3257 if (filetype == FILETYPE::MP4 || filetype == FILETYPE::PRORES || filetype == FILETYPE::TS || filetype == FILETYPE::HLS)
3270 AVIOContext * output_io_context =
static_cast<AVIOContext *
>(
m_out.
m_format_ctx->pb);
3271 Buffer *buffer =
static_cast<Buffer *
>(output_io_context->opaque);
3272 size_t current_offset = buffer->
tell();
3273 size_t read_offset = 0;
3278 buffer->
copy(
reinterpret_cast<uint8_t*
>(&wav_header), 0,
sizeof(
WAV_HEADER));
3290 buffer->
copy(
reinterpret_cast<uint8_t*
>(&wav_fact), read_offset,
sizeof(
WAV_FACT));
3298 buffer->
copy(
reinterpret_cast<uint8_t*
>(&list_header), read_offset,
sizeof(
WAV_LIST_HEADER));
3301 buffer->
copy(
reinterpret_cast<uint8_t*
>(&data_header), read_offset,
sizeof(
WAV_DATA_HEADER));
3306#if __BYTE_ORDER == __BIG_ENDIAN
3312 buffer->
seek(0, SEEK_SET);
3316 buffer->
seek(
static_cast<long>(read_offset), SEEK_SET);
3320 buffer->
seek(
static_cast<long>(current_offset), SEEK_SET);
3328 size_t buffsize = *size;
3332 if (!buffer->
copy(chunk, *buffoffset, buffsize))
3350#if __BYTE_ORDER == __BIG_ENDIAN
3353 *size = __builtin_bswap32(p->
m_ckSize) + 8;
3364 *buffoffset += *size;
3373 AVIOContext * output_io_context =
static_cast<AVIOContext *
>(
m_out.
m_format_ctx->pb);
3374 Buffer *buffer =
static_cast<Buffer *
>(output_io_context->opaque);
3375 size_t current_offset = buffer->
tell();
3376 size_t read_offset = 0;
3381 size =
sizeof(form_chunk);
3387 read_offset += size;
3390#if __BYTE_ORDER != __BIG_ENDIAN
3394 size =
sizeof(common_chunk);
3400 read_offset += size;
3404 size =
sizeof(sounddata_chunk);
3411#if __BYTE_ORDER != __BIG_ENDIAN
3416 buffer->
seek(0, SEEK_SET);
3417 buffer->
writeio(
reinterpret_cast<uint8_t*
>(&form_chunk),
sizeof(form_chunk));
3420 buffer->
seek(
static_cast<long>(read_offset), SEEK_SET);
3421 buffer->
writeio(
reinterpret_cast<uint8_t*
>(&sounddata_chunk),
sizeof(sounddata_chunk));
3424 buffer->
seek(
static_cast<long>(current_offset), SEEK_SET);
3454 case FILETYPE::AIFF:
3472 frame->format = pix_fmt;
3473 frame->width = width;
3474 frame->height = height;
3477 ret = av_frame_get_buffer(frame, 32);
3495 ret = avcodec_send_packet(codec_ctx, pkt);
3496 if (ret < 0 && ret != AVERROR_EOF)
3501 if (ret == AVERROR(EAGAIN))
3503 ret = AVERROR_EXTERNAL;
3523 ret = avcodec_receive_frame(codec_ctx, frame);
3524 if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
3536 *got_frame = (ret >= 0) ? 1 : 0;
3543 int data_present = 0;
3585 *decoded += pkt->size;
3588 if (frame->nb_samples)
3591 uint8_t **converted_input_samples =
nullptr;
3594 int nb_output_samples;
3615 ret =
convert_samples(frame->extended_data, frame->nb_samples, converted_input_samples, &nb_output_samples);
3634 if (converted_input_samples !=
nullptr)
3636 av_freep(&converted_input_samples[0]);
3637 av_free(converted_input_samples);
3699 ret = sw_frame.
res();
3710 ret = av_hwframe_transfer_data(sw_frame, frame, 0);
3720 *decoded += pkt->size;
3723 if (pkt->dts != AV_NOPTS_VALUE)
3725 int64_t pkt_dts = pkt->dts;
3726 if (pkt_dts >
m_pts)
3731 else if (pkt->pts != AV_NOPTS_VALUE)
3733 int64_t pkt_pts = pkt->pts;
3734 if (pkt_pts >
m_pts)
3745 if (frame !=
nullptr)
3747 if (!(frame->flags & AV_FRAME_FLAG_CORRUPT || frame->flags & AV_FRAME_FLAG_DISCARD))
3759 ret = tmp_frame.
res();
3775 static_cast<const uint8_t *
const *
>(frame->data), frame->linesize,
3777 tmp_frame->data, tmp_frame->linesize);
3779 tmp_frame->pts = frame->pts;
3780 tmp_frame->best_effort_timestamp = frame->best_effort_timestamp;
3785 int64_t best_effort_timestamp = frame->best_effort_timestamp;
3787 if (best_effort_timestamp != AV_NOPTS_VALUE)
3789 frame->pts = best_effort_timestamp;
3792 if (frame->pts == AV_NOPTS_VALUE)
3815#if !LAVU_ADD_NEW_FRAME_FLAGS
3816 frame->key_frame = 0;
3818 frame->pict_type = AV_PICTURE_TYPE_NONE;
3820 if (frame->pts != AV_NOPTS_VALUE)
3822 int64_t tmp_pts = frame->pts - video_start_time;
3838#if LAVU_ADD_NEW_FRAME_FLAGS
3839 frame->flags |= AV_FRAME_FLAG_KEY;
3841 frame->key_frame = 1;
3843 frame->pict_type = AV_PICTURE_TYPE_I;
3863 StreamRef_map::const_iterator it =
m_in.
m_subtitle.find(pkt->stream_index);
3870 int ret = AVERROR_STREAM_NOT_FOUND;
3886 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::decode_subtitle()! Unable to map input subtitle stream #%1 to output stream.", it->first);
3887 throw AVERROR(EINVAL);
3890 return decode_subtitle(it->second.m_codec_ctx.get(), pkt, decoded, out_stream_idx);
3896 int data_present = 0;
3901 ret = subtitle.
res();
3908 ret = avcodec_decode_subtitle2(codec_ctx, subtitle, &data_present, pkt);
3910 if (ret < 0 && ret != AVERROR(EINVAL))
3934 if (
is_hls() && pkt->pts != AV_NOPTS_VALUE)
3938 case AVMEDIA_TYPE_AUDIO:
3957 ret = fifo_pkt.
res();
3967 case AVMEDIA_TYPE_VIDEO:
3986 ret = fifo_pkt.
res();
3996 case AVMEDIA_TYPE_SUBTITLE:
4000 if (subtitle !=
nullptr && subtitle->
m_stream !=
nullptr)
4012 ret = fifo_pkt.
res();
4036 if (mediatype != AVMEDIA_TYPE_ATTACHMENT)
4038 type = av_get_media_type_string(mediatype);
4040 if (type ==
nullptr)
4058 if (pkt->pts != AV_NOPTS_VALUE)
4060 *cur_ts = pkt->pts + pkt->duration;
4062 else if (pkt->dts != AV_NOPTS_VALUE)
4069 if (pkt->pts == AV_NOPTS_VALUE)
4074 *cur_ts += pkt->duration;
4076 if (pkt->dts == AV_NOPTS_VALUE)
4163 if ((ret == AVERROR(EAGAIN) && ret == lastret) || ret == AVERROR_EOF)
4171 if (ret < 0 && ret != AVERROR(EAGAIN))
4179 pkt->data += decoded;
4180 pkt->size -= decoded;
4182 while (pkt->size > 0 && (ret == 0 || ret == AVERROR(EAGAIN)));
4213 switch (
m_in.
m_format_ctx->streams[pkt->stream_index]->codecpar->codec_type)
4215 case AVMEDIA_TYPE_VIDEO:
4222 if (pkt->stream_index == input_stream->index && !(input_stream->disposition & AV_DISPOSITION_ATTACHED_PIC))
4262 if (*converted_input_samples ==
nullptr)
4265 return AVERROR(ENOMEM);
4270 ret = av_samples_alloc(*converted_input_samples,
nullptr,
4277 av_freep(&(*converted_input_samples)[0]);
4278 av_free(*converted_input_samples);
4291 ret = swr_convert(
m_audio_resample_ctx, converted_data, *out_samples,
const_cast<const uint8_t **
>(input_data), in_samples);
4302 *out_samples = in_samples;
4309 std::memcpy(converted_data[0], input_data[0],
static_cast<size_t>(samples));
4317 std::memcpy(converted_data[n], input_data[n],
static_cast<size_t>(samples));
4339 ret =
m_audio_fifo.
write(
reinterpret_cast<void **
>(converted_input_samples), frame_size);
4340 if (ret < frame_size)
4350 return AVERROR_EXIT;
4387 int (
FFmpeg_Transcoder::*decode_frame_ptr)(AVPacket *pkt,
int *decoded) =
nullptr;
4398 if (decode_frame_ptr !=
nullptr)
4401 AVPacket *flush_packet_ptr =
nullptr;
4403 if (flush_packet.
res() < 0)
4405 return flush_packet.
res();
4408 if (use_flush_packet)
4410 flush_packet->data =
nullptr;
4411 flush_packet->size = 0;
4412 flush_packet->stream_index = stream_idx;
4413 flush_packet_ptr = flush_packet;
4417 for (
int decoded = 1; decoded;)
4419 ret = (this->*decode_frame_ptr)(flush_packet_ptr, &decoded);
4420 if (ret < 0 && ret != AVERROR(EAGAIN))
4435 int ret = pkt.
res();
4448 if (ret == AVERROR_EOF)
4484 if (ret < 0 && ret != AVERROR(EAGAIN))
4516 frame->nb_samples = frame_size;
4517#if LAVU_DEP_OLD_CHANNEL_LAYOUT
4534 ret = av_frame_get_buffer(frame, 0);
4546 if (pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
4550 int64_t pkt_duration;
4556 pkt_duration = pkt->duration;
4558#if !LAVC_DEP_TICKSPERFRAME
4592 int ret = pkt.
res();
4608 if (ret < 0 && ret != AVERROR_EOF)
4620 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4636 const bool packet_has_timestamps =
4637 pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE;
4651 if (packet_has_timestamps)
4653 av_packet_rescale_ts(pkt,
4692 return AVERROR(EINVAL);
4698 return AVERROR(EINVAL);
4702 int ret = pkt.
res();
4713 ret = cloned_frame.
res();
4732 if (ret < 0 && ret != AVERROR_EOF)
4744 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4760 if (pkt->pts != AV_NOPTS_VALUE)
4793 if (frame !=
nullptr)
4795#if LAVU_ADD_NEW_FRAME_FLAGS
4796 if (frame->flags & AV_FRAME_FLAG_INTERLACED)
4800 m_out.
m_video.
m_stream->codecpar->field_order = (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? AV_FIELD_TT : AV_FIELD_BB;
4804 m_out.
m_video.
m_stream->codecpar->field_order = (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? AV_FIELD_TB : AV_FIELD_BT;
4808 if (frame->interlaced_frame)
4812 m_out.
m_video.
m_stream->codecpar->field_order = frame->top_field_first ? AV_FIELD_TT : AV_FIELD_BB;
4816 m_out.
m_video.
m_stream->codecpar->field_order = frame->top_field_first ? AV_FIELD_TB : AV_FIELD_BT;
4827 int ret = pkt.
res();
4839 if (hw_frame ==
nullptr)
4841 ret = AVERROR(ENOMEM);
4846 ret = hw_frame->
res();
4869 if (ret < 0 && ret != AVERROR_EOF)
4881 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
4901 if (pkt->dts != AV_NOPTS_VALUE &&
4902 pkt->pts != AV_NOPTS_VALUE &&
4903 pkt->dts > pkt->pts &&
4923 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);
4925 if (pkt->pts >= pkt->dts)
4927 pkt->pts = FFMAX(pkt->pts, max);
4934 if (frame !=
nullptr && !pkt->duration)
4936#if !LAVU_DEP_PKT_DURATION
4937 pkt->duration = frame->pkt_duration;
4939 pkt->duration = frame->duration;
4943 if (pkt->pts != AV_NOPTS_VALUE)
4946 m_out.
m_last_mux_dts = (pkt->dts != AV_NOPTS_VALUE) ? pkt->dts : (pkt->pts - pkt->duration);
4977 if (out_streamref ==
nullptr)
4979 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::encode_subtitle()! Invalid stream index #%1.", out_stream_idx);
4980 return AVERROR(EINVAL);
4985 int ret = pkt.
res();
4995 std::memcpy(&subtmp, sub,
sizeof(AVSubtitle));
5002 if (subtmp.pts == AV_NOPTS_VALUE)
5005 throw AVERROR(EINVAL);
5009 ret = av_new_packet(pkt, 1024 * 1024);
5017 if (out_streamref->
m_codec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
5027 sub_pts = subtmp.pts;
5034 for (
int i = 0; i < nb; i++)
5036 unsigned save_num_rects = subtmp.num_rects;
5037 subtmp.pts = sub_pts;
5039 if (subtmp.end_display_time == UINT32_MAX)
5041 subtmp.end_display_time = 0;
5045 subtmp.pts +=
ffmpeg_rescale_q(subtmp.start_display_time, AVRational({ 1, 1000 }));
5046 subtmp.end_display_time -= subtmp.start_display_time;
5047 subtmp.start_display_time = 0;
5050 subtmp.num_rects = 0;
5054 ret = avcodec_encode_subtitle(out_streamref->
m_codec_ctx.get(), pkt->data, pkt->size, &subtmp);
5057 subtmp.num_rects = save_num_rects;
5068 pkt->duration =
ffmpeg_rescale_q(subtmp.end_display_time, AVRational({ 1, 1000 }), out_streamref->
m_stream->time_base);
5071 if (out_streamref->
m_codec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
5076 pkt->pts +=
ffmpeg_rescale_q(subtmp.end_display_time, AVRational({ 1, 1000 }), out_streamref->
m_stream->time_base);
5079 pkt->dts = pkt->pts;
5106 ret = output_frame.
res();
5129 ret =
m_audio_fifo.
read(
reinterpret_cast<void **
>(output_frame->data), frame_size);
5130 if (ret < frame_size)
5157 if (output_frame->sample_rate)
5169 int64_t sample_duration = av_rescale(AV_TIME_BASE, output_frame->nb_samples, output_frame->sample_rate);
5202template <
size_t size>
5205 std::memset(out,
' ', size);
5206 std::memcpy(out, in.c_str(), std::min(size, in.size()));
5214 std::memcpy(out.data(), in.c_str(), std::min(out.size(), in.size()));
5223 AVDictionaryEntry *tag =
nullptr;
5225 while ((tag = av_dict_get(metadata_in,
"", tag, AV_DICT_IGNORE_SUFFIX)) !=
nullptr)
5227 std::string value(tag->value);
5317 if (av_dict_get(
m_out.
m_format_ctx->metadata,
"ALBUM_ARTIST",
nullptr, 0) ==
nullptr)
5339 if (input_stream->disposition & AV_DISPOSITION_ATTACHED_PIC)
5390 uint32_t next_frame_no = frame_no;
5395 std::this_thread::yield();
5420 if (forced_seek || (frame_no != next_frame_no && next_frame_no > 1))
5441 int data_written = 0;
5446 if (ret == AVERROR_EOF)
5452 if (ret < 0 && ret != AVERROR(EAGAIN))
5458 while (data_written);
5471 int data_written = 0;
5485 if (ret == AVERROR_EOF)
5490 if (ret < 0 && ret != AVERROR(EAGAIN))
5496 while (data_written);
5509 int output_frame_size;
5514 output_frame_size = 10000;
5585 if (ret == AVERROR_EOF)
5639 delay = 6 * AV_TIME_BASE;
5650 MULTIFRAME_MAP::const_iterator it =
m_frame_map.cbegin();
5670 if (std::holds_alternative<FFmpeg_Frame>(multiframe))
5673 const FFmpeg_Frame & frame = std::get<FFmpeg_Frame>(multiframe);
5679 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::process_single_fr()! Invalid stream index in audio/video buffer skipped.");
5692 if (ret < 0 && ret != AVERROR(EAGAIN))
5701 int data_written = 0;
5704 if (ret < 0 && ret != AVERROR(EAGAIN))
5710 else if (std::holds_alternative<FFmpeg_Subtitle>(multiframe))
5713 const FFmpeg_Subtitle & subtitle = std::get<FFmpeg_Subtitle>(multiframe);
5719 Logging::error(
virtname(),
"INTERNAL ERROR: FFmpeg_Transcoder::process_single_fr()! Invalid stream index in subtitle buffer skipped.");
5726 int data_written = 0;
5730 if (ret < 0 && ret != AVERROR(EAGAIN))
5748 int data_written = 0;
5753 if (ret < 0 && ret != AVERROR(EAGAIN))
5826#ifdef PRESCAN_FRAMES
5827 if (seek_frame_no > PRESCAN_FRAMES)
5829 seek_frame_no -= PRESCAN_FRAMES;
5850 bool opened =
false;
5867 if (min_seek_segments && segment_no >= next_segment && segment_no <= next_segment + min_seek_segments)
5931 next_segment = segment_no;
5950 return AVERROR(errno);
5986 unsigned int mindist;
5987 size_t match = UINT_MAX;
5993 unsigned int x =
static_cast<unsigned int>(width -
m_prores_bitrate[i].m_width);
5994 unsigned int y =
static_cast<unsigned int>(height -
m_prores_bitrate[i].m_height);
5995 unsigned int dist = (x * x) + (y * y);
6010 if (match == UINT_MAX)
6019 double framerateX = av_q2d(framerate);
6023 unsigned int dist = UINT_MAX;
6026 unsigned int x =
static_cast<unsigned int>(framerateX -
m_prores_bitrate[i].m_framerate[j].m_framerate);
6027 unsigned int y =
static_cast<unsigned int>(interleaved -
m_prores_bitrate[i].m_framerate[j].m_interleaved);
6029 dist = (x * x) + (y * y);
6051 if (match == UINT_MAX)
6056 return m_prores_bitrate[match].m_bitrate[
static_cast<size_t>(profile)] * (1000 * 1000);
6061 BITRATE output_audio_bit_rate;
6062 int output_sample_rate;
6063 bool success =
true;
6070 case AV_CODEC_ID_AAC:
6073 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
6074 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
6077 case AV_CODEC_ID_MP3:
6088 case AV_CODEC_ID_PCM_U8:
6089 case AV_CODEC_ID_PCM_S8:
6091 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_U8);
6097 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6100 case AV_CODEC_ID_PCM_S8_PLANAR:
6102 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_U8P);
6108 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6111 case AV_CODEC_ID_PCM_U16LE:
6112 case AV_CODEC_ID_PCM_U16BE:
6113 case AV_CODEC_ID_PCM_S16LE:
6114 case AV_CODEC_ID_PCM_S16BE:
6116 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
6122 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6125 case AV_CODEC_ID_PCM_S16LE_PLANAR:
6126 case AV_CODEC_ID_PCM_S16BE_PLANAR:
6128 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P);
6134 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6137 case AV_CODEC_ID_PCM_U24LE:
6138 case AV_CODEC_ID_PCM_U24BE:
6139 case AV_CODEC_ID_PCM_S24LE:
6140 case AV_CODEC_ID_PCM_S24BE:
6141 case AV_CODEC_ID_PCM_U32LE:
6142 case AV_CODEC_ID_PCM_U32BE:
6143 case AV_CODEC_ID_PCM_S32LE:
6144 case AV_CODEC_ID_PCM_S32BE:
6146 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S32);
6152 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6155 case AV_CODEC_ID_PCM_S24LE_PLANAR:
6156 case AV_CODEC_ID_PCM_S32LE_PLANAR:
6158 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S32P);
6164 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6167 case AV_CODEC_ID_PCM_S64LE:
6168 case AV_CODEC_ID_PCM_S64BE:
6170 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S64);
6176 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6179 case AV_CODEC_ID_PCM_F16LE:
6180 case AV_CODEC_ID_PCM_F24LE:
6181 case AV_CODEC_ID_PCM_F32BE:
6182 case AV_CODEC_ID_PCM_F32LE:
6183 case AV_CODEC_ID_PCM_F64BE:
6184 case AV_CODEC_ID_PCM_F64LE:
6186 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_FLT);
6192 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6195 case AV_CODEC_ID_VORBIS:
6198 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
6199 *filesize =
static_cast<size_t>(900 * (*filesize) / 1000);
6202 case AV_CODEC_ID_OPUS:
6205 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
6206 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
6209 case AV_CODEC_ID_ALAC:
6211 int bytes_per_sample = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
6216 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6217 *filesize =
static_cast<size_t>(620 * (*filesize) / 1000);
6220 case AV_CODEC_ID_AC3:
6223 *filesize +=
static_cast<size_t>(
duration * output_audio_bit_rate / (8LL * AV_TIME_BASE));
6224 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
6227 case AV_CODEC_ID_FLAC:
6229 int bytes_per_sample = av_get_bytes_per_sample(sample_format != AV_SAMPLE_FMT_NONE ? sample_format : AV_SAMPLE_FMT_S16);
6234 *filesize +=
static_cast<size_t>(
duration * sample_rate * (channels >= 2 ? 2 : 1) * bytes_per_sample / AV_TIME_BASE);
6235 *filesize =
static_cast<size_t>(600 * (*filesize) / 1000);
6238 case AV_CODEC_ID_NONE:
6254 bool success =
true;
6260 case AV_CODEC_ID_MPEG1VIDEO:
6262 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6263 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
6266 case AV_CODEC_ID_MPEG2VIDEO:
6268 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6269 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
6272 case AV_CODEC_ID_H264:
6274 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6275 *filesize =
static_cast<size_t>(1050 * (*filesize) / 1000);
6278 case AV_CODEC_ID_H265:
6280 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6281 *filesize =
static_cast<size_t>(1250 * (*filesize) / 1000);
6284 case AV_CODEC_ID_THEORA:
6286 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6287 *filesize =
static_cast<size_t>(1025 * (*filesize) / 1000);
6290 case AV_CODEC_ID_VP8:
6292 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6293 *filesize =
static_cast<size_t>(1020 * (*filesize) / 1000);
6296 case AV_CODEC_ID_VP9:
6298 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6299 *filesize =
static_cast<size_t>(1450 * (*filesize) / 1000);
6302 case AV_CODEC_ID_AV1:
6304 *filesize +=
static_cast<size_t>(
duration * out_video_bit_rate / (8LL * AV_TIME_BASE));
6308 case AV_CODEC_ID_PRORES:
6313 case AV_CODEC_ID_PNG:
6314 case AV_CODEC_ID_BMP:
6315 case AV_CODEC_ID_MJPEG:
6319 *filesize +=
static_cast<size_t>(width * height * 24 / 8);
6322 case AV_CODEC_ID_NONE:
6337 bool success =
true;
6348 *filesize += 250000;
6359 case FILETYPE::AIFF:
6366 case FILETYPE::OPUS:
6367 case FILETYPE::ALAC:
6368 case FILETYPE::FLAC:
6378 *filesize += 1600000;
6383 case FILETYPE::WEBM:
6385 case FILETYPE::PRORES:
6402 case FILETYPE::UNKNOWN:
6425 size_t filesize = 0;
6428 BITRATE input_audio_bit_rate = 0;
6429 int input_sample_rate = 0;
6430 BITRATE input_video_bit_rate = 0;
6432 if (
m_fileio->duration() != AV_NOPTS_VALUE)
6434 file_duration =
m_fileio->duration();
6448 if (input_audio_bit_rate)
6458 if (input_video_bit_rate)
6524 if (virtualfile !=
nullptr)
6551 Logging::error(
nullptr,
"input_read(): Internal error: FileIO is NULL!");
6552 return AVERROR(EINVAL);
6561 int read =
static_cast<int>(io->
readio(
reinterpret_cast<char *
>(data),
static_cast<size_t>(size)));
6563 if (read != size && io->
error())
6566 return AVERROR(io->
error());
6572#if LAVF_WRITEPACKET_CONST
6580 if (buffer ==
nullptr)
6582 Logging::error(
nullptr,
"input_write(): Internal error: FileIO is NULL!");
6583 return AVERROR(EINVAL);
6586#if LAVF_WRITEPACKET_CONST
6587 int written =
static_cast<int>(buffer->
writeio(data,
static_cast<size_t>(size)));
6589 int written =
static_cast<int>(buffer->
writeio(
static_cast<const uint8_t*
>(data),
static_cast<size_t>(size)));
6591 if (written != size)
6594 return (AVERROR(errno));
6602 int64_t res_offset = 0;
6606 Logging::error(
nullptr,
"seek(): Internal error: FileIO is NULL!");
6607 return AVERROR(EINVAL);
6610 if (whence & AVSEEK_SIZE)
6613 res_offset =
static_cast<int64_t
>(io->
size());
6617 whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE);
6619 if (!io->
seek(offset, whence))
6622 res_offset = offset;
6627 res_offset = AVERROR(errno);
6641 int audio_samples_left = 0;
6649 return audio_samples_left;
6670 return hls_packets_left;
6675 std::string outfile;
6689 const char *p = outfile.empty() ? nullptr : outfile.c_str();
6690 if (audio_samples_left)
6692 Logging::warning(p,
"%1 audio samples left in buffer and not written to target file!", audio_samples_left);
6697 Logging::warning(p,
"%1 frames left in buffer and not written to target file!", frames_left);
6700 if (hls_packets_left)
6702 Logging::warning(p,
"%1 HLS packets left in buffer and not written to target file!", hls_packets_left);
6708 bool closed =
false;
6736 bool closed =
false;
6762 bool closed =
false;
6805 const AVFilter * buffer_src = avfilter_get_by_name(
"buffer");
6806 const AVFilter * buffer_sink = avfilter_get_by_name(
"buffersink");
6807 AVFilterInOut * outputs = avfilter_inout_alloc();
6808 AVFilterInOut * inputs = avfilter_inout_alloc();
6813 if (!avg_frame_rate.den && !avg_frame_rate.num)
6816 throw static_cast<int>(AVERROR(EINVAL));
6821 if (outputs ==
nullptr || inputs ==
nullptr ||
m_filter_graph ==
nullptr)
6823 throw static_cast<int>(AVERROR(ENOMEM));
6829 "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
6830 codec_ctx->width, codec_ctx->height, pix_fmt,
6831 time_base.num, time_base.den,
6832 codec_ctx->sample_aspect_ratio.num,
6833 FFMAX(codec_ctx->sample_aspect_ratio.den, 1));
6843#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(10, 6, 100) && LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(59, 36, 100)
6848 throw static_cast<int>(AVERROR(ENOMEM));
6853 const enum AVPixelFormat pf = pix_fmt;
6857 AV_OPT_SEARCH_CHILDREN | AV_OPT_ARRAY_REPLACE,
6860 AV_OPT_TYPE_PIXEL_FMT,
6880 throw static_cast<int>(AVERROR(ENOMEM));
6884 enum AVPixelFormat pixel_fmts[] = { pix_fmt, AV_PIX_FMT_NONE };
6886#pragma GCC diagnostic push
6887#pragma GCC diagnostic ignored "-Wconversion"
6888#pragma GCC diagnostic ignored "-Wsign-conversion"
6889 ret = av_opt_set_int_list(
m_buffer_sink_context,
"pix_fmts", pixel_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
6890#pragma GCC diagnostic pop
6907 outputs->name = av_strdup(
"in");
6909 outputs->pad_idx = 0;
6910 outputs->next =
nullptr;
6912 inputs->name = av_strdup(
"out");
6914 inputs->pad_idx = 0;
6915 inputs->next =
nullptr;
6921 const char * filters;
6923 filters =
"yadif=mode=send_frame:parity=auto:deint=all";
6933 ret = avfilter_graph_parse_ptr(
m_filter_graph, filters, &inputs, &outputs,
nullptr);
6959 if (inputs !=
nullptr)
6961 avfilter_inout_free(&inputs);
6963 if (outputs !=
nullptr)
6965 avfilter_inout_free(&outputs);
6988 ret = filterframe.
res();
7005 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
7018 filterframe->pts = (*srcframe)->pts;
7019 filterframe->best_effort_timestamp = (*srcframe)->best_effort_timestamp;
7021 *srcframe = filterframe;
7063 return AVERROR(EINVAL);
7079 return AVERROR(EINVAL);
7128 return pThis->
get_format(input_codec_ctx, pix_fmts);
7136 Logging::error(
filename(),
"Unable to decode this file using hardware acceleration: Internal error! No hardware device type set.");
7137 return AV_PIX_FMT_NONE;
7142 for (
const AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++)
7144 if (*p == pix_fmt_expected)
7146 return pix_fmt_expected;
7152 return AV_PIX_FMT_NONE;
7157 std::string active_device(device);
7160 if (active_device ==
"AUTO" && dev_type == AV_HWDEVICE_TYPE_VAAPI)
7162 active_device =
"/dev/dri/renderD128";
7165 ret = av_hwdevice_ctx_create(hwaccel_enc_device_ctx, dev_type, !active_device.empty() ? active_device.c_str() :
nullptr,
nullptr, 0);
7178 int ret = AVERROR(EINVAL);
7184 if (input_codec_ctx->hw_device_ctx ==
nullptr)
7186 int ret = AVERROR(ENOMEM);
7191 input_codec_ctx->opaque =
static_cast<void*
>(
this);
7199 if (*hwaccel_device_ctx !=
nullptr)
7201 av_buffer_unref(hwaccel_device_ctx);
7202 *hwaccel_device_ctx =
nullptr;
7208 AVBufferRef *hw_new_frames_ref;
7209 AVHWFramesContext *frames_ctx =
nullptr;
7212 hw_new_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
7213 if (hw_new_frames_ref ==
nullptr)
7215 ret = AVERROR(ENOMEM);
7220 frames_ctx =
reinterpret_cast<AVHWFramesContext *
>(hw_new_frames_ref->data);
7223 frames_ctx->width = input_codec_ctx->width;
7224 frames_ctx->height = input_codec_ctx->height;
7226 frames_ctx->initial_pool_size = 20;
7228 ret = av_hwframe_ctx_init(hw_new_frames_ref);
7232 av_buffer_unref(&hw_new_frames_ref);
7236 output_codec_ctx->hw_frames_ctx = av_buffer_ref(hw_new_frames_ref);
7237 if (output_codec_ctx->hw_frames_ctx ==
nullptr)
7239 ret = AVERROR(ENOMEM);
7243 av_buffer_unref(&hw_new_frames_ref);
7315 ret = av_frame_copy_props(*sw_frame, hw_frame);
7322 ret = av_hwframe_transfer_data(*sw_frame, hw_frame, 0);
7336 ret = av_frame_copy_props(*hw_frame, sw_frame);
7343 ret = av_hwframe_get_buffer(output_codec_ctx->hw_frames_ctx, *hw_frame, 0);
7350 if ((*hw_frame)->hw_frames_ctx ==
nullptr)
7352 ret = AVERROR(ENOMEM);
7357 ret = av_hwframe_transfer_data(*hw_frame, sw_frame, 0);
7380 std::string codec_name_buf;
7400 case HWACCELAPI::NONE:
7403 ret = AVERROR_DECODER_NOT_FOUND;
7408 if (codec_name !=
nullptr)
7412 *codec_name = codec_name_buf;
7416 codec_name->clear();
7425 std::string codec_name_buf;
7445 case HWACCELAPI::NONE:
7448 ret = AVERROR_DECODER_NOT_FOUND;
7453 if (codec_name !=
nullptr)
7457 *codec_name = codec_name_buf;
7461 codec_name->clear();
7485 case AV_CODEC_ID_H264:
7487 *codec_name =
"h264_vaapi";
7521 case AV_CODEC_ID_MPEG2VIDEO:
7523 *codec_name =
"mpeg2_vaapi";
7526 case AV_CODEC_ID_HEVC:
7528 *codec_name =
"hevc_vaapi";
7531 case AV_CODEC_ID_VC1:
7533 *codec_name =
"vc1_vaapi";
7536 case AV_CODEC_ID_VP8:
7538 *codec_name =
"vp9_vaapi";
7541 case AV_CODEC_ID_VP9:
7543 *codec_name =
"vp9_vaapi";
7548 ret = AVERROR_DECODER_NOT_FOUND;
7570 case AV_CODEC_ID_H264:
7572 *codec_name =
"h264_mmal";
7592 case AV_CODEC_ID_MPEG2VIDEO:
7594 *codec_name =
"mpeg2_mmal";
7597 case AV_CODEC_ID_MPEG4:
7599 *codec_name =
"mpeg4_mmal";
7615 case AV_CODEC_ID_VC1:
7617 *codec_name =
"vc1_mmal";
7622 ret = AVERROR_DECODER_NOT_FOUND;
7713 case AV_CODEC_ID_H264:
7715 *codec_name =
"h264_omx";
7720 ret = AVERROR_DECODER_NOT_FOUND;
7742 case AV_CODEC_ID_H263:
7744 *codec_name =
"h263_v4l2m2m";
7747 case AV_CODEC_ID_H264:
7749 *codec_name =
"h264_v4l2m2m";
7752 case AV_CODEC_ID_H265:
7754 *codec_name =
"hevc_v4l2m2m";
7757 case AV_CODEC_ID_MPEG4:
7759 *codec_name =
"mpeg4_v4l2m2m";
7762 case AV_CODEC_ID_VP8:
7764 *codec_name =
"vp8_v4l2m2m";
7769 ret = AVERROR_DECODER_NOT_FOUND;
7783 return AV_PIX_FMT_NONE;
7798 if (output_codec_ctx ==
nullptr)
7804 *out_pix_fmt = (output_codec_ctx !=
nullptr) ? output_codec_ctx->pix_fmt : AV_PIX_FMT_YUV420P;
7806 if (*in_pix_fmt == AV_PIX_FMT_NONE)
7809 *in_pix_fmt = *out_pix_fmt;
7816 output_codec_ctx !=
nullptr &&
7817 output_codec_ctx->hw_frames_ctx !=
nullptr &&
7818 output_codec_ctx->hw_frames_ctx->data !=
nullptr)
7820 *out_pix_fmt =
reinterpret_cast<AVHWFramesContext*
>(output_codec_ctx->hw_frames_ctx->data)->sw_format;
7831 return (next_segment ==
m_current_segment + 1 && next_segment <= m_virtualfile->get_segment_count());
7846 StreamRef_map::const_iterator it =
m_in.
m_subtitle.find(stream_idx);
7878 STREAM_MAP::const_iterator it =
m_stream_map.find(in_stream_idx);
7885 return (it->second);
7894 const std::filesystem::directory_iterator end;
7895 for (std::filesystem::directory_iterator iter{ search_path }; iter != end && ret == 0; iter++)
7897 const std::string subtitle_filename(iter->path().filename().string());
7898 if (std::filesystem::is_regular_file(*iter))
7900 if (std::regex_match(subtitle_filename, regex))
7903 if (std::regex_search(subtitle_filename.cbegin(), subtitle_filename.cend(), res, regex))
7905 if (res[2].length())
7907 ret = f(iter->path().string(), res[2]);
7911 ret = f(iter->path().string(), std::nullopt);
7916 else if (std::filesystem::is_directory(*iter) && depth > 0)
7922 catch (std::filesystem::filesystem_error& e)
7924 ret = AVERROR(e.code().value());
7927 catch (std::bad_alloc & e)
7929 ret = AVERROR(ENOMEM);
7939 buf_size = FFMIN(buf_size,
static_cast<int>(bd->
size));
7947 std::memcpy(buf, bd->
ptr,
static_cast<size_t>(buf_size));
7948 bd->
ptr += buf_size;
7949 bd->
size -=
static_cast<size_t>(buf_size);
7956 AVFormatContext *format_ctx =
nullptr;
7957 AVIOContext *avio_ctx =
nullptr;
7958 uint8_t *buffer =
nullptr;
7964 Logging::debug(
filename(),
"Adding external subtitle stream: %1 [%2]", subtitle_file.c_str(), language->c_str());
7973 uint8_t *avio_ctx_buffer =
nullptr;
7974 int avio_ctx_buffer_size = 4096;
7978 ret = av_file_map(subtitle_file.c_str(), &buffer, &buffer_size, 0,
nullptr);
7986 bd.
size = buffer_size;
7988 format_ctx = avformat_alloc_context();
7989 if (format_ctx ==
nullptr)
7991 throw AVERROR(ENOMEM);
7994 avio_ctx_buffer =
reinterpret_cast<uint8_t *
>(av_malloc(
static_cast<size_t>(avio_ctx_buffer_size)));
7995 if (avio_ctx_buffer ==
nullptr)
7997 throw AVERROR(ENOMEM);
8000 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, &bd, &
read_packet,
nullptr,
nullptr);
8001 if (avio_ctx ==
nullptr)
8003 throw AVERROR(ENOMEM);
8005 format_ctx->pb = avio_ctx;
8007 ret = avformat_open_input(&format_ctx,
nullptr,
nullptr,
nullptr);
8014 ret = avformat_find_stream_info(format_ctx,
nullptr);
8023 AVCodecContext * codec_ctx =
nullptr;
8027 if (ret < 0 && ret != AVERROR_STREAM_NOT_FOUND)
8033 if (ret != AVERROR_STREAM_NOT_FOUND)
8037 if (codec_id != AV_CODEC_ID_NONE)
8041 codec_ctx->pkt_timebase = codec_ctx->time_base = format_ctx->streams[0]->time_base;
8045 input_streamref.
m_stream = format_ctx->streams[0];
8056 int output_stream_index = ret;
8065 while ((ret = av_read_frame(format_ctx, pkt)) == 0)
8077 if (ret == AVERROR_EOF)
8087 avformat_close_input(&format_ctx);
8090 if (avio_ctx !=
nullptr)
8092 av_freep(&avio_ctx->buffer);
8095 avio_context_free(&avio_ctx);
8097 av_file_unmap(buffer, buffer_size);
8108 std::filesystem::path file(
filename());
8109 std::string stem(file.stem().string());
8114 std::string regex_string(
"^(" + stem +
"[.])(.*)([.]srt|[.]vtt)|^(" + stem +
")([.]srt|[.]vtt)");
8115 std::regex regex(regex_string, std::regex::ECMAScript);
8125 file.parent_path().string(),
8128 [
this](
const std::string & subtitle_file,
const std::optional<std::string> & language)
8130 add_external_subtitle_stream(std::forward<decltype(subtitle_file)>(subtitle_file), std::forward<decltype(language)>(language));
8152 catch (std::regex_error & e)
8155 Logging::error(
filename(),
"INTERNAL ERROR: FFmpeg_Transcoder::add_external_subtitle_streams()! Unable to create reg exp: %1", e.what());
8163 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.
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.
int write(void **data, int nb_samples)
Write audio samples into the FIFO.
void reset()
Free the owned FIFO and reset the wrapper to empty.
int read(void **data, int nb_samples)
Read audio samples from the FIFO.
bool empty() const
Check whether the wrapper currently owns a FIFO.
int size() const
Return the number of samples currently stored in the FIFO.
int realloc(int nb_samples)
Resize the FIFO allocation.
int alloc(AVSampleFormat sample_fmt, int channels, int nb_samples=1)
Allocate a new audio FIFO, replacing any existing one.
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.
RAII wrapper for AVDictionary.
AVDictionary ** address()
Get a writable pointer-to-pointer for FFmpeg APIs.
int alloc_input_context()
Allocate a new input format context.
bool reset()
Free the owned format context and reset the wrapper to empty.
AVFormatContext ** address()
Get a writable pointer-to-pointer for FFmpeg APIs.
void set_custom_io(bool custom_io=true)
Mark whether the context owns a custom AVIOContext.
int alloc_output_context(const char *format_name, const char *filename=nullptr)
Allocate a new output format context.
int m_stream_idx
Stream index frame belongs to, or -1 (INVALID_STREAM)
int res() const
Get result of last operation.
RAII wrapper for AVPacket.
void unref()
Unreference packet payload, keep the AVPacket object allocated.
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.
bool reset(SwrContext *ctx=nullptr)
Replace the owned context.
SwrContext ** address()
Get a writable pointer-to-pointer for FFmpeg allocation APIs.
bool reset(SwsContext *ctx=nullptr)
Replace the owned context.
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.
@ NONE
Hardware acceleration not active.
@ 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)
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.
std::queue< FFmpeg_Packet > m_hls_packet_fifo
HLS packet FIFO.
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.
FFmpeg_SwrContext m_audio_resample_ctx
SwResample context for audio resampling.
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....
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.
FFmpeg_AudioFifo m_audio_fifo
Audio sample FIFO.
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...
FFmpeg_SwsContext m_sws_ctx
Context for video filtering.
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.
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...
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
FFmpeg AVDictionary RAII wrapper.
#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.