libheif/plugin_registry.cc (239 lines of code) (raw):

/* * HEIF codec. * Copyright (c) 2017 Dirk Farin <dirk.farin@gmail.com> * * This file is part of libheif. * * libheif 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 3 of * the License, or (at your option) any later version. * * libheif 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 libheif. If not, see <http://www.gnu.org/licenses/>. */ #include <utility> #include <cstring> #include <algorithm> #include "plugin_registry.h" #include "init.h" #if HAVE_LIBHEVC #include "heif_decoder_libhevc.h" #endif #if HAVE_LIBDE265 #include "plugins/decoder_libde265.h" #endif #if HAVE_X265 #include "plugins/encoder_x265.h" #endif #if HAVE_KVAZAAR #include "plugins/encoder_kvazaar.h" #endif #if HAVE_UVG266 #include "plugins/encoder_uvg266.h" #endif #if HAVE_VVDEC #include "plugins/decoder_vvdec.h" #endif #if HAVE_VVENC #include "plugins/encoder_vvenc.h" #endif #if HAVE_AOM_ENCODER #include "plugins/encoder_aom.h" #endif #if HAVE_AOM_DECODER #include "plugins/decoder_aom.h" #endif #if HAVE_RAV1E #include "plugins/encoder_rav1e.h" #endif #if HAVE_DAV1D #include "plugins/decoder_dav1d.h" #endif #if HAVE_SvtEnc #include "plugins/encoder_svt.h" #endif #if HAVE_FFMPEG_DECODER #include "plugins/decoder_ffmpeg.h" #endif #if WITH_UNCOMPRESSED_CODEC #include "plugins/encoder_uncompressed.h" #endif #if HAVE_JPEG_DECODER #include "plugins/decoder_jpeg.h" #endif #if HAVE_JPEG_ENCODER #include "plugins/encoder_jpeg.h" #endif #if HAVE_OPENJPEG_ENCODER #include "plugins/encoder_openjpeg.h" #endif #if HAVE_OPENJPEG_DECODER #include "plugins/decoder_openjpeg.h" #endif #include "plugins/encoder_mask.h" #if HAVE_OPENJPH_ENCODER #include "plugins/encoder_openjph.h" #endif std::set<const struct heif_decoder_plugin*> s_decoder_plugins; std::multiset<std::unique_ptr<struct heif_encoder_descriptor>, encoder_descriptor_priority_order> s_encoder_descriptors; std::set<const struct heif_decoder_plugin*>& get_decoder_plugins() { load_plugins_if_not_initialized_yet(); return s_decoder_plugins; } extern std::multiset<std::unique_ptr<struct heif_encoder_descriptor>, encoder_descriptor_priority_order>& get_encoder_descriptors() { load_plugins_if_not_initialized_yet(); return s_encoder_descriptors; } // Note: we cannot move this to 'heif_init' because we have to make sure that this is initialized // AFTER the two global std::set above. static class Register_Default_Plugins { public: Register_Default_Plugins() { register_default_plugins(); } } dummy; void register_default_plugins() { #if HAVE_LIBHEVC heif::register_decoder(get_decoder_plugin_libhevc()); #endif #if HAVE_LIBDE265 register_decoder(get_decoder_plugin_libde265()); #endif #if HAVE_X265 register_encoder(get_encoder_plugin_x265()); #endif #if HAVE_KVAZAAR register_encoder(get_encoder_plugin_kvazaar()); #endif #if HAVE_UVG266 register_encoder(get_encoder_plugin_uvg266()); #endif #if HAVE_VVENC register_encoder(get_encoder_plugin_vvenc()); #endif #if HAVE_VVDEC register_decoder(get_decoder_plugin_vvdec()); #endif #if HAVE_AOM_ENCODER register_encoder(get_encoder_plugin_aom()); #endif #if HAVE_AOM_DECODER register_decoder(get_decoder_plugin_aom()); #endif #if HAVE_RAV1E register_encoder(get_encoder_plugin_rav1e()); #endif #if HAVE_DAV1D register_decoder(get_decoder_plugin_dav1d()); #endif #if HAVE_SvtEnc register_encoder(get_encoder_plugin_svt()); #endif #if HAVE_FFMPEG_DECODER register_decoder(get_decoder_plugin_ffmpeg()); #endif #if HAVE_JPEG_DECODER register_decoder(get_decoder_plugin_jpeg()); #endif #if HAVE_JPEG_ENCODER register_encoder(get_encoder_plugin_jpeg()); #endif #if HAVE_OPENJPEG_ENCODER register_encoder(get_encoder_plugin_openjpeg()); #endif #if HAVE_OPENJPEG_DECODER register_decoder(get_decoder_plugin_openjpeg()); #endif #if HAVE_OPENJPH_ENCODER register_encoder(get_encoder_plugin_openjph()); #endif #if WITH_UNCOMPRESSED_CODEC register_encoder(get_encoder_plugin_uncompressed()); #endif register_encoder(get_encoder_plugin_mask()); } void register_decoder(const heif_decoder_plugin* decoder_plugin) { if (decoder_plugin->init_plugin) { (*decoder_plugin->init_plugin)(); } s_decoder_plugins.insert(decoder_plugin); } const struct heif_decoder_plugin* get_decoder(enum heif_compression_format type, const char* name_id) { load_plugins_if_not_initialized_yet(); int highest_priority = 0; const struct heif_decoder_plugin* best_plugin = nullptr; for (const auto* plugin : s_decoder_plugins) { int priority = plugin->does_support_format(type); if (priority > 0 && name_id && plugin->plugin_api_version >= 3) { if (strcmp(name_id, plugin->id_name) == 0) { return plugin; } } if (priority > highest_priority) { highest_priority = priority; best_plugin = plugin; } } return best_plugin; } void register_encoder(const heif_encoder_plugin* encoder_plugin) { if (encoder_plugin->init_plugin) { (*encoder_plugin->init_plugin)(); } auto descriptor = std::unique_ptr<struct heif_encoder_descriptor>(new heif_encoder_descriptor); descriptor->plugin = encoder_plugin; s_encoder_descriptors.insert(std::move(descriptor)); } const struct heif_encoder_plugin* get_encoder(enum heif_compression_format type) { load_plugins_if_not_initialized_yet(); auto filtered_encoder_descriptors = get_filtered_encoder_descriptors(type, nullptr); if (filtered_encoder_descriptors.size() > 0) { return filtered_encoder_descriptors[0]->plugin; } else { return nullptr; } } std::vector<const struct heif_encoder_descriptor*> get_filtered_encoder_descriptors(enum heif_compression_format format, const char* name) { std::vector<const struct heif_encoder_descriptor*> filtered_descriptors; for (const auto& descr : s_encoder_descriptors) { const struct heif_encoder_plugin* plugin = descr->plugin; if (plugin->compression_format == format || format == heif_compression_undefined) { if (name == nullptr || strcmp(name, plugin->id_name) == 0) { filtered_descriptors.push_back(descr.get()); } } } // Note: since our std::set<> is ordered by priority, we do not have to sort our output return filtered_descriptors; } void heif_unregister_decoder_plugins() { for (const auto* plugin : s_decoder_plugins) { if (plugin->deinit_plugin) { (*plugin->deinit_plugin)(); } } s_decoder_plugins.clear(); } void heif_unregister_encoder_plugins() { for (const auto& plugin : s_encoder_descriptors) { if (plugin->plugin->cleanup_plugin) { (*plugin->plugin->cleanup_plugin)(); } } s_encoder_descriptors.clear(); } #if ENABLE_PLUGIN_LOADING void heif_unregister_encoder_plugin(const heif_encoder_plugin* plugin) { if (plugin->cleanup_plugin) { (*plugin->cleanup_plugin)(); } for (auto iter = s_encoder_descriptors.begin() ; iter != s_encoder_descriptors.end(); ++iter) { if ((*iter)->plugin == plugin) { s_encoder_descriptors.erase(iter); return; } } } #endif