livekit / python-sdks

LiveKit real-time and server SDKs for Python
https://docs.livekit.io
Apache License 2.0
129 stars 37 forks source link

rtc.VideoSource().capture_frame consume high CPU when publish 25fps video stream #282

Open quoctuanck99 opened 5 hours ago

quoctuanck99 commented 5 hours ago

I'm working from this example here, and here is my modified version for 25fps video streaming:

WIDTH = 540
HEIGHT = 960

async def entrypoint(job: JobContext):
    await job.connect()

    room = job.room
    source = rtc.VideoSource(WIDTH, HEIGHT)
    track = rtc.LocalVideoTrack.create_video_track("single-color", source)
    options = rtc.TrackPublishOptions(source=rtc.TrackSource.SOURCE_UNKNOWN)
    publication = await room.local_participant.publish_track(track, options)
    logging.info("published track", extra={"track_sid": publication.sid})

    async def _draw_color():
        argb_frame = bytearray(WIDTH * HEIGHT * 4)
        while True:
            await asyncio.sleep(1/25)  # 25fps

            # Create a new random color
            argb_frame = bytearray(WIDTH * HEIGHT * 4)
            r, g, b = [random.randint(0, 255) for _ in range(3)]
            color = bytes([r, g, b, 255])

            argb_frame[:] = color * WIDTH * HEIGHT
            frame = rtc.VideoFrame(WIDTH, HEIGHT, rtc.VideoBufferType.RGB24, argb_frame) -
            source.capture_frame(frame)

    await _draw_color()

if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))

Notably, CPU usage for each call is high at around 30%. After debugging, I found that most of the CPU load comes from this line: source.capture_frame Does anyone have suggestions to reduce CPU usage for this?

Here are the docker stats:

docker stats >

CONTAINER ID   NAME           CPU %     MEM USAGE / LIMIT     MEM %     NET I/O   BLOCK I/O        PIDS
8116cd040c0a   livekit_perf   28.42%    1.221GiB / 15.44GiB   7.91%     0B / 0B   7.75MB / 721kB   496
davidzhao commented 3 hours ago

how much resources did you give to the container? this is likely expected as each frame needs to be encoded for transmission

quoctuanck99 commented 3 hours ago

@davidzhao I didn't limit resources for this container.

this is likely expected as each frame needs to be encoded for transmission

We are limited by hardware, and this is really a challenge for us. Please provide us with suggestions.