1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#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;
};
OPT_STRING_VALIDATE_FUNC(ra_hwdec_validate_opt);
OPT_STRING_VALIDATE_FUNC(ra_hwdec_validate_drivers_only_opt);
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
|