-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Add cv::cuda::cvtColorTwoPlane #4033
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
base: 4.x
Are you sure you want to change the base?
Conversation
|
@srcejon Would it be better to use
e.g. If you agree then the requirement for Nvidia Video Codec SDK to be installed for this function to be available should be removed. |
In my application (Which is using FFMPEG with HW decoder (pixfmt=AV_PIX_FMT_CUDA, so should be using NVDEC)), it appears to be giving me two plane NV12. As far as I can see, the UV plane isn't contiguous with the Y plane - there's a small gap inbetween. (Why aren't I using cv::cudacodec? Because I have an mp4 with multiple video + audio streams, which doesn't appear to be supported) Both cudacodec and FFPMEG are using NVDEC, so presumably there should be a way for it to work, but can't currently see it. Maybe it's a useful function anyway - as it's in the main opencv library. |
|
I guess that's how FFMpeg wants to present the output, the Nvidia decoder uses
Anyway what's your use case for outputing NV12 and then converting to BGR/RGB and why only from SD files using BT.601 color space? @asmorkalov Should we have additional CUDA functions for different data layouts? |
I will dig in to it more to try to find out why it appears different and if really necessary to have two plane conversion.
Good question, that's possibly not what I want. I just blindly copied the BT.601 coeffs from cv::cvtColorTwoPlane so the functionality is the same. (cv::cvtColor() and cv::cvtColorTwoPlane() don't have color space & range as parameters). The source mp4 is actually created using cudacodec::VideoWriter with 4096x3000 BGRA input, h264 and mostly default EncoderParams. It's not clear from the OpenCV or NVEnc docs what the default color space used is. It looks like NvEncoder.cpp doesn't set h264VUIParameters explictly, so colourMatrix would presumably default to NV_ENC_VUI_MATRIX_COEFFS_RGB. |
The issue is that my frame height is 3000, which isn't divisible by 16, so it allocates a 3008 line YUV buffer. Those extra 8 lines account for the gap between the Y and UV when viewed as a 3000 line frame. So, it seems it is useful to have a two plane conversion function, but also should have the other functionality of NVSurfaceToColorConverter. Perhaps NVSurfaceToColorConverter::convert could have an overloaded version with separate y and uv parameters? This would be preferable to using the NPP functions as it could support RGBA and also wouldn't depend on NPP v13. |
|
Not sure I understand. You are encoding a 4096x3000 video to h264 using
If its a single plane you should still be able to convert it using the function I mentioned where the NV12 input frame has1.5*3008 rows. |
I can't see an option to get BGR when the decoder is NVDEC. To clarify, I'm using libavcodec directly rather than the ffmpeg executable.
Yes, if I oversize the buffers with the extra lines, then it works. Thanks. |
This PR adds cv::cuda::cvtColorTwoPlane, similar to cv::cvtColorTwoPlane.
Currently it supports COLOR_YUV2BGR_NV12 and COLOR_YUV2RGB_NV12 for CV_8U only. Unfortunately there doesn't appear to be a npp function supporting RGBA.
It requires NPP v13 or greater, as nppiNV12ToRGB_8u_ColorTwist32f_P2C3R_Ctx is buggy in earlier versions of NPP.
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.
No patch to opencv_extra - but test is included that compares cv::cuda::cvtColorTwoPlane to cv::cvtColorTwoPlane.