Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermitent blank output when using '#![windows_subsystem = "windows"]' on Windows 10 #28

Open
McSpidey opened this issue Nov 8, 2019 · 5 comments

Comments

@McSpidey
Copy link

McSpidey commented Nov 8, 2019

Was just testing this rad library with some sample code and noticed it's ultra reliable when called in a standard console mode, but I wanted the console not in the screenshot so tried wrapping it #![windows_subsystem = "windows"], now 4 out of 5 attempts to call this produces a blank output.

Testing on Windows 10.

`//#![windows_subsystem = "windows"]

extern crate repng;
extern crate scrap;

use scrap::{Capturer, Display};
use std::io::ErrorKind::WouldBlock;
use std::fs::File;
use std::thread;
use std::time::Duration;

fn main() {
let one_second = Duration::new(1, 0);
let one_frame = one_second / 60;

let display = Display::primary().expect("Couldn't find primary display.");
let mut capturer = Capturer::new(display).expect("Couldn't begin capture.");
let (width, height) = (capturer.width(), capturer.height());

loop {
    // Wait until there's a frame.

    let buffer = match capturer.frame() {
        Ok(buffer) => buffer,
        Err(error) => {
            if error.kind() == WouldBlock {
                // Keep spinning.
                // println!("Waiting...");
                thread::sleep(one_frame);
                continue;
            } else {
                panic!("Error: {}", error);
            }
        }
    };

    // println!("Captured! Saving...");

    // Flip the ARGB image into a BGRA image.

    let mut bitflipped = Vec::with_capacity(width * height * 4);
    let stride = buffer.len() / height;

    for y in 0..height {
        for x in 0..width {
            let i = stride * y + 4 * x;
            bitflipped.extend_from_slice(&[
                buffer[i + 2],
                buffer[i + 1],
                buffer[i],
                255,
            ]);
        }
    }

    // Save the image.

    repng::encode(
        File::create("screenshot.png").unwrap(),
        width as u32,
        height as u32,
        &bitflipped,
    ).unwrap();

    // println!("Image saved to `screenshot.png`.");
    break;
}

}`

@McSpidey McSpidey closed this as completed Nov 8, 2019
@McSpidey McSpidey reopened this Nov 8, 2019
@Nebual
Copy link
Contributor

Nebual commented Nov 11, 2019

I too experienced this on Windows; a workaround I used was to wrap the let buffer = match capturer.frame in a loop, sleep + continue'ing until I got a non-black frame, at which point I returned out of the loop.

if !buffer.to_vec().iter().any(|&x| x != 0) {
    thread::sleep(Duration::new(0, 1)); // sleep 1ms
    continue;
}
return buffer;

I recall when this happened (which seemed pretty inconsistent), I'd need to wait 5-15ms before getting a non-solid-black buffer, which sounded suspiciously like I had to wait for the "next frame" @ 60hz.

@McSpidey
Copy link
Author

Thanks for the workaround, it's helped and gives a consistent output.

Odd the output is blank still somtimes to need this as I was already waiting on match error for another frame.

@lukevp
Copy link

lukevp commented Aug 26, 2020

@McSpidey @Nebual any further progress on figuring this out? I am experiencing this and it occurs if I shake the mouse a bunch, every frame is all 0s and WouldBlock does not show, so it seems to be interrupt-related.

The section here where Buffer length: is printed out 3 times in a row (without blocking for the next frame) occurred while the mouse was being shaken. When the mouse stopped moving it resumed normal behavior.

image

This behavior is also reproducible only when the mouse is moved on the screen being captured, if the mouse is moving on the other screen, no blank frames are captured.

@McSpidey
Copy link
Author

Sorry, I haven't revisited this. That's a good find re mouse interrupts though.

@samarthc-rapid
Copy link

Hi, I am currently facing this issue working with the example code. This is what I have currently.

    let mut buffer = None;
    let display = Display::primary().expect("Couldn't find primary display.");
    let mut capturer = Capturer::new(display).expect("Couldn't begin capture.");
    let (mut w, mut h);
    
    while buffer.is_none() {
        
        (w, h) = (&mut capturer.width(), &mut capturer.height());
        // Wait until there's a frame.
        match &mut capturer.frame() {
            Ok(buf) => {
                buffer = Some(buf);
                break;
            }
            Err(error) => {
                if error.kind() == WouldBlock {
                    // Keep spinning.
                    thread::sleep(one_frame);
                    continue;
                } else {
                    panic!("Error: {}", error);
                }
            }
        };
    }
//further computation

The blank output occurs for me whenever the WouldBlock error is returned, so I assume this is a problem with calling capture.frame() inside a loop. Trying to learn more about lifetimes to remedy this, any help would be appreciated .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants