Skip to content

Commit

Permalink
Revert "Remove support for DgDecNv (#796)"
Browse files Browse the repository at this point in the history
This reverts commit a946721.
  • Loading branch information
shssoichiro committed Jan 5, 2024
1 parent 75d2a5f commit 5f701e8
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Prerequisites:
Optional:

- [L-SMASH](https://github.com/AkarinVS/L-SMASH-Works) VapourSynth plugin for better chunking (recommended)
- [DGDecNV](https://www.rationalqm.us/dgdecnv/dgdecnv.html) Vapoursynth plugin for very fast and accurate chunking, `dgindexnv` executable needs to be present in system path and an NVIDIA GPU with CUVID
- [ffms2](https://github.com/FFMS/ffms2) VapourSynth plugin for better chunking
- [bestsource](https://github.com/vapoursynth/bestsource) Vapoursynth plugin for slow but accurate chunking
- [mkvmerge](https://mkvtoolnix.download/) to use mkvmerge instead of FFmpeg for file concatenation
Expand Down
7 changes: 5 additions & 2 deletions av1an-core/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Av1anContext {
// generated when vspipe is first called), so it's not worth adding all the extra complexity.
if (self.args.input.is_vapoursynth()
|| (self.args.input.is_video()
&& matches!(self.args.chunk_method, ChunkMethod::LSMASH | ChunkMethod::FFMS2 | ChunkMethod::BESTSOURCE)))
&& matches!(self.args.chunk_method, ChunkMethod::LSMASH | ChunkMethod::FFMS2 | ChunkMethod::DGDECNV | ChunkMethod::BESTSOURCE)))
&& !self.args.resume
{
self.vs_script = Some(match &self.args.input {
Expand Down Expand Up @@ -665,7 +665,10 @@ impl Av1anContext {
fn create_encoding_queue(&mut self, scenes: &[Scene]) -> anyhow::Result<Vec<Chunk>> {
let mut chunks = match &self.args.input {
Input::Video(_) => match self.args.chunk_method {
ChunkMethod::FFMS2 | ChunkMethod::LSMASH | ChunkMethod::BESTSOURCE => {
ChunkMethod::FFMS2
| ChunkMethod::LSMASH
| ChunkMethod::DGDECNV
| ChunkMethod::BESTSOURCE => {
let vs_script = self.vs_script.as_ref().unwrap().as_path();
self.create_video_queue_vs(scenes, vs_script)
}
Expand Down
2 changes: 2 additions & 0 deletions av1an-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ pub enum ChunkMethod {
FFMS2,
#[strum(serialize = "lsmash")]
LSMASH,
#[strum(serialize = "dgdecnv")]
DGDECNV,
#[strum(serialize = "bestsource")]
BESTSOURCE,
}
Expand Down
10 changes: 9 additions & 1 deletion av1an-core/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use crate::concat::ConcatMethod;
use crate::encoder::Encoder;
use crate::parse::valid_params;
use crate::target_quality::TargetQuality;
use crate::vapoursynth::{is_bestsource_installed, is_ffms2_installed, is_lsmash_installed};
use crate::vapoursynth::{
is_bestsource_installed, is_dgdecnv_installed, is_ffms2_installed, is_lsmash_installed,
};
use crate::vmaf::validate_libvmaf;
use crate::{ChunkMethod, ChunkOrdering, Input, ScenecutMethod, SplitMethod, Verbosity};

Expand Down Expand Up @@ -125,6 +127,12 @@ properly into a mkv file. Specify mkvmerge as the concatenation method by settin
"FFMS2 is not installed, but it was specified as the chunk method"
);
}
if self.chunk_method == ChunkMethod::DGDECNV && which::which("dgindexnv").is_err() {
ensure!(
is_dgdecnv_installed(),
"Either DGDecNV is not installed or DGIndexNV is not in system path, but it was specified as the chunk method"
);
}
if self.chunk_method == ChunkMethod::BESTSOURCE {
ensure!(
is_bestsource_installed(),
Expand Down
34 changes: 33 additions & 1 deletion av1an-core/src/vapoursynth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
use anyhow::{anyhow, bail};
use once_cell::sync::Lazy;
use path_abs::PathAbs;
use std::process::Command;
use vapoursynth::prelude::*;
use vapoursynth::video_info::VideoInfo;

Expand Down Expand Up @@ -45,6 +46,13 @@ pub fn is_ffms2_installed() -> bool {
*FFMS2_PRESENT
}

pub fn is_dgdecnv_installed() -> bool {
static DGDECNV_PRESENT: Lazy<bool> =
Lazy::new(|| VAPOURSYNTH_PLUGINS.contains("com.vapoursynth.dgdecodenv"));

*DGDECNV_PRESENT
}

pub fn is_bestsource_installed() -> bool {
static BESTSOURCE_PRESENT: Lazy<bool> =
Lazy::new(|| VAPOURSYNTH_PLUGINS.contains("com.vapoursynth.bestsource"));
Expand All @@ -57,6 +65,8 @@ pub fn best_available_chunk_method() -> ChunkMethod {
ChunkMethod::LSMASH
} else if is_ffms2_installed() {
ChunkMethod::FFMS2
} else if is_dgdecnv_installed() {
ChunkMethod::DGDECNV
} else if is_bestsource_installed() {
ChunkMethod::BESTSOURCE
} else {
Expand Down Expand Up @@ -194,12 +204,34 @@ pub fn create_vs_file(
match chunk_method {
ChunkMethod::FFMS2 => "ffindex",
ChunkMethod::LSMASH => "lwi",
ChunkMethod::DGDECNV => "dgi",
ChunkMethod::BESTSOURCE => "json",
_ => return Err(anyhow!("invalid chunk method")),
}
)))?;

if chunk_method == ChunkMethod::BESTSOURCE {
if chunk_method == ChunkMethod::DGDECNV {
// Run dgindexnv to generate the .dgi index file
let dgindexnv_output = temp.join("split").join("index.dgi");

Command::new("dgindexnv")
.arg("-h")
.arg("-i")
.arg(source)
.arg("-o")
.arg(&dgindexnv_output)
.output()?;

let dgindex_path = dgindexnv_output.canonicalize()?;
load_script.write_all(
format!(
"from vapoursynth import core\n\
core.max_cache_size=1024\n\
core.dgdecodenv.DGSource(source={dgindex_path:?}).set_output()"
)
.as_bytes(),
)?;
} else if chunk_method == ChunkMethod::BESTSOURCE {
load_script.write_all(
format!(
"from vapoursynth import core\n\
Expand Down
8 changes: 7 additions & 1 deletion av1an/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ fn version() -> &'static str {
* VapourSynth Plugins
systems.innocent.lsmas : {}
com.vapoursynth.ffms2 : {}
com.vapoursynth.dgdecodenv : {}
com.vapoursynth.bestsource : {}",
isfound(vapoursynth::is_lsmash_installed()),
isfound(vapoursynth::is_ffms2_installed()),
isfound(vapoursynth::is_dgdecnv_installed()),
isfound(vapoursynth::is_bestsource_installed())
)
}
Expand Down Expand Up @@ -334,6 +336,10 @@ pub struct CliOpts {
/// cause artifacts in the piped output). Slightly faster than lsmash for y4m input. Requires the ffms2 vapoursynth plugin to be
/// installed.
///
/// dgdecnv - Very fast, but only decodes AVC, HEVC, MPEG-2, and VC1. Does not require intermediate files.
/// Requires dgindexnv to be present in system path, NVIDIA GPU that support CUDA video decoding, and dgdecnv vapoursynth plugin
/// to be installed.
///
/// bestsource - Very slow but accurate. Linearly decodes input files, very slow. Does not require intermediate files, requires the BestSource vapoursynth plugin
/// to be installed.
///
Expand All @@ -349,7 +355,7 @@ pub struct CliOpts {
/// segment - Create chunks based on keyframes in the source. Not frame exact, as it can only split on keyframes in the source.
/// Requires intermediate files (which can be large).
///
/// Default: lsmash (if available), otherwise ffms2 (if available), otherwise bestsource (if available), otherwise hybrid.
/// Default: lsmash (if available), otherwise ffms2 (if available), otherwise DGDecNV (if available), otherwise bestsource (if available), otherwise hybrid.
#[clap(short = 'm', long, help_heading = "Encoding")]
pub chunk_method: Option<ChunkMethod>,

Expand Down
8 changes: 6 additions & 2 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@
Slightly faster than lsmash for y4m input. Requires the ffms2 vapoursynth plugin to
be installed.
dgdecnv - Very fast, but only decodes AVC, HEVC, MPEG-2, and VC1. Does not require intermediate files.
Requires dgindexnv to be present in system path, NVIDIA GPU that support CUDA video decoding, and dgdecnv vapoursynth plugin
to be installed.
bestsource - Very slow but accurate. Linearly decodes input files. Does not require intermediate files, requires the BestSource vapoursynth plugin
to be installed.
Expand All @@ -256,9 +260,9 @@
segment - Create chunks based on keyframes in the source. Not frame exact, as it can
only split on keyframes in the source. Requires intermediate files (which can be large).
Default: lsmash (if available), otherwise ffms2 (if available), otherwise bestsource (if available), otherwise hybrid.
Default: lsmash (if available), otherwise ffms2 (if available), otherwise DGDecNV (if available), otherwise bestsource (if available), otherwise hybrid.
[possible values: segment, select, ffms2, lsmash, bestsource, hybrid]
[possible values: segment, select, ffms2, lsmash, dgdecnv, bestsource, hybrid]
--chunk-order <CHUNK_ORDER>
The order in which av1an will encode chunks
Expand Down

0 comments on commit 5f701e8

Please sign in to comment.