1 /*
2  * tcmodule-data.h -- transcode module system, take two: data types.
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  * this header file contains basic data types declarations for transcode's
24  * new module system (1.1.x and later).
25  * Should not be included directly, but doing this will not harm anything.
26  */
27 #ifndef TCMODULE_DATA_H
28 #define TCMODULE_DATA_H
29 
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33 
34 #include <stdint.h>
35 #include <stdlib.h>
36 
37 #include "framebuffer.h"
38 #include "transcode.h"
39 #include "tcmodule-info.h"
40 
41 #define TC_MODULE_VERSION_MAJOR     2
42 #define TC_MODULE_VERSION_MINOR     0
43 #define TC_MODULE_VERSION_MICRO     0
44 
45 #define TC_MAKE_MOD_VERSION(MAJOR, MINOR, MICRO) \
46          (((    0UL & 0xFF) << 24) \
47          |(((MAJOR) & 0xFF) << 16) \
48          |(((MINOR) & 0xFF) <<  8) \
49          | ((MICRO) & 0xFF))
50 
51 #define TC_MODULE_VERSION   \
52         TC_MAKE_MOD_VERSION(TC_MODULE_VERSION_MAJOR, \
53                             TC_MODULE_VERSION_MINOR, \
54                             TC_MODULE_VERSION_MICRO)
55 
56 /*
57  * allowed status transition chart:
58  *
59  *                     init                 configure
60  *  +--------------+ -----> +-----------+ ------------> +--------------+
61  *  | module limbo |        | [created] |               | [configured] |
62  *  +--------------+ <----- +-----------+ <-----------  +--------------+
63  *                    fini  A                stop       |
64  *                          |                           |
65  *                          |                           |
66  *                          |   any specific operation: |
67  *                          |       encode_*, filter_*, |
68  *                          |            multiplex, ... |
69  *                          |                           V
70  *                          `-------------- +-----------+
71  *                                 stop     | [running] |
72  *                                          +-----------+
73  *
74  */
75 
76 /*
77  * Data structure private for each instance.
78  * This is an almost-opaque structure.
79  *
80  * The main purpose of this structure is to let each module (class)
81  * to have it's private data, totally opaque to loader and to the
82  * client code.
83  * This structure also keep some accounting informations useful
84  * both for module code and for loader. Those informations are
85  * a module id, which identifies uniquely a given module instance
86  * in a given timespan, and a string representing the module 'type',
87  * a composition of it's class and specific name.
88  */
89 typedef struct tcmoduleinstance_ TCModuleInstance;
90 struct tcmoduleinstance_ {
91     int id; /* instance id; */
92     const char *type; /* packed class + name of module */
93     uint32_t features; /* subset of enabled features for this instance */
94 
95     void *userdata; /* opaque to factory, used by each module */
96 
97     void *extradata;
98     size_t extradata_size;
99     /*
100      * extradata:
101      * opaque data needed by a module that should'nt be private.
102      * Used mainly into encoder->multiplexor communication.
103      * NOTE:
104      * I'don't see a better way to handle extradata (see encode_ffmpeg
105      * module) in current architecture. I don't want to stack modules
106      * (if encoder drives multiplexor can handle itself the extradata)
107      * nor add more operations and/or accessors. This way looks as the
108      * cleanest and cheapest to me. Suggestions welcome. -- FRomani.
109      */
110     // FIXME: add status to enforce correct operation sequence?
111 };
112 
113 /* can be shared between _all_ instances */
114 typedef struct tcmoduleclass_ TCModuleClass;
115 struct tcmoduleclass_ {
116     uint32_t version;
117 
118     int id; /* opaque internal handle */
119 
120     const TCModuleInfo *info;
121 
122     /* mandatory operations: */
123     int (*init)(TCModuleInstance *self, uint32_t features);
124     int (*fini)(TCModuleInstance *self);
125     int (*configure)(TCModuleInstance *self, const char *options, vob_t *vob);
126     int (*stop)(TCModuleInstance *self);
127     int (*inspect)(TCModuleInstance *self, const char *param, const char **value);
128 
129     /*
130      * not-mandatory operations, a module doing something useful implements
131      * at least one of following.
132      */
133     int (*encode_audio)(TCModuleInstance *self,
134                         aframe_list_t *inframe, aframe_list_t *outframe);
135     int (*encode_video)(TCModuleInstance *self,
136                         vframe_list_t *inframe, vframe_list_t *outframe);
137     int (*decode_audio)(TCModuleInstance *self,
138                         aframe_list_t *inframe, aframe_list_t *outframe);
139     int (*decode_video)(TCModuleInstance *self,
140                         vframe_list_t *inframe, vframe_list_t *outframe);
141     int (*filter_audio)(TCModuleInstance *self, aframe_list_t *frame);
142     int (*filter_video)(TCModuleInstance *self, vframe_list_t *frame);
143     int (*multiplex)(TCModuleInstance *self,
144                      vframe_list_t *vframe, aframe_list_t *aframe);
145     int (*demultiplex)(TCModuleInstance *self,
146                        vframe_list_t *vframe, aframe_list_t *aframe);
147 };
148 
149 /**************************************************************************
150  * TCModuleClass operations documentation:                                *
151  **************************************************************************
152  *
153  * init:
154  *      initialize a module, acquiring all needed resources.
155  *      A module must also be configure()d before to be used.
156  *      An initialized, but unconfigured, module CAN'T DELIVER
157  *      a proper result when a specific operation (encode, demultiplex)
158  *      is requested. Request an operation in a initialized but unconfigured
159  *      module will result in an undefined behaviour.
160  * Parameters:
161  *          self: pointer to module instance to initialize.
162  *      features: select feature of this module to initialize.
163  * Return Value:
164  *      0  succesfull.
165  *      -1 error occurred. A proper message should be sent to user using
166  *         tc_log*()
167  * Postconditions:
168  *      Given module is ready to be configured.
169  *
170  *
171  * fini:
172  *      finalize an initialized module, releasing all acquired resources.
173  *      A finalized module MUST be re-initialized before any new usage.
174  * Parameters:
175  *      self: pointer to module instance to finalize.
176  * Return Value:
177  *      0  succesfull.
178  *      -1 error occurred. A proper message should be sent to user using
179  *         tc_log*()
180  * Preconditions:
181  *      module was already initialized. To finalize a uninitialized module
182  *      will cause an undefined behaviour.
183  *      An unconfigured module can be finalized safely.
184  * Postconditions:
185  *      all resources acquired by given module are released.
186  *
187  *
188  * configure:
189  *      setup a module using module specific options and required data
190  *      (via `vob' structure). It is requested to configure a module
191  *      before to be used safely to perform any specific operation.
192  *      Trying to configure a non-initialized module will cause an
193  *      undefined behaviour.
194  * Parameters:
195  *      self: pointer to module instance to configure.
196  *      options: string contaning module options.
197  *               Syntax is fixed (see optstr),
198  *               semantic is module-dependent.
199  *      vob: pointer to vob structure.
200  * Return Value:
201  *      0  succesfull.
202  *      -1 error occurred. A proper message should be sent to user using
203  *         tc_log*()
204  * Preconditions:
205  *      Given module was already initialized AND stopped.
206  *      A module MUST be stop()ped before to be configured again, otherwise
207  *      an undefined behaviour will occur (expect at least resource leaks).
208  * Postconditions:
209  *      Given module is ready to perform any supported operation.
210  *
211  *
212  * stop:
213  *      reset a module and prepare for reconfiguration or finalization.
214  *      This means to flush buffers, close open files and so on,
215  *      but NOT release the reseource needed by a module to work.
216  *      Please note that this operation can do actions similar, but
217  *      not equal, to `fini'. Also note that `stop' can be invoked
218  *      zero or multiple times during the module lifetime, but
219  *      `fini' WILL be invkoed one and only one time.
220  * Parameters:
221  *      self: pointer to module instance to stop.
222  * Return Value:
223  *      0  succesfull.
224  *      -1 error occurred. A proper message should be sent to user using
225  *         tc_log*()
226  * Preconditions:
227  *      Given module was already initialized. Try to (re)stop
228  *      an unitialized module will cause an undefined behaviour.
229  *      It's safe to stop an unconfigured module.
230  * Postconditions:
231  *      Given module is ready to be reconfigured safely.
232  *
233  *
234  * inspect:
235  *      expose the current value of an a tunable option in a module,
236  *      represented as a string.
237  *      Every module MUST support two special options:
238  *      'all': will return a packed, human-readable representation
239  *             of ALL tunable parameters in a given module, or an
240  *             empty string if module hasn't any tunable option.
241  *             This string must be in the same form accepted by
242  *             `configure' operation.
243  *      'help': will return a formatted, human-readable string
244  *              with module overview, tunable options and explanation.
245  * Parameters:
246  *      self: pointer to module instance to inspect.
247  *      param: name of parameter to inspect
248  *      value: when method succesfully returns, will point to a constant
249  *             string (that MUST NOT be *free()d by calling code)
250  *             containing the actual value of requested parameter.
251  *             PLEASE NOTE that this value CAN change between
252  *             invocations of this method.
253  * Return value:
254  *      0  succesfull. That means BOTH the request was honoured OR
255  *         the requested parameter isn't known and was silently ignored.
256  *      -1 INTERNAL error, reason will be tc_log*()'d out.
257  * Preconditions:
258  *      module was already initialized.
259  *      Inspecting a uninitialized module will cause an
260  *      undefined behaviour.
261  *
262  *
263  * decode_{audio,video}:
264  * encode_{audio,video}:
265  *      decode or encode a given audio/video frame, storing
266  *      (de)compressed data into another frame.
267  *      Specific module loaded implements various codecs.
268  * Parameters:
269  *      self: pointer to module instance to use.
270  *      inframe: pointer to {audio,video} frame data to decode/encode.
271  *      outframe: pointer to {audio,videp} frame which will hold
272  *                (un)compressed data. Must be != NULL
273  * Return Value:
274  *      0  succesfull.
275  *      -1 error occurred. A proper message should be sent to user using
276  *         tc_log*()
277  * Preconditions:
278  *      module was already initialized AND configured.
279  *      To use a uninitialized and/or unconfigured module
280  *      for decoding/encoding will cause an undefined behaviour.
281  *      outframe != NULL.
282  *
283  * SPECIAL NOTE FOR encode_audio operation:
284  * if a NULL input frame pointer is given, but a VALID (not NULL)
285  * output frame pointer is given as well, a flush operation will performed.
286  * This means that encoder will emit all buffered audio data, in order
287  * to complete an audio frame and avoid data truncation/loss in output.
288  *
289  *
290  * filter_{audio,video}:
291  *      apply an in-place transformation to a given audio/video frame.
292  *      Specific module loaded determines the action performend on
293  *      given frame.
294  * Parameters:
295  *      self: pointer to module instance to use.
296  *      frame: pointer to {audio,video} frame data to elaborate.
297  * Return Value:
298  *      0  succesfull.
299  *      -1 error occurred. A proper message should be sent to user using
300  *         tc_log*()
301  * Preconditions:
302  *      module was already initialized AND configured.
303  *      To use a uninitialized and/or unconfigured module
304  *      for filter will cause an undefined behaviour.
305  *
306  *
307  * multiplex:
308  *      merge given encoded frames in output stream.
309  * Parameters:
310  *      self: pointer to module instance to use.
311  *      vframe: pointer to video frame to multiplex.
312  *              if NULL, don't multiplex video for this invokation.
313  *      aframe: pointer to audio frame to multiplex
314  *              if NULL, don't multiplex audio for this invokation.
315  * Return value:
316  *      -1 error occurred. A proper message should be sent to user using
317  *         tc_log*().
318  *      >0 number of bytes writed for multiplexed frame(s). Can be
319  *         (and usually is) different from the plain sum of sizes of
320  *         encoded frames.
321  * Preconditions:
322  *      module was already initialized AND configured.
323  *      To use a uninitialized and/or unconfigured module
324  *      for multiplex will cause an undefined behaviour.
325  *
326  *
327  * demultiplex:
328  *      extract given encoded frames from input stream.
329  * Parameters:
330  *      self: pointer to module instance to use.
331  *      vframe: if not NULL, extract next video frame from input stream
332  *              and store it here.
333  *      aframe: if not NULL, extract next audio frame from input strema
334  *              and store it here.
335  * Return value:
336  *      -1 error occurred. A proper message should be sent to user using
337  *         tc_log*().
338  *      >0 number of bytes readed for demultiplexed frame(s). Can be
339  *         (and usually is) different from the plain sum of sizes of
340  *         encoded frames.
341  * Preconditions:
342  *      module was already initialized AND configured.
343  *      To use a uninitialized and/or unconfigured module
344  *      for demultiplex will cause an undefined behaviour.
345  *
346  */
347 
348 #endif /* TCMODULE_DATA_H */
349