6#include <libavcodec/avcodec.h>
7#include <libavformat/avformat.h>
8#include <libavutil/imgutils.h>
9#include <libavutil/opt.h>
10#include <libavutil/pixdesc.h>
11#include <libswscale/swscale.h>
25 AVCodecID infer_video_codec(AVFormatContext* fmt_ctx)
27 if (!fmt_ctx || !fmt_ctx->oformat)
28 return AV_CODEC_ID_H264;
30 const char* name = fmt_ctx->oformat->name;
32 return AV_CODEC_ID_H264;
34 if (std::string_view(name).find(
"webm") != std::string_view::npos)
35 return AV_CODEC_ID_VP9;
36 if (std::string_view(name).find(
"avi") != std::string_view::npos)
37 return AV_CODEC_ID_MPEG4;
39 return AV_CODEC_ID_H264;
48 int bpp_for_format(AVPixelFormat fmt)
56 case AV_PIX_FMT_BGR24:
57 case AV_PIX_FMT_RGB24:
59 case AV_PIX_FMT_RGBA64LE:
60 case AV_PIX_FMT_RGBA64BE:
61 case AV_PIX_FMT_BGRA64LE:
62 case AV_PIX_FMT_BGRA64BE:
110 AVPixelFormat src_pixel_format,
116 m_last_error =
"VideoEncodeContext::open: mux context is not open";
120 if (
width == 0 ||
height == 0 || frame_rate <= 0.0) {
121 m_last_error =
"VideoEncodeContext::open: invalid dimensions or frame rate";
131 if (codec_id == AV_CODEC_ID_NONE)
134 const AVCodec* codec = avcodec_find_encoder(codec_id);
136 m_last_error = std::string(
"avcodec_find_encoder failed for codec_id=")
137 + std::to_string(
static_cast<int>(codec_id));
155 const int fps_num =
static_cast<int>(std::round(frame_rate * 1000.0));
172 if (codec_id == AV_CODEC_ID_H264 || codec_id == AV_CODEC_ID_H265) {
188 m_last_error =
"FFmpegMuxContext::add_stream returned nullptr";
194 m_last_error =
"avcodec_parameters_from_context failed";
213 nullptr,
nullptr,
nullptr);
242 "[VideoEncodeContext] open: {}x{} @ {:.3f} fps | src={} enc={} stream#{}",
244 av_get_pix_fmt_name(src_pixel_format) ? av_get_pix_fmt_name(src_pixel_format) :
"unknown",
245 avcodec_get_name(codec_id),
264 if (src_width == 0 || src_height == 0) {
269 const size_t expected =
static_cast<size_t>(src_width)
270 *
static_cast<size_t>(src_height)
273 if (src_size < expected) {
274 m_last_error =
"encode_frame: src_size too small for declared dimensions";
288 static_cast<int>(src_width),
289 static_cast<int>(src_height),
295 nullptr,
nullptr,
nullptr);
298 m_last_error =
"sws_getContext failed on dimension change";
306 const int src_stride =
static_cast<int>(src_width) *
m_src_src_bpp;
308 &src_data, &src_stride,
309 0,
static_cast<int>(src_height),
332 m_last_error =
"avcodec_send_frame(null) failed during drain";
345 AVPacket* pkt = av_packet_alloc();
354 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
357 char errbuf[AV_ERROR_MAX_STRING_SIZE];
358 av_strerror(ret, errbuf,
sizeof(errbuf));
359 m_last_error = std::string(
"avcodec_receive_packet failed: ") + errbuf;
365 av_packet_rescale_ts(pkt,
375 av_packet_unref(pkt);
378 av_packet_free(&pkt);
#define MF_INFO(comp, ctx,...)
bool is_open() const
True if the context is open and ready to accept streams / packets.
AVStream * add_stream()
Allocate a new AVStream inside this context.
const std::string & last_error() const
bool write_packet(AVPacket *pkt)
Submit one encoded packet for interleaved writing.
AVFormatContext * format_context
Owned; freed in close().
RAII owner of a single AVFormatContext on the write path.
AVStream * m_stream
Weak ref into FFmpegMuxContext; not owned.
AVFrame * m_scratch_frame
Owned scratch buffer for encoder input.
bool open(FFmpegMuxContext &mux, uint32_t width, uint32_t height, double frame_rate, AVPixelFormat src_pixel_format, AVCodecID codec_id)
Open the encoder and register a video stream in the mux context.
bool drain(FFmpegMuxContext &mux)
Flush all buffered frames from the encoder to the mux.
bool encode_frame(const uint8_t *src_data, size_t src_size, uint32_t src_width, uint32_t src_height, FFmpegMuxContext &mux)
Encode one raw pixel frame into the mux context.
bool is_valid() const
True if codec, scaler, and scratch frame are all ready.
bool drain_packets(FFmpegMuxContext &mux)
void close()
Release all owned resources.
SwsContext * sws_context
Owned; freed in destructor.
AVCodecContext * codec_context
Owned; freed in destructor.
AVPixelFormat m_src_pixel_fmt
@ FileIO
Filesystem I/O operations.
@ IO
Networking, file handling, streaming.