I’m currently evaluating the video encoder od SDK 7.0 on a GTX1060.
As an input I use the testsrc generated by ffmpeg:
ffmpeg -f lavfi -i testsrc=duration=60:size=3840x2160:rate=60 -crf 0 -c:v libx264rgb -vf scale=dst_range=1 testsrc.mp4
I convert it to YUV444 before, of course.
Finally, I use such command to encode:
NvEncoderPerf -i testsrc_crf00.yuv -o testsrc_crf00.h265 -size 3840 2160 -inputFormat 1 -fps 60 -codec 1 -preset hq -rcmode 0 -qp 0
I want to do a lossless encoding, so I need to check that the decoded video has same color than the input, which isn’t the case.
IMHO it’s because the encoder consider the YCbCr to be in TV range, where Y is in [0…255], but Cb and Cr are scaled to [16…235].
I found in the
hevcVUIParameters
there are parameters that could do the full range job:
- VideoSignalTypePresentFlag
- videoFullRangeFlag
- videoFormat
- colourDescriptionPresentFlag
- colourPrimaries
- colourMatrix
- transferCharacteristics
So in the Sample NvHWEncoder.cpp provided with the SDK, I added these lines at line 896.
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoSignalTypePresentFlag = 1;
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag = 1;
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFormat = 5; // unspecified
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourDescriptionPresentFlag = 1;
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourPrimaries = 1; // AVCOL_SPC_BT709 = 1
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.colourMatrix = 1; //AVCOL_PRI_BT709 = 1
m_stEncodeConfig.encodeCodecConfig.hevcConfig.hevcVUIParameters.transferCharacteristics = 1; // AVCOL_TRC_BT709 = 1
Unfortunately it doesn’t produce a full range color video as I expected. Any idea why?