Hello!
I am working on low-latency real time streaming product for my client, using Jetson hardware (Nano and AGX). I am encoding live camera input into h.265 stream. My code is written in C++ and uses Argus for camera input, and NvVideoEncoder class for the video encoding.
Stream features that I use are slicing (setting slice sizes to 1kB) and GDR (every now and then, instead of sending I frames). My code is working more or less fine, except that I’ve noticed that GDR always subdivides frame into 2 or 3 slices, ignoring slicing settings. Please consider the plot below:
One can clearly see that while non-GDR frames are subdivided into 1kB slices (short bars of alternating shades), GDR frames are subdivided into either I/P, P/I/P or P/I slices. But that’s a minor problem.
The bigger problem is, I’d like to use slice level encoding on top of GDR and slicing. The reason being - we want lowest latency possible. I want to send the first slices of the frame ASAP, well before the encode ends. Unfortunately GDR, slicing and slice level encode don’t work together. My code crashes on the first GDR frame.
To avoid copyright issues, as well as to save everybody’s time, I worked out the command line switches for the 01_video_encode sample that demonstrate the problem. So this is the one that fails:
/usr/src/jetson_multimedia_api/samples/01_video_encode/video_encode ../videos/nv12_video.yuv 1920 1080 H265 experiment.h265 --sp --egdr -gdrf gdr.txt --input-metadata -gdrof gdr_stream.h265 -slt 2 -slen 1000 --sle
I get the following messages:
Creating Encoder in blocking mode
Opening in BLOCKING MODE
NvMMLiteOpen : Block : BlockType = 8
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 8
892744264
842091854
NVMEDIA: H265 : Profile : 1
NVMEDIA_ENC: bBlitMode is set to TRUE
NvVideoEncTransferOutputBufferToBlock: DoWork failed line# 674
NvVideoEnc: NvVideoEncTransferOutputBufferToBlock TransferBufferToBlock failed Line=685
Now, if I remove either --sle
(meaning that I use GDR and slicing, but not Slice Level Encode) or -slt 2 -slen 1000
(meaning that I use GDR and Slice Level Encode but not slicing) everything works just fine.
Unless I am missing something, this looks like a bug to me. I’ll be grateful for any help. I had the idea of disabling the slicing just for the GDR periods, but unfortunately this is not possible, as the setSliceLength()
can only be called before requestBuffers
on the encoder planes.
Regards
Michal