1 /* $Id$ */
2 /*
3  * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #ifndef __PJMEDIA_EVENT_H__
20 #define __PJMEDIA_EVENT_H__
21 
22 /**
23  * @file pjmedia/event.h
24  * @brief Event framework
25  */
26 #include <pjmedia/audiodev.h>
27 #include <pjmedia/format.h>
28 #include <pjmedia/rtcp_fb.h>
29 #include <pjmedia/signatures.h>
30 #include <pjmedia/videodev.h>
31 
32 PJ_BEGIN_DECL
33 
34 /**
35  * @defgroup PJMEDIA_EVENT Event Framework
36  * @brief PJMEDIA event framework
37  * @{
38  */
39 
40 /**
41  * This enumeration describes list of media events.
42  */
43 typedef enum pjmedia_event_type
44 {
45     /**
46      * No event.
47      */
48     PJMEDIA_EVENT_NONE,
49 
50     /**
51      * Media format has changed event.
52      */
53     PJMEDIA_EVENT_FMT_CHANGED	= PJMEDIA_FOURCC('F', 'M', 'C', 'H'),
54 
55     /**
56      * Video window is being closed.
57      */
58     PJMEDIA_EVENT_WND_CLOSING	= PJMEDIA_FOURCC('W', 'N', 'C', 'L'),
59 
60     /**
61      * Video window has been closed event.
62      */
63     PJMEDIA_EVENT_WND_CLOSED	= PJMEDIA_FOURCC('W', 'N', 'C', 'O'),
64 
65     /**
66      * Video window has been resized event.
67      */
68     PJMEDIA_EVENT_WND_RESIZED	= PJMEDIA_FOURCC('W', 'N', 'R', 'Z'),
69 
70     /**
71      * Mouse button has been pressed event.
72      */
73     PJMEDIA_EVENT_MOUSE_BTN_DOWN = PJMEDIA_FOURCC('M', 'S', 'D', 'N'),
74 
75     /**
76      * Video keyframe has just been decoded event.
77      */
78     PJMEDIA_EVENT_KEYFRAME_FOUND = PJMEDIA_FOURCC('I', 'F', 'R', 'F'),
79 
80     /**
81      * Video decoding error due to missing keyframe event.
82      */
83     PJMEDIA_EVENT_KEYFRAME_MISSING = PJMEDIA_FOURCC('I', 'F', 'R', 'M'),
84 
85     /**
86      * Video orientation has been changed event.
87      */
88     PJMEDIA_EVENT_ORIENT_CHANGED = PJMEDIA_FOURCC('O', 'R', 'N', 'T'),
89 
90     /**
91      * RTCP-FB has been received.
92      */
93     PJMEDIA_EVENT_RX_RTCP_FB = PJMEDIA_FOURCC('R', 'T', 'F', 'B'),
94 
95     /**
96      * Audio device stopped on error.
97      */
98     PJMEDIA_EVENT_AUD_DEV_ERROR = PJMEDIA_FOURCC('A', 'E', 'R', 'R'),
99 
100     /**
101      * Video device stopped on error.
102      */
103     PJMEDIA_EVENT_VID_DEV_ERROR = PJMEDIA_FOURCC('V', 'E', 'R', 'R'),
104 
105     /**
106      * Transport media error.
107      */
108     PJMEDIA_EVENT_MEDIA_TP_ERR = PJMEDIA_FOURCC('T', 'E', 'R', 'R'),
109 
110     /**
111      * Callback event. Currently for internal use only.
112      */
113     PJMEDIA_EVENT_CALLBACK = PJMEDIA_FOURCC('C', 'B', ' ', ' ')
114 
115 } pjmedia_event_type;
116 
117 /**
118  * Additional data/parameters for media format changed event
119  * (PJMEDIA_EVENT_FMT_CHANGED).
120  */
121 typedef struct pjmedia_event_fmt_changed_data
122 {
123     /** The media flow direction */
124     pjmedia_dir		dir;
125 
126     /** The new media format. */
127     pjmedia_format	new_fmt;
128 } pjmedia_event_fmt_changed_data;
129 
130 /**
131  * Additional data/parameters are not needed.
132  */
133 typedef struct pjmedia_event_dummy_data
134 {
135     /** Dummy data */
136     int			dummy;
137 } pjmedia_event_dummy_data;
138 
139 /**
140  * Additional data/parameters for window resized event
141  * (PJMEDIA_EVENT_WND_RESIZED).
142  */
143 typedef struct pjmedia_event_wnd_resized_data
144 {
145     /**
146      * The new window size.
147      */
148     pjmedia_rect_size	new_size;
149 } pjmedia_event_wnd_resized_data;
150 
151 /**
152  * Additional data/parameters for window closing event.
153  */
154 typedef struct pjmedia_event_wnd_closing_data
155 {
156     /** Consumer may set this field to PJ_TRUE to cancel the closing */
157     pj_bool_t		cancel;
158 } pjmedia_event_wnd_closing_data;
159 
160 /**
161  * Additional data/parameters for audio device error event.
162  */
163 typedef struct pjmedia_event_aud_dev_err_data
164 {
165     /** The media direction that fails */
166     pjmedia_dir		     dir;
167 
168     /** The audio device ID */
169     pjmedia_aud_dev_index    id;
170 
171     /** The error code */
172     pj_status_t		     status;
173 
174 } pjmedia_event_aud_dev_err_data;
175 
176 /**
177  * Additional data/parameters for video device error event.
178  */
179 typedef struct pjmedia_event_vid_dev_err_data
180 {
181     /** The media direction that fails */
182     pjmedia_dir		     dir;
183 
184     /** The video device ID */
185     pjmedia_vid_dev_index    id;
186 
187     /** The error code */
188     pj_status_t		     status;
189 
190 } pjmedia_event_vid_dev_err_data;
191 
192 /**
193  * Additional data/parameters for media transmit error event.
194  */
195 typedef struct pjmedia_event_media_tp_err_data
196 {
197     /** The media type		*/
198     pjmedia_type	    type;
199 
200     /** RTP/RTCP?		*/
201     pj_bool_t		    is_rtp;
202 
203     /** Media direction		*/
204     pjmedia_dir		    dir;
205 
206     /** The error code		*/
207     pj_status_t		    status;
208 
209 } pjmedia_event_media_tp_err_data;
210 
211 
212 /** Additional parameters for window changed event. */
213 typedef pjmedia_event_dummy_data pjmedia_event_wnd_closed_data;
214 
215 /** Additional parameters for mouse button down event */
216 typedef pjmedia_event_dummy_data pjmedia_event_mouse_btn_down_data;
217 
218 /** Additional parameters for keyframe found event */
219 typedef pjmedia_event_dummy_data pjmedia_event_keyframe_found_data;
220 
221 /** Additional parameters for keyframe missing event */
222 typedef pjmedia_event_dummy_data pjmedia_event_keyframe_missing_data;
223 
224 /**
225  * Maximum size of additional parameters section in pjmedia_event structure
226  */
227 #define PJMEDIA_EVENT_DATA_MAX_SIZE	sizeof(pjmedia_event_fmt_changed_data)
228 
229 /** Type of storage to hold user data in pjmedia_event structure */
230 typedef char pjmedia_event_user_data[PJMEDIA_EVENT_DATA_MAX_SIZE];
231 
232 /**
233  * This structure describes a media event. It consists mainly of the event
234  * type and additional data/parameters for the event. Applications can
235  * use #pjmedia_event_init() to initialize this event structure with
236  * basic information about the event.
237  */
238 typedef struct pjmedia_event
239 {
240     /**
241      * The event type.
242      */
243     pjmedia_event_type			 type;
244 
245     /**
246      * The media timestamp when the event occurs.
247      */
248     pj_timestamp		 	 timestamp;
249 
250     /**
251      * Pointer information about the source of this event. This field
252      * is provided mainly for comparison purpose so that event subscribers
253      * can check which source the event originated from. Usage of this
254      * pointer for other purpose may require special care such as mutex
255      * locking or checking whether the object is already destroyed.
256      */
257     const void	                        *src;
258 
259     /**
260      * Pointer information about the publisher of this event. This field
261      * is provided mainly for comparison purpose so that event subscribers
262      * can check which object published the event. Usage of this
263      * pointer for other purpose may require special care such as mutex
264      * locking or checking whether the object is already destroyed.
265      */
266     const void	                        *epub;
267 
268     /**
269      * Additional data/parameters about the event. The type of data
270      * will be specific to the event type being reported.
271      */
272     union {
273 	/** Media format changed event data. */
274 	pjmedia_event_fmt_changed_data		fmt_changed;
275 
276 	/** Window resized event data */
277 	pjmedia_event_wnd_resized_data		wnd_resized;
278 
279 	/** Window closing event data. */
280 	pjmedia_event_wnd_closing_data		wnd_closing;
281 
282 	/** Window closed event data */
283 	pjmedia_event_wnd_closed_data		wnd_closed;
284 
285 	/** Mouse button down event data */
286 	pjmedia_event_mouse_btn_down_data	mouse_btn_down;
287 
288 	/** Keyframe found event data */
289 	pjmedia_event_keyframe_found_data	keyframe_found;
290 
291 	/** Keyframe missing event data */
292 	pjmedia_event_keyframe_missing_data	keyframe_missing;
293 
294 	/** Audio device error event data */
295 	pjmedia_event_aud_dev_err_data		aud_dev_err;
296 
297 	/** Video device error event data */
298 	pjmedia_event_vid_dev_err_data		vid_dev_err;
299 
300 	/** Storage for user event data */
301 	pjmedia_event_user_data			user;
302 
303 	/** Media transport error event data */
304 	pjmedia_event_media_tp_err_data		med_tp_err;
305 
306 	/** Receiving RTCP-FB event data */
307 	pjmedia_event_rx_rtcp_fb_data		rx_rtcp_fb;
308 
309 	/** Pointer to storage to user event data, if it's outside
310 	 * this struct
311 	 */
312 	void					*ptr;
313     } data;
314 } pjmedia_event;
315 
316 /**
317  * The callback to receive media events.
318  *
319  * @param event		The media event.
320  * @param user_data	The user data associated with the callback.
321  *
322  * @return		If the callback returns non-PJ_SUCCESS, this return
323  * 			code may be propagated back to the caller.
324  */
325 typedef pj_status_t pjmedia_event_cb(pjmedia_event *event,
326                                      void *user_data);
327 
328 /**
329  * This enumeration describes flags for event publication via
330  * #pjmedia_event_publish().
331  */
332 typedef enum pjmedia_event_publish_flag
333 {
334     /**
335      * Default flag.
336      */
337     PJMEDIA_EVENT_PUBLISH_DEFAULT,
338 
339     /**
340      * Publisher will only post the event to the event manager. It is the
341      * event manager that will later notify all the publisher's subscribers.
342      */
343     PJMEDIA_EVENT_PUBLISH_POST_EVENT = 1
344 
345 } pjmedia_event_publish_flag;
346 
347 /**
348  * Event manager flag.
349  */
350 typedef enum pjmedia_event_mgr_flag
351 {
352     /**
353      * Tell the event manager not to create any event worker thread.
354      * Do not set this flag if app plans to publish an event using
355      * PJMEDIA_EVENT_PUBLISH_POST_EVENT.
356      */
357     PJMEDIA_EVENT_MGR_NO_THREAD = 1
358 
359 } pjmedia_event_mgr_flag;
360 
361 /**
362  * Opaque data type for event manager. Typically, the event manager
363  * is a singleton instance, although application may instantiate more than one
364  * instances of this if required.
365  */
366 typedef struct pjmedia_event_mgr pjmedia_event_mgr;
367 
368 /**
369  * Create a new event manager instance. This will also set the pointer
370  * to the singleton instance if the value is still NULL.
371  *
372  * @param pool		Pool to allocate memory from.
373  * @param options       Options. Bitmask flags from #pjmedia_event_mgr_flag
374  * @param mgr		Pointer to hold the created instance of the
375  * 			event manager.
376  *
377  * @return		PJ_SUCCESS on success or the appropriate error code.
378  */
379 PJ_DECL(pj_status_t) pjmedia_event_mgr_create(pj_pool_t *pool,
380                                               unsigned options,
381 				              pjmedia_event_mgr **mgr);
382 
383 /**
384  * Get the singleton instance of the event manager.
385  *
386  * @return		The instance.
387  */
388 PJ_DECL(pjmedia_event_mgr*) pjmedia_event_mgr_instance(void);
389 
390 /**
391  * Manually assign a specific event manager instance as the singleton
392  * instance. Normally this is not needed if only one instance is ever
393  * going to be created, as the library automatically assign the singleton
394  * instance.
395  *
396  * @param mgr		The instance to be used as the singleton instance.
397  * 			Application may specify NULL to clear the singleton
398  * 			singleton instance.
399  */
400 PJ_DECL(void) pjmedia_event_mgr_set_instance(pjmedia_event_mgr *mgr);
401 
402 /**
403  * Destroy an event manager. If the manager happens to be the singleton
404  * instance, the singleton instance will be set to NULL.
405  *
406  * @param mgr		The eventmanager. Specify NULL to use
407  * 			the singleton instance.
408  */
409 PJ_DECL(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr);
410 
411 /**
412  * Initialize event structure with basic data about the event.
413  *
414  * @param event		The event to be initialized.
415  * @param type		The event type to be set for this event.
416  * @param ts		Event timestamp. May be set to NULL to set the event
417  * 			timestamp to zero.
418  * @param src		Event source.
419  */
420 PJ_DECL(void) pjmedia_event_init(pjmedia_event *event,
421                                  pjmedia_event_type type,
422                                  const pj_timestamp *ts,
423                                  const void *src);
424 
425 /**
426  * Subscribe a callback function to events published by the specified
427  * publisher. Note that the subscriber may receive not only events emitted by
428  * the specific publisher specified in the argument, but also from other
429  * publishers contained by the publisher, if the publisher is republishing
430  * events from other publishers.
431  *
432  * @param mgr		The event manager.
433  * @param cb            The callback function to receive the event.
434  * @param user_data     The user data to be associated with the callback
435  *                      function.
436  * @param epub		The event publisher.
437  *
438  * @return		PJ_SUCCESS on success or the appropriate error code.
439  */
440 PJ_DECL(pj_status_t) pjmedia_event_subscribe(pjmedia_event_mgr *mgr,
441                                              pjmedia_event_cb *cb,
442                                              void *user_data,
443                                              void *epub);
444 
445 /**
446  * Unsubscribe the callback associated with the user data from a publisher.
447  * If the user data is not specified, this function will do the
448  * unsubscription for all user data. If the publisher, epub, is not
449  * specified, this function will do the unsubscription from all publishers.
450  *
451  * @param mgr		The event manager.
452  * @param cb            The callback function.
453  * @param user_data     The user data associated with the callback
454  *                      function, can be NULL.
455  * @param epub		The event publisher, can be NULL.
456  *
457  * @return		PJ_SUCCESS on success or the appropriate error code.
458  */
459 PJ_DECL(pj_status_t)
460 pjmedia_event_unsubscribe(pjmedia_event_mgr *mgr,
461                           pjmedia_event_cb *cb,
462                           void *user_data,
463                           void *epub);
464 
465 /**
466  * Publish the specified event to all subscribers of the specified event
467  * publisher. By default, the function will call all the subcribers'
468  * callbacks immediately. If the publisher uses the flag
469  * PJMEDIA_EVENT_PUBLISH_POST_EVENT, publisher will only post the event
470  * to the event manager and return immediately. It is the event manager
471  * that will later notify all the publisher's subscribers.
472  *
473  * @param mgr		The event manager.
474  * @param epub		The event publisher.
475  * @param event		The event to be published.
476  * @param flag          Publication flag.
477  *
478  * @return		PJ_SUCCESS only if all subscription callbacks returned
479  * 			PJ_SUCCESS.
480  */
481 PJ_DECL(pj_status_t) pjmedia_event_publish(pjmedia_event_mgr *mgr,
482                                            void *epub,
483                                            pjmedia_event *event,
484                                            pjmedia_event_publish_flag flag);
485 
486 
487 /**
488  * @}  PJMEDIA_EVENT
489  */
490 
491 
492 PJ_END_DECL
493 
494 #endif	/* __PJMEDIA_EVENT_H__ */
495