/src/pjsip/pjmedia/include/pjmedia/port.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
3 | | * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
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_PORT_H__ |
20 | | #define __PJMEDIA_PORT_H__ |
21 | | |
22 | | /** |
23 | | * @file port.h |
24 | | * @brief Port interface declaration |
25 | | */ |
26 | | #include <pjmedia/clock.h> |
27 | | #include <pjmedia/event.h> |
28 | | #include <pjmedia/format.h> |
29 | | #include <pjmedia/frame.h> |
30 | | #include <pjmedia/signatures.h> |
31 | | #include <pj/assert.h> |
32 | | #include <pj/lock.h> |
33 | | #include <pj/os.h> |
34 | | |
35 | | |
36 | | /** |
37 | | @addtogroup PJMEDIA_PORT Media Ports Framework |
38 | | @{ |
39 | | |
40 | | @section media_port_intro Media Port Concepts |
41 | | |
42 | | @subsection The Media Port |
43 | | A media port (represented with pjmedia_port "class") provides a generic |
44 | | and extensible framework for implementing media elements. Media element |
45 | | itself could be a media source, sink, or processing element. A media |
46 | | port interface basically has the following properties: |
47 | | - media port information (pjmedia_port_info) to describe the |
48 | | media port properties (sampling rate, number of channels, etc.), |
49 | | - optional pointer to function to acquire frames from the port (the |
50 | | <tt>get_frame() </tt> interface), which will be called by |
51 | | #pjmedia_port_get_frame() public API, and |
52 | | - optional pointer to function to store frames to the port (the |
53 | | <tt>put_frame()</tt> interface) which will be called by |
54 | | #pjmedia_port_put_frame() public API. |
55 | | |
56 | | The <tt>get_frame()</tt> and <tt>put_frame()</tt> interface of course |
57 | | would only need to be implemented if the media port emits and/or takes |
58 | | media frames respectively. |
59 | | |
60 | | Media ports are passive "objects". By default, there is no worker thread |
61 | | to run the media flow. Applications (or other PJMEDIA |
62 | | components, as explained in @ref PJMEDIA_PORT_CLOCK) must actively call |
63 | | #pjmedia_port_get_frame() or #pjmedia_port_put_frame() from/to the media |
64 | | port in order to retrieve/store media frames. |
65 | | |
66 | | Some media ports (such as @ref PJMEDIA_CONF and @ref PJMEDIA_RESAMPLE_PORT) |
67 | | may be interconnected with (or encapsulate) other port, to perform the |
68 | | combined task of the ports, while some |
69 | | others represent the ultimate source/sink termination for the media. |
70 | | Interconnection means the upstream media port will call <tt>get_frame()</tt> |
71 | | and <tt>put_frame()</tt> to its downstream media port. For this to happen, |
72 | | the media ports need to have the same format, where format is defined as |
73 | | combination of sample format, clock rate, channel count, bits per sample, |
74 | | and samples per frame for audio media. |
75 | | |
76 | | |
77 | | @subsection port_clock_ex1 Example: Manual Resampling |
78 | | |
79 | | For example, suppose application wants to convert the sampling rate |
80 | | of one WAV file to another. In this case, application would create and |
81 | | arrange media ports connection as follows: |
82 | | |
83 | | \img{pjmedia/docs/sample-manual-resampling.jpg} |
84 | | |
85 | | Application would setup the media ports using the following pseudo- |
86 | | code: |
87 | | |
88 | | \code |
89 | | |
90 | | pjmedia_port *player, *resample, *writer; |
91 | | pj_status_t status; |
92 | | |
93 | | // Create the file player port. |
94 | | status = pjmedia_wav_player_port_create(pool, |
95 | | "Input.WAV", // file name |
96 | | 20, // ptime. |
97 | | PJMEDIA_FILE_NO_LOOP, // flags |
98 | | 0, // buffer size |
99 | | NULL, // user data. |
100 | | &player ); |
101 | | PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS); |
102 | | |
103 | | // Create the resample port with specifying the target sampling rate, |
104 | | // and with the file port as the source. This will effectively |
105 | | // connect the resample port with the player port. |
106 | | status = pjmedia_resample_port_create( pool, player, 8000, |
107 | | 0, &resample); |
108 | | PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS); |
109 | | |
110 | | // Create the file writer, specifying the resample port's configuration |
111 | | // as the WAV parameters. |
112 | | status pjmedia_wav_writer_port_create(pool, |
113 | | "Output.WAV", // file name. |
114 | | resample->info.clock_rate, |
115 | | resample->info.channel_count, |
116 | | resample->info.samples_per_frame, |
117 | | resample->info.bits_per_sample, |
118 | | 0, // flags |
119 | | 0, // buffer size |
120 | | NULL, // user data. |
121 | | &writer); |
122 | | |
123 | | \endcode |
124 | | |
125 | | |
126 | | After the ports have been set up, application can perform the conversion |
127 | | process by running this loop: |
128 | | |
129 | | \code |
130 | | |
131 | | pj_int16_t samplebuf[MAX_FRAME]; |
132 | | |
133 | | while (1) { |
134 | | pjmedia_frame frame; |
135 | | pj_status_t status; |
136 | | |
137 | | frame.buf = samplebuf; |
138 | | frame.size = sizeof(samplebuf); |
139 | | |
140 | | // Get the frame from resample port. |
141 | | status = pjmedia_port_get_frame(resample, &frame); |
142 | | if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) { |
143 | | // End-of-file, end the conversion. |
144 | | break; |
145 | | } |
146 | | |
147 | | // Put the frame to write port. |
148 | | status = pjmedia_port_put_frame(writer, &frame); |
149 | | if (status != PJ_SUCCESS) { |
150 | | // Error in writing the file. |
151 | | break; |
152 | | } |
153 | | } |
154 | | |
155 | | \endcode |
156 | | |
157 | | For the sake of completeness, after the resampling process is done, |
158 | | application would need to destroy the ports: |
159 | | |
160 | | \code |
161 | | // Note: by default, destroying resample port will destroy the |
162 | | // the downstream port too. |
163 | | pjmedia_port_destroy(resample); |
164 | | pjmedia_port_destroy(writer); |
165 | | \endcode |
166 | | |
167 | | |
168 | | The above steps are okay for our simple purpose of changing file's sampling |
169 | | rate. But for other purposes, the process of reading and writing frames |
170 | | need to be done in timely manner (for example, sending RTP packets to |
171 | | remote stream). And more over, as the application's scope goes bigger, |
172 | | the same pattern of manually reading/writing frames comes up more and more often, |
173 | | thus perhaps it would be better if PJMEDIA provides mechanism to |
174 | | automate this process. |
175 | | |
176 | | And indeed PJMEDIA does provide such mechanism, which is described in |
177 | | @ref PJMEDIA_PORT_CLOCK section. |
178 | | |
179 | | |
180 | | @subsection media_port_autom Automating Media Flow |
181 | | |
182 | | PJMEDIA provides few mechanisms to make media flows automatically |
183 | | among media ports. This concept is described in @ref PJMEDIA_PORT_CLOCK |
184 | | section. |
185 | | */ |
186 | | |
187 | | PJ_BEGIN_DECL |
188 | | |
189 | | |
190 | | /* Since media port's callback is called synchronously and has a return value, |
191 | | * it can introduce a deadlock when a mutex is held before calling it. |
192 | | * To prevent this, media ports' set_eof_cb() and set_cb() functions have |
193 | | * been deprecated and replaced by set_eof_cb2() and set_cb2(), which |
194 | | * will call the callback asynchronously without expecting any return value. |
195 | | * |
196 | | * See also https://github.com/pjsip/pjproject/issues/2251. |
197 | | */ |
198 | | #ifndef DEPRECATED_FOR_TICKET_2251 |
199 | | # define DEPRECATED_FOR_TICKET_2251 0 |
200 | | #endif |
201 | | |
202 | | |
203 | | /** |
204 | | * Create 32bit port signature from ASCII characters. |
205 | | */ |
206 | | #define PJMEDIA_PORT_SIG(a,b,c,d) PJMEDIA_OBJ_SIG(a,b,c,d) |
207 | | |
208 | | |
209 | | /** |
210 | | * Port operation setting. |
211 | | */ |
212 | | typedef enum pjmedia_port_op |
213 | | { |
214 | | /** |
215 | | * No change to the port TX or RX settings. |
216 | | */ |
217 | | PJMEDIA_PORT_NO_CHANGE, |
218 | | |
219 | | /** |
220 | | * TX or RX is disabled from the port. It means get_frame() or |
221 | | * put_frame() WILL NOT be called for this port. |
222 | | */ |
223 | | PJMEDIA_PORT_DISABLE, |
224 | | |
225 | | /** |
226 | | * TX or RX is muted, which means that get_frame() or put_frame() |
227 | | * will still be called, but the audio frame is discarded. |
228 | | */ |
229 | | PJMEDIA_PORT_MUTE, |
230 | | |
231 | | /** |
232 | | * Enable TX and RX to/from this port. |
233 | | */ |
234 | | PJMEDIA_PORT_ENABLE |
235 | | |
236 | | } pjmedia_port_op; |
237 | | |
238 | | |
239 | | /** |
240 | | * Port info. |
241 | | */ |
242 | | typedef struct pjmedia_port_info |
243 | | { |
244 | | pj_str_t name; /**< Port name. */ |
245 | | pj_uint32_t signature; /**< Port signature. */ |
246 | | pjmedia_dir dir; /**< Port direction. */ |
247 | | pjmedia_format fmt; /**< Format. */ |
248 | | } pjmedia_port_info; |
249 | | |
250 | | /** |
251 | | * Utility to retrieve audio clock rate/sampling rate value from |
252 | | * pjmedia_port_info. |
253 | | * |
254 | | * @param pia Pointer to port info containing audio format. |
255 | | * @return Audio clock rate. |
256 | | */ |
257 | | PJ_INLINE(unsigned) PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia) |
258 | 0 | { |
259 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
260 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
261 | 0 | return pia->fmt.det.aud.clock_rate; |
262 | 0 | } |
263 | | |
264 | | /** |
265 | | * Utility to retrieve audio channel count value from pjmedia_port_info. |
266 | | * |
267 | | * @param pia Pointer to port info containing audio format. |
268 | | * @return Audio channel count. |
269 | | */ |
270 | | PJ_INLINE(unsigned) PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia) |
271 | 0 | { |
272 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
273 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
274 | 0 | return pia->fmt.det.aud.channel_count; |
275 | 0 | } |
276 | | |
277 | | /** |
278 | | * Utility to retrieve audio bits per sample value from pjmedia_port_info. |
279 | | * |
280 | | * @param pia Pointer to port info containing audio format. |
281 | | * @return Number of bits per sample. |
282 | | */ |
283 | | PJ_INLINE(unsigned) PJMEDIA_PIA_BITS(const pjmedia_port_info *pia) |
284 | 0 | { |
285 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
286 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
287 | 0 | return pia->fmt.det.aud.bits_per_sample; |
288 | 0 | } |
289 | | |
290 | | /** |
291 | | * Utility to retrieve audio frame interval (ptime) value from |
292 | | * pjmedia_port_info. |
293 | | * |
294 | | * @param pia Pointer to port info containing audio format. |
295 | | * @return Frame interval in msec. |
296 | | */ |
297 | | PJ_INLINE(unsigned) PJMEDIA_PIA_PTIME(const pjmedia_port_info *pia) |
298 | 0 | { |
299 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
300 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
301 | 0 | return pia->fmt.det.aud.frame_time_usec / 1000; |
302 | 0 | } |
303 | | |
304 | | /** |
305 | | * This is a utility routine to retrieve the audio samples_per_frame value |
306 | | * from port info. |
307 | | * |
308 | | * @param pia Pointer to port info containing audio format. |
309 | | * @return Samples per frame value. |
310 | | */ |
311 | | PJ_INLINE(unsigned) PJMEDIA_PIA_SPF(const pjmedia_port_info *pia) |
312 | 0 | { |
313 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
314 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
315 | 0 | return PJMEDIA_AFD_SPF(&pia->fmt.det.aud); |
316 | 0 | } |
317 | | |
318 | | /** |
319 | | * This is a utility routine to retrieve the average bitrate value |
320 | | * from port info. |
321 | | * |
322 | | * @param pia Pointer to port info containing audio format. |
323 | | * @return Bitrate, in bits per second. |
324 | | */ |
325 | | PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_BPS(const pjmedia_port_info *pia) |
326 | 0 | { |
327 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
328 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
329 | 0 | return pia->fmt.det.aud.avg_bps; |
330 | 0 | } |
331 | | |
332 | | /** |
333 | | * This is a utility routine to retrieve the maximum bitrate value |
334 | | * from port info. |
335 | | * |
336 | | * @param pia Pointer to port info containing audio format. |
337 | | * @return Bitrate, in bits per second. |
338 | | */ |
339 | | PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_BPS(const pjmedia_port_info *pia) |
340 | 0 | { |
341 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
342 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
343 | 0 | return pia->fmt.det.aud.max_bps; |
344 | 0 | } |
345 | | |
346 | | /** |
347 | | * This is a utility routine to retrieve the average audio frame size value |
348 | | * from pjmedia_port_info. |
349 | | * |
350 | | * @param pia Pointer to port info containing audio format. |
351 | | * @return Frame size in bytes. |
352 | | */ |
353 | | PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_FSZ(const pjmedia_port_info *pia) |
354 | 0 | { |
355 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
356 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
357 | 0 | return PJMEDIA_AFD_AVG_FSZ(&pia->fmt.det.aud); |
358 | 0 | } |
359 | | |
360 | | /** |
361 | | * Utility to retrieve audio frame size from maximum bitrate from |
362 | | * pjmedia_port_info. |
363 | | * |
364 | | * @param pia Pointer to port info containing audio format. |
365 | | * @return Frame size in bytes. |
366 | | */ |
367 | | PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_FSZ(const pjmedia_port_info *pia) |
368 | 0 | { |
369 | 0 | pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO && |
370 | 0 | pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO); |
371 | 0 | return PJMEDIA_AFD_MAX_FSZ(&pia->fmt.det.aud); |
372 | 0 | } |
373 | | |
374 | | /** |
375 | | * Port interface. |
376 | | */ |
377 | | typedef struct pjmedia_port |
378 | | { |
379 | | pjmedia_port_info info; /**< Port information. */ |
380 | | |
381 | | /** Port data can be used by the port creator to attach arbitrary |
382 | | * value to be associated with the port. |
383 | | */ |
384 | | struct port_data { |
385 | | void *pdata; /**< Pointer data. */ |
386 | | long ldata; /**< Long data. */ |
387 | | } port_data; |
388 | | |
389 | | /** |
390 | | * Group lock. |
391 | | * |
392 | | * This is optional, but if this port is registered to the audio/video |
393 | | * conference bridge, the bridge will create one if the port has none. |
394 | | */ |
395 | | pj_grp_lock_t *grp_lock; |
396 | | |
397 | | /** |
398 | | * Get clock source. |
399 | | * This should only be called by #pjmedia_port_get_clock_src(). |
400 | | */ |
401 | | pjmedia_clock_src* (*get_clock_src)(struct pjmedia_port *this_port, |
402 | | pjmedia_dir dir); |
403 | | |
404 | | /** |
405 | | * Sink interface. |
406 | | * This should only be called by #pjmedia_port_put_frame(). |
407 | | */ |
408 | | pj_status_t (*put_frame)(struct pjmedia_port *this_port, |
409 | | pjmedia_frame *frame); |
410 | | |
411 | | /** |
412 | | * Source interface. |
413 | | * This should only be called by #pjmedia_port_get_frame(). |
414 | | */ |
415 | | pj_status_t (*get_frame)(struct pjmedia_port *this_port, |
416 | | pjmedia_frame *frame); |
417 | | |
418 | | /** |
419 | | * Destructor. |
420 | | * This should only be called by #pjmedia_port_destroy(). |
421 | | */ |
422 | | pj_status_t (*on_destroy)(struct pjmedia_port *this_port); |
423 | | |
424 | | } pjmedia_port; |
425 | | |
426 | | |
427 | | /** |
428 | | * This is an auxiliary function to initialize port info for |
429 | | * ports which deal with PCM audio. |
430 | | * |
431 | | * @param info The port info to be initialized. |
432 | | * @param name Port name. |
433 | | * @param signature Port signature. |
434 | | * @param clock_rate Port's clock rate. |
435 | | * @param channel_count Number of channels. |
436 | | * @param bits_per_sample Bits per sample. |
437 | | * @param samples_per_frame Number of samples per frame. |
438 | | * |
439 | | * @return PJ_SUCCESS on success. |
440 | | */ |
441 | | PJ_DECL(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info, |
442 | | const pj_str_t *name, |
443 | | unsigned signature, |
444 | | unsigned clock_rate, |
445 | | unsigned channel_count, |
446 | | unsigned bits_per_sample, |
447 | | unsigned samples_per_frame); |
448 | | |
449 | | /** |
450 | | * This is an auxiliary function to initialize port info for |
451 | | * ports which deal with PCM audio. |
452 | | * |
453 | | * @param info The port info to be initialized. |
454 | | * @param name Port name. |
455 | | * @param signature Port signature. |
456 | | * @param dir Port's direction. |
457 | | * @param fmt Port's media format. |
458 | | * |
459 | | * @return PJ_SUCCESS on success. |
460 | | */ |
461 | | PJ_DECL(pj_status_t) pjmedia_port_info_init2(pjmedia_port_info *info, |
462 | | const pj_str_t *name, |
463 | | unsigned signature, |
464 | | pjmedia_dir dir, |
465 | | const pjmedia_format *fmt); |
466 | | |
467 | | |
468 | | /** |
469 | | * Get a clock source from the port. |
470 | | * |
471 | | * @param port The media port. |
472 | | * @param dir Media port's direction. |
473 | | * |
474 | | * @return The clock source or NULL if clock source is not present |
475 | | * in the port. |
476 | | */ |
477 | | PJ_DECL(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port, |
478 | | pjmedia_dir dir ); |
479 | | |
480 | | |
481 | | /** |
482 | | * Get a frame from the port (and subsequent downstream ports). |
483 | | * |
484 | | * @param port The media port. |
485 | | * @param frame Frame to store samples. |
486 | | * |
487 | | * @return PJ_SUCCESS on success, or the appropriate error code. |
488 | | */ |
489 | | PJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port, |
490 | | pjmedia_frame *frame ); |
491 | | |
492 | | /** |
493 | | * Put a frame to the port (and subsequent downstream ports). |
494 | | * |
495 | | * @param port The media port. |
496 | | * @param frame Frame to the put to the port. |
497 | | * |
498 | | * @return PJ_SUCCESS on success, or the appropriate error code. |
499 | | */ |
500 | | PJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port, |
501 | | pjmedia_frame *frame ); |
502 | | |
503 | | /** |
504 | | * Destroy port (and subsequent downstream ports). |
505 | | * |
506 | | * Note that if the port has group lock, instead of destroying the port |
507 | | * immediately, this function will just decrease the reference counter. |
508 | | * |
509 | | * @param port The media port. |
510 | | * |
511 | | * @return PJ_SUCCESS on success, or the appropriate error code. |
512 | | */ |
513 | | PJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port ); |
514 | | |
515 | | |
516 | | |
517 | | /* |
518 | | ******************************************************************* |
519 | | * Helper functions. |
520 | | ******************************************************************* |
521 | | */ |
522 | | |
523 | | /** |
524 | | * This is a helper function to initialize the port's group lock. This |
525 | | * function will create a group lock if NULL is passed, initialize the group |
526 | | * lock by adding the port's destructor to the group lock handler list, and |
527 | | * increment the reference counter. |
528 | | * |
529 | | * Normally this function is only called by media port implementation, |
530 | | * application should never call this function. |
531 | | * |
532 | | * This function will check whether the port implements on_destroy(), |
533 | | * because when working with conference bridge, a port is required to manage |
534 | | * its lifetime via group lock (e.g: initialized by this function), |
535 | | * so basically it must use its own pool and the pool is normally |
536 | | * released from its on_destroy(). |
537 | | * |
538 | | * Also note that this function will add a group lock destroy handler |
539 | | * that calls port's on_destroy(), so port implementation can release |
540 | | * its resources from on_destroy() as usual. |
541 | | * |
542 | | * @param port The pjmedia port to be initialized. |
543 | | * @param pool The pool, this can be a temporary pool as |
544 | | * group lock will create and use its internal pool. |
545 | | * @param glock The group lock, or create a new one if NULL. |
546 | | * |
547 | | * @return PJ_SUCCESS on success, PJ_EEXISTS if group lock |
548 | | * is already initialized, or the other appropriate |
549 | | * error code. |
550 | | */ |
551 | | PJ_DECL(pj_status_t) pjmedia_port_init_grp_lock( pjmedia_port *port, |
552 | | pj_pool_t *pool, |
553 | | pj_grp_lock_t *glock ); |
554 | | |
555 | | |
556 | | /** |
557 | | * This is a helper function to increase the port reference counter. |
558 | | * |
559 | | * @param port The PJMEDIA port. |
560 | | * |
561 | | * @return PJ_SUCCESS on success. |
562 | | */ |
563 | | PJ_DECL(pj_status_t) pjmedia_port_add_ref( pjmedia_port *port ); |
564 | | |
565 | | |
566 | | /** |
567 | | * This is a helper function to decrease the port reference counter. |
568 | | * |
569 | | * @param port The PJMEDIA port. |
570 | | * |
571 | | * @return PJ_SUCCESS on success. |
572 | | */ |
573 | | PJ_DECL(pj_status_t) pjmedia_port_dec_ref( pjmedia_port *port ); |
574 | | |
575 | | |
576 | | /** |
577 | | * This is a helper function to add port destructor handler. |
578 | | * |
579 | | * Application can use this function to schedule its resource release. |
580 | | * Note that application cannot release the resources related to the port, |
581 | | * e.g: memory pool (custom ports that do not use its own pool), |
582 | | * immediately after removing the port from the conference bridge |
583 | | * as the port removal is done asynchronously. |
584 | | * |
585 | | * Usually this function is called after adding the port to the conference |
586 | | * bridge. |
587 | | * |
588 | | * @param port The PJMEDIA port. |
589 | | * @param member A pointer to be passed to the handler. |
590 | | * @param handler The destroy handler. |
591 | | * |
592 | | * @return PJ_SUCCESS on success. |
593 | | */ |
594 | | PJ_DECL(pj_status_t) pjmedia_port_add_destroy_handler( |
595 | | pjmedia_port* port, |
596 | | void *member, |
597 | | pj_grp_lock_handler handler); |
598 | | |
599 | | |
600 | | /** |
601 | | * This is a helper function to remove previously registered |
602 | | * destructor handler. |
603 | | * |
604 | | * @param port The PJMEDIA port. |
605 | | * @param member A pointer to be passed to the handler. |
606 | | * @param handler The destroy handler. |
607 | | * |
608 | | * @return PJ_SUCCESS on success. |
609 | | */ |
610 | | PJ_DECL(pj_status_t) pjmedia_port_del_destroy_handler( |
611 | | pjmedia_port* port, |
612 | | void *member, |
613 | | pj_grp_lock_handler handler); |
614 | | |
615 | | |
616 | | PJ_END_DECL |
617 | | |
618 | | /** |
619 | | * @} |
620 | | */ |
621 | | |
622 | | #endif /* __PJMEDIA_PORT_H__ */ |
623 | | |