Difference in CPU & memory utilization while using VLC Mozilla plugin and VLC player for playback of RTSP streams - benchmarking

For one of our ongoing projects we were planning to use some multimedia framework like VLC / Gstreamer to capture and playback / render h.264 encoded rtsp streams. For the same we have been observing the performance (CPU & memory utilization) of VLC using two demo applications that we have built. One of the demo application uses the mozilla vlc plugin using which we have embedded up to four h.264 encoded RTSP streams on a single html webpage while the other demo application simply invoked the vlc player and plays a single h.264 encoded rtsp stream.
I was surprised to observe that the results were as under (Tests were conducted on Ubuntu 11.04):
Demo 2 (Mozilla VLC plugin - 4 parallel streams)
CPU utilization: 16%
Memory utilization: ~61MB
Demo 2 (VLC player - 1 stream)
CPU utilization: 16%
Memory utilization: ~17MB
My question is, why is the CPU utilization lesser for the mozilla VLC plugin even though it is decoding more video streams.
Reply awaited.
Regards,
Saurabh Gandhi

I'm also using VLC mozilla plugin for my project and I have problem with h264 streams. The only way to handle such stream was to use --ffmpeg-hw (for vaapi use) which due Xlib works only in standalone VLC app (--no-xlib flag in vlcplugin_base.cpp). So I removed that flag and added XInitThreads() and it works now BUT far from performance level you had and besides no-xlib flag was there for reason (it might come to some unwanted behavior).
So the main question is HOW did you come to such results and if its possible to share your configuration flags with me and the rest.
The system I'm using is 4 core CPU and nvidia ION graphics. CPU cores stay at moderate level but stream on fullscreen doesn't play smoothly. If the same streams gets run in cvlc it works perfect. ffmpeg-hw flag is used in both accounts without any warning messages (vaapi successfully returns).

If you have hardware acceleration of some sort, then CPU only takes care of routing the data..

Related

How to play sound in C from scratch (Linux)

How to play sounds at different tones in C without using any external library? I know there are dozens of sound libraries in C that allows you to play sound but what I want to know is how does that work behind? How do you tell the computer to play a certain note at a certain tone/frequency?
I know it's possible on windows using the sound() function but I can't find any documentation talking about Linux, all that I found is the beep() function (or write(1, "\a", 1)) that outputs the default terminal beep but I can't figure out how to play different sounds.
The Linux kernel native audio API is ALSA (Advanced Linux Sound Architecture).
Example of raw audio playback with ALSA:
https://gist.github.com/ghedo/963382/815c98d1ba0eda1b486eb9d80d9a91a81d995283
However, ALSA is a low-level API that is not recommended to be used directly by higher-level applications.
A modern system audio API for GNU/Linux would be either PulseAudio (the current default on Ubuntu), or the newer and arguably better PipeWire (the default on Fedora).
Example of raw audio playback with PipeWire that generates audio "from scratch":
https://docs.pipewire.org/page_tutorial4.html
How do you tell the computer to play a certain note at a certain tone/frequency?
Sound is a mechanical vibration that propagates through the air (or another medium). It can be represented digitally as a sequence of numerical values representing air pressure at a given sampling rate. To play a given tone/frequency, generate a sine wave of that frequency (at the playback sampling rate) and use the sound API of your choice to play it.
See the PipeWire tutorial above for an example generating a 440Hz tone.
About PulseAudio/PipeWire:
These libraries are typically part of the OS and exposed as system APIs (so they are not "external libraries" if that means some library to ship with your program or to ask users to install), and they should be used by applications to play audio.
Behind the scene, these libraries handle audio routing, mixing, echo-canceling, recording, and playback to the kernel through ALSA (or using Bluetooth, etc). Everything that users and developers expect from the system audio layer.
Until recently, PulseAudio was the de-facto universal desktop system audio API, and many apps still use the PulseAudio API to play audio on GNU/Linux.
PipeWire includes compatibility with PulseAudio, so that apps using the PulseAudio API will keep working in the foreseeable future.
Example of raw audio playback with PulseAudio:
https://freedesktop.org/software/pulseaudio/doxygen/pacat-simple_8c-example.html

How to create a video stream from a series of bitmaps and send it over IP network?

I have a bare-metal application running on a tiny 16 bit microcontroller (ST10) with 10BASE-T Ethernet (CS8900) and a Tcp/IP implementation based upon the EasyWeb project.
The application's main job is to control a led matrix display for public traffic passenger information. It generates display information with about about 41 fps and configurable display size of e.g. 160 × 32 pixel, 1 bit color depth (each led can be just either on or off).
Example:
There is a tiny webserver implemented, which provides the respective frame buffer content (equals to led matrix display content) as PNG or BMP for download (both uncompressed because of CPU load and 1 Bit color depth). So I can receive snapshots by e.g.:
wget http://$IP/content.png
or
wget http://$IP/content.bmp
or put appropriate html code into the controller's index.html to view that in a web browser.
I also could write html / javascript code to update that picture periodically, e.g. each second so that the user can see changes of the display content.
Now for the next step, I want to provide the display content as some kind of video stream and then put appropriate html code to my index.html or just open that "streaming URI" with e.g. vlc.
As my framebuffer bitmaps are built uncompressed, I expect a constant bitrate.
I'm not sure what's the best way to start with this.
(1) Which video format is the most easy to generate if I already have a PNG for each frame (but I have that PNG only for a couple of milliseconds and cannot buffer it for a longer time)?
Note that my target system is very resource restricted in both memory and computing power.
(2) Which way for distribution over IP?
I already have some tcp sockets open for listening on port 80. I could stream the video over HTTP (after received) by using chunked transfer encoding (each frame as an own chunk).
(Maybe HTTP Live Streaming doing like this?)
I'd also read about thinks like SCTP, RTP and RTSP but it looks like more work to implement this on my target. And as there is also the potential firewall drawback, I think I prefer HTTP for transport.
Please note, that the application is coded in plain C, without operating system or powerful libraries. All stuff is coded from the scratch, even the web server and PNG generation.
Edit 2017-09-14, tryout with APNG
As suggested by Nominal Animal, I gave a try with using APNG.
I'd extend my code to produce appropriate fcTL and fdAT chunks for each frame and provide that bla.apng with HTTP Content-Type image/apng.
After downloading those bla.apng it looks useful when e.g. opening in firefox or chrome (but not in
konqueror,
vlc,
dragon player,
gwenview).
Trying to stream that apng works nicely but only with firefox.
Chrome wants first to download the file completely.
So APNG might be a solution, but with the disadvantage that it currently only works with firefox. After further testing I found out, that 32 Bit versions of Firefox (55.0.2) crashing after about 1h of APNG playback were about 100 MiB of data has been transfered in this time. Looks that they don't discard old / obsolete frames.
Further restrictions: As APNG needs to have a 32 bit "sequence number" at each animation chunk (need 2 for each frame), there might to be a limit for the maximum playback duration. But for my frame rate of 24 ms this duration limit is at about 600 days and so I could live with.
Note that APNG mime type was specified by mozilla.org to be image/apng. But in my tests I found out that it's a bit better supported when my HTTP server delivers APNG with Content-Type image/png instead. E.g. Chromium and Safari on iOS will play my APNG files after download (but still not streaming). Even the wikipedia server delivers e.g. this beach ball APNG with Content-Type image/png.
Edit 2017-09-17, tryout with animated GIF
As also suggested by Nominal Animal, I now tried animated GIF.
Looks ok in some browsers and viewers after complete download (of e.g. 100 or 1000 frames).
Trying live streaming it looks ok in Firefox, Chrome, Opera, Rekonq and Safari (on macOS Sierra).
Not working Safari (on OSX El Capitan and iOS 10.3.1), Konqueror, vlc, dragon player, gwenview.
E.g. Safari (tested on iOS 10.3.3 and OSX El Capitan) first want to download the gif completely before display / playback.
Drawback of using GIF: For some reason (e.g. cpu usage) I don't want to implement data compression for the generated frame pictures. For e.g. PNG, I use uncompressed data in IDAT chunk and for a 160x32 PNG with 1 Bit color depth a got about 740 Byte for each frame. But when using GIF without compression, especially for 1 Bit black/white bitmaps, it blows up the pixel data by factor 3-4.
At first, embedded low-level devices not very friendly with very complex modern web browsers. It very bad idea to "connect" such sides. But if you have tech spec with this strong requirements...
MJPEG is well known for streaming video, but in your case it is very bad, as requires much CPU resources and produces bad compression ratio and high graphics quality impact. This is nature of jpeg compression - it's best with photographs (images with many gradients), but bad with pixel art (images with sharp lines).
Looks that they don't discard old / obsolete frames.
And this is correct behavior, since this is not video, but animation format and can be repeated! Exactly same will be with GIF format. Case with MJPEG may be better, as this is established as video stream.
If I were doing this project, I would do something like this:
No browser AT ALL. Write very simple native player with winapi or some low-level library to just create window, receive UDP packet and display binary data. In controller part, you must just fill udp packets and send it to client. UDP protocol is better for realtime streaming, it's drop packets (frames) in case of latency, very simple to maintain.
Stream with TCP, but raw data (1 bit per pixel). TCP will always produce some latency and caching, you can't avoid it. Same as before, but you don't need handshaking mechanism for starting video stream. Also, you can write your application in old good technologies like Flash and Applets, read raw socket and place your app in webpage.
You can try to stream AVI files with raw data over TCP (HTTP). Without indexes, it will unplayable almost everywhere, except VLC. Strange solution, but if you can't write client code and wand VLC - it will work.
You can write transcoder on intermediate server. For example, your controller sent UDP packets to this server, server transcode it in h264 and streams via RTMP to youtube... Your clients can play it with browsers, VLC, stream will in good quality upto few mbits/sec. But you need some server.
And finally, I think this is best solution: send to client only text, coordinates, animations and so on, everything what renders your controller. With Emscripten, you can convert your sources to JS and write exact same renderer in browser. As transport, you can use websockets or some tricks with long-long HTML page with multiple <script> elements, like we do in older days.
Please, tell me, which country/city have this public traffic passenger information display? It looks very cool. In my city every bus already have LED panel, but it just shows static text, it's just awful that the huge potential of the devices is not used.
Have you tried just piping this through a websocket and handling the binary data in javascript?
Every websocket frame sent would match a frame of your animation.
you would then take this data and draw it into an html canvas. This would work on every browser with websocket support - which would be quite a lot - and would give you all the flexibility you need. (and the player could be more high end than the "encoder" in the embedded device)

MediaElement doesn’t release RTSP stream and VLC Player rebuffers it before stabilizing. How to display RTSP streams correctly?

I am working on a WPF application that displays RTSP video streams. Currently, the application handles communication with two types of devices that use RTSP: cameras and archivers (pretty much DVR). Over the lifetime of the app the streams may and usually will be closed multiple times, so we need to make sure they are not cluttering the memory and network when we close them.
We had a go with the MediaElement. We needed to install LAV Filters for ME to display RTSP streams at all. We could see the video from the cameras but the stream wasn’t released until we stopped the video, invoked Close() on MediaElement and set its source to null. The video seemed to be released but we still decided to check memory usage using a profiler. We simply created a loop in which we initialized a new MediaElement (local reference), played RTSP stream and closed it after establishing the connection. Over half an hour of running the test we witnessed a steady increase in memory consumption, and as a result we lost 20MB of memory to all the MediaElements we created. The reason is still unknown to us (timers being bound to the dispatcher?) but after searching the Internet we accepted that there is a problem with MediaElement itself.
We decided this is negligible for our use case (no one is going to create MediaElements with that frequency). Unfortunately, MediaElement was not releaseing streams for archivers when using the same approach. After we got rid of the MediaElement for archivers stream, the archiver’s server still reported the connection being open.
We analyzed the packets with Wireshark. Cameras and archivers use the same version of the RTSP protocol, but when we close the connection on the camera the RTCP and data packets stop coming, which is not the case with the archivers.
We decided to abandon ME altogether and switch to the VLC Player. When we hit stop on the VLC player the connections are nicely closed, but VLC has a bug causing rebuffering of streams at the beginning of any connection. It’s a known issue: https://trac.videolan.org/vlc/ticket/9087. Rebuffering is not consistent. Sometimes it happens twice, sometimes three times. We tried playing around with buffer settings for VLC (network-buffer, live-buffer… you name it) but nothing helped.
There are many questions we are looking answers for:
why ME is keeping the connection alive for archivers but not for cameras? Is archiver not handling RTSP termination packet correctly?
which component is responsible for keeping the connection open on the client side and how could we possibly work around it (terminate the stream)?
how to prevent VLC from rebuffering the stream after the connections is established?
Did you have any success with streaming multiple RTSP streams without performance/memory issues in your application? What components did you use?
Side note: we also played with MediaPlayerHQ, which behaves nicely, unless we kill the process. If we do that the stream remains open for couple of minutes.
I will appreciate any hints and suggestions!
Check out https://net7mma.codeplex.com, it is excellent on memory cpu. It has been tested with 1000 clients connected and the end users never experienced any additional delays. Vlc achieves Rtcp synchronization with my library so buffering should happen only once if at all. The library should also help to allow you to decode the video / audio using media foundation. It also supports getting media information from container files and will support their playback through the included rtsp server or writing them to alternate container formats.
The code is completely managed and written in c# and released under the apache license.

GetSampleAsync does not fire in MediaStreamSource on WP7 device

I've been developing an audio app for Windows Phone 7 and up to this point have been using the WP7 emulator. The app uses a custom MediaStreamSource class to stream audio to a MediaElement.
On a real device, the custom MediaStreamSource completely fails. After calling MediaElement.Play(), the MediaStreamSource's GetSampleAsync method never gets called. It works just fine in the emulator.
I've started the app in the debugger (running on the device) and no exceptions get thrown anywhere.
I'm wondering if maybe my stream source is using a sample rate, bits per sample, or channel count that is not supported? I cannot find any documentation on what values are supported - however I find it hard to believe that my settings are not supported (44,100 Hz, 16 bits/sample, 2 channels).
Thoughts?
The answer is that the Zune software interferes with the phone's media capabilities. The app will work on the device if you disconnect the device from the computer, or by using the WPConnect tool: http://blogs.msdn.com/b/jaimer/archive/2010/11/03/tips-for-debugging-wp7-media-apps-with-wpconnect.aspx

Audio API Suitable for multi channel playback in windows

I am researching a project in which I need to playback simultaneously a multi-track audio source. ( >30 mono channels ) The audio on all channels needs to start simultaneously and be sustained for hours of playback.
What is the best audio API to use for this? WDM and ASIO have come up in my searches. I will be using a MOTU PCI Audio interface to get this many channels. The channels show up as normal audio channels in the host PC.
ASIO is definitely the way to go about this. It will keep everything in sync properly, with low latency, and is the defacto industry standard way to do it. Any pro audio interfaces supports ASIO, and for interfaces that don't, there is a wrapper that is capable of syncing multiple devices.

Resources