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>
153 bool open(
const std::string &filename,
int width,
int height,
float fps,
const char *crf);
163 bool open(
const std::string &filename,
int width,
int height,
float fps,
const EncodeOptions &opts);
168 void write(
void *rgba_buffer);
203 bool write_cuda_rgba(
void *cuda_rgba_buffer,
int src_stride,
bool bottom_up =
false);
213 bool bottom_up =
false);
223 bool open_ts(
const std::string &filename,
int width,
int height,
float fps,
const char *crf);
233 bool open_ts(
const std::string &filename,
int width,
int height,
float fps,
const EncodeOptions &opts);
261 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,
327 bool prefer_cuda_rgba);
329 void startEncoderThread();
331 void stopEncoderThread();
333 void encodeLoop(std::stop_token stop_token);
335 void encodeAndWriteFrame(AVFrame *in_frame);
337 void drainEncoderPackets();
339 void updateBytesWritten() noexcept;
341 void releaseFrame(AVFrame *f);
349extern
void transfer_audio(std::string_view sourceAudioFile, std::string_view destVideoFile);
356extern
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::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.