pjsip logo pjsip.org
Open source SIP stack and media stack for presence, im/instant messaging, and multimedia communication

HOME

SIP/media Features
High Performance SIP
Small Footprint SIP
Symbian Port

FAQ

Documentation

Licensing

Download

Development (Trac)

Projects using pjsip

Mailing List

Open Source Links


About: PJLIB, PJLIB-UTIL, PJSIP, and PJMEDIA are created by: Benny Prijono
<bennylp@pjsip.org>


 

Home --> Documentations --> PJMEDIA Reference

Media Ports Framework


Detailed Description

Media Port Concepts

Media Port

A media port (represented with pjmedia_port "class") provides a generic and extensible framework for implementing media terminations. A media port interface basically has the following properties:
  • media port information (pjmedia_port_info) to describe the media port properties (sampling rate, number of channels, etc.),
  • pointer to function to acquire frames from the port (get_frame() interface), which will be called by pjmedia_port_get_frame() public API, and
  • pointer to function to store frames to the port (put_frame() interface) which will be called by pjmedia_port_put_frame() public API.

Media ports are passive "objects". Applications (or other PJMEDIA components) must actively calls pjmedia_port_get_frame() or pjmedia_port_put_frame() from/to the media port in order to retrieve/ store media frames.

Some media ports (such as Conference Bridge and Resample Port) may be interconnected with each other, while some others represent the ultimate source/sink termination for the media.

Example: Manual Resampling

For example, suppose application wants to convert the sampling rate of one WAV file to another. In this case, application would create and arrange media ports connection as follows:

sample-manual-resampling.jpg

Application would setup the media ports using the following pseudo- code:

      pjmedia_port *player, *resample, *writer;
      pj_status_t status;
  
      // Create the file player port.
      status = pjmedia_wav_player_port_create(pool, 
                                              "Input.WAV",          // file name
                                              20,                   // ptime.
                                              PJMEDIA_FILE_NO_LOOP, // flags
                                              0,                    // buffer size
                                              NULL,                 // user data.
                                              &player );
      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
  
      // Create the resample port with specifying the target sampling rate, 
      // and with the file port as the source. This will effectively
      // connect the resample port with the player port.
      status = pjmedia_resample_port_create( pool, player, 8000, 
                                             0, &resample);
      PJ_ASSERT_RETURN(status==PJ_SUCCESS, PJ_SUCCESS);
  
      // Create the file writer, specifying the resample port's configuration
      // as the WAV parameters.
      status pjmedia_wav_writer_port_create(pool, 
                                            "Output.WAV",  // file name.
                                            resample->info.clock_rate,
                                            resample->info.channel_count,
                                            resample->info.samples_per_frame,
                                            resample->info.bits_per_sample,
                                            0,          // flags
                                            0,          // buffer size
                                            NULL,       // user data.
                                            &writer);

After the ports have been set up, application can perform the conversion process by running this loop:

        pj_int16_t samplebuf[MAX_FRAME];
        
        while (1) {
            pjmedia_frame frame;
            pj_status_t status;
  
            frame.buf = samplebuf;
            frame.size = sizeof(samplebuf);
  
            // Get the frame from resample port.
            status = pjmedia_port_get_frame(resample, &frame);
            if (status != PJ_SUCCESS || frame.type == PJMEDIA_FRAME_TYPE_NONE) {
                // End-of-file, end the conversion.
                break;
            }
  
            // Put the frame to write port.
            status = pjmedia_port_put_frame(writer, &frame);
            if (status != PJ_SUCCESS) {
                // Error in writing the file.
                break;
            }
        }

For the sake of completeness, after the resampling process is done, application would need to destroy the ports:

        // Note: by default, destroying resample port will destroy the
        //       the downstream port too.
        pjmedia_port_destroy(resample);
        pjmedia_port_destroy(writer);

The above steps are okay for our simple purpose of changing file's sampling rate. But for other purposes, the process of reading and writing frames need to be done in timely manner (for example, sending RTP packets to remote stream). And more over, as the application's scope goes bigger, the same pattern of manually reading/writing frames comes up more and more often, thus perhaps it would be better if PJMEDIA provides mechanism to automate this process.

And indeed PJMEDIA does provide such mechanism, which is described in Clock/Timing section.

Automating Media Flow

PJMEDIA provides few mechanisms to make media flows automatically among media ports. This concept is described in Clock/Timing section.


Table of Contents

 Bidirectional Port
 A bidirectional port combines two unidirectional ports into one bidirectional port.
 Conference Bridge
 Audio conference bridge implementation.
 Accoustic Echo Cancellation API
 Echo Cancellation API.
 Echo Cancellation Port
 Echo Cancellation.
 Memory/Buffer-based Playback Port
 Media playback from a fixed size memory buffer.
 Memory/Buffer-based Capture Port
 Media capture to fixed size memory buffer.
 Null Port
 The simplest type of media port which does nothing.
 Resample Port
 Audio sample rate conversion.
 Streams
 Communicating with remote peer via the network.
 Multi-frequency tone generator
 Multi-frequency tone generator.
 WAV File Play List
 Audio playback of multiple WAV files.
 WAV File Player
 Audio playback from WAV file.
 File Writer (Recorder)
 Audio capture/recording to WAV file.
 Media channel splitter/combiner
 Split and combine multiple mono-channel media ports into a single multiple-channels media port.

Data Structures

struct  pjmedia_port_info
struct  pjmedia_frame
struct  pjmedia_port

Enumerations

enum  pjmedia_port_op {
  PJMEDIA_PORT_NO_CHANGE,
  PJMEDIA_PORT_DISABLE,
  PJMEDIA_PORT_MUTE,
  PJMEDIA_PORT_ENABLE
}
enum  pjmedia_frame_type {
  PJMEDIA_FRAME_TYPE_NONE,
  PJMEDIA_FRAME_TYPE_AUDIO
}

Functions

pj_status_t pjmedia_port_info_init (pjmedia_port_info *info, const pj_str_t *name, unsigned signature, unsigned clock_rate, unsigned channel_count, unsigned bits_per_sample, unsigned samples_per_frame)
pj_status_t pjmedia_port_get_frame (pjmedia_port *port, pjmedia_frame *frame)
pj_status_t pjmedia_port_put_frame (pjmedia_port *port, const pjmedia_frame *frame)
pj_status_t pjmedia_port_destroy (pjmedia_port *port)


Enumeration Type Documentation

Port operation setting.

Enumerator:
PJMEDIA_PORT_NO_CHANGE  No change to the port TX or RX settings.
PJMEDIA_PORT_DISABLE  TX or RX is disabled from the port. It means get_frame() or put_frame() WILL NOT be called for this port.
PJMEDIA_PORT_MUTE  TX or RX is muted, which means that get_frame() or put_frame() will still be called, but the audio frame is discarded.
PJMEDIA_PORT_ENABLE  Enable TX and RX to/from this port.

Types of media frame.

Enumerator:
PJMEDIA_FRAME_TYPE_NONE  No frame.
PJMEDIA_FRAME_TYPE_AUDIO  Normal audio frame.


Function Documentation

pj_status_t pjmedia_port_info_init ( pjmedia_port_info info,
const pj_str_t name,
unsigned  signature,
unsigned  clock_rate,
unsigned  channel_count,
unsigned  bits_per_sample,
unsigned  samples_per_frame 
)

This is an auxiliary function to initialize port info for ports which deal with PCM audio.

Parameters:
info The port info to be initialized.
name Port name.
signature Port signature.
clock_rate Port's clock rate.
channel_count Number of channels.
bits_per_sample Bits per sample.
samples_per_frame Number of samples per frame.
Returns:
PJ_SUCCESS on success.

pj_status_t pjmedia_port_get_frame ( pjmedia_port port,
pjmedia_frame frame 
)

Get a frame from the port (and subsequent downstream ports).

Parameters:
port The media port.
frame Frame to store samples.
Returns:
PJ_SUCCESS on success, or the appropriate error code.

pj_status_t pjmedia_port_put_frame ( pjmedia_port port,
const pjmedia_frame frame 
)

Put a frame to the port (and subsequent downstream ports).

Parameters:
port The media port.
frame Frame to the put to the port.
Returns:
PJ_SUCCESS on success, or the appropriate error code.

pj_status_t pjmedia_port_destroy ( pjmedia_port port  ) 

Destroy port (and subsequent downstream ports)

Parameters:
port The media port.
Returns:
PJ_SUCCESS on success, or the appropriate error code.

 


PJMEDIA small footprint Open Source media stack
(C)2003-2008 Benny Prijono