MXVK Vulkan Framework 0.35.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
python_example Namespace Reference

Functions

 main ()
 make_frame (x_coordinates, y_coordinates, frame_index, frame_count)
 parse_arguments ()
 validate_arguments (args)

Function Documentation

◆ main()

main ( void )

Definition at line 72 of file python_example.py.

72def main():
73 args = parse_arguments()
74 validate_arguments(args)
75 args.output.parent.mkdir(parents=True, exist_ok=True)
76
77 encoders = mxwrite_ext.available_video_encoders()
78 matching_encoders = [encoder for encoder in encoders if encoder.name == args.codec]
79 print(f"MXWrite reported {len(encoders)} video encoder(s).")
80 if matching_encoders:
81 encoder = matching_encoders[0]
82 mode = "hardware" if encoder.hardware else "software"
83 print(f"Using {encoder.name} ({encoder.long_name}, {mode}).")
84 options = mxwrite_ext.video_encoder_options(encoder.name)
85 print(f"The encoder exposes {len(options)} configurable option(s).")
86 elif args.codec not in {
87 "auto",
88 "software",
89 "cpu",
90 "x264",
91 "h264",
92 "hevc",
93 "h265",
94 "nvenc",
95 }:
96 names = ", ".join(encoder.name for encoder in encoders[:12])
97 raise SystemExit(
98 f"Requested encoder '{args.codec}' is unavailable. "
99 f"Available encoders include: {names}"
100 )
101
102 encode_options = mxwrite_ext.EncodeOptions()
103 encode_options.codec = args.codec
104 encode_options.preset = args.preset
105 encode_options.crf = args.crf
106 encode_options.block_when_full = True
107
108 writer = mxwrite_ext.Writer()
109 open_method = writer.open_ts if args.explicit_pts else writer.open
110 if not open_method(
111 str(args.output), args.width, args.height, float(args.fps), encode_options
112 ):
113 raise SystemExit(f"MXWrite could not open {args.output}")
114
115 x_coordinates = np.linspace(0.0, 1.0, args.width, dtype=np.float32)[None, :]
116 y_coordinates = np.linspace(0.0, 1.0, args.height, dtype=np.float32)[:, None]
117
118 try:
119 for frame_index in range(args.frames):
120 frame = make_frame(
121 x_coordinates, y_coordinates, frame_index, args.frames
122 )
123 if args.explicit_pts:
124 writer.write_at_pts(frame, frame_index)
125 else:
126 writer.write(frame)
127 finally:
128 writer.close()
129
130 frame_count = writer.get_frame_count()
131 duration = writer.get_duration()
132 byte_count = writer.get_bytes_written()
133 file_size = args.output.stat().st_size if args.output.is_file() else 0
134 expected_duration = args.frames / args.fps
135
136 if frame_count != args.frames:
137 raise SystemExit(f"Expected {args.frames} frames, but MXWrite reported {frame_count}.")
138 if not math.isclose(
139 duration, expected_duration, rel_tol=0.0, abs_tol=1.0 / args.fps
140 ):
141 raise SystemExit(
142 f"Expected about {expected_duration:.3f}s, "
143 f"but MXWrite reported {duration:.3f}s."
144 )
145 if file_size == 0:
146 raise SystemExit(f"MXWrite did not create a non-empty file at {args.output}.")
147
148 print(
149 f"PASS: wrote {frame_count} frames, {duration:.3f}s, "
150 f"{file_size} filesystem bytes to {args.output}"
151 )
152 print(f"MXWrite's muxer byte counter reported {byte_count} bytes.")
153
154
Definition main.py:1

◆ make_frame()

make_frame ( x_coordinates,
y_coordinates,
frame_index,
frame_count )

Definition at line 52 of file python_example.py.

52def make_frame(x_coordinates, y_coordinates, frame_index, frame_count):
53 phase = 2.0 * math.pi * frame_index / frame_count
54 x_wave = np.sin(x_coordinates * 2.0 * math.pi + phase)
55 y_wave = np.cos(y_coordinates * 2.0 * math.pi - phase * 1.7)
56 diagonal = np.sin(
57 (x_coordinates + y_coordinates) * 3.0 * math.pi + phase * 2.3
58 )
59
60 frame = np.empty(
61 (y_coordinates.shape[0], x_coordinates.shape[1], 4), dtype=np.uint8
62 )
63 frame[:, :, 0] = np.clip((x_wave + 1.0) * 127.5, 0, 255).astype(np.uint8)
64 frame[:, :, 1] = np.clip((y_wave + 1.0) * 127.5, 0, 255).astype(np.uint8)
65 frame[:, :, 2] = np.clip((diagonal + 1.0) * 127.5, 0, 255).astype(
66 np.uint8
67 )
68 frame[:, :, 3] = 255
69 return frame
70
71

◆ parse_arguments()

parse_arguments ( )

Definition at line 21 of file python_example.py.

21def parse_arguments():
22 parser = argparse.ArgumentParser(
23 description="Generate an animated test video with the MXWrite Python module."
24 )
25 parser.add_argument("--output", type=Path, default=Path("mxwrite-python-example.mp4"))
26 parser.add_argument("--width", type=int, default=320)
27 parser.add_argument("--height", type=int, default=180)
28 parser.add_argument("--fps", type=float, default=30.0)
29 parser.add_argument("--frames", type=int, default=90)
30 parser.add_argument("--codec", default="libx264")
31 parser.add_argument("--preset", default="veryfast")
32 parser.add_argument("--crf", type=int, default=20)
33 parser.add_argument(
34 "--explicit-pts",
35 action="store_true",
36 help="Exercise open_ts() and write_at_pts() instead of sequential writes.",
37 )
38 return parser.parse_args()
39
40

◆ validate_arguments()

validate_arguments ( args)

Definition at line 41 of file python_example.py.

41def validate_arguments(args):
42 if args.width <= 0 or args.height <= 0:
43 raise SystemExit("Width and height must be positive.")
44 if args.fps <= 0.0:
45 raise SystemExit("FPS must be positive.")
46 if args.frames <= 0:
47 raise SystemExit("Frame count must be positive.")
48 if not 0 <= args.crf <= 51:
49 raise SystemExit("CRF must be between 0 and 51.")
50
51