diff options
Diffstat (limited to 'video/out/gpu/hwdec.h')
-rw-r--r-- | video/out/gpu/hwdec.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/video/out/gpu/hwdec.h b/video/out/gpu/hwdec.h new file mode 100644 index 0000000..7766073 --- /dev/null +++ b/video/out/gpu/hwdec.h @@ -0,0 +1,156 @@ +#ifndef MPGL_HWDEC_H_ +#define MPGL_HWDEC_H_ + +#include "video/mp_image.h" +#include "context.h" +#include "ra.h" +#include "video/hwdec.h" + +// Helper to organize/load hwdecs dynamically +struct ra_hwdec_ctx { + // Set these before calling `ra_hwdec_ctx_init` + struct mp_log *log; + struct mpv_global *global; + struct ra_ctx *ra_ctx; + + bool loading_done; + struct ra_hwdec **hwdecs; + int num_hwdecs; +}; + +int ra_hwdec_validate_opt(struct mp_log *log, const m_option_t *opt, + struct bstr name, const char **value); + +int ra_hwdec_validate_drivers_only_opt(struct mp_log *log, + const m_option_t *opt, + struct bstr name, const char **value); + +void ra_hwdec_ctx_init(struct ra_hwdec_ctx *ctx, struct mp_hwdec_devices *devs, + const char *opt, bool load_all_by_default); +void ra_hwdec_ctx_uninit(struct ra_hwdec_ctx *ctx); + +void ra_hwdec_ctx_load_fmt(struct ra_hwdec_ctx *ctx, struct mp_hwdec_devices *devs, + struct hwdec_imgfmt_request *params); + +// Gets the right `ra_hwdec` for a format, if any +struct ra_hwdec *ra_hwdec_get(struct ra_hwdec_ctx *ctx, int imgfmt); + +struct ra_hwdec { + const struct ra_hwdec_driver *driver; + struct mp_log *log; + struct mpv_global *global; + struct ra_ctx *ra_ctx; + struct mp_hwdec_devices *devs; + // GLSL extensions required to sample textures from this. + const char **glsl_extensions; + // For free use by hwdec driver + void *priv; + // For working around the vdpau vs. vaapi mess. + bool probing; + // Used in overlay mode only. + float overlay_colorkey[4]; +}; + +struct ra_hwdec_mapper { + const struct ra_hwdec_mapper_driver *driver; + struct mp_log *log; + struct ra *ra; + void *priv; + struct ra_hwdec *owner; + // Input frame parameters. (Set before init(), immutable.) + struct mp_image_params src_params; + // Output frame parameters (represents the format the textures return). Must + // be set by init(), immutable afterwards, + struct mp_image_params dst_params; + + // The currently mapped source image (or the image about to be mapped in + // ->map()). NULL if unmapped. The mapper can also clear this reference if + // the mapped textures contain a full copy. + struct mp_image *src; + + // The mapped textures and metadata about them. These fields change if a + // new frame is mapped (or unmapped), but otherwise remain constant. + // The common code won't mess with these, so you can e.g. set them in the + // .init() callback. + struct ra_tex *tex[4]; +}; + +// This can be used to map frames of a specific hw format as GL textures. +struct ra_hwdec_mapper_driver { + // Used to create ra_hwdec_mapper.priv. + size_t priv_size; + + // Init the mapper implementation. At this point, the field src_params, + // fns, devs, priv are initialized. + int (*init)(struct ra_hwdec_mapper *mapper); + // Destroy the mapper. unmap is called before this. + void (*uninit)(struct ra_hwdec_mapper *mapper); + + // Map mapper->src as texture, and set mapper->frame to textures using it. + // It is expected that the textures remain valid until the next unmap + // or uninit call. + // The function is allowed to unref mapper->src if it's not needed (i.e. + // this function creates a copy). + // The underlying format can change, so you might need to do some form + // of change detection. You also must reject unsupported formats with an + // error. + // On error, returns negative value on error and remains unmapped. + int (*map)(struct ra_hwdec_mapper *mapper); + // Unmap the frame. Does nothing if already unmapped. Optional. + void (*unmap)(struct ra_hwdec_mapper *mapper); +}; + +struct ra_hwdec_driver { + // Name of the interop backend. This is used for informational purposes and + // for use with debugging options. + const char *name; + // Used to create ra_hwdec.priv. + size_t priv_size; + // One of the hardware surface IMGFMT_ that must be passed to map_image later. + // Terminated with a 0 entry. (Extend the array size as needed.) + const int imgfmts[3]; + + // Create the hwdec device. It must add it to hw->devs, if applicable. + int (*init)(struct ra_hwdec *hw); + void (*uninit)(struct ra_hwdec *hw); + + // This will be used to create a ra_hwdec_mapper from ra_hwdec. + const struct ra_hwdec_mapper_driver *mapper; + + // The following function provides an alternative API. Each ra_hwdec_driver + // must have either provide a mapper or overlay_frame (not both or none), and + // if overlay_frame is set, it operates in overlay mode. In this mode, + // OSD etc. is rendered via OpenGL, but the video is rendered as a separate + // layer below it. + // Non-overlay mode is strictly preferred, so try not to use overlay mode. + // Set the given frame as overlay, replacing the previous one. This can also + // just change the position of the overlay. + // hw_image==src==dst==NULL is passed to clear the overlay. + int (*overlay_frame)(struct ra_hwdec *hw, struct mp_image *hw_image, + struct mp_rect *src, struct mp_rect *dst, bool newframe); +}; + +extern const struct ra_hwdec_driver *const ra_hwdec_drivers[]; + +struct ra_hwdec *ra_hwdec_load_driver(struct ra_ctx *ra_ctx, + struct mp_log *log, + struct mpv_global *global, + struct mp_hwdec_devices *devs, + const struct ra_hwdec_driver *drv, + bool is_auto); + +void ra_hwdec_uninit(struct ra_hwdec *hwdec); + +bool ra_hwdec_test_format(struct ra_hwdec *hwdec, int imgfmt); + +struct ra_hwdec_mapper *ra_hwdec_mapper_create(struct ra_hwdec *hwdec, + const struct mp_image_params *params); +void ra_hwdec_mapper_free(struct ra_hwdec_mapper **mapper); +void ra_hwdec_mapper_unmap(struct ra_hwdec_mapper *mapper); +int ra_hwdec_mapper_map(struct ra_hwdec_mapper *mapper, struct mp_image *img); + +// Get the primary image format for the given driver name. +// Returns IMGFMT_NONE if the name doesn't get matched. +int ra_hwdec_driver_get_imgfmt_for_name(const char *name); + +#endif |