1#include <nanobind/nanobind.h>
2#include <nanobind/ndarray.h>
3#include <nanobind/stl/chrono.h>
4#include <nanobind/stl/string.h>
5#include <nanobind/stl/string_view.h>
6#include <nanobind/stl/vector.h>
10namespace nb = nanobind;
13 m.doc() =
"Python bindings for MXWrite FFmpeg video writer";
26 nb::class_<EncodeOptions>(m,
"EncodeOptions").def(nb::init<>()).def_rw(
"preset", &
EncodeOptions::preset).def_rw(
"tune", &
EncodeOptions::tune).def_rw(
"crf", &
EncodeOptions::crf).def_rw(
"bit_rate", &
EncodeOptions::bit_rate).def_rw(
"codec", &
EncodeOptions::codec).def_rw(
"ffmpeg_options", &
EncodeOptions::ffmpeg_options).def_rw(
"realtime", &
EncodeOptions::realtime).def_rw(
"block_when_full", &
EncodeOptions::block_when_full).def_rw(
"hdr", &
EncodeOptions::hdr);
28 nb::class_<Writer>(m,
"Writer")
31 .def(
"open", nb::overload_cast<const std::string &, int, int, float, const char *>(&
Writer::open), nb::arg(
"filename"), nb::arg(
"width"), nb::arg(
"height"), nb::arg(
"fps"), nb::arg(
"crf"))
32 .def(
"open", nb::overload_cast<const std::string &, int, int, float, const EncodeOptions &>(&
Writer::open), nb::arg(
"filename"), nb::arg(
"width"), nb::arg(
"height"), nb::arg(
"fps"), nb::arg(
"opts"))
34 .def(
"open_ts", nb::overload_cast<const std::string &, int, int, float, const char *>(&
Writer::open_ts), nb::arg(
"filename"), nb::arg(
"width"), nb::arg(
"height"), nb::arg(
"fps"), nb::arg(
"crf"))
35 .def(
"open_ts", nb::overload_cast<const std::string &, int, int, float, const EncodeOptions &>(&
Writer::open_ts), nb::arg(
"filename"), nb::arg(
"width"), nb::arg(
"height"), nb::arg(
"fps"), nb::arg(
"opts"))
39 [](
Writer &w, nb::ndarray<uint8_t, nb::c_contig, nb::device::cpu> arr) { w.
write(arr.data()); },
40 nb::arg(
"rgba_buffer"))
44 [](
Writer &w, nb::ndarray<uint8_t, nb::c_contig, nb::device::cpu> arr, int64_t pts) { w.
write_at_pts(arr.data(), pts); },
45 nb::arg(
"rgba_buffer"),
50 [](
Writer &w, nb::ndarray<uint8_t, nb::c_contig, nb::device::cpu> arr) { w.
write_ts(arr.data()); },
51 nb::arg(
"rgba_buffer"))
55 [](
Writer &w, nb::ndarray<uint16_t, nb::c_contig, nb::device::cpu> arr) { w.
write_hdr_rgba16(arr.data()); },
56 nb::arg(
"rgba16_buffer"))
59 "write_hdr_rgba16_at_pts",
61 nb::arg(
"rgba16_buffer"),
64#ifdef MXWRITE_HAS_CUDA_COPY
67 [](
Writer &w, nb::ndarray<uint8_t, nb::c_contig, nb::device::cuda> arr,
int src_stride,
bool bottom_up) {
return w.
write_cuda_rgba(arr.data(), src_stride, bottom_up); },
68 nb::arg(
"cuda_rgba_buffer"),
69 nb::arg(
"src_stride"),
70 nb::arg(
"bottom_up") =
false)
73 "write_cuda_rgba_at_pts",
74 [](
Writer &w, nb::ndarray<uint8_t, nb::c_contig, nb::device::cuda> arr,
int src_stride, int64_t pts,
bool bottom_up) {
return w.
write_cuda_rgba_at_pts(arr.data(), src_stride, pts, bottom_up); },
75 nb::arg(
"cuda_rgba_buffer"),
76 nb::arg(
"src_stride"),
78 nb::arg(
"bottom_up") =
false)
90 m.def(
"transfer_audio", &
transfer_audio, nb::arg(
"sourceAudioFile"), nb::arg(
"destVideoFile"));
92 m.def(
"cleanup_contexts", [](nb::capsule source_ctx, nb::capsule dest_ctx, nb::capsule output_ctx) {
cleanup_contexts(
static_cast<AVFormatContext *
>(source_ctx.data()),
static_cast<AVFormatContext *
>(dest_ctx.data()),
static_cast<AVFormatContext *
>(output_ctx.data())); });
FFmpeg-backed RGBA video writer.
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.
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.
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.
NB_MODULE(mxvk_ext, module)
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< EncoderInfo > available_video_encoders()
std::vector< EncoderOptionInfo > video_encoder_options(std::string_view encoder_name)
Return the options exposed by one registered video encoder.
FFmpeg-based video writer used by MXWrite.
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.
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.
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.
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.