xine-lib 1.2.11
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
35struct plugin_node_s;
36
37#define POST_PLUGIN_IFACE_VERSION 10
38
39
42typedef struct post_in_s post_in_t;
43typedef struct post_out_s post_out_t;
44
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
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 */
132void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED;
133
134struct 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 */
144};
145
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 */
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 */
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 */
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. */
373static inline void _x_post_rewire(post_plugin_t *post) {
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 */
380static inline void _x_post_lock(post_plugin_t *post) {
381 post->running_ticket->acquire(post->running_ticket, 1);
382}
383static 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) \
400do { \
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) \
407do { \
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 ) \
432typedef param_t temp_t; \
433static 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}; \
446static xine_post_api_descr_t name = { \
447 sizeof( temp_t ), \
448 temp_p \
449};
450
451#endif
static int input(void)
Definition: goomsl_lex.c:1495
#define XINE_PROTECTED
Definition: attributes.h:75
int _x_post_video_port_ref(xine_video_port_t *port_gen)
Definition: post.c:211
int _x_post_audio_port_ref(xine_audio_port_t *port_gen)
Definition: post.c:262
int _x_post_audio_port_unref(xine_audio_port_t *port_gen)
Definition: post.c:287
int _x_post_video_port_unref(xine_video_port_t *port_gen)
Definition: post.c:236
void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream)
Definition: post.c:719
static void _x_post_rewire(post_plugin_t *post)
Definition: post.h:373
int _x_post_dispose(post_plugin_t *post)
Definition: post.c:1044
void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from)
Definition: post.c:695
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
void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to)
Definition: post.c:660
static post_video_port_t * _x_post_ovl_manager_to_port(video_overlay_manager_t *manager)
Definition: post.h:287
void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port)
Definition: post.c:817
static void _x_post_lock(post_plugin_t *post)
Definition: post.h:380
static void _x_post_unlock(post_plugin_t *post)
Definition: post.h:383
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
static post_video_port_t * _x_post_video_frame_to_port(vo_frame_t *frame)
Definition: post.h:283
vo_frame_t * _x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:656
vo_frame_t * _x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port)
Definition: post.c:651
void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs)
Definition: post.c:292
Definition: plugin_catalog.h:44
Definition: post.h:299
xine_stream_t * stream
Definition: post.h:309
uint32_t mode
Definition: post.h:319
pthread_mutex_t usage_lock
Definition: post.h:311
int usage_count
Definition: post.h:314
post_plugin_t * post
Definition: post.h:326
uint32_t bits
Definition: post.h:317
xine_audio_port_t new_port
Definition: post.h:302
void * user_data
Definition: post.h:329
pthread_mutex_t * port_lock
Definition: post.h:322
uint32_t rate
Definition: post.h:318
xine_audio_port_t * original_port
Definition: post.h:305
Definition: post.h:45
const char * description
human readable (verbose = 1 line) description for this plugin class
Definition: post.h:64
const char * text_domain
Optional non-standard catalog to use with dgettext() for description.
Definition: post.h:69
void(* dispose)(post_class_t *this_gen)
Definition: post.h:75
const char * identifier
short human readable identifier for this plugin class
Definition: post.h:57
Definition: post.h:134
xine_post_in_t xine_in
Definition: post.h:137
void * user_data
Definition: post.h:143
post_plugin_t * post
Definition: post.h:140
Definition: post.h:146
xine_post_out_t xine_out
Definition: post.h:149
post_plugin_t * post
Definition: post.h:152
void * user_data
Definition: post.h:155
Definition: post.h:80
xine_list_t * output
Definition: post.h:90
const char ** output_ids
Definition: post.h:117
int dispose_pending
Definition: post.h:128
xine_ticket_t * running_ticket
Definition: post.h:109
void(* dispose)(post_plugin_t *this_gen)
Definition: post.h:95
const char ** input_ids
Definition: post.h:116
struct plugin_node_s *node XINE_PRIVATE_FIELD
Pointer to the loaded plugin node.
Definition: post.h:125
xine_list_t * input
Definition: post.h:89
xine_t * xine
Definition: post.h:113
xine_post_t xine_post
Definition: post.h:83
Definition: post.h:173
pthread_mutex_t * frame_lock
Definition: post.h:220
xine_stream_t * stream
Definition: post.h:216
pthread_mutex_t * manager_lock
Definition: post.h:221
pthread_mutex_t * port_lock
Definition: post.h:219
int(* intercept_ovl)(post_video_port_t *self)
Definition: post.h:201
int(* route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:195
pthread_mutex_t usage_lock
Definition: post.h:212
int(* intercept_frame)(post_video_port_t *self, vo_frame_t *frame)
Definition: post.h:185
int usage_count
Definition: post.h:211
vo_frame_t * new_frame
Definition: post.h:188
xine_video_port_t new_port
Definition: post.h:176
void * user_data
Definition: post.h:228
video_overlay_manager_t * new_manager
Definition: post.h:204
xine_video_port_t * original_port
Definition: post.h:179
post_plugin_t * post
Definition: post.h:225
video_overlay_manager_t * original_manager
Definition: post.h:207
Definition: video_out.h:518
Definition: video_out.h:59
xine_video_port_t * port
Definition: video_out.h:150
Definition: audio_out.h:172
Definition: list.c:51
Definition: xine.h:721
Definition: xine.h:735
Definition: xine.h:667
Definition: xine_internal.h:80
Definition: xine_internal.h:123
Definition: tickets.h:53
void(* acquire)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:66
void(* release)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:69
void(* renew)(xine_ticket_t *self, int irrevocable)
Definition: tickets.h:75
int ticket_revoked
Definition: tickets.h:61
Definition: video_out.h:176
NULL
Definition: xine_plugin.c:78