Changing gop length in NVENC

Hi,

I have an application that uses NVENC.
We recently noticed some strange behavior while trying to change gop length.
Whatever we create the encoder with essentially becomes the max gop length.

For example, starting out with a gop length of 50 for a 250 frame video gives us 5 I-frames as expected.
Changing gop length [by calling NvEncReconfigureEncoder()] to 25 then gives us 10 I-frames.
However, changing this to 100 gives us 5 I-frames again (as opposed to 3).

In general, if we start with a gop of x, we get frames/x I-frames as expected.
We can then reconfigure it to anything below x and receive the proper number of I-frames,
but any gop length greater than x still gives frames/x.

Reading the doc, (NvEncodeAPI_v.7.1.pdf), we found that NvEncReconfigureEncoder does not support
a change in GOP structure. Is this the exact reason why we can’t reconfigure to something larger?
If so, why does NvEncReconfigureEncoder work for smaller numbers?
If not, what could the issue be? Is there another parameter we have to change in unison?

Thanks,
Eric

Hello.

I do not known exact answer. As you wrote you are testing “unsupported” (by docs) dynamic parameter change. But:

  1. Did you test in 8.x Video SDK (drivers >r378) ?
  2. What "video stream use-case" (NVENC_VideoEncoder_API_ProgGuide.pdf - table - Recommended NVENC settings for various use-cases) do you need ?
  3. Did you try to use "infinite GOP" and insert "NV_ENC_PIC_FLAG_FORCEINTRA" as needed ?

M.C>

  1. We are currently bound to 7.0. I’m testing on a Windows machine with driver 376.53.
  2. Use case is probably the second one: game casting & cloud transcoding. Good quality is
    pretty important, but we’re also streaming, so we want lower latency than something like recording/archiving.
  3. No, does this just allow you to place the i-frames manually?

If you are casting stream over unreliable protocol or clients can join stream anytime you should also send IDR+SPS+PPS - NV_ENC_PIC_FLAG_FORCEIDR (that also sends NV_ENC_PIC_FLAG_OUTPUT_SPSPPS) to allow clients (re)join the stream. Also check hints from Q29 and Q30 from NVidia Capture SDK FAQ https://developer.nvidia.com/sites/default/files/akamai/designworks/docs/NVIDIA_Capture_SDK_6/NVIDIA-Capture-SDK-FAQ.pdf (NVidia Capture SDK https://developer.nvidia.com/capture-sdk).
Check presentation (search by keyword) s4654, s4646, s6226, s6307 … @ http://on-demand-gtc.gputechconf.com/gtcnew/on-demand-gtc.php

As of now, I’m just curious if what I’m getting is expected behavior,
and/or why it’s behaving as I described. It seems strange to me that I can reduce the gop
but not increase it, and also that I can change it at all considering the doc says that
I shouldn’t be able to change the gop structure at all with the reconfigure call.

But thanks for the links - I’ve started watching them. Should help a lot!

Did not figure out why you called the NvEncReconfigureEncoder to set up the GOP length. Instead, you may set it up directly befire you call nvEncInitializeEncoder.

We did use nvEncInitializeEncoder to set the gop length first.

The question is about what happens when we call nvEncReconfigureEncoder afterwards.
Supposedly it doesn’t support changing the gop structure after init. We are seeing
that it does change, just with strange behavior.

Thanks,
eric

Can you try setting the IDR period also to 100? IDR period cannot be smaller than GOP length.