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 Sep 10, 2024
2 parents cda2184 + 0377a6a commit a15a0ea
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 36 deletions.
20 changes: 5 additions & 15 deletions modules/cudaarithm/src/cuda/polar_cart.cu
Original file line number Diff line number Diff line change
Expand Up @@ -159,25 +159,15 @@ void cv::cuda::cartToPolar(InputArray _xy, OutputArray _mag, OutputArray _angle,
GpuMat_<float> magc(mag);
GpuMat_<float> anglec(angle);

gridTransformUnary(globPtr<float2>(xy), globPtr<float>(magc), magnitude_interleaved_func<float2>(), stream);

if (angleInDegrees)
{
auto f1 = magnitude_interleaved_func<float2>();
auto f2 = direction_interleaved_func<float2, true>();
cv::cudev::tuple<decltype(f1), decltype(f2)> f12 = cv::cudev::make_tuple(f1, f2);
gridTransformTuple(globPtr<float2>(xy),
tie(magc, anglec),
f12,
stream);
gridTransformUnary(globPtr<float2>(xy), globPtr<float>(anglec), direction_interleaved_func<float2, true>(), stream);
}
else
{
auto f1 = magnitude_interleaved_func<float2>();
auto f2 = direction_interleaved_func<float2, false>();
cv::cudev::tuple<decltype(f1), decltype(f2)> f12 = cv::cudev::make_tuple(f1, f2);
gridTransformTuple(globPtr<float2>(xy),
tie(magc, anglec),
f12,
stream);
gridTransformUnary(globPtr<float2>(xy), globPtr<float>(anglec), direction_interleaved_func<float2, false>(), stream);
}

syncOutput(mag, _mag, stream);
Expand All @@ -191,7 +181,7 @@ void cv::cuda::cartToPolar(InputArray _xy, OutputArray _magAngle, bool angleInDe
CV_Assert( xy.type() == CV_32FC2 );

GpuMat magAngle = getOutputMat(_magAngle, xy.size(), CV_32FC2, stream);

if (angleInDegrees)
{
gridTransformUnary(globPtr<float2>(xy),
Expand Down
9 changes: 8 additions & 1 deletion modules/cudacodec/include/opencv2/cudacodec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,15 @@ class CV_EXPORTS_W EncoderCallback {
/** @brief Callback function to signal that the encoded bitstream for one or more frames is ready.
@param vPacket The raw bitstream for one or more frames.
@param pts Presentation timestamps for each frame in vPacket using the FPS time base. e.g. fps = 25, pts = 3, presentation time = 3/25 seconds.
*/
virtual void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) = 0;
virtual void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket, const std::vector<uint64_t>& pts) = 0;

/** @brief Set the GOP pattern used by the encoder.
@param frameIntervalP Specify the GOP pattern as follows : \p frameIntervalP = 0: I, 1 : IPP, 2 : IBP, 3 : IBBP.
*/
virtual bool setFrameIntervalP(const int frameIntervalP) = 0;

/** @brief Callback function to that the encoding has finished.
* */
Expand Down
16 changes: 10 additions & 6 deletions modules/cudacodec/src/NvEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,10 @@ void NvEncoder::MapResources(uint32_t bfrIdx)
m_vMappedInputBuffers[bfrIdx] = mapInputResource.mappedResource;
}

void NvEncoder::EncodeFrame(std::vector<std::vector<uint8_t>>& vPacket, NV_ENC_PIC_PARAMS* pPicParams)
void NvEncoder::EncodeFrame(std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps, NV_ENC_PIC_PARAMS* pPicParams)
{
vPacket.clear();
outputTimeStamps.clear();
if (!IsHWEncoderInitialized())
{
NVENC_THROW_ERROR("Encoder device not found", NV_ENC_ERR_NO_ENCODE_DEVICE);
Expand All @@ -322,7 +323,7 @@ void NvEncoder::EncodeFrame(std::vector<std::vector<uint8_t>>& vPacket, NV_ENC_P
if (nvStatus == NV_ENC_SUCCESS || nvStatus == NV_ENC_ERR_NEED_MORE_INPUT)
{
m_iToSend++;
GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, true);
GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, outputTimeStamps, true);
}
else
{
Expand Down Expand Up @@ -353,6 +354,7 @@ NVENCSTATUS NvEncoder::DoEncode(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_OUTPUT_PTR
{
picParams = *pPicParams;
}
picParams.inputTimeStamp = m_iInputFrame++;
picParams.version = NV_ENC_PIC_PARAMS_VER;
picParams.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
picParams.inputBuffer = inputBuffer;
Expand All @@ -376,7 +378,7 @@ void NvEncoder::SendEOS()
NVENC_API_CALL(m_nvenc.nvEncEncodePicture(m_hEncoder, &picParams));
}

void NvEncoder::EndEncode(std::vector<std::vector<uint8_t>>& vPacket)
void NvEncoder::EndEncode(std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps)
{
vPacket.clear();
if (!IsHWEncoderInitialized())
Expand All @@ -386,10 +388,10 @@ void NvEncoder::EndEncode(std::vector<std::vector<uint8_t>>& vPacket)

SendEOS();

GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, false);
GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, outputTimeStamps, false);
}

void NvEncoder::GetEncodedPacket(std::vector<NV_ENC_OUTPUT_PTR>& vOutputBuffer, std::vector<std::vector<uint8_t>>& vPacket, bool bOutputDelay)
void NvEncoder::GetEncodedPacket(std::vector<NV_ENC_OUTPUT_PTR>& vOutputBuffer, std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps, bool bOutputDelay)
{
unsigned i = 0;
int iEnd = bOutputDelay ? m_iToSend - m_nOutputDelay : m_iToSend;
Expand All @@ -402,6 +404,7 @@ void NvEncoder::GetEncodedPacket(std::vector<NV_ENC_OUTPUT_PTR>& vOutputBuffer,
lockBitstreamData.doNotWait = false;
NVENC_API_CALL(m_nvenc.nvEncLockBitstream(m_hEncoder, &lockBitstreamData));

outputTimeStamps.push_back(lockBitstreamData.outputTimeStamp);
uint8_t* pData = (uint8_t*)lockBitstreamData.bitstreamBufferPtr;
if (vPacket.size() < i + 1)
{
Expand Down Expand Up @@ -499,7 +502,8 @@ void NvEncoder::FlushEncoder()
try
{
std::vector<std::vector<uint8_t>> vPacket;
EndEncode(vPacket);
std::vector<uint64_t> outputTimeStamps;
EndEncode(vPacket, outputTimeStamps);
}
catch (...)
{
Expand Down
7 changes: 4 additions & 3 deletions modules/cudacodec/src/NvEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class NvEncoder
* data, which has been copied to an input buffer obtained from the
* GetNextInputFrame() function.
*/
virtual void EncodeFrame(std::vector<std::vector<uint8_t>>& vPacket, NV_ENC_PIC_PARAMS* pPicParams = nullptr);
virtual void EncodeFrame(std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps, NV_ENC_PIC_PARAMS* pPicParams = nullptr);

/**
* @brief This function to flush the encoder queue.
Expand All @@ -109,7 +109,7 @@ class NvEncoder
* from the encoder. The application must call this function before destroying
* an encoder session.
*/
virtual void EndEncode(std::vector<std::vector<uint8_t>>& vPacket);
virtual void EndEncode(std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps);

/**
* @brief This function is used to query hardware encoder capabilities.
Expand Down Expand Up @@ -317,7 +317,7 @@ class NvEncoder
* This is called by DoEncode() function. If there is buffering enabled,
* this may return without any output data.
*/
void GetEncodedPacket(std::vector<NV_ENC_OUTPUT_PTR>& vOutputBuffer, std::vector<std::vector<uint8_t>>& vPacket, bool bOutputDelay);
void GetEncodedPacket(std::vector<NV_ENC_OUTPUT_PTR>& vOutputBuffer, std::vector<std::vector<uint8_t>>& vPacket, std::vector<uint64_t>& outputTimeStamps, bool bOutputDelay);

/**
* @brief This is a private function which is used to initialize the bitstream buffers.
Expand Down Expand Up @@ -369,6 +369,7 @@ class NvEncoder
int32_t m_iGot = 0;
int32_t m_nEncoderBuffer = 0;
int32_t m_nOutputDelay = 0;
int32_t m_iInputFrame = 0;

private:
void* m_pDevice;
Expand Down
41 changes: 32 additions & 9 deletions modules/cudacodec/src/video_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ Ptr<cudacodec::VideoWriter> createVideoWriter(const String&, const Size, const C

#else // !defined HAVE_NVCUVENC

#if defined(WIN32) // remove when FFmpeg wrapper includes PR25874
#define WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE
#endif

NV_ENC_BUFFER_FORMAT EncBufferFormat(const ColorFormat colorFormat);
int NChannels(const ColorFormat colorFormat);
GUID CodecGuid(const Codec codec);
Expand All @@ -72,8 +76,9 @@ 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 onEncoded(const std::vector<std::vector<uint8_t>>& vPacket, const std::vector<uint64_t>& pts);
void onEncodingFinished();
bool setFrameIntervalP(const int frameIntervalP);
private:
cv::VideoWriter writer;
};
Expand All @@ -95,21 +100,32 @@ FFmpegVideoWriter::~FFmpegVideoWriter() {
onEncodingFinished();
}

void FFmpegVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) {
for (auto& packet : vPacket) {
void FFmpegVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket, const std::vector<uint64_t>& pts) {
CV_Assert(vPacket.size() == pts.size());
for (int i = 0; i < vPacket.size(); i++){
std::vector<uint8_t> packet = vPacket.at(i);
Mat wrappedPacket(1, packet.size(), CV_8UC1, (void*)packet.data());
const double ptsDouble = static_cast<double>(pts.at(i));
CV_Assert(static_cast<uint64_t>(ptsDouble) == pts.at(i));
#if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
CV_Assert(writer.set(VIDEOWRITER_PROP_PTS, ptsDouble));
#endif
writer.write(wrappedPacket);
}
}

bool FFmpegVideoWriter::setFrameIntervalP(const int frameIntervalP) {
return writer.set(VIDEOWRITER_PROP_DTS_DELAY, static_cast<double>(frameIntervalP - 1));
}

class RawVideoWriter : public EncoderCallback
{
public:
RawVideoWriter(const String fileName);
~RawVideoWriter();
void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket);
void onEncoded(const std::vector<std::vector<uint8_t>>& vPacket, const std::vector<uint64_t>& pts);
void onEncodingFinished();
bool setFrameIntervalP(const int) { return false;}
private:
std::ofstream fpOut;
};
Expand All @@ -128,7 +144,7 @@ RawVideoWriter::~RawVideoWriter() {
onEncodingFinished();
}

void RawVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket) {
void RawVideoWriter::onEncoded(const std::vector<std::vector<uint8_t>>& vPacket, const std::vector<uint64_t>&) {
for (auto& packet : vPacket)
fpOut.write(reinterpret_cast<const char*>(packet.data()), packet.size());
}
Expand Down Expand Up @@ -208,8 +224,9 @@ VideoWriterImpl::VideoWriterImpl(const Ptr<EncoderCallback>& encoderCallBack_, c
}

void VideoWriterImpl::release() {
pEnc->EndEncode(vPacket);
encoderCallback->onEncoded(vPacket);
std::vector<uint64_t> pts;
pEnc->EndEncode(vPacket, pts);
encoderCallback->onEncoded(vPacket, pts);
encoderCallback->onEncodingFinished();
}

Expand Down Expand Up @@ -316,6 +333,11 @@ 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 !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
if (initializeParams.encodeConfig->frameIntervalP > 1) {
CV_Assert(encoderCallback->setFrameIntervalP(initializeParams.encodeConfig->frameIntervalP));
}
#endif
if (codec == NV_ENC_CODEC_H264_GUID)
initializeParams.encodeConfig->encodeCodecConfig.h264Config.idrPeriod = encoderParams.idrPeriod;
else if (codec == NV_ENC_CODEC_HEVC_GUID)
Expand Down Expand Up @@ -383,8 +405,9 @@ void VideoWriterImpl::CopyToNvSurface(const InputArray src)
void VideoWriterImpl::write(const InputArray frame) {
CV_Assert(frame.channels() == nSrcChannels);
CopyToNvSurface(frame);
pEnc->EncodeFrame(vPacket);
encoderCallback->onEncoded(vPacket);
std::vector<uint64_t> pts;
pEnc->EncodeFrame(vPacket, pts);
encoderCallback->onEncoded(vPacket, pts);
};

EncoderParams VideoWriterImpl::getEncoderParams() const {
Expand Down
15 changes: 15 additions & 0 deletions modules/cudacodec/test/test_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,9 @@ struct TransCode : testing::TestWithParam<cv::cuda::DeviceInfo>
}
};

#if defined(WIN32) // remove when FFmpeg wrapper includes PR25874
#define WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE
#endif

CUDA_TEST_P(TransCode, H264ToH265)
{
Expand Down Expand Up @@ -691,6 +694,10 @@ CUDA_TEST_P(TransCode, H264ToH265)
for (int i = 0; i < nFrames; ++i) {
cap >> frame;
ASSERT_FALSE(frame.empty());
#if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
const int pts = static_cast<int>(cap.get(CAP_PROP_PTS));
ASSERT_EQ(i, pts > 0 ? pts : 0); // FFmpeg back end returns dts if pts is zero.
#endif
}
}
ASSERT_EQ(0, remove(outputFile.c_str()));
Expand Down Expand Up @@ -773,6 +780,10 @@ CUDA_TEST_P(Write, Writer)
for (int i = 0; i < nFrames; ++i) {
cap >> frame;
ASSERT_FALSE(frame.empty());
#if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
const int pts = static_cast<int>(cap.get(CAP_PROP_PTS));
ASSERT_EQ(i, pts > 0 ? pts : 0); // FFmpeg back end returns dts if pts is zero.
#endif
}
}
ASSERT_EQ(0, remove(outputFile.c_str()));
Expand Down Expand Up @@ -867,6 +878,10 @@ CUDA_TEST_P(EncoderParams, Writer)
const bool keyFrameActual = capRaw.get(CAP_PROP_LRF_HAS_KEY_FRAME) == 1.0;
const bool keyFrameReference = i % idrPeriod == 0;
ASSERT_EQ(keyFrameActual, keyFrameReference);
#if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
const int pts = static_cast<int>(cap.get(CAP_PROP_PTS));
ASSERT_EQ(i, pts > 0 ? pts : 0); // FFmpeg back end returns dts if pts is zero.
#endif
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions modules/wechat_qrcode/src/zxing/zxing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#ifndef __ZXING_ZXING_HPP__
#define __ZXING_ZXING_HPP__

#include "opencv2/core/fast_math.hpp"

#define COUNTER_TYPE short

Expand Down Expand Up @@ -54,8 +55,8 @@ typedef unsigned char boolean;
#include <cmath>

namespace zxing {
inline bool isnan(float v) { return std::isnan(v); }
inline bool isnan(double v) { return std::isnan(v); }
inline bool isnan(float v) { return cvIsNaN(v) != 0; }
inline bool isnan(double v) { return cvIsNaN(v) != 0; }
inline float nan() { return std::numeric_limits<float>::quiet_NaN(); }
} // namespace zxing

Expand Down

0 comments on commit a15a0ea

Please sign in to comment.