cudacodec::VideoReader add reconfigure decoder functionality#3453
cudacodec::VideoReader add reconfigure decoder functionality#3453asmorkalov merged 1 commit intoopencv:4.xfrom
cudacodec::VideoReader add reconfigure decoder functionality#3453Conversation
asmorkalov
left a comment
There was a problem hiding this comment.
👍 Well done! Tested with Ubuntu 18.04 and CUDA 10.2.
|
@cudawarped I made experiments with cv::VideoCapture and ported your test. VideoCapture class behaves differently and changes frame resolution on the go. What if make the behavior optional? |
|
@asmorkalov I just ran a quick test and As you can see Personally I like the resize option for the reasons mentioned in the Nvidia docs,
but I understand the importants of having the same behaviour accross OpenCV's video reading interfaces. Therefore I can add default the behaviour to do the same thing as I am happy either way, the main reason for this PR was to avoid |
|
Let's do the following then:
|
2c2e39e to
f0fa5bb
Compare
Added a |
f0fa5bb to
ea1a5be
Compare
| if (!decodeResChange) | ||
| return 1; | ||
|
|
There was a problem hiding this comment.
It should be before block with autolock.
There was a problem hiding this comment.
I will take a look at this next week, I need to find the test footage I was using where the number of decode surfaces changed but the resolution didn't to check if this can be moved.
| }; | ||
|
|
||
| /** @brief Output format for a decoded frame when the resolution of the source is reduced by the encoder. In all cases the size of the output frame remains the same. | ||
| * @param Default Use the approach adopted by cv::VideoCapture, i.e. maintain the same frame size by placing the smaller output in the top left corner. |
There was a problem hiding this comment.
I made experiment with your test stream and VideoCapture follows frame resolution according to video:
Frame size: 700x400
Resolution: 700x400
Frame size: 700x400
Resolution: 700x400
Frame size: 700x400
[swscaler @ 0x55a1797812e0] Slice parameters 0, 400 are invalid
Resolution: 672x384
Frame size: 672x384
[swscaler @ 0x55a1797812e0] Slice parameters 0, 400 are invalid
Resolution: 672x384
Frame size: 672x384
Resolution: 672x384
Frame size: 672x384
Resolution: 672x384
Frame size: 672x384
Resolution: 672x384
Frame size: cols & rows for Mat. Resolution: CAP_PROP_FRAME_WIDTH and CAP_PROP_FRAME_HEIGHT. IMHO, it should be default behavior for consistency.
There was a problem hiding this comment.
This appears to depend on the version of FFMpeg. If I use the prebuilt windows plugin
-- FFMPEG: YES (prebuilt binaries)
-- avcodec: YES (58.134.100)
-- avformat: YES (58.76.100)
-- avutil: YES (56.70.100)
-- swscale: YES (5.9.100)
-- avresample: YES (4.0.0)
then I get the output you described, shown below
avcodec: 58.134.100
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[swscaler @ 00000220c64f4140] Slice parameters 0, 400 are invalid
[672 x 384]
[swscaler @ 00000220c64f4140] Slice parameters 0, 400 are invalid
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
[672 x 384]
however when I link to a more recent version of FFmpeg, e.g.
-- FFMPEG: YES (find_package)
-- avcodec: YES (59.18.100)
-- avformat: YES (59.16.100)
-- avutil: YES (57.17.100)
-- swscale: YES (6.4.100)
I get the previous output I showed in the screen shot with consistent sizes and no
[swscaler @ 00000220c64f4140] Slice parameters 0, 400 are invalid
error message.
avcodec: 59.18.100
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
[700 x 400]
IMHO, it should be default behavior for consistency
Unfortunately the output from the Nvidia decoder will always be the same resolution as the original/first decoded frame (700x400) because the reconfigure functionality is designed for QOS use where you would want to maintain the same output resolution.
What would you like me to do?
There was a problem hiding this comment.
I propose to rename enum items and remove reference to cv::VideoCature as soon as it behaves slightly different depending on backend.
- "default" -> "copy"
- "QoS" -> "scale" or "upscale"
It makes behaviour more obvious even without documentation.
There was a problem hiding this comment.
OK, just a thought would it be cleaner to remove ResolutionChangeMode completely and just default to QOS as the copy behaviour may not be a sensible default anymore (FFmpeg could change again so why copy them)?
ea1a5be to
045a9b0
Compare
asmorkalov
left a comment
There was a problem hiding this comment.
👍 Thanks a lot for the contribution!
|
Tested manually with Ubuntu 18.04, CUDA 10.2 and GF 1080. |

Add decoder reconfiguration functionality on resolution change, see Nvidia Docs.
PR test is dependent on multi-resolution test video from opencv/opencv_extra#1047
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.