Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where is the streaming part? #2

Open
Tsardoz opened this issue Jul 16, 2023 · 3 comments
Open

Where is the streaming part? #2

Tsardoz opened this issue Jul 16, 2023 · 3 comments

Comments

@Tsardoz
Copy link

Tsardoz commented Jul 16, 2023

I have looked over the code for the part that streams to localhost but cannot find it.
Is this it (in MainStreamer)?

` VideoCapture cap(VIDEO_FILE, CAP_FFMPEG);

if(!cap.isOpened()){ FrameError=true; goto Ferr; }

if (!cap.read(frame)) { FrameError=true; goto Ferr; }

cout << "Camera start streaming...." << endl;
//reset lock mechanism
unlink(SWAP_IMG_FILE);
unlink(SWAP_RDY_FILE);

while(true)
{
    //wait until ready
    while(FileExists(SWAP_IMG_FILE) || FileExists(SWAP_RDY_FILE)) cap.read(frame);
    //event app is ready to recieve a new frame
    cap.read(frame);
    cv::resize(frame, norm_frame, cv::Size(320, 240));
    imwrite(SWAP_IMG_FILE,norm_frame);
    //signal image to file writing is done
    Fdone.open(SWAP_RDY_FILE);
    Fdone.close(); //write empty file
}`

It just seems to write the image to SWAP_IMG_FILE.
I am new to c++ - just trying to work it out.

Thanks

@Qengineering
Copy link
Owner

@Tsardoz,

First of all, thank you very much for the tip. We really appreciate that.

How does it work?

The heart of the app is a tiny web server, Nginx.
You will see a web page (HTML) when you connect to the app. The page can be found in the directory /var/www/html/index.html
It consists of a single video element. It could be much more, even a well-kept website.

Nginx uses HLS packages to stream the video to the user. These are buffered /dev/shm/hls/for about 10 sec before being sent. The /dev/shm/hls/ folder lives in RAM. This way continuing writing to the SD card is prevented.

Nginx uses an RT stream to feed its HLS packages. FFmpeg takes care of this RT steam. It is initiated in /etc/rc.local with the command ffmpeg -input_format h264 -f video4linux2 -video_size 1296x972 -framerate 15 -i /dev/video0 -c:v copy -an -f flv rtmp://localhost /live/rpi

The beauty of FFmpeg is that it uses the GPU instead of the CPU. Until now, we have a working camera streaming to nginx and nginx, on his turn, surging to a browser without using (almost) any CPU power. We can use the CPU now for things like motion detection, or recognizing objects with deep learning, like YoloCam.
Notice also, there is not one line of C++ code involved so far.

There a in fact two applications running at the same time. One app, MainStreamer, is writing frames from the HLS buffer to memory (/dev/shm/pic.jpg) by using Gstreamer tapping var/www/html/hls/rpi.m3u8 from the nginx HLS buffer.
The other app, MainEvent, detects motion (or objects in case of YoloCam) from the stored pictures.
This two-app mechanism is used because processing frames take longer than nginx stream frames. In other words, the processes must be asynchronous. Flags like SWAP_RDY_FILE or SWAP_IMG_FILE are used to signal between the two apps.

@Tsardoz
Copy link
Author

Tsardoz commented Jul 18, 2023

Thanks for the explanation. That is a great idea using FFmpeg for its GPU use. Also I figure to change the resolution rc.local is edited not MainStreamer.cpp which just uses the smaller image for movement detection. It would have been helpful to mention the nginx/rc.local thing in the readme but thanks for answering my question.

Mybad - its in the wiki which I did not read!

@Qengineering
Copy link
Owner

@Tsardoz,

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants