Proper/best LibVLC lifecycle?

This forum is about all development around libVLC.
ibrewster
New Cone
New Cone
Posts: 8
Joined: 06 Jul 2021 17:05

Proper/best LibVLC lifecycle?

Postby ibrewster » 06 Jul 2021 17:31

I am using LibVLC (pulled from VLC version 3.0.9) in a Qt/C++ app I am running under xUbuntu Linux on an old (circa 2009 I think) MacBook Pro. The workflow I have is that, upon being triggered by external events VLC will be initialized using the code below, play for several seconds, then stop. This process will then repeat periodically at irregular intervals (anywhere from a few seconds to hours/days) forever, as external events trigger it. My question is what is the best lifecycle for LibVLC for this sort of use? What "cleanup" should I be doing after each play cycle to prevent memory leaks while ensuring the best performance/reliability of the system?

My initialization code currently looks like this:

Code: Select all

vlcInstance=libvlc_new(0,NULL); QString rtsp_url="rtsp://<my_rtsp_source>"; libvlc_media_t *vlcMedia=libvlc_media_new_location(vlcInstance,rtsp_url.toUtf8()); vlcPlayer=libvlc_media_player_new_from_media(vlcMedia); libvlc_audio_set_volume(vlcPlayer,75); vlcEventManager=libvlc_media_player_event_manager(vlcPlayer); libvlc_event_attach(vlcEventManager,libvlc_MediaPlayerPlaying, &play_event_handler,this); libvlc_event_attach(vlcEventManager,libvlc_MediaPlayerEncounteredError, &vlc_error_handler,this); libvlc_media_player_set_xwindow(vlcPlayer, ui->videoframe->winId()); libvlc_media_player_play(vlcPlayer);
And after playback is complete, I run the following cleanup code:

Code: Select all

if (vlcPlayer!=nullptr){ if(libvlc_media_player_is_playing(vlcPlayer)){ libvlc_media_player_stop(vlcPlayer); } libvlc_media_player_release(vlcPlayer); vlcPlayer=nullptr; } if(vlcInstance!=nullptr){ libvlc_release(vlcInstance); vlcInstance=nullptr; }
Is this enough cleanup? Too much? Not enough? Thanks in advance!

Rémi Denis-Courmont
Developer
Developer
Posts: 15266
Joined: 07 Jun 2004 16:01
VLC version: master
Operating System: Linux
Contact:

Re: Proper/best LibVLC lifecycle?

Postby Rémi Denis-Courmont » 06 Jul 2021 18:12

There is no better or worse lifecycle in terms of avoiding leaks, so long as you eventually release what you allocated.

If you want to protect against underlying bugs, the only way is to run the engine in a separate process. That's true for leaks as well as for other bugs.
Rémi Denis-Courmont
https://www.remlab.net/
Private messages soliciting support will be systematically discarded

ibrewster
New Cone
New Cone
Posts: 8
Joined: 06 Jul 2021 17:05

Re: Proper/best LibVLC lifecycle?

Postby ibrewster » 07 Jul 2021 00:35

My apologies, it appears I was unclear in my question. Clearly if you eventually release everything you allocated, then there is no memory leak. That's pretty much the definition of avoiding memory leaks. My question though is more specific to this situation: given what I am allocating, is the cleanup routine I have sufficient to release everything?

The difficulty here is that I have no idea what is or is not being allocated at any given step that I then need to release (since it's not like I am explicitly calling new anywhere). For example, I'm assuming that the libvlc_new() function allocates something, therefore I need to call libvlc_release() at some point to de-allocate it, which I do in the cleanup code I showed. This seems to work, so again I'm assuming - though that IS just an assumption - that this is the correct lifecycle. But what about the call to libvlc_media_new_location()? Does that allocate something that I then need to release in the cleanup code? Or does the player instance take ownership of it when I call libvlc_media_player_new_from_media(), such that when I call libvlc_media_player_release() the libvlc_media object is also released?

That's what I was trying to get at with my question of "Is this enough cleanup? Too much? Not enough?" - am I properly deallocating everything that I allocated, no more and no less?

Further, regarding the best/proper part of the question, given the create-play-destroy-repeat nature of my code, is this lifecycle - where I create and destroy everything (presumably) each time the program is triggered to show the RTSP stream - the best option? Or would it be better (from a reliability and performance standpoint) to, for example, create a single vlcInstance object that exists for the lifetime of the application, and only create/destroy the player object each time? Or maybe even not that, just create one instance of everything and call play/stop each time? How is libvlc designed/intended to be used - as a single long-running instance that is simply started/stopped and has the media changed (if needed)? Or as separate instances created/destroyed each time something else needs to be played?

mfkl
Developer
Developer
Posts: 739
Joined: 13 Jun 2017 10:41

Re: Proper/best LibVLC lifecycle?

Postby mfkl » 07 Jul 2021 03:45

Checking the LibVLC docs for the functions you use is probably a good practice https://videolan.videolan.me/vlc/group_ ... e887fa9b42

Letting your process run for a few days and checking the memory usage before and after, to see whether it is stable, will give you a hint if you're doing it OK, also.

Code: Select all

vlcPlayer=libvlc_media_player_new_from_media(vlcMedia);
After this line, you can free the vlcMedia object.

Since you subscribe to events, you might as well unsubscribe from them. Sounds cleaner. https://videolan.videolan.me/vlc/group_ ... c56f4cf766

All I can see so far.
https://mfkl.github.io

ibrewster
New Cone
New Cone
Posts: 8
Joined: 06 Jul 2021 17:05

Re: Proper/best LibVLC lifecycle?

Postby ibrewster » 07 Jul 2021 18:19

Checking the LibVLC docs for the functions you use is probably a good practice https://videolan.videolan.me/vlc/group_ ... e887fa9b42
Agreed, and I have done that. Unfortunately the documentation doesn't really address the issues I asked here. For example, looking at the documentation for the libvlc_media_new_location() function, it doesn't say anything about if I need to explicitly call libvlc_media_release, aside from the reference under "see also".
Letting your process run for a few days and checking the memory usage before and after, to see whether it is stable, will give you a hint if you're doing it OK, also.
Sure. I'll probably do some profiling as well, but while useful a lot of that would be essentially taking stabs in the dark, guessing at what I need to do, and hoping it works. Thus my request for advice :)

Code: Select all

vlcPlayer=libvlc_media_player_new_from_media(vlcMedia);
After this line, you can free the vlcMedia object.
The documentation appears to agree with you (at least the one for 4.0.0-dev, I can't seem to find the documentation for the 3.x current release series...). Unfortunately, when I tried that, my program started crashing (Termination Signal: Segmentation fault: 11) upon returning to the event loop after running the cleanup code, which makes me think I am doing a double free or something. Removing either the call to libvlc_media_release or the call to libvlc_media_player_release() prevents the crash, which makes me think having both is wrong.
Since you subscribe to events, you might as well unsubscribe from them. Sounds cleaner. https://videolan.videolan.me/vlc/group_ ... c56f4cf766

All I can see so far.
Thanks, I'll do that!

ibrewster
New Cone
New Cone
Posts: 8
Joined: 06 Jul 2021 17:05

Re: Proper/best LibVLC lifecycle?

Postby ibrewster » 13 Jul 2021 18:07

To update this discussion: the above cycle of create/release seems to work properly the first few times, but after several cycles over 24 hours or so, VLC starts locking up for extended periods of time on various commands, such as libvlc_media_player_stop(). This makes me think I'm doing *something* wrong, or at least not as well as I could be, but I have no idea what.

As far as I can tell, the only errors returned from VLC at any point are these that it returns during initialization, even when it is working properly:

Code: Select all

libva info: VA-API version 1.7.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/nouveau_drv_video.so libva info: Found init function __vaDriverInit_1_7 libva info: va_openDriver() returns 0 [00007fc170033380] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed [00007fc16800b340] main video output error: video output creation failed [00007fc0f80b2af0] main decoder error: failed to create video output [00007fc0f80b2af0] avcodec decoder: [h264 @ 0x7fc16c024500] Failed setup for format vdpau: hwaccel initialisation returned error. [00007fc0f80b2af0] avcodec decoder error: existing hardware acceleration cannot be reused libva info: VA-API version 1.7.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/nouveau_drv_video.so libva info: Found init function __vaDriverInit_1_7 libva info: va_openDriver() returns 0 [00007fc120001a10] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed libva info: VA-API version 1.7.0 libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/nouveau_drv_video.so libva info: Found init function __vaDriverInit_1_7 libva info: va_openDriver() returns 0 [00007fc14c001480] glconv_vaapi_x11 gl error: vaDeriveImage: operation failed [00007fc16800b340] main video output error: video output creation failed [00007fc0f80b2af0] main decoder error: failed to create video output
Perhaps a single long-lived instance of VLC and/or the player that I don't delete each cycle would work better/be safer? Can/should I run the VLC commands in a separate thread to avoid blocking the main thread/event loop if/when VLC starts locking up?

mfkl
Developer
Developer
Posts: 739
Joined: 13 Jun 2017 10:41

Re: Proper/best LibVLC lifecycle?

Postby mfkl » 15 Jul 2021 04:33

Can/should I run the VLC commands in a separate thread to avoid blocking the main thread/event loop if/when VLC starts locking up?
Yup. The stop freezing is known 3.x issue, fixed in 4.x https://code.videolan.org/videolan/vlc/ ... 602fc5349b
4.x is still unstable, so you should keep using 3.x and call stop from another thread (not the main thread).
https://mfkl.github.io


Return to “Development around libVLC”

Who is online

Users browsing this forum: No registered users and 16 guests