8#include <libavcodec/avcodec.h>
9#include <libavformat/avformat.h>
10#include <libavutil/hwcontext.h>
11#include <libavutil/imgutils.h>
12#include <libavutil/mathematics.h>
13#include <libavutil/opt.h>
14#include <libswscale/swscale.h>
18#include <condition_variable>
26#ifdef MXWRITE_HAS_CUDA_COPY
27#include <cuda_runtime.h>
156 bool open(
const std::string &filename,
int width,
int height,
float fps,
const char *crf);
166 bool open(
const std::string &filename,
int width,
int height,
float fps,
const EncodeOptions &opts);
171 void write(
void *rgba_buffer);
206 bool write_cuda_rgba(
void *cuda_rgba_buffer,
int src_stride,
bool bottom_up =
false);
225 bool open_ts(
const std::string &filename,
int width,
int height,
float fps,
const char *crf);
235 bool open_ts(
const std::string &filename,
int width,
int height,
float fps,
const EncodeOptions &opts);
262 std::uint64_t
get_bytes_written()
const {
return bytes_written.load(std::memory_order_relaxed); }
279 int64_t frame_count = 0;
280 double last_duration = 0.0;
281 AVFormatContext *format_ctx =
nullptr;
282 AVCodecContext *codec_ctx =
nullptr;
283 AVStream *stream =
nullptr;
284 AVFrame *frameYUV =
nullptr;
285 AVFrame *frameRGBA =
nullptr;
286 AVFrame *frame10 =
nullptr;
287 AVFrame *upload_sw_frame =
nullptr;
288 AVBufferRef *hw_device_ctx =
nullptr;
289 AVBufferRef *hw_frames_ctx =
nullptr;
290 bool use_hw_encode =
false;
291 bool active_encoder_hardware =
false;
292 bool direct_cuda_upload =
false;
293#ifdef MXWRITE_HAS_CUDA_COPY
296 cudaStream_t cuda_upload_stream =
nullptr;
298 bool hdr_output =
false;
299 EncodeOptions::HdrInfo hdr_info;
300 SwsContext *sws_ctx =
nullptr;
301 AVRational time_base;
303 void calculateFPSFraction(
float fps,
int &fps_num,
int &fps_den);
304 std::chrono::steady_clock::time_point recordingStart;
306 std::queue<AVFrame *> encode_queue;
309 static constexpr size_t MAX_QUEUE_SIZE = 120;
313 static constexpr size_t NO_DROP_QUEUE_SIZE = 1;
314 std::condition_variable queue_cv;
315 std::jthread encode_thread;
317 std::mutex queue_mutex{};
318 std::mutex writer_mutex{};
319 bool stop_requested =
false;
320 std::atomic<bool> block_when_full{
false};
321 std::atomic<std::uint64_t> bytes_written{0};
324 bool openInternal(
const std::string &filename,
int w,
int h,
float fps,
const EncodeOptions &opts,
bool ts_mode);
326 bool initHardwareEncoding(
const AVCodec *codec, AVPixelFormat requested_format,
bool prefer_cuda_rgba);
328 void startEncoderThread();
330 void stopEncoderThread();
332 void encodeLoop(std::stop_token stop_token);
334 void encodeAndWriteFrame(AVFrame *in_frame);
336 void drainEncoderPackets();
338 void updateBytesWritten() noexcept;
340 void releaseFrame(AVFrame *f);
348extern
void transfer_audio(std::string_view sourceAudioFile, std::string_view destVideoFile);
355extern
void cleanup_contexts(AVFormatContext *source_ctx, AVFormatContext *dest_ctx, AVFormatContext *output_ctx);
std::uint64_t get_bytes_written() const
Return the current logical byte position of the output muxer.
bool is_hardware_encode() const
True when FFmpeg identifies the active encoder as hardware or hybrid.
void write_hdr_rgba16_at_pts(void *rgba16_buffer, int64_t pts)
Queue a 16-bit HDR RGBA frame with an explicit presentation timestamp.
Writer()=default
Construct a closed writer.
bool get_block_when_full() const
Check whether the encoder queue blocks instead of dropping frames.
bool write_cuda_rgba(void *cuda_rgba_buffer, int src_stride, bool bottom_up=false)
Queue a CUDA RGBA frame for encoding.
void set_block_when_full(bool value)
If true, keep one pending frame and pace producer threads to the encoder instead of dropping frames....
void write_at_pts(void *rgba_buffer, int64_t pts)
Queue a host RGBA frame with an explicit presentation timestamp.
~Writer()
Close the writer on destruction if it is still open.
bool open(const std::string &filename, int width, int height, float fps, const char *crf)
Open an output file using the legacy CRF string interface.
void write(void *rgba_buffer)
Queue a host RGBA frame for immediate-mode encoding.
bool open_ts(const std::string &filename, int width, int height, float fps, const char *crf)
Open a timestamp-based output stream using the legacy CRF string interface.
bool is_open() const
Check whether the writer is currently open.
double get_duration() const
Return the encoded duration in seconds.
bool write_cuda_rgba_at_pts(void *cuda_rgba_buffer, int src_stride, int64_t pts, bool bottom_up=false)
Queue a CUDA RGBA frame with an explicit presentation timestamp.
void close()
Close the writer and flush pending packets.
int64_t get_frame_count() const
Return the output timeline length in nominal frame ticks.
void write_hdr_rgba16(void *rgba16_buffer)
Write a 16-bit RGBA frame that is already PQ- or HLG-encoded in BT.2020 primaries (8 bytes/pixel: R16...
void write_ts(void *rgba_buffer)
Queue a host RGBA frame using capture timestamps.
std::vector< EncoderInfo > available_video_encoders()
std::vector< EncoderOptionInfo > video_encoder_options(std::string_view encoder_name)
Return the options exposed by one registered video encoder.
void transfer_audio(std::string_view sourceAudioFile, std::string_view destVideoFile)
Copy audio from one video file to another.
void cleanup_contexts(AVFormatContext *source_ctx, AVFormatContext *dest_ctx, AVFormatContext *output_ctx)
Free FFmpeg format contexts used during transfer operations.
std::vector< uint8_t > content_light
Raw AVContentLightMetadata side-data bytes, or empty.
int color_range
AVColorRange value. Raw AVMasteringDisplayMetadata side-data bytes, or empty.
std::vector< uint8_t > mastering_display
int color_trc
AVColorTransferCharacteristic value.
bool enabled
Enables the HDR output path.
int color_primaries
AVColorPrimaries value.
int color_space
AVColorSpace value.
User-configurable video encoder quality options.
std::string codec
Encoder selection policy or exact FFmpeg encoder name.
std::int64_t bit_rate
Target bits/second; 0 selects CRF/CQ.
std::string tune
Optional tuning mode.
bool realtime
Enable low-latency settings.
std::string ffmpeg_options
Additional FFmpeg-style video encoder options.
struct EncodeOptions::HdrInfo hdr
int crf
Constant Rate Factor.
bool block_when_full
Pace producers to encoder throughput instead of dropping frames.
std::string preset
Encoder preset name.
A video encoder reported by the linked FFmpeg installation.
std::string long_name
Human-readable encoder description.
std::string pixel_formats
Comma-separated supported input pixel formats.
std::string name
Exact libavcodec encoder name (for example, libx265).
std::string codec_name
Encoded format name (for example, hevc or av1).
bool experimental
True when FFmpeg marks the encoder experimental.
bool hardware
True for hardware or hybrid encoders.
One configurable AVOption exposed by a video encoder.
std::string minimum
Minimum value for numeric options.
std::string name
Option name accepted by EncodeOptions::ffmpeg_options.
std::string help
Human-readable FFmpeg option description.
std::string choices
Comma-separated named values for enum-like options.
std::string type
FFmpeg option type.
std::string maximum
Maximum value for numeric options.
std::string default_value
Encoder default, when it can be represented as text.
Queue entry that stores a frame pointer and its capture timestamp.
void * data
Pointer to RGBA frame data owned by the producer.
std::chrono::steady_clock::time_point capture_time
Capture time for timestamp-based encoding.