Frame Drops when increasing the number of RTSP streams

Question

Frame Drops When Increasing Number of RTSP Streams

Hello,

I am currently working on a project that involves processing multiple RTSP streams to count the number of vehicles. I am using the following technologies and libraries in my code:

aiokafka: To send frames to a Kafka topic
cv2 (OpenCV): To capture frames from RTSP streams
asyncio: To handle asynchronous tasks of handling each stream (used asyncio.create_task for stream processes handling and later asyncio.gather(**tasks))
ThreadPoolExecutor: For processing frames concurrently for each stream. I need to process each frame before sending to my kafka topic. I have otimized the processing part as much as possible. process_frame is being called by the ThreadPoolExecutor for every frame in a while True loop.

The issue I am facing is that when I increase the number of streams beyond a certain point, I experience significant frame drops. Note that I dont want to skip frmes intenstionally since y model heavily relies on weach frame for the usecase that I am implementing. Here are the key parts of my implementation:

Stream Processing: Using cv2.VideoCapture to read frames and aiokafkaAIOKafkaProducer to send frames to Kafka.
Concurrency: Utilizing asyncio with ThreadPoolExecutor to handle multiple streams concurrently.I’ve lready tried increasing the number of workers.

Problem

When the number of streams is increased, I encounter frame drops. I suspect this could be due to limitations in concurrency handling, processing power, or network bandwidth.

Request

I would greatly appreciate any advice or suggestions on how to address the frame drop issue when handling multiple RTSP streams. Specifically, I am looking for recommendations on:

Optimizing concurrency and frame processing

Efficiently handling high-throughput streaming with minimal frame loss.
Any other potential improvements in my current setup.
Thank you for your assistance!

P.S. My code looks like this:

1. Load environment variables (HOST, USER, PASSWORD, DATABASE, SAVE_PATH, STREAMS_TO_TEST)

2. Define a function to create a table in the MySQL database:
   - Connect to the MySQL database
   - Create a cursor
   - Execute SQL query to create table if it doesn't exist
   - Commit changes

3. Define a function to start a connection to the MySQL database:
   - Connect to the MySQL database using credentials from environment variables
   - Return the connection

4. Define a function to initialize a logger for a stream:
   - Check if the stream directory exists, create if it doesn't
   - Create a logger instance for the stream
   - Set the logging level to DEBUG
   - Define a log file path
   - Create a file handler for the logger
   - Set the logging level and formatter for the handler
   - Add the handler to the logger
   - Return the logger

5. Define an asynchronous function to process a stream:
   - Define a function to process a frame:
     - Encode the frame as JPEG
     - Convert the encoded frame to base64 string
     - Return the base64 string
   - Define an asynchronous function to send a frame:
     - Create a message dictionary with frame data and frame count
     - Send the message to Kafka
   - Initialize frame count and start time
   - Open the RTSP stream
   - Check if the stream opened successfully, log an error if not
   - Create an event loop and a thread pool executor
   - Loop to read and process frames:
     - Read a frame using the executor
     - Process the frame to base64 using the executor
     - Send the frame to Kafka
     - Increment the frame count
     - Break the loop if duration is exceeded
   - Release the video capture
   - Log the total frames sent, elapsed time, and average FPS
   - Handle exceptions and log errors

6. Define the main asynchronous function:
   - Read RTSP stream URLs and locations from a CSV file
   - Initialize lists for loggers, working streams, and working locations
   - Loop through streams and locations:
     - Check if the maximum number of test cases is reached
     - Try to open the RTSP stream
     - If the stream is opened successfully:
       - Increment the test cases count
       - Add the stream and location to the working lists
       - Create a logger for the stream and add it to the loggers list
   - Initialize a Kafka producer
   - Start the Kafka producer
   - Create a list of tasks to process each stream
   - Gather all tasks and wait for them to complete
   - Stop the Kafka producer

7. Run the main function using asyncio

for some reason, you involve base-64 encoding. that tells me you don’t understand the resource usage of the code your AI produced for you.

monitor your system’s resource usage, specifically CPU.

you should not use OpenCV to receive the streams. use some other library to receive the streams.

FYI,

I require base64 encoding for json serializable text, which i require to send to my kafka topic. I have heavy dependency with json format on the consumer side.

so the consumer requires json, to receive binary data?

I could comment on the state of “modern” “web” “protocols”…

I am not only sending the image, I am also sending some information regarding it. If I send raw buffer of the image in bytes/list format the request size of the payload is too large for my producer.

I didn’t say to send the raw uncompressed frame. I see that you at least JPEG-compress it.

I did criticize the base64 stuff. that costs bandwidth and decoding.

you need to profile your entire situation. find out how much time is spent in every line of code.

If that’s the issue causing frame drops because of bandwidth, can you suggest other ways of encoding which are json serializable for my producer instance?

I didn’t say that’s the issue.

I said it could be, and that you need to analyze your programs. look up “profiling” in the context of programming.

I know about profiling. I have worked on cProfiler earlier, so I definitely know what it is. I just want to know if that comes out as an issue, how can I approach it.

video streaming does not consist of encoding frames to JPEG and sending them. that’s the lowest form of compression. you should look into WebRTC. that’s for live video streaming.

by the way, HTTP as well as websockets are binary-safe, and HTTP requests and responses can be multi-part, so you can deliver both text and binary data in the same request/response.

I won’t entertain hypotheticals. you need to investigate first. then you can present your quantitive findings that suggest spending time improving specific parts of your situation. then you can ask for others to spend their brain time solving actual issues.

Isn’t this a community, like, where any one can answer? I am pretty sure there are other people around who can help with the information that I’ve provided.

From your description it is not clear if the issue is related to RTSP as the topic name suggests or just that your CPU as with all CPU’s can only process so many tasks at once.

If you add an additional thread and frames are dropped and this is not an RTSP issue (timing etc.) then you need to reduce the length of time it takes to process each frame. The first step as @crackwitz suggested would be to profile your thread to find out which parts are causing the most delay and then address these if possible.

The topic name is exactly as per the issue what I am facing. I have frame drops when I increase the number of RTSP streams. I have described it to the fullest extent possible. Also I profiled my code and it seems that the compression is taking most of the time. Some zlib.Compress is taking most of the time.

well did you observe CPU usage yet? it’s probably near 100% and that one more stream just hits the limit

True but you also have frame drops when you increase any of the parameters that you use in your threads but I would suggest “Frame Drops when increasing the number of Mat containers” is probably not a useful title which you have illistrated by profiling and coming to the conclusion that the issue is

Also I profiled my code and it seems that the compression is taking most of the time. Some zlib.Compress is taking most of the time.

As I said earlier, can you suggest other encoding techniques which are json serializable

Although this is unrelated to OpenCV and you would probably get a better response on stack overflow to get a better response here you probably want to change the title so you attract people who’s “specialty” is json encoding and not RTSP streaming with OpenCV.

related: