mod support;
use mediadecode::{Received, Sent, Timebase, decoder::ScaledOutputCapability};
use mediadecode_ffmpeg::{
DecoderLimits, OwnedVideoFrame, PacketLimits, empty_owned_video_frame,
owned_video_packet_from_ffmpeg_in,
};
fn probe_scaled_output(
path: &std::path::Path,
request: (u32, u32),
) -> (
ScaledOutputCapability,
ScaledOutputCapability,
OwnedVideoFrame,
) {
use mediadecode::decoder::VideoStreamDecoder;
let mut input = ffmpeg_next::format::input(path).expect("open the fixture");
let stream = input
.streams()
.best(ffmpeg_next::media::Type::Video)
.expect("the fixture has a video stream");
let stream_index = stream.index();
let tb = stream.time_base();
let time_base = Timebase::new(
tb.numerator(),
core::num::NonZeroI32::new(tb.denominator().max(1)).expect("a non-zero denominator"),
);
let mut decoder = mediadecode_ffmpeg::FfmpegOwnedVideoStreamDecoder::open(
stream.parameters(),
time_base,
DecoderLimits::default(),
)
.expect("open the video decoder");
let before = decoder.scaled_output_capability();
let after = decoder.request_scaled_output(request);
let mut frame: OwnedVideoFrame = empty_owned_video_frame();
for (index, (s, av_packet)) in input.packets().enumerate() {
if s.index() != stream_index {
continue;
}
let Some(packet) =
owned_video_packet_from_ffmpeg_in(&av_packet, time_base, PacketLimits::default())
.expect("a wrappable video payload")
else {
continue;
};
if decoder.send_packet(&packet).expect("send packet") != Sent::Accepted {
continue;
}
if let Received::Frame = decoder.receive_frame(&mut frame).expect("receive frame") {
return (before, after, frame);
}
assert!(index < 64, "no frame within the first 64 packets");
}
panic!("the input ended before a frame was produced");
}
#[test]
fn hardware_probed_session_refuses_scaled_output_and_delivers_full_size() {
let Some(corpus) = support::Corpus::new() else {
return;
};
let path = corpus.multi_track_mkv();
let (before, after, frame) = probe_scaled_output(&path, (32, 32));
assert_eq!(before, ScaledOutputCapability::Unsupported);
assert_eq!(after, ScaledOutputCapability::Unsupported);
assert_eq!(frame.width(), 160);
assert_eq!(frame.height(), 120);
}
#[test]
fn software_only_session_refuses_scaled_output_and_delivers_full_size() {
let Some(corpus) = support::Corpus::new() else {
return;
};
let path = corpus.software_only_video();
let (before, after, frame) = probe_scaled_output(&path, (16, 16));
assert_eq!(before, ScaledOutputCapability::Unsupported);
assert_eq!(after, ScaledOutputCapability::Unsupported);
assert_eq!(frame.width(), 1280);
assert_eq!(frame.height(), 720);
}