mod fixtures;
use fixtures::*;
use ff_decode::{HardwareAccel, VideoDecoder};
#[test]
fn test_hardware_accel_none_explicitly() {
let decoder = VideoDecoder::open(&test_video_path())
.hardware_accel(HardwareAccel::None)
.build()
.expect("Failed to create decoder with HardwareAccel::None");
assert_eq!(
decoder.hardware_accel(),
HardwareAccel::None,
"Hardware acceleration should be None when explicitly disabled"
);
let mut decoder = decoder;
let frame = decoder.decode_one().expect("decode_one failed");
assert!(frame.is_some(), "Should decode a frame");
}
#[test]
fn test_hardware_accel_auto_fallback_to_software() {
let decoder = VideoDecoder::open(&test_video_path())
.hardware_accel(HardwareAccel::Auto)
.build()
.expect("Failed to create decoder with HardwareAccel::Auto");
let active_accel = decoder.hardware_accel();
assert!(
matches!(
active_accel,
HardwareAccel::None
| HardwareAccel::Nvdec
| HardwareAccel::Qsv
| HardwareAccel::VideoToolbox
| HardwareAccel::Vaapi
| HardwareAccel::Amf
),
"Auto mode should select a valid hardware accelerator or fall back to None, got {:?}",
active_accel
);
let mut decoder = decoder;
let frame = decoder.decode_one().expect("decode_one failed");
assert!(frame.is_some(), "Should decode a frame");
}
#[test]
#[ignore] fn test_hardware_accel_specific_unavailable() {
let result = VideoDecoder::open(&test_video_path())
.hardware_accel(HardwareAccel::Amf) .build();
match result {
Ok(decoder) => {
assert_eq!(
decoder.hardware_accel(),
HardwareAccel::Amf,
"When AMF is available, it should be active"
);
let mut decoder = decoder;
let frame = decoder.decode_one().expect("decode_one failed");
assert!(frame.is_some(), "Should decode a frame");
}
Err(err) => {
assert!(
matches!(err, ff_decode::DecodeError::HwAccelUnavailable { .. }),
"Error should be HwAccelUnavailable when specific accelerator is not available, got: {:?}",
err
);
}
}
}
#[test]
fn test_hardware_accel_builder_chain() {
let result = VideoDecoder::open(&test_video_path())
.output_format(ff_format::PixelFormat::Rgba)
.hardware_accel(HardwareAccel::None)
.thread_count(4)
.build();
assert!(
result.is_ok(),
"Builder chaining with hardware_accel should work"
);
let decoder = result.unwrap();
assert_eq!(
decoder.hardware_accel(),
HardwareAccel::None,
"Hardware acceleration should be None"
);
}
#[test]
fn test_hardware_accel_does_not_affect_software_decoding() {
let mut decoder_none = VideoDecoder::open(&test_video_path())
.hardware_accel(HardwareAccel::None)
.build()
.expect("Failed to create decoder with HardwareAccel::None");
let mut decoder_auto = VideoDecoder::open(&test_video_path())
.hardware_accel(HardwareAccel::Auto)
.build()
.expect("Failed to create decoder with HardwareAccel::Auto");
let frame_none = decoder_none
.decode_one()
.expect("decode_one failed for None")
.expect("Should have a frame");
let frame_auto = decoder_auto
.decode_one()
.expect("decode_one failed for Auto")
.expect("Should have a frame");
assert_eq!(
frame_none.width(),
frame_auto.width(),
"Frames should have same width"
);
assert_eq!(
frame_none.height(),
frame_auto.height(),
"Frames should have same height"
);
}
#[test]
fn test_hardware_accel_enum_name() {
assert_eq!(HardwareAccel::Auto.name(), "auto");
assert_eq!(HardwareAccel::None.name(), "none");
assert_eq!(HardwareAccel::Nvdec.name(), "nvdec");
assert_eq!(HardwareAccel::Qsv.name(), "qsv");
assert_eq!(HardwareAccel::Amf.name(), "amf");
assert_eq!(HardwareAccel::VideoToolbox.name(), "videotoolbox");
assert_eq!(HardwareAccel::Vaapi.name(), "vaapi");
}
#[test]
fn test_hardware_accel_is_specific() {
assert!(!HardwareAccel::Auto.is_specific());
assert!(!HardwareAccel::None.is_specific());
assert!(HardwareAccel::Nvdec.is_specific());
assert!(HardwareAccel::Qsv.is_specific());
assert!(HardwareAccel::Amf.is_specific());
assert!(HardwareAccel::VideoToolbox.is_specific());
assert!(HardwareAccel::Vaapi.is_specific());
}