Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/hw/vaapi/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 7 kB image not shown  

Quelle  decoder_device.c   Sprache: C

 

/*****************************************************************************
 * decoder_device.c: VAAPI decoder_device
 *****************************************************************************
 * Copyright (C) 2017-2019 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_window.h>
#include <vlc_codec.h>
#include <vlc_fs.h>

#include "vlc_vaapi.h"
#include <va/va_drmcommon.h>

#ifdef HAVE_VA_WL
# include <va/va_wayland.h>
#endif

#ifdef HAVE_VA_X11
# include <va/va_x11.h>
# include <vlc_xlib.h>
#endif

#ifdef HAVE_VA_DRM
# include <va/va_drm.h>
# include <vlc_fs.h>
# include <fcntl.h>
#endif

typedef void (*vaapi_native_destroy_cb)(VANativeDisplay);
struct vaapi_instance;

struct vaapi_instance
{
    VADisplay dpy;
    VANativeDisplay native;
    vaapi_native_destroy_cb native_destroy_cb;
};

/* Initializes the VADisplay. If not NULL, native_destroy_cb will be called
 * when the instance is released in order to destroy the native holder (that
 * can be a drm/x11/wl). On error, dpy is terminated and the destroy callback
 * is called. */

static struct vaapi_instance *
vaapi_InitializeInstance(vlc_object_t *o, VADisplay dpy,
                             VANativeDisplay native,
                             vaapi_native_destroy_cb native_destroy_cb)
{
    int major = 0, minor = 0;
    VAStatus s = vaInitialize(dpy, &major, &minor);
    if (s != VA_STATUS_SUCCESS)
    {
        msg_Err(o, "vaInitialize: %s", vaErrorStr(s));
        goto error;
    }

    const char *vendor = vaQueryVendorString(dpy);
    if (vendor != NULL && strstr(vendor, "NVDEC") != NULL)
    {
        msg_Err(o, "Rejecting VA-API NVDEC driver: %s", vendor);
        goto error;
    }

    struct vaapi_instance *inst = malloc(sizeof(*inst));

    if (unlikely(inst == NULL))
        goto error;
    inst->dpy = dpy;
    inst->native = native;
    inst->native_destroy_cb = native_destroy_cb;

    return inst;
error:
    vaTerminate(dpy);
    if (native != NULL && native_destroy_cb != NULL)
        native_destroy_cb(native);
    return NULL;
}

static void
vaapi_DestroyInstance(struct vaapi_instance *inst)
{
    vaTerminate(inst->dpy);
    if (inst->native != NULL && inst->native_destroy_cb != NULL)
        inst->native_destroy_cb(inst->native);
    free(inst);
}

#ifdef HAVE_VA_X11
static void
x11_native_destroy_cb(VANativeDisplay native)
{
    XCloseDisplay(native);
}

static struct vaapi_instance *
x11_init_vaapi_instance(vlc_decoder_device *device, vlc_window_t *window,
                        VADisplay *vadpyp)
{
    if (!vlc_xlib_init(VLC_OBJECT(window)))
        return NULL;

    Display *x11dpy = XOpenDisplay(window->display.x11);
    if (x11dpy == NULL)
        return NULL;

    VADisplay vadpy = *vadpyp = vaGetDisplay(x11dpy);
    if (vadpy == NULL)
    {
        x11_native_destroy_cb(x11dpy);
        return NULL;
    }

    return vaapi_InitializeInstance(VLC_OBJECT(device), vadpy,
                                    x11dpy, x11_native_destroy_cb);
}
#endif

#ifdef HAVE_VA_DRM

static void
native_drm_destroy_cb(VANativeDisplay native)
{
    vlc_close((intptr_t) native);
}

/* Get and Initializes a VADisplay from a DRM device. If device is NULL, this
 * function will try to open default devices. */

static struct vaapi_instance *
vaapi_InitializeInstanceDRM(vlc_object_t *o,
                            VADisplay (*pf_getDisplayDRM)(int),
                            VADisplay *pdpy, const char *device)
{
    static const char *default_drm_device_paths[] = {
        "/dev/dri/renderD128",
        "/dev/dri/card0",
        "/dev/dri/renderD129",
        "/dev/dri/card1",
    };

    const char *user_drm_device_paths[] = { device };
    const char **drm_device_paths;
    size_t drm_device_paths_count;

    if (device != NULL)
    {
        drm_device_paths = user_drm_device_paths;
        drm_device_paths_count = 1;
    }
    else
    {
        drm_device_paths = default_drm_device_paths;
        drm_device_paths_count = ARRAY_SIZE(default_drm_device_paths);
    }

    for (size_t i = 0; i < drm_device_paths_count; i++)
    {
        int drm_fd = vlc_open(drm_device_paths[i], O_RDWR);
        if (drm_fd < 0)
            continue;

        VADisplay dpy = pf_getDisplayDRM(drm_fd);
        if (dpy)
        {
            struct vaapi_instance *va_inst =
                vaapi_InitializeInstance(o, dpy,
                                         (VANativeDisplay)(intptr_t)drm_fd,
                                         native_drm_destroy_cb);
            if (va_inst)
            {
                *pdpy = dpy;
                return va_inst;
            }
        }
        else
            vlc_close(drm_fd);
    }
    return NULL;
}

static struct vaapi_instance *
drm_init_vaapi_instance(vlc_decoder_device *device, VADisplay *vadpyp)
{
    return vaapi_InitializeInstanceDRM(VLC_OBJECT(device), vaGetDisplayDRM,
                                       vadpyp, NULL);
}
#endif

#ifdef HAVE_VA_WL
static struct vaapi_instance *
wl_init_vaapi_instance(vlc_decoder_device *device, vlc_window_t *window,
                       VADisplay *vadpyp)
{
    VADisplay vadpy = *vadpyp = vaGetDisplayWl(window->display.wl);
    if (vadpy == NULL)
        return NULL;

    return vaapi_InitializeInstance(VLC_OBJECT(device), vadpy, NULL, NULL);
}
#endif

static void
Close(vlc_decoder_device *device)
{
    vaapi_DestroyInstance(device->sys);
}

static const struct vlc_decoder_device_operations ops = {
    .close = Close,
};

static int
Open(vlc_decoder_device *device, vlc_window_t *window)
{
    VADisplay vadpy = NULL;
    struct vaapi_instance *vainst = NULL;
#if defined (HAVE_VA_X11)
    if (window && window->type == VLC_WINDOW_TYPE_XID)
        vainst = x11_init_vaapi_instance(device, window, &vadpy);
#elif defined(HAVE_VA_WL)
    if (window && window->type == VLC_WINDOW_TYPE_WAYLAND)
        vainst = wl_init_vaapi_instance(device, window, &vadpy);
#elif defined (HAVE_VA_DRM)
    (void) window;
    vainst = drm_init_vaapi_instance(device, &vadpy);
#else
# error need X11/WL/DRM support
#endif
    if (!vainst)
        return VLC_EGENERIC;
    assert(vadpy != NULL);

    device->ops = &ops;
    device->sys = vainst;
    device->type = VLC_DECODER_DEVICE_VAAPI;
    device->opaque = vadpy;
    return VLC_SUCCESS;
}

#if defined (HAVE_VA_X11)
# define PRIORITY 5
# define SHORTCUT "vaapi_x11"
# define DESCRIPTION_SUFFIX "X11"
#elif defined(HAVE_VA_WL)
# define PRIORITY 5
# define SHORTCUT "vaapi_wl"
# define DESCRIPTION_SUFFIX "Wayland"
#elif defined (HAVE_VA_DRM)
# define PRIORITY 4
# define SHORTCUT "vaapi_drm"
# define DESCRIPTION_SUFFIX "DRM"
#endif

vlc_module_begin ()
    set_description("VA-API decoder device for " DESCRIPTION_SUFFIX)
    set_callback_dec_device(Open, PRIORITY)
    set_subcategory(SUBCAT_VIDEO_VOUT)
    add_shortcut("vaapi", SHORTCUT)
vlc_module_end ()

Messung
CHZG
84989893

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.