Skip to content

Conversation

BoatsMcGee
Copy link
Collaborator

Resolves #1102

Target Metric VMAF is now only validated if the user supplies --target-quality or specifies at least 1 Zone where Target Quality is enabled. Zones are now validated after parsing so any issues with a specified Target Metric can be addressed in the new function.

I initially wanted to cache the validation as I planned to validate each Zone as it's parsed but instead went with parsing all Zones, then doing a filter check for the exact condition(s) that require validation. At worst, XPSNR could be validated up to 3 times, 2 for everything else. With the function only executing up to a maximum of 3 times, I decided to forgo complicating things with lazy loading and caching.

Thanks,
- Boats M.

Copy link

codecov bot commented Jul 30, 2025

Codecov Report

❌ Patch coverage is 7.47664% with 99 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.98%. Comparing base (1ad7e86) to head (b189144).
⚠️ Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
av1an-core/src/settings.rs 4.54% 63 Missing ⚠️
av1an-core/src/zones.rs 10.00% 36 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1103      +/-   ##
==========================================
- Coverage   62.31%   61.98%   -0.34%     
==========================================
  Files          23       23              
  Lines        6303     6410     +107     
==========================================
+ Hits         3928     3973      +45     
- Misses       2375     2437      +62     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Khaoklong51
Copy link

fix confirmed

@shssoichiro shssoichiro requested a review from Copilot August 10, 2025 01:04
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue where FFmpeg VMAF validation was being performed even when Target Quality was not used. The changes ensure that Target Metric validation only occurs when --target-quality is supplied or when at least one Zone has Target Quality enabled.

  • Extracted metric validation logic into reusable methods in EncodeArgs
  • Added a new validate_zones function to validate Target Metrics used in zones
  • Moved zone validation to occur after parsing all zones

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
av1an-core/src/zones.rs Adds new validate_zones function that conditionally validates Target Metrics based on zone configurations
av1an-core/src/settings.rs Refactors metric validation logic into separate methods and adds conditional validation for global target quality
av1an-core/src/context.rs Integrates zone validation after zone parsing

.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::SSIMULACRA2))
.is_some()
}) {
args.validate_ssimululacra2()?;
Copy link
Preview

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method name 'validate_ssimululacra2' contains a typo - should be 'validate_ssimulacra2' (missing 'u' in 'ssimulacra')

Suggested change
args.validate_ssimululacra2()?;
args.validate_ssimulacra2()?;

Copilot uses AI. Check for mistakes.

}

#[inline]
pub fn validate_ssimululacra2(&self) -> anyhow::Result<()> {
Copy link
Preview

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function name 'validate_ssimululacra2' contains a typo - should be 'validate_ssimulacra2' (missing 'u' in 'ssimulacra')

Suggested change
pub fn validate_ssimululacra2(&self) -> anyhow::Result<()> {
pub fn validate_ssimulacra2(&self) -> anyhow::Result<()> {

Copilot uses AI. Check for mistakes.

if self.target_quality.target.is_some() {
match self.target_quality.metric {
TargetMetric::VMAF => validate_libvmaf()?,
TargetMetric::SSIMULACRA2 => self.validate_ssimululacra2()?,
Copy link
Preview

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method call 'validate_ssimululacra2' contains a typo - should be 'validate_ssimulacra2' (missing 'u' in 'ssimulacra')

Suggested change
TargetMetric::SSIMULACRA2 => self.validate_ssimululacra2()?,
TargetMetric::SSIMULACRA2 => self.validate_ssimulacra2()?,

Copilot uses AI. Check for mistakes.

Comment on lines 26 to 63
pub(crate) fn validate_zones(args: &EncodeArgs, zones: &[Scene]) -> anyhow::Result<()> {
if zones.is_empty() {
// No zones to validate
return Ok(());
}

// Using VMAF, validate libvmaf
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::VMAF))
.is_some()
}) {
validate_libvmaf()?;
}

// Using SSIMULACRA2, validate SSIMULACRA2
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::SSIMULACRA2))
.is_some()
}) {
args.validate_ssimululacra2()?;
}

// Using butteraugli-Inf, validate butteraugli-Inf
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::ButteraugliINF))
.is_some()
}) {
args.validate_butteraugli_inf()?;
}
Copy link
Preview

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation logic has significant code duplication across all metric checks. Consider extracting a helper function that takes a predicate to reduce repetition and improve maintainability.

Suggested change
pub(crate) fn validate_zones(args: &EncodeArgs, zones: &[Scene]) -> anyhow::Result<()> {
if zones.is_empty() {
// No zones to validate
return Ok(());
}
// Using VMAF, validate libvmaf
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::VMAF))
.is_some()
}) {
validate_libvmaf()?;
}
// Using SSIMULACRA2, validate SSIMULACRA2
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::SSIMULACRA2))
.is_some()
}) {
args.validate_ssimululacra2()?;
}
// Using butteraugli-Inf, validate butteraugli-Inf
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == TargetMetric::ButteraugliINF))
.is_some()
}) {
args.validate_butteraugli_inf()?;
}
fn validate_metric_in_zones<F>(
zones: &[Scene],
metric: TargetMetric,
validate_fn: F,
) -> anyhow::Result<()>
where
F: Fn() -> anyhow::Result<()>,
{
if zones.iter().any(|zone| {
zone.zone_overrides
.as_ref()
.and_then(|ovr| ovr.target_quality.as_ref())
.and_then(|tq| tq.target.as_ref().filter(|_| tq.metric == metric))
.is_some()
}) {
validate_fn()?;
}
Ok(())
}
pub(crate) fn validate_zones(args: &EncodeArgs, zones: &[Scene]) -> anyhow::Result<()> {
if zones.is_empty() {
// No zones to validate
return Ok(());
}
// Using VMAF, validate libvmaf
validate_metric_in_zones(zones, TargetMetric::VMAF, || validate_libvmaf())?;
// Using SSIMULACRA2, validate SSIMULACRA2
validate_metric_in_zones(zones, TargetMetric::SSIMULACRA2, || args.validate_ssimululacra2())?;
// Using butteraugli-Inf, validate butteraugli-Inf
validate_metric_in_zones(zones, TargetMetric::ButteraugliINF, || args.validate_butteraugli_inf())?;

Copilot uses AI. Check for mistakes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have done this the Rust Idiomatic way in the first place.

@shssoichiro
Copy link
Member

The comments from copilot seem valid, if you wouldn't mind fixing those, then we can merge.

Add ensure_chunk_method to consolidate ChunkMethod checks
Add generic tq_used_and functions to consolidate condition checks for Zones Target Quality validation
@shssoichiro shssoichiro merged commit 8786a18 into rust-av:master Aug 11, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

av1an failed to run if ffmpeg not compile with --enable-libvmaf
3 participants