Skip to content

Commit 17755dc

Browse files
committed
Detect DirectShow bottom-up frames by format
1 parent 96c7a78 commit 17755dc

1 file changed

Lines changed: 31 additions & 5 deletions

File tree

  • crates/camera-windows/src

crates/camera-windows/src/lib.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ impl VideoDeviceInfo {
367367
};
368368

369369
let bi_height = video_info.bmiHeader.biHeight;
370-
let is_bottom_up = bi_height > 0;
370+
let is_bottom_up = directshow_frame_is_bottom_up(format, bi_height);
371371
let height = bi_height.unsigned_abs() as usize;
372372

373373
callback(Frame {
@@ -503,6 +503,10 @@ impl PixelFormat {
503503
}
504504
}
505505

506+
fn directshow_frame_is_bottom_up(pixel_format: PixelFormat, bi_height: i32) -> bool {
507+
bi_height > 0 && pixel_format.is_traditionally_bottom_up()
508+
}
509+
506510
#[derive(Clone)]
507511
enum VideoDeviceInfoInner {
508512
MediaFoundation {
@@ -706,18 +710,19 @@ impl VideoFormat {
706710
}
707711

708712
let video_info = unsafe { inner.video_info() };
713+
let pixel_format = DSPixelFormat::new(&inner)
714+
.ok_or(VideoFormatError::InvalidPixelFormat(inner.subtype))?
715+
.format;
709716
let bi_height = video_info.bmiHeader.biHeight;
710-
let is_bottom_up = bi_height > 0;
717+
let is_bottom_up = directshow_frame_is_bottom_up(pixel_format, bi_height);
711718
let height = bi_height.unsigned_abs();
712719

713720
Ok(VideoFormat {
714721
width: video_info.bmiHeader.biWidth as u32,
715722
height,
716723
frame_rate: ((10_000_000.0 / video_info.AvgTimePerFrame as f32) * 100.0).round()
717724
/ 100.0,
718-
pixel_format: DSPixelFormat::new(&inner)
719-
.ok_or(VideoFormatError::InvalidPixelFormat(inner.subtype))?
720-
.format,
725+
pixel_format,
721726
is_bottom_up,
722727
inner: VideoFormatInner::DirectShow(inner),
723728
})
@@ -817,3 +822,24 @@ impl DSPixelFormat {
817822
})
818823
}
819824
}
825+
826+
#[cfg(test)]
827+
mod tests {
828+
use super::{PixelFormat, directshow_frame_is_bottom_up};
829+
830+
#[test]
831+
fn directshow_rgb_with_positive_height_is_bottom_up() {
832+
assert!(directshow_frame_is_bottom_up(PixelFormat::RGB32, 1080));
833+
}
834+
835+
#[test]
836+
fn directshow_yuv_with_positive_height_is_not_bottom_up() {
837+
assert!(!directshow_frame_is_bottom_up(PixelFormat::YUYV422, 1080));
838+
assert!(!directshow_frame_is_bottom_up(PixelFormat::NV12, 1080));
839+
}
840+
841+
#[test]
842+
fn directshow_negative_height_is_not_bottom_up() {
843+
assert!(!directshow_frame_is_bottom_up(PixelFormat::RGB32, -1080));
844+
}
845+
}

0 commit comments

Comments
 (0)