36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wconversion"
38#pragma GCC diagnostic ignored "-Wsign-conversion"
39#include <libavutil/opt.h>
40#include <libavutil/mathematics.h>
41#include <libavutil/pixdesc.h>
42#include <libavutil/channel_layout.h>
43#include <libavcodec/avcodec.h>
44#pragma GCC diagnostic pop
54 : m_virtualfile(nullptr)
59void FFmpeg_Base::video_stream_setup(AVCodecContext *output_codec_ctx, AVStream* output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt)
const
61 AVRational time_base_tbn;
62 AVRational time_base_tbc;
64 if (!framerate.num || !framerate.den)
68 Logging::warning(
nullptr,
"No information about the input framerate is available. Falling back to a default value of 25fps for the output stream.");
78 switch (output_codec_ctx->codec_id)
80 case AV_CODEC_ID_THEORA:
81 case AV_CODEC_ID_MPEG1VIDEO:
82 case AV_CODEC_ID_MPEG2VIDEO:
84 time_base_tbn = av_inv_q(framerate);
85 time_base_tbc = time_base_tbn;
90 time_base_tbn.num = 1;
91 time_base_tbn.den = 1000;
92 time_base_tbc = time_base_tbn;
95 case AV_CODEC_ID_H264:
96 case AV_CODEC_ID_H265:
98 time_base_tbn.num = 1;
99 time_base_tbn.den = 90000;
100 time_base_tbc = av_inv_q(framerate);
105 time_base_tbn.num = 1;
106 time_base_tbn.den = 90000;
107 time_base_tbc = time_base_tbn;
113 output_stream->time_base = time_base_tbn;
115 output_codec_ctx->time_base = time_base_tbc;
119 output_stream->r_frame_rate = framerate;
122 output_stream->avg_frame_rate = framerate;
125 if (enc_hw_pix_fmt == AV_PIX_FMT_NONE)
130 AVPixelFormat src_pix_fmt = input_codec_ctx->pix_fmt;
131#if LAVC_USE_SUPPORTED_CFG
133 const enum AVPixelFormat *pix_list =
nullptr;
135 int ret_cfg = avcodec_get_supported_config(output_codec_ctx, output_codec_ctx->codec,
136 AV_CODEC_CONFIG_PIX_FORMAT,
137 0, (
const void**)&pix_list, &npix);
138 if (ret_cfg >= 0 && pix_list && npix > 0)
141 enc_hw_pix_fmt = avcodec_find_best_pix_fmt_of_list(pix_list, src_pix_fmt, alpha, &loss);
145 if (output_codec_ctx->codec->pix_fmts !=
nullptr)
148 enc_hw_pix_fmt = avcodec_find_best_pix_fmt_of_list(output_codec_ctx->codec->pix_fmts, src_pix_fmt, alpha, &loss);
152 if (enc_hw_pix_fmt == AV_PIX_FMT_NONE)
155 switch (output_codec_ctx->codec_id)
157 case AV_CODEC_ID_PRORES:
161 enc_hw_pix_fmt = AV_PIX_FMT_YUV422P10LE;
167 enc_hw_pix_fmt = AV_PIX_FMT_YUV420P;
174 output_codec_ctx->pix_fmt = enc_hw_pix_fmt;
175 output_codec_ctx->gop_size = 12;
180 if (nodelete && !*value)
185 int ret = av_dict_set(pm, key, value, flags);
197 if (nodelete && !value)
202 int ret = av_dict_set_int(pm, key, value, flags);
214 int ret = av_opt_set(obj, key, value, flags);
226 if (stream !=
nullptr && stream->codecpar !=
nullptr)
228 int64_t duration = AV_NOPTS_VALUE;
230 if (stream->duration != AV_NOPTS_VALUE)
236 out_file ?
"out" :
"in",
239 format_bitrate((stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate : format_ctx->bit_rate).c_str(),
245 out_file ?
"out" :
"in");
251 if (stream !=
nullptr && stream->codecpar !=
nullptr)
253 int64_t duration = AV_NOPTS_VALUE;
255 if (stream->duration != AV_NOPTS_VALUE)
261 out_file ?
"out" :
"in",
264 format_bitrate((stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate : format_ctx->bit_rate).c_str(),
272 out_file ?
"out" :
"in");
278 if (stream !=
nullptr && stream->codecpar !=
nullptr)
281 out_file ?
"out" :
"in",
288 out_file ?
"out" :
"in");
294 const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
295 return (fmt_name !=
nullptr ? fmt_name :
"none");
300 return av_get_sample_fmt_name(sample_fmt);
303#if LAVU_DEP_OLD_CHANNEL_LAYOUT
306 std::array<char, 1024> buffer;
307 av_channel_layout_describe(ch_layout, buffer.data(), buffer.size() - 1);
308 return buffer.data();
313 std::array<char, 1024> buffer;
314 av_get_channel_layout_string(buffer.data(), buffer.size() - 1, nb_channels, channel_layout);
315 return buffer.data();
321 if (pts == AV_NOPTS_VALUE)
325 int64_t start_time = (stream->start_time != AV_NOPTS_VALUE) ? stream->start_time : 0;
326 AVRational factor = av_mul_q(stream->avg_frame_rate, stream->time_base);
327 return static_cast<uint32_t
>(av_rescale(pts - start_time, factor.num, factor.den) + 1);
332 int64_t start_time = (stream->start_time != AV_NOPTS_VALUE) ? stream->start_time : 0;
333 AVRational factor = av_mul_q(stream->avg_frame_rate, stream->time_base);
334 return static_cast<uint32_t
>(av_rescale(frame_no - 1, factor.den, factor.num) + start_time);
339#if LAVU_DEP_OLD_CHANNEL_LAYOUT
340 return codecpar->ch_layout.nb_channels;
342 return codecpar->channels;
348#if LAVU_DEP_OLD_CHANNEL_LAYOUT
349 codecpar_out->ch_layout.nb_channels = codecpar_in->ch_layout.nb_channels;
351 codecpar_out->channels = codecpar_in->channels;
357#if LAVU_DEP_OLD_CHANNEL_LAYOUT
358 return codec_ctx->ch_layout.nb_channels;
360 return codec_ctx->channels;
366#if LAVU_DEP_OLD_CHANNEL_LAYOUT
367 codec_ctx_out->ch_layout.nb_channels= codec_ctx_in->ch_layout.nb_channels;
369 codec_ctx_out->channels = codec_ctx_in->channels;
375#if LAVU_DEP_OLD_CHANNEL_LAYOUT
376 codec_ctx_out->ch_layout.nb_channels = channels;
378 codec_ctx_out->channels = channels;
388int FFmpeg_Base::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
393 "; https://github.com/nschlia/ffmpegfs\r\n"
394 "ScriptType: v4.00+\r\n"
397 "ScaledBorderAndShadow: yes\r\n"
415 "Fontname, Fontsize, "
416 "PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
417 "Bold, Italic, Underline, StrikeOut, "
420 "BorderStyle, Outline, Shadow, "
421 "Alignment, MarginL, MarginR, MarginV, "
427 "&H%x,&H%x,&H%x,&H%x,"
437 "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n";
439 size_t size =
static_cast<size_t>(snprintf(
nullptr, 0, format, play_res_x, play_res_y, font, font_size,
440 primary_color, secondary_color, outline_color, back_color,
441 -bold, -italic, -underline, border_style, alignment)) + 1;
443 codec_ctx->subtitle_header =
reinterpret_cast<uint8_t *
>(av_malloc(size + 1));
445 if (codec_ctx->subtitle_header ==
nullptr)
447 return AVERROR(ENOMEM);
450 snprintf(
reinterpret_cast<char *
>(codec_ctx->subtitle_header), size, format,
451 play_res_x, play_res_y, font, font_size,
452 primary_color, secondary_color, outline_color, back_color,
453 -bold, -italic, -underline, border_style, alignment);
455 codec_ctx->subtitle_header_size =
static_cast<int>(size);
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.
virtual const char * virtname() const =0
Return virtual filename. Must be implemented in child class.
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.
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.
FFmpeg_Base()
Construct FFmpeg_Base object.
virtual const char * filename() const =0
Return source filename. Must be implemented in child class.
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 error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
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.
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 format_bitrate(BITRATE value)
Format a bit rate.
std::string ffmpeg_geterror(int errnum)
Get FFmpeg error string for errnum. Internally calls av_strerror().
#define FFMPEFS_VERSION
FFmpegfs version number.
Provide various log facilities to stderr, disk or syslog.