Enforce Dolby Vision profile policy (#61)
This commit was merged in pull request #61.
This commit is contained in:
@@ -2,8 +2,8 @@ use arr_parse::{LanguageMarker, NameClaims};
|
||||
|
||||
use crate::{
|
||||
lang::{is_resolved_portuguese, language_of_marker},
|
||||
Language, MovieOverrides, Policy, ProbedMedia, RequiredAudio, Resolution, Rule, Source,
|
||||
Verdict,
|
||||
HdrFormat, Language, MovieOverrides, Policy, ProbedMedia, RequiredAudio, Resolution, Rule,
|
||||
Source, Verdict,
|
||||
};
|
||||
|
||||
/// The evidence available while evaluating a candidate.
|
||||
@@ -105,9 +105,10 @@ pub fn evaluate(
|
||||
original_language,
|
||||
candidate,
|
||||
};
|
||||
let rules: [&dyn PolicyRule; 4] = [
|
||||
let rules: [&dyn PolicyRule; 5] = [
|
||||
&ResolutionRule,
|
||||
&SourceRule,
|
||||
&HdrRule,
|
||||
&DubBlacklistRule,
|
||||
&RequiredAudioRule,
|
||||
];
|
||||
@@ -200,6 +201,38 @@ impl PolicyRule for SourceRule {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies Dolby Vision profile policy using post-download probe evidence.
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct HdrRule;
|
||||
|
||||
impl PolicyRule for HdrRule {
|
||||
fn evaluate(&self, context: &EvaluationContext<'_>) -> RuleEvaluation {
|
||||
let Candidate::PostDownload(media) = context.candidate else {
|
||||
return RuleEvaluation::Unknown(RuleKind::DolbyVisionProfile);
|
||||
};
|
||||
let HdrFormat::DolbyVision(profile) = media.hdr else {
|
||||
return RuleEvaluation::Pass(RuleKind::DolbyVisionProfile);
|
||||
};
|
||||
|
||||
let rejected = context
|
||||
.policy
|
||||
.hdr_rules
|
||||
.rejected_dolby_vision_profiles
|
||||
.iter()
|
||||
.any(|blocked| {
|
||||
blocked.profile == profile.profile
|
||||
&& blocked.compatibility_id.is_none_or(|compatibility_id| {
|
||||
profile.compatibility_id == Some(compatibility_id)
|
||||
})
|
||||
});
|
||||
if rejected {
|
||||
RuleEvaluation::HardFail(Rule::DolbyVisionProfile(profile))
|
||||
} else {
|
||||
RuleEvaluation::Pass(RuleKind::DolbyVisionProfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The one language expression from `DESIGN.md` §5.2:
|
||||
///
|
||||
/// ```text
|
||||
@@ -363,7 +396,9 @@ mod tests {
|
||||
use arr_parse::{NameClaims, Resolution as ClaimedResolution, Source as ClaimedSource};
|
||||
|
||||
use super::*;
|
||||
use crate::{AudioTrack, HdrFormat, HdrRules, PolicyId, RequiredAudio, SubtitleTrack};
|
||||
use crate::{
|
||||
AudioTrack, DolbyVisionProfile, HdrFormat, HdrRules, PolicyId, RequiredAudio, SubtitleTrack,
|
||||
};
|
||||
|
||||
fn en() -> Language {
|
||||
Language::Other("en".to_owned())
|
||||
@@ -378,7 +413,16 @@ mod tests {
|
||||
required_audio: RequiredAudio::OriginalLanguage,
|
||||
dub_blacklist: vec![Language::PortugueseBrazil],
|
||||
hdr_rules: HdrRules {
|
||||
rejected_dolby_vision_profiles: Vec::new(),
|
||||
rejected_dolby_vision_profiles: vec![
|
||||
DolbyVisionProfile {
|
||||
profile: 5,
|
||||
compatibility_id: None,
|
||||
},
|
||||
DolbyVisionProfile {
|
||||
profile: 7,
|
||||
compatibility_id: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
size_bands: BTreeMap::new(),
|
||||
resolution_preference: vec![Resolution::R2160p, Resolution::R1080p],
|
||||
@@ -470,6 +514,7 @@ mod tests {
|
||||
vec![
|
||||
RuleEvaluation::Unknown(RuleKind::Resolution),
|
||||
RuleEvaluation::Unknown(RuleKind::Source),
|
||||
RuleEvaluation::Unknown(RuleKind::DolbyVisionProfile),
|
||||
RuleEvaluation::Unknown(RuleKind::DubBlacklist),
|
||||
RuleEvaluation::Unknown(RuleKind::RequiredAudio),
|
||||
]
|
||||
@@ -648,6 +693,81 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dolby_vision_profile_5_is_rejected() {
|
||||
assert_dolby_vision_verdict(&policy(), 5, None, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dolby_vision_profile_7_is_rejected() {
|
||||
assert_dolby_vision_verdict(&policy(), 7, Some(6), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dolby_vision_profile_8_1_is_accepted() {
|
||||
assert_dolby_vision_verdict(&policy(), 8, Some(1), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compatibility_specific_rule_matches_only_that_id() {
|
||||
let mut policy = policy();
|
||||
policy
|
||||
.hdr_rules
|
||||
.rejected_dolby_vision_profiles
|
||||
.push(DolbyVisionProfile {
|
||||
profile: 8,
|
||||
compatibility_id: Some(2),
|
||||
});
|
||||
|
||||
assert_dolby_vision_verdict(&policy, 8, Some(2), true);
|
||||
assert_dolby_vision_verdict(&policy, 8, Some(1), false);
|
||||
}
|
||||
|
||||
fn assert_dolby_vision_verdict(
|
||||
policy: &Policy,
|
||||
profile: u8,
|
||||
compatibility_id: Option<u8>,
|
||||
rejected: bool,
|
||||
) {
|
||||
let mut media = probed(Resolution::R2160p, Some(Source::WebDl));
|
||||
let profile = DolbyVisionProfile {
|
||||
profile,
|
||||
compatibility_id,
|
||||
};
|
||||
media.hdr = HdrFormat::DolbyVision(profile);
|
||||
|
||||
let report = evaluate(
|
||||
policy,
|
||||
&MovieOverrides::default(),
|
||||
&en(),
|
||||
Candidate::PostDownload(&media),
|
||||
);
|
||||
let expected = if rejected {
|
||||
Verdict::Rejected(Rule::DolbyVisionProfile(profile))
|
||||
} else {
|
||||
Verdict::Eligible
|
||||
};
|
||||
|
||||
assert_eq!(report.verdict, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_grab_dolby_vision_claim_stays_unknown() {
|
||||
let claims = arr_parse::parse("Movie.2024.2160p.WEB-DL.DV-GROUP");
|
||||
let report = evaluate(
|
||||
&policy(),
|
||||
&MovieOverrides::default(),
|
||||
&en(),
|
||||
Candidate::PreGrab(&claims),
|
||||
);
|
||||
|
||||
assert_eq!(report.verdict, Verdict::Eligible);
|
||||
assert_eq!(
|
||||
report.rules[2],
|
||||
RuleEvaluation::Unknown(RuleKind::DolbyVisionProfile)
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FixedRule {
|
||||
evaluation: RuleEvaluation,
|
||||
@@ -929,7 +1049,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(report.verdict, Verdict::Eligible);
|
||||
assert_eq!(
|
||||
report.rules[3],
|
||||
report.rules[4],
|
||||
RuleEvaluation::Unknown(RuleKind::RequiredAudio)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user