Skip to content

Commit

Permalink
Merge branch 4.x
Browse files Browse the repository at this point in the history
  • Loading branch information
asmorkalov committed Nov 2, 2023
2 parents 219eaec + d51add3 commit 72721eb
Show file tree
Hide file tree
Showing 20 changed files with 507 additions and 436 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/PR-5.x.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ jobs:

macOS-X64:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-Contrib-PR-5.x-macOS-x86_64.yaml@main

Linux-RISC-V-Clang:
uses: opencv/ci-gha-workflow/.github/workflows/OCV-Contrib-PR-5.x-RISCV.yaml@main
2 changes: 1 addition & 1 deletion modules/cudaarithm/test/test_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ CUDA_TEST_P(AsyncEvent, Timing)
const double elTimeMs = Event::elapsedTime(startEvent, stopEvent);
ASSERT_GT(elTimeMs, 0);
}
catch (cv::Exception ex) {
catch (const cv::Exception& ex) {
failed = true;
}
ASSERT_EQ(failed, shouldFail.at(i));
Expand Down
38 changes: 19 additions & 19 deletions modules/cudacodec/include/opencv2/cudacodec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,18 +184,18 @@ struct CV_EXPORTS_W_SIMPLE EncoderParams
public:
CV_WRAP EncoderParams() : nvPreset(ENC_PRESET_P3), tuningInfo(ENC_TUNING_INFO_HIGH_QUALITY), encodingProfile(ENC_CODEC_PROFILE_AUTOSELECT),
rateControlMode(ENC_PARAMS_RC_VBR), multiPassEncoding(ENC_MULTI_PASS_DISABLED), constQp({ 0,0,0 }), averageBitRate(0), maxBitRate(0),
targetQuality(30), gopLength(0) {};

targetQuality(30), gopLength(250), idrPeriod(250) {};
CV_PROP_RW EncodePreset nvPreset;
CV_PROP_RW EncodeTuningInfo tuningInfo;
CV_PROP_RW EncodeProfile encodingProfile;
CV_PROP_RW EncodeParamsRcMode rateControlMode;
CV_PROP_RW EncodeMultiPass multiPassEncoding;
CV_PROP_RW EncodeQp constQp; //!< QP's for ENC_PARAMS_RC_CONSTQP.
CV_PROP_RW int averageBitRate; //!< target bitrate for ENC_PARAMS_RC_VBR and ENC_PARAMS_RC_CBR.
CV_PROP_RW int maxBitRate; //!< upper bound on bitrate for ENC_PARAMS_RC_VBR and ENC_PARAMS_RC_CONSTQP.
CV_PROP_RW uint8_t targetQuality; //!< value 0 - 51 where video quality decreases as targetQuality increases, used with ENC_PARAMS_RC_VBR.
CV_PROP_RW int gopLength;
CV_PROP_RW EncodeQp constQp; //!< QP's for \ref ENC_PARAMS_RC_CONSTQP.
CV_PROP_RW int averageBitRate; //!< target bitrate for \ref ENC_PARAMS_RC_VBR and \ref ENC_PARAMS_RC_CBR.
CV_PROP_RW int maxBitRate; //!< upper bound on bitrate for \ref ENC_PARAMS_RC_VBR and \ref ENC_PARAMS_RC_CONSTQP.
CV_PROP_RW uint8_t targetQuality; //!< value 0 - 51 where video quality decreases as targetQuality increases, used with \ref ENC_PARAMS_RC_VBR.
CV_PROP_RW int gopLength; //!< the number of pictures in one GOP, ensuring \ref idrPeriod >= \ref gopLength.
CV_PROP_RW int idrPeriod; //!< IDR interval, ensuring \ref idrPeriod >= \ref gopLength.
};
CV_EXPORTS bool operator==(const EncoderParams& lhs, const EncoderParams& rhs);

Expand All @@ -209,7 +209,7 @@ class CV_EXPORTS_W EncoderCallback {
@param vPacket The raw bitstream for one or more frames.
*/
virtual void onEncoded(std::vector<std::vector<uint8_t>> vPacket) = 0;
virtual void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) = 0;

/** @brief Callback function to that the encoding has finished.
* */
Expand All @@ -218,14 +218,14 @@ class CV_EXPORTS_W EncoderCallback {
virtual ~EncoderCallback() {}
};

/** @brief Video writer interface.
/** @brief Video writer interface, see createVideoWriter().
Available when built with WITH_NVCUVENC=ON while Nvidia's Video Codec SDK is installed.
Available if Nvidia's Video Codec SDK is installed.
Encoding support is dependent on the GPU, refer to the Nvidia Video Codec SDK Video Encode and Decode GPU Support Matrix for details.
Only Codec::H264 and Codec::HEVC are supported with encoding support dependent on the GPU, refer to the Nvidia Video Codec SDK Video Encode and Decode GPU Support Matrix for details.
@note
- An example on how to use the videoWriter class can be found at
- An example on how to use the VideoWriter class can be found at
opencv_source_code/samples/gpu/video_writer.cpp
*/
class CV_EXPORTS_W VideoWriter
Expand Down Expand Up @@ -253,9 +253,9 @@ class CV_EXPORTS_W VideoWriter

/** @brief Creates video writer.
@param fileName Name of the output video file. Only raw h264 or hevc files are supported.
@param fileName Name of the output video file.
@param frameSize Size of the input video frames.
@param codec Codec.
@param codec Supports Codec::H264 and Codec::HEVC.
@param fps Framerate of the created video stream.
@param colorFormat OpenCv color format of the frames to be encoded.
@param encoderCallback Callbacks for video encoder. See cudacodec::EncoderCallback. Required for working with the encoded video stream.
Expand All @@ -266,9 +266,9 @@ CV_EXPORTS_W Ptr<cudacodec::VideoWriter> createVideoWriter(const String& fileNam

/** @brief Creates video writer.
@param fileName Name of the output video file. Only raw h264 or hevc files are supported.
@param fileName Name of the output video file.
@param frameSize Size of the input video frames.
@param codec Codec.
@param codec Supports Codec::H264 and Codec::HEVC.
@param fps Framerate of the created video stream.
@param colorFormat OpenCv color format of the frames to be encoded.
@param params Additional encoding parameters.
Expand Down Expand Up @@ -361,14 +361,14 @@ enum class VideoReaderProps {
#endif
};

/** @brief Video reader interface.
/** @brief Video reader interface, see createVideoReader().
Available when built with WITH_NVCUVID=ON while Nvidia's Video Codec SDK is installed.
Available if Nvidia's Video Codec SDK is installed.
Decoding support is dependent on the GPU, refer to the Nvidia Video Codec SDK Video Encode and Decode GPU Support Matrix for details.
@note
- An example on how to use the videoReader class can be found at
- An example on how to use the VideoReader interface can be found at
opencv_source_code/samples/gpu/video_reader.cpp
*/
class CV_EXPORTS_W VideoReader
Expand Down
10 changes: 0 additions & 10 deletions modules/cudacodec/src/NvEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@
#include "NvEncoder.h"

namespace cv { namespace cudacodec {
#ifndef _WIN32
#include <cstring>
static inline bool operator==(const GUID& guid1, const GUID& guid2) {
return !memcmp(&guid1, &guid2, sizeof(GUID));
}

static inline bool operator!=(const GUID& guid1, const GUID& guid2) {
return !(guid1 == guid2);
}
#endif

NvEncoder::NvEncoder(NV_ENC_DEVICE_TYPE eDeviceType, void* pDevice, uint32_t nWidth, uint32_t nHeight, NV_ENC_BUFFER_FORMAT eBufferFormat,
uint32_t nExtraOutputDelay) :
Expand Down
11 changes: 11 additions & 0 deletions modules/cudacodec/src/NvEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@

namespace cv { namespace cudacodec {

#ifndef _WIN32
#include <cstring>
static inline bool operator==(const GUID& guid1, const GUID& guid2) {
return !memcmp(&guid1, &guid2, sizeof(GUID));
}

static inline bool operator!=(const GUID& guid1, const GUID& guid2) {
return !(guid1 == guid2);
}
#endif

#define NVENC_THROW_ERROR( errorStr, errorCode ) \
do \
{ \
Expand Down
82 changes: 58 additions & 24 deletions modules/cudacodec/src/video_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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');
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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 = {};
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down
Loading

0 comments on commit 72721eb

Please sign in to comment.