/src/libheif/libheif/plugin_registry.cc
Line | Count | Source |
1 | | /* |
2 | | * HEIF codec. |
3 | | * Copyright (c) 2017 Dirk Farin <dirk.farin@gmail.com> |
4 | | * |
5 | | * This file is part of libheif. |
6 | | * |
7 | | * libheif is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation, either version 3 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * libheif is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libheif. If not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #include <utility> |
22 | | #include <cstring> |
23 | | #include <algorithm> |
24 | | |
25 | | #include "plugin_registry.h" |
26 | | #include "init.h" |
27 | | |
28 | | #if HAVE_WEBCODECS |
29 | | #include "plugins/decoder_webcodecs.h" |
30 | | #endif |
31 | | |
32 | | #if HAVE_LIBDE265 |
33 | | #include "plugins/decoder_libde265.h" |
34 | | #endif |
35 | | |
36 | | #if HAVE_X265 |
37 | | #include "plugins/encoder_x265.h" |
38 | | #endif |
39 | | |
40 | | #if HAVE_KVAZAAR |
41 | | #include "plugins/encoder_kvazaar.h" |
42 | | #endif |
43 | | |
44 | | #if HAVE_UVG266 |
45 | | #include "plugins/encoder_uvg266.h" |
46 | | #endif |
47 | | |
48 | | #if HAVE_VVDEC |
49 | | #include "plugins/decoder_vvdec.h" |
50 | | #endif |
51 | | |
52 | | #if HAVE_VVENC |
53 | | #include "plugins/encoder_vvenc.h" |
54 | | #endif |
55 | | |
56 | | #if HAVE_AOM_ENCODER |
57 | | #include "plugins/encoder_aom.h" |
58 | | #endif |
59 | | |
60 | | #if HAVE_AOM_DECODER |
61 | | #include "plugins/decoder_aom.h" |
62 | | #endif |
63 | | |
64 | | #if HAVE_RAV1E |
65 | | #include "plugins/encoder_rav1e.h" |
66 | | #endif |
67 | | |
68 | | #if HAVE_DAV1D |
69 | | #include "plugins/decoder_dav1d.h" |
70 | | #endif |
71 | | |
72 | | #if HAVE_SvtEnc |
73 | | #include "plugins/encoder_svt.h" |
74 | | #endif |
75 | | |
76 | | #if HAVE_FFMPEG_DECODER |
77 | | #include "plugins/decoder_ffmpeg.h" |
78 | | #endif |
79 | | |
80 | | #if WITH_UNCOMPRESSED_CODEC |
81 | | #include "plugins/encoder_uncompressed.h" |
82 | | #include "plugins/decoder_uncompressed.h" |
83 | | #endif |
84 | | |
85 | | #if HAVE_JPEG_DECODER |
86 | | #include "plugins/decoder_jpeg.h" |
87 | | #endif |
88 | | |
89 | | #if HAVE_JPEG_ENCODER |
90 | | #include "plugins/encoder_jpeg.h" |
91 | | #endif |
92 | | |
93 | | #if HAVE_X264 |
94 | | #include "plugins/encoder_x264.h" |
95 | | #endif |
96 | | |
97 | | #if HAVE_OpenH264_DECODER |
98 | | #include "plugins/decoder_openh264.h" |
99 | | #endif |
100 | | |
101 | | #if HAVE_OPENJPEG_ENCODER |
102 | | #include "plugins/encoder_openjpeg.h" |
103 | | #endif |
104 | | |
105 | | #if HAVE_OPENJPEG_DECODER |
106 | | #include "plugins/decoder_openjpeg.h" |
107 | | #endif |
108 | | |
109 | | #include "plugins/encoder_mask.h" |
110 | | |
111 | | #if HAVE_OPENJPH_ENCODER |
112 | | #include "plugins/encoder_openjph.h" |
113 | | #endif |
114 | | |
115 | | std::set<const heif_decoder_plugin*> s_decoder_plugins; |
116 | | |
117 | | std::multiset<std::unique_ptr<heif_encoder_descriptor>, |
118 | | encoder_descriptor_priority_order> s_encoder_descriptors; |
119 | | |
120 | | std::set<const heif_decoder_plugin*>& get_decoder_plugins() |
121 | 36 | { |
122 | 36 | load_plugins_if_not_initialized_yet(); |
123 | | |
124 | 36 | return s_decoder_plugins; |
125 | 36 | } |
126 | | |
127 | | extern std::multiset<std::unique_ptr<heif_encoder_descriptor>, |
128 | | encoder_descriptor_priority_order>& get_encoder_descriptors() |
129 | 0 | { |
130 | 0 | load_plugins_if_not_initialized_yet(); |
131 | |
|
132 | 0 | return s_encoder_descriptors; |
133 | 0 | } |
134 | | |
135 | | |
136 | | // Note: we cannot move this to 'heif_init' because we have to make sure that this is initialized |
137 | | // AFTER the two global std::set above. |
138 | | static class Register_Default_Plugins |
139 | | { |
140 | | public: |
141 | | Register_Default_Plugins() |
142 | 254 | { |
143 | 254 | register_default_plugins(); |
144 | 254 | } |
145 | | } dummy; |
146 | | |
147 | | |
148 | | void register_default_plugins() |
149 | 254 | { |
150 | | #if HAVE_WEBCODECS |
151 | | register_decoder(get_decoder_plugin_webcodecs()); |
152 | | #endif |
153 | | |
154 | 254 | #if HAVE_LIBDE265 |
155 | 254 | register_decoder(get_decoder_plugin_libde265()); |
156 | 254 | #endif |
157 | | |
158 | 254 | #if HAVE_X265 |
159 | 254 | register_encoder(get_encoder_plugin_x265()); |
160 | 254 | #endif |
161 | | |
162 | | #if HAVE_KVAZAAR |
163 | | register_encoder(get_encoder_plugin_kvazaar()); |
164 | | #endif |
165 | | |
166 | | #if HAVE_UVG266 |
167 | | register_encoder(get_encoder_plugin_uvg266()); |
168 | | #endif |
169 | | |
170 | 254 | #if HAVE_VVENC |
171 | 254 | register_encoder(get_encoder_plugin_vvenc()); |
172 | 254 | #endif |
173 | | |
174 | 254 | #if HAVE_VVDEC |
175 | 254 | register_decoder(get_decoder_plugin_vvdec()); |
176 | 254 | #endif |
177 | | |
178 | 254 | #if HAVE_AOM_ENCODER |
179 | 254 | register_encoder(get_encoder_plugin_aom()); |
180 | 254 | #endif |
181 | | |
182 | 254 | #if HAVE_AOM_DECODER |
183 | 254 | register_decoder(get_decoder_plugin_aom()); |
184 | 254 | #endif |
185 | | |
186 | | #if HAVE_RAV1E |
187 | | register_encoder(get_encoder_plugin_rav1e()); |
188 | | #endif |
189 | | |
190 | 254 | #if HAVE_DAV1D |
191 | 254 | register_decoder(get_decoder_plugin_dav1d()); |
192 | 254 | #endif |
193 | | |
194 | | #if HAVE_SvtEnc |
195 | | register_encoder(get_encoder_plugin_svt()); |
196 | | #endif |
197 | | |
198 | | #if HAVE_FFMPEG_DECODER |
199 | | register_decoder(get_decoder_plugin_ffmpeg()); |
200 | | #endif |
201 | | |
202 | 254 | #if HAVE_JPEG_DECODER |
203 | 254 | register_decoder(get_decoder_plugin_jpeg()); |
204 | 254 | #endif |
205 | | |
206 | 254 | #if HAVE_JPEG_ENCODER |
207 | 254 | register_encoder(get_encoder_plugin_jpeg()); |
208 | 254 | #endif |
209 | | |
210 | 254 | #if HAVE_OPENJPEG_ENCODER |
211 | 254 | register_encoder(get_encoder_plugin_openjpeg()); |
212 | 254 | #endif |
213 | | |
214 | 254 | #if HAVE_OPENJPEG_DECODER |
215 | 254 | register_decoder(get_decoder_plugin_openjpeg()); |
216 | 254 | #endif |
217 | | |
218 | 254 | #if HAVE_OPENJPH_ENCODER |
219 | 254 | register_encoder(get_encoder_plugin_openjph()); |
220 | 254 | #endif |
221 | | |
222 | 254 | #if HAVE_OpenH264_DECODER |
223 | 254 | register_decoder(get_decoder_plugin_openh264()); |
224 | 254 | #endif |
225 | | |
226 | 254 | #if HAVE_X264 |
227 | 254 | register_encoder(get_encoder_plugin_x264()); |
228 | 254 | #endif |
229 | | |
230 | 254 | #if WITH_UNCOMPRESSED_CODEC |
231 | 254 | register_encoder(get_encoder_plugin_uncompressed()); |
232 | 254 | register_decoder(get_decoder_plugin_uncompressed()); |
233 | 254 | #endif |
234 | | |
235 | 254 | register_encoder(get_encoder_plugin_mask()); |
236 | 254 | } |
237 | | |
238 | | |
239 | | void register_decoder(const heif_decoder_plugin* decoder_plugin) |
240 | 2.03k | { |
241 | 2.03k | if (decoder_plugin->init_plugin) { |
242 | 1.77k | (*decoder_plugin->init_plugin)(); |
243 | 1.77k | } |
244 | | |
245 | 2.03k | s_decoder_plugins.insert(decoder_plugin); |
246 | 2.03k | } |
247 | | |
248 | | |
249 | | bool has_decoder(heif_compression_format type, const char* name_id) |
250 | 0 | { |
251 | 0 | load_plugins_if_not_initialized_yet(); |
252 | |
|
253 | 0 | for (const auto* plugin : s_decoder_plugins) { |
254 | 0 | int priority = plugin->does_support_format(type); |
255 | 0 | if (priority > 0 && strcmp(name_id, plugin->id_name) == 0) { |
256 | 0 | return true; |
257 | 0 | } |
258 | 0 | } |
259 | | |
260 | 0 | return false; |
261 | 0 | } |
262 | | |
263 | | |
264 | | const heif_decoder_plugin* get_decoder(heif_compression_format type, const char* name_id) |
265 | 48.4k | { |
266 | 48.4k | load_plugins_if_not_initialized_yet(); |
267 | | |
268 | 48.4k | int highest_priority = 0; |
269 | 48.4k | const struct heif_decoder_plugin* best_plugin = nullptr; |
270 | | |
271 | 387k | for (const auto* plugin : s_decoder_plugins) { |
272 | | |
273 | 387k | int priority = plugin->does_support_format(type); |
274 | | |
275 | 387k | if (priority > 0 && name_id && plugin->plugin_api_version >= 3) { |
276 | 0 | if (strcmp(name_id, plugin->id_name) == 0) { |
277 | 0 | return plugin; |
278 | 0 | } |
279 | 0 | } |
280 | | |
281 | 387k | if (priority > highest_priority) { |
282 | 48.4k | highest_priority = priority; |
283 | 48.4k | best_plugin = plugin; |
284 | 48.4k | } |
285 | 387k | } |
286 | | |
287 | 48.4k | return best_plugin; |
288 | 48.4k | } |
289 | | |
290 | | |
291 | | void register_encoder(const heif_encoder_plugin* encoder_plugin) |
292 | 2.28k | { |
293 | 2.28k | if (encoder_plugin->init_plugin) { |
294 | 2.28k | (*encoder_plugin->init_plugin)(); |
295 | 2.28k | } |
296 | | |
297 | 2.28k | auto descriptor = std::unique_ptr<heif_encoder_descriptor>(new heif_encoder_descriptor); |
298 | 2.28k | descriptor->plugin = encoder_plugin; |
299 | | |
300 | 2.28k | s_encoder_descriptors.insert(std::move(descriptor)); |
301 | 2.28k | } |
302 | | |
303 | | |
304 | | const heif_encoder_plugin* get_encoder(heif_compression_format type) |
305 | 0 | { |
306 | 0 | auto filtered_encoder_descriptors = get_filtered_encoder_descriptors(type, nullptr); |
307 | 0 | if (filtered_encoder_descriptors.size() > 0) { |
308 | 0 | return filtered_encoder_descriptors[0]->plugin; |
309 | 0 | } |
310 | 0 | else { |
311 | 0 | return nullptr; |
312 | 0 | } |
313 | 0 | } |
314 | | |
315 | | |
316 | | std::vector<const heif_encoder_descriptor*> |
317 | | get_filtered_encoder_descriptors(heif_compression_format format, |
318 | | const char* name) |
319 | 0 | { |
320 | 0 | load_plugins_if_not_initialized_yet(); |
321 | |
|
322 | 0 | std::vector<const heif_encoder_descriptor*> filtered_descriptors; |
323 | |
|
324 | 0 | for (const auto& descr : s_encoder_descriptors) { |
325 | 0 | const heif_encoder_plugin* plugin = descr->plugin; |
326 | |
|
327 | 0 | if (plugin->compression_format == format || format == heif_compression_undefined) { |
328 | 0 | if (name == nullptr || strcmp(name, plugin->id_name) == 0) { |
329 | 0 | filtered_descriptors.push_back(descr.get()); |
330 | 0 | } |
331 | 0 | } |
332 | 0 | } |
333 | | |
334 | | |
335 | | // Note: since our std::set<> is ordered by priority, we do not have to sort our output |
336 | |
|
337 | 0 | return filtered_descriptors; |
338 | 0 | } |
339 | | |
340 | | |
341 | | void heif_unregister_decoder_plugins() |
342 | 0 | { |
343 | 0 | for (const auto* plugin : s_decoder_plugins) { |
344 | 0 | if (plugin->deinit_plugin) { |
345 | 0 | (*plugin->deinit_plugin)(); |
346 | 0 | } |
347 | 0 | } |
348 | 0 | s_decoder_plugins.clear(); |
349 | 0 | } |
350 | | |
351 | | void heif_unregister_encoder_plugins() |
352 | 0 | { |
353 | 0 | for (const auto& plugin : s_encoder_descriptors) { |
354 | 0 | if (plugin->plugin->cleanup_plugin) { |
355 | 0 | (*plugin->plugin->cleanup_plugin)(); |
356 | 0 | } |
357 | 0 | } |
358 | 0 | s_encoder_descriptors.clear(); |
359 | 0 | } |
360 | | |
361 | | #if ENABLE_PLUGIN_LOADING |
362 | | void heif_unregister_encoder_plugin(const heif_encoder_plugin* plugin) |
363 | | { |
364 | | if (plugin->cleanup_plugin) { |
365 | | (*plugin->cleanup_plugin)(); |
366 | | } |
367 | | |
368 | | for (auto iter = s_encoder_descriptors.begin() ; iter != s_encoder_descriptors.end(); ++iter) { |
369 | | if ((*iter)->plugin == plugin) { |
370 | | s_encoder_descriptors.erase(iter); |
371 | | return; |
372 | | } |
373 | | } |
374 | | } |
375 | | #endif |