Panda3D
Loading...
Searching...
No Matches
movieTypeRegistry.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file movieTypeRegistry.cxx
10 * @author rdb
11 * @date 2013-08-24
12 */
13
14#include "movieTypeRegistry.h"
15
16#include "string_utils.h"
17#include "config_movies.h"
18#include "config_putil.h"
19#include "load_dso.h"
20#include "reMutexHolder.h"
21
22using std::endl;
23using std::string;
24
25MovieTypeRegistry *MovieTypeRegistry::_global_ptr = nullptr;
26
27/**
28 * Obtains a MovieVideo that references a file.
29 */
30PT(MovieAudio) MovieTypeRegistry::
31make_audio(const Filename &name) {
32 string ext = downcase(name.get_extension());
33
34#ifdef HAVE_ZLIB
35 if (ext == "pz" || ext == "gz") {
37 }
38#endif
39
40 _audio_lock.lock();
41
42 // Make sure that the list of audio types has been read in.
44
45 // Maybe we need to load a module?
46 if (_deferred_audio_types.count(ext)) {
47 load_movie_library(_deferred_audio_types[ext]);
48 _deferred_audio_types.erase(ext);
49 }
50
51 // Explicit extension is preferred over catch-all.
52 if (_audio_type_registry.count(ext)) {
53 MakeAudioFunc func = _audio_type_registry[ext];
54 _audio_lock.unlock();
55 return (*func)(name);
56 }
57
58 // If we didn't find it, see if there was a type registered with '*' as
59 // extension. This is a catch-all loader.
60 if (_deferred_audio_types.count("*")) {
61 load_movie_library(_deferred_audio_types["*"]);
62 _deferred_audio_types.erase("*");
63 }
64
65 if (_audio_type_registry.count("*")) {
66 MakeAudioFunc func = _audio_type_registry["*"];
67 _audio_lock.unlock();
68 return (*func)(name);
69 }
70
71 movies_cat.error()
72 << "Support for audio files with extension ." << ext << " was not enabled.\n";
73
74 _audio_lock.unlock();
75 return new MovieAudio("Load-Failure Stub");
76}
77
78/**
79 * Registers a MovieAudio type, so that files with any of the given extensions
80 * will be loaded as this type. You may use * as a catch-all extension.
81 */
83register_audio_type(MakeAudioFunc func, const string &extensions) {
84 ReMutexHolder holder(_audio_lock);
85 vector_string words;
86 extract_words(downcase(extensions), words);
87
88 vector_string::const_iterator wi;
89 for (wi = words.begin(); wi != words.end(); ++wi) {
90 if (_audio_type_registry.count(*wi)) {
91 movies_cat->warning()
92 << "Attempt to register multiple audio types with extension " << (*wi) << "\n";
93 } else if (movies_cat->is_debug()) {
94 movies_cat->debug()
95 << "Registered audio type with extension " << (*wi) << "\n";
96 }
97 _audio_type_registry[*wi] = func;
98 }
99}
100
101/**
102 * Loads the list with audio types, if we haven't already.
103 */
106 ReMutexHolder holder(_audio_lock);
107 static bool audio_types_loaded = false;
108
109 if (!audio_types_loaded) {
110 int num_unique_values = load_audio_type.get_num_unique_values();
111
112 for (int i = 0; i < num_unique_values; i++) {
113 string param = load_audio_type.get_unique_value(i);
114
115 vector_string words;
116 extract_words(param, words);
117
118 if (words.size() == 1) {
119 // Exactly one word: load the named library immediately.
120 string name = words[0];
121 Filename dlname = Filename::dso_filename("lib" + name + ".so");
122 movies_cat.info()
123 << "loading audio type module: " << name << endl;
124 void *tmp = load_dso(get_plugin_path().get_value(), dlname);
125 if (tmp == nullptr) {
126 std::string error = load_dso_error();
127 movies_cat.warning()
128 << "Unable to load " << dlname.to_os_specific()
129 << ": " << error << endl;
130 } else if (movies_cat.is_debug()) {
131 movies_cat.debug()
132 << "done loading audio type module: " << name << endl;
133 }
134
135 } else if (words.size() > 1) {
136 // Multiple words: the first n words are filename extensions, and the
137 // last word is the name of the library to load should any of those
138 // filename extensions be encountered.
139 size_t num_extensions = words.size() - 1;
140 string library_name = words[num_extensions];
141
142 for (size_t i = 0; i < num_extensions; i++) {
143 string extension = downcase(words[i]);
144 if (extension[0] == '.') {
145 extension = extension.substr(1);
146 }
147
148 _deferred_audio_types[extension] = library_name;
149 }
150 }
151 }
152
153 audio_types_loaded = true;
154 }
155}
156
157/**
158 * Obtains a MovieVideo that references a file.
159 */
160PT(MovieVideo) MovieTypeRegistry::
161make_video(const Filename &name) {
162 string ext = downcase(name.get_extension());
163
164#ifdef HAVE_ZLIB
165 if (ext == "pz" || ext == "gz") {
167 }
168#endif
169
170 _video_lock.lock();
171
172 // Make sure that the list of video types has been read in.
174
175 // Maybe we need to load a module?
176 if (_deferred_video_types.count(ext)) {
177 load_movie_library(_deferred_video_types[ext]);
178 _deferred_video_types.erase(ext);
179 }
180
181 // Explicit extension is preferred over catch-all.
182 if (_video_type_registry.count(ext)) {
183 MakeVideoFunc func = _video_type_registry[ext];
184 _video_lock.unlock();
185 return (*func)(name);
186 }
187
188 // If we didn't find it, see if there was a type registered with '*' as
189 // extension. This is a catch-all loader.
190 if (_deferred_video_types.count("*")) {
191 load_movie_library(_deferred_video_types["*"]);
192 _deferred_video_types.erase("*");
193 }
194
195 if (_video_type_registry.count("*")) {
196 MakeVideoFunc func = _video_type_registry["*"];
197 _video_lock.unlock();
198 return (*func)(name);
199 }
200
201 movies_cat.error()
202 << "Support for video files with extension ." << ext << " was not enabled.\n";
203
204 _video_lock.unlock();
205 return new MovieVideo("Load-Failure Stub");
206}
207
208/**
209 * Registers a MovieVideo type, so that files with any of the given extensions
210 * will be loaded as this type. You may use * as a catch-all extension.
211 */
213register_video_type(MakeVideoFunc func, const string &extensions) {
214 ReMutexHolder holder(_video_lock);
215 vector_string words;
216 extract_words(downcase(extensions), words);
217
218 vector_string::const_iterator wi;
219 for (wi = words.begin(); wi != words.end(); ++wi) {
220 if (_video_type_registry.count(*wi)) {
221 movies_cat->warning()
222 << "Attempt to register multiple video types with extension " << (*wi) << "\n";
223 } else if (movies_cat->is_debug()) {
224 movies_cat->debug()
225 << "Registered video type with extension " << (*wi) << "\n";
226 }
227 _video_type_registry[*wi] = func;
228 }
229}
230
231/**
232 * Loads the list with video types, if we haven't already.
233 */
236 ReMutexHolder holder(_video_lock);
237 static bool video_types_loaded = false;
238
239 if (!video_types_loaded) {
240 int num_unique_values = load_video_type.get_num_unique_values();
241
242 for (int i = 0; i < num_unique_values; i++) {
243 string param = load_video_type.get_unique_value(i);
244
245 vector_string words;
246 extract_words(param, words);
247
248 if (words.size() == 1) {
249 // Exactly one word: load the named library immediately.
250 string name = words[0];
251 Filename dlname = Filename::dso_filename("lib" + name + ".so");
252 movies_cat.info()
253 << "loading video type module: " << name << endl;
254 void *tmp = load_dso(get_plugin_path().get_value(), dlname);
255 if (tmp == nullptr) {
256 std::string error = load_dso_error();
257 movies_cat.warning()
258 << "Unable to load " << dlname.to_os_specific()
259 << ": " << error << endl;
260 } else if (movies_cat.is_debug()) {
261 movies_cat.debug()
262 << "done loading video type module: " << name << endl;
263 }
264
265 } else if (words.size() > 1) {
266 // Multiple words: the first n words are filename extensions, and the
267 // last word is the name of the library to load should any of those
268 // filename extensions be encountered.
269 size_t num_extensions = words.size() - 1;
270 string library_name = words[num_extensions];
271
272 for (size_t i = 0; i < num_extensions; i++) {
273 string extension = downcase(words[i]);
274 if (extension[0] == '.') {
275 extension = extension.substr(1);
276 }
277
278 _deferred_video_types[extension] = library_name;
279 }
280 }
281 }
282
283 video_types_loaded = true;
284 }
285}
286
287/**
288 * Loads the module.
289 */
291load_movie_library(const string &name) {
292 ReMutexHolder holder(_video_lock);
293 Filename dlname = Filename::dso_filename("lib" + name + ".so");
294 movies_cat.info()
295 << "loading video type module: " << name << endl;
296 void *tmp = load_dso(get_plugin_path().get_value(), dlname);
297
298 if (tmp == nullptr) {
299 std::string error = load_dso_error();
300 movies_cat.warning()
301 << "Unable to load " << dlname.to_os_specific()
302 << ": " << error << endl;
303 } else if (movies_cat.is_debug()) {
304 movies_cat.debug()
305 << "done loading video type module: " << name << endl;
306 }
307}
std::string get_unique_value(size_t n) const
Returns the nth unique value of the variable.
size_t get_num_unique_values() const
Returns the number of unique values in the variable.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...
std::string get_extension() const
Returns the file extension.
Definition filename.I:400
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
Definition filename.I:386
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition movieAudio.h:44
This class records the different types of MovieAudio and MovieVideo that are available for loading.
void register_video_type(MakeVideoFunc func, const std::string &extensions)
Registers a MovieVideo type, so that files with any of the given extensions will be loaded as this ty...
void load_audio_types()
Loads the list with audio types, if we haven't already.
void register_audio_type(MakeAudioFunc func, const std::string &extensions)
Registers a MovieAudio type, so that files with any of the given extensions will be loaded as this ty...
void load_video_types()
Loads the list with video types, if we haven't already.
void load_movie_library(const std::string &name)
Loads the module.
A MovieVideo is actually any source that provides a sequence of video frames.
Definition movieVideo.h:38
void unlock()
Alias for release() to match C++11 semantics.
void lock()
Alias for acquire() to match C++11 semantics.
Similar to MutexHolder, but for a reentrant mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int extract_words(const string &str, vector_string &words)
Divides the string into a number of words according to whitespace.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.