Skip to content

Commit f259c44

Browse files
committed
Implement zerocopy scene detection for Vapoursynth inputs
1 parent 4ebdcd0 commit f259c44

File tree

3 files changed

+44
-35
lines changed

3 files changed

+44
-35
lines changed

Cargo.lock

+3-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

av1an-core/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ crossbeam-channel = "0.5.1"
4040
crossbeam-utils = "0.8.5"
4141
textwrap = "0.16.0"
4242
path_abs = "0.5.1"
43-
av-scenechange = { version = "0.10.0", default-features = false }
43+
av-scenechange = { version = "0.11.0", default-features = false, features = [
44+
"vapoursynth",
45+
] }
4446
y4m = "0.8.0"
4547
thiserror = "1.0.30"
4648
paste = "1.0.5"

av1an-core/src/scene_detect.rs

+38-32
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::thread;
44

55
use ansi_term::Style;
66
use anyhow::bail;
7+
use av_scenechange::decoder::Decoder;
8+
use av_scenechange::vapoursynth::VapoursynthDecoder;
79
use av_scenechange::{detect_scene_changes, DetectionOptions, SceneDetectionSpeed};
810
use ffmpeg::format::Pixel;
911
use itertools::Itertools;
@@ -147,7 +149,7 @@ pub fn scene_detect(
147149
frame_limit,
148150
callback.as_ref().map(|cb| cb as &dyn Fn(usize, usize)),
149151
)
150-
};
152+
}?;
151153
if let Some(limit) = frame_limit {
152154
if limit != sc_result.frame_count {
153155
bail!(
@@ -206,7 +208,7 @@ fn build_decoder(
206208
sc_scaler: &str,
207209
sc_pix_format: Option<Pixel>,
208210
sc_downscale_height: Option<usize>,
209-
) -> anyhow::Result<(y4m::Decoder<impl Read>, usize)> {
211+
) -> anyhow::Result<(Decoder<impl Read>, usize)> {
210212
let bit_depth;
211213
let filters: SmallVec<[String; 4]> = match (sc_downscale_height, sc_pix_format) {
212214
(Some(sdh), Some(spf)) => into_smallvec![
@@ -225,53 +227,57 @@ fn build_decoder(
225227
(None, None) => smallvec![],
226228
};
227229

228-
let decoder = y4m::Decoder::new(match input {
230+
let decoder = match input {
229231
Input::VapourSynth(path) => {
230232
bit_depth = crate::vapoursynth::bit_depth(path.as_ref())?;
231-
let vspipe = Command::new("vspipe")
232-
.arg("-c")
233-
.arg("y4m")
234-
.arg(path)
235-
.arg("-")
236-
.stdin(Stdio::null())
237-
.stdout(Stdio::piped())
238-
.stderr(Stdio::null())
239-
.spawn()?
240-
.stdout
241-
.unwrap();
242233

243234
if !filters.is_empty() {
244-
Command::new("ffmpeg")
245-
.stdin(vspipe)
246-
.args(["-i", "pipe:", "-f", "yuv4mpegpipe", "-strict", "-1"])
247-
.args(filters)
235+
let vspipe = Command::new("vspipe")
236+
.arg("-c")
237+
.arg("y4m")
238+
.arg(path)
248239
.arg("-")
240+
.stdin(Stdio::null())
249241
.stdout(Stdio::piped())
250242
.stderr(Stdio::null())
251243
.spawn()?
252244
.stdout
253-
.unwrap()
245+
.unwrap();
246+
Decoder::Y4m(y4m::Decoder::new(
247+
Command::new("ffmpeg")
248+
.stdin(vspipe)
249+
.args(["-i", "pipe:", "-f", "yuv4mpegpipe", "-strict", "-1"])
250+
.args(filters)
251+
.arg("-")
252+
.stdout(Stdio::piped())
253+
.stderr(Stdio::null())
254+
.spawn()?
255+
.stdout
256+
.unwrap(),
257+
)?)
254258
} else {
255-
vspipe
259+
Decoder::Vapoursynth(VapoursynthDecoder::new(path.as_ref())?)
256260
}
257261
}
258262
Input::Video(path) => {
259263
let input_pix_format = crate::ffmpeg::get_pixel_format(path.as_ref())
260264
.unwrap_or_else(|e| panic!("FFmpeg failed to get pixel format for input video: {e:?}"));
261265
bit_depth = encoder.get_format_bit_depth(sc_pix_format.unwrap_or(input_pix_format))?;
262-
Command::new("ffmpeg")
263-
.args(["-r", "1", "-i"])
264-
.arg(path)
265-
.args(filters.as_ref())
266-
.args(["-f", "yuv4mpegpipe", "-strict", "-1", "-"])
267-
.stdin(Stdio::null())
268-
.stdout(Stdio::piped())
269-
.stderr(Stdio::null())
270-
.spawn()?
271-
.stdout
272-
.unwrap()
266+
Decoder::Y4m(y4m::Decoder::new(
267+
Command::new("ffmpeg")
268+
.args(["-r", "1", "-i"])
269+
.arg(path)
270+
.args(filters.as_ref())
271+
.args(["-f", "yuv4mpegpipe", "-strict", "-1", "-"])
272+
.stdin(Stdio::null())
273+
.stdout(Stdio::piped())
274+
.stderr(Stdio::null())
275+
.spawn()?
276+
.stdout
277+
.unwrap(),
278+
)?)
273279
}
274-
})?;
280+
};
275281

276282
Ok((decoder, bit_depth))
277283
}

0 commit comments

Comments
 (0)