improve video, ignore same image
This commit is contained in:
parent
264db496ff
commit
4d5d0a4c62
@ -30,3 +30,16 @@ pub use self::convert::*;
|
|||||||
pub const STRIDE_ALIGN: usize = 64; // commonly used in libvpx vpx_img_alloc caller
|
pub const STRIDE_ALIGN: usize = 64; // commonly used in libvpx vpx_img_alloc caller
|
||||||
|
|
||||||
mod vpx;
|
mod vpx;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn would_block_if_equal(old: &mut Vec<u128>, b: &[u8]) -> std::io::Result<()> {
|
||||||
|
let b = unsafe {
|
||||||
|
std::slice::from_raw_parts::<u128>(b.as_ptr() as _, b.len() / 16)
|
||||||
|
};
|
||||||
|
if b == &old[..] {
|
||||||
|
return Err(std::io::ErrorKind::WouldBlock.into());
|
||||||
|
}
|
||||||
|
old.resize(b.len(), 0);
|
||||||
|
old.copy_from_slice(b);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ pub struct Capturer {
|
|||||||
frame: Arc<Mutex<Option<quartz::Frame>>>,
|
frame: Arc<Mutex<Option<quartz::Frame>>>,
|
||||||
use_yuv: bool,
|
use_yuv: bool,
|
||||||
i420: Vec<u8>,
|
i420: Vec<u8>,
|
||||||
|
saved_raw_data: Vec<u128>, // for faster compare and copy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Capturer {
|
impl Capturer {
|
||||||
@ -38,6 +39,7 @@ impl Capturer {
|
|||||||
frame,
|
frame,
|
||||||
use_yuv,
|
use_yuv,
|
||||||
i420: Vec::new(),
|
i420: Vec::new(),
|
||||||
|
saved_raw_data: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ impl Capturer {
|
|||||||
|
|
||||||
match frame {
|
match frame {
|
||||||
Some(mut frame) => {
|
Some(mut frame) => {
|
||||||
|
crate::would_block_if_equal(&mut self.saved_raw_data, frame.inner())?;
|
||||||
if self.use_yuv {
|
if self.use_yuv {
|
||||||
frame.nv12_to_i420(self.width(), self.height(), &mut self.i420);
|
frame.nv12_to_i420(self.width(), self.height(), &mut self.i420);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ impl Capturer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result<Frame<'a>> {
|
pub fn frame<'a>(&'a mut self, _timeout_ms: u32) -> io::Result<Frame<'a>> {
|
||||||
Ok(Frame(self.0.frame()))
|
Ok(Frame(self.0.frame()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ pub struct Capturer {
|
|||||||
rotated: Vec<u8>,
|
rotated: Vec<u8>,
|
||||||
gdi_capturer: Option<CapturerGDI>,
|
gdi_capturer: Option<CapturerGDI>,
|
||||||
gdi_buffer: Vec<u8>,
|
gdi_buffer: Vec<u8>,
|
||||||
|
saved_raw_data: Vec<u128>, // for faster compare and copy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Capturer {
|
impl Capturer {
|
||||||
@ -150,6 +151,7 @@ impl Capturer {
|
|||||||
rotated: Vec::new(),
|
rotated: Vec::new(),
|
||||||
gdi_capturer,
|
gdi_capturer,
|
||||||
gdi_buffer: Vec::new(),
|
gdi_buffer: Vec::new(),
|
||||||
|
saved_raw_data: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +235,13 @@ impl Capturer {
|
|||||||
let result = {
|
let result = {
|
||||||
if let Some(gdi_capturer) = &self.gdi_capturer {
|
if let Some(gdi_capturer) = &self.gdi_capturer {
|
||||||
match gdi_capturer.frame(&mut self.gdi_buffer) {
|
match gdi_capturer.frame(&mut self.gdi_buffer) {
|
||||||
Ok(_) => &self.gdi_buffer,
|
Ok(_) => {
|
||||||
|
crate::would_block_if_equal(
|
||||||
|
&mut self.saved_raw_data,
|
||||||
|
&self.gdi_buffer,
|
||||||
|
)?;
|
||||||
|
&self.gdi_buffer
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, err.to_string()));
|
return Err(io::Error::new(io::ErrorKind::Other, err.to_string()));
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,12 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inner(&self) -> &[u8] {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
|
||||||
pub fn nv12_to_i420<'a>(&'a mut self, w: usize, h: usize, i420: &'a mut Vec<u8>) {
|
pub fn nv12_to_i420<'a>(&'a mut self, w: usize, h: usize, i420: &'a mut Vec<u8>) {
|
||||||
if self.inner.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let plane0 = IOSurfaceGetBaseAddressOfPlane(self.surface, 0);
|
let plane0 = IOSurfaceGetBaseAddressOfPlane(self.surface, 0);
|
||||||
let stride0 = IOSurfaceGetBytesPerRowOfPlane(self.surface, 0);
|
let stride0 = IOSurfaceGetBytesPerRowOfPlane(self.surface, 0);
|
||||||
|
@ -14,6 +14,7 @@ pub struct Capturer {
|
|||||||
size: usize,
|
size: usize,
|
||||||
use_yuv: bool,
|
use_yuv: bool,
|
||||||
yuv: Vec<u8>,
|
yuv: Vec<u8>,
|
||||||
|
saved_raw_data: Vec<u128>, // for faster compare and copy
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Capturer {
|
impl Capturer {
|
||||||
@ -68,6 +69,7 @@ impl Capturer {
|
|||||||
size,
|
size,
|
||||||
use_yuv,
|
use_yuv,
|
||||||
yuv: Vec::new(),
|
yuv: Vec::new(),
|
||||||
|
saved_raw_data: Vec::new(),
|
||||||
};
|
};
|
||||||
Ok(c)
|
Ok(c)
|
||||||
}
|
}
|
||||||
@ -97,15 +99,16 @@ impl Capturer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame<'b>(&'b mut self) -> &'b [u8] {
|
pub fn frame<'b>(&'b mut self) -> std::io::Result<&'b [u8]> {
|
||||||
self.get_image();
|
self.get_image();
|
||||||
let result = unsafe { slice::from_raw_parts(self.buffer, self.size) };
|
let result = unsafe { slice::from_raw_parts(self.buffer, self.size) };
|
||||||
if self.use_yuv {
|
crate::would_block_if_equal(&mut self.saved_raw_data, result)?;
|
||||||
|
Ok(if self.use_yuv {
|
||||||
crate::common::bgra_to_i420(self.display.w(), self.display.h(), &result, &mut self.yuv);
|
crate::common::bgra_to_i420(self.display.w(), self.display.h(), &result, &mut self.yuv);
|
||||||
&self.yuv[..]
|
&self.yuv[..]
|
||||||
} else {
|
} else {
|
||||||
result
|
result
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user