~ubuntu-branches/ubuntu/vivid/sflphone/vivid

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjmedia/include/pjmedia/port.h

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2013-06-30 11:40:56 UTC
  • mfrom: (4.1.18 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130630114056-0np50jkyqo6vnmii
Tags: 1.2.3-2
* changeset_r92d62cfc54732bbbcfff2b1d36c096b120b981a5.diff 
  - fixes automatic endian detection 
* Update Vcs: fixes vcs-field-not-canonical

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: port.h 3893 2011-12-01 10:49:07Z ming $ */
 
2
/*
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
6
 * This program 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
 * This program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
#ifndef __PJMEDIA_PORT_H__
 
21
#define __PJMEDIA_PORT_H__
 
22
 
 
23
/**
 
24
 * @file port.h
 
25
 * @brief Port interface declaration
 
26
 */
 
27
#include <pjmedia/clock.h>
 
28
#include <pjmedia/event.h>
 
29
#include <pjmedia/format.h>
 
30
#include <pjmedia/frame.h>
 
31
#include <pjmedia/signatures.h>
 
32
#include <pj/assert.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
    \image html 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
/**
 
191
 * Create 32bit port signature from ASCII characters.
 
192
 */
 
193
#define PJMEDIA_PORT_SIG(a,b,c,d)               PJMEDIA_OBJ_SIG(a,b,c,d)
 
194
 
 
195
 
 
196
/**
 
197
 * Port operation setting.
 
198
 */
 
199
typedef enum pjmedia_port_op
 
200
{
 
201
    /**
 
202
     * No change to the port TX or RX settings.
 
203
     */
 
204
    PJMEDIA_PORT_NO_CHANGE,
 
205
 
 
206
    /**
 
207
     * TX or RX is disabled from the port. It means get_frame() or
 
208
     * put_frame() WILL NOT be called for this port.
 
209
     */
 
210
    PJMEDIA_PORT_DISABLE,
 
211
 
 
212
    /**
 
213
     * TX or RX is muted, which means that get_frame() or put_frame()
 
214
     * will still be called, but the audio frame is discarded.
 
215
     */
 
216
    PJMEDIA_PORT_MUTE,
 
217
 
 
218
    /**
 
219
     * Enable TX and RX to/from this port.
 
220
     */
 
221
    PJMEDIA_PORT_ENABLE
 
222
 
 
223
} pjmedia_port_op;
 
224
 
 
225
 
 
226
/**
 
227
 * Port info.
 
228
 */
 
229
typedef struct pjmedia_port_info
 
230
{
 
231
    pj_str_t        name;               /**< Port name.                     */
 
232
    pj_uint32_t     signature;          /**< Port signature.                */
 
233
    pjmedia_dir     dir;                /**< Port direction.                */
 
234
    pjmedia_format  fmt;                /**< Format.                        */
 
235
} pjmedia_port_info;
 
236
 
 
237
/**
 
238
 * Utility to retrieve audio clock rate/sampling rate value from
 
239
 * pjmedia_port_info.
 
240
 *
 
241
 * @param pia           Pointer to port info containing audio format.
 
242
 * @return              Audio clock rate.
 
243
 */
 
244
PJ_INLINE(unsigned) PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)
 
245
{
 
246
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
247
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
248
    return pia->fmt.det.aud.clock_rate;
 
249
}
 
250
 
 
251
/**
 
252
 * Utility to retrieve audio channel count value from pjmedia_port_info.
 
253
 *
 
254
 * @param pia           Pointer to port info containing audio format.
 
255
 * @return              Audio channel count.
 
256
 */
 
257
PJ_INLINE(unsigned) PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)
 
258
{
 
259
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
260
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
261
    return pia->fmt.det.aud.channel_count;
 
262
}
 
263
 
 
264
/**
 
265
 * Utility to retrieve audio bits per sample value from pjmedia_port_info.
 
266
 *
 
267
 * @param pia           Pointer to port info containing audio format.
 
268
 * @return              Number of bits per sample.
 
269
 */
 
270
PJ_INLINE(unsigned) PJMEDIA_PIA_BITS(const pjmedia_port_info *pia)
 
271
{
 
272
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
273
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
274
    return pia->fmt.det.aud.bits_per_sample;
 
275
}
 
276
 
 
277
/**
 
278
 * Utility to retrieve audio frame interval (ptime) value from
 
279
 * pjmedia_port_info.
 
280
 *
 
281
 * @param pia           Pointer to port info containing audio format.
 
282
 * @return              Frame interval in msec.
 
283
 */
 
284
PJ_INLINE(unsigned) PJMEDIA_PIA_PTIME(const pjmedia_port_info *pia)
 
285
{
 
286
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
287
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
288
    return pia->fmt.det.aud.frame_time_usec / 1000;
 
289
}
 
290
 
 
291
/**
 
292
 * This is a utility routine to retrieve the audio samples_per_frame value
 
293
 * from port info.
 
294
 *
 
295
 * @param pia           Pointer to port info containing audio format.
 
296
 * @return              Samples per frame value.
 
297
 */
 
298
PJ_INLINE(unsigned) PJMEDIA_PIA_SPF(const pjmedia_port_info *pia)
 
299
{
 
300
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
301
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
302
    return PJMEDIA_AFD_SPF(&pia->fmt.det.aud);
 
303
}
 
304
 
 
305
/**
 
306
 * This is a utility routine to retrieve the average bitrate value
 
307
 * from port info.
 
308
 *
 
309
 * @param pia           Pointer to port info containing audio format.
 
310
 * @return              Bitrate, in bits per second.
 
311
 */
 
312
PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_BPS(const pjmedia_port_info *pia)
 
313
{
 
314
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
315
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
316
    return pia->fmt.det.aud.avg_bps;
 
317
}
 
318
 
 
319
/**
 
320
 * This is a utility routine to retrieve the maximum bitrate value
 
321
 * from port info.
 
322
 *
 
323
 * @param pia           Pointer to port info containing audio format.
 
324
 * @return              Bitrate, in bits per second.
 
325
 */
 
326
PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_BPS(const pjmedia_port_info *pia)
 
327
{
 
328
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
329
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
330
    return pia->fmt.det.aud.max_bps;
 
331
}
 
332
 
 
333
/**
 
334
 * This is a utility routine to retrieve the average audio frame size value
 
335
 * from pjmedia_port_info.
 
336
 *
 
337
 * @param pia           Pointer to port info containing audio format.
 
338
 * @return              Frame size in bytes.
 
339
 */
 
340
PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_FSZ(const pjmedia_port_info *pia)
 
341
{
 
342
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
343
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
344
    return PJMEDIA_AFD_AVG_FSZ(&pia->fmt.det.aud);
 
345
}
 
346
 
 
347
/**
 
348
 * Utility to retrieve audio frame size from maximum bitrate from
 
349
 * pjmedia_port_info.
 
350
 *
 
351
 * @param pia           Pointer to port info containing audio format.
 
352
 * @return              Frame size in bytes.
 
353
 */
 
354
PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_FSZ(const pjmedia_port_info *pia)
 
355
{
 
356
    pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
 
357
              pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
 
358
    return PJMEDIA_AFD_MAX_FSZ(&pia->fmt.det.aud);
 
359
}
 
360
 
 
361
/**
 
362
 * Port interface.
 
363
 */
 
364
typedef struct pjmedia_port
 
365
{
 
366
    pjmedia_port_info    info;              /**< Port information.  */
 
367
 
 
368
    /** Port data can be used by the port creator to attach arbitrary
 
369
     *  value to be associated with the port.
 
370
     */
 
371
    struct port_data {
 
372
        void            *pdata;             /**< Pointer data.      */
 
373
        long             ldata;             /**< Long data.         */
 
374
    } port_data;
 
375
 
 
376
    /**
 
377
     * Get clock source.
 
378
     * This should only be called by #pjmedia_port_get_clock_src().
 
379
     */
 
380
    pjmedia_clock_src* (*get_clock_src)(struct pjmedia_port *this_port,
 
381
                                        pjmedia_dir dir);
 
382
 
 
383
    /**
 
384
     * Sink interface.
 
385
     * This should only be called by #pjmedia_port_put_frame().
 
386
     */
 
387
    pj_status_t (*put_frame)(struct pjmedia_port *this_port,
 
388
                             pjmedia_frame *frame);
 
389
 
 
390
    /**
 
391
     * Source interface.
 
392
     * This should only be called by #pjmedia_port_get_frame().
 
393
     */
 
394
    pj_status_t (*get_frame)(struct pjmedia_port *this_port,
 
395
                             pjmedia_frame *frame);
 
396
 
 
397
    /**
 
398
     * Called to destroy this port.
 
399
     */
 
400
    pj_status_t (*on_destroy)(struct pjmedia_port *this_port);
 
401
 
 
402
} pjmedia_port;
 
403
 
 
404
 
 
405
/**
 
406
 * This is an auxiliary function to initialize port info for
 
407
 * ports which deal with PCM audio.
 
408
 *
 
409
 * @param info              The port info to be initialized.
 
410
 * @param name              Port name.
 
411
 * @param signature         Port signature.
 
412
 * @param clock_rate        Port's clock rate.
 
413
 * @param channel_count     Number of channels.
 
414
 * @param bits_per_sample   Bits per sample.
 
415
 * @param samples_per_frame Number of samples per frame.
 
416
 *
 
417
 * @return                  PJ_SUCCESS on success.
 
418
 */
 
419
PJ_DECL(pj_status_t) pjmedia_port_info_init( pjmedia_port_info *info,
 
420
                                             const pj_str_t *name,
 
421
                                             unsigned signature,
 
422
                                             unsigned clock_rate,
 
423
                                             unsigned channel_count,
 
424
                                             unsigned bits_per_sample,
 
425
                                             unsigned samples_per_frame);
 
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 dir               Port's direction.
 
435
 * @param fmt               Port's media format.
 
436
 *
 
437
 * @return                  PJ_SUCCESS on success.
 
438
 */
 
439
PJ_DECL(pj_status_t) pjmedia_port_info_init2(pjmedia_port_info *info,
 
440
                                             const pj_str_t *name,
 
441
                                             unsigned signature,
 
442
                                             pjmedia_dir dir,
 
443
                                             const pjmedia_format *fmt);
 
444
 
 
445
 
 
446
/**
 
447
 * Get a clock source from the port.
 
448
 *
 
449
 * @param port      The media port.
 
450
 * @param dir       Media port's direction.
 
451
 *
 
452
 * @return          The clock source or NULL if clock source is not present
 
453
 *                  in the port.
 
454
 */
 
455
PJ_DECL(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,
 
456
                                                         pjmedia_dir dir );
 
457
 
 
458
 
 
459
/**
 
460
 * Get a frame from the port (and subsequent downstream ports).
 
461
 *
 
462
 * @param port      The media port.
 
463
 * @param frame     Frame to store samples.
 
464
 *
 
465
 * @return          PJ_SUCCESS on success, or the appropriate error code.
 
466
 */
 
467
PJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
 
468
                                             pjmedia_frame *frame );
 
469
 
 
470
/**
 
471
 * Put a frame to the port (and subsequent downstream ports).
 
472
 *
 
473
 * @param port      The media port.
 
474
 * @param frame     Frame to the put to the port.
 
475
 *
 
476
 * @return          PJ_SUCCESS on success, or the appropriate error code.
 
477
 */
 
478
PJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
 
479
                                             pjmedia_frame *frame );
 
480
 
 
481
/**
 
482
 * Destroy port (and subsequent downstream ports)
 
483
 *
 
484
 * @param port      The media port.
 
485
 *
 
486
 * @return          PJ_SUCCESS on success, or the appropriate error code.
 
487
 */
 
488
PJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port );
 
489
 
 
490
 
 
491
 
 
492
PJ_END_DECL
 
493
 
 
494
/**
 
495
 * @}
 
496
 */
 
497
 
 
498
#endif  /* __PJMEDIA_PORT_H__ */