-
Notifications
You must be signed in to change notification settings - Fork 5.8k
OpenCV fix 14774 breaks cudacodec #2180
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for contribution.
Please ensure that this can be built without FFmpeg (cmake -DWITH_FFMPEG=OFF ...
).
@@ -0,0 +1,49 @@ | |||
#ifndef __OPENCV_CUVID_FFMPEG_API_H__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add short license header (here and for other files): https://github.com/opencv/opencv/wiki/Coding_Style_Guide#file-structure
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
struct OutputMediaStream_FFMPEG | ||
{ | ||
bool open(const char* fileName, int width, int height, double fps); | ||
void close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please replace tabs => 4 spaces
|
||
OPENCV_FFMPEG_API struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps); | ||
OPENCV_FFMPEG_API void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream); | ||
OPENCV_FFMPEG_API void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid indentation in namespace/extern "C" blocks.
//#elif defined __GNUC__ && __GNUC__ >= 4 | ||
//# define OPENCV_FFMPEG_API __attribute__ ((visibility ("default"))) | ||
//#else | ||
//# define OPENCV_FFMPEG_API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe OPENCV_FFMPEG_API
modifier can be removed.
modules/cudacodec/CMakeLists.txt
Outdated
@@ -13,6 +13,10 @@ ocv_glob_module_sources() | |||
|
|||
set(extra_libs "") | |||
|
|||
if(HAVE_FFMPEG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this should not work with HAVE_FFMPEG_WRAPPER
(Windows)
modules/cudacodec/src/precomp.hpp
Outdated
@@ -81,7 +81,7 @@ | |||
#include "video_decoder.hpp" | |||
#include "video_parser.hpp" | |||
|
|||
#include "../src/cap_ffmpeg_api.hpp" | |||
#include "cuvid_ffmpeg_api.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need guard: #if defined(HAVE_FFMPEG)
here and in places where this API is used.
I have added the changes but I am still unsure if I have used the correct preprocessor. What is the difference in purpose between WITH_FFMPEG and WITH_FFMPEG_WRAPPER? I have also added a guard on the tests as the smaller video requires ffmpeg to demux the file. The guards are not properly implemented yet because I can't work out how to include HAVE_FFMPEG_WRAPPER, should it be as a preprocessor or cvconfig.h, or should I remove the guard and let the tests fail? |
There is no such option/variable. HAVE_FFMPEG - OpenCV can use FFmpeg SDK (headers/libs) So your condition should be Also to use FFmpeg header/libs your should use proper dependency target ( |
Your correct, I wasn't correctly including cuvid_ffmpeg_impl.hpp and now I have, I realize everything depends on FFmpeg headers/libs. I still am unsure as to why the cudacodec routines were removed in #14774 so I'm not entirely sure if I should be directly using FFmpeg headers/libs in cudacodec or somehow using the dynamic wrapper? If I can use the FFmpeg headers/libs what is the recommended way to include them in cudacodec? If not I will have to leave this and it may be an idea to just disable the FFmpeg fallback in cudacodec. |
Dynamic wrapper doesn't contain CUDA-related code anymore. |
On reading the FFmpeg readme and this I have a clearer idea of what is going on. Now the only issue is that the shared library on windows has changed from
have been removed. Will these be included in the |
@cudawarped , current CUDA codec design is flawed, because it uses private methods and definitions of videoio module. It is better to add raw stream output support to VideoCapture to make it work instead of duplicating the code. Or, even better, new class: |
@mshabunin that sounds reasonable, I may not have time to implement this for a while, it was not my intention to implement a fix just to highlight the changes which broke cudacodec after 4.1.0, if someone else wants to take over so that cudacodec is not broken in 4.1.1 then feel free. |
…raw encoded bitstream, from the videoio module instead of its own implementation.
@mshabunin everything should be working as well as it was before the break. Ideally cudacodec should be updated to mirror the AppDec sample from Nvidia, adding support for a wider variety of color space formats etc. Unfortunately because cudacodec needs to work with all CUDA API's from the last 5 years mirroring the sample code and maintaining compatibility would be very difficult. |
@@ -320,7 +323,7 @@ class CV_EXPORTS_W RawVideoSource | |||
@param size Size in bytes of current frame. | |||
@param endOfFile Indicates that it is end of stream. | |||
*/ | |||
virtual bool getNextPacket(unsigned char** data, int* size, bool* endOfFile) = 0; | |||
virtual bool getNextPacket(unsigned char** data, size_t* size, bool* endOfFile) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endOfFile
is probably duplicated by return value. It is better to avoid behavior confusion and remove endOfFile
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree should I change this or are you happy to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if you can add commit for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commit added
chromaFormat = YUV420; | ||
nBitDepthMinus8 = 0; | ||
break; | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to add more cases (if you have corresponding videos)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your change makes everything clearer because I am pretty sure the historic version of AppDec which cudacodec is based on cannot deal with any formats other than YUV420. Therefore any other cases would be redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done! Thank you 👍
resolves opencv/opencv#14850
In opencv/opencv#14774
cap_ffmpeg_api.hpp
was replaced withcap_ffmpeg_legacy_api.hpp
and all of the cuda encoder decoder parts were removed fromcap_ffmpeg_legacy_api.hpp
, e.g.additionaly the CUDA encoder/decoder implementation was removed from
cap_ffmpeg_impl.hpp
meaning that simply updating the include in precomp.hpp fails when compiling cudacodec.
I don't have a deep understanding of the intention of the changes in #14774 or the recommended way that all the pieces of OpenCV fit together so I have submitted this hack which I used to get things working on my system as a PR to further explain the problem, and get some guidance as to the correct solution.