cv2.cudacodec.createVideoWriter does not work?

Hello

New to these forums and very new to python in gerneral. I’ve made a program that, amongst other thing reads a webcam feed, adds some stuff to the frame and writes it to a *.avi. All good, my program is working. However, doing all the stuff on the CPU, my program is not able to keep 30 fps while recording and displaying the feed at the same time, so I started investigating openCV with cuda support to get the encoding part over on my GPU. I’ve built the module with cmake and are able to get it to work with my code, except the function I really need:

cv2.cudacodec.createVideoWriter

Creating this object and trying to run the code gives me this error message:

error: OpenCV(4.5.5) D:\Cuda\opencv-4.5.5\modules\core\include\opencv2/core/private.cuda.hpp:112: error: (-213:The function/feature is not implemented) The called functionality is disabled for current build or platform in function ‘throw_no_cuda’

^^ I cannot find this file either (private.cuda.hpp) This folder contains one file only: “cv_cpu_include_simd_declarations.hpp”

I’m using cuda v11.6 and also downloaded the Video_Codec_SDK_11.1.5.

I really need help on this. Maybe point me in a different direction if what I’m pursuing is not possible. Doing this on CPU grinds my program to ~15fps which is useless for my application.

cv::cudacodec::VideoWriter has not worked for several years unfortunately.

1 Like

That was also my concern as I could not find any updated information regarding it… Is there any workaround to speed up the encoding process for my application ?

You could see if hardware accelerated encoding through cv::VideoWriter works. I have not tried this myself so I cannot confirm that it works or will help but its worth a try.

1 Like

Thanks. I’ve tried to figure out how to apply this for my videowriter now, but I’m not experienced enough to figure out how to set this flag correctly.

I don’t have time to test this at the moment but can you not just add something like
params=[cv2.CAP_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY] to your list of arguments to cv::VideoWriter and see if your GPU is being used?

1 Like

I’ve tried like this:

    out = cv2.VideoWriter('.\Video\{}.avi'.format(timestr), fourcc, 30.0, (1920, 1080),
                        (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY))

But I can’t see any difference with or without unfortunately. However, what is confusing me is from the documentation, it says:

“(open-only) Hardware acceleration type (see VideoAccelerationType). Setting supported only via params parameter in cv::VideoCapture constructor / .open() method. Default value is backend-specific.”

What does this mean ?

1 Like

I will need to investigate further… I see something strange though. After building the openCV 4.5.5, it seems like GPU is used as default…

import cv2

#Set up video Capture
vod = cv2.VideoCapture(0)
vod.set(cv2.CAP_PROP_FPS, 30)
vod.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
vod.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)

#Set up video Recorder
fourcc = cv2.VideoWriter_fourcc('M','P','4','2')

out = cv2.VideoWriter('target.mp4', fourcc, 30.0, (1920, 1080))#,
                   # (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY))

rec = True

while True:
    ret, frame = vod.read()
    cv2.imshow('test', frame)
    
    if rec:
        #print('recording')
        #frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) #Convert back to 3 channel for recording    
        out.write(frame)
    
    if cv2.waitKey(1) == 27: 
        out.release()
        break  # esc to quit

cv2.VideoCapture(0).release()
cv2.destroyAllWindows() or paste code here

Using this code, my GPU actually IS loaded at ~8%. during encoding. By limiting my CPU speed to 30%, I still get the desired output. (Even when commenting away the HW_acc flags). However, for some reason, it does not work when I implement it in my main code, then GPU load is ~ 1% …

Edit: My main code used ‘MP42’ as well, but it saved the file as *.avi. When changing it to *.mp4 it loads the GPU in main code as well. To be honest, I don’t know what is happening here… If this was something that started working after building the openCV 4.5.5 with cuda support, or if it was due to the file extension ? Anyway, it works now… Stored videofile is 30 fps and no missed frames in stream …

So, I guess the reason for it to “suddenly work” was due to me having an old version of openCV installed during my coding of my app (4.5.2 iirc). Compiling the 4.5.5 release, or just pip ugrade the opencv-python module seems to have included fixes for GPU support already :slight_smile:

Case closed then !