@@ -53,6 +53,10 @@ Ptr<cudacodec::VideoWriter> createVideoWriter(const String&, const Size, const C
5353
5454#else // !defined HAVE_NVCUVENC
5555
56+ #if defined(WIN32) // remove when FFmpeg wrapper includes PR25874
57+ #define WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE
58+ #endif
59+
5660NV_ENC_BUFFER_FORMAT EncBufferFormat (const ColorFormat colorFormat);
5761int NChannels (const ColorFormat colorFormat);
5862GUID CodecGuid (const Codec codec);
@@ -72,8 +76,9 @@ class FFmpegVideoWriter : public EncoderCallback
7276public:
7377 FFmpegVideoWriter (const String& fileName, const Codec codec, const int fps, const Size sz, const int idrPeriod);
7478 ~FFmpegVideoWriter ();
75- void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket);
79+ void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket, const std::vector< uint64_t >& pts );
7680 void onEncodingFinished ();
81+ bool setFrameIntervalP (const int frameIntervalP);
7782private:
7883 cv::VideoWriter writer;
7984};
@@ -95,21 +100,32 @@ FFmpegVideoWriter::~FFmpegVideoWriter() {
95100 onEncodingFinished ();
96101}
97102
98- void FFmpegVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket) {
99- for (auto & packet : vPacket) {
103+ void FFmpegVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket, const std::vector<uint64_t >& pts) {
104+ CV_Assert (vPacket.size () == pts.size ());
105+ for (int i = 0 ; i < vPacket.size (); i++){
106+ std::vector<uint8_t > packet = vPacket.at (i);
100107 Mat wrappedPacket (1 , packet.size (), CV_8UC1, (void *)packet.data ());
108+ const double ptsDouble = static_cast <double >(pts.at (i));
109+ CV_Assert (static_cast <uint64_t >(ptsDouble) == pts.at (i));
110+ #if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
111+ CV_Assert (writer.set (VIDEOWRITER_PROP_PTS, ptsDouble));
112+ #endif
101113 writer.write (wrappedPacket);
102114 }
103115}
104116
117+ bool FFmpegVideoWriter::setFrameIntervalP (const int frameIntervalP) {
118+ return writer.set (VIDEOWRITER_PROP_DTS_DELAY, static_cast <double >(frameIntervalP - 1 ));
119+ }
105120
106121class RawVideoWriter : public EncoderCallback
107122{
108123public:
109124 RawVideoWriter (const String fileName);
110125 ~RawVideoWriter ();
111- void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket);
126+ void onEncoded (const std::vector<std::vector<uint8_t >>& vPacket, const std::vector< uint64_t >& pts );
112127 void onEncodingFinished ();
128+ bool setFrameIntervalP (const int ) { return false ;}
113129private:
114130 std::ofstream fpOut;
115131};
@@ -128,7 +144,7 @@ RawVideoWriter::~RawVideoWriter() {
128144 onEncodingFinished ();
129145}
130146
131- void RawVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket) {
147+ void RawVideoWriter::onEncoded (const std::vector<std::vector<uint8_t >>& vPacket, const std::vector< uint64_t >& ) {
132148 for (auto & packet : vPacket)
133149 fpOut.write (reinterpret_cast <const char *>(packet.data ()), packet.size ());
134150}
@@ -208,8 +224,9 @@ VideoWriterImpl::VideoWriterImpl(const Ptr<EncoderCallback>& encoderCallBack_, c
208224}
209225
210226void VideoWriterImpl::release () {
211- pEnc->EndEncode (vPacket);
212- encoderCallback->onEncoded (vPacket);
227+ std::vector<uint64_t > pts;
228+ pEnc->EndEncode (vPacket, pts);
229+ encoderCallback->onEncoded (vPacket, pts);
213230 encoderCallback->onEncodingFinished ();
214231}
215232
@@ -316,6 +333,11 @@ void VideoWriterImpl::InitializeEncoder(const GUID codec, const double fps)
316333 initializeParams.encodeConfig ->rcParams .maxBitRate = encoderParams.maxBitRate ;
317334 initializeParams.encodeConfig ->rcParams .targetQuality = encoderParams.targetQuality ;
318335 initializeParams.encodeConfig ->gopLength = encoderParams.gopLength ;
336+ #if !defined(WIN32_WAIT_FOR_FFMPEG_WRAPPER_UPDATE)
337+ if (initializeParams.encodeConfig ->frameIntervalP > 1 ) {
338+ CV_Assert (encoderCallback->setFrameIntervalP (initializeParams.encodeConfig ->frameIntervalP ));
339+ }
340+ #endif
319341 if (codec == NV_ENC_CODEC_H264_GUID)
320342 initializeParams.encodeConfig ->encodeCodecConfig .h264Config .idrPeriod = encoderParams.idrPeriod ;
321343 else if (codec == NV_ENC_CODEC_HEVC_GUID)
@@ -383,8 +405,9 @@ void VideoWriterImpl::CopyToNvSurface(const InputArray src)
383405void VideoWriterImpl::write (const InputArray frame) {
384406 CV_Assert (frame.channels () == nSrcChannels);
385407 CopyToNvSurface (frame);
386- pEnc->EncodeFrame (vPacket);
387- encoderCallback->onEncoded (vPacket);
408+ std::vector<uint64_t > pts;
409+ pEnc->EncodeFrame (vPacket, pts);
410+ encoderCallback->onEncoded (vPacket, pts);
388411};
389412
390413EncoderParams VideoWriterImpl::getEncoderParams () const {
0 commit comments