i use 5.0 sdk,set bRepeatSPSPPSHeader = 1 , In addition to the first I-frame contains spspps, the other I frame are not spsppps,:(
From SDK docs: By default, SPS/PPS data will be attached to every IDR frame . However, the client can request the encoder to generate SPS/PPS data on demand as well. To accomplish this, set NV_ENC_PIC_PARAMS::encodePicFlags = NV_ENC_PIC_FLAG_OUTPUT_SPSPPS. The output frame generated for the current input will then include SPS/PPS. Also see other "NV_ENC_PIC_FLAGS".
I use idrPeriod=300 + repeatSPSPPS=1 (nvEncodeAPI.h: repeatSPSPPS = Set to 1 to enable writing of Sequence and Picture parameter for every IDR frame) and I see expected sequence "00000001 67" (SPS) "00000001 68" (PPS) "00000001 65" (IDR) in output stream. The short answer is that every IDR frame is an I-frame, but not vice versa, so there can be I-frames that aren’t IDR frames.
but the NVIDIA Capture SDK 5.0 NvFBCHWEncode NV_HW_ENC_CONFIG_PARAMS.bRepeatSPSPPSHeader does not work#
Aha, Capture SDK (I am using NvFBCToSys and encoding elsewhere). You have right. I tested this bug with sample NvFBCHwEncode and I also do not see any SPS/PPS headers before IDR (except the first one).
encodeConfig.bOutBandSPSPPS = FALSE;
encodeConfig.bRepeatSPSPPSHeader = TRUE;
....
if (i % 30 == 0)
fbcHwEncGrabFrameParams.EncodeParams.bForceIDRFrame = TRUE;
To "patch" Nvidia bug I simple add SPS/PPS to stream manually.
if (i % 30 == 0)
fbcHwEncGrabFrameParams.EncodeParams.bForceIDRFrame = TRUE;
res = encoder->NvFBCHWEncGrabFrame(&fbcHwEncGrabFrameParams);
if (i % 30 == 0) {
NvU8 buffer[1024];
NVFBC_HW_ENC_GET_STREAM_HEADER_PARAMS getHeaderParams;
getHeaderParams.dwVersion = NVFBC_HW_ENC_GET_STREAM_HEADER_PARAMS_VER;
getHeaderParams.pBuffer = buffer;
NVFBCRESULT result;
result = encoder->NvFBCHWEncGetStreamHeader(&getHeaderParams);
if (outputFile != NULL) {
printf("SPSPPS size %d\n", getHeaderParams.dwSize);
fwrite(buffer, getHeaderParams.dwSize, 1, outputFile);
}
}
Thank you mcerveny, and encodeConfig.dwGOPLength set 30 or -1 ?
It depends …
The every 30 frame IDR maybe too frequent. I use it only for testing. Forcing IDR ends actual GOP and begin new therefore "encodeConfig.dwGOPLength" can be infinite if there is no need to generate I-Frame between IDRs.
The recommendation rules for different use-cases are in "NVIDIA VIDEO ENCODER (NVENC) INTERFACE, NVENC_VideoEncoder_API_PG-06155-001_v07 | June 2016, Programming Guide " - page 29 .
Also use of IDR to restart stream is not good for network WAN streaming see (b) (it makes data transfer peaks (https://gridforums.nvidia.com/default/topic/752/grid-vgpu-benchmarks/vdi-click-to-photon-with-raspberry-pi/post/2891/#2891 )). See recommendation Q31 "NVIDIA CAPTURE SDK FAQ, PG-06185-001_v1.04| February 2016, Frequently Asked Questions " - page 16 .
:) Thank you , i use nvdia capture sdk to cloud game and remote desktop, the net library is use live555(Is there a better recommendation), and do you have some good idea about encode param (low bitrate and better QUALITY);