libvlc not using hardware accel?

Forum for questions and support relating to the 1.32.x releases only.
Post Reply
chapatt
Posts: 4
Joined: Mon Oct 15, 2018 4:42 pm

libvlc not using hardware accel?

Post by chapatt »

I'm using 1.32.1 on Arch Linux. I have a couple different types of cameras: Hikvisions and Dahuas streaming h.264 via rtsp. The ffmpeg decoding is a great (low) cpu usage, but so much smearing and other artifacts--I mitigated the worst of it changing the options on the cameras, but it's still not good enough. VLC, however, is flawless, but the cpu usage is absurd--like 20%.

I tested streaming directly with VLC on the same machine. With hardware acceleration disabled, I see a similar cpu usage (18% or so), but with VDPAU enabled on an NVidia card, the cpu goes down to about 3-5%. I tried adding --avcodec-hw=any (as prescribed here https://www.remlab.net/op/vlc-vdpau.shtml and on the official docs https://wiki.videolan.org/VLC_command-line_help/) to the Source > Options field but observed no change.

I can't really tell what zmc is actually doing and I couldn't figure out a log option to get more about that. Any input there? Thanks!
chapatt
Posts: 4
Joined: Mon Oct 15, 2018 4:42 pm

Re: libvlc not using hardware accel?

Post by chapatt »

I don't think this documentation is up-to-date (the interface differs a little, now) but it says "hardware acceleration is not yet available to external application via LibVLC" https://wiki.videolan.org/VLC_GPU_Decoding/#Activation

Someone on stack overflow seems to have gotten it to work https://stackoverflow.com/questions/346 ... -in-libvlc. zm_libvlc_camera.cpp seems to pass all options in libvlc_new(), so maybe using libvlc_media_add_option() is worth a try (I don't know the ZM source at all--I'll have to study up and try building).
chapatt
Posts: 4
Joined: Mon Oct 15, 2018 4:42 pm

Re: libvlc not using hardware accel?

Post by chapatt »

Using this example https://wiki.videolan.org/LibVLC_Tutori ... ibVLC_Code substituting a camera's rtsp stream for the address in the call to libvlc_media_new_location and following it with the lines

Code: Select all

libvlc_media_add_option(m, ":avcodec-hw=any");
libvlc_media_add_option(m, ":avcodec-threads=1");
correctly uses hardware acceleration. This outputs the following to stderr

Code: Select all

libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
[00007fed14020500] avcodec decoder: Using Intel i965 driver for Intel(R) Skylake - 1.7.3 for hardware decoding
Unfortunately adding these lines to zm_libvlc_camera.cpp doesn't seem to do anything. I'm looking into getting that stderr stream so I can at least see if hw accel is properly enabled.
chapatt
Posts: 4
Joined: Mon Oct 15, 2018 4:42 pm

Re: libvlc not using hardware accel?

Post by chapatt »

Adding logging with the code below (to my sample code and zoneminder) showed me that hardware acceleration (VA-API or VDPAU) isn't being initialized in the zmc instances. Running the sample from a terminal in an X session did use hw accel, while from a non-graphical login did not. I understand that using hw accel and not rendering to the screen (e.g. for re-encoding and storage) diminishes the net performance gain as the decoded frames have to be transferred from the graphics memory elsewhere, but I also understand that ffmpeg uses this technique to great advantage and believe it should be possible to use one of the hw decoding apis without an X session.

Code: Select all

#define STRLEN(s) ((sizeof(s)/sizeof(s[0])) - 1)
#define MAX_PID_LIMIT_LEN 7

FILE *log_file;
const char log_filename_prefix[21] = "/tmp/zm_libvlc_test_";
char log_filename_pid[MAX_PID_LIMIT_LEN + 1];
const char log_filename_suffix[5] = ".log";
char log_filename[STRLEN(log_filename_prefix) +
                          STRLEN(log_filename_pid) +
                          STRLEN(log_filename_suffix) +
                          1] = "\0";
  
/*
 *libvlc_new() here
 */

strcat(log_filename, log_filename_prefix);
sprintf(log_filename_pid, "%d", getpid());
strcat(log_filename, log_filename_pid);
strcat(log_filename, log_filename_suffix);
log_file = fopen(log_filename, "w");
libvlc_log_set_file(mLibvlcInstance, log_file);

libvlc_log_unset(mLibvlcInstance);

/*
 * libvlc_release() here
 */
Post Reply