-
Notifications
You must be signed in to change notification settings - Fork 5.8k
cudacodec::VideoWriter
add container output
#3569
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,6 @@ GUID CodecGuid(const Codec codec); | |
void FrameRate(const double fps, uint32_t& frameRateNum, uint32_t& frameRateDen); | ||
GUID EncodingProfileGuid(const EncodeProfile encodingProfile); | ||
GUID EncodingPresetGuid(const EncodePreset nvPreset); | ||
bool Equal(const GUID& g1, const GUID& g2); | ||
|
||
bool operator==(const EncoderParams& lhs, const EncoderParams& rhs) | ||
{ | ||
|
@@ -68,12 +67,48 @@ bool operator==(const EncoderParams& lhs, const EncoderParams& rhs) | |
rhs.averageBitRate, rhs.maxBitRate, rhs.targetQuality, rhs.gopLength); | ||
}; | ||
|
||
class FFmpegVideoWriter : public EncoderCallback | ||
{ | ||
public: | ||
FFmpegVideoWriter(const String& fileName, const Codec codec, const int fps, const Size sz, const int idrPeriod); | ||
~FFmpegVideoWriter(); | ||
void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket); | ||
void onEncodingFinished(); | ||
private: | ||
cv::VideoWriter writer; | ||
}; | ||
|
||
FFmpegVideoWriter::FFmpegVideoWriter(const String& fileName, const Codec codec, const int fps, const Size sz, const int idrPeriod) { | ||
if (!videoio_registry::hasBackend(CAP_FFMPEG)) | ||
CV_Error(Error::StsNotImplemented, "FFmpeg backend not found"); | ||
const int fourcc = codec == Codec::H264 ? cv::VideoWriter::fourcc('a', 'v', 'c', '1') : cv::VideoWriter::fourcc('h', 'e', 'v', '1'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about VP8, VP9, MPEG4, others? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Nvidia Video Codec SDK only supports H264, H265 and AV1 encoding, with I will add comments to the create methods to clarify this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I screwed up with decoder. Please add assertion for codec then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is taken care of in Just noticed the error message uses the incorrect codec identifiers I can fix this once the CI finishes. |
||
writer.open(fileName, fourcc, fps, sz, { VideoWriterProperties::VIDEOWRITER_PROP_RAW_VIDEO, 1, VideoWriterProperties::VIDEOWRITER_PROP_KEY_INTERVAL, idrPeriod }); | ||
if (!writer.isOpened()) | ||
CV_Error(Error::StsUnsupportedFormat, "Unsupported video sink"); | ||
} | ||
|
||
void FFmpegVideoWriter::onEncodingFinished() { | ||
writer.release(); | ||
} | ||
|
||
FFmpegVideoWriter::~FFmpegVideoWriter() { | ||
onEncodingFinished(); | ||
} | ||
|
||
void FFmpegVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) { | ||
for (auto& packet : vPacket) { | ||
Mat wrappedPacket(1, packet.size(), CV_8UC1, (void*)packet.data()); | ||
writer.write(wrappedPacket); | ||
} | ||
} | ||
|
||
|
||
class RawVideoWriter : public EncoderCallback | ||
{ | ||
public: | ||
RawVideoWriter(String fileName); | ||
RawVideoWriter(const String fileName); | ||
~RawVideoWriter(); | ||
void onEncoded(std::vector<std::vector<uint8_t>> vPacket); | ||
void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket); | ||
void onEncodingFinished(); | ||
private: | ||
std::ofstream fpOut; | ||
|
@@ -93,9 +128,9 @@ RawVideoWriter::~RawVideoWriter() { | |
onEncodingFinished(); | ||
} | ||
|
||
void RawVideoWriter::onEncoded(std::vector<std::vector<uint8_t>> vPacket) { | ||
void RawVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) { | ||
for (auto& packet : vPacket) | ||
fpOut.write(reinterpret_cast<char*>(packet.data()), packet.size()); | ||
fpOut.write(reinterpret_cast<const char*>(packet.data()), packet.size()); | ||
} | ||
|
||
class VideoWriterImpl : public VideoWriter | ||
|
@@ -172,12 +207,6 @@ VideoWriterImpl::VideoWriterImpl(const Ptr<EncoderCallback>& encoderCallBack_, c | |
Init(codec, fps, frameSz); | ||
} | ||
|
||
VideoWriterImpl::VideoWriterImpl(const Ptr<EncoderCallback>& encoderCallback, const Size frameSz, const Codec codec, const double fps, | ||
const ColorFormat colorFormat, const Stream& stream) : | ||
VideoWriterImpl(encoderCallback, frameSz, codec, fps, colorFormat, EncoderParams(), stream) | ||
{ | ||
} | ||
|
||
void VideoWriterImpl::release() { | ||
pEnc->EndEncode(vPacket); | ||
encoderCallback->onEncoded(vPacket); | ||
|
@@ -271,12 +300,6 @@ GUID EncodingPresetGuid(const EncodePreset nvPreset) { | |
CV_Error(Error::StsUnsupportedFormat, msg); | ||
} | ||
|
||
bool Equal(const GUID& g1, const GUID& g2) { | ||
if (std::tie(g1.Data1, g1.Data2, g1.Data3, g1.Data4) == std::tie(g2.Data1, g2.Data2, g2.Data3, g2.Data4)) | ||
return true; | ||
return false; | ||
} | ||
|
||
void VideoWriterImpl::InitializeEncoder(const GUID codec, const double fps) | ||
{ | ||
NV_ENC_INITIALIZE_PARAMS initializeParams = {}; | ||
|
@@ -293,10 +316,10 @@ void VideoWriterImpl::InitializeEncoder(const GUID codec, const double fps) | |
initializeParams.encodeConfig->rcParams.maxBitRate = encoderParams.maxBitRate; | ||
initializeParams.encodeConfig->rcParams.targetQuality = encoderParams.targetQuality; | ||
initializeParams.encodeConfig->gopLength = encoderParams.gopLength; | ||
if (Equal(codec, NV_ENC_CODEC_H264_GUID)) | ||
initializeParams.encodeConfig->encodeCodecConfig.h264Config.idrPeriod = encoderParams.gopLength; | ||
else if (Equal(codec, NV_ENC_CODEC_HEVC_GUID)) | ||
initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.idrPeriod = encoderParams.gopLength; | ||
if (codec == NV_ENC_CODEC_H264_GUID) | ||
initializeParams.encodeConfig->encodeCodecConfig.h264Config.idrPeriod = encoderParams.idrPeriod; | ||
else if (codec == NV_ENC_CODEC_HEVC_GUID) | ||
initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.idrPeriod = encoderParams.idrPeriod; | ||
pEnc->CreateEncoder(&initializeParams); | ||
} | ||
|
||
|
@@ -371,14 +394,25 @@ EncoderParams VideoWriterImpl::getEncoderParams() const { | |
Ptr<VideoWriter> createVideoWriter(const String& fileName, const Size frameSize, const Codec codec, const double fps, const ColorFormat colorFormat, | ||
Ptr<EncoderCallback> encoderCallback, const Stream& stream) | ||
{ | ||
encoderCallback = encoderCallback ? encoderCallback : new RawVideoWriter(fileName); | ||
return makePtr<VideoWriterImpl>(encoderCallback, frameSize, codec, fps, colorFormat, stream); | ||
return createVideoWriter(fileName, frameSize, codec, fps, colorFormat, EncoderParams(), encoderCallback, stream); | ||
} | ||
|
||
Ptr<VideoWriter> createVideoWriter(const String& fileName, const Size frameSize, const Codec codec, const double fps, const ColorFormat colorFormat, | ||
const EncoderParams& params, Ptr<EncoderCallback> encoderCallback, const Stream& stream) | ||
{ | ||
encoderCallback = encoderCallback ? encoderCallback : new RawVideoWriter(fileName); | ||
CV_Assert(params.idrPeriod >= params.gopLength); | ||
if (!encoderCallback) { | ||
// required until PR for raw video encapsulation is merged and windows dll is updated | ||
#ifndef WIN32 // remove #define and keep code once merged | ||
try { | ||
encoderCallback = new FFmpegVideoWriter(fileName, codec, fps, frameSize, params.idrPeriod); | ||
} | ||
catch (...) | ||
#endif | ||
{ | ||
encoderCallback = new RawVideoWriter(fileName); | ||
} | ||
} | ||
return makePtr<VideoWriterImpl>(encoderCallback, frameSize, codec, fps, colorFormat, params, stream); | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.