Skip to content

Commit 9ccca57

Browse files
committed
Update cudacodec::VideoWriter to work with the latest Nvidia Video Codec SDK
1 parent c4027ab commit 9ccca57

File tree

12 files changed

+2432
-1032
lines changed

12 files changed

+2432
-1032
lines changed

modules/cudacodec/CMakeLists.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ if(HAVE_NVCUVID)
1818
endif()
1919

2020
if(HAVE_NVCUVENC)
21-
if(WIN32)
22-
list(APPEND extra_libs ${CUDA_nvcuvenc_LIBRARY})
23-
endif()
21+
list(APPEND extra_libs ${CUDA_CUDA_LIBRARY} ${CUDA_nvencodeapi_LIBRARY})
22+
ocv_add_module(cudacodec opencv_cudaimgproc)
2423
endif()
2524

2625
ocv_create_module(${extra_libs})
2726

2827
ocv_add_accuracy_tests()
29-
ocv_add_perf_tests()
28+
ocv_add_perf_tests()

modules/cudacodec/include/opencv2/cudacodec.hpp

Lines changed: 227 additions & 120 deletions
Large diffs are not rendered by default.

modules/cudacodec/misc/python/pyopencv_cudacodec.hpp

Lines changed: 0 additions & 10 deletions
This file was deleted.

modules/cudacodec/misc/python/test/test_cudacodec.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
import cv2 as cv
44
import numpy as np
5-
5+
import tempfile
66
from tests_common import NewOpenCVTests, unittest
77

88
class cudacodec_test(NewOpenCVTests):
@@ -79,12 +79,25 @@ def test_writer_existence(self):
7979
#Test at least the existence of wrapped functions for now
8080

8181
try:
82-
_writer = cv.cudacodec.createVideoWriter("tmp", (128, 128), 30)
82+
_, fname = tempfile.mkstemp(suffix=".h264")
83+
encoder_params_in = cv.cudacodec.EncoderParams()
84+
encoder_params_in.gopLength = 10
85+
stream = cv.cuda.Stream()
86+
sz = (1920,1080)
87+
writer = cv.cudacodec.createVideoWriter(fname, sz, cv.cudacodec.VideoWriterCodec_H264, 30, cv.cudacodec.ColorFormat_BGR,
88+
encoder_params_in, stream)
89+
blankFrameIn = cv.cuda.GpuMat(sz,cv.CV_8UC3)
90+
writer.write(blankFrameIn)
91+
writer.close()
92+
encoder_params_out = writer.getEncoderParams()
93+
self.assert_true(encoder_params_in.gopLength == encoder_params_out.gopLength)
94+
cap = cv.VideoCapture(fname,cv.CAP_FFMPEG)
95+
self.assert_true(cap.isOpened())
96+
ret, blankFrameOut = cap.read()
97+
self.assert_true(ret and blankFrameOut.shape == blankFrameIn.download().shape)
8398
except cv.error as e:
8499
self.assertEqual(e.code, cv.Error.StsNotImplemented)
85-
self.skipTest("NVCUVENC is not installed")
86-
87-
self.assertTrue(True) #It is sufficient that no exceptions have been there
100+
self.skipTest("Either NVCUVENC or a GPU hardware encoder is missing or the encoding profile is not supported.")
88101

89102
if __name__ == '__main__':
90103
NewOpenCVTests.bootstrap()

modules/cudacodec/perf/perf_video.cpp

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
namespace opencv_test { namespace {
4747

48-
#if defined(HAVE_NVCUVID)
48+
#if defined(HAVE_NVCUVID) || defined(HAVE_NVCUVENC)
4949

5050
#if defined(HAVE_FFMPEG_WRAPPER) // should this be set in preprocessor or in cvconfig.h
5151
#define VIDEO_SRC Values("cv/video/768x576.avi", "cv/video/1920x1080.avi")
@@ -54,6 +54,8 @@ namespace opencv_test { namespace {
5454
#define VIDEO_SRC Values( "cv/video/1920x1080.avi")
5555
#endif
5656

57+
#if defined(HAVE_NVCUVID)
58+
5759
DEF_PARAM_TEST_1(FileName, string);
5860

5961
//////////////////////////////////////////////////////
@@ -93,63 +95,93 @@ PERF_TEST_P(FileName, VideoReader, VIDEO_SRC)
9395
//////////////////////////////////////////////////////
9496
// VideoWriter
9597

96-
#if defined(HAVE_NVCUVID) && defined(_WIN32)
98+
#if defined(HAVE_NVCUVENC)
9799

98-
PERF_TEST_P(FileName, VideoWriter, VIDEO_SRC)
99-
{
100-
declare.time(30);
101-
102-
const string inputFile = perf::TestBase::getDataPath(GetParam());
103-
const string outputFile = cv::tempfile(".avi");
100+
DEF_PARAM_TEST(WriteToFile, string, cv::cudacodec::COLOR_FORMAT_CV, cv::cudacodec::VideoWriterCodec);
104101

105-
const double FPS = 25.0;
102+
#define COLOR_FORMAT Values(cv::cudacodec::COLOR_FORMAT_CV::BGR, cv::cudacodec::COLOR_FORMAT_CV::RGB, cv::cudacodec::COLOR_FORMAT_CV::BGRA, \
103+
cv::cudacodec::COLOR_FORMAT_CV::RGBA, cv::cudacodec::COLOR_FORMAT_CV::GRAY)
104+
#define CODEC Values(cv::cudacodec::VideoWriterCodec::H264, cv::cudacodec::VideoWriterCodec::HEVC)
106105

106+
PERF_TEST_P(WriteToFile, VideoWriter, Combine(VIDEO_SRC, COLOR_FORMAT, CODEC))
107+
{
108+
declare.time(30);
109+
const string inputFile = perf::TestBase::getDataPath(GET_PARAM(0));
110+
const cv::cudacodec::COLOR_FORMAT_CV surfaceFormat = GET_PARAM(1);
111+
const cudacodec::VideoWriterCodec codec = GET_PARAM(2);
112+
const double fps = 25;
113+
const int nFrames = 20;
107114
cv::VideoCapture reader(inputFile);
108-
ASSERT_TRUE( reader.isOpened() );
109-
110-
cv::Mat frame;
111-
112-
if (PERF_RUN_CUDA())
113-
{
114-
cv::Ptr<cv::cudacodec::VideoWriter> d_writer;
115-
116-
cv::cuda::GpuMat d_frame;
117-
118-
for (int i = 0; i < 10; ++i)
119-
{
120-
reader >> frame;
121-
ASSERT_FALSE(frame.empty());
122-
123-
d_frame.upload(frame);
124-
125-
if (d_writer.empty())
126-
d_writer = cv::cudacodec::createVideoWriter(outputFile, frame.size(), FPS);
127-
128-
startTimer(); next();
129-
d_writer->write(d_frame);
115+
ASSERT_TRUE(reader.isOpened());
116+
Mat frameBgr;
117+
if (PERF_RUN_CUDA()) {
118+
const std::string ext = codec == cudacodec::VideoWriterCodec::H264 ? ".h264" : ".hevc";
119+
const string outputFile = cv::tempfile(ext.c_str());
120+
std::vector<GpuMat> frames;
121+
cv::Mat frameNewSf;
122+
cuda::Stream stream;
123+
ColorConversionCodes conversionCode = COLOR_COLORCVT_MAX;
124+
switch (surfaceFormat) {
125+
case cudacodec::COLOR_FORMAT_CV::RGB:
126+
conversionCode = COLOR_BGR2RGB;
127+
break;
128+
case cudacodec::COLOR_FORMAT_CV::BGRA:
129+
conversionCode = COLOR_BGR2BGRA;
130+
break;
131+
case cudacodec::COLOR_FORMAT_CV::RGBA:
132+
conversionCode = COLOR_BGR2RGBA;
133+
break;
134+
case cudacodec::COLOR_FORMAT_CV::GRAY:
135+
conversionCode = COLOR_BGR2GRAY;
136+
default:
137+
break;
138+
}
139+
for (int i = 0; i < nFrames; i++) {
140+
reader >> frameBgr;
141+
ASSERT_FALSE(frameBgr.empty());
142+
if (conversionCode == COLOR_COLORCVT_MAX)
143+
frameNewSf = frameBgr;
144+
else
145+
cv::cvtColor(frameBgr, frameNewSf, conversionCode);
146+
GpuMat frame; frame.upload(frameNewSf, stream);
147+
frames.push_back(frame);
148+
}
149+
stream.waitForCompletion();
150+
cv::Ptr<cv::cudacodec::VideoWriter> d_writer = cv::cudacodec::createVideoWriter(outputFile, frameBgr.size(), codec, fps, surfaceFormat, stream);
151+
for (int i = 0; i < nFrames - 1; ++i) {
152+
startTimer();
153+
d_writer->write(frames[i]);
130154
stopTimer();
131155
}
156+
startTimer();
157+
d_writer->write(frames[nFrames - 1]);
158+
d_writer->close();
159+
stopTimer();
132160
}
133-
else
134-
{
161+
else {
162+
if (surfaceFormat != cv::cudacodec::COLOR_FORMAT_CV::BGR || codec != cv::cudacodec::VideoWriterCodec::H264)
163+
throw PerfSkipTestException();
135164
cv::VideoWriter writer;
136-
137-
for (int i = 0; i < 10; ++i)
138-
{
139-
reader >> frame;
140-
ASSERT_FALSE(frame.empty());
141-
165+
const string outputFile = cv::tempfile(".avi");
166+
for (int i = 0; i < nFrames-1; ++i) {
167+
reader >> frameBgr;
168+
ASSERT_FALSE(frameBgr.empty());
142169
if (!writer.isOpened())
143-
writer.open(outputFile, VideoWriter::fourcc('X', 'V', 'I', 'D'), FPS, frame.size());
144-
145-
startTimer(); next();
146-
writer.write(frame);
170+
writer.open(outputFile, VideoWriter::fourcc('x', '2', '6', '4'), fps, frameBgr.size());
171+
startTimer();
172+
writer.write(frameBgr);
147173
stopTimer();
148174
}
175+
reader >> frameBgr;
176+
ASSERT_FALSE(frameBgr.empty());
177+
startTimer();
178+
writer.write(frameBgr);
179+
writer.release();
180+
stopTimer();
149181
}
150-
151-
SANITY_CHECK(frame);
182+
SANITY_CHECK(frameBgr);
152183
}
153184

185+
#endif
154186
#endif
155187
}} // namespace

0 commit comments

Comments
 (0)