<div dir="ltr">Hello,<div><br></div><div>We are using GStreamer within a WebRTC app (the WebRTC part is done with <a href="https://github.com/pion/webrtc">https://github.com/pion/webrtc</a>) where we estimate the best target bitrate depending on network conditions (congestion control).</div><div><br></div><div>I was wondering if anyone has experience about the best way to control encoders (x264enc and nvcodec' nvh264enc) in particular:</div><div><ul><li>when we update the target bitrate: should it be done at a slow pace? (or: is updating every second could be useless or even harmful in any way)</li><li>can it have an impact on keyframes (other than their quality)?</li><li>are there other encoders' properties worth controlling?</li></ul><div>Just in case anyone is interested, below is a typical pipeline we use.</div><div><br></div><div>Thanks,</div></div><div>Guillaume</div><div><br></div><div><font face="monospace" size="1">## Pipeline with RTP in/out (appsrc/appsink)</font></div><div><font face="monospace" size="1">## and two filesinks (one for the in/dry stream, one after applying a video FX, here facedetect)</font></div><div><font face="monospace" size="1">## we force streams to a 800x600 resolution not to crash muxers with changing resolutions</font></div><div><font face="monospace" size="1"><br></font></div><div><font face="monospace" size="1">appsrc name=video_src is-live=true format=GST_FORMAT_TIME min-latency=33333333<br>appsink name=video_sink qos=true<br>matroskamux name=dry_recorder ! filesink location=data/dry.mkv<br>matroskamux name=wet_recorder ! filesink location=data/wet.mkv<br><br>video_src. !<br>application/x-rtp,encoding-name=H264 !<br>rtpjitterbuffer name=video_buffer do-lost=1 add-reference-timestamp-meta=true latency=200 !<br>rtph264depay wait-for-keyframe=true !<br>h264parse !<br>nvh264sldec min-force-key-unit-interval=3000000000 discard-corrupted-frames=true qos=true !<br>cudaupload !<br>cudaconvertscale !<br>cudadownload !<br>videorate !<br>video/x-raw, framerate=30/1, width=800, height=600, format=I420, colorimetry=bt601, chroma-site=jpeg, pixel-aspect-ratio=1/1 !<br><br>tee name=tee_video_in !<br>queue !<br>nvh264enc name=video_encoder_dry rc-mode=3 preset=4 gop-size=15 zerolatency=true b-adapt=0 bframes=0 rc-lookahead=0 min-force-key-unit-interval=3000000000 qos=true ! video/x-h264, profile=constrained-baseline !<br>h264parse !<br>dry_recorder.<br><br>tee_video_in. !<br>queue !<br>videoconvert !<br>facedetect !<br>queue !<br>cudaupload !<br>cudaconvertscale !<br>cudadownload !<br>video/x-raw, format=I420, colorimetry=bt601, chroma-site=jpeg, pixel-aspect-ratio=1/1 !<br>nvh264enc name=video_encoder_wet rc-mode=3 preset=4 gop-size=15 zerolatency=true b-adapt=0 bframes=0 rc-lookahead=0 min-force-key-unit-interval=3000000000 qos=true !<br>video/x-h264, profile=constrained-baseline !<br>h264parse !<br><br>tee name=tee_video_out !<br>queue !<br>wet_recorder.<br><br>tee_video_out. !<br>queue !<br>rtph264pay config-interval=-1 min-ptime=30000000 !<br>video_sink.</font><br></div></div>