livekit / egress

Export and record WebRTC sessions and tracks
https://blog.livekit.io/livekit-universal-egress-launch/
Apache License 2.0
173 stars 72 forks source link

[BUG] Frame Rate Drop and Stuttering in Egress Output at 1080p 30fps #777

Open ozgur-d opened 1 week ago

ozgur-d commented 1 week ago

Describe the bug When attempting to stream at 1920x1080 30fps with a 6000 bitrate, the stream looks smooth via the egress layout URL but experiences significant stuttering (as if at a low framerate) in both the file output and RTMP stream. CPU usage on the server remains around 50%. Reducing the resolution to 1280x720 at 30fps improves the stream, but it’s still not flawless. Changing the bitrate does not affect the result. As motion in the video increases, the quality doesn’t degrade significantly, but the framerate drops further, leading to more noticeable stuttering. I’m also sharing OBS-captured output at 30fps and the RTMP stream output for comparison.

Obs Record From Layout: https://www.youtube.com/watch?v=QH4Ugk4nJB8 Stream Record: https://www.youtube.com/watch?v=nv8UauKl41g Egress Version 1.8.2

Egress Request The request is as follows (TypeScript backend):

const encodingOptions: EncodingOptions = {
  width: 1920,
  height: 1080,
  framerate: 30,
  videoBitrate: 6000,
  videoCodec: VideoCodec.H264_MAIN,
  audioBitrate: 128,
  audioCodec: AudioCodec.OPUS,
  depth: 24,
  audioFrequency: 44100,
};

const options: RoomCompositeOptions = {
  layout: roomSettings.streamLayout,
  customBaseUrl: process.env.EGRESS_LAYOUT_URL,
  encodingOptions: encodingOptions,
};

await this.egressClient.startRoomCompositeEgress(
  roomMember.room.uid,
  rtmpOutput,
  options,
);

Additional context My egress server has 8 CPU cores. I have tried different settings for videoCodec and audioCodec, but the issue persists. The problem seems tied to high resolutions and framerate inconsistencies. The server load seems moderate at around 50% CPU usage during streams. I also tried overriding the following values, but the result remained the same:

cpu_cost: # optionally override cpu cost estimation, used when accepting or denying requests
  room_composite_cpu_cost: 8.0
  web_cpu_cost: 8.0
  track_composite_cpu_cost: 6.0
  track_cpu_cost: 3.0

I have tested with the following options for frontend typescript:

<LiveKitRoom
options={{
  adaptiveStream: true (also false),
  dynacast: false,
  videoCaptureDefaults: {
    resolution: {
      width: 1280,
      height: 720,
      aspectRatio: 1280 / 720,
      frameRate: 30,
    },
  },
}}

Logs

2024-09-16T15:13:08.730Z        INFO    egress  redis/redis.go:142      connecting to redis     {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "simple": true, "addr": "90px-live.redis.cache.windows.net:6379"}
2024-09-16T15:13:08.753Z        INFO    egress  stats/monitor.go:169    cpu available: 8.000000 max cost: 4.000000      {"nodeID": "NE_Rm6y42thEsMs", "clusterID": ""}
2024-09-16T15:13:08.753Z        DEBUG   egress  service/service_debug.go:38     debug handler disabled  {"nodeID": "NE_Rm6y42thEsMs", "clusterID": ""}
2024-09-16T15:13:08.753Z        DEBUG   egress  service/service.go:137  starting service        {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "version": "1.8.2"}
2024-09-16T15:13:08.753Z        INFO    egress  service/service.go:143  service ready   {"nodeID": "NE_Rm6y42thEsMs", "clusterID": ""}
2024-09-16T15:13:08.753Z        DEBUG   egress  service/service.go:125  starting template server on address localhost:7980      {"nodeID": "NE_Rm6y42thEsMs", "clusterID": ""}
2024-09-17T13:29:32.877Z        DEBUG   egress  stats/monitor.go:306    cpu check       {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "total": 8, "pending": 0, "used": 0, "required": 4, "available": 8, "activeRequests": 0, "canAccept": true}
2024-09-17T13:29:33.409Z        DEBUG   egress  stats/monitor.go:306    cpu check       {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "total": 8, "pending": 0, "used": 0, "required": 4, "available": 8, "activeRequests": 0, "canAccept": true}
2024-09-17T13:29:33.409Z        INFO    egress  service/service_rpc.go:45       request received        {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:33.421Z        INFO    egress  service/service_rpc.go:60       request validated       {"nodeID": "NE_Rm6y42thEsMs", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "requestType": "room_composite", "outputType": "stream", "room": "6c123486-3ea5-48a3-9cdf-a3a888076f5c", "request": {"RoomComposite":{"room_name":"6c123486-3ea5-48a3-9cdf-a3a888076f5c","layout":"screenshare","custom_base_url":"https://egresslayout-azure.test.net","Output":{"Stream":{"protocol":1,"urls":["rtmp://cdn-static.testnet/LiveApp/{jfW...865}","rtmp://20.218.136.230:1934/live/{6c1...863}"]}},"Options":{"Advanced":{"width":1920,"height":1080,"depth":24,"framerate":30,"audio_codec":1,"audio_bitrate":128,"audio_frequency":44100,"video_codec":2,"video_bitrate":6000}}}}}
2024-09-17T13:29:33.443Z        DEBUG   egress  server/main.go:188      handler launched        {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:33.444Z        INFO    egress  redis/redis.go:142      connecting to redis     {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "simple": true, "addr": "90px-live.redis.cache.windows.net:6379"}
2024-09-17T13:29:33.459Z        DEBUG   egress  source/web.go:149       creating pulse sink     {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:33.470Z        DEBUG   egress  source/web.go:173       creating X display      {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "display": ":1028125055", "dims": "1920x1080x24"}
2024-09-17T13:29:33.471Z        DEBUG   egress  source/web.go:204       launching chrome        {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "url": "https://egresslayout-azure.test.net?layout=screenshare&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjY2NjYxNzMsImlzcyI6IjZlbTIzZmtnZnIzc25iZDIiLCJraW5kIjoiZWdyZXNzIiwibmJmIjoxNzI2NTc5NzczLCJzdWIiOiJFR19WVldpSndkTENaaWkiLCJ2aWRlbyI6eyJjYW5QdWJsaXNoIjpmYWxzZSwiY2FuUHVibGlzaERhdGEiOmZhbHNlLCJjYW5TdWJzY3JpYmUiOnRydWUsImhpZGRlbiI6dHJ1ZSwicmVjb3JkZXIiOnRydWUsInJvb20iOiI2YzEyMzQ4Ni0zZWE1LTQ4YTMtOWNkZi1hM2E4ODgwNzZmNWMiLCJyb29tSm9pbiI6dHJ1ZX19.0_Yp-bZSMVzj3yAzszpIR7MrwDG-oWTDwKYw5QnuSda&url=wss%3A%2F%2Flive-azure.test.net%3A7880", "sandbox": true, "insecure": true}
0:00:00.209906420    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x120000: 'AVR (Audio Visual Research)' is not mapped
0:00:00.209940021    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x180000: 'CAF (Apple Core Audio File)' is not mapped
0:00:00.209947321    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x100000: 'HTK (HMM Tool Kit)' is not mapped
0:00:00.209955421    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xc0000: 'MAT4 (GNU Octave 2.0 / Matlab 4.2)' is not mapped
0:00:00.209961121    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xd0000: 'MAT5 (GNU Octave 2.1 / Matlab 5.0)' is not mapped
0:00:00.209967621    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x210000: 'MPC (Akai MPC 2k)' is not mapped
0:00:00.209974421    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x230000: 'MPEG-1/2 Audio' is not mapped
0:00:00.209982322    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xe0000: 'PVF (Portable Voice Format)' is not mapped
0:00:00.209990122    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x160000: 'SD2 (Sound Designer II)' is not mapped
0:00:00.209999822    39 0x648c4e374f90 WARN                 default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x190000: 'WVE (Psion Series 3)' is not mapped
0:00:00.339319130    39 0x648c4e374f90 WARN              cudaloader gstcudaloader.c:169:gst_cuda_load_library: Could not open library libcuda.so.1, libcuda.so.1: cannot open shared object file: No such file or directory
0:00:00.339341030    39 0x648c4e374f90 WARN                 nvcodec plugin.c:94:plugin_init: Failed to load cuda library
2024-09-17T13:29:34.951Z        DEBUG   egress  gstreamer/bin.go:64     adding src audio to pipeline    {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.952Z        INFO    egress  source/web.go:275       chrome: START_RECORDING {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.953Z        DEBUG   egress  gstreamer/bin.go:64     adding src video to pipeline    {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.954Z        DEBUG   egress  gstreamer/bin.go:70     adding sink iUhZ3K3L53XA to stream      {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.954Z        DEBUG   egress  gstreamer/bin.go:70     adding sink NYro9vpwUnrj to stream      {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.954Z        DEBUG   egress  gstreamer/bin.go:70     adding sink stream to pipeline  {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.958Z        DEBUG   egress  pipeline/controller.go:211      waiting for start signal        {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.958Z        DEBUG   egress  gstreamer/state.go:75   pipeline state building -> starting     {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.964Z        DEBUG   egress  gstreamer/state.go:75   pipeline state starting -> running      {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:34.965Z        INFO    egress  pipeline/watch.go:235   pipeline playing        {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii"}
2024-09-17T13:29:36.349Z        DEBUG   egress  [gst fixme] gst_rtmp_connection_handle_protocol_control: set peer bandwidth: 10000000, 2        {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "caller": "../gst/rtmp2/rtmp/rtmpconnection.c:867"}
2024-09-17T13:29:36.350Z        DEBUG   egress  [gst warning] parse_ecma_array: Expected array with 1 elements, but read 2      {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "caller": "../gst/rtmp2/rtmp/amf.c:802"}
2024-09-17T13:29:36.363Z        DEBUG   egress  [gst fixme] gst_rtmp_connection_handle_protocol_control: set peer bandwidth: 5000000, 2 {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "caller": "../gst/rtmp2/rtmp/rtmpconnection.c:867"}
2024-09-17T13:29:36.398Z        DEBUG   egress  [gst warning] gst_rtmp_connection_handle_cm: Server sent response "_result" without transaction {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "caller": "../gst/rtmp2/rtmp/rtmpconnection.c:1074"}
2024-09-17T13:29:36.398Z        DEBUG   egress  [gst warning] gst_rtmp_connection_handle_cm: Server sent response "_result" without transaction {"nodeID": "NE_Rm6y42thEsMs", "handlerID": "EGH_HQTgqiYgufrQ", "clusterID": "", "egressID": "EG_VVWiJwdLCZii", "caller": "../gst/rtmp2/rtmp/rtmpconnection.c:1074"}
cagrisungur commented 1 day ago

Any update on this?

Same problem is going on.