crates/veilvoice-video/src/size.rs
veilvoice-video · 732 lines · read the source here · or on GitHub
The size and frame rate a video is rendered at.
Why this is a module rather than two numbers
The renderer used to write 1280x720 at thirty frames a second and offer no way to say otherwise. Both numbers were reasonable defaults and neither was a choice anybody could make, which is the whole of the problem: somebody rendering a conversation to put on a screen wants it to look like the screen they are putting it on.
Getting that wrong is expensive in a way a wrong colour is not. Frames are rendered one file at a time before ffmpeg is asked for anything, so a choice made at the start decides how long the render takes, how much disk it wants while it runs, and whether it finishes at all. Plan::estimate exists so a front end can say that before starting rather than after.
The rules a size has to obey, and where they come from
Both dimensions have to be even. H.264 with yuv420p, which is what every player and every platform accepts, stores colour at half resolution in both directions, so an odd dimension has half a chroma sample in it. ffmpeg refuses outright: "width not divisible by 2". A person typing 1921 has made a typo rather than a request, so Size::new says so and Size::nearest_valid offers the size they meant.
There is a floor and a ceiling, and both are about somebody's typo rather than about taste. Under MIN_EDGE the subtitles are unreadable and the waveform is a line. Over MAX_EDGE, which is 8K, an extra digit turns a ten-minute render into one that fills the disk: at 4K a frame is about eight megabytes before compression, and at 60 frames a second that is half a gigabyte for every second of recording.
The default is the screen it will be watched on, when the screen will say
Choice::Monitor is the default and it is resolved late: the size is decided when the render starts, from the display the program is actually running on, rather than stored as a number that becomes wrong when somebody plugs in a different monitor.
Where nothing can say what the display is running at, and a command line on a machine with no display server is the ordinary case, it falls back to Preset::Hd1080 and says so. A guess about somebody's monitor presented as a detection would be worse than a stated default.
In plain words
How big the video is and how many pictures a second it has.
By default it matches the screen you are using, because that is usually the screen you are going to watch it on. You can pick 720p, 1080p, 1440p or 4K instead, or type your own size, and anything up to 60 frames a second.
Bigger and faster is not better here. The picture is a waveform, some circles and words on a flat background, none of which move quickly, so 4K at 60 costs a great deal of time and disk for something that looks the same as 1080p at 30 to almost everybody.
WHAT THIS FILE CONTAINS
732 lines defining 22 functions (20 public), 7 types and 7 constants. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
struct Sizeline 94 · A frame size in pixels, known to be one a render can actually use.enum Presetline 186 · The sizes offered by name.enum Choiceline 252 · What the user asked for, before anything has looked at the display.struct Resolvedline 268 · A size, and why it is that size.struct FrameRateline 375 · Frames per second, known to be inside the range a render allows.struct Planline 429 · A size and a frame rate together, with what they will cost.struct Estimateline 438 · What a render is going to want before it is started.
What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.
Size::newline 104 · A size, if it is one a video can be rendered at.Size::widthline 145 · Width in pixels.Size::heightline 150 · Height in pixels.Size::pixelsline 159 · How many pixels one frame holds.Size::labelline 167 · What ffmpeg wants after -s, and what a person reads in a menu.
reachesmatchingSize::geometryline 175 · Just the digits, for a command line argument.Preset::sizeline 207 · The size this preset means.Preset::nameline 222 · What a person calls it.Preset::keyline 232 · What it answers to on a command line.Choice::parseline 287 · Read a choice somebody typed.Choice::describeline 319 · What this reads as in a menu or a report.Choice::resolveline 338 · Turn a choice into a size, given what the display said.
reachesnearest_validFrameRate::newline 379 · A frame rate, if it is one a render allows.FrameRate::getline 389 · The number.FrameRate::parseline 405 · Read a frame rate somebody typed.human_bytesline 457 · A byte count, in the units a person reads.Plan::newline 476 · A plan.Plan::estimateline 485 · What rendering seconds of recording will want.
WHAT CALLS WHAT
The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_new(["Size::new<br/>line 104"])
n_nearest_valid["Size::nearest_valid<br/>line 136"]
n_width(["Size::width<br/>line 145"])
n_height(["Size::height<br/>line 150"])
n_pixels(["Size::pixels<br/>line 159"])
n_label(["Size::label<br/>line 167"])
n_geometry(["Size::geometry<br/>line 175"])
n_size(["Preset::size<br/>line 207"])
n_name(["Preset::name<br/>line 222"])
n_key(["Preset::key<br/>line 232"])
n_matching["Preset::matching<br/>line 242"]
n_parse(["Choice::parse<br/>line 287"])
n_describe(["Choice::describe<br/>line 319"])
n_resolve(["Choice::resolve<br/>line 338"])
n_new(["FrameRate::new<br/>line 379"])
n_get(["FrameRate::get<br/>line 389"])
n_parse(["FrameRate::parse<br/>line 405"])
n_default["FrameRate::default<br/>line 419"]
n_human_bytes(["human_bytes<br/>line 457"])
n_new(["Plan::new<br/>line 476"])
n_estimate(["Plan::estimate<br/>line 485"])
n_default["Plan::default<br/>line 509"]
n_label --> n_matching
n_resolve --> n_nearest_valid
click n_new href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L104" "open the source"
click n_nearest_valid href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L136" "open the source"
click n_width href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L145" "open the source"
click n_height href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L150" "open the source"
click n_pixels href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L159" "open the source"
click n_label href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L167" "open the source"
click n_geometry href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L175" "open the source"
click n_size href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L207" "open the source"
click n_name href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L222" "open the source"
click n_key href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L232" "open the source"
click n_matching href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L242" "open the source"
click n_parse href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L287" "open the source"
click n_describe href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L319" "open the source"
click n_resolve href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L338" "open the source"
click n_new href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L379" "open the source"
click n_get href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L389" "open the source"
click n_parse href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L405" "open the source"
click n_default href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L419" "open the source"
click n_human_bytes href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L457" "open the source"
click n_new href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L476" "open the source"
click n_estimate href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L485" "open the source"
click n_default href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-video/src/size.rs#L509" "open the source"
classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
class n_new,n_width,n_height,n_pixels,n_label,n_geometry,n_size,n_name,n_key,n_parse,n_describe,n_resolve,n_new,n_get,n_parse,n_human_bytes,n_new,n_estimate entry
classDef api fill:#1f2335,stroke:#7dcfff,color:#c0caf5
class n_nearest_valid,n_matching api
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_default,n_default helper
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
ITEMS
| Item | Line | Documentation |
|---|---|---|
MIN_EDGE pub const | 66 | The shortest edge a render may have, in pixels. |
MAX_EDGE pub const | 72 | The longest edge a render may have, in pixels. |
MAX_FPS pub const | 82 | The most frames a second a render may have. |
MIN_FPS pub const | 87 | The fewest frames a second a render may have. |
Size pub struct | 94 | A frame size in pixels, known to be one a render can actually use. |
Size::new pub fn | 104 | A size, if it is one a video can be rendered at. |
Size::nearest_valid pub fn | 136 | The nearest size that obeys every rule, for offering after a refusal. |
Size::width pub fn | 145 | Width in pixels. |
Size::height pub fn | 150 | Height in pixels. |
Size::pixels pub fn | 159 | How many pixels one frame holds. |
Size::label pub fn | 167 | What ffmpeg wants after -s, and what a person reads in a menu. |
Size::geometry pub fn | 175 | Just the digits, for a command line argument. |
Preset pub enum | 186 | The sizes offered by name. |
Preset::ALL pub const | 199 | Every preset, in the order a menu should list them. |
Preset::size pub fn | 207 | The size this preset means. |
Preset::name pub fn | 222 | What a person calls it. |
Preset::key pub fn | 232 | What it answers to on a command line. |
Preset::matching pub fn | 242 | The preset a size is, if it is one of them. |
Choice pub enum | 252 | What the user asked for, before anything has looked at the display. |
Resolved pub struct | 268 | A size, and why it is that size. |
Choice::KEYS pub const | 280 | What this answers to on a command line, in the order help should list it. |
Choice::parse pub fn | 287 | Read a choice somebody typed. |
Choice::describe pub fn | 319 | What this reads as in a menu or a report. |
Choice::resolve pub fn | 338 | Turn a choice into a size, given what the display said. |
FrameRate pub struct | 375 | Frames per second, known to be inside the range a render allows. |
FrameRate::new pub fn | 379 | A frame rate, if it is one a render allows. |
FrameRate::get pub fn | 389 | The number. |
FrameRate::OFFERED pub const | 398 | The rates offered by name, in the order a menu should list them. |
FrameRate::parse pub fn | 405 | Read a frame rate somebody typed. |
FrameRate::default fn | 419 | |
Plan pub struct | 429 | A size and a frame rate together, with what they will cost. |
Estimate pub struct | 438 | What a render is going to want before it is started. |
human_bytes pub fn | 457 | A byte count, in the units a person reads. |
Plan::new pub fn | 476 | A plan. |
Plan::estimate pub fn | 485 | What rendering seconds of recording will want. |
Plan::default fn | 509 |