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

Empty pixel data on Windows #11

Open
EmiliaTheGoddess opened this issue Sep 24, 2022 · 4 comments
Open

Empty pixel data on Windows #11

EmiliaTheGoddess opened this issue Sep 24, 2022 · 4 comments

Comments

@EmiliaTheGoddess
Copy link

The example code(taking average color of screen, exactly what I need) is running on GNU/Linux without any problem but on windows every pixel just returns 0. Happens on both a daily use Windows with drivers installed and a new VM with nothing installed. Is there some sort of windows-specific dependency I'm missing?

@yurtemre7
Copy link

Did you find a solution or another library?

@EmiliaTheGoddess
Copy link
Author

@yurtemre7 I ended up using some code I found online. You can try other capture libraries like screenshot-rs.

@TommyGymer
Copy link
Contributor

I've found that, for some reason, the first capture on Windows results in a blank (an entirely zero) frame with subsequent captures working correctly.

frame 1

frame1

frame 2

frame2

code used

let mut capturer = Capturer::new(1).unwrap();
let (w, h) = capturer.geometry();

// capture_frame_components is a modified version of capture_frame
// which returns a bgr Vec<u8> rather than a Vec<Bgr8>
let f1 = capturer.capture_frame_components().unwrap();
let f2 = capturer.capture_frame_components().unwrap();

// qoi has been converted to png for the images above
let p1 = Path::new("./frame1.qoi");
let p2 = Path::new("./frame2.qoi");

// using the bgr array directly for the qoi, causing the inverted colour as this expects rgb
let o1 = encode_to_vec(&f1, w, h).unwrap();
let o2 = encode_to_vec(&f2, w, h).unwrap();

File::create(p1).unwrap().write_all(&o1).unwrap();
File::create(p2).unwrap().write_all(&o2).unwrap();

@0Ky
Copy link

0Ky commented Jul 14, 2023

Could this be related to how AcquireNextFrame() works via Desktop Duplication API in Windows?
Which implies that you can have a pointer information before the image.

The AccumulatedFrames, TotalMetadataBufferSize, and LastPresentTime are set to zero only when the pointer was updated (that is, the desktop image was not updated) based on FrameInfo output when calling AcquireNextFrame.

Would it be possible to include checks, something similar to:

// No image update, only cursor moved.
if (info.AccumulatedFrames == 0 || info.LastPresentTime.QuadPart == 0)
{
    RETURN_ERR(DXGI_ERROR_WAIT_TIMEOUT);
}

// not interested in just mouse updates, which can happen much faster than 60fps if you really shake the mouse
if (info.LastPresentTime.HighPart == 0) 
{
    hr = _lDeskDupl->ReleaseFrame();
    return false;
}

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