Skip to content

Commit dacc035

Browse files
committed
cudacodec: Add flag to signal whether the luma and chroma samples in the yuv frames passed to VideoWriter occupy the full or limited range as defined by the Annex E of the ITU-T Specification.
1 parent 0e5254e commit dacc035

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

modules/cudacodec/include/opencv2/cudacodec.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ struct CV_EXPORTS_W_SIMPLE EncoderParams
186186
public:
187187
CV_WRAP EncoderParams() : nvPreset(ENC_PRESET_P3), tuningInfo(ENC_TUNING_INFO_HIGH_QUALITY), encodingProfile(ENC_CODEC_PROFILE_AUTOSELECT),
188188
rateControlMode(ENC_PARAMS_RC_VBR), multiPassEncoding(ENC_MULTI_PASS_DISABLED), constQp({ 0,0,0 }), averageBitRate(0), maxBitRate(0),
189-
targetQuality(30), gopLength(250), idrPeriod(250) {};
189+
targetQuality(30), gopLength(250), idrPeriod(250), videoFullRangeFlag(false){};
190190
CV_PROP_RW EncodePreset nvPreset;
191191
CV_PROP_RW EncodeTuningInfo tuningInfo;
192192
CV_PROP_RW EncodeProfile encodingProfile;
@@ -198,6 +198,7 @@ struct CV_EXPORTS_W_SIMPLE EncoderParams
198198
CV_PROP_RW uint8_t targetQuality; //!< value 0 - 51 where video quality decreases as targetQuality increases, used with \ref ENC_PARAMS_RC_VBR.
199199
CV_PROP_RW int gopLength; //!< the number of pictures in one GOP, ensuring \ref idrPeriod >= \ref gopLength.
200200
CV_PROP_RW int idrPeriod; //!< IDR interval, ensuring \ref idrPeriod >= \ref gopLength.
201+
CV_PROP_RW bool videoFullRangeFlag;//!< Indicates if the black level, luma and chroma of the source are represented using the full or limited range (AKA TV or "analogue" range) of values as defined in Annex E of the ITU-T Specification.
201202
};
202203
CV_EXPORTS bool operator==(const EncoderParams& lhs, const EncoderParams& rhs);
203204

modules/cudacodec/src/video_writer.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,20 @@ void VideoWriterImpl::InitializeEncoder(const GUID codec, const double fps)
342342
CV_Assert(encoderCallback->setFrameIntervalP(initializeParams.encodeConfig->frameIntervalP));
343343
}
344344
#endif
345-
if (codec == NV_ENC_CODEC_H264_GUID)
345+
if (codec == NV_ENC_CODEC_H264_GUID) {
346346
initializeParams.encodeConfig->encodeCodecConfig.h264Config.idrPeriod = encoderParams.idrPeriod;
347-
else if (codec == NV_ENC_CODEC_HEVC_GUID)
347+
if (encoderParams.videoFullRangeFlag) {
348+
initializeParams.encodeConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag = 1;
349+
initializeParams.encodeConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoSignalTypePresentFlag = 1;
350+
}
351+
}
352+
else if (codec == NV_ENC_CODEC_HEVC_GUID) {
348353
initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.idrPeriod = encoderParams.idrPeriod;
354+
if (encoderParams.videoFullRangeFlag) {
355+
initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag = 1;
356+
initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoSignalTypePresentFlag = 1;
357+
}
358+
}
349359
pEnc->CreateEncoder(&initializeParams);
350360
}
351361

modules/cudacodec/test/test_video.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ CUDA_TEST_P(H264ToH265, Transcode)
10661066
INSTANTIATE_TEST_CASE_P(CUDA_Codec, H264ToH265, ALL_DEVICES);
10671067

10681068
CV_ENUM(YuvColorFormats, cudacodec::ColorFormat::NV_YUV444, cudacodec::ColorFormat::NV_YUV420_10BIT, cudacodec::ColorFormat::NV_YUV444_10BIT)
1069-
PARAM_TEST_CASE(YUVFormats, cv::cuda::DeviceInfo, YuvColorFormats)
1069+
PARAM_TEST_CASE(YUVFormats, cv::cuda::DeviceInfo, YuvColorFormats, bool)
10701070
{
10711071
};
10721072

@@ -1075,6 +1075,7 @@ CUDA_TEST_P(YUVFormats, Transcode)
10751075
cv::cuda::setDevice(GET_PARAM(0).deviceID());
10761076
const std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../highgui/video/big_buck_bunny.h265";
10771077
const cv::cudacodec::ColorFormat writerColorFormat = static_cast<cudacodec::ColorFormat>(static_cast<int>(GET_PARAM(1)));
1078+
const bool fullRange = GET_PARAM(2);
10781079
constexpr double fps = 25;
10791080
const cudacodec::Codec codec = cudacodec::Codec::HEVC;
10801081
const std::string ext = ".mp4";
@@ -1088,6 +1089,7 @@ CUDA_TEST_P(YUVFormats, Transcode)
10881089
cv::cudacodec::EncoderParams params;
10891090
params.tuningInfo = cv::cudacodec::EncodeTuningInfo::ENC_TUNING_INFO_LOSSLESS;
10901091
params.rateControlMode = cv::cudacodec::EncodeParamsRcMode::ENC_PARAMS_RC_CONSTQP;
1092+
params.videoFullRangeFlag = fullRange;
10911093
for (int i = 0; i < nFrames; ++i) {
10921094
ASSERT_TRUE(cap.read(frame));
10931095
ASSERT_FALSE(frame.empty());
@@ -1101,7 +1103,7 @@ CUDA_TEST_P(YUVFormats, Transcode)
11011103
yuvFormat = cudacodec::SurfaceFormat::SF_P016;
11021104
bitDepth = cudacodec::BitDepth::SIXTEEN;
11031105
}
1104-
generateTestImages(frame, yuv, bgr, yuvFormat, cudacodec::ColorFormat::BGR, bitDepth, false);
1106+
generateTestImages(frame, yuv, bgr, yuvFormat, cudacodec::ColorFormat::BGR, bitDepth, false, fullRange);
11051107
bgrGs.push_back(bgr.clone());
11061108
if (writer.empty())
11071109
writer = cv::cudacodec::createVideoWriter(outputFile, frame.size(), codec, fps, writerColorFormat, params);
@@ -1125,7 +1127,7 @@ CUDA_TEST_P(YUVFormats, Transcode)
11251127
ASSERT_EQ(0, remove(outputFile.c_str()));
11261128
}
11271129

1128-
INSTANTIATE_TEST_CASE_P(CUDA_Codec, YUVFormats, testing::Combine(ALL_DEVICES, YuvColorFormats::all()));
1130+
INSTANTIATE_TEST_CASE_P(CUDA_Codec, YUVFormats, testing::Combine(ALL_DEVICES, YuvColorFormats::all(), testing::Bool()));
11291131
#endif
11301132

11311133
#if defined(HAVE_NVCUVENC)

0 commit comments

Comments
 (0)