-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Add automatic writing encoded video streams to disk when streaming from RTSP sources using cudacodec #3098
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
…luding checks to ensure codec used in input video file is supported on the current device.
…o update_nvcuvid_codecs
# Conflicts: # modules/cudacodec/include/opencv2/cudacodec.hpp # modules/cudacodec/src/video_decoder.cpp
1) automatically write the raw encoded video stream to a video file and, 2) use less GPU memory by more closely mirroring the Nvidia samples. Specifically querying the decoder for the number of decode surfaces (h265 commonly uses 4) instead of always using 20 and not using adaptive deinterlacing when the video sequence is progressive. Additional updates to mirror the Nvidia sample include initializing the decoder so that HandleVideoSequence() gets called every time before the decoder is initialized, ensuring all the parameters for the decoder are provided by nvcudec. Added facility to decode AV1, not tested as VideoCapture doesn't return a valid fourcc for this. Add facility to decode MPEG4 video - requires modification to VideoCapture see pull request.
…les to that they play in vlc. Notes: VideoCapture - returns mpeg as the codec for mpeg4 files, so files written as .m4v from mpeg4 sources cannot currently be decoded. This is also true for AV1 sources where cap.get(CAP_PROP_FOURCC) returns 0. Added mpeg4 test file which can be decoded when VideoCapture adds the extra_data.
…stead of appended to the first packet.
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.
Be careful with creation of GOD classes.
Reader should read, not write.
Please take a look on comments below before merge.
file, especially from container formats avi, mp4 etc. If the filename provided is invalid, cannot be opened | ||
or written to, the first call to nextFrame() after calling this function will return false. | ||
*/ | ||
CV_WRAP virtual void writeToFile(const std::string filename, const bool autoDetectExt = false) = 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.
const std::string filename
const reference
Here and below
|
||
FFMPEG is used to read videos. User can implement own demultiplexing with cudacodec::RawVideoSource | ||
*/ | ||
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const String& filename); | ||
CV_EXPORTS_W Ptr<VideoReader> createVideoReader(const String& filename, const String filenameToWrite = "", const bool autoDetectExt = false); |
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.
String filenameToWrite
Main problem of this approach is missing unicode support.
I would create dedicated API for that:
- keep existed API "as is"
- add new API like proposed (with
_W
) - add extra new API with
std::ostream&&
orstd::ofstream&&
(note, move ctor is available only)
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.
Main problem of this approach is missing unicode support.
Ahh I see. How can we support unicode in the new api (VideoReader_W
) for const String& filename
?
add extra new API with std::ostream&& or std::ofstream&& (note, move ctor is available only)
If possible I would like to be able to automatically detect the extension before creating the file so that the file can be played back without having to be renamed after writing has finished.
If this is not performed internally then this would involve creating a VideoCapture object before creating the new class just to detect the codec and then using that info to determine the file extension.
VideoCapture cap("rtsp://...")
std::string ext = FourCCToExtension(cap.get(CAP_PROP_FOURCC))
std::ofstream fileOut = (fileName + ext);
cap.release(); // release the stream so we can connect to it again below
cv::Ptr<cv::cudacodec::VideoReader_W> reader_w = cv::cudacodec::createVideoReader_W(inputFile, fileOut);
I would like to avoid that can you suggest and alternative?
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.
How can we support unicode in the new api (VideoReader_W) for const String& filename
String
may handle UTF-8 strings only (it is std::string , BTW). There is no wchar_t
or std::wstring
in OpenCV.
Main question is about support on target platform (e.g., support of UTF-8 in std::ofstream
) - Win 10 brings some support for UTF-8 but it should be pre-configured (also this configuration may break legacy apps).
alternative
Capture to temporary file and then rename()
with correct extension on user side.
But it also looks weird, so I don't have strong suggestion or recommendation here.
Thank you for taking a look.
I am not sure how to achieve my objective without creating a GOD class. I want to be able to stream and decode from an RTSP source at the same time as archiving the footage. This seems like a common use case for IP camera's, e.g. run DNN over live decoded footage and archive footage for training later or to simply see why the DNN failed. |
I can suggest
|
…t the same time as decoded frames.
I have added retrieve, grab etc. to enable the raw packets to be retrieved from the VideoReader class. I understand that there may not be a strong requirement for this, however these additions should not interfere with the current functionality when rawMode is disabled. The only "issue" I can see is that there is no straight forward way to get the packets corresponding to the current frame because the decoder is fed encoded data as fast as possible. As a result when it outputs a decoded frame ( |
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 for contribution 👍
|
||
int StartCodeLen(unsigned char* data, const int sz) { |
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.
static
to keep code local
Thanks for all you help alalek, I will add static when cudacodec needs modifying again to account for depreciation of CUvideosource. |
Update cudacoded VideoReader to;
This pull request relies on the changes in opencv/opencv#20978.
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.