mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Export: AV1 WebM refuses an explicit RGB + Alpha request (#166)
apply_output checked `channels: rgba` against the module before it applied `webmCodec`, and choosing AV1 then quietly dropped the channels to RGB. So `render --format webm --webm-codec av1 --channels rgba` (one renderQueue.add) succeeded and wrote an opaque AV1 stream. The codec options now apply before Channels, so the existing "has no alpha channel" error (how an unsupported channels request is already reported) refuses the combination; for WebM it names the codec: "AV1 WebM has no alpha channel (VP9 WebM has)". Choosing AV1 alone on an RGBA VP9 item still switches it to RGB, as changing the format does. Test: av1_webm_refuses_requested_alpha. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
247187872d
commit
c1e13b1f66
2 files changed
+27
-2
No files matched your search
@@ -219,6 +219,9 @@ fn apply_output(om: &mut OutputModule, templates: &RenderTemplates, roi: Option<
|
||||
let f = OutputFormat::from_name(f).ok_or_else(|| bad(cmd, FORMATS))?;
|
||||
om.set_format(f);
|
||||
}
|
||||
// Before Channels: the WebM codec decides whether alpha can be written, so an explicit
|
||||
// `channels: rgba` with `webmCodec: av1` is refused rather than dropped (#166).
|
||||
any |= apply_codec_options(om, p, cmd)?;
|
||||
if let Some(c) = str_p(p, "channels") {
|
||||
om.channels = match c.to_ascii_lowercase().replace([' ', '+'], "").as_str() {
|
||||
"rgb" => Channels::Rgb,
|
||||
@@ -227,7 +230,11 @@ fn apply_output(om: &mut OutputModule, templates: &RenderTemplates, roi: Option<
|
||||
_ => return Err(bad(cmd, "channels: rgb|rgba|alpha")),
|
||||
};
|
||||
if om.channels == Channels::Rgba && !om.supports_alpha() {
|
||||
return Err(bad(cmd, format!("{} has no alpha channel", om.format.label())));
|
||||
let what = match om.format {
|
||||
OutputFormat::WebM => format!("{} WebM has no alpha channel (VP9 WebM has)", om.webm_codec.label()),
|
||||
f => format!("{} has no alpha channel", f.label()),
|
||||
};
|
||||
return Err(bad(cmd, what));
|
||||
}
|
||||
}
|
||||
if let Some(c) = str_p(p, "color").or(str_p(p, "alphaMode")) {
|
||||
@@ -237,7 +244,6 @@ fn apply_output(om: &mut OutputModule, templates: &RenderTemplates, roi: Option<
|
||||
_ => return Err(bad(cmd, "color: straight|premultiplied")),
|
||||
};
|
||||
}
|
||||
any |= apply_codec_options(om, p, cmd)?;
|
||||
if let Some(q) = f_p(p, "quality") {
|
||||
om.quality = q.clamp(1.0, 100.0) as u8;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,25 @@ fn output_to_keeps_a_format_that_writes_the_extension() {
|
||||
assert_eq!((&r["output"]["format"], &r["outputModuleSummary"]), (&json!("Hevc"), &a["outputModuleSummary"]), "{r}");
|
||||
}
|
||||
|
||||
/// An explicit RGB + Alpha request with the AV1 WebM codec (which has no alpha) is refused, not
|
||||
/// silently rendered opaque (#166). Without `channels`, AV1 WebM renders RGB as before.
|
||||
#[test]
|
||||
fn av1_webm_refuses_requested_alpha() {
|
||||
let mut s = session();
|
||||
let n = s.project.render_queue.len();
|
||||
let e = s.execute("renderQueue.add", json!({"format": "webm", "webmCodec": "av1", "channels": "rgba"})).unwrap_err().to_string();
|
||||
assert!(e.contains("AV1 WebM has no alpha channel"), "{e}");
|
||||
assert_eq!(s.project.render_queue.len(), n, "nothing queued");
|
||||
let a = s.execute("renderQueue.add", json!({"format": "webm", "channels": "rgba"})).unwrap();
|
||||
let e = s.execute("renderQueue.setOutputModule", json!({"item": a["item"], "webmCodec": "av1", "channels": "rgba"})).unwrap_err().to_string();
|
||||
assert!(e.contains("AV1 WebM has no alpha channel"), "{e}");
|
||||
let om = &s.project.render_queue.last().unwrap().output;
|
||||
assert_eq!((om.webm_codec, om.channels), (WebmVideoCodec::Vp9, Channels::Rgba), "unchanged");
|
||||
s.execute("renderQueue.add", json!({"format": "webm", "webmCodec": "av1"})).unwrap();
|
||||
let om = &s.project.render_queue.last().unwrap().output;
|
||||
assert_eq!((om.webm_codec, om.channels), (WebmVideoCodec::Av1, Channels::Rgb));
|
||||
}
|
||||
|
||||
/// A `comp` that names no composition says so, rather than "no active composition" (#155).
|
||||
#[test]
|
||||
fn an_unknown_comp_is_named_in_the_error() {
|
||||
|
||||
Reference in new issue
Block a user