use super::*;
use ffmpeg_next::ffi::AVColorRange;
#[test]
fn map_range_for_forces_full_for_every_yuvj_variant() {
let yuvj = [
PixelFormat::Yuvj411p,
PixelFormat::Yuvj420p,
PixelFormat::Yuvj422p,
PixelFormat::Yuvj440p,
PixelFormat::Yuvj444p,
];
let unspecified = AVColorRange::AVCOL_RANGE_UNSPECIFIED as i32;
let mpeg = AVColorRange::AVCOL_RANGE_MPEG as i32;
let jpeg = AVColorRange::AVCOL_RANGE_JPEG as i32;
for pf in &yuvj {
assert_eq!(
map_range_for(pf, unspecified),
ColorRange::Full,
"{pf:?} with UNSPECIFIED color_range must deliver Full"
);
assert_eq!(
map_range_for(pf, mpeg),
ColorRange::Full,
"{pf:?} is full-range by definition even if color_range says MPEG"
);
assert_eq!(map_range_for(pf, jpeg), ColorRange::Full);
}
}
#[test]
fn map_range_for_defers_for_non_yuvj() {
let unspecified = AVColorRange::AVCOL_RANGE_UNSPECIFIED as i32;
let jpeg = AVColorRange::AVCOL_RANGE_JPEG as i32;
let mpeg = AVColorRange::AVCOL_RANGE_MPEG as i32;
assert_eq!(
map_range_for(&PixelFormat::Yuv420p, unspecified),
ColorRange::Unspecified
);
assert_eq!(map_range_for(&PixelFormat::Yuv420p, jpeg), ColorRange::Full);
assert_eq!(
map_range_for(&PixelFormat::Yuv420p, mpeg),
ColorRange::Limited
);
assert_eq!(
map_range_for(&PixelFormat::Rgb24, unspecified),
ColorRange::Unspecified
);
assert_eq!(
map_range_for(&PixelFormat::Rgba, unspecified),
ColorRange::Unspecified
);
}
#[test]
fn is_yuvj_covers_exactly_the_five_variants() {
for pf in &[
PixelFormat::Yuvj411p,
PixelFormat::Yuvj420p,
PixelFormat::Yuvj422p,
PixelFormat::Yuvj440p,
PixelFormat::Yuvj444p,
] {
assert!(is_yuvj(pf), "{pf:?} should be recognized as yuvj");
}
for pf in &[
PixelFormat::Yuv411p,
PixelFormat::Yuv420p,
PixelFormat::Yuv422p,
PixelFormat::Yuv440p,
PixelFormat::Yuv444p,
PixelFormat::Nv12,
PixelFormat::Rgb24,
PixelFormat::Gray8,
] {
assert!(!is_yuvj(pf), "{pf:?} must not be classified yuvj");
}
}
#[test]
fn yuvj420p_unspecified_range_delivers_full() {
let mut frame = ffmpeg_next::frame::Video::new(ffmpeg_next::format::Pixel::YUVJ420P, 64, 48);
unsafe {
(*frame.as_mut_ptr()).color_range = AVColorRange::AVCOL_RANGE_UNSPECIFIED;
}
let out = video_frame_from(&frame, Timebase::default())
.expect("YUVJ420P frame should convert to a VideoFrame");
assert_eq!(*out.pixel_format(), PixelFormat::Yuvj420p);
assert_eq!(
out.color().range(),
ColorRange::Full,
"YUVJ420P with UNSPECIFIED color_range must be delivered as Full"
);
}
fn frame_with_raw_format(raw: i32) -> ffmpeg_next::frame::Video {
let mut frame = ffmpeg_next::frame::Video::empty();
unsafe {
let frame_ptr = frame.as_mut_ptr();
(*frame_ptr).format = raw;
(*frame_ptr).width = 64;
(*frame_ptr).height = 48;
}
frame
}
#[test]
fn an_unsupported_format_is_named_in_the_error() {
use ffmpeg_next::ffi::AVPixelFormat;
let raw = AVPixelFormat::AV_PIX_FMT_VIDEOTOOLBOX as i32;
let frame = frame_with_raw_format(raw);
let Err(err) = video_frame_from(&frame, Timebase::default()) else {
panic!("a hardware surface carries no deliverable CPU layout");
};
let ConvertError::UnsupportedPixelFormat {
format,
raw: got,
name,
} = &err
else {
panic!("expected UnsupportedPixelFormat, got {err:?}");
};
assert_eq!(*format, PixelFormat::None);
assert_eq!(*got, raw);
assert_eq!(name.as_deref(), Some("videotoolbox_vld"));
let rendered = err.to_string();
assert!(
rendered.contains(&raw.to_string()),
"the raw id is missing from {rendered:?}"
);
assert!(
rendered.contains("videotoolbox_vld"),
"the FFmpeg name is missing from {rendered:?}"
);
}
#[test]
fn an_unnameable_format_still_reports_its_raw_id() {
let raw = 99_999;
let frame = frame_with_raw_format(raw);
let Err(err) = video_frame_from(&frame, Timebase::default()) else {
panic!("an unmappable format integer has no deliverable layout");
};
let ConvertError::UnsupportedPixelFormat {
format,
raw: got,
name,
} = &err
else {
panic!("expected UnsupportedPixelFormat, got {err:?}");
};
assert_eq!(*format, PixelFormat::None);
assert_eq!(*got, raw);
assert_eq!(*name, None);
let rendered = err.to_string();
assert!(
rendered.contains("99999"),
"the raw id is missing from {rendered:?}"
);
assert!(
rendered.contains("unnamed by libavutil"),
"the absent-name case is not spelled out in {rendered:?}"
);
}