1 /*
2 * tcmodule-core.h -- transcode module system, take two: core components.
3 * (C) 2005-2010 - Francesco Romani <fromani -at- gmail -dot- com>
4 *
5 * This file is part of transcode, a video stream processing tool.
6 *
7 * transcode is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * transcode 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 General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22
23 /*
24 * this header file is intended to be included in components
25 * which want to use the new transcode module system, acting like
26 * clients respect to a plugin.
27 */
28
29 #ifndef TCMODULE_CORE_H
30 #define TCMODULE_CORE_H
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <stdint.h>
37
38 #include "tcmodule-data.h" /* pulls framebuffer.h and transcode.h */
39
40 /*
41 * this structure will hold all data needed to use a module by client code:
42 * module operations and capabilities (given by module class, so shared
43 * between all modules) and private data.
44 */
45 typedef struct tcmodule_ *TCModule;
46 struct tcmodule_ {
47 const TCModuleClass *klass;
48 /* pointer to class data shared between all instances */
49
50 TCModuleInstance instance;
51 /* each module has it's private instance data, it's embedded here */
52 };
53
54 /*************************************************************************
55 * interface helpers, using shortened notation *
56 *************************************************************************/
57
58 #ifdef HAVE_GCC_ATTRIBUTES
59 __attribute__((unused))
60 #endif
tc_module_configure(TCModule handle,const char * options,vob_t * vob)61 static int tc_module_configure(TCModule handle,
62 const char *options, vob_t *vob)
63 {
64 return handle->klass->configure(&(handle->instance), options, vob);
65 }
66
67 #ifdef HAVE_GCC_ATTRIBUTES
68 __attribute__((unused))
69 #endif
tc_module_stop(TCModule handle)70 static int tc_module_stop(TCModule handle)
71 {
72 return handle->klass->stop(&(handle->instance));
73 }
74
75 #ifdef HAVE_GCC_ATTRIBUTES
76 __attribute__((unused))
77 #endif
tc_module_inspect(TCModule handle,const char * param,const char ** value)78 static int tc_module_inspect(TCModule handle,
79 const char *param, const char **value)
80 {
81 return handle->klass->inspect(&(handle->instance), param, value);
82 }
83
84 #ifdef HAVE_GCC_ATTRIBUTES
85 __attribute__((unused))
86 #endif
tc_module_encode_video(TCModule handle,vframe_list_t * inframe,vframe_list_t * outframe)87 static int tc_module_encode_video(TCModule handle,
88 vframe_list_t *inframe,
89 vframe_list_t *outframe)
90 {
91 return handle->klass->encode_video(&(handle->instance),
92 inframe, outframe);
93 }
94
95 #ifdef HAVE_GCC_ATTRIBUTES
96 __attribute__((unused))
97 #endif
tc_module_encode_audio(TCModule handle,aframe_list_t * inframe,aframe_list_t * outframe)98 static int tc_module_encode_audio(TCModule handle,
99 aframe_list_t *inframe,
100 aframe_list_t *outframe)
101 {
102 return handle->klass->encode_audio(&(handle->instance),
103 inframe, outframe);
104 }
105
106 #ifdef HAVE_GCC_ATTRIBUTES
107 __attribute__((unused))
108 #endif
tc_module_decode_video(TCModule handle,vframe_list_t * inframe,vframe_list_t * outframe)109 static int tc_module_decode_video(TCModule handle,
110 vframe_list_t *inframe,
111 vframe_list_t *outframe)
112 {
113 return handle->klass->decode_video(&(handle->instance),
114 inframe, outframe);
115 }
116
117 #ifdef HAVE_GCC_ATTRIBUTES
118 __attribute__((unused))
119 #endif
tc_module_decode_audio(TCModule handle,aframe_list_t * inframe,aframe_list_t * outframe)120 static int tc_module_decode_audio(TCModule handle,
121 aframe_list_t *inframe,
122 aframe_list_t *outframe)
123 {
124 return handle->klass->decode_audio(&(handle->instance),
125 inframe, outframe);
126 }
127
128 #ifdef HAVE_GCC_ATTRIBUTES
129 __attribute__((unused))
130 #endif
tc_module_filter_video(TCModule handle,vframe_list_t * frame)131 static int tc_module_filter_video(TCModule handle,
132 vframe_list_t *frame)
133 {
134 return handle->klass->filter_video(&(handle->instance), frame);
135 }
136
137 #ifdef HAVE_GCC_ATTRIBUTES
138 __attribute__((unused))
139 #endif
tc_module_filter_audio(TCModule handle,aframe_list_t * frame)140 static int tc_module_filter_audio(TCModule handle,
141 aframe_list_t *frame)
142 {
143 return handle->klass->filter_audio(&(handle->instance), frame);
144 }
145
146 #ifdef HAVE_GCC_ATTRIBUTES
147 __attribute__((unused))
148 #endif
tc_module_multiplex(TCModule handle,vframe_list_t * vframe,aframe_list_t * aframe)149 static int tc_module_multiplex(TCModule handle,
150 vframe_list_t *vframe,
151 aframe_list_t *aframe)
152 {
153 return handle->klass->multiplex(&(handle->instance), vframe, aframe);
154 }
155
156 #ifdef HAVE_GCC_ATTRIBUTES
157 __attribute__((unused))
158 #endif
tc_module_demultiplex(TCModule handle,vframe_list_t * vframe,aframe_list_t * aframe)159 static int tc_module_demultiplex(TCModule handle,
160 vframe_list_t *vframe,
161 aframe_list_t *aframe)
162 {
163 return handle->klass->demultiplex(&(handle->instance), vframe, aframe);
164 }
165
166 #ifdef HAVE_GCC_ATTRIBUTES
167 __attribute__((unused))
168 #endif
tc_module_get_info(TCModule handle)169 static const TCModuleInfo *tc_module_get_info(TCModule handle)
170 {
171 return handle->klass->info;
172 }
173
174 #ifdef HAVE_GCC_ATTRIBUTES
175 __attribute__((unused))
176 #endif
tc_module_match(int codec,TCModule handle,TCModule other)177 static int tc_module_match(int codec,
178 TCModule handle, TCModule other)
179 {
180 return tc_module_info_match(codec,
181 handle->klass->info, other->klass->info);
182 }
183
184 #ifdef HAVE_GCC_ATTRIBUTES
185 __attribute__((unused))
186 #endif
tc_module_show_info(TCModule handle,int verbose)187 static void tc_module_show_info(TCModule handle, int verbose)
188 {
189 tc_module_info_log(handle->klass->info, verbose);
190 }
191
192 /* FIXME: that's just ugly. */
193 #ifdef HAVE_GCC_ATTRIBUTES
194 __attribute__((unused))
195 #endif
tc_module_pass_extradata(TCModule source,TCModule dest)196 static void tc_module_pass_extradata(TCModule source, TCModule dest)
197 {
198 if (source != NULL && dest != NULL) {
199 /* soft copy */
200 dest->instance.extradata = source->instance.extradata;
201 dest->instance.extradata_size = source->instance.extradata_size;
202 }
203 }
204
205
206 /* factory data type. */
207 typedef struct tcfactory_ *TCFactory;
208
209 /*************************************************************************
210 * factory methods *
211 *************************************************************************/
212
213 /*
214 * tc_new_module_factory:
215 * initialize a module factory. This function will acquire all
216 * needed resources and set all things appropriately to make the
217 * factory ready for create module instances, loading plugins on
218 * demand if needed.
219 *
220 * Parameters:
221 * modpath:
222 * module base directory. The factory will look for
223 * transcode plugins to load if needed starting from this
224 * directory.
225 * Note that this must be a single directory.
226 * verbose:
227 * verbosiness level of factory. Control the quantity
228 * of informative messates to print out.
229 * Should be one of TC_INFO, TC_DEBUG... value.
230 *
231 * Return Value:
232 * A valid TCFactory if initialization was done
233 * succesfully, NULL otherwise. In latter case, a informative
234 * message is sent through tc_log*().
235 *
236 * Side effects:
237 * uses tc_log*() internally.
238 *
239 * Preconditions:
240 * modpath NOT NULL; giving a NULL parameter will cause a
241 * graceful failure.
242 *
243 * Postconditions:
244 * factory initialized and ready to create TCModules.
245 */
246 TCFactory tc_new_module_factory(const char *modpath, int verbose);
247
248 /*
249 * tc_del_module_factory:
250 * finalize a module factory. Shutdowns the factory completely,
251 * cleaning up everything and unloading plugins.
252 * PLEASE NOTE: this function _CAN_ fail, notably if a plugin
253 * can't be unloaded cleanly (this usually happens because a plugin
254 * has still some live instances at finalization time).
255 * ALWAYS check the return value and take opportune countermeasures.
256 * At time of writing, a factory can't (and it's unlikely it will
257 * do) destroy all living instances automatically.
258 *
259 * Parameters:
260 * factory: factory handle to finalize.
261 *
262 * Return Value:
263 * 0 succesfull.
264 * -1 an error occurred (notified via tc_log*).
265 *
266 * Side effects:
267 * uses tc_log*() internally.
268 *
269 * Preconditions:
270 * given factory was already initialized. Trying to finalize a
271 * non-initialized factory causes undefined behaviour.
272 *
273 * Postconditions:
274 * all resources acquired by factory are released; no modules are
275 * loaded or avalaible, nor module instances are still floating around.
276 */
277 int tc_del_module_factory(TCFactory factory);
278
279 /*
280 * tc_new_module:
281 * using given factory, create a new module instance of the given type,
282 * belonging to given class, and initialize it with reasonnable
283 * defaults values.
284 * This function may load a plugin implicitely to fullfill the request,
285 * since plugins are loaded on demand of client code.
286 * The returned instance pointer must be released using
287 * tc_del_module (see below).
288 * The returned instance is ready to use with above tc_module_* macros,
289 * or in any way you like.
290 *
291 * PLEASE NOTE: this function automatically invokes module initialization
292 * method on given module. You should NOT do by yourself.
293 *
294 * Parameters:
295 * factory: use this factory instance to build the new module.
296 * modclass: class of module requested (filter, encoding,
297 * demultiplexing...).
298 * modname: name of module requested.
299 * media: media type for new module (TC_VIDEO, TC_AUDIO, TC_EXTRA)
300 *
301 * Return value:
302 * NULL: an error occurred, and notified via tc_log_*()
303 * valid handle to a new module instance otherwise.
304 *
305 * Side effects:
306 * uses tc_log*() internally.
307 * a plugin can be loaded (except for errors!) implicitely.
308 *
309 * Preconditions:
310 * given factory was already intialized.
311 *
312 * Postconditions:
313 * if succeeded, module ready to use by client code.
314 *
315 * Examples:
316 * if you want to load the "foobar" plugin, belonging to filter class,
317 * you should use a code like this:
318 *
319 * TCModule my_module = tc_new_module("filter", "foobar");
320 */
321 TCModule tc_new_module(TCFactory factory,
322 const char *modclass, const char *modname, int media);
323
324 /*
325 * tc_del_module:
326 * destroy a module instance using given factory, unloading corrispondent
327 * plugin from factory if needed.
328 * This function release the maximum amount of resources possible
329 * acquired by a given module; since some resources (originating plugin)
330 * are shared between all instances, there is possible that some call
331 * doesn't release all resources. Anyway, si guaranted that all resources
332 * are released when all instances are destroyed.
333 *
334 * PLEASE NOTE: this function automatically invokes module finalization
335 * method on given module. You should'nt do by yourself.
336 *
337 * Parameters:
338 * factory: a factory handle, the same one used to create the module
339 * module: module instance to destroy.
340 *
341 * Return Value:
342 * 0 succesfull
343 * -1 an error occurred (notified via tc_log*).
344 *
345 * Side effects:
346 * uses tc_log*() internally.
347 * a plugin could be unloaded implicitely.
348 *
349 * Preconditions:
350 * factory already initialized.
351 * ***GIVEN MODULE WAS CREATED USING GIVEN FACTORY***
352 * to violate this condition will case an undefined behaviour.
353 * At time of writing, factory *CANNOT* detect when this condition
354 * is violated. So be careful.
355 *
356 * given module instance was obtained using tc_new_module,
357 * applying this function to a module instances obtained in a
358 * different way causes undefined behaviour, most likely a memory
359 * corruption.
360 *
361 * Postconditions:
362 * resources belonging to instance are released (see above).
363 */
364 int tc_del_module(TCFactory factory, TCModule module);
365
366 /*
367 * tc_plugin_count:
368 * get the number of loaded plugins in a given factory.
369 * Used mainly for debug purposes.
370 *
371 * Parameters:
372 * factory: handle to factory to analyze.
373 *
374 * Return Value:
375 * the number of plugins loaded at the moment.
376 *
377 * Side effects:
378 * None
379 *
380 * Preconditions:
381 * Given factory was already initialized.
382 * To apply this function to an unitialized factory will cause
383 * an undefine dbehaviour
384 *
385 * Postconditions:
386 * None
387 */
388 int tc_plugin_count(const TCFactory factory);
389
390 /*
391 * tc_module_count:
392 * get the number of module created and still valid by a given
393 * factory. Used mainly for debug purposes.
394 *
395 * Parameters:
396 * factory: handle to factory to analyze.
397 *
398 * Return Value:
399 * the number of module created and not yet destroyed at the moment.
400 *
401 * Side effects:
402 * None
403 *
404 * Preconditions:
405 * Given factory was already initialized.
406 * To apply this function to an unitialized factory will cause
407 * an undefine dbehaviour
408 *
409 * Postconditions:
410 * None
411 */
412 int tc_instance_count(const TCFactory factory);
413
414 /*
415 * tc_compare_modules:
416 * compare two module (through it's handler) supposed to be the same
417 * type (class + name). Used mainly for debug purposes.
418 *
419 * This function *MUST* SCREW UP BADLY if internal checks
420 * are absoultely clean, so assert are used at this moment.
421 *
422 * Parameters:
423 * amod: handle to first module instance.
424 * bmod: handle to second module instance
425 *
426 * Return value:
427 * -1 totally different modules
428 * 0 same class (some shared data)
429 * +1 same module instance: the two handles point to same instance
430 *
431 * Side effects:
432 * client code can be abort()ed.
433 *
434 * Preconditions:
435 * both module handles must refer to valid modules.
436 *
437 * Postconditions:
438 * None
439 */
440 int tc_compare_modules(const TCModule amod, const TCModule bmod);
441
442 #endif /* TCMODULE_CORE_H */
443