xine-lib  1.2.10
post.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2000-2018 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/attributes.h>
30 #include <xine/video_out.h>
31 #include <xine/audio_out.h>
32 #include <xine/xine_internal.h>
33 #include <xine/xineutils.h>
34 
35 struct plugin_node_s;
36 
37 #define POST_PLUGIN_IFACE_VERSION 10
38 
39 
40 typedef struct post_class_s post_class_t;
42 typedef struct post_in_s post_in_t;
43 typedef struct post_out_s post_out_t;
44 
45 struct post_class_s {
46 
47  /*
48  * open a new instance of this plugin class
49  */
50  post_plugin_t* (*open_plugin) (post_class_t *this_gen, int inputs,
51  xine_audio_port_t **audio_target,
52  xine_video_port_t **video_target);
53 
57  const char *identifier;
58 
64  const char *description;
65 
69  const char *text_domain;
70 
71  /*
72  * free all class-related resources
73  */
74 
75  void (*dispose) (post_class_t *this_gen);
76 };
77 
78 #define default_post_class_dispose (void (*) (post_class_t *this_gen))free
79 
80 struct post_plugin_s {
81 
82  /* public part of the plugin */
84 
85  /*
86  * the connections announced by the plugin
87  * the plugin must fill these with xine_post_{in,out}_t on init
88  */
91 
92  /*
93  * close down, free all resources
94  */
95  void (*dispose) (post_plugin_t *this_gen);
96 
97  /* plugins don't have to init the stuff below */
98 
99  /*
100  * the running ticket
101  *
102  * the plugin must assure to check for ticket revocation in
103  * intervals of finite length; this means that you must release
104  * the ticket before any operation that might block;
105  * note that all port functions are safe in this respect
106  *
107  * the running ticket is assigned to you by the engine
108  */
110 
111  /* this is needed by the engine to decrement the reference counter
112  * on disposal of the plugin, but since this is useful, we expose it */
114 
115  /* used when the user requests a list of all inputs/outputs */
116  const char **input_ids;
117  const char **output_ids;
118 
126 
127  /* has dispose been called */
129 };
130 
131 /* helper function to initialize a post_plugin_t */
132 void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED;
133 
134 struct post_in_s {
135 
136  /* public part of the input */
138 
139  /* backward reference so that you have access to the post plugin */
141 
142  /* you can fill this to your liking */
143  void *user_data;
144 };
145 
146 struct post_out_s {
147 
148  /* public part of the output */
150 
151  /* backward reference so that you have access to the post plugin */
153 
154  /* you can fill this to your liking */
155  void *user_data;
156 };
157 
158 
159 /* Post plugins work by intercepting calls to video or audio ports
160  * in the sense of the decorator design pattern. They reuse the
161  * functions of a given target port, but add own functionality in
162  * front of that port by creating a new port structure and filling in
163  * the function pointers with pointers to own functions that
164  * would do something and then call the original port function.
165  *
166  * Much the same is done with video frames which have their own
167  * set of functions attached that you might need to decorate.
168  */
169 
170 
171 /* helper structure for intercepting video port calls */
174 
175  /* the new public port with replaced function pointers */
177 
178  /* the original port to call its functions from inside yours */
180 
181  /* if you want to decide yourself, whether a given frame should
182  * be intercepted, fill in this function; get_frame() acts as
183  * a template method and asks your function; return a boolean;
184  * the default is to intercept all frames */
186 
187  /* the new frame function pointers */
189 
190  /* if you want to decide yourself, whether the preprocessing functions
191  * should still be routed when draw is intercepted, fill in this
192  * function; _x_post_intercept_video_frame() acts as a template method
193  * and asks your function; return a boolean; the default is _not_ to
194  * route preprocessing functions when draw is intercepted */
196 
197  /* if you want to decide yourself, whether the overlay manager should
198  * be intercepted, fill in this function; get_overlay_manager() acts as
199  * a template method and asks your function; return a boolean;
200  * the default is _not_ to intercept the overlay manager */
202 
203  /* the new public overlay manager with replaced function pointers */
205 
206  /* the original manager to call its functions from inside yours */
208 
209  /* usage counter: how many objects are floating around that need
210  * these pointers to exist */
212  pthread_mutex_t usage_lock;
213 
214  /* the stream we are being fed by; NULL means no stream is connected;
215  * this may be an anonymous stream */
217 
218  /* point to a mutex here, if you need some synchronization */
219  pthread_mutex_t *port_lock;
220  pthread_mutex_t *frame_lock;
221  pthread_mutex_t *manager_lock;
222 
223  /* backward reference so that you have access to the post plugin
224  * when the call only gives you the port */
226 
227  /* you can fill this to your liking */
228  void *user_data;
229 
230 #ifdef POST_INTERNAL
231  /* some of the above members are to be directly included here, but
232  * adding the structures would mean that post_video_port_t becomes
233  * depended of the sizes of these structs; solution: we add pointers
234  * above and have them point into the memory provided here;
235  * note that the overlay manager needs to be first so that we can
236  * reconstruct the post_video_port_t* from overlay manager calls */
237 
238  /* any change here requires a change in _x_post_ovl_manager_to_port()
239  * below! */
240 
241  video_overlay_manager_t manager_storage;
242  vo_frame_t frame_storage;
243 
244  /* this is used to keep a linked list of free vo_frame_t's */
245  vo_frame_t *free_frame_slots;
246  pthread_mutex_t free_frames_lock;
247 #endif
248 };
249 
250 /* use this to create a new decorated video port in which
251  * port functions will be replaced with own implementations;
252  * for convenience, this can also create a related post_in_t and post_out_t */
255 
256 /* use this to decorate and to undecorate a frame so that its functions
257  * can be replaced with own implementations, decoration is usually done in
258  * get_frame(), undecoration in frame->free() */
261 
262 /* when you want to pass a frame call on to the original issuer of the frame,
263  * you need to propagate potential changes up and down the pipe, so the usual
264  * procedure for this situation would be:
265  *
266  * _x_post_frame_copy_down(frame, frame->next);
267  * frame->next->function(frame->next);
268  * _x_post_frame_copy_up(frame, frame->next);
269  */
272 
273 /* when you shortcut a frames usual draw() travel so that it will never reach
274  * the draw() function of the original issuer, you still have to do some
275  * housekeeping on the frame, before returning control up the pipe */
277 
278 /* use this to create a new, trivially decorated overlay manager in which
279  * port functions can be replaced with own implementations */
281 
282 /* pointer retrieval functions */
284  return (post_video_port_t *)frame->port;
285 }
286 
288 #ifdef POST_INTERNAL
289  return (post_video_port_t *)( (uint8_t *)manager -
290  (uint8_t*)&(((post_video_port_t *)NULL)->manager_storage) );
291 #else
292  return (post_video_port_t *)( (uint8_t *)manager - sizeof(post_video_port_t) );
293 #endif
294 }
295 
296 
297 /* helper structure for intercepting audio port calls */
300 
301  /* the new public port with replaced function pointers */
303 
304  /* the original port to call its functions from inside yours */
306 
307  /* the stream we are being fed by; NULL means no stream is connected;
308  * this may be an anonymous stream */
310 
311  pthread_mutex_t usage_lock;
312  /* usage counter: how many objects are floating around that need
313  * these pointers to exist */
315 
316  /* some values remembered by (port->open) () */
317  uint32_t bits;
318  uint32_t rate;
319  uint32_t mode;
320 
321  /* point to a mutex here, if you need some synchronization */
322  pthread_mutex_t *port_lock;
323 
324  /* backward reference so that you have access to the post plugin
325  * when the call only gives you the port */
327 
328  /* you can fill this to your liking */
329  void *user_data;
330 };
331 
332 /* use this to create a new decorated audio port in which
333  * port functions will be replaced with own implementations */
336 
337 
338 /* If you do intercept these decoder-called functions
339  * (that is, you do not use post defaults), please
340  * open ():
341  * _x_post_inc_usage (port);
342  * _x_post_rewire (port->post);
343  * ...
344  * close ():
345  * ...
346  * _x_post_dec_usage (port);
347  * get_buffer ():
348  * _x_post_inc_usage (port);
349  * ...
350  * port->original_port->get_buffer (port->original_port); and/or
351  * while (not_done_yet) {
352  * _x_post_rewire (port->post);
353  * timed_wait (done);
354  * }
355  * ...
356  * _x_post_dec_usage (port);
357  * get_frame ():
358  * _x_post_inc_usage (port);
359  * ...
360  * port->original_port->get_frame (port->original_port, ...); and/or
361  * while (not_done_yet) {
362  * _x_post_rewire (port->post);
363  * timed_wait (done);
364  * }
365  * ...
366  * if (this_frame_is_not_intercepted)
367  * _x_post_dec_usage (port);
368  * frame.free ():
369  * ...
370  * _x_post_dec_usage (port);
371  * this will allow pending rewire operations, while preventing your port from getting
372  * pulled from under your feet by the possible rewire. */
373 static inline void _x_post_rewire(post_plugin_t *post) {
374  if (post->running_ticket->ticket_revoked)
375  post->running_ticket->renew(post->running_ticket, 1);
376 }
377 
378 /* with these functions you can switch interruptions like rewiring or engine pausing
379  * off for a block of code; use this only when really necessary */
380 static inline void _x_post_lock(post_plugin_t *post) {
381  post->running_ticket->acquire(post->running_ticket, 1);
382 }
383 static inline void _x_post_unlock(post_plugin_t *post) {
384  post->running_ticket->release(post->running_ticket, 1);
385  _x_post_rewire(post);
386 }
387 
388 /* the standard disposal operation; returns 1 if the plugin is really
389  * disposed and you should free everything you malloc()ed yourself */
391 
392 
393 /* macros to handle usage counter */
394 
395 /* WARNING!
396  * note that _x_post_dec_usage() can call dispose, so be sure to
397  * not use any potentially already freed memory after this */
398 
399 #define _x_post_inc_usage(port) \
400 do { \
401  pthread_mutex_lock(&(port)->usage_lock); \
402  (port)->usage_count++; \
403  pthread_mutex_unlock(&(port)->usage_lock); \
404 } while(0)
405 
406 #define _x_post_dec_usage(port) \
407 do { \
408  pthread_mutex_lock(&(port)->usage_lock); \
409  (port)->usage_count--; \
410  if ((port)->usage_count == 0) { \
411  if ((port)->post->dispose_pending) { \
412  pthread_mutex_unlock(&(port)->usage_lock); \
413  (port)->post->dispose((port)->post); \
414  } else \
415  pthread_mutex_unlock(&(port)->usage_lock); \
416  } else \
417  pthread_mutex_unlock(&(port)->usage_lock); \
418 } while(0)
419 
420 #ifdef POST_INTERNAL
421 /* try to recognize post ports, do the above, return new use count.
422  * otherwise, return -1. */
427 #endif
428 
429 /* macros to create parameter descriptors */
430 
431 #define START_PARAM_DESCR( param_t ) \
432 typedef param_t temp_t; \
433 static xine_post_api_parameter_t temp_p[] = {
434 
435 #ifndef offsetof
436 #include <stddef.h>
437 #endif
438 
439 #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \
440 { param_type, #var, sizeof(((temp_t*)0)->var), \
441  offsetof(temp_t, var), enumv, min, max, readonly, descr },
442 
443 #define END_PARAM_DESCR( name ) \
444  { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \
445 }; \
446 static xine_post_api_descr_t name = { \
447  sizeof( temp_t ), \
448  temp_p \
449 };
450 
451 #endif
xine_s
Definition: xine_internal.h:80
_x_post_audio_port_unref
int _x_post_audio_port_unref(xine_audio_port_t *port_gen)
Definition: post.c:287
post_video_port_s::intercept_frame
int(* intercept_frame)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:185
_x_post_dispose
int _x_post_dispose(post_plugin_t *post)
Definition: post.c:1044
post_video_port_s::stream
xine_stream_t * stream
Definition: post.h:216
post_in_s
Definition: post.h:134
_x_post_frame_u_turn
void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream)
Definition: post.c:719
xine_stream_s
Definition: xine_internal.h:123
post_plugin_s::xine
xine_t * xine
Definition: post.h:113
xine_ticket_s::acquire
void(* acquire)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:66
post_plugin_s::xine_post
xine_post_t xine_post
Definition: post.h:83
xineutils.h
post_in_s::xine_in
xine_post_in_t xine_in
Definition: post.h:137
post_video_port_s::new_port
xine_video_port_t new_port
Definition: post.h:176
post_plugin_s::dispose
void(* dispose)(post_plugin_t *this_gen)
Definition: post.h:95
xine_ticket_s
Definition: tickets.h:53
post_audio_port_s::new_port
xine_audio_port_t new_port
Definition: post.h:302
post_plugin_s::dispose_pending
int dispose_pending
Definition: post.h:128
post_class_s::text_domain
const char * text_domain
Optional non-standard catalog to use with dgettext() for description.
Definition: post.h:69
post_video_port_s::original_port
xine_video_port_t * original_port
Definition: post.h:179
post_class_s::description
const char * description
human readable (verbose = 1 line) description for this plugin class
Definition: post.h:64
post_video_port_s
Definition: post.h:173
post_plugin_s::output
xine_list_t * output
Definition: post.h:90
post_video_port_s::original_manager
video_overlay_manager_t * original_manager
Definition: post.h:207
xine_video_port_s
Definition: video_out.h:176
post_video_port_s::manager_lock
pthread_mutex_t * manager_lock
Definition: post.h:221
post_class_s
Definition: post.h:45
post_video_port_s::frame_lock
pthread_mutex_t * frame_lock
Definition: post.h:220
_x_post_unlock
static void _x_post_unlock(post_plugin_t *post)
Definition: post.h:383
audio_out.h
post_audio_port_s::stream
xine_stream_t * stream
Definition: post.h:309
post_video_port_s::new_frame
vo_frame_t * new_frame
Definition: post.h:188
attributes.h
video_out.h
post_audio_port_s::original_port
xine_audio_port_t * original_port
Definition: post.h:305
post_audio_port_s::port_lock
pthread_mutex_t * port_lock
Definition: post.h:322
_x_post_frame_copy_up
void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from)
Definition: post.c:695
xine_post_out_s
Definition: xine.h:735
NULL
NULL
Definition: xine_plugin.c:78
post_video_port_s::intercept_ovl
int(* intercept_ovl)(post_video_port_t *self)
Definition: post.h:201
_x_post_video_port_ref
int _x_post_video_port_ref(xine_video_port_t *port_gen)
Definition: post.c:211
post_out_s
Definition: post.h:146
_x_post_frame_copy_down
void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to)
Definition: post.c:660
post_class_s::dispose
void(* dispose)(post_class_t *this_gen)
Definition: post.h:75
post_video_port_s::port_lock
pthread_mutex_t * port_lock
Definition: post.h:219
_x_post_video_frame_to_port
static post_video_port_t * _x_post_video_frame_to_port(vo_frame_t *frame)
Definition: post.h:283
post_class_s::identifier
const char * identifier
short human readable identifier for this plugin class
Definition: post.h:57
post_plugin_s::running_ticket
xine_ticket_t * running_ticket
Definition: post.h:109
xine_list_s
Definition: list.c:51
post_video_port_s::usage_lock
pthread_mutex_t usage_lock
Definition: post.h:212
post_audio_port_s::rate
uint32_t rate
Definition: post.h:318
post_in_s::user_data
void * user_data
Definition: post.h:143
post_video_port_s::route_preprocessing_procs
int(* route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:195
post_plugin_s::output_ids
const char ** output_ids
Definition: post.h:117
post_plugin_s::XINE_PRIVATE_FIELD
struct plugin_node_s *node XINE_PRIVATE_FIELD
Pointer to the loaded plugin node.
Definition: post.h:125
_x_post_ovl_manager_to_port
static post_video_port_t * _x_post_ovl_manager_to_port(video_overlay_manager_t *manager)
Definition: post.h:287
_x_post_lock
static void _x_post_lock(post_plugin_t *post)
Definition: post.h:380
post_video_port_s::post
post_plugin_t * post
Definition: post.h:225
post_out_s::xine_out
xine_post_out_t xine_out
Definition: post.h:149
post_plugin_s::input_ids
const char ** input_ids
Definition: post.h:116
post_audio_port_s
Definition: post.h:299
_x_post_audio_port_ref
int _x_post_audio_port_ref(xine_audio_port_t *port_gen)
Definition: post.c:262
post_in_s::post
post_plugin_t * post
Definition: post.h:140
video_overlay_manager_s
Definition: video_out.h:518
vo_frame_s::port
xine_video_port_t * port
Definition: video_out.h:150
post_audio_port_s::mode
uint32_t mode
Definition: post.h:319
xine_audio_port_s
Definition: audio_out.h:172
_x_post_intercept_video_port
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:509
_x_post_restore_video_frame
vo_frame_t * _x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:656
_x_post_init
void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs)
Definition: post.c:292
post_plugin_s::input
xine_list_t * input
Definition: post.h:89
_x_post_intercept_video_frame
vo_frame_t * _x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:651
xine_internal.h
xine_ticket_s::renew
void(* renew)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:75
_x_post_video_port_unref
int _x_post_video_port_unref(xine_video_port_t *port_gen)
Definition: post.c:236
_x_post_intercept_audio_port
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:993
xine_post_s
Definition: xine.h:667
XINE_PROTECTED
#define XINE_PROTECTED
Definition: attributes.h:73
plugin_node_s
Definition: plugin_catalog.h:44
vo_frame_s
Definition: video_out.h:59
xine_post_in_s
Definition: xine.h:721
post_plugin_s
Definition: post.h:80
xine_ticket_s::ticket_revoked
int ticket_revoked
Definition: tickets.h:61
post_audio_port_s::post
post_plugin_t * post
Definition: post.h:326
post_audio_port_s::user_data
void * user_data
Definition: post.h:329
xine_ticket_s::release
void(* release)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:69
post_audio_port_s::usage_count
int usage_count
Definition: post.h:314
post_audio_port_s::bits
uint32_t bits
Definition: post.h:317
input
static int input(void)
Definition: goomsl_lex.c:1495
post_audio_port_s::usage_lock
pthread_mutex_t usage_lock
Definition: post.h:311
_x_post_intercept_overlay_manager
void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port)
Definition: post.c:817
post_out_s::user_data
void * user_data
Definition: post.h:155
post_video_port_s::user_data
void * user_data
Definition: post.h:228
post_out_s::post
post_plugin_t * post
Definition: post.h:152
xine.h
post_video_port_s::new_manager
video_overlay_manager_t * new_manager
Definition: post.h:204
post_video_port_s::usage_count
int usage_count
Definition: post.h:211
_x_post_rewire
static void _x_post_rewire(post_plugin_t *post)
Definition: post.h:373