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

Quelle  interop.c   Sprache: C

 

/*****************************************************************************
 * interop.h
 *****************************************************************************
 * Copyright (C) 2019 Videolabs
 *
 * 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_modules.h>

#include "gl_util.h"
#include "interop.h"

struct vlc_gl_interop_private
{
    struct vlc_gl_interop interop;

#define OPENGL_VTABLE_F(X) \
        X(PFNGLDELETETEXTURESPROC, DeleteTextures) \
        X(PFNGLGENTEXTURESPROC,    GenTextures) \
        X(PFNGLBINDTEXTUREPROC,    BindTexture) \
        X(PFNGLTEXIMAGE2DPROC,     TexImage2D) \
        X(PFNGLTEXENVFPROC,        TexEnvf) \
        X(PFNGLTEXPARAMETERFPROC,  TexParameterf) \
        X(PFNGLTEXPARAMETERIPROC,  TexParameteri) \
        X(PFNGLGETERRORPROC,       GetError) \
        X(PFNGLGETTEXLEVELPARAMETERIVPROC, GetTexLevelParameteriv) \

    struct {
#define DECLARE_SYMBOL(type, name) type name;
        OPENGL_VTABLE_F(DECLARE_SYMBOL)
    } gl;
};

int
vlc_gl_interop_GenerateTextures(const struct vlc_gl_interop *interop,
                                const GLsizei *tex_width,
                                const GLsizei *tex_height, GLuint *textures)
{
    struct vlc_gl_interop_private *priv =
        container_of(interop, struct vlc_gl_interop_private, interop);

    priv->gl.GenTextures(interop->tex_count, textures);

    for (unsigned i = 0; i < interop->tex_count; i++)
    {
        priv->gl.BindTexture(interop->tex_target, textures[i]);

        priv->gl.TexParameteri(interop->tex_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        priv->gl.TexParameteri(interop->tex_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        priv->gl.TexParameteri(interop->tex_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        priv->gl.TexParameteri(interop->tex_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }
    GL_ASSERT_NOERROR(&priv->gl);

    if (interop->ops->allocate_textures != NULL)
    {
        int ret = interop->ops->allocate_textures(interop, textures, tex_width, tex_height);
        if (ret != VLC_SUCCESS)
        {
            priv->gl.DeleteTextures(interop->tex_count, textures);
            memset(textures, 0, interop->tex_count * sizeof(GLuint));
            return ret;
        }
    }
    return VLC_SUCCESS;
}

void
vlc_gl_interop_DeleteTextures(const struct vlc_gl_interop *interop,
                              GLuint *textures)
{
    struct vlc_gl_interop_private *priv =
        container_of(interop, struct vlc_gl_interop_private, interop);
    if (interop->ops->deallocate_textures != NULL)
        interop->ops->deallocate_textures(interop, textures);
    priv->gl.DeleteTextures(interop->tex_count, textures);
    memset(textures, 0, interop->tex_count * sizeof(GLuint));
}

static int GetTexFormatSize(struct vlc_gl_interop *interop, GLenum target,
                            GLenum tex_format, GLint tex_internal, GLenum tex_type)
{
    struct vlc_gl_interop_private *priv =
        container_of(interop, struct vlc_gl_interop_private, interop);

    GL_ASSERT_NOERROR(&priv->gl);

    if (!priv->gl.GetTexLevelParameteriv)
        return -1;

    GLint tex_param_size;
    int mul = 1;
    switch (tex_format)
    {
        case GL_BGRA:
            mul = 4;
            /* fall through */
        case GL_RED:
        case GL_RED_INTEGER:
        case GL_RG:
        case GL_RGBA:
            tex_param_size = GL_TEXTURE_RED_SIZE;
            break;
        case GL_LUMINANCE:
        case GL_LUMINANCE_ALPHA:
            tex_param_size = GL_TEXTURE_LUMINANCE_SIZE;
            break;
        default:
            return -1;
    }
    GLuint texture;

    priv->gl.GenTextures(1, &texture);
    priv->gl.BindTexture(target, texture);
    priv->gl.TexImage2D(target, 0, tex_internal, 64, 64, 0, tex_format, tex_type, NULL);
    GLint size = 0;
    priv->gl.GetTexLevelParameteriv(target, 0, tex_param_size, &size);

    priv->gl.DeleteTextures(1, &texture);

    bool has_error = false;
    while (priv->gl.GetError() != GL_NO_ERROR)
        has_error = true;

    if (has_error)
        return -1;

    return size > 0 ? size * mul : size;
}

static int
LoadInterop(void *func, bool forced, va_list args)
{
    (void)forced;
    vlc_gl_interop_probe start = func;
    struct vlc_gl_interop *interop = va_arg(args, struct vlc_gl_interop *);
    return start(interop);
}

struct vlc_gl_interop *
vlc_gl_interop_New(struct vlc_gl_t *gl, vlc_video_context *context,
                   const video_format_t *fmt)
{
    struct vlc_gl_interop_private *priv = vlc_object_create(gl, sizeof *priv);
    if (priv == NULL)
        return NULL;

    struct vlc_gl_interop *interop = &priv->interop;
    struct vlc_logger *logger = vlc_object_logger(interop);

    interop->get_tex_format_size = GetTexFormatSize;
    interop->ops = NULL;
    interop->fmt_out = interop->fmt_in = *fmt;
    interop->gl = gl;
    /* this is the only allocated field, and we don't need it */
    interop->fmt_out.p_palette = interop->fmt_in.p_palette = NULL;

    const vlc_chroma_description_t *desc =
        vlc_fourcc_GetChromaDescription(fmt->i_chroma);

    if (desc == NULL)
    {
        vlc_object_delete(interop);
        return NULL;
    }

#define LOAD_SYMBOL(type, name) \
    priv->gl.name = vlc_gl_GetProcAddress(interop->gl, "gl" # name);
    OPENGL_VTABLE_F(LOAD_SYMBOL);
#undef LOAD_SYMBOL

    if (desc->plane_count == 0)
    {
        /* Opaque chroma: load a module to handle it */
        assert(context);
        interop->vctx = vlc_video_context_Hold(context);
        char *interop_name = var_InheritString(interop, "glinterop");
        interop->module = vlc_module_load(logger, "glinterop", interop_name,
                                          true, LoadInterop, interop);
        free(interop_name);
    }
    else
    {
        interop->vctx = NULL;
        interop->module = vlc_module_load(logger, "opengl sw interop", NULL,
                                          false, LoadInterop, interop);
    }

    if (interop->module == NULL)
        goto error;

    return interop;

error:
    if (interop->vctx)
       vlc_video_context_Release(interop->vctx);
    vlc_object_delete(interop);
    return NULL;
}

struct vlc_gl_interop *
vlc_gl_interop_NewForSubpictures(struct vlc_gl_t *gl)
{
    struct vlc_gl_interop_private *priv = vlc_object_create(gl, sizeof *priv);
    if (priv == NULL)
        return NULL;

    struct vlc_gl_interop *interop = &priv->interop;
    interop->ops = NULL;
    interop->gl = gl;

    video_format_Init(&interop->fmt_in, VLC_CODEC_RGBA);
    interop->fmt_out = interop->fmt_in;

#define LOAD_SYMBOL(type, name) \
    priv->gl.name = vlc_gl_GetProcAddress(interop->gl, "gl" # name);
    OPENGL_VTABLE_F(LOAD_SYMBOL);
#undef LOAD_SYMBOL

    interop->module = module_need(interop, "opengl sw interop", "sw", true);

    if (interop->module == NULL)
        goto error;

    return interop;
error:
    vlc_object_delete(interop);
    return NULL;
}

void
vlc_gl_interop_Delete(struct vlc_gl_interop *interop)
{
    if (interop->ops && interop->ops->close)
        interop->ops->close(interop);
    if (interop->vctx)
        vlc_video_context_Release(interop->vctx);
    if (interop->module)
        module_unneed(interop, interop->module);
    vlc_object_delete(interop);
}

Messung
CHZG
849510093

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© 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.