@@ -59,7 +59,6 @@ GUID CodecGuid(const Codec codec);
59
59
void FrameRate (const double fps, uint32_t & frameRateNum, uint32_t & frameRateDen);
60
60
GUID EncodingProfileGuid (const EncodeProfile encodingProfile);
61
61
GUID EncodingPresetGuid (const EncodePreset nvPreset);
62
- bool Equal (const GUID& g1, const GUID& g2);
63
62
64
63
bool operator ==(const EncoderParams& lhs, const EncoderParams& rhs)
65
64
{
@@ -68,12 +67,48 @@ bool operator==(const EncoderParams& lhs, const EncoderParams& rhs)
68
67
rhs.averageBitRate , rhs.maxBitRate , rhs.targetQuality , rhs.gopLength );
69
68
};
70
69
70
+ class FFmpegVideoWriter : public EncoderCallback
71
+ {
72
+ public:
73
+ FFmpegVideoWriter (const String& fileName, const Codec codec, const int fps, const Size sz, const int idrPeriod);
74
+ ~FFmpegVideoWriter ();
75
+ void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket);
76
+ void onEncodingFinished ();
77
+ private:
78
+ cv::VideoWriter writer;
79
+ };
80
+
81
+ FFmpegVideoWriter::FFmpegVideoWriter (const String& fileName, const Codec codec, const int fps, const Size sz, const int idrPeriod) {
82
+ if (!videoio_registry::hasBackend (CAP_FFMPEG))
83
+ CV_Error (Error::StsNotImplemented, " FFmpeg backend not found" );
84
+ const int fourcc = codec == Codec::H264 ? cv::VideoWriter::fourcc (' a' , ' v' , ' c' , ' 1' ) : cv::VideoWriter::fourcc (' h' , ' e' , ' v' , ' 1' );
85
+ writer.open (fileName, fourcc, fps, sz, { VideoWriterProperties::VIDEOWRITER_PROP_RAW_VIDEO, 1 , VideoWriterProperties::VIDEOWRITER_PROP_KEY_INTERVAL, idrPeriod });
86
+ if (!writer.isOpened ())
87
+ CV_Error (Error::StsUnsupportedFormat, " Unsupported video sink" );
88
+ }
89
+
90
+ void FFmpegVideoWriter::onEncodingFinished () {
91
+ writer.release ();
92
+ }
93
+
94
+ FFmpegVideoWriter::~FFmpegVideoWriter () {
95
+ onEncodingFinished ();
96
+ }
97
+
98
+ void FFmpegVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket) {
99
+ for (auto & packet : vPacket) {
100
+ Mat wrappedPacket (1 , packet.size (), CV_8UC1, (void *)packet.data ());
101
+ writer.write (wrappedPacket);
102
+ }
103
+ }
104
+
105
+
71
106
class RawVideoWriter : public EncoderCallback
72
107
{
73
108
public:
74
- RawVideoWriter (String fileName);
109
+ RawVideoWriter (const String fileName);
75
110
~RawVideoWriter ();
76
- void onEncoded (std::vector<std::vector<uint8_t >> vPacket);
111
+ void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket);
77
112
void onEncodingFinished ();
78
113
private:
79
114
std::ofstream fpOut;
@@ -93,9 +128,9 @@ RawVideoWriter::~RawVideoWriter() {
93
128
onEncodingFinished ();
94
129
}
95
130
96
- void RawVideoWriter::onEncoded (std::vector<std::vector<uint8_t >> vPacket) {
131
+ void RawVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket) {
97
132
for (auto & packet : vPacket)
98
- fpOut.write (reinterpret_cast <char *>(packet.data ()), packet.size ());
133
+ fpOut.write (reinterpret_cast <const char *>(packet.data ()), packet.size ());
99
134
}
100
135
101
136
class VideoWriterImpl : public VideoWriter
@@ -172,12 +207,6 @@ VideoWriterImpl::VideoWriterImpl(const Ptr<EncoderCallback>& encoderCallBack_, c
172
207
Init (codec, fps, frameSz);
173
208
}
174
209
175
- VideoWriterImpl::VideoWriterImpl (const Ptr<EncoderCallback>& encoderCallback, const Size frameSz, const Codec codec, const double fps,
176
- const ColorFormat colorFormat, const Stream& stream) :
177
- VideoWriterImpl(encoderCallback, frameSz, codec, fps, colorFormat, EncoderParams(), stream)
178
- {
179
- }
180
-
181
210
void VideoWriterImpl::release () {
182
211
pEnc->EndEncode (vPacket);
183
212
encoderCallback->onEncoded (vPacket);
@@ -271,12 +300,6 @@ GUID EncodingPresetGuid(const EncodePreset nvPreset) {
271
300
CV_Error (Error::StsUnsupportedFormat, msg);
272
301
}
273
302
274
- bool Equal (const GUID& g1, const GUID& g2) {
275
- if (std::tie (g1.Data1 , g1.Data2 , g1.Data3 , g1.Data4 ) == std::tie (g2.Data1 , g2.Data2 , g2.Data3 , g2.Data4 ))
276
- return true ;
277
- return false ;
278
- }
279
-
280
303
void VideoWriterImpl::InitializeEncoder (const GUID codec, const double fps)
281
304
{
282
305
NV_ENC_INITIALIZE_PARAMS initializeParams = {};
@@ -293,10 +316,10 @@ void VideoWriterImpl::InitializeEncoder(const GUID codec, const double fps)
293
316
initializeParams.encodeConfig ->rcParams .maxBitRate = encoderParams.maxBitRate ;
294
317
initializeParams.encodeConfig ->rcParams .targetQuality = encoderParams.targetQuality ;
295
318
initializeParams.encodeConfig ->gopLength = encoderParams.gopLength ;
296
- if (Equal ( codec, NV_ENC_CODEC_H264_GUID) )
297
- initializeParams.encodeConfig ->encodeCodecConfig .h264Config .idrPeriod = encoderParams.gopLength ;
298
- else if (Equal ( codec, NV_ENC_CODEC_HEVC_GUID) )
299
- initializeParams.encodeConfig ->encodeCodecConfig .hevcConfig .idrPeriod = encoderParams.gopLength ;
319
+ if (codec == NV_ENC_CODEC_H264_GUID)
320
+ initializeParams.encodeConfig ->encodeCodecConfig .h264Config .idrPeriod = encoderParams.idrPeriod ;
321
+ else if (codec == NV_ENC_CODEC_HEVC_GUID)
322
+ initializeParams.encodeConfig ->encodeCodecConfig .hevcConfig .idrPeriod = encoderParams.idrPeriod ;
300
323
pEnc->CreateEncoder (&initializeParams);
301
324
}
302
325
@@ -371,14 +394,25 @@ EncoderParams VideoWriterImpl::getEncoderParams() const {
371
394
Ptr<VideoWriter> createVideoWriter (const String& fileName, const Size frameSize, const Codec codec, const double fps, const ColorFormat colorFormat,
372
395
Ptr<EncoderCallback> encoderCallback, const Stream& stream)
373
396
{
374
- encoderCallback = encoderCallback ? encoderCallback : new RawVideoWriter (fileName);
375
- return makePtr<VideoWriterImpl>(encoderCallback, frameSize, codec, fps, colorFormat, stream);
397
+ return createVideoWriter (fileName, frameSize, codec, fps, colorFormat, EncoderParams (), encoderCallback, stream);
376
398
}
377
399
378
400
Ptr<VideoWriter> createVideoWriter (const String& fileName, const Size frameSize, const Codec codec, const double fps, const ColorFormat colorFormat,
379
401
const EncoderParams& params, Ptr<EncoderCallback> encoderCallback, const Stream& stream)
380
402
{
381
- encoderCallback = encoderCallback ? encoderCallback : new RawVideoWriter (fileName);
403
+ CV_Assert (params.idrPeriod >= params.gopLength );
404
+ if (!encoderCallback) {
405
+ // required until PR for raw video encapsulation is merged and windows dll is updated
406
+ #ifndef WIN32 // remove #define and keep code once merged
407
+ try {
408
+ encoderCallback = new FFmpegVideoWriter (fileName, codec, fps, frameSize, params.idrPeriod );
409
+ }
410
+ catch (...)
411
+ #endif
412
+ {
413
+ encoderCallback = new RawVideoWriter (fileName);
414
+ }
415
+ }
382
416
return makePtr<VideoWriterImpl>(encoderCallback, frameSize, codec, fps, colorFormat, params, stream);
383
417
}
384
418
0 commit comments