Giter VIP home page Giter VIP logo

Comments (6)

ra1nty avatar ra1nty commented on May 30, 2024

Hi, thanks for trying out my library—
In this case I suppose the error is due to the Microsoft hybrid system.

DDA does not support being run against the discrete GPU so you probably want to create dxcam with parameters device_idx=1, output_idx=0. (Idx of uhd graphics)

I’m currently traveling and does not have a laptop with hybrid gpu to test the issue thoroughly — Please let me know the result.

from dxcam.

pamalite avatar pamalite commented on May 30, 2024

Same result. Throws the same error with device_idx=1, output_idx=0.

from dxcam.

ra1nty avatar ra1nty commented on May 30, 2024

I see. If you are using camera.start() and camera.stop() you should use .get_latest_frame() to get the real-time grabbed region. .grab() is for one-time screenshot. You shouldn't use .grab with .start and .stop together in your code.

camera.start()  # Start a video capture
for i in range(1000):
    image = camera.get_latest_frame()  # Will block until new frame available
camera.stop()

Please see documentation for further detail.
https://github.com/ra1nty/DXcam#screen-capture

TLDR; Use .grab for one-time screenshot/ad-hoc screenshot, camera.start(), camera.get_latest_frame(), camera.stop() for screen recording / async screenshot.

from dxcam.

pamalite avatar pamalite commented on May 30, 2024

Finally, some progress from your inputs.

I changed it to .get_latest_frame() and made my .create() like so:

camera = dxcam.create(
      device_idx=0,
      output_idx=0,
      region=(clip_region["left"], clip_region["top"], clip_region["right"], clip_region["bottom"]),
      output_color="BGR",
)

Then, the capturing happens like so:

camera.start(target_fps=int(fps), video_mode=True)
while camera.is_capturing:
    frame = camera.get_latest_frame()
    frames_queue.put_nowait(frame)
    frame_count = frame_count + 1

    if time.time() - start_time >= duration_seconds:
        frames_queue.put_nowait("EOS")
        break
camera.stop()

The frames_queue is consumed by another thread for the file writing by cv2.VideoWriter(). The thread is a simple function:

def write_to_file(outfile, codec, fps, dimension, frames_queue: queue.Queue):
    out = cv.VideoWriter(outfile, codec, fps, dimension)
    while True:
        frame = frames_queue.get()
        if isinstance(frame, str) and str(frame) == "EOS":
            break
        out.write(frame)

    out.release()
    return

With these, I was able to get FPS about 54. That means, it is capturing. However, I am getting blanks. The file written is only 1KB and cannot be opened.

I swapped out the line frames_queue.put_nowait(frame) to cv2.imshow("capture", frame). I got a grey window.

I tried following the examples, and changed the device_idx to 1 too, but to no avail.

from dxcam.

ra1nty avatar ra1nty commented on May 30, 2024

Hi, trying to answer your question step-by-step:

camera = dxcam.create(output_color="BGR", region=(0, 0, 600, 600))
camera.start(target_fps=30, video_mode=True)

while True:
    frame = camera.get_latest_frame()
    cv2.imshow("OpenCV/Numpy normal", np.copy(frame))
    if cv2.waitKey(40) & 0xFF == ord("q"):
        cv2.destroyAllWindows()
        break

camera.stop()
  • Writing video: I'm not sure how you handling the threading part, but I was able to put down a quick threaded example using mostly your code without issue: I was able to get a 5 sec screen recording, avg 60fps using the following snippet:
q = queue.Queue()
target_fps = 60
camera = dxcam.create(output_idx=0, output_color="BGR")
frame_count = 0


def write_to_file(frames_queue: queue.Queue):
    out = cv2.VideoWriter(
        "video.mp4", cv2.VideoWriter_fourcc(*"mp4v"), target_fps, (1920, 1080)
    )
    while True:
        frame = frames_queue.get()
        if isinstance(frame, str):
            break
        out.write(frame)

    out.release()


thread = threading.Thread(target=write_to_file, args=(q,))
thread.start()

camera.start(target_fps=target_fps, video_mode=True)

while camera.is_capturing:
    frame_count += 1
    frame = camera.get_latest_frame()
    q.put_nowait(frame)
    if frame_count >= 300:
        q.put_nowait("EOS")
        break
camera.stop()
thread.join()
  • Comments on speed:
    • deque is faster, and thread-safe for appends and pops from opposite sides.
    • if you want higher fps, you can try different codecs (check pyav https://github.com/PyAV-Org/PyAV)

from dxcam.

pamalite avatar pamalite commented on May 30, 2024

Thank you for the pointers!

My thread is as simple as your. Just pop the frame from queue, and write it to file.

Putting everything together, I managed write it to file. I was able to reach roughly 57fps, even with deque. It is good enough for me.

One caveat I have is High DPI. I just need to add the following to scale the left, top, right, bottom to the scaling set:

import ctypes
scale_perc = ctypes.windll.shcore.GetScaleFactorForDevice(0)

from dxcam.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.