Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to read video into a buffer using threads in OpenCV and I get " Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:167 " the reason I want to use threads to do this is so I can read a lot of frames into a list at a time so it's fast. I need all the frames and can not skip any frames. I thought multi-threading would be the way to go. my code works single-threaded aka with " buffer_refill = 1 ".

import threading
import cv2
cap = cv2.VideoCapture('data/temp/testing/test.mp4')
frames = []
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
frames_left = total_frames
threads = []
print(total_frames)
min_buffer = 120
buffer_refill = 60
def buffer():
    print('buffer')
    frame = cap.grab()
    ret, frame = cap.retrieve()
    frames.append(frame)
def get_buffer(num):
    global frames_left
    for i in range(num):
        frames_left -= 1
        if frames_left > 0:
            t = threading.Thread(target=buffer)
            t.start()
            threads.append(t)
    for thread in threads:
        thread.join()
    print('block')
while(cap.isOpened()):
    if frames_left > 0 and len(frames) < min_buffer:
        get_buffer(buffer_refill)
    else:
        cv2.imshow('Frame',frames[0])
        frames.pop(0)
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break
cap.release()
cv2.destroyAllWindows()
                that's not how any of this works. please stop. video reading is inherently sequential, and WILL FAIL if you do what you do there, with multiple threads trying to read from the video object at the same time. DO NOT DO THIS. it's wrong. -- if the backend is ffmpeg, decoding is probably already using multiple threads, so you don't have to do anything.
– Christoph Rackwitz
                Sep 3, 2022 at 22:14
                what you can do is spawn one thread that does video reading (NOT a single read per thread, ONE thread, living very long) and feeding into a queue, blocking if the queue is full. -- in case anyone's considering turning that into an answer, just poke me instead.
– Christoph Rackwitz
                Sep 3, 2022 at 22:16
                that approach still isn't guaranteed to be faster because the VideoCapture already runs multithreaded (ffmpeg). -- you should just stick to simple code. you've got no reason to complicate it like this.
– Christoph Rackwitz
                Sep 3, 2022 at 22:22
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.