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