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)
58#if !LAVC_DEP_AV_INIT_PACKET
59void FFmpeg_Base::init_packet(AVPacket *pkt)
const
68void FFmpeg_Base::video_stream_setup(AVCodecContext *output_codec_ctx, AVStream* output_stream, AVCodecContext *input_codec_ctx, AVRational framerate, AVPixelFormat enc_hw_pix_fmt)
const
70 AVRational time_base_tbn;
71 AVRational time_base_tbc;
73 if (!framerate.num || !framerate.den)
77 Logging::warning(
nullptr,
"No information about the input framerate is available. Falling back to a default value of 25fps for the output stream.");
87 switch (output_codec_ctx->codec_id)
89 case AV_CODEC_ID_THEORA:
90 case AV_CODEC_ID_MPEG1VIDEO:
91 case AV_CODEC_ID_MPEG2VIDEO:
93 time_base_tbn = av_inv_q(framerate);
94 time_base_tbc = time_base_tbn;
99 time_base_tbn.num = 1;
100 time_base_tbn.den = 1000;
101 time_base_tbc = time_base_tbn;
104 case AV_CODEC_ID_H264:
105 case AV_CODEC_ID_H265:
107 time_base_tbn.num = 1;
108 time_base_tbn.den = 90000;
109 time_base_tbc = av_inv_q(framerate);
114 time_base_tbn.num = 1;
115 time_base_tbn.den = 90000;
116 time_base_tbc = time_base_tbn;
122 output_stream->time_base = time_base_tbn;
124 output_codec_ctx->time_base = time_base_tbc;
128 output_stream->r_frame_rate = framerate;
131 output_stream->avg_frame_rate = framerate;
134 if (enc_hw_pix_fmt == AV_PIX_FMT_NONE)
139 AVPixelFormat src_pix_fmt = input_codec_ctx->pix_fmt;
140 if (output_codec_ctx->codec->pix_fmts !=
nullptr)
143 enc_hw_pix_fmt = avcodec_find_best_pix_fmt_of_list(output_codec_ctx->codec->pix_fmts, src_pix_fmt, alpha, &loss);
146 if (enc_hw_pix_fmt == AV_PIX_FMT_NONE)
149 switch (output_codec_ctx->codec_id)
151 case AV_CODEC_ID_PRORES:
155 enc_hw_pix_fmt = AV_PIX_FMT_YUV422P10LE;
161 enc_hw_pix_fmt = AV_PIX_FMT_YUV420P;
168 output_codec_ctx->pix_fmt = enc_hw_pix_fmt;
169 output_codec_ctx->gop_size = 12;
174 if (nodelete && !*value)
179 int ret = av_dict_set(pm, key, value, flags);
191 if (nodelete && !value)
196 int ret = av_dict_set_int(pm, key, value, flags);
208 int ret = av_opt_set(obj, key, value, flags);
220 if (stream !=
nullptr && stream->codecpar !=
nullptr)
222 int64_t duration = AV_NOPTS_VALUE;
224 if (stream->duration != AV_NOPTS_VALUE)
230 out_file ?
"out" :
"in",
233 format_bitrate((stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate : format_ctx->bit_rate).c_str(),
239 out_file ?
"out" :
"in");
245 if (stream !=
nullptr && stream->codecpar !=
nullptr)
247 int64_t duration = AV_NOPTS_VALUE;
249 if (stream->duration != AV_NOPTS_VALUE)
255 out_file ?
"out" :
"in",
258 format_bitrate((stream->codecpar->bit_rate != 0) ? stream->codecpar->bit_rate : format_ctx->bit_rate).c_str(),
266 out_file ?
"out" :
"in");
272 if (stream !=
nullptr && stream->codecpar !=
nullptr)
275 out_file ?
"out" :
"in",
282 out_file ?
"out" :
"in");
288 const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
289 return (fmt_name !=
nullptr ? fmt_name :
"none");
294 return av_get_sample_fmt_name(sample_fmt);
297#if LAVU_DEP_OLD_CHANNEL_LAYOUT
300 std::array<char, 1024> buffer;
301 av_channel_layout_describe(ch_layout, buffer.data(), buffer.size() - 1);
302 return buffer.data();
307 std::array<char, 1024> buffer;
308 av_get_channel_layout_string(buffer.data(), buffer.size() - 1, nb_channels, channel_layout);
309 return buffer.data();
315 if (pts == AV_NOPTS_VALUE)
319 int64_t start_time = (stream->start_time != AV_NOPTS_VALUE) ? stream->start_time : 0;
320 AVRational factor = av_mul_q(stream->avg_frame_rate, stream->time_base);
321 return static_cast<uint32_t
>(av_rescale(pts - start_time, factor.num, factor.den) + 1);
326 int64_t start_time = (stream->start_time != AV_NOPTS_VALUE) ? stream->start_time : 0;
327 AVRational factor = av_mul_q(stream->avg_frame_rate, stream->time_base);
328 return static_cast<uint32_t
>(av_rescale(frame_no - 1, factor.den, factor.num) + start_time);
333#if LAVU_DEP_OLD_CHANNEL_LAYOUT
334 return codecpar->ch_layout.nb_channels;
336 return codecpar->channels;
342#if LAVU_DEP_OLD_CHANNEL_LAYOUT
343 codecpar_out->ch_layout.nb_channels = codecpar_in->ch_layout.nb_channels;
345 codecpar_out->channels = codecpar_in->channels;
351#if LAVU_DEP_OLD_CHANNEL_LAYOUT
352 return codec_ctx->ch_layout.nb_channels;
354 return codec_ctx->channels;
360#if LAVU_DEP_OLD_CHANNEL_LAYOUT
361 codec_ctx_out->ch_layout.nb_channels= codec_ctx_in->ch_layout.nb_channels;
363 codec_ctx_out->channels = codec_ctx_in->channels;
369#if LAVU_DEP_OLD_CHANNEL_LAYOUT
370 codec_ctx_out->ch_layout.nb_channels = channels;
372 codec_ctx_out->channels = channels;
382int 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
387 "; https://github.com/nschlia/ffmpegfs\r\n"
388 "ScriptType: v4.00+\r\n"
391 "ScaledBorderAndShadow: yes\r\n"
409 "Fontname, Fontsize, "
410 "PrimaryColour, SecondaryColour, OutlineColour, BackColour, "
411 "Bold, Italic, Underline, StrikeOut, "
414 "BorderStyle, Outline, Shadow, "
415 "Alignment, MarginL, MarginR, MarginV, "
421 "&H%x,&H%x,&H%x,&H%x,"
431 "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n";
433 size_t size =
static_cast<size_t>(snprintf(
nullptr, 0, format, play_res_x, play_res_y, font, font_size,
434 primary_color, secondary_color, outline_color, back_color,
435 -bold, -italic, -underline, border_style, alignment)) + 1;
437 codec_ctx->subtitle_header =
reinterpret_cast<uint8_t *
>(av_malloc(size + 1));
439 if (codec_ctx->subtitle_header ==
nullptr)
441 return AVERROR(ENOMEM);
444 snprintf(
reinterpret_cast<char *
>(codec_ctx->subtitle_header), size, format,
445 play_res_x, play_res_y, font, font_size,
446 primary_color, secondary_color, outline_color, back_color,
447 -bold, -italic, -underline, border_style, alignment);
449 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.