xine-lib  1.2.9
post.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2000-2017 the xine project
3  *
4  * This file is part of xine, a free video player.
5  *
6  * xine is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * xine is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * post plugin definitions
21  */
22 
23 #ifndef XINE_POST_H
24 #define XINE_POST_H
25 
26 #include <pthread.h>
27 
28 #include <xine.h>
29 #include <xine/video_out.h>
30 #include <xine/audio_out.h>
31 #include <xine/xine_internal.h>
32 #include <xine/xineutils.h>
33 
34 #ifdef XINE_COMPILE
35 # include <xine/plugin_catalog.h>
36 #endif
37 
38 #define POST_PLUGIN_IFACE_VERSION 10
39 
40 
41 typedef struct post_class_s post_class_t;
43 typedef struct post_in_s post_in_t;
44 typedef struct post_out_s post_out_t;
45 
46 struct post_class_s {
47 
48  /*
49  * open a new instance of this plugin class
50  */
51  post_plugin_t* (*open_plugin) (post_class_t *this_gen, int inputs,
52  xine_audio_port_t **audio_target,
53  xine_video_port_t **video_target);
54 
58  const char *identifier;
59 
65  const char *description;
66 
70  const char *text_domain;
71 
72  /*
73  * free all class-related resources
74  */
75 
76  void (*dispose) (post_class_t *this_gen);
77 };
78 
79 #define default_post_class_dispose (void (*) (post_class_t *this_gen))free
80 
81 struct post_plugin_s {
82 
83  /* public part of the plugin */
85 
86  /*
87  * the connections announced by the plugin
88  * the plugin must fill these with xine_post_{in,out}_t on init
89  */
92 
93  /*
94  * close down, free all resources
95  */
96  void (*dispose) (post_plugin_t *this_gen);
97 
98  /* plugins don't have to init the stuff below */
99 
100  /*
101  * the running ticket
102  *
103  * the plugin must assure to check for ticket revocation in
104  * intervals of finite length; this means that you must release
105  * the ticket before any operation that might block;
106  * note that all port functions are safe in this respect
107  *
108  * the running ticket is assigned to you by the engine
109  */
111 
112  /* this is needed by the engine to decrement the reference counter
113  * on disposal of the plugin, but since this is useful, we expose it */
115 
116  /* used when the user requests a list of all inputs/outputs */
117  const char **input_ids;
118  const char **output_ids;
119 
126 #ifdef XINE_COMPILE
128 #else
129  void *node;
130 #endif
131 
132  /* has dispose been called */
134 };
135 
136 /* helper function to initialize a post_plugin_t */
137 void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED;
138 
139 struct post_in_s {
140 
141  /* public part of the input */
143 
144  /* backward reference so that you have access to the post plugin */
146 
147  /* you can fill this to your liking */
148  void *user_data;
149 };
150 
151 struct post_out_s {
152 
153  /* public part of the output */
155 
156  /* backward reference so that you have access to the post plugin */
158 
159  /* you can fill this to your liking */
160  void *user_data;
161 };
162 
163 
164 /* Post plugins work by intercepting calls to video or audio ports
165  * in the sense of the decorator design pattern. They reuse the
166  * functions of a given target port, but add own functionality in
167  * front of that port by creating a new port structure and filling in
168  * the function pointers with pointers to own functions that
169  * would do something and then call the original port function.
170  *
171  * Much the same is done with video frames which have their own
172  * set of functions attached that you might need to decorate.
173  */
174 
175 
176 /* helper structure for intercepting video port calls */
179 
180  /* the new public port with replaced function pointers */
182 
183  /* the original port to call its functions from inside yours */
185 
186  /* if you want to decide yourself, whether a given frame should
187  * be intercepted, fill in this function; get_frame() acts as
188  * a template method and asks your function; return a boolean;
189  * the default is to intercept all frames */
191 
192  /* the new frame function pointers */
194 
195  /* if you want to decide yourself, whether the preprocessing functions
196  * should still be routed when draw is intercepted, fill in this
197  * function; _x_post_intercept_video_frame() acts as a template method
198  * and asks your function; return a boolean; the default is _not_ to
199  * route preprocessing functions when draw is intercepted */
201 
202  /* if you want to decide yourself, whether the overlay manager should
203  * be intercepted, fill in this function; get_overlay_manager() acts as
204  * a template method and asks your function; return a boolean;
205  * the default is _not_ to intercept the overlay manager */
207 
208  /* the new public overlay manager with replaced function pointers */
210 
211  /* the original manager to call its functions from inside yours */
213 
214  /* usage counter: how many objects are floating around that need
215  * these pointers to exist */
217  pthread_mutex_t usage_lock;
218 
219  /* the stream we are being fed by; NULL means no stream is connected;
220  * this may be an anonymous stream */
222 
223  /* point to a mutex here, if you need some synchronization */
224  pthread_mutex_t *port_lock;
225  pthread_mutex_t *frame_lock;
226  pthread_mutex_t *manager_lock;
227 
228  /* backward reference so that you have access to the post plugin
229  * when the call only gives you the port */
231 
232  /* you can fill this to your liking */
233  void *user_data;
234 
235 #ifdef POST_INTERNAL
236  /* some of the above members are to be directly included here, but
237  * adding the structures would mean that post_video_port_t becomes
238  * depended of the sizes of these structs; solution: we add pointers
239  * above and have them point into the memory provided here;
240  * note that the overlay manager needs to be first so that we can
241  * reconstruct the post_video_port_t* from overlay manager calls */
242 
243  /* any change here requires a change in _x_post_ovl_manager_to_port()
244  * below! */
245 
246  video_overlay_manager_t manager_storage;
247  vo_frame_t frame_storage;
248 
249  /* this is used to keep a linked list of free vo_frame_t's */
250  vo_frame_t *free_frame_slots;
251  pthread_mutex_t free_frames_lock;
252 #endif
253 };
254 
255 /* use this to create a new decorated video port in which
256  * port functions will be replaced with own implementations;
257  * for convenience, this can also create a related post_in_t and post_out_t */
260 
261 /* use this to decorate and to undecorate a frame so that its functions
262  * can be replaced with own implementations, decoration is usually done in
263  * get_frame(), undecoration in frame->free() */
266 
267 /* when you want to pass a frame call on to the original issuer of the frame,
268  * you need to propagate potential changes up and down the pipe, so the usual
269  * procedure for this situation would be:
270  *
271  * _x_post_frame_copy_down(frame, frame->next);
272  * frame->next->function(frame->next);
273  * _x_post_frame_copy_up(frame, frame->next);
274  */
277 
278 /* when you shortcut a frames usual draw() travel so that it will never reach
279  * the draw() function of the original issuer, you still have to do some
280  * housekeeping on the frame, before returning control up the pipe */
282 
283 /* use this to create a new, trivially decorated overlay manager in which
284  * port functions can be replaced with own implementations */
286 
287 /* pointer retrieval functions */
289  return (post_video_port_t *)frame->port;
290 }
291 
293 #ifdef POST_INTERNAL
294  return (post_video_port_t *)( (uint8_t *)manager -
295  (uint8_t*)&(((post_video_port_t *)NULL)->manager_storage) );
296 #else
297  return (post_video_port_t *)( (uint8_t *)manager - sizeof(post_video_port_t) );
298 #endif
299 }
300 
301 
302 /* helper structure for intercepting audio port calls */
305 
306  /* the new public port with replaced function pointers */
308 
309  /* the original port to call its functions from inside yours */
311 
312  /* the stream we are being fed by; NULL means no stream is connected;
313  * this may be an anonymous stream */
315 
316  pthread_mutex_t usage_lock;
317  /* usage counter: how many objects are floating around that need
318  * these pointers to exist */
320 
321  /* some values remembered by (port->open) () */
322  uint32_t bits;
323  uint32_t rate;
324  uint32_t mode;
325 
326  /* point to a mutex here, if you need some synchronization */
327  pthread_mutex_t *port_lock;
328 
329  /* backward reference so that you have access to the post plugin
330  * when the call only gives you the port */
332 
333  /* you can fill this to your liking */
334  void *user_data;
335 };
336 
337 /* use this to create a new decorated audio port in which
338  * port functions will be replaced with own implementations */
341 
342 
343 /* this will allow pending rewire operations, calling this at the beginning
344  * of decoder-called functions like get_buffer() and open() is a good idea
345  * (if you do not intercept get_buffer() or open(), this will be done automatically) */
346 static inline void _x_post_rewire(post_plugin_t *post) {
347  if (post->running_ticket->ticket_revoked)
348  post->running_ticket->renew(post->running_ticket, 1);
349 }
350 
351 /* with these functions you can switch interruptions like rewiring or engine pausing
352  * off for a block of code; use this only when really necessary */
353 static inline void _x_post_lock(post_plugin_t *post) {
354  post->running_ticket->acquire(post->running_ticket, 1);
355 }
356 static inline void _x_post_unlock(post_plugin_t *post) {
357  post->running_ticket->release(post->running_ticket, 1);
358  _x_post_rewire(post);
359 }
360 
361 /* the standard disposal operation; returns 1 if the plugin is really
362  * disposed and you should free everything you malloc()ed yourself */
364 
365 
366 /* macros to handle usage counter */
367 
368 /* WARNING!
369  * note that _x_post_dec_usage() can call dispose, so be sure to
370  * not use any potentially already freed memory after this */
371 
372 #define _x_post_inc_usage(port) \
373 do { \
374  pthread_mutex_lock(&(port)->usage_lock); \
375  (port)->usage_count++; \
376  pthread_mutex_unlock(&(port)->usage_lock); \
377 } while(0)
378 
379 #define _x_post_dec_usage(port) \
380 do { \
381  pthread_mutex_lock(&(port)->usage_lock); \
382  (port)->usage_count--; \
383  if ((port)->usage_count == 0) { \
384  if ((port)->post->dispose_pending) { \
385  pthread_mutex_unlock(&(port)->usage_lock); \
386  (port)->post->dispose((port)->post); \
387  } else \
388  pthread_mutex_unlock(&(port)->usage_lock); \
389  } else \
390  pthread_mutex_unlock(&(port)->usage_lock); \
391 } while(0)
392 
393 
394 /* macros to create parameter descriptors */
395 
396 #define START_PARAM_DESCR( param_t ) \
397 typedef param_t temp_t; \
398 static param_t temp_s; \
399 static xine_post_api_parameter_t temp_p[] = {
400 
401 #ifndef offsetof
402 #include <stddef.h>
403 #endif
404 
405 #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \
406 { param_type, #var, sizeof(temp_s.var), \
407  offsetof(temp_t, var), enumv, min, max, readonly, descr },
408 
409 #define END_PARAM_DESCR( name ) \
410  { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \
411 }; \
412 static xine_post_api_descr_t name = { \
413  sizeof( temp_s ), \
414  temp_p \
415 };
416 
417 #endif
pthread_mutex_t * manager_lock
Definition: post.h:226
post_plugin_t * post
Definition: post.h:145
void * user_data
Definition: post.h:148
Definition: xine.h:711
vo_frame_t * _x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:598
post_plugin_t * post
Definition: post.h:157
post_audio_port_t * _x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *port, post_in_t **input, post_out_t **output)
Definition: post.c:922
xine_post_t xine_post
Definition: post.h:84
int(* intercept_ovl)(post_video_port_t *self)
Definition: post.h:206
Definition: post.h:46
Definition: xine_internal.h:125
void * user_data
Definition: post.h:233
int dispose_pending
Definition: post.h:133
NULL
Definition: xine_plugin.c:91
pthread_mutex_t * frame_lock
Definition: post.h:225
pthread_mutex_t usage_lock
Definition: post.h:316
plugin_node_t * node
Pointer to the loaded plugin node.
Definition: post.h:127
void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to)
Definition: post.c:602
Definition: xine.h:725
void(* renew)(xine_ticket_t *self, int irrevocable)
Definition: xine_internal.h:147
uint32_t rate
Definition: post.h:323
xine_post_in_t xine_in
Definition: post.h:142
const char ** output_ids
Definition: post.h:118
int _x_post_dispose(post_plugin_t *post)
Definition: post.c:973
pthread_mutex_t * port_lock
Definition: post.h:327
Definition: plugin_catalog.h:44
void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream)
Definition: post.c:653
xine_video_port_t * port
Definition: video_out.h:151
static post_video_port_t * _x_post_ovl_manager_to_port(video_overlay_manager_t *manager)
Definition: post.h:292
static post_video_port_t * _x_post_video_frame_to_port(vo_frame_t *frame)
Definition: post.h:288
vo_frame_t * _x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:594
xine_t * xine
Definition: post.h:114
post_video_port_t * _x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *port, post_in_t **input, post_out_t **output)
Definition: post.c:452
void(* release)(xine_ticket_t *self, int irrevocable)
Definition: xine_internal.h:141
void * user_data
Definition: post.h:334
void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs)
Definition: post.c:239
video_overlay_manager_t * original_manager
Definition: post.h:212
Definition: post.h:178
int usage_count
Definition: post.h:319
Definition: xine_internal.h:210
Definition: video_out.h:522
const char * text_domain
Optional non-standard catalog to use with dgettext() for description.
Definition: post.h:70
Definition: video_out.h:177
void(* dispose)(post_class_t *this_gen)
Definition: post.h:76
video_overlay_manager_t * new_manager
Definition: post.h:209
const char * identifier
short human readable identifier for this plugin class
Definition: post.h:58
xine_audio_port_t new_port
Definition: post.h:307
const char ** input_ids
Definition: post.h:117
static void _x_post_rewire(post_plugin_t *post)
Definition: post.h:346
Definition: list.c:51
Definition: video_out.h:60
static int input(void)
Definition: goomsl_lex.c:1495
xine_video_port_t new_port
Definition: post.h:181
xine_audio_port_t * original_port
Definition: post.h:310
int(* intercept_frame)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:190
xine_post_out_t xine_out
Definition: post.h:154
void * user_data
Definition: post.h:160
void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port)
Definition: post.c:746
Definition: post.h:139
#define XINE_PROTECTED
Definition: attributes.h:73
pthread_mutex_t * port_lock
Definition: post.h:224
void(* acquire)(xine_ticket_t *self, int irrevocable)
Definition: xine_internal.h:138
const char * description
human readable (verbose = 1 line) description for this plugin class
Definition: post.h:65
int ticket_revoked
Definition: xine_internal.h:133
xine_stream_t * stream
Definition: post.h:221
vo_frame_t * new_frame
Definition: post.h:193
post_plugin_t * post
Definition: post.h:331
Definition: xine_internal.h:81
Definition: xine.h:657
Definition: post.h:151
void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from)
Definition: post.c:633
xine_list_t * input
Definition: post.h:90
uint32_t bits
Definition: post.h:322
void(* dispose)(post_plugin_t *this_gen)
Definition: post.h:96
int(* route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:200
xine_stream_t * stream
Definition: post.h:314
static void _x_post_unlock(post_plugin_t *post)
Definition: post.h:356
xine_ticket_t * running_ticket
Definition: post.h:110
xine_video_port_t * original_port
Definition: post.h:184
Definition: post.h:304
int usage_count
Definition: post.h:216
pthread_mutex_t usage_lock
Definition: post.h:217
static void _x_post_lock(post_plugin_t *post)
Definition: post.h:353
post_plugin_t * post
Definition: post.h:230
uint32_t mode
Definition: post.h:324
Definition: audio_out.h:178
Definition: post.h:81
xine_list_t * output
Definition: post.h:91