summaryrefslogtreecommitdiff
path: root/pjmedia/include
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
committerDavid M. Lee <dlee@digium.com>2013-01-07 14:24:28 -0600
commitf3ab456a17af1c89a6e3be4d20c5944853df1cb0 (patch)
treed00e1a332cd038a6d906a1ea0ac91e1a4458e617 /pjmedia/include
Import pjproject-2.0.1
Diffstat (limited to 'pjmedia/include')
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiodev.h719
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiodev_imp.h188
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiotest.h116
-rw-r--r--pjmedia/include/pjmedia-audiodev/config.h459
-rw-r--r--pjmedia/include/pjmedia-audiodev/errno.h212
-rw-r--r--pjmedia/include/pjmedia-codec.h42
-rw-r--r--pjmedia/include/pjmedia-codec/amr_helper.h1228
-rw-r--r--pjmedia/include/pjmedia-codec/amr_sdp_match.h61
-rw-r--r--pjmedia/include/pjmedia-codec/audio_codecs.h98
-rw-r--r--pjmedia/include/pjmedia-codec/config.h423
-rw-r--r--pjmedia/include/pjmedia-codec/config_auto.h.in80
-rw-r--r--pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h67
-rw-r--r--pjmedia/include/pjmedia-codec/g722.h104
-rw-r--r--pjmedia/include/pjmedia-codec/g7221.h162
-rw-r--r--pjmedia/include/pjmedia-codec/g7221_sdp_match.h59
-rw-r--r--pjmedia/include/pjmedia-codec/gsm.h87
-rw-r--r--pjmedia/include/pjmedia-codec/h263_packetizer.h146
-rw-r--r--pjmedia/include/pjmedia-codec/h264_packetizer.h157
-rw-r--r--pjmedia/include/pjmedia-codec/ilbc.h119
-rw-r--r--pjmedia/include/pjmedia-codec/ipp_codecs.h322
-rw-r--r--pjmedia/include/pjmedia-codec/l16.h81
-rw-r--r--pjmedia/include/pjmedia-codec/opencore_amrnb.h89
-rw-r--r--pjmedia/include/pjmedia-codec/passthrough.h277
-rw-r--r--pjmedia/include/pjmedia-codec/speex.h150
-rw-r--r--pjmedia/include/pjmedia-codec/types.h126
-rw-r--r--pjmedia/include/pjmedia-videodev/avi_dev.h139
-rw-r--r--pjmedia/include/pjmedia-videodev/config.h203
-rw-r--r--pjmedia/include/pjmedia-videodev/errno.h159
-rw-r--r--pjmedia/include/pjmedia-videodev/videodev.h827
-rw-r--r--pjmedia/include/pjmedia-videodev/videodev_imp.h230
-rw-r--r--pjmedia/include/pjmedia.h81
-rw-r--r--pjmedia/include/pjmedia/alaw_ulaw.h213
-rw-r--r--pjmedia/include/pjmedia/avi.h202
-rw-r--r--pjmedia/include/pjmedia/avi_stream.h170
-rw-r--r--pjmedia/include/pjmedia/bidirectional.h67
-rw-r--r--pjmedia/include/pjmedia/circbuf.h436
-rw-r--r--pjmedia/include/pjmedia/clock.h335
-rw-r--r--pjmedia/include/pjmedia/codec.h1126
-rw-r--r--pjmedia/include/pjmedia/conference.h509
-rw-r--r--pjmedia/include/pjmedia/config.h1181
-rw-r--r--pjmedia/include/pjmedia/config_auto.h.in43
-rw-r--r--pjmedia/include/pjmedia/converter.h322
-rw-r--r--pjmedia/include/pjmedia/delaybuf.h176
-rw-r--r--pjmedia/include/pjmedia/doxygen.h244
-rw-r--r--pjmedia/include/pjmedia/echo.h260
-rw-r--r--pjmedia/include/pjmedia/echo_port.h74
-rw-r--r--pjmedia/include/pjmedia/endpoint.h295
-rw-r--r--pjmedia/include/pjmedia/errno.h650
-rw-r--r--pjmedia/include/pjmedia/event.h395
-rw-r--r--pjmedia/include/pjmedia/format.h766
-rw-r--r--pjmedia/include/pjmedia/frame.h332
-rw-r--r--pjmedia/include/pjmedia/g711.h89
-rw-r--r--pjmedia/include/pjmedia/jbuf.h451
-rw-r--r--pjmedia/include/pjmedia/master_port.h199
-rw-r--r--pjmedia/include/pjmedia/mem_port.h195
-rw-r--r--pjmedia/include/pjmedia/null_port.h70
-rw-r--r--pjmedia/include/pjmedia/plc.h115
-rw-r--r--pjmedia/include/pjmedia/port.h499
-rw-r--r--pjmedia/include/pjmedia/resample.h200
-rw-r--r--pjmedia/include/pjmedia/rtcp.h486
-rw-r--r--pjmedia/include/pjmedia/rtcp_xr.h478
-rw-r--r--pjmedia/include/pjmedia/rtp.h394
-rw-r--r--pjmedia/include/pjmedia/sdp.h736
-rw-r--r--pjmedia/include/pjmedia/sdp_neg.h765
-rw-r--r--pjmedia/include/pjmedia/session.h436
-rw-r--r--pjmedia/include/pjmedia/signatures.h217
-rw-r--r--pjmedia/include/pjmedia/silencedet.h200
-rw-r--r--pjmedia/include/pjmedia/sound.h336
-rw-r--r--pjmedia/include/pjmedia/sound_port.h352
-rw-r--r--pjmedia/include/pjmedia/splitcomb.h140
-rw-r--r--pjmedia/include/pjmedia/stereo.h206
-rw-r--r--pjmedia/include/pjmedia/stream.h436
-rw-r--r--pjmedia/include/pjmedia/stream_common.h57
-rw-r--r--pjmedia/include/pjmedia/symbian_sound_aps.h48
-rw-r--r--pjmedia/include/pjmedia/tonegen.h293
-rw-r--r--pjmedia/include/pjmedia/transport.h853
-rw-r--r--pjmedia/include/pjmedia/transport_adapter_sample.h76
-rw-r--r--pjmedia/include/pjmedia/transport_ice.h228
-rw-r--r--pjmedia/include/pjmedia/transport_loop.h82
-rw-r--r--pjmedia/include/pjmedia/transport_srtp.h317
-rw-r--r--pjmedia/include/pjmedia/transport_udp.h162
-rw-r--r--pjmedia/include/pjmedia/types.h272
-rw-r--r--pjmedia/include/pjmedia/vid_codec.h871
-rw-r--r--pjmedia/include/pjmedia/vid_codec_util.h158
-rw-r--r--pjmedia/include/pjmedia/vid_port.h243
-rw-r--r--pjmedia/include/pjmedia/vid_stream.h423
-rw-r--r--pjmedia/include/pjmedia/vid_tee.h142
-rw-r--r--pjmedia/include/pjmedia/wav_playlist.h105
-rw-r--r--pjmedia/include/pjmedia/wav_port.h250
-rw-r--r--pjmedia/include/pjmedia/wave.h184
-rw-r--r--pjmedia/include/pjmedia/wsola.h219
-rw-r--r--pjmedia/include/pjmedia_audiodev.h33
-rw-r--r--pjmedia/include/pjmedia_videodev.h31
93 files changed, 27054 insertions, 0 deletions
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev.h b/pjmedia/include/pjmedia-audiodev/audiodev.h
new file mode 100644
index 0000000..f8edb0d
--- /dev/null
+++ b/pjmedia/include/pjmedia-audiodev/audiodev.h
@@ -0,0 +1,719 @@
+/* $Id: audiodev.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_H__
+#define __PJMEDIA_AUDIODEV_AUDIODEV_H__
+
+/**
+ * @file audiodev.h
+ * @brief Audio device API.
+ */
+#include <pjmedia-audiodev/config.h>
+#include <pjmedia-audiodev/errno.h>
+#include <pjmedia/format.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup s2_audio_device_reference Audio Device API Reference
+ * @ingroup audio_device_api
+ * @brief API Reference
+ * @{
+ */
+
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_aud_dev_index;
+
+/**
+ * Device index constants.
+ */
+enum
+{
+ /**
+ * Constant to denote default capture device
+ */
+ PJMEDIA_AUD_DEFAULT_CAPTURE_DEV = -1,
+
+ /**
+ * Constant to denote default playback device
+ */
+ PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV = -2,
+
+ /**
+ * Constant to denote invalid device index.
+ */
+ PJMEDIA_AUD_INVALID_DEV = -3
+};
+
+
+/**
+ * This enumeration identifies various audio device capabilities. These audio
+ * capabilities indicates what features are supported by the underlying
+ * audio device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_aud_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the audio stream by setting the \a flags member of #pjmedia_aud_param
+ * structure.
+ *
+ * Once audio stream is running, application can also retrieve or set some
+ * specific audio capability, by using #pjmedia_aud_stream_get_cap() and
+ * #pjmedia_aud_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_aud_dev_cap
+{
+ /**
+ * Support for audio formats other than PCM. The value of this capability
+ * is represented by #pjmedia_format structure.
+ */
+ PJMEDIA_AUD_DEV_CAP_EXT_FORMAT = 1,
+
+ /**
+ * Support for audio input latency control or query. The value of this
+ * capability is an unsigned integer containing milliseconds value of
+ * the latency.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY = 2,
+
+ /**
+ * Support for audio output latency control or query. The value of this
+ * capability is an unsigned integer containing milliseconds value of
+ * the latency.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY = 4,
+
+ /**
+ * Support for setting/retrieving the audio input device volume level.
+ * The value of this capability is an unsigned integer representing
+ * the input audio volume setting in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING = 8,
+
+ /**
+ * Support for setting/retrieving the audio output device volume level.
+ * The value of this capability is an unsigned integer representing
+ * the output audio volume setting in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING = 16,
+
+ /**
+ * Support for monitoring the current audio input signal volume.
+ * The value of this capability is an unsigned integer representing
+ * the audio volume in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_SIGNAL_METER = 32,
+
+ /**
+ * Support for monitoring the current audio output signal volume.
+ * The value of this capability is an unsigned integer representing
+ * the audio volume in percent.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_SIGNAL_METER = 64,
+
+ /**
+ * Support for audio input routing. The value of this capability is an
+ * integer containing #pjmedia_aud_dev_route enumeration.
+ */
+ PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE = 128,
+
+ /**
+ * Support for audio output routing (e.g. loudspeaker vs earpiece). The
+ * value of this capability is an integer containing #pjmedia_aud_dev_route
+ * enumeration.
+ */
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE = 256,
+
+ /**
+ * The audio device has echo cancellation feature. The value of this
+ * capability is a pj_bool_t containing boolean PJ_TRUE or PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_EC = 512,
+
+ /**
+ * The audio device supports setting echo cancellation fail length. The
+ * value of this capability is an unsigned integer representing the
+ * echo tail in milliseconds.
+ */
+ PJMEDIA_AUD_DEV_CAP_EC_TAIL = 1024,
+
+ /**
+ * The audio device has voice activity detection feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_VAD = 2048,
+
+ /**
+ * The audio device has comfort noise generation feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_CNG = 4096,
+
+ /**
+ * The audio device has packet loss concealment feature. The value
+ * of this capability is a pj_bool_t containing boolean PJ_TRUE or
+ * PJ_FALSE.
+ */
+ PJMEDIA_AUD_DEV_CAP_PLC = 8192,
+
+ /**
+ * End of capability
+ */
+ PJMEDIA_AUD_DEV_CAP_MAX = 16384
+
+} pjmedia_aud_dev_cap;
+
+
+/**
+ * This enumeration describes audio routing setting.
+ */
+typedef enum pjmedia_aud_dev_route
+{
+ /** Default route. */
+ PJMEDIA_AUD_DEV_ROUTE_DEFAULT = 0,
+
+ /** Route to loudspeaker */
+ PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER = 1,
+
+ /** Route to earpiece */
+ PJMEDIA_AUD_DEV_ROUTE_EARPIECE = 2,
+
+ /** Route to paired Bluetooth device */
+ PJMEDIA_AUD_DEV_ROUTE_BLUETOOTH = 4
+
+} pjmedia_aud_dev_route;
+
+
+/**
+ * Device information structure returned by #pjmedia_aud_dev_get_info().
+ */
+typedef struct pjmedia_aud_dev_info
+{
+ /**
+ * The device name
+ */
+ char name[64];
+
+ /**
+ * Maximum number of input channels supported by this device. If the
+ * value is zero, the device does not support input operation (i.e.
+ * it is a playback only device).
+ */
+ unsigned input_count;
+
+ /**
+ * Maximum number of output channels supported by this device. If the
+ * value is zero, the device does not support output operation (i.e.
+ * it is an input only device).
+ */
+ unsigned output_count;
+
+ /**
+ * Default sampling rate.
+ */
+ unsigned default_samples_per_sec;
+
+ /**
+ * The underlying driver name
+ */
+ char driver[32];
+
+ /**
+ * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.
+ */
+ unsigned caps;
+
+ /**
+ * Supported audio device routes, as bitmask combination of
+ * #pjmedia_aud_dev_route. The value may be zero if the device
+ * does not support audio routing.
+ */
+ unsigned routes;
+
+ /**
+ * Number of audio formats supported by this device. The value may be
+ * zero if the device does not support non-PCM format.
+ */
+ unsigned ext_fmt_cnt;
+
+ /**
+ * Array of supported extended audio formats
+ */
+ pjmedia_format ext_fmt[8];
+
+
+} pjmedia_aud_dev_info;
+
+
+/**
+ * This callback is called by player stream when it needs additional data
+ * to be played by the device. Application must fill in the whole of output
+ * buffer with audio samples.
+ *
+ * The frame argument contains the following values:
+ * - timestamp Playback timestamp, in samples.
+ * - buf Buffer to be filled out by application.
+ * - size The size requested in bytes, which will be equal to
+ * the size of one whole packet.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame Audio frame, which buffer is to be filled in by
+ * the application.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the audio stream
+ * to stop
+ */
+typedef pj_status_t (*pjmedia_aud_play_cb)(void *user_data,
+ pjmedia_frame *frame);
+
+/**
+ * This callback is called by recorder stream when it has captured the whole
+ * packet worth of audio samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param frame Captured frame.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the audio stream
+ * to stop
+ */
+typedef pj_status_t (*pjmedia_aud_rec_cb)(void *user_data,
+ pjmedia_frame *frame);
+
+/**
+ * This structure specifies the parameters to open the audio stream.
+ */
+typedef struct pjmedia_aud_param
+{
+ /**
+ * The audio direction. This setting is mandatory.
+ */
+ pjmedia_dir dir;
+
+ /**
+ * The audio recorder device ID. This setting is mandatory if the audio
+ * direction includes input/capture direction.
+ */
+ pjmedia_aud_dev_index rec_id;
+
+ /**
+ * The audio playback device ID. This setting is mandatory if the audio
+ * direction includes output/playback direction.
+ */
+ pjmedia_aud_dev_index play_id;
+
+ /**
+ * Clock rate/sampling rate. This setting is mandatory.
+ */
+ unsigned clock_rate;
+
+ /**
+ * Number of channels. This setting is mandatory.
+ */
+ unsigned channel_count;
+
+ /**
+ * Number of samples per frame. This setting is mandatory.
+ */
+ unsigned samples_per_frame;
+
+ /**
+ * Number of bits per sample. This setting is mandatory.
+ */
+ unsigned bits_per_sample;
+
+ /**
+ * This flags specifies which of the optional settings are valid in this
+ * structure. The flags is bitmask combination of pjmedia_aud_dev_cap.
+ */
+ unsigned flags;
+
+ /**
+ * Set the audio format. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_EXT_FORMAT is set in the flags.
+ */
+ pjmedia_format ext_fmt;
+
+ /**
+ * Input latency, in milliseconds. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY is set in the flags.
+ */
+ unsigned input_latency_ms;
+
+ /**
+ * Input latency, in milliseconds. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY is set in the flags.
+ */
+ unsigned output_latency_ms;
+
+ /**
+ * Input volume setting, in percent. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING is set in
+ * the flags.
+ */
+ unsigned input_vol;
+
+ /**
+ * Output volume setting, in percent. This setting is optional, and will
+ * only be used if PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING is set in
+ * the flags.
+ */
+ unsigned output_vol;
+
+ /**
+ * Set the audio input route. This setting is optional, and will only be
+ * used if PJMEDIA_AUD_DEV_CAP_INPUT_ROUTE is set in the flags.
+ */
+ pjmedia_aud_dev_route input_route;
+
+ /**
+ * Set the audio output route. This setting is optional, and will only be
+ * used if PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE is set in the flags.
+ */
+ pjmedia_aud_dev_route output_route;
+
+ /**
+ * Enable/disable echo canceller, if the device supports it. This setting
+ * is optional, and will only be used if PJMEDIA_AUD_DEV_CAP_EC is set in
+ * the flags.
+ */
+ pj_bool_t ec_enabled;
+
+ /**
+ * Set echo canceller tail length in milliseconds, if the device supports
+ * it. This setting is optional, and will only be used if
+ * PJMEDIA_AUD_DEV_CAP_EC_TAIL is set in the flags.
+ */
+ unsigned ec_tail_ms;
+
+ /**
+ * Enable/disable PLC. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_PLC is set in the flags.
+ */
+ pj_bool_t plc_enabled;
+
+ /**
+ * Enable/disable CNG. This setting is optional, and will only be used
+ * if PJMEDIA_AUD_DEV_CAP_CNG is set in the flags.
+ */
+ pj_bool_t cng_enabled;
+
+} pjmedia_aud_param;
+
+
+/** Forward declaration for pjmedia_aud_stream */
+typedef struct pjmedia_aud_stream pjmedia_aud_stream;
+
+/** Forward declaration for audio device factory */
+typedef struct pjmedia_aud_dev_factory pjmedia_aud_dev_factory;
+
+/* typedef for factory creation function */
+typedef pjmedia_aud_dev_factory*
+(*pjmedia_aud_dev_factory_create_func_ptr)(pj_pool_factory*);
+
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap The capability ID.
+ * @param p_desc Optional pointer which will be filled with longer
+ * description about the capability.
+ *
+ * @return Capability name.
+ */
+PJ_DECL(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap,
+ const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_aud_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param The structure.
+ * @param cap The audio capability which value is to be set.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_set_cap(pjmedia_aud_param *param,
+ pjmedia_aud_dev_cap cap,
+ const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_aud_param structure. This
+ * function will return PJMEDIA_EAUD_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param The structure.
+ * @param cap The audio capability which value is to be retrieved.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_param_get_cap(const pjmedia_aud_param *param,
+ pjmedia_aud_dev_cap cap,
+ void *pval);
+
+/**
+ * Initialize the audio subsystem. This will register all supported audio
+ * device factories to the audio subsystem. This function may be called
+ * more than once, but each call to this function must have the
+ * corresponding #pjmedia_aud_subsys_shutdown() call.
+ *
+ * @param pf The pool factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf);
+
+
+/**
+ * Get the pool factory registered to the audio subsystem.
+ *
+ * @return The pool factory.
+ */
+PJ_DECL(pj_pool_factory*) pjmedia_aud_subsys_get_pool_factory(void);
+
+
+/**
+ * Shutdown the audio subsystem. This will destroy all audio device factories
+ * registered in the audio subsystem. Note that currently opened audio streams
+ * may or may not be closed, depending on the implementation of the audio
+ * device factories.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_subsys_shutdown(void);
+
+
+/**
+ * Register a supported audio device factory to the audio subsystem. This
+ * function can only be called after calling #pjmedia_aud_subsys_init().
+ *
+ * @param adf The audio device factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_aud_register_factory(pjmedia_aud_dev_factory_create_func_ptr adf);
+
+
+/**
+ * Unregister an audio device factory from the audio subsystem. This
+ * function can only be called after calling #pjmedia_aud_subsys_init().
+ * Devices from this factory will be unlisted. If a device from this factory
+ * is currently in use, then the behavior is undefined.
+ *
+ * @param adf The audio device factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf);
+
+
+/**
+ * Refresh the list of sound devices installed in the system. This function
+ * will only refresh the list of audio device so all active audio streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to audio devices (i.e. all variables of type
+ * pjmedia_aud_dev_index) before calling any function that accepts audio device
+ * index as its parameter.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void);
+
+
+/**
+ * Get the number of sound devices installed in the system.
+ *
+ * @return The number of sound devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_aud_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id The audio device ID.
+ * @param info The device information which will be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_get_info(pjmedia_aud_dev_index id,
+ pjmedia_aud_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name The driver name.
+ * @param dev_name The device name.
+ * @param id Pointer to store the returned device ID.
+ *
+ * @return PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_lookup(const char *drv_name,
+ const char *dev_name,
+ pjmedia_aud_dev_index *id);
+
+
+/**
+ * Initialize the audio device parameters with default values for the
+ * specified device.
+ *
+ * @param id The audio device ID.
+ * @param param The audio device parameters which will be initialized
+ * by this function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_default_param(pjmedia_aud_dev_index id,
+ pjmedia_aud_param *param);
+
+
+/**
+ * Open audio stream object using the specified parameters.
+ *
+ * @param param Sound device parameters to be used for the stream.
+ * @param rec_cb Callback to be called on every input frame captured.
+ * @param play_cb Callback to be called everytime the sound device needs
+ * audio frames to be played back.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ * @param p_strm Pointer to receive the audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_create(const pjmedia_aud_param *param,
+ pjmedia_aud_rec_cb rec_cb,
+ pjmedia_aud_play_cb play_cb,
+ void *user_data,
+ pjmedia_aud_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified audio stream.
+ *
+ * @param strm The audio stream.
+ * @param param Audio stream parameters to be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_param(pjmedia_aud_stream *strm,
+ pjmedia_aud_param *param);
+
+/**
+ * Get the value of a specific capability of the audio stream.
+ *
+ * @param strm The audio stream.
+ * @param cap The audio capability which value is to be retrieved.
+ * @param value Pointer to value to be filled in by this function
+ * once it returns successfully. Please see the type
+ * of value to be supplied in the pjmedia_aud_dev_cap
+ * documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_get_cap(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ void *value);
+
+/**
+ * Set the value of a specific capability of the audio stream.
+ *
+ * @param strm The audio stream.
+ * @param cap The audio capability which value is to be set.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_aud_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_set_cap(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_start(pjmedia_aud_stream *strm);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_stop(pjmedia_aud_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm The audio stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_stream_destroy(pjmedia_aud_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_H__ */
+
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev_imp.h b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
new file mode 100644
index 0000000..65088f5
--- /dev/null
+++ b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
@@ -0,0 +1,188 @@
+/* $Id: audiodev_imp.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __AUDIODEV_IMP_H__
+#define __AUDIODEV_IMP_H__
+
+#include <pjmedia-audiodev/audiodev.h>
+
+/**
+ * @defgroup s8_audio_device_implementors_api Audio Device Implementors API
+ * @ingroup audio_device_api
+ * @brief API for audio device implementors
+ * @{
+ */
+
+/**
+ * Sound device factory operations.
+ */
+typedef struct pjmedia_aud_dev_factory_op
+{
+ /**
+ * Initialize the audio device factory.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*init)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Close this audio device factory and release all resources back to the
+ * operating system.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*destroy)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Get the number of audio devices installed in the system.
+ *
+ * @param f The audio device factory.
+ */
+ unsigned (*get_dev_count)(pjmedia_aud_dev_factory *f);
+
+ /**
+ * Get the audio device information and capabilities.
+ *
+ * @param f The audio device factory.
+ * @param index Device index.
+ * @param info The audio device information structure which will be
+ * initialized by this function once it returns
+ * successfully.
+ */
+ pj_status_t (*get_dev_info)(pjmedia_aud_dev_factory *f,
+ unsigned index,
+ pjmedia_aud_dev_info *info);
+
+ /**
+ * Initialize the specified audio device parameter with the default
+ * values for the specified device.
+ *
+ * @param f The audio device factory.
+ * @param index Device index.
+ * @param param The audio device parameter.
+ */
+ pj_status_t (*default_param)(pjmedia_aud_dev_factory *f,
+ unsigned index,
+ pjmedia_aud_param *param);
+
+ /**
+ * Open the audio device and create audio stream. See
+ * #pjmedia_aud_stream_create()
+ */
+ pj_status_t (*create_stream)(pjmedia_aud_dev_factory *f,
+ const pjmedia_aud_param *param,
+ pjmedia_aud_rec_cb rec_cb,
+ pjmedia_aud_play_cb play_cb,
+ void *user_data,
+ pjmedia_aud_stream **p_aud_strm);
+
+ /**
+ * Refresh the list of audio devices installed in the system.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*refresh)(pjmedia_aud_dev_factory *f);
+
+} pjmedia_aud_dev_factory_op;
+
+
+/**
+ * This structure describes an audio device factory.
+ */
+struct pjmedia_aud_dev_factory
+{
+ /** Internal data to be initialized by audio subsystem. */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_aud_dev_factory_op *op;
+};
+
+
+/**
+ * Sound stream operations.
+ */
+typedef struct pjmedia_aud_stream_op
+{
+ /**
+ * See #pjmedia_aud_stream_get_param()
+ */
+ pj_status_t (*get_param)(pjmedia_aud_stream *strm,
+ pjmedia_aud_param *param);
+
+ /**
+ * See #pjmedia_aud_stream_get_cap()
+ */
+ pj_status_t (*get_cap)(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ void *value);
+
+ /**
+ * See #pjmedia_aud_stream_set_cap()
+ */
+ pj_status_t (*set_cap)(pjmedia_aud_stream *strm,
+ pjmedia_aud_dev_cap cap,
+ const void *value);
+
+ /**
+ * See #pjmedia_aud_stream_start()
+ */
+ pj_status_t (*start)(pjmedia_aud_stream *strm);
+
+ /**
+ * See #pjmedia_aud_stream_stop().
+ */
+ pj_status_t (*stop)(pjmedia_aud_stream *strm);
+
+ /**
+ * See #pjmedia_aud_stream_destroy().
+ */
+ pj_status_t (*destroy)(pjmedia_aud_stream *strm);
+
+} pjmedia_aud_stream_op;
+
+
+/**
+ * This structure describes the audio device stream.
+ */
+struct pjmedia_aud_stream
+{
+ /** Internal data to be initialized by audio subsystem */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_aud_stream_op *op;
+};
+
+
+
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __AUDIODEV_IMP_H__ */
diff --git a/pjmedia/include/pjmedia-audiodev/audiotest.h b/pjmedia/include/pjmedia-audiodev/audiotest.h
new file mode 100644
index 0000000..97b5798
--- /dev/null
+++ b/pjmedia/include/pjmedia-audiodev/audiotest.h
@@ -0,0 +1,116 @@
+/* $Id: audiotest.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AUDIODEV_AUDIOTEST_H__
+#define __PJMEDIA_AUDIODEV_AUDIOTEST_H__
+
+/**
+ * @file audiotest.h
+ * @brief Audio test utility.
+ */
+#include <pjmedia-audiodev/audiodev.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup s30_audio_test_utility Audio tests utility.
+ * @ingroup audio_device_api
+ * @brief Audio test utility.
+ * @{
+ */
+
+/**
+ * Statistic for each direction.
+ */
+typedef struct pjmedia_aud_test_stat
+{
+ /**
+ * Number of frames processed during the test.
+ */
+ unsigned frame_cnt;
+
+ /**
+ * Minimum inter-frame arrival time, in milliseconds
+ */
+ unsigned min_interval;
+
+ /**
+ * Maximum inter-frame arrival time, in milliseconds
+ */
+ unsigned max_interval;
+
+ /**
+ * Average inter-frame arrival time, in milliseconds
+ */
+ unsigned avg_interval;
+
+ /**
+ * Standard deviation of inter-frame arrival time, in milliseconds
+ */
+ unsigned dev_interval;
+
+ /**
+ * Maximum number of frame burst
+ */
+ unsigned max_burst;
+
+} pjmedia_aud_test_stat;
+
+
+/**
+ * Test results.
+ */
+typedef struct pjmedia_aud_test_results
+{
+ /**
+ * Recording statistic.
+ */
+ pjmedia_aud_test_stat rec;
+
+ /**
+ * Playback statistic.
+ */
+ pjmedia_aud_test_stat play;
+
+ /**
+ * Clock drifts per second, in samples. Positive number indicates rec
+ * device is running faster than playback device.
+ */
+ pj_int32_t rec_drift_per_sec;
+
+} pjmedia_aud_test_results;
+
+
+/**
+ * Perform audio device testing.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_test(const pjmedia_aud_param *param,
+ pjmedia_aud_test_results *result);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIOTEST_H__ */
+
+
diff --git a/pjmedia/include/pjmedia-audiodev/config.h b/pjmedia/include/pjmedia-audiodev/config.h
new file mode 100644
index 0000000..e2884a9
--- /dev/null
+++ b/pjmedia/include/pjmedia-audiodev/config.h
@@ -0,0 +1,459 @@
+/* $Id: config.h 4150 2012-06-01 04:29:56Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AUDIODEV_CONFIG_H__
+#define __PJMEDIA_AUDIODEV_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief Audio config.
+ */
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup audio_device_api Audio Device API
+ * @brief PJMEDIA audio device abstraction API.
+ */
+
+/**
+ * @defgroup s1_audio_device_config Compile time configurations
+ * @ingroup audio_device_api
+ * @brief Compile time configurations
+ * @{
+ */
+
+/**
+ * This setting controls whether PortAudio support should be included.
+ *
+ * By default it is enabled except on Windows platforms (including
+ * Windows Mobile) and Symbian.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
+# if (defined(PJ_WIN32) && PJ_WIN32!=0) || \
+ (defined(PJ_SYMBIAN) && PJ_SYMBIAN!=0)
+# define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
+# else
+# define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 1
+# endif
+#endif
+
+/**
+ * This setting controls whether BlackBerry 10 (BB10) audio support
+ * should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_BB10
+# define PJMEDIA_AUDIO_DEV_HAS_BB10 0
+#endif
+
+/**
+ * This setting controls whether native ALSA support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_ALSA
+# define PJMEDIA_AUDIO_DEV_HAS_ALSA 0
+#endif
+
+
+/**
+ * This setting controls whether null audio support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO
+# define PJMEDIA_AUDIO_DEV_HAS_NULL_AUDIO 0
+#endif
+
+
+/**
+ * This setting controls whether coreaudio support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
+# define PJMEDIA_AUDIO_DEV_HAS_COREAUDIO 0
+#endif
+
+
+/**
+ * This setting controls whether WMME support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_WMME
+# define PJMEDIA_AUDIO_DEV_HAS_WMME 1
+#endif
+
+
+/**
+ * This setting controls whether Symbian APS support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_APS
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0
+#endif
+
+
+/**
+ * This setting controls whether Symbian APS should perform codec
+ * detection in its factory initalization. Note that codec detection
+ * may take few seconds and detecting more codecs will take more time.
+ * Possible values are:
+ * - 0: no codec detection, all APS codec (AMR-NB, G.711, G.729, and
+ * iLBC) will be assumed as supported.
+ * - 1: minimal codec detection, i.e: only detect for AMR-NB and G.711,
+ * (G.729 and iLBC are considered to be supported/unsupported when
+ * G.711 is supported/unsupported).
+ * - 2: full codec detection, i.e: detect AMR-NB, G.711, G.729, and iLBC.
+ *
+ * Default: 1 (minimal codec detection)
+ */
+#ifndef PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC
+# define PJMEDIA_AUDIO_DEV_SYMB_APS_DETECTS_CODEC 1
+#endif
+
+
+/**
+ * This setting controls whether Symbian VAS support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 0
+#endif
+
+/**
+ * This setting controls Symbian VAS version to be used. Currently, valid
+ * values are only 1 (for VAS 1.0) and 2 (for VAS 2.0).
+ *
+ * Default: 1 (VAS version 1.0)
+ */
+#ifndef PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION
+# define PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION 1
+#endif
+
+
+/**
+ * This setting controls whether Symbian audio (using built-in multimedia
+ * framework) support should be included.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA
+# define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA PJ_SYMBIAN
+#endif
+
+
+/**
+ * This setting controls whether the Symbian audio with built-in multimedia
+ * framework backend should be started synchronously. Note that synchronous
+ * start will block the application/UI, e.g: about 40ms for each direction
+ * on N95. While asynchronous start may cause invalid value (always zero)
+ * returned in input/output volume query, if the query is performed when
+ * the internal start procedure is not completely finished.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START
+# define PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START 1
+#endif
+
+
+/**
+ * This setting controls whether the Audio Device API should support
+ * device implementation that is based on the old sound device API
+ * (sound.h).
+ *
+ * Enable this API if:
+ * - you have implemented your own sound device using the old sound
+ * device API (sound.h), and
+ * - you wish to be able to use your sound device implementation
+ * using the new Audio Device API.
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * info.
+ */
+#ifndef PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE
+# define PJMEDIA_AUDIO_DEV_HAS_LEGACY_DEVICE 0
+#endif
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AUDIODEV_CONFIG_H__ */
+
+/*
+ --------------------- DOCUMENTATION FOLLOWS ---------------------------
+ */
+
+/**
+ * @addtogroup audio_device_api Audio Device API
+ * @{
+
+PJMEDIA Audio Device API is a cross-platform audio API appropriate for use with
+VoIP applications and many other types of audio streaming applications.
+
+The API abstracts many different audio API's on various platforms, such as:
+ - PortAudio back-end for Win32, Windows Mobile, Linux, Unix, dan MacOS X.
+ - native WMME audio for Win32 and Windows Mobile devices
+ - native Symbian audio streaming/multimedia framework (MMF) implementation
+ - native Nokia Audio Proxy Server (APS) implementation
+ - null-audio implementation
+ - and more to be implemented in the future
+
+The Audio Device API/library is an evolution from PJMEDIA @ref PJMED_SND and
+contains many enhancements:
+
+ - Forward compatibility:
+\n
+ The new API has been designed to be extensible, it will support new API's as
+ well as new features that may be introduced in the future without breaking
+ compatibility with applications that use this API as well as compatibility
+ with existing device implementations.
+
+ - Device capabilities:
+\n
+ At the heart of the API is device capabilities management, where all possible
+ audio capabilities of audio devices should be able to be handled in a generic
+ manner. With this framework, new capabilities that may be discovered in the
+ future can be handled in manner without breaking existing applications.
+
+ - Built-in features:
+\n
+ The device capabilities framework enables applications to use and control
+ audio features built-in in the device, such as:
+ - echo cancellation,
+ - built-in codecs,
+ - audio routing (e.g. to earpiece or loudspeaker),
+ - volume control,
+ - etc.
+
+ - Codec support:
+\n
+ Some audio devices such as Nokia/Symbian Audio Proxy Server (APS) and Nokia
+ VoIP Audio Services (VAS) support built-in hardware audio codecs (e.g. G.729,
+ iLBC, and AMR), and application can use the sound device in encoded mode to
+ make use of these hardware codecs.
+
+ - Multiple backends:
+\n
+ The new API supports multiple audio backends (called factories or drivers in
+ the code) to be active simultaneously, and audio backends may be added or
+ removed during run-time.
+
+
+@section using Overview on using the API
+
+@subsection getting_started Getting started
+
+ -# <b>Configure the application's project settings</b>.\n
+ Add the following
+ include:
+ \code
+ #include <pjmedia_audiodev.h>\endcode\n
+ And add <b>pjmedia-audiodev</b> library to your application link
+ specifications.\n
+ -# <b>Compile time settings</b>.\n
+ Use the compile time settings to enable or
+ disable specific audio drivers. For more information, please see
+ \ref s1_audio_device_config.
+ -# <b>API initialization and cleaning up</b>.\n
+ Before anything else, application must initialize the API by calling:
+ \code
+ pjmedia_aud_subsys_init(pf);\endcode\n
+ And add this in the application cleanup sequence
+ \code
+ pjmedia_aud_subsys_shutdown();\endcode
+
+@subsection devices Working with devices
+
+ -# The following code prints the list of audio devices detected
+ in the system.
+ \code
+ int dev_count;
+ pjmedia_aud_dev_index dev_idx;
+ pj_status_t status;
+
+ dev_count = pjmedia_aud_dev_count();
+ printf("Got %d audio devices\n", dev_count);
+
+ for (dev_idx=0; dev_idx<dev_count; ++i) {
+ pjmedia_aud_dev_info info;
+
+ status = pjmedia_aud_dev_get_info(dev_idx, &info);
+ printf("%d. %s (in=%d, out=%d)\n",
+ dev_idx, info.name,
+ info.input_count, info.output_count);
+ }
+ \endcode\n
+ -# Info: The #PJMEDIA_AUD_DEFAULT_CAPTURE_DEV and #PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV
+ constants are used to denote default capture and playback devices
+ respectively.
+ -# Info: You may save the device and driver's name in your application
+ setting, for example to specify the prefered devices to be
+ used by your application. You can then retrieve the device index
+ for the device by calling:
+ \code
+ const char *drv_name = "WMME";
+ const char *dev_name = "Wave mapper";
+ pjmedia_aud_dev_index dev_idx;
+
+ status = pjmedia_aud_dev_lookup(drv_name, dev_name, &dev_idx);
+ if (status==PJ_SUCCESS)
+ printf("Device index is %d\n", dev_idx);
+ \endcode
+
+@subsection caps Device capabilities
+
+Capabilities are encoded as #pjmedia_aud_dev_cap enumeration. Please see
+#pjmedia_aud_dev_cap enumeration for more information.
+
+ -# The following snippet prints the capabilities supported by the device:
+ \code
+ pjmedia_aud_dev_info info;
+ pj_status_t status;
+
+ status = pjmedia_aud_dev_get_info(PJMEDIA_AUD_DEFAULT_CAPTURE_DEV, &info);
+ if (status == PJ_SUCCESS) {
+ unsigned i;
+ // Enumerate capability bits
+ printf("Device capabilities: ");
+ for (i=0; i<32; ++i) {
+ if (info.caps & (1 << i))
+ printf("%s ", pjmedia_aud_dev_cap_name(1 << i, NULL));
+ }
+ }
+ \endcode\n
+ -# Info: You can set the device settings when opening audio stream by setting
+ the flags and the appropriate setting in #pjmedia_aud_param when calling
+ #pjmedia_aud_stream_create()\n
+ -# Info: Once the audio stream is running, you can retrieve or change the stream
+ setting by specifying the capability in #pjmedia_aud_stream_get_cap()
+ and #pjmedia_aud_stream_set_cap() respectively.
+
+
+@subsection creating_stream Creating audio streams
+
+The audio stream enables audio streaming to capture device, playback device,
+or both.
+
+ -# It is recommended to initialize the #pjmedia_aud_param with its default
+ values before using it:
+ \code
+ pjmedia_aud_param param;
+ pjmedia_aud_dev_index dev_idx;
+ pj_status_t status;
+
+ dev_idx = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+ status = pjmedia_aud_dev_default_param(dev_idx, &param);
+ \endcode\n
+ -# Configure the mandatory parameters:
+ \code
+ param.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+ param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+ param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+ param.clock_rate = 8000;
+ param.channel_count = 1;
+ param.samples_per_frame = 160;
+ param.bits_per_sample = 16;
+ \endcode\n
+ -# If you want the audio stream to use the device's built-in codec, specify
+ the codec in the #pjmedia_aud_param. You must make sure that the codec
+ is supported by the device, by looking at its supported format list in
+ the #pjmedia_aud_dev_info.\n
+ The snippet below sets the audio stream to use G.711 ULAW encoding:
+ \code
+ unsigned i;
+
+ // Make sure Ulaw is supported
+ if ((info.caps & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) == 0)
+ error("Device does not support extended formats");
+ for (i = 0; i < info.ext_fmt_cnt; ++i) {
+ if (info.ext_fmt[i].id == PJMEDIA_FORMAT_ULAW)
+ break;
+ }
+ if (i == info.ext_fmt_cnt)
+ error("Device does not support Ulaw format");
+
+ // Set Ulaw format
+ param.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
+ param.ext_fmt.id = PJMEDIA_FORMAT_ULAW;
+ param.ext_fmt.bitrate = 64000;
+ param.ext_fmt.vad = PJ_FALSE;
+ \endcode\n
+ -# Note that if non-PCM format is configured on the audio stream, the
+ capture and/or playback functions (#pjmedia_aud_rec_cb and
+ #pjmedia_aud_play_cb respectively) will report the audio frame as
+ #pjmedia_frame_ext structure instead of the #pjmedia_frame.
+ -# Optionally configure other device's capabilities. The following snippet
+ shows how to enable echo cancellation on the device (note that this
+ snippet may not be necessary since the setting may have been enabled
+ when calling #pjmedia_aud_dev_default_param() above):
+ \code
+ if (info.caps & PJMEDIA_AUD_DEV_CAP_EC) {
+ param.flags |= PJMEDIA_AUD_DEV_CAP_EC;
+ param.ec_enabled = PJ_TRUE;
+ }
+ \endcode
+ -# Open the audio stream, specifying the capture and/or playback callback
+ functions:
+ \code
+ pjmedia_aud_stream *stream;
+
+ status = pjmedia_aud_stream_create(&param, &rec_cb, &play_cb,
+ user_data, &stream);
+ \endcode
+
+@subsection working_with_stream Working with audio streams
+
+ -# To start the audio stream:
+ \code
+ status = pjmedia_aud_stream_start(stream);
+ \endcode\n
+ To stop the stream:
+ \code
+ status = pjmedia_aud_stream_stop(stream);
+ \endcode\n
+ And to destroy the stream:
+ \code
+ status = pjmedia_aud_stream_destroy(stream);
+ \endcode\n
+ -# Info: The following shows how to retrieve the capability value of the
+ stream (in this case, the current output volume setting).
+ \code
+ // Volume setting is an unsigned integer showing the level in percent.
+ unsigned vol;
+ status = pjmedia_aud_stream_get_cap(stream,
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+ &vol);
+ \endcode
+ -# Info: And following shows how to modify the capability value of the
+ stream (in this case, the current output volume setting).
+ \code
+ // Volume setting is an unsigned integer showing the level in percent.
+ unsigned vol = 50;
+ status = pjmedia_aud_stream_set_cap(stream,
+ PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
+ &vol);
+ \endcode
+
+
+*/
+
+
+/**
+ * @}
+ */
+
diff --git a/pjmedia/include/pjmedia-audiodev/errno.h b/pjmedia/include/pjmedia-audiodev/errno.h
new file mode 100644
index 0000000..df60748
--- /dev/null
+++ b/pjmedia/include/pjmedia-audiodev/errno.h
@@ -0,0 +1,212 @@
+/* $Id: errno.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__
+#define __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief Audiodev specific error codes.
+ */
+
+#include <pjmedia-audiodev/config.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup error_codes Error Codes
+ * @ingroup audio_device_api
+ * @brief Audio devive library specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 420000.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_START \
+ (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*5)
+#define PJMEDIA_AUDIODEV_ERRNO_END \
+ (PJMEDIA_AUDIODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/**
+ * Mapping from PortAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START \
+ (PJMEDIA_AUDIODEV_ERRNO_END-10000)
+#define PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END \
+ (PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START + 10000 -1)
+/**
+ * Convert PortAudio error code to PJLIB error code.
+ * PortAudio error code range: 0 >= err >= -10000
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err) \
+ ((int)PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START-err)
+
+/**
+ * Mapping from Windows multimedia WaveIn error codes.
+ */
+#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_START \
+ (PJMEDIA_AUDIODEV_ERRNO_START + 30000)
+#define PJMEDIA_AUDIODEV_WMME_IN_ERROR_END \
+ (PJMEDIA_AUDIODEV_WMME_IN_ERROR_START + 1000 - 1)
+/**
+ * Convert WaveIn operation error codes to PJLIB error space.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_IN(err) \
+ ((int)PJMEDIA_AUDIODEV_WMME_IN_ERROR_START+err)
+
+
+/**
+ * Mapping from Windows multimedia WaveOut error codes.
+ */
+#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START \
+ (PJMEDIA_AUDIODEV_WMME_IN_ERROR_END + 1000)
+#define PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END \
+ (PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START + 1000)
+/**
+ * Convert WaveOut operation error codes to PJLIB error space.
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_WMME_OUT(err) \
+ ((int)PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START+err)
+
+
+/**
+ * Mapping from CoreAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START \
+ (PJMEDIA_AUDIODEV_ERRNO_START+20000)
+#define PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_END \
+ (PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START + 20000 -1)
+/**
+ * Convert CoreAudio error code to PJLIB error code.
+ * CoreAudio error code range: 0 >= err >= -10000
+ */
+#define PJMEDIA_AUDIODEV_ERRNO_FROM_COREAUDIO(err) \
+ ((int)PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START-err)
+
+/************************************************************
+ * Audio Device API error codes
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown error.
+ */
+#define PJMEDIA_EAUD_ERR (PJMEDIA_AUDIODEV_ERRNO_START+1) /* 420001 */
+
+/**
+ * @hideinitializer
+ * Unknown error from audio driver
+ */
+#define PJMEDIA_EAUD_SYSERR (PJMEDIA_AUDIODEV_ERRNO_START+2) /* 420002 */
+
+/**
+ * @hideinitializer
+ * Audio subsystem not initialized
+ */
+#define PJMEDIA_EAUD_INIT (PJMEDIA_AUDIODEV_ERRNO_START+3) /* 420003 */
+
+/**
+ * @hideinitializer
+ * Invalid audio device
+ */
+#define PJMEDIA_EAUD_INVDEV (PJMEDIA_AUDIODEV_ERRNO_START+4) /* 420004 */
+
+/**
+ * @hideinitializer
+ * Found no devices
+ */
+#define PJMEDIA_EAUD_NODEV (PJMEDIA_AUDIODEV_ERRNO_START+5) /* 420005 */
+
+/**
+ * @hideinitializer
+ * Unable to find default device
+ */
+#define PJMEDIA_EAUD_NODEFDEV (PJMEDIA_AUDIODEV_ERRNO_START+6) /* 420006 */
+
+/**
+ * @hideinitializer
+ * Device not ready
+ */
+#define PJMEDIA_EAUD_NOTREADY (PJMEDIA_AUDIODEV_ERRNO_START+7) /* 420007 */
+
+/**
+ * @hideinitializer
+ * The audio capability is invalid or not supported
+ */
+#define PJMEDIA_EAUD_INVCAP (PJMEDIA_AUDIODEV_ERRNO_START+8) /* 420008 */
+
+/**
+ * @hideinitializer
+ * The operation is invalid or not supported
+ */
+#define PJMEDIA_EAUD_INVOP (PJMEDIA_AUDIODEV_ERRNO_START+9) /* 420009 */
+
+/**
+ * @hideinitializer
+ * Bad or invalid audio device format
+ */
+#define PJMEDIA_EAUD_BADFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+10) /* 4200010 */
+
+/**
+ * @hideinitializer
+ * Invalid audio device sample format
+ */
+#define PJMEDIA_EAUD_SAMPFORMAT (PJMEDIA_AUDIODEV_ERRNO_START+11) /* 4200011 */
+
+/**
+ * @hideinitializer
+ * Bad latency setting
+ */
+#define PJMEDIA_EAUD_BADLATENCY (PJMEDIA_AUDIODEV_ERRNO_START+12) /* 4200012 */
+
+
+
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA Audiodev specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_audiodev_strerror(pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AUDIODEV_AUDIODEV_ERRNO_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec.h b/pjmedia/include/pjmedia-codec.h
new file mode 100644
index 0000000..c666996
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec.h
@@ -0,0 +1,42 @@
+/* $Id: pjmedia-codec.h 4049 2012-04-13 06:24:23Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_PJMEDIA_CODEC_H__
+#define __PJMEDIA_CODEC_PJMEDIA_CODEC_H__
+
+/**
+ * @file pjmedia-codec.h
+ * @brief Include all codecs API in PJMEDIA-CODEC
+ */
+
+#include <pjmedia-codec/audio_codecs.h>
+#include <pjmedia-codec/l16.h>
+#include <pjmedia-codec/ffmpeg_vid_codecs.h>
+#include <pjmedia-codec/gsm.h>
+#include <pjmedia-codec/speex.h>
+#include <pjmedia-codec/ilbc.h>
+#include <pjmedia-codec/g722.h>
+#include <pjmedia-codec/g7221.h>
+#include <pjmedia-codec/ipp_codecs.h>
+#include <pjmedia-codec/passthrough.h>
+#include <pjmedia-codec/opencore_amrnb.h>
+
+
+#endif /* __PJMEDIA_CODEC_PJMEDIA_CODEC_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/amr_helper.h b/pjmedia/include/pjmedia-codec/amr_helper.h
new file mode 100644
index 0000000..dc1f6e7
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/amr_helper.h
@@ -0,0 +1,1228 @@
+/* $Id: amr_helper.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJMEDIA_CODECS_AMR_HELPER_H__
+#define __PJMEDIA_CODECS_AMR_HELPER_H__
+
+/**
+ * @file pjmedia-codec/amr_helper.h
+ * @brief Common tables and helper functions for AMR codec (NB & WB).
+ */
+
+
+#ifdef _MSC_VER
+# pragma warning(disable:4214) // bit field types other than int
+#endif
+
+/**
+ * @defgroup PJMED_AMR_CODEC_HELPER AMR Codec Helper
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief AMR common tables and helper functions.
+ * @{
+ *
+ * This sections describes common AMR constants tables (e.g: bits sensitivity
+ * order map, frame lengths, bitrates) and helper functions (e.g: pack AMR
+ * payload in octet-aligned mode or bandwidth-efficient mode, payload parser,
+ * reorder AMR bitstream).
+ */
+
+PJ_BEGIN_DECL
+
+
+/* AMR bits sensitivity order maps */
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap122[244] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
+ 19, 20, 21, 22, 24, 25, 26, 27, 28, 38,
+ 141, 39, 142, 40, 143, 41, 144, 42, 145, 43,
+ 146, 44, 147, 45, 148, 46, 149, 47, 97, 150,
+ 200, 48, 98, 151, 201, 49, 99, 152, 202, 86,
+ 136, 189, 239, 87, 137, 190, 240, 88, 138, 191,
+ 241, 91, 194, 92, 195, 93, 196, 94, 197, 95,
+ 198, 29, 30, 31, 32, 33, 34, 35, 50, 100,
+ 153, 203, 89, 139, 192, 242, 51, 101, 154, 204,
+ 55, 105, 158, 208, 90, 140, 193, 243, 59, 109,
+ 162, 212, 63, 113, 166, 216, 67, 117, 170, 220,
+ 36, 37, 54, 53, 52, 58, 57, 56, 62, 61,
+ 60, 66, 65, 64, 70, 69, 68, 104, 103, 102,
+ 108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
+ 119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
+ 163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
+ 211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
+ 222, 221, 73, 72, 71, 76, 75, 74, 79, 78,
+ 77, 82, 81, 80, 85, 84, 83, 123, 122, 121,
+ 126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
+ 134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
+ 180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
+ 229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
+ 237, 236, 96, 199
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap102[204] =
+{
+ 7, 6, 5, 4, 3, 2, 1, 0, 16, 15,
+ 14, 13, 12, 11, 10, 9, 8, 26, 27, 28,
+ 29, 30, 31, 115, 116, 117, 118, 119, 120, 72,
+ 73, 161, 162, 65, 68, 69, 108, 111, 112, 154,
+ 157, 158, 197, 200, 201, 32, 33, 121, 122, 74,
+ 75, 163, 164, 66, 109, 155, 198, 19, 23, 21,
+ 22, 18, 17, 20, 24, 25, 37, 36, 35, 34,
+ 80, 79, 78, 77, 126, 125, 124, 123, 169, 168,
+ 167, 166, 70, 67, 71, 113, 110, 114, 159, 156,
+ 160, 202, 199, 203, 76, 165, 81, 82, 92, 91,
+ 93, 83, 95, 85, 84, 94, 101, 102, 96, 104,
+ 86, 103, 87, 97, 127, 128, 138, 137, 139, 129,
+ 141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
+ 133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
+ 173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
+ 38, 39, 49, 48, 50, 40, 52, 42, 41, 51,
+ 58, 59, 53, 61, 43, 60, 44, 54, 194, 179,
+ 189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
+ 153, 134, 152, 135, 144, 145, 105, 90, 100, 107,
+ 88, 106, 89, 98, 99, 62, 47, 57, 64, 45,
+ 63, 46, 55, 56
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap795[159] =
+{
+ 8, 7, 6, 5, 4, 3, 2, 14, 16, 9,
+ 10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
+ 19, 18, 21, 56, 88, 122, 154, 57, 89, 123,
+ 155, 58, 90, 124, 156, 52, 84, 118, 150, 53,
+ 85, 119, 151, 27, 93, 28, 94, 29, 95, 30,
+ 96, 31, 97, 61, 127, 62, 128, 63, 129, 59,
+ 91, 125, 157, 32, 98, 64, 130, 1, 0, 25,
+ 26, 33, 99, 34, 100, 65, 131, 66, 132, 54,
+ 86, 120, 152, 60, 92, 126, 158, 55, 87, 121,
+ 153, 117, 116, 115, 46, 78, 112, 144, 43, 75,
+ 109, 141, 40, 72, 106, 138, 36, 68, 102, 134,
+ 114, 149, 148, 147, 146, 83, 82, 81, 80, 51,
+ 50, 49, 48, 47, 45, 44, 42, 39, 35, 79,
+ 77, 76, 74, 71, 67, 113, 111, 110, 108, 105,
+ 101, 145, 143, 142, 140, 137, 133, 41, 73, 107,
+ 139, 37, 69, 103, 135, 38, 70, 104, 136
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap74[148] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
+ 88, 28, 89, 29, 90, 30, 91, 51, 80, 112,
+ 141, 52, 81, 113, 142, 54, 83, 115, 144, 55,
+ 84, 116, 145, 58, 119, 59, 120, 21, 22, 23,
+ 17, 18, 19, 31, 60, 92, 121, 56, 85, 117,
+ 146, 20, 24, 25, 50, 79, 111, 140, 57, 86,
+ 118, 147, 49, 78, 110, 139, 48, 77, 53, 82,
+ 114, 143, 109, 138, 47, 76, 108, 137, 32, 33,
+ 61, 62, 93, 94, 122, 123, 41, 42, 43, 44,
+ 45, 46, 70, 71, 72, 73, 74, 75, 102, 103,
+ 104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
+ 34, 63, 95, 124, 35, 64, 96, 125, 36, 65,
+ 97, 126, 37, 66, 98, 127, 38, 67, 99, 128,
+ 39, 68, 100, 129, 40, 69, 101, 130
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap67[134] =
+{
+ 0, 1, 4, 3, 5, 6, 13, 7, 2, 8,
+ 9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
+ 27, 81, 26, 80, 30, 84, 16, 55, 109, 56,
+ 110, 31, 85, 57, 111, 48, 73, 102, 127, 32,
+ 86, 51, 76, 105, 130, 52, 77, 106, 131, 58,
+ 112, 33, 87, 19, 23, 53, 78, 107, 132, 21,
+ 22, 18, 17, 20, 24, 25, 50, 75, 104, 129,
+ 47, 72, 101, 126, 54, 79, 108, 133, 46, 71,
+ 100, 125, 128, 103, 74, 49, 45, 70, 99, 124,
+ 42, 67, 96, 121, 39, 64, 93, 118, 38, 63,
+ 92, 117, 35, 60, 89, 114, 34, 59, 88, 113,
+ 44, 69, 98, 123, 43, 68, 97, 122, 41, 66,
+ 95, 120, 40, 65, 94, 119, 37, 62, 91, 116,
+ 36, 61, 90, 115
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap59[118] =
+{
+ 0, 1, 4, 5, 3, 6, 7, 2, 13, 15,
+ 8, 9, 11, 12, 14, 10, 16, 28, 74, 29,
+ 75, 27, 73, 26, 72, 30, 76, 51, 97, 50,
+ 71, 96, 117, 31, 77, 52, 98, 49, 70, 95,
+ 116, 53, 99, 32, 78, 33, 79, 48, 69, 94,
+ 115, 47, 68, 93, 114, 46, 67, 92, 113, 19,
+ 21, 23, 22, 18, 17, 20, 24, 111, 43, 89,
+ 110, 64, 65, 44, 90, 25, 45, 66, 91, 112,
+ 54, 100, 40, 61, 86, 107, 39, 60, 85, 106,
+ 36, 57, 82, 103, 35, 56, 81, 102, 34, 55,
+ 80, 101, 42, 63, 88, 109, 41, 62, 87, 108,
+ 38, 59, 84, 105, 37, 58, 83, 104
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap515[103] =
+{
+ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
+ 13, 12, 11, 10, 9, 8, 23, 24, 25, 26,
+ 27, 46, 65, 84, 45, 44, 43, 64, 63, 62,
+ 83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
+ 28, 47, 66, 85, 18, 41, 60, 79, 98, 29,
+ 48, 67, 17, 20, 22, 40, 59, 78, 97, 21,
+ 30, 49, 68, 86, 19, 16, 87, 39, 38, 58,
+ 57, 77, 35, 54, 73, 92, 76, 96, 95, 36,
+ 55, 74, 93, 32, 51, 33, 52, 70, 71, 89,
+ 90, 31, 50, 69, 88, 37, 56, 75, 94, 34,
+ 53, 72, 91
+};
+
+const pj_int16_t pjmedia_codec_amrnb_ordermap475[95] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
+ 27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
+ 45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
+ 77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
+ 38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
+ 64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
+ 36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
+ 88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
+ 92, 31, 52, 65, 86
+};
+
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_660[] =
+{
+ 0, 5, 6, 7, 61, 84, 107, 130, 62, 85,
+ 8, 4, 37, 38, 39, 40, 58, 81, 104, 127,
+ 60, 83, 106, 129, 108, 131, 128, 41, 42, 80,
+ 126, 1, 3, 57, 103, 82, 105, 59, 2, 63,
+ 109, 110, 86, 19, 22, 23, 64, 87, 18, 20,
+ 21, 17, 13, 88, 43, 89, 65, 111, 14, 24,
+ 25, 26, 27, 28, 15, 16, 44, 90, 66, 112,
+ 9, 11, 10, 12, 67, 113, 29, 30, 31, 32,
+ 34, 33, 35, 36, 45, 51, 68, 74, 91, 97,
+ 114, 120, 46, 69, 92, 115, 52, 75, 98, 121,
+ 47, 70, 93, 116, 53, 76, 99, 122, 48, 71,
+ 94, 117, 54, 77, 100, 123, 49, 72, 95, 118,
+ 55, 78, 101, 124, 50, 73, 96, 119, 56, 79,
+ 102, 125
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_885[] =
+{
+ 0, 4, 6, 7, 5, 3, 47, 48, 49, 112,
+ 113, 114, 75, 106, 140, 171, 80, 111, 145, 176,
+ 77, 108, 142, 173, 78, 109, 143, 174, 79, 110,
+ 144, 175, 76, 107, 141, 172, 50, 115, 51, 2,
+ 1, 81, 116, 146, 19, 21, 12, 17, 18, 20,
+ 16, 25, 13, 10, 14, 24, 23, 22, 26, 8,
+ 15, 52, 117, 31, 82, 147, 9, 33, 11, 83,
+ 148, 53, 118, 28, 27, 84, 149, 34, 35, 29,
+ 46, 32, 30, 54, 119, 37, 36, 39, 38, 40,
+ 85, 150, 41, 42, 43, 44, 45, 55, 60, 65,
+ 70, 86, 91, 96, 101, 120, 125, 130, 135, 151,
+ 156, 161, 166, 56, 87, 121, 152, 61, 92, 126,
+ 157, 66, 97, 131, 162, 71, 102, 136, 167, 57,
+ 88, 122, 153, 62, 93, 127, 158, 67, 98, 132,
+ 163, 72, 103, 137, 168, 58, 89, 123, 154, 63,
+ 94, 128, 159, 68, 99, 133, 164, 73, 104, 138,
+ 169, 59, 90, 124, 155, 64, 95, 129, 160, 69,
+ 100, 134, 165, 74, 105, 139, 170
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1265[] =
+{
+ 0, 4, 6, 93, 143, 196, 246, 7, 5, 3,
+ 47, 48, 49, 50, 51, 150, 151, 152, 153, 154,
+ 94, 144, 197, 247, 99, 149, 202, 252, 96, 146,
+ 199, 249, 97, 147, 200, 250, 100, 203, 98, 148,
+ 201, 251, 95, 145, 198, 248, 52, 2, 1, 101,
+ 204, 155, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 156, 31, 102, 205, 9, 33, 11, 103, 206, 54,
+ 157, 28, 27, 104, 207, 34, 35, 29, 46, 32,
+ 30, 55, 158, 37, 36, 39, 38, 40, 105, 208,
+ 41, 42, 43, 44, 45, 56, 106, 159, 209, 57,
+ 66, 75, 84, 107, 116, 125, 134, 160, 169, 178,
+ 187, 210, 219, 228, 237, 58, 108, 161, 211, 62,
+ 112, 165, 215, 67, 117, 170, 220, 71, 121, 174,
+ 224, 76, 126, 179, 229, 80, 130, 183, 233, 85,
+ 135, 188, 238, 89, 139, 192, 242, 59, 109, 162,
+ 212, 63, 113, 166, 216, 68, 118, 171, 221, 72,
+ 122, 175, 225, 77, 127, 180, 230, 81, 131, 184,
+ 234, 86, 136, 189, 239, 90, 140, 193, 243, 60,
+ 110, 163, 213, 64, 114, 167, 217, 69, 119, 172,
+ 222, 73, 123, 176, 226, 78, 128, 181, 231, 82,
+ 132, 185, 235, 87, 137, 190, 240, 91, 141, 194,
+ 244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
+ 120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
+ 232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
+ 142, 195, 245
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1425[] =
+{
+ 0, 4, 6, 101, 159, 220, 278, 7, 5, 3,
+ 47, 48, 49, 50, 51, 166, 167, 168, 169, 170,
+ 102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
+ 223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
+ 225, 283, 103, 161, 222, 280, 52, 2, 1, 109,
+ 228, 171, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 172, 31, 110, 229, 9, 33, 11, 111, 230, 54,
+ 173, 28, 27, 112, 231, 34, 35, 29, 46, 32,
+ 30, 55, 174, 37, 36, 39, 38, 40, 113, 232,
+ 41, 42, 43, 44, 45, 56, 114, 175, 233, 62,
+ 120, 181, 239, 75, 133, 194, 252, 57, 115, 176,
+ 234, 63, 121, 182, 240, 70, 128, 189, 247, 76,
+ 134, 195, 253, 83, 141, 202, 260, 92, 150, 211,
+ 269, 84, 142, 203, 261, 93, 151, 212, 270, 85,
+ 143, 204, 262, 94, 152, 213, 271, 86, 144, 205,
+ 263, 95, 153, 214, 272, 64, 122, 183, 241, 77,
+ 135, 196, 254, 65, 123, 184, 242, 78, 136, 197,
+ 255, 87, 145, 206, 264, 96, 154, 215, 273, 58,
+ 116, 177, 235, 66, 124, 185, 243, 71, 129, 190,
+ 248, 79, 137, 198, 256, 88, 146, 207, 265, 97,
+ 155, 216, 274, 59, 117, 178, 236, 67, 125, 186,
+ 244, 72, 130, 191, 249, 80, 138, 199, 257, 89,
+ 147, 208, 266, 98, 156, 217, 275, 60, 118, 179,
+ 237, 68, 126, 187, 245, 73, 131, 192, 250, 81,
+ 139, 200, 258, 90, 148, 209, 267, 99, 157, 218,
+ 276, 61, 119, 180, 238, 69, 127, 188, 246, 74,
+ 132, 193, 251, 82, 140, 201, 259, 91, 149, 210,
+ 268, 100, 158, 219, 277
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1585[] =
+{
+ 0, 4, 6, 109, 175, 244, 310, 7, 5, 3,
+ 47, 48, 49, 50, 51, 182, 183, 184, 185, 186,
+ 110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
+ 247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
+ 249, 315, 111, 177, 246, 312, 52, 2, 1, 117,
+ 252, 187, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 188, 31, 118, 253, 9, 33, 11, 119, 254, 54,
+ 189, 28, 27, 120, 255, 34, 35, 29, 46, 32,
+ 30, 55, 190, 37, 36, 39, 38, 40, 121, 256,
+ 41, 42, 43, 44, 45, 56, 122, 191, 257, 63,
+ 129, 198, 264, 76, 142, 211, 277, 89, 155, 224,
+ 290, 102, 168, 237, 303, 57, 123, 192, 258, 70,
+ 136, 205, 271, 83, 149, 218, 284, 96, 162, 231,
+ 297, 62, 128, 197, 263, 75, 141, 210, 276, 88,
+ 154, 223, 289, 101, 167, 236, 302, 58, 124, 193,
+ 259, 71, 137, 206, 272, 84, 150, 219, 285, 97,
+ 163, 232, 298, 59, 125, 194, 260, 64, 130, 199,
+ 265, 67, 133, 202, 268, 72, 138, 207, 273, 77,
+ 143, 212, 278, 80, 146, 215, 281, 85, 151, 220,
+ 286, 90, 156, 225, 291, 93, 159, 228, 294, 98,
+ 164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
+ 307, 60, 126, 195, 261, 65, 131, 200, 266, 68,
+ 134, 203, 269, 73, 139, 208, 274, 78, 144, 213,
+ 279, 81, 147, 216, 282, 86, 152, 221, 287, 91,
+ 157, 226, 292, 94, 160, 229, 295, 99, 165, 234,
+ 300, 104, 170, 239, 305, 107, 173, 242, 308, 61,
+ 127, 196, 262, 66, 132, 201, 267, 69, 135, 204,
+ 270, 74, 140, 209, 275, 79, 145, 214, 280, 82,
+ 148, 217, 283, 87, 153, 222, 288, 92, 158, 227,
+ 293, 95, 161, 230, 296, 100, 166, 235, 301, 105,
+ 171, 240, 306, 108, 174, 243, 309
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1825[] =
+{
+ 0, 4, 6, 121, 199, 280, 358, 7, 5, 3,
+ 47, 48, 49, 50, 51, 206, 207, 208, 209, 210,
+ 122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
+ 283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
+ 285, 363, 123, 201, 282, 360, 52, 2, 1, 129,
+ 288, 211, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 212, 31, 130, 289, 9, 33, 11, 131, 290, 54,
+ 213, 28, 27, 132, 291, 34, 35, 29, 46, 32,
+ 30, 55, 214, 37, 36, 39, 38, 40, 133, 292,
+ 41, 42, 43, 44, 45, 56, 134, 215, 293, 198,
+ 299, 136, 120, 138, 60, 279, 58, 62, 357, 139,
+ 140, 295, 156, 57, 219, 297, 63, 217, 137, 170,
+ 300, 222, 64, 106, 61, 78, 294, 92, 142, 141,
+ 135, 221, 296, 301, 343, 59, 298, 184, 329, 315,
+ 220, 216, 265, 251, 218, 237, 352, 223, 157, 86,
+ 171, 87, 164, 351, 111, 302, 65, 178, 115, 323,
+ 72, 192, 101, 179, 93, 73, 193, 151, 337, 309,
+ 143, 274, 69, 324, 165, 150, 97, 338, 110, 310,
+ 330, 273, 68, 107, 175, 245, 114, 79, 113, 189,
+ 246, 259, 174, 71, 185, 96, 344, 100, 322, 83,
+ 334, 316, 333, 252, 161, 348, 147, 82, 269, 232,
+ 260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
+ 146, 177, 266, 350, 256, 85, 149, 116, 191, 160,
+ 238, 258, 336, 305, 255, 88, 224, 99, 339, 230,
+ 228, 227, 272, 242, 241, 319, 233, 311, 102, 74,
+ 180, 275, 66, 194, 152, 325, 172, 247, 244, 261,
+ 117, 158, 166, 354, 75, 144, 108, 312, 94, 186,
+ 303, 80, 234, 89, 195, 112, 340, 181, 345, 317,
+ 326, 276, 239, 167, 118, 313, 70, 355, 327, 253,
+ 190, 176, 271, 104, 98, 153, 103, 90, 76, 267,
+ 277, 248, 225, 262, 182, 84, 154, 235, 335, 168,
+ 331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
+ 257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
+ 240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
+ 105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
+ 169, 268, 226, 236, 264
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_1985[] =
+{
+ 0, 4, 6, 129, 215, 304, 390, 7, 5, 3,
+ 47, 48, 49, 50, 51, 222, 223, 224, 225, 226,
+ 130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
+ 307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
+ 309, 395, 131, 217, 306, 392, 52, 2, 1, 137,
+ 312, 227, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 228, 31, 138, 313, 9, 33, 11, 139, 314, 54,
+ 229, 28, 27, 140, 315, 34, 35, 29, 46, 32,
+ 30, 55, 230, 37, 36, 39, 38, 40, 141, 316,
+ 41, 42, 43, 44, 45, 56, 142, 231, 317, 63,
+ 73, 92, 340, 82, 324, 149, 353, 159, 334, 165,
+ 338, 178, 163, 254, 77, 168, 257, 153, 343, 57,
+ 248, 238, 79, 252, 166, 67, 80, 201, 101, 267,
+ 143, 164, 341, 255, 339, 187, 376, 318, 78, 328,
+ 362, 115, 232, 242, 253, 290, 276, 62, 58, 158,
+ 68, 93, 179, 319, 148, 169, 154, 72, 385, 329,
+ 333, 344, 102, 83, 144, 233, 323, 124, 243, 192,
+ 354, 237, 64, 247, 202, 209, 150, 116, 335, 268,
+ 239, 299, 188, 196, 298, 94, 195, 258, 123, 363,
+ 384, 109, 325, 371, 170, 370, 84, 110, 295, 180,
+ 74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
+ 355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
+ 294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
+ 297, 259, 125, 369, 197, 97, 194, 286, 211, 281,
+ 280, 183, 372, 87, 155, 283, 59, 348, 327, 184,
+ 76, 111, 330, 203, 349, 69, 98, 152, 145, 189,
+ 66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
+ 126, 241, 193, 88, 388, 117, 95, 387, 112, 359,
+ 287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
+ 373, 181, 292, 85, 378, 302, 121, 107, 364, 346,
+ 356, 212, 278, 213, 65, 382, 288, 207, 113, 175,
+ 99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
+ 270, 264, 250, 240, 75, 350, 151, 60, 89, 321,
+ 156, 274, 360, 326, 70, 282, 167, 146, 352, 81,
+ 91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
+ 128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
+ 293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
+ 261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
+ 71, 332, 61, 265, 157, 246, 236
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_2305[] =
+{
+ 0, 4, 6, 145, 247, 352, 454, 7, 5, 3,
+ 47, 48, 49, 50, 51, 254, 255, 256, 257, 258,
+ 146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
+ 355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
+ 357, 459, 147, 249, 354, 456, 52, 2, 1, 153,
+ 360, 259, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 260, 31, 154, 361, 9, 33, 11, 155, 362, 54,
+ 261, 28, 27, 156, 363, 34, 35, 29, 46, 32,
+ 30, 55, 262, 37, 36, 39, 38, 40, 157, 364,
+ 41, 42, 43, 44, 45, 56, 158, 263, 365, 181,
+ 192, 170, 79, 57, 399, 90, 159, 297, 377, 366,
+ 275, 68, 183, 388, 286, 194, 299, 92, 70, 182,
+ 401, 172, 59, 91, 58, 400, 368, 161, 81, 160,
+ 264, 171, 80, 389, 390, 378, 379, 193, 298, 69,
+ 266, 265, 367, 277, 288, 276, 287, 184, 60, 195,
+ 82, 93, 71, 369, 402, 173, 162, 444, 300, 391,
+ 98, 76, 278, 61, 267, 374, 135, 411, 167, 102,
+ 380, 200, 87, 178, 65, 94, 204, 124, 72, 342,
+ 189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
+ 113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
+ 370, 422, 174, 64, 392, 83, 425, 219, 134, 188,
+ 432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
+ 236, 229, 97, 294, 385, 230, 166, 268, 177, 443,
+ 225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
+ 414, 95, 140, 240, 410, 395, 209, 129, 283, 346,
+ 105, 241, 437, 86, 308, 448, 203, 345, 186, 107,
+ 220, 415, 334, 319, 106, 313, 118, 123, 73, 207,
+ 421, 214, 384, 373, 438, 62, 371, 341, 75, 449,
+ 168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
+ 271, 63, 191, 325, 96, 169, 231, 280, 312, 187,
+ 406, 84, 201, 100, 67, 382, 175, 336, 202, 330,
+ 269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
+ 302, 372, 398, 190, 180, 89, 99, 103, 232, 78,
+ 88, 77, 136, 387, 165, 198, 394, 125, 176, 428,
+ 74, 375, 238, 227, 66, 273, 282, 141, 306, 412,
+ 114, 85, 130, 348, 119, 291, 296, 386, 233, 397,
+ 303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
+ 274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
+ 310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
+ 418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
+ 417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
+ 121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
+ 126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
+ 322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
+ 213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
+ 318
+};
+
+const pj_int16_t pjmedia_codec_amrwb_ordermap_2385[] =
+{
+ 0, 4, 6, 145, 251, 360, 466, 7, 5, 3,
+ 47, 48, 49, 50, 51, 262, 263, 264, 265, 266,
+ 146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
+ 363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
+ 365, 471, 147, 253, 362, 468, 52, 2, 1, 157,
+ 372, 267, 19, 21, 12, 17, 18, 20, 16, 25,
+ 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
+ 268, 31, 152, 153, 154, 155, 258, 259, 260, 261,
+ 367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
+ 9, 33, 11, 159, 374, 54, 269, 28, 27, 160,
+ 375, 34, 35, 29, 46, 32, 30, 55, 270, 37,
+ 36, 39, 38, 40, 161, 376, 41, 42, 43, 44,
+ 45, 56, 162, 271, 377, 185, 196, 174, 79, 57,
+ 411, 90, 163, 305, 389, 378, 283, 68, 187, 400,
+ 294, 198, 307, 92, 70, 186, 413, 176, 59, 91,
+ 58, 412, 380, 165, 81, 164, 272, 175, 80, 401,
+ 402, 390, 391, 197, 306, 69, 274, 273, 379, 285,
+ 296, 284, 295, 188, 60, 199, 82, 93, 71, 381,
+ 414, 177, 166, 456, 308, 403, 98, 76, 286, 61,
+ 275, 386, 135, 423, 171, 102, 392, 204, 87, 182,
+ 65, 94, 208, 124, 72, 350, 193, 313, 393, 408,
+ 445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
+ 317, 415, 116, 328, 200, 339, 382, 434, 178, 64,
+ 404, 83, 437, 223, 134, 192, 444, 112, 439, 139,
+ 287, 167, 448, 212, 459, 222, 240, 233, 97, 302,
+ 397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
+ 138, 127, 298, 117, 355, 203, 426, 95, 140, 244,
+ 422, 407, 213, 129, 291, 354, 105, 245, 449, 86,
+ 316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
+ 106, 321, 118, 123, 73, 211, 433, 218, 396, 385,
+ 450, 62, 383, 349, 75, 461, 172, 331, 168, 246,
+ 428, 332, 312, 201, 343, 416, 279, 63, 195, 333,
+ 96, 173, 235, 288, 320, 191, 418, 84, 205, 100,
+ 67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
+ 301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
+ 184, 89, 99, 103, 236, 78, 88, 77, 136, 399,
+ 169, 202, 406, 125, 180, 440, 74, 387, 242, 231,
+ 66, 281, 290, 141, 314, 424, 114, 85, 130, 356,
+ 119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
+ 435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
+ 345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
+ 289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
+ 334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
+ 452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
+ 132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
+ 352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
+ 465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
+ 239, 250, 133, 144, 432, 337, 326
+};
+
+/**
+ * AMR-NB bitstream sensitivity order maps.
+ */
+const pj_int16_t* const pjmedia_codec_amrnb_ordermaps[8] =
+{
+ pjmedia_codec_amrnb_ordermap475,
+ pjmedia_codec_amrnb_ordermap515,
+ pjmedia_codec_amrnb_ordermap59,
+ pjmedia_codec_amrnb_ordermap67,
+ pjmedia_codec_amrnb_ordermap74,
+ pjmedia_codec_amrnb_ordermap795,
+ pjmedia_codec_amrnb_ordermap102,
+ pjmedia_codec_amrnb_ordermap122
+};
+
+/**
+ * AMR-WB bitstream sensitivity order maps.
+ */
+const pj_int16_t* const pjmedia_codec_amrwb_ordermaps[9] =
+{
+ pjmedia_codec_amrwb_ordermap_660,
+ pjmedia_codec_amrwb_ordermap_885,
+ pjmedia_codec_amrwb_ordermap_1265,
+ pjmedia_codec_amrwb_ordermap_1425,
+ pjmedia_codec_amrwb_ordermap_1585,
+ pjmedia_codec_amrwb_ordermap_1825,
+ pjmedia_codec_amrwb_ordermap_1985,
+ pjmedia_codec_amrwb_ordermap_2305,
+ pjmedia_codec_amrwb_ordermap_2385
+};
+
+/**
+ * Constant of AMR-NB frame lengths in bytes.
+ */
+const pj_uint8_t pjmedia_codec_amrnb_framelen[16] =
+ {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
+/**
+ * Constant of AMR-NB frame lengths in bits.
+ */
+const pj_uint16_t pjmedia_codec_amrnb_framelenbits[9] =
+ {95, 103, 118, 134, 148, 159, 204, 244, 39};
+/**
+ * Constant of AMR-NB bitrates.
+ */
+const pj_uint16_t pjmedia_codec_amrnb_bitrates[8] =
+ {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};
+
+/**
+ * Constant of AMR-WB frame lengths in bytes.
+ */
+const pj_uint8_t pjmedia_codec_amrwb_framelen[16] =
+ {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 0};
+/**
+ * Constant of AMR-WB frame lengths in bits.
+ */
+const pj_uint16_t pjmedia_codec_amrwb_framelenbits[10] =
+ {132, 177, 253, 285, 317, 365, 397, 461, 477, 40};
+/**
+ * Constant of AMR-WB bitrates.
+ */
+const pj_uint16_t pjmedia_codec_amrwb_bitrates[9] =
+ {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850};
+
+
+/**
+ * This structure describes AMR frame info, to be fitted into #pjmedia_frame
+ * bit info.
+ */
+#pragma pack(1)
+typedef struct pjmedia_codec_amr_bit_info {
+ pj_uint8_t frame_type; /**< AMR frame type. */
+ pj_int8_t mode; /**< AMR mode. */
+ pj_uint8_t start_bit; /**< Frame start bit. */
+ pj_uint8_t good_quality:1; /**< Flag if frame is good/degraded. */
+ pj_uint8_t STI:1; /**< STI mode (first/update). */
+} pjmedia_codec_amr_bit_info;
+#pragma pack()
+
+
+/**
+ * This structure describes AMR settings.
+ */
+typedef struct pjmedia_codec_amr_pack_setting {
+ pj_uint8_t amr_nb:1; /**< Set 1 for AMR-NB, 0 for AMR-WB. */
+ pj_uint8_t reorder:1; /**< Reorder bitstream into descending
+ sensitivity order or vice versa. */
+ pj_uint8_t octet_aligned:1; /**< TRUE if payload is in octet-aligned mode,
+ FALSE if payload is in bandwidth
+ efficient mode. */
+ pj_uint8_t cmr:4; /**< Change Mode Request for remote
+ encoder. */
+} pjmedia_codec_amr_pack_setting;
+
+
+/**
+ * Get AMR mode based on bitrate.
+ *
+ * @param bitrate AMR bitrate.
+ *
+ * @return AMR mode.
+ */
+PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode(unsigned bitrate)
+{
+ pj_int8_t mode = -1;
+
+ if(bitrate==4750){
+ mode = 0;
+ } else if(bitrate==5150){
+ mode = 1;
+ } else if(bitrate==5900){
+ mode = 2;
+ } else if(bitrate==6700){
+ mode = 3;
+ } else if(bitrate==7400){
+ mode = 4;
+ } else if(bitrate==7950){
+ mode = 5;
+ } else if(bitrate==10200){
+ mode = 6;
+ } else if(bitrate==12200){
+ mode = 7;
+
+ /* AMRWB */
+ } else if(bitrate==6600){
+ mode = 0;
+ } else if(bitrate==8850){
+ mode = 1;
+ } else if(bitrate==12650){
+ mode = 2;
+ } else if(bitrate==14250){
+ mode = 3;
+ } else if(bitrate==15850){
+ mode = 4;
+ } else if(bitrate==18250){
+ mode = 5;
+ } else if(bitrate==19850){
+ mode = 6;
+ } else if(bitrate==23050){
+ mode = 7;
+ } else if(bitrate==23850){
+ mode = 8;
+ }
+ return mode;
+}
+
+/**
+ * Get AMR mode based on frame length.
+ *
+ * @param amrnb Set to PJ_TRUE for AMR-NB domain or PJ_FALSE for AMR-WB.
+ * @param frame_len The frame length.
+ *
+ * @return AMR mode.
+ */
+
+PJ_INLINE(pj_int8_t) pjmedia_codec_amr_get_mode2(pj_bool_t amrnb,
+ unsigned frame_len)
+{
+ int i;
+
+ if (amrnb) {
+ for (i = 0; i < 9; ++i)
+ if (frame_len == pjmedia_codec_amrnb_framelen[i])
+ return (pj_int8_t)i;
+ } else {
+ for (i = 0; i < 10; ++i) {
+ if (frame_len == pjmedia_codec_amrwb_framelen[i])
+ return (pj_int8_t)i;
+ }
+ }
+
+ pj_assert(!"Invalid AMR frame length");
+ return -1;
+}
+
+/**
+ * Prepare a frame before pass it to decoder. This function will do:
+ * - reorder AMR bitstream from descending sensitivity order into
+ * encoder bits order. This can be enabled/disabled via param
+ * 'setting' by setting/resetting field 'reorder'.
+ * - align left the start bit (make the start_bit to be 0).
+ *
+ * @param in Input frame.
+ * @param setting Settings, see #pjmedia_codec_amr_pack_setting.
+ * @param out Output frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_amr_predecode(
+ const pjmedia_frame *in,
+ const pjmedia_codec_amr_pack_setting *setting,
+ pjmedia_frame *out)
+{
+ pj_int8_t amr_bits[477 + 7] = {0};
+ pj_int8_t *p_amr_bits = &amr_bits[0];
+
+ pj_uint8_t *r = (pj_uint8_t*) in->buf; /* read cursor */
+ pj_uint8_t *w = (pj_uint8_t*) out->buf; /* write cursor */
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_uint16_t *bitrate_tbl;
+ const pj_int16_t* const *order_maps;
+
+ pjmedia_codec_amr_bit_info *in_info =
+ (pjmedia_codec_amr_bit_info*) &in->bit_info;
+ pjmedia_codec_amr_bit_info *out_info =
+ (pjmedia_codec_amr_bit_info*) &out->bit_info;
+
+ unsigned i;
+
+ *out_info = *in_info;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrnb_bitrates;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrwb_bitrates;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ /* unpack AMR bitstream if there is any data */
+ if (in_info->frame_type <= SID_FT) {
+ i = 0;
+ if (in_info->start_bit) {
+ for (; i < (unsigned)(8-in_info->start_bit); ++i)
+ *p_amr_bits++ = (pj_uint8_t)
+ ((*r >> (7-in_info->start_bit-i)) & 1);
+ ++r;
+ }
+ for(; i < framelenbit_tbl[in_info->frame_type]; i += 8, ++r) {
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
+ }
+ }
+
+ if (in_info->frame_type < SID_FT) {
+
+ /* Speech */
+ out_info->mode = in_info->frame_type;
+ out->size = framelen_tbl[out_info->mode];
+
+ pj_bzero(out->buf, out->size);
+
+ if (setting->reorder) {
+ const pj_int16_t *order_map;
+
+ order_map = order_maps[out_info->mode];
+ for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) {
+ if (amr_bits[i]) {
+ pj_uint16_t bitpos;
+ bitpos = order_map[i];
+ w[bitpos>>3] |= 1 << (7 - (bitpos % 8));
+ }
+ }
+ } else {
+ for(i = 0; i < framelenbit_tbl[out_info->mode]; ++i) {
+ if (amr_bits[i])
+ w[i >> 3] |= 1 << (7 - (i % 8));
+ }
+ }
+
+ } else if (in_info->frame_type == SID_FT) {
+
+ /* SID */
+ pj_uint8_t w_bitptr = 0;
+ pj_uint8_t FT_;
+
+ if (setting->amr_nb)
+ FT_ = (pj_uint8_t)((amr_bits[36] << 2) | (amr_bits[37] << 1) |
+ amr_bits[38]);
+ else
+ FT_ = (pj_uint8_t)((amr_bits[36] << 3) | (amr_bits[37] << 2) |
+ (amr_bits[38] << 1) | amr_bits[39]);
+
+ out_info->mode = FT_;
+ out->size = 5;
+
+ pj_bzero(out->buf, out->size);
+ for(i = 0; i < framelenbit_tbl[SID_FT]; ++i) {
+ if (amr_bits[i])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ } else {
+
+ /* NO DATA */
+ out->size = 0;
+ out_info->mode = -1;
+ }
+
+ out_info->start_bit = 0;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Pack encoded AMR frame(s) into an RTP payload.
+ *
+ * @param frames AMR frames to be packed.
+ * @param nframes Number of frames to be packed.
+ * @param setting Settings, see #pjmedia_codec_amr_pack_setting.
+ * @param pkt Payload.
+ * @param pkt_size Payload size, as input this specifies payload maximum size,
+ * as output this specifies payload packed size.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE (pj_status_t) pjmedia_codec_amr_pack(
+ const pjmedia_frame frames[],
+ unsigned nframes,
+ const pjmedia_codec_amr_pack_setting *setting,
+ void *pkt,
+ pj_size_t *pkt_size)
+{
+ /* Write cursor */
+ pj_uint8_t *w = (pj_uint8_t*)pkt;
+ pj_uint8_t w_bitptr = 0;
+
+ /* Read cursor */
+ pj_uint8_t *r;
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_uint16_t *bitrate_tbl;
+ const pj_int16_t* const *order_maps;
+
+ /* frame info */
+ pjmedia_codec_amr_bit_info *info;
+
+ unsigned i, max_pkt_size;
+
+ max_pkt_size = *pkt_size;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrnb_bitrates;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ bitrate_tbl = pjmedia_codec_amrwb_bitrates;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ /* Code Mode Request, 4 bits */
+ *w = (pj_uint8_t)(setting->cmr << 4);
+ w_bitptr = 4;
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+
+ /* Table Of Contents, 6 bits each */
+ for (i = 0; i < nframes; ++i) {
+ pj_uint8_t TOC, FT, Q;
+ pj_bool_t F;
+
+ info = (pjmedia_codec_amr_bit_info*)&frames[i].bit_info;
+
+ F = (i != nframes-1);
+ FT = info->frame_type;
+ Q = (pj_uint8_t)(info->good_quality == 1);
+ pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
+
+ /* Check buffer availability */
+ *pkt_size = w - (pj_uint8_t*)pkt + 1;
+ PJ_ASSERT_RETURN(*pkt_size <= max_pkt_size, PJ_ETOOSMALL);
+
+ TOC = (pj_uint8_t)((F<<5) | (FT<<1) | Q);
+ if (w_bitptr == 0) {
+ *w = (pj_uint8_t)(TOC<<2);
+ w_bitptr = 6;
+ } else if (w_bitptr == 2) {
+ *w++ |= TOC;
+ w_bitptr = 0;
+ } else if (w_bitptr == 4) {
+ *w++ |= TOC>>2;
+ *w = (pj_uint8_t)(TOC<<6);
+ w_bitptr = 2;
+ } else if (w_bitptr == 6) {
+ *w++ |= TOC>>4;
+ *w = (pj_uint8_t)(TOC<<4);
+ w_bitptr = 4;
+ }
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ /* Encoded data */
+ for (i = 0; i < nframes; ++i) {
+ pj_int8_t amr_bits[477 + 7] = {0};
+ pj_int8_t *p_amr_bits = &amr_bits[0];
+ unsigned j;
+
+ info = (pjmedia_codec_amr_bit_info*)&frames[i].bit_info;
+
+ /* Check buffer availability */
+ *pkt_size = w - (pj_uint8_t*)pkt;
+ if (info->frame_type <= SID_FT)
+ *pkt_size += framelen_tbl[info->frame_type] + 1;
+ PJ_ASSERT_RETURN(*pkt_size <= max_pkt_size, PJ_ETOOSMALL);
+
+ /* Skip if there is no data */
+ if (info->frame_type > SID_FT)
+ continue;
+
+ /* Unpack bits */
+ r = (pj_uint8_t*) frames[i].buf;
+ j = 0;
+ if (info->start_bit) {
+ for (; j < (unsigned)(8-info->start_bit); ++j)
+ *p_amr_bits++ = (pj_uint8_t)
+ ((*r >> (7-info->start_bit-j)) & 1);
+ ++r;
+ }
+ for(; j < framelenbit_tbl[info->frame_type]; j+=8, ++r) {
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
+ *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
+ }
+
+ if (info->frame_type < SID_FT) {
+
+ /* Speech */
+ if (w_bitptr == 0) *w = 0;
+
+ if (setting->reorder) {
+ const pj_int16_t *order_map;
+
+ /* Put bits in the packet, sensitivity descending ordered */
+ order_map = order_maps[info->frame_type];
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[order_map[j]])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ } else {
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[j])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ }
+
+ } else if (info->frame_type == SID_FT) {
+
+ /* SID */
+ amr_bits[35] |= info->STI;
+
+ if (setting->amr_nb) {
+ amr_bits[36] = (pj_uint8_t)((info->mode >> 2) & 1);
+ amr_bits[37] = (pj_uint8_t)((info->mode >> 1) & 1);
+ amr_bits[38] = (pj_uint8_t)((info->mode) & 1);
+ } else {
+ amr_bits[36] = (pj_uint8_t)((info->mode >> 3) & 1);
+ amr_bits[37] = (pj_uint8_t)((info->mode >> 2) & 1);
+ amr_bits[38] = (pj_uint8_t)((info->mode >> 1) & 1);
+ amr_bits[39] = (pj_uint8_t)((info->mode) & 1);
+ }
+
+ if (w_bitptr == 0) *w = 0;
+ for(j = 0; j < framelenbit_tbl[info->frame_type]; ++j) {
+ if (amr_bits[j])
+ *w |= (1 << (7-w_bitptr));
+
+ if (++w_bitptr == 8) {
+ w_bitptr = 0;
+ ++w;
+ *w = 0;
+ }
+ }
+ }
+
+ if (setting->octet_aligned) {
+ ++w;
+ w_bitptr = 0;
+ }
+ }
+
+ *pkt_size = w - (pj_uint8_t*)pkt;
+ if (w_bitptr)
+ *pkt_size += 1;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Parse AMR payload into frames.
+ *
+ * @param pkt Payload.
+ * @param pkt_size Payload size.
+ * @param ts Base timestamp.
+ * @param setting Settings, see #pjmedia_codec_amr_pack_setting.
+ * @param frames Frames parsed.
+ * @param nframes Number of frames parsed.
+ * @param cmr Change Mode Request message for local encoder.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_amr_parse(
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *ts,
+ const pjmedia_codec_amr_pack_setting* setting,
+ pjmedia_frame frames[],
+ unsigned *nframes,
+ pj_uint8_t *cmr)
+{
+ unsigned cnt = 0;
+ pj_timestamp ts_ = *ts;
+
+ /* Read cursor */
+ pj_uint8_t r_bitptr = 0;
+ pj_uint8_t *r = (pj_uint8_t*)pkt;
+
+ /* env vars for AMR or AMRWB */
+ pj_uint8_t SID_FT;
+ const pj_uint8_t *framelen_tbl;
+ const pj_uint16_t *framelenbit_tbl;
+ const pj_int16_t* const *order_maps;
+
+ /* frame info */
+ pjmedia_codec_amr_bit_info *info;
+
+ if (setting->amr_nb) {
+ SID_FT = 8;
+ framelen_tbl = pjmedia_codec_amrnb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrnb_framelenbits;
+ order_maps = pjmedia_codec_amrnb_ordermaps;
+ } else {
+ SID_FT = 9;
+ framelen_tbl = pjmedia_codec_amrwb_framelen;
+ framelenbit_tbl = pjmedia_codec_amrwb_framelenbits;
+ order_maps = pjmedia_codec_amrwb_ordermaps;
+ }
+
+ PJ_UNUSED_ARG(pkt_size);
+
+ /* Code Mode Request, 4 bits */
+ *cmr = (pj_uint8_t)((*r >> 4) & 0x0F);
+ r_bitptr = 4;
+ if (setting->octet_aligned) {
+ ++r;
+ r_bitptr = 0;
+ }
+
+ /* Table Of Contents, 6 bits each */
+ for (;;) {
+ pj_uint8_t TOC = 0;
+ pj_uint8_t F, FT, Q;
+
+ if (r_bitptr == 0) {
+ TOC = (pj_uint8_t)(*r >> 2);
+ r_bitptr = 6;
+ } else if (r_bitptr == 2) {
+ TOC = (pj_uint8_t)(*r++ & 0x3F);
+ r_bitptr = 0;
+ } else if (r_bitptr == 4) {
+ TOC = (pj_uint8_t)((*r++ & 0x0f) << 2);
+ TOC |= *r >> 6;
+ r_bitptr = 2;
+ } else if (r_bitptr == 6) {
+ TOC = (pj_uint8_t)((*r++ & 0x03) << 4);
+ TOC |= *r >> 4;
+ r_bitptr = 4;
+ }
+
+ F = (pj_uint8_t)(TOC >> 5);
+ FT = (pj_uint8_t)((TOC >> 1) & 0x0F);
+ Q = (pj_uint8_t)(TOC & 1);
+
+ if (FT > SID_FT && FT < 14) {
+ pj_assert(!"Invalid AMR frametype, stream may be corrupted!");
+ break;
+ }
+
+ if (setting->octet_aligned) {
+ ++r;
+ r_bitptr = 0;
+ }
+
+ /* Set frame attributes */
+ info = (pjmedia_codec_amr_bit_info*) &frames[cnt].bit_info;
+ info->frame_type = FT;
+ info->mode = (pj_int8_t)((FT < SID_FT)? FT : -1);
+ info->good_quality = (pj_uint8_t)(Q == 1);
+ info->start_bit = 0;
+ info->STI = 0;
+ frames[cnt].timestamp = ts_;
+ frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+ /* AMR frame length is 20ms */
+ ts_.u64 += setting->amr_nb? 160 : 320;
+
+ if (++cnt == *nframes || !F)
+ break;
+ }
+ *nframes = cnt;
+
+ cnt = 0;
+
+ /* Speech frames */
+ while (cnt < *nframes) {
+ pj_uint8_t FT;
+
+ info = (pjmedia_codec_amr_bit_info*) &frames[cnt].bit_info;
+ FT = info->frame_type;
+
+ frames[cnt].buf = r;
+ info->start_bit = r_bitptr;
+
+ if (FT == SID_FT) {
+ unsigned sti_bitptr;
+ sti_bitptr = r_bitptr + 35;
+ info->STI = (pj_uint8_t)
+ (r[sti_bitptr >> 3] >> (7 - (sti_bitptr % 8))) & 1;
+ }
+
+ if (setting->octet_aligned) {
+ r += framelen_tbl[FT];
+ frames[cnt].size = framelen_tbl[FT];
+ } else {
+ if (FT == 14 || FT == 15) {
+ /* NO DATA */
+ frames[cnt].size = 0;
+ } else {
+ unsigned adv_bit;
+
+ adv_bit = framelenbit_tbl[FT] + r_bitptr;
+ r += adv_bit >> 3;
+ r_bitptr = (pj_uint8_t)(adv_bit % 8);
+
+ frames[cnt].size = adv_bit >> 3;
+ if (r_bitptr)
+ ++frames[cnt].size;
+ }
+ }
+ ++cnt;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_AMR_HELPER_H__ */
diff --git a/pjmedia/include/pjmedia-codec/amr_sdp_match.h b/pjmedia/include/pjmedia-codec/amr_sdp_match.h
new file mode 100644
index 0000000..7f379ab
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/amr_sdp_match.h
@@ -0,0 +1,61 @@
+/* $Id: amr_sdp_match.h 3911 2011-12-15 06:45:23Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_AMR_SDP_MATCH_H__
+#define __PJMEDIA_CODEC_AMR_SDP_MATCH_H__
+
+
+/**
+ * @file g7221_sdp_match.h
+ * @brief Special SDP format match for AMR-NB and AMR-WB.
+ */
+
+#include <pjmedia/sdp_neg.h>
+
+PJ_BEGIN_DECL
+
+
+/* Match AMR-NB and AMR-WB format in the SDP media offer and answer. This
+ * function will match some AMR settings in the SDP format parameters, i.e:
+ * octet-align, crc, robust-sorting, interleaving. Note that, for answerer,
+ * if octet-align mode needs to be adaptable to offerer setting, application
+ * should set #PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER in the option.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the AMR format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the AMR format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_amr_match_sdp( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_AMR_SDP_MATCH_H__ */
diff --git a/pjmedia/include/pjmedia-codec/audio_codecs.h b/pjmedia/include/pjmedia-codec/audio_codecs.h
new file mode 100644
index 0000000..5605c5c
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/audio_codecs.h
@@ -0,0 +1,98 @@
+/* $Id: audio_codecs.h 3666 2011-07-19 08:40:20Z nanang $ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_ALL_CODECS_H__
+#define __PJMEDIA_CODEC_ALL_CODECS_H__
+
+/**
+ * @file pjmedia-codec/all_codecs.h
+ * @brief Helper function to register all codecs
+ */
+#include <pjmedia/endpoint.h>
+#include <pjmedia-codec/passthrough.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_CODEC_REGISTER_ALL Codec registration helper
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Helper function to register all codecs
+ * @{
+ *
+ * Helper function to register all codecs that are implemented in
+ * PJMEDIA-CODEC library.
+ */
+
+/**
+ * Codec configuration. Call #pjmedia_audio_codec_config_default() to initialize
+ * this structure with the default values.
+ */
+typedef struct pjmedia_audio_codec_config
+{
+ /** Speex codec settings. See #pjmedia_codec_speex_init() for more info */
+ struct {
+ unsigned option; /**< Bitmask of options. */
+ int quality; /**< Codec quality. */
+ int complexity; /**< Codec complexity. */
+ } speex;
+
+ /** iLBC settings */
+ struct {
+ unsigned mode; /**< iLBC mode. */
+ } ilbc;
+
+ /** Passthrough */
+ struct {
+ pjmedia_codec_passthrough_setting setting; /**< Passthrough */
+ } passthrough;
+
+} pjmedia_audio_codec_config;
+
+
+/**
+ * Initialize pjmedia_audio_codec_config structure with default values.
+ *
+ * @param cfg The codec config to be initialized.
+ */
+PJ_DECL(void)
+pjmedia_audio_codec_config_default(pjmedia_audio_codec_config *cfg);
+
+/**
+ * Register all known audio codecs implemented in PJMEDA-CODEC library to the
+ * specified media endpoint.
+ *
+ * @param endpt The media endpoint.
+ * @param c Optional codec configuration, or NULL to use default
+ * values.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_register_audio_codecs(pjmedia_endpt *endpt,
+ const pjmedia_audio_codec_config *c);
+
+
+/**
+ * @} PJMEDIA_CODEC_REGISTER_ALL
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_CODEC_ALL_CODECS_H__ */
diff --git a/pjmedia/include/pjmedia-codec/config.h b/pjmedia/include/pjmedia-codec/config.h
new file mode 100644
index 0000000..2c71cc9
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/config.h
@@ -0,0 +1,423 @@
+/* $Id: config.h 4070 2012-04-23 13:48:10Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_CONFIG_H__
+#define __PJMEDIA_CODEC_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief PJMEDIA-CODEC compile time settings
+ */
+
+/**
+ * @defgroup pjmedia_codec_config PJMEDIA-CODEC Compile Time Settings
+ * @ingroup PJMEDIA_CODEC
+ * @brief Various compile time settings such as to enable/disable codecs
+ * @{
+ */
+
+#include <pjmedia/types.h>
+
+/*
+ * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjmedia-codec/config_auto.h>
+#endif
+
+
+/**
+ * Unless specified otherwise, L16 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_L16_CODEC
+# define PJMEDIA_HAS_L16_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, GSM codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_GSM_CODEC
+# define PJMEDIA_HAS_GSM_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, Speex codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_SPEEX_CODEC
+# define PJMEDIA_HAS_SPEEX_CODEC 1
+#endif
+
+/**
+ * Speex codec default complexity setting.
+ */
+#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY
+# define PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY 2
+#endif
+
+/**
+ * Speex codec default quality setting. Please note that pjsua-lib may override
+ * this setting via its codec quality setting (i.e PJSUA_DEFAULT_CODEC_QUALITY).
+ */
+#ifndef PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY
+# define PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY 8
+#endif
+
+
+/**
+ * Unless specified otherwise, iLBC codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_ILBC_CODEC
+# define PJMEDIA_HAS_ILBC_CODEC 1
+#endif
+
+
+/**
+ * Unless specified otherwise, G.722 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_G722_CODEC
+# define PJMEDIA_HAS_G722_CODEC 1
+#endif
+
+
+/**
+ * Default G.722 codec encoder and decoder level adjustment. The G.722
+ * specifies that it uses 14 bit PCM for input and output, while PJMEDIA
+ * normally uses 16 bit PCM, so the conversion is done by applying
+ * level adjustment. If the value is non-zero, then PCM input samples to
+ * the encoder will be shifted right by this value, and similarly PCM
+ * output samples from the decoder will be shifted left by this value.
+ *
+ * This can be changed at run-time after initialization by calling
+ * #pjmedia_codec_g722_set_pcm_shift().
+ *
+ * Default: 2.
+ */
+#ifndef PJMEDIA_G722_DEFAULT_PCM_SHIFT
+# define PJMEDIA_G722_DEFAULT_PCM_SHIFT 2
+#endif
+
+
+/**
+ * Specifies whether G.722 PCM shifting should be stopped when clipping
+ * detected in the decoder. Enabling this feature can be useful when
+ * talking to G.722 implementation that uses 16 bit PCM for G.722 input/
+ * output (for any reason it seems to work) and the PCM shifting causes
+ * audio clipping.
+ *
+ * See also #PJMEDIA_G722_DEFAULT_PCM_SHIFT.
+ *
+ * Default: enabled.
+ */
+#ifndef PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING
+# define PJMEDIA_G722_STOP_PCM_SHIFT_ON_CLIPPING 1
+#endif
+
+
+/**
+ * Enable the features provided by Intel IPP libraries, for example
+ * codecs such as G.729, G.723.1, G.726, G.728, G.722.1, and AMR.
+ *
+ * By default this is disabled. Please follow the instructions in
+ * http://trac.pjsip.org/repos/wiki/Intel_IPP_Codecs on how to setup
+ * Intel IPP with PJMEDIA.
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP
+# define PJMEDIA_HAS_INTEL_IPP 0
+#endif
+
+
+/**
+ * Visual Studio only: when this option is set, the Intel IPP libraries
+ * will be automatically linked to application using pragma(comment)
+ * constructs. This is convenient, however it will only link with
+ * the stub libraries and the Intel IPP DLL's will be required when
+ * distributing the application.
+ *
+ * If application wants to link with the different types of the Intel IPP
+ * libraries (for example, the static libraries), it must set this option
+ * to zero and specify the Intel IPP libraries in the application's input
+ * library specification manually.
+ *
+ * Default 1.
+ */
+#ifndef PJMEDIA_AUTO_LINK_IPP_LIBS
+# define PJMEDIA_AUTO_LINK_IPP_LIBS 1
+#endif
+
+
+/**
+ * Enable Intel IPP AMR codec. This also needs to be enabled when AMR WB
+ * codec is enabled. This option is only used when PJMEDIA_HAS_INTEL_IPP
+ * is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_AMR 1
+#endif
+
+
+/**
+ * Enable Intel IPP AMR wideband codec. The PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
+ * option must also be enabled to use this codec. This option is only used
+ * when PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.729 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G729
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G729 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.723.1 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.726 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G726
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G726 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.728 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G728
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G728 1
+#endif
+
+
+/**
+ * Enable Intel IPP G.722.1 codec. This option is only used when
+ * PJMEDIA_HAS_INTEL_IPP is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
+# define PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 1
+#endif
+
+/**
+ * Enable Passthrough codecs.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODECS
+# define PJMEDIA_HAS_PASSTHROUGH_CODECS 0
+#endif
+
+/**
+ * Enable AMR passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_AMR 1
+#endif
+
+/**
+ * Enable G.729 passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_G729
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_G729 1
+#endif
+
+/**
+ * Enable iLBC passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_ILBC 1
+#endif
+
+/**
+ * Enable PCMU passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU 1
+#endif
+
+/**
+ * Enable PCMA passthrough codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA
+# define PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA 1
+#endif
+
+/* If passthrough and PCMU/PCMA are enabled, disable the software
+ * G.711 codec
+ */
+#if PJMEDIA_HAS_PASSTHROUGH_CODECS && \
+ (PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMU || PJMEDIA_HAS_PASSTHROUGH_CODEC_PCMA)
+# undef PJMEDIA_HAS_G711_CODEC
+# define PJMEDIA_HAS_G711_CODEC 0
+#endif
+
+
+/**
+ * G.722.1 codec is disabled by default.
+ */
+#ifndef PJMEDIA_HAS_G7221_CODEC
+# define PJMEDIA_HAS_G7221_CODEC 0
+#endif
+
+/**
+ * Enable OpenCORE AMR-NB codec.
+ * See https://trac.pjsip.org/repos/ticket/1388 for some info.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_OPENCORE_AMRNB_CODEC
+# define PJMEDIA_HAS_OPENCORE_AMRNB_CODEC 0
+#endif
+
+/**
+ * Link with libopencore-amrXX via pragma comment on Visual Studio.
+ * This option only makes sense if PJMEDIA_HAS_OPENCORE_AMRNB_CODEC
+ * is enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_AUTO_LINK_OPENCORE_AMR_LIBS
+# define PJMEDIA_AUTO_LINK_OPENCORE_AMR_LIBS 1
+#endif
+
+/**
+ * Link with libopencore-amrXX.a that has been produced with gcc.
+ * This option only makes sense if PJMEDIA_HAS_OPENCORE_AMRNB_CODEC
+ * and PJMEDIA_AUTO_LINK_OPENCORE_AMR_LIBS are enabled.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_OPENCORE_AMR_BUILT_WITH_GCC
+# define PJMEDIA_OPENCORE_AMR_BUILT_WITH_GCC 1
+#endif
+
+
+/**
+ * Default G.722.1 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * This can be changed at run-time after initialization by calling
+ * #pjmedia_codec_g7221_set_pcm_shift().
+ */
+#ifndef PJMEDIA_G7221_DEFAULT_PCM_SHIFT
+# define PJMEDIA_G7221_DEFAULT_PCM_SHIFT 1
+#endif
+
+
+/**
+ * Enabling both G.722.1 codec implementations, internal PJMEDIA and IPP,
+ * may cause problem in SDP, i.e: payload types duplications. So, let's
+ * just trap such case here at compile time.
+ *
+ * Application can control which implementation to be used by manipulating
+ * PJMEDIA_HAS_G7221_CODEC and PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in
+ * config_site.h.
+ */
+#if (PJMEDIA_HAS_G7221_CODEC != 0) && (PJMEDIA_HAS_INTEL_IPP != 0) && \
+ (PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 != 0)
+# error Only one G.722.1 implementation can be enabled at the same time. \
+ Please use PJMEDIA_HAS_G7221_CODEC and \
+ PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 in your config_site.h \
+ to control which implementation to be used.
+#endif
+
+
+/**
+ * Specify if FFMPEG codecs are available.
+ *
+ * Default: PJMEDIA_HAS_LIBAVCODEC
+ */
+#ifndef PJMEDIA_HAS_FFMPEG_CODEC
+# define PJMEDIA_HAS_FFMPEG_CODEC PJMEDIA_HAS_LIBAVCODEC
+#endif
+
+
+/**
+ * Specify if FFMPEG video codecs are available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG_CODEC
+ */
+#ifndef PJMEDIA_HAS_FFMPEG_VID_CODEC
+# define PJMEDIA_HAS_FFMPEG_VID_CODEC PJMEDIA_HAS_FFMPEG_CODEC
+#endif
+
+/**
+ * Enable FFMPEG H263+/H263-1998 codec.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_HAS_FFMPEG_CODEC_H263P
+# define PJMEDIA_HAS_FFMPEG_CODEC_H263P PJMEDIA_HAS_FFMPEG_VID_CODEC
+#endif
+
+/**
+ * Enable FFMPEG H264 codec (requires libx264).
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_FFMPEG_CODEC_H264
+# define PJMEDIA_HAS_FFMPEG_CODEC_H264 PJMEDIA_HAS_FFMPEG_VID_CODEC
+#endif
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __PJMEDIA_CODEC_CONFIG_H__ */
diff --git a/pjmedia/include/pjmedia-codec/config_auto.h.in b/pjmedia/include/pjmedia-codec/config_auto.h.in
new file mode 100644
index 0000000..887d083
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/config_auto.h.in
@@ -0,0 +1,80 @@
+/* $Id: config_auto.h.in 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_CONFIG_AUTO_H_
+#define __PJMEDIA_CODEC_CONFIG_AUTO_H_
+
+/**
+ * @file config_auto.h
+ * @brief PJMEDIA-CODEC configuration as set by autoconf script
+ */
+
+/*
+ * Note:
+ * The configuration in config_site.h overrides any other settings,
+ * including the setting as detected by autoconf.
+ */
+
+/* L16 codec */
+#ifndef PJMEDIA_HAS_L16_CODEC
+#undef PJMEDIA_HAS_L16_CODEC
+#endif
+
+
+/* GSM codec */
+#ifndef PJMEDIA_HAS_GSM_CODEC
+#undef PJMEDIA_HAS_GSM_CODEC
+#endif
+
+#undef PJMEDIA_EXTERNAL_GSM_CODEC
+#undef PJMEDIA_EXTERNAL_GSM_GSM_H
+#undef PJMEDIA_EXTERNAL_GSM_H
+
+/* Speex codec */
+#ifndef PJMEDIA_HAS_SPEEX_CODEC
+#undef PJMEDIA_HAS_SPEEX_CODEC
+#endif
+
+#undef PJMEDIA_EXTERNAL_SPEEX_CODEC
+
+/* iLBC codec */
+#ifndef PJMEDIA_HAS_ILBC_CODEC
+#undef PJMEDIA_HAS_ILBC_CODEC
+#endif
+
+
+/* G722 codec */
+#ifndef PJMEDIA_HAS_G722_CODEC
+#undef PJMEDIA_HAS_G722_CODEC
+#endif
+
+/* G7221 codec */
+#ifndef PJMEDIA_HAS_G7221_CODEC
+#undef PJMEDIA_HAS_G7221_CODEC
+#endif
+
+/* OpenCORE AMR-NB codec */
+#ifndef PJMEDIA_HAS_OPENCORE_AMRNB_CODEC
+#undef PJMEDIA_HAS_OPENCORE_AMRNB_CODEC
+#endif
+
+
+#endif /* __PJMEDIA_CODEC_CONFIG_AUTO_H_ */
+
+
diff --git a/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h b/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h
new file mode 100644
index 0000000..e238af2
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/ffmpeg_vid_codecs.h
@@ -0,0 +1,67 @@
+/* $Id: ffmpeg_vid_codecs.h 4049 2012-04-13 06:24:23Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODECS_FFMPEG_VID_H__
+#define __PJMEDIA_CODECS_FFMPEG_VID_H__
+
+
+#include <pjmedia-codec/types.h>
+#include <pjmedia/vid_codec.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_CODEC_VID_FFMPEG FFmpeg Codecs
+ * @ingroup PJMEDIA_CODEC_VID_CODECS
+ * @{
+ */
+
+/**
+ * Initialize and register FFMPEG video codecs factory to pjmedia endpoint.
+ *
+ * @param mgr The video codec manager instance where this codec will
+ * be registered to. Specify NULL to use default instance
+ * (in that case, an instance of video codec manager must
+ * have been created beforehand).
+ * @param pf Pool factory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr,
+ pj_pool_factory *pf);
+
+
+/**
+ * Unregister FFMPEG video codecs factory from the video codec manager and
+ * deinitialize the codecs library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ffmpeg_vid_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_FFMPEG_VID_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/g722.h b/pjmedia/include/pjmedia-codec/g722.h
new file mode 100644
index 0000000..8f5b72f
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/g722.h
@@ -0,0 +1,104 @@
+/* $Id: g722.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_G722_H__
+#define __PJMEDIA_CODEC_G722_H__
+
+/**
+ * @file pjmedia-codec/g722.h
+ * @brief G.722 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G722 G.722 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of G.722 Codec
+ * @{
+ *
+ * This section describes functions to initialize and register G.722 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The G.722 implementation uses 16-bit PCM with sampling rate 16000Hz and
+ * 20ms frame length resulting in 64kbps bitrate.
+ *
+ * The G.722 codec implementation is provided as part of pjmedia-codec
+ * library, and does not depend on external G.722 codec implementation.
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * Currently none.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register G.722 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g722_init(pjmedia_endpt *endpt);
+
+
+/**
+ * Unregister G.722 codec factory from pjmedia endpoint and cleanup
+ * resources allocated by the factory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g722_deinit(void);
+
+
+/**
+ * Set the G.722 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * Default value is PJMEDIA_G722_DEFAULT_PCM_SHIFT.
+ *
+ * @param val The value
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g722_set_pcm_shift(unsigned val);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_G722_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/g7221.h b/pjmedia/include/pjmedia-codec/g7221.h
new file mode 100644
index 0000000..596eee2
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/g7221.h
@@ -0,0 +1,162 @@
+/* $Id: g7221.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODECS_G7221_H__
+#define __PJMEDIA_CODECS_G7221_H__
+
+/**
+ * @file pjmedia-codec/g7221.h
+ * @brief G722.1 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G7221_CODEC G.722.1 Codec (Siren7/Siren14)
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of G.722.1 codec
+ * @{
+ *
+ * <b>G.722.1 licensed from Polycom®</b><br />
+ * <b>G.722.1 Annex C licensed from Polycom®</b>
+ *
+ * This section describes functions to initialize and register G.722.1 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * PJMEDIA G722.1 codec implementation is based on ITU-T Recommendation
+ * G.722.1 (05/2005) C fixed point implementation including its Annex C.
+ *
+ * G.722.1 is a low complexity codec that supports 7kHz and 14kHz audio
+ * bandwidth working at bitrates ranging from 16kbps to 48kbps. It may be
+ * used with speech or music inputs.
+ *
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * The following settings are applicable for this codec.
+ *
+ * \subsubsection bitrate Bitrate
+ *
+ * The codec implementation supports standard and non-standard bitrates.
+ * Use #pjmedia_codec_g7221_set_mode() to enable or disable the bitrates.
+ *
+ * By default, only standard bitrates are enabled upon initialization:
+ * - for 7kHz audio bandwidth (16kHz sampling rate): 24kbps and 32kbps,
+ * - for 14kHz audio bandwidth (32kHz sampling rate): 24kbps, 32kbps, and
+ * 48kbps.
+ *
+ * The usage of non-standard bitrates must follow these requirements:
+ * - for 7kHz audio bandwidth (16kHz sampling rate): 16000 to 32000 bps,
+ * multiplication of 400
+ * - for 14kHz audio bandwidth (32kHz sampling rate): 24000 to 48000 bps,
+ * multiplication of 400
+ *
+ * \note
+ * Currently only up to two non-standard modes can be enabled.
+ *
+ * \remark
+ * There is a flaw in the codec manager as currently it could not
+ * differentiate G.722.1 codecs by bitrates, hence invoking
+ * #pjmedia_codec_mgr_set_default_param() may only affect a G.722.1 codec
+ * with the highest priority (or first index found in codec enumeration
+ * when they have same priority) and invoking
+ * #pjmedia_codec_mgr_set_codec_priority() will set priority of all G.722.1
+ * codecs with sampling rate as specified.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Initialize and register G.722.1 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt );
+
+
+/**
+ * Enable and disable G.722.1 mode. By default, the standard modes are
+ * enabled upon initialization, i.e.:
+ * - sampling rate 16kHz, bitrate 24kbps and 32kbps.
+ * - sampling rate 32kHz, bitrate 24kbps, 32kbps, and 48kbps.
+ * This function can also be used for enabling non-standard modes.
+ * Note that currently only up to two non-standard modes can be enabled
+ * at one time.
+ *
+ * @param sample_rate PCM sampling rate, in Hz, valid values are only
+ * 16000 and 32000.
+ * @param bitrate G722.1 bitrate, in bps, the valid values are
+ * standard and non-standard bitrates as described
+ * above.
+ * @param enabled PJ_TRUE for enabling specified mode.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
+ unsigned bitrate,
+ pj_bool_t enabled);
+
+/**
+ * Set the G.722.1 codec encoder and decoder level adjustment.
+ * If the value is non-zero, then PCM input samples to the encoder will
+ * be shifted right by this value, and similarly PCM output samples from
+ * the decoder will be shifted left by this value.
+ *
+ * \note
+ * This function is also applicable for G722.1 implementation with IPP
+ * back-end.
+ *
+ * Default value is PJMEDIA_G7221_DEFAULT_PCM_SHIFT.
+ *
+ * @param val The value
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val);
+
+
+
+/**
+ * Unregister G.722.1 codecs factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_G7221_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/g7221_sdp_match.h b/pjmedia/include/pjmedia-codec/g7221_sdp_match.h
new file mode 100644
index 0000000..c3aa647
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/g7221_sdp_match.h
@@ -0,0 +1,59 @@
+/* $Id: g7221_sdp_match.h 3911 2011-12-15 06:45:23Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_G7221_SDP_MATCH_H__
+#define __PJMEDIA_CODEC_G7221_SDP_MATCH_H__
+
+
+/**
+ * @file g7221_sdp_match.h
+ * @brief Special SDP format match for G722.1.
+ */
+
+#include <pjmedia/sdp_neg.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Match G.722.1 format in the SDP media offer and answer. This function
+ * will match G.722.1 bitrate setting in the SDP format parameter of
+ * offer and answer.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the G.722.1 format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the G.722.1 format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g7221_match_sdp( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_G7221_SDP_MATCH_H__ */
diff --git a/pjmedia/include/pjmedia-codec/gsm.h b/pjmedia/include/pjmedia-codec/gsm.h
new file mode 100644
index 0000000..aa939d4
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/gsm.h
@@ -0,0 +1,87 @@
+/* $Id: gsm.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_GSM_H__
+#define __PJMEDIA_CODEC_GSM_H__
+
+/**
+ * @file pjmedia-codec/gsm.h
+ * @brief GSM 06.10 codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_GSM GSM 06.10 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of GSM FR based on GSM 06.10 library
+ * @{
+ *
+ * This section describes functions to initialize and register GSM codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The GSM codec supports 16-bit PCM with sampling rate of 8000Hz resulting
+ * in 13.2kbps bitrate.
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * Currently none.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register GSM codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_gsm_init( pjmedia_endpt *endpt );
+
+
+
+/**
+ * Unregister GSM codec factory from pjmedia endpoint and deinitialize
+ * the GSM codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_gsm_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_GSM_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/h263_packetizer.h b/pjmedia/include/pjmedia-codec/h263_packetizer.h
new file mode 100644
index 0000000..62644a0
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/h263_packetizer.h
@@ -0,0 +1,146 @@
+/* $Id: h263_packetizer.h 3715 2011-08-19 09:35:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_H263_PACKETIZER_H__
+#define __PJMEDIA_H263_PACKETIZER_H__
+
+
+/**
+ * @file h263_packetizer.h
+ * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload.
+ */
+
+#include <pj/pool.h>
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for H.263 packetizer.
+ */
+typedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer;
+
+
+/**
+ * Enumeration of H.263 packetization modes.
+ */
+typedef enum
+{
+ /**
+ * H.263 RTP packetization using RFC 4629.
+ */
+ PJMEDIA_H263_PACKETIZER_MODE_RFC4629,
+
+ /**
+ * H.263 RTP packetization using legacy RFC 2190.
+ * This is currently not supported.
+ */
+ PJMEDIA_H263_PACKETIZER_MODE_RFC2190,
+
+} pjmedia_h263_packetizer_mode;
+
+
+/**
+ * H.263 packetizer configuration.
+ */
+typedef struct pjmedia_h263_packetizer_cfg
+{
+ /**
+ * Maximum payload length.
+ * Default: PJMEDIA_MAX_MTU
+ */
+ int mtu;
+
+ /**
+ * Packetization mode.
+ * Default: PJMEDIA_H263_PACKETIZER_MODE_RFC4629
+ */
+ pjmedia_h263_packetizer_mode mode;
+
+} pjmedia_h263_packetizer_cfg;
+
+
+/**
+ * Create H.263 packetizer.
+ *
+ * @param pool The memory pool.
+ * @param cfg Packetizer settings, if NULL, default setting
+ * will be used.
+ * @param p_pktz Pointer to receive the packetizer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h263_packetizer_cfg *cfg,
+ pjmedia_h263_packetizer **p_pktz);
+
+
+/**
+ * Generate an RTP payload from a H.263 picture bitstream. Note that this
+ * function will apply in-place processing, so the bitstream may be modified
+ * during the packetization.
+ *
+ * @param pktz The packetizer.
+ * @param bits The picture bitstream to be packetized.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos The bitstream offset to be packetized.
+ * @param payload The output payload.
+ * @param payload_len The output payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
+
+
+/**
+ * Append an RTP payload to an H.263 picture bitstream. Note that in case of
+ * noticing packet lost, application should keep calling this function with
+ * payload pointer set to NULL, as the packetizer need to update its internal
+ * state.
+ *
+ * @param pktz The packetizer.
+ * @param payload The payload to be unpacketized.
+ * @param payload_len The payload length.
+ * @param bits The bitstream buffer.
+ * @param bits_size The bitstream buffer size.
+ * @param bits_pos The bitstream offset to put the unpacketized payload
+ * in the bitstream, upon return, this will be updated
+ * to the latest offset as a result of the unpacketized
+ * payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_unpacketize(pjmedia_h263_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_size,
+ unsigned *bits_pos);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_H263_PACKETIZER_H__ */
diff --git a/pjmedia/include/pjmedia-codec/h264_packetizer.h b/pjmedia/include/pjmedia-codec/h264_packetizer.h
new file mode 100644
index 0000000..4e26180
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/h264_packetizer.h
@@ -0,0 +1,157 @@
+/* $Id: h264_packetizer.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_H264_PACKETIZER_H__
+#define __PJMEDIA_H264_PACKETIZER_H__
+
+/**
+ * @file h264_packetizer.h
+ * @brief Packetizes H.264 bitstream into RTP payload and vice versa.
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Opaque declaration for H.264 packetizer.
+ */
+typedef struct pjmedia_h264_packetizer pjmedia_h264_packetizer;
+
+
+/**
+ * Enumeration of H.264 packetization modes.
+ */
+typedef enum
+{
+ /**
+ * Single NAL unit packetization mode will only generate payloads
+ * containing a complete single NAL unit packet. As H.264 NAL unit
+ * size can be very large, this mode is usually not applicable for
+ * network environments with MTU size limitation.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL,
+
+ /**
+ * Non-interleaved packetization mode will generate payloads with the
+ * following possible formats:
+ * - single NAL unit packets,
+ * - NAL units aggregation STAP-A packets,
+ * - fragmented NAL unit FU-A packets.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED,
+
+ /**
+ * Interleaved packetization mode will generate payloads with the
+ * following possible formats:
+ * - single NAL unit packets,
+ * - NAL units aggregation STAP-A & STAP-B packets,
+ * - fragmented NAL unit FU-A & FU-B packets.
+ * This packetization mode is currently unsupported.
+ */
+ PJMEDIA_H264_PACKETIZER_MODE_INTERLEAVED,
+} pjmedia_h264_packetizer_mode;
+
+
+/**
+ * H.264 packetizer setting.
+ */
+typedef struct pjmedia_h264_packetizer_cfg
+{
+ /**
+ * Maximum payload length.
+ * Default: PJMEDIA_MAX_MTU
+ */
+ int mtu;
+
+ /**
+ * Packetization mode.
+ * Default: PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED
+ */
+ pjmedia_h264_packetizer_mode mode;
+}
+pjmedia_h264_packetizer_cfg;
+
+
+/**
+ * Create H.264 packetizer.
+ *
+ * @param pool The memory pool.
+ * @param cfg Packetizer settings, if NULL, default setting
+ * will be used.
+ * @param p_pktz Pointer to receive the packetizer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h264_packetizer_cfg *cfg,
+ pjmedia_h264_packetizer **p_pktz);
+
+
+/**
+ * Generate an RTP payload from a H.264 picture bitstream. Note that this
+ * function will apply in-place processing, so the bitstream may be modified
+ * during the packetization.
+ *
+ * @param pktz The packetizer.
+ * @param bits The picture bitstream to be packetized.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos The bitstream offset to be packetized.
+ * @param payload The output payload.
+ * @param payload_len The output payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
+
+
+/**
+ * Append an RTP payload to an H.264 picture bitstream. Note that in case of
+ * noticing packet lost, application should keep calling this function with
+ * payload pointer set to NULL, as the packetizer need to update its internal
+ * state.
+ *
+ * @param pktz The packetizer.
+ * @param payload The payload to be unpacketized.
+ * @param payload_len The payload length.
+ * @param bits The bitstream buffer.
+ * @param bits_size The bitstream buffer size.
+ * @param bits_pos The bitstream offset to put the unpacketized payload
+ * in the bitstream, upon return, this will be updated
+ * to the latest offset as a result of the unpacketized
+ * payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos);
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_H264_PACKETIZER_H__ */
diff --git a/pjmedia/include/pjmedia-codec/ilbc.h b/pjmedia/include/pjmedia-codec/ilbc.h
new file mode 100644
index 0000000..c92f637
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/ilbc.h
@@ -0,0 +1,119 @@
+/* $Id: ilbc.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_ILBC_H__
+#define __PJMEDIA_CODEC_ILBC_H__
+
+/**
+ * @file pjmedia-codec/ilbc.h
+ * @brief iLBC codec.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_ILBC iLBC Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of iLBC Codec
+ * @{
+ *
+ * This section describes functions to initialize and register iLBC codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The iLBC codec is developed by Global IP Solutions (GIPS), formerly
+ * Global IP Sound. The iLBC offers low bitrate and graceful audio quality
+ * degradation on frame losses.
+ *
+ * The iLBC codec supports 16-bit PCM audio signal with sampling rate of
+ * 8000Hz operating at two modes: 20ms and 30ms frame length modes, resulting
+ * in bitrates of 15.2kbps for 20ms mode and 13.33kbps for 30ms mode.
+ *
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * The following settings are applicable for this codec.
+ *
+ * \subsubsection mode Mode
+ *
+ * The default mode should be set upon initialization, see
+ * #pjmedia_codec_ilbc_init(). After the codec is initialized, the default
+ * mode can be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, iLBC mode can be set by specifying SDP
+ * format parameter "mode" in the SDP "a=fmtp" attribute for decoding
+ * direction. Valid values are "20" and "30" (for 20ms and 30ms mode
+ * respectively).
+ *
+ * Here is an example to set up #pjmedia_codec_param to use mode 20ms:
+ * \code
+ pjmedia_codec_param param;
+ ...
+ // setting iLBC mode in SDP
+ param.setting.dec_fmtp.cnt = 1;
+ param.setting.dec_fmtp.param[0].name = pj_str("mode");
+ param.setting.dec_fmtp.param[0].val = pj_str("20");
+ ...
+ \endcode
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register iLBC codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param mode Default decoder mode to be used. Valid values are
+ * 20 and 30 ms. Note that encoder mode follows the
+ * setting advertised in the remote's SDP.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
+ int mode );
+
+
+
+/**
+ * Unregister iLBC codec factory from pjmedia endpoint and deinitialize
+ * the iLBC codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ilbc_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_ILBC_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/ipp_codecs.h b/pjmedia/include/pjmedia-codec/ipp_codecs.h
new file mode 100644
index 0000000..3544367
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/ipp_codecs.h
@@ -0,0 +1,322 @@
+/* $Id: ipp_codecs.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODECS_IPP_H__
+#define __PJMEDIA_CODECS_IPP_H__
+
+/**
+ * @file pjmedia-codec/ipp_codecs.h
+ * @brief IPP codecs wrapper.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_IPP_CODEC IPP Codecs
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of IPP codecs
+ * @{
+ *
+ * This section describes functions to initialize and register IPP codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * This codec factory contains various codecs, i.e: G.729, G.723.1, G.726,
+ * G.728, G.722.1, AMR, and AMR-WB.
+ *
+ *
+ * \section pjmedia_codec_ipp_g729 IPP G.729
+ *
+ * IPP G.729 is compliant with ITU-T G.729 and Annexes A, B, C, C+, D,
+ * E, I specifications. However, currently the pjmedia implementation is
+ * using Annexes A and B only.
+ *
+ * IPP G.729 supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * frame length 10ms, and resulting in bitrate 8000bps (annexes D and E
+ * introduce bitrates 6400bps and 11800bps).
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * Note that G.729 VAD status should be signalled in SDP, see more
+ * description below.
+ *
+ * \subsubsection annexb Annex B
+ *
+ * The capability of VAD/DTX is specified in Annex B.
+ *
+ * By default, Annex B is enabled. This default setting of Annex B can
+ * be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, Annex B is configured via VAD setting and
+ * format parameter "annexb" in the SDP "a=fmtp" attribute in
+ * decoding fmtp field. Valid values are "yes" and "no",
+ * the implementation default is "yes". When this parameter is omitted
+ * in the SDP, the value will be "yes" (RFC 4856 Section 2.1.9).
+ *
+ * Here is an example of modifying default setting of Annex B to
+ * be disabled using #pjmedia_codec_mgr_set_default_param():
+ \code
+ pjmedia_codec_param param;
+
+ pjmedia_codec_mgr_get_default_param(.., &param);
+ ...
+ // Set VAD
+ param.setting.vad = 0;
+ // Set SDP format parameter
+ param.setting.dec_fmtp.cnt = 1;
+ param.setting.dec_fmtp.param[0].name = pj_str("annexb");
+ param.setting.dec_fmtp.param[0].val = pj_str("no");
+ ...
+ pjmedia_codec_mgr_set_default_param(.., &param);
+ \endcode
+ *
+ * \note
+ * The difference of Annex B status in SDP offer/answer may be considered as
+ * incompatible codec in SDP negotiation.
+ *
+ *
+ * \section pjmedia_codec_ipp_g7231 IPP G.723.1
+ *
+ * IPP G.723.1 speech codec is compliant with ITU-T G.723.1 and Annex A
+ * specifications.
+ *
+ * IPP G.723.1 supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * frame length 30ms, and resulting in bitrates 5300bps and 6300bps.
+ *
+ * By default, pjmedia implementation uses encoding bitrate of 6300bps.
+ * The bitrate is signalled in-band in G.723.1 frames and interoperable.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ *
+ * \section pjmedia_codec_ipp_g726 IPP G.726
+ *
+ * IPP G.726 is compliant with ITU-T G.726 and G.726 Annex A specifications.
+ *
+ * IPP G.726 supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * 10ms frame length and producing 16kbps, 24kbps, 32kbps, 48kbps bitrates.
+ * The bitrate is specified explicitly in its encoding name, i.e: G726-16,
+ * G726-24, G726-32, G726-48.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ *
+ * \section pjmedia_codec_ipp_g728 IPP G.728
+ *
+ * IPP G.728 is compliant with ITU-T G.728 with I, G, H Appendixes
+ * specifications for Low-Delay CELP coder.
+ *
+ * IPP G.728 supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * 20ms frame length and producing 9.6kbps, 12.8kbps, and 16kbps bitrates.
+ *
+ * The pjmedia implementation currently uses 16kbps bitrate only.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ *
+ * \section pjmedia_codec_ipp_g7221 IPP G.722.1
+ *
+ * The pjmedia implementation of IPP G.722.1 supports 16-bit PCM audio
+ * signal with sampling rate 16000Hz, 20ms frame length and producing
+ * 16kbps, 24kbps, and 32kbps bitrates.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsubsection bitrate Bitrate
+ *
+ * The codec implementation supports only standard bitrates, i.e:
+ * 24kbps and 32kbps. Both are enabled by default.
+ *
+ * \remark
+ * There is a flaw in the codec manager as currently it could not
+ * differentiate G.722.1 codecs by bitrates, hence invoking
+ * #pjmedia_codec_mgr_set_default_param() may only affect a G.722.1 codec
+ * with the highest priority (or first index found in codec enumeration
+ * when they have same priority) and invoking
+ * #pjmedia_codec_mgr_set_codec_priority() will set priority of all G.722.1
+ * codecs with sampling rate as specified.
+ *
+ *
+ * \section pjmedia_codec_ipp_amr IPP AMR
+ *
+ * The IPP AMR is compliant with GSM06.90-94 specifications for GSM Adaptive
+ * Multi-Rate codec.
+ *
+ * IPP AMR supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * 20ms frame length and producing various bitrates that ranges from 4.75kbps
+ * to 12.2kbps.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsubsection bitrate Bitrate
+ *
+ * By default, encoding bitrate is 7400bps. This default setting can be
+ * modified using #pjmedia_codec_mgr_set_default_param() by specifying
+ * prefered AMR bitrate in field <tt>info::avg_bps</tt> of
+ * #pjmedia_codec_param. Valid bitrates could be seen in
+ * #pjmedia_codec_amrnb_bitrates.
+ *
+ * \subsubsection payload_format Payload Format
+ *
+ * There are two AMR payload format types, bandwidth-efficient and
+ * octet-aligned. Default setting is using octet-aligned. This default payload
+ * format can be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, payload format can be set by specifying SDP
+ * format parameters "octet-align" in the SDP "a=fmtp" attribute for
+ * decoding direction. Valid values are "0" (for bandwidth efficient mode)
+ * and "1" (for octet-aligned mode).
+ *
+ * \subsubsection mode_set Mode-Set
+ *
+ * Mode-set is used for restricting AMR modes in decoding direction.
+ *
+ * By default, no mode-set restriction applied. This default setting can be
+ * be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, mode-set could be specified via format parameters
+ * "mode-set" in the SDP "a=fmtp" attribute for decoding direction. Valid
+ * value is a comma separated list of modes from the set 0 - 7, e.g:
+ * "4,5,6,7". When this parameter is omitted, no mode-set restrictions applied.
+ *
+ * Here is an example of modifying AMR default codec param:
+ \code
+ pjmedia_codec_param param;
+
+ pjmedia_codec_mgr_get_default_param(.., &param);
+ ...
+ // set default encoding bitrate to the highest 12.2kbps
+ param.info.avg_bps = 12200;
+
+ // restrict decoding bitrate to 10.2kbps and 12.2kbps only
+ param.setting.dec_fmtp.param[0].name = pj_str("mode-set");
+ param.setting.dec_fmtp.param[0].val = pj_str("6,7");
+
+ // also set to use bandwidth-efficient payload format
+ param.setting.dec_fmtp.param[1].name = pj_str("octet-align");
+ param.setting.dec_fmtp.param[1].val = pj_str("0");
+
+ param.setting.dec_fmtp.cnt = 2;
+ ...
+ pjmedia_codec_mgr_set_default_param(.., &param);
+ \endcode
+ *
+ *
+ * \section pjmedia_codec_ipp_amrwb IPP AMR-WB
+ *
+ * The IPP AMR-WB is compliant with 3GPP TS 26.190-192, 194, 201
+ * specifications for Adaptive Multi-Rate WideBand codec.
+ *
+ * IPP AMR-WB supports 16-bit PCM audio signal with sampling rate 16000Hz,
+ * 20ms frame length and producing various bitrates. Valid bitrates could be
+ * seen in #pjmedia_codec_amrwb_bitrates. The pjmedia implementation default
+ * bitrate is 15850bps.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsubsection bitrate Bitrate
+ *
+ * By default, encoding bitrate is 15850bps. This default setting can be
+ * modified using #pjmedia_codec_mgr_set_default_param() by specifying
+ * prefered AMR bitrate in field <tt>info::avg_bps</tt> of
+ * #pjmedia_codec_param.
+ *
+ * \subsubsection payload_format Payload Format
+ *
+ * There are two AMR payload format types, bandwidth-efficient and
+ * octet-aligned. Default setting is using octet-aligned. This default payload
+ * format can be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, payload format can be set by specifying SDP
+ * format parameters "octet-align" in the SDP "a=fmtp" attribute for
+ * decoding direction. Valid values are "0" (for bandwidth efficient mode)
+ * and "1" (for octet-aligned mode).
+ *
+ * \subsubsection mode_set Mode-Set
+ *
+ * Mode-set is used for restricting AMR modes in decoding direction.
+ *
+ * By default, no mode-set restriction applied. This default setting can be
+ * be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, mode-set could be specified via format parameters
+ * "mode-set" in the SDP "a=fmtp" attribute for decoding direction. Valid
+ * value is a comma separated list of modes from the set 0 - 7, e.g:
+ * "4,5,6,7". When this parameter is omitted, no mode-set restrictions applied.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register IPP codecs factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt );
+
+
+/**
+ * Unregister IPP codecs factory from pjmedia endpoint and deinitialize
+ * the IPP codecs library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_ipp_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_IPP_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/l16.h b/pjmedia/include/pjmedia-codec/l16.h
new file mode 100644
index 0000000..04b50d0
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/l16.h
@@ -0,0 +1,81 @@
+/* $Id: l16.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_L16_H__
+#define __PJMEDIA_CODEC_L16_H__
+
+#include <pjmedia-codec/types.h>
+
+
+/**
+ * @defgroup PJMED_L16 L16 Codec Family
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of PCM/16bit/linear codecs
+ * @{
+ *
+ * This section describes functions to initialize and register L16 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * Note that the L16 codec factory registers several (about fourteen!)
+ * L16 codec types to codec manager (different combinations of clock
+ * rate and number of channels).
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * Currently none.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register L16 codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param options Must be zero for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_l16_init( pjmedia_endpt *endpt,
+ unsigned options);
+
+
+
+/**
+ * Unregister L16 codec factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_l16_deinit(void);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_L16_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/opencore_amrnb.h b/pjmedia/include/pjmedia-codec/opencore_amrnb.h
new file mode 100644
index 0000000..aedb460
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/opencore_amrnb.h
@@ -0,0 +1,89 @@
+/* $Id: opencore_amrnb.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2011 Dan Arrhenius <dan@keystream.se>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_OPENCORE_AMRNB_H__
+#define __PJMEDIA_CODEC_OPENCORE_AMRNB_H__
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_OC_AMRNB OpenCORE AMR-NB Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief AMRCodec wrapper for OpenCORE AMR-NB codec
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Settings. Use #pjmedia_codec_opencore_amrnb_set_config() to
+ * activate.
+ */
+typedef struct pjmedia_codec_amrnb_config
+{
+ /**
+ * Control whether to use octent align.
+ */
+ pj_bool_t octet_align;
+
+ /**
+ * Set the bitrate.
+ */
+ unsigned bitrate;
+
+} pjmedia_codec_amrnb_config;
+
+
+/**
+ * Initialize and register AMR-NB codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_opencore_amrnb_init(pjmedia_endpt* endpt);
+
+/**
+ * Unregister AMR-NB codec factory from pjmedia endpoint and deinitialize
+ * the OpenCORE codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_opencore_amrnb_deinit(void);
+
+
+/**
+ * Set AMR-NB parameters.
+ *
+ * @param cfg The settings;
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_opencore_amrnb_set_config(
+ const pjmedia_codec_amrnb_config* cfg);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_OPENCORE_AMRNB_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/passthrough.h b/pjmedia/include/pjmedia-codec/passthrough.h
new file mode 100644
index 0000000..775af19
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/passthrough.h
@@ -0,0 +1,277 @@
+/* $Id: passthrough.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODECS_PASSTHROUGH_H__
+#define __PJMEDIA_CODECS_PASSTHROUGH_H__
+
+/**
+ * @file pjmedia-codec/passthrough.h
+ * @brief Passthrough codecs.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_PASSTHROUGH_CODEC Passthrough Codecs
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of passthrough codecs
+ * @{
+ *
+ * This section describes functions to initialize and register passthrough
+ * codecs factory to the codec manager. After the codec factory has been
+ * registered, application can use @ref PJMEDIA_CODEC API to manipulate
+ * the codec.
+ *
+ * Passthrough codecs are codecs wrapper that does NOT perform encoding
+ * or decoding, it just PACK and PARSE encoded audio data from/into RTP
+ * payload. This will accomodate pjmedia ports which work with encoded
+ * audio data, e.g: encoded audio files, sound device with capability
+ * of playing/recording encoded audio data.
+ *
+ * This codec factory contains various codecs, i.e: G.729, iLBC,
+ * AMR, and G.711.
+ *
+ *
+ * \section pjmedia_codec_passthrough_g729 Passthrough G.729
+ *
+ * G.729 supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * frame length 10ms, and resulting in bitrate 8000bps.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * Note that G.729 VAD status should be signalled in SDP, see more
+ * description below.
+ *
+ * \subsubsection annexb Annex B
+ *
+ * The capability of VAD/DTX is specified in Annex B.
+ *
+ * By default, Annex B is enabled. This default setting of Annex B can
+ * be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, Annex B is configured via VAD setting and
+ * format parameter "annexb" in the SDP "a=fmtp" attribute in
+ * decoding fmtp field. Valid values are "yes" and "no",
+ * the implementation default is "yes". When this parameter is omitted
+ * in the SDP, the value will be "yes" (RFC 4856 Section 2.1.9).
+ *
+ * Here is an example of modifying default setting of Annex B to
+ * be disabled using #pjmedia_codec_mgr_set_default_param():
+ \code
+ pjmedia_codec_param param;
+
+ pjmedia_codec_mgr_get_default_param(.., &param);
+ ...
+ // Set VAD
+ param.setting.vad = 0;
+ // Set SDP format parameter
+ param.setting.dec_fmtp.cnt = 1;
+ param.setting.dec_fmtp.param[0].name = pj_str("annexb");
+ param.setting.dec_fmtp.param[0].val = pj_str("no");
+ ...
+ pjmedia_codec_mgr_set_default_param(.., &param);
+ \endcode
+ *
+ * \note
+ * The difference of Annex B status in SDP offer/answer may be considered as
+ * incompatible codec in SDP negotiation.
+ *
+ *
+ * \section pjmedia_codec_passthrough_ilbc Passthrough iLBC
+ *
+ * The iLBC codec is developed by Global IP Solutions (GIPS), formerly
+ * Global IP Sound. The iLBC offers low bitrate and graceful audio quality
+ * degradation on frame losses.
+ *
+ * The iLBC codec supports 16-bit PCM audio signal with sampling rate of
+ * 8000Hz operating at two modes: 20ms and 30ms frame length modes, resulting
+ * in bitrates of 15.2kbps for 20ms mode and 13.33kbps for 30ms mode.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsubsection mode Mode
+ *
+ * The default mode should be set upon initialization, see
+ * #pjmedia_codec_passthrough_init2(). After the codec is initialized, the
+ * default mode can be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, iLBC mode can be set by specifying SDP
+ * format parameter "mode" in the SDP "a=fmtp" attribute for decoding
+ * direction. Valid values are "20" and "30" (for 20ms and 30ms mode
+ * respectively).
+ *
+ * Here is an example to set up #pjmedia_codec_param to use mode 20ms:
+ * \code
+ pjmedia_codec_param param;
+ ...
+ // setting iLBC mode in SDP
+ param.setting.dec_fmtp.cnt = 1;
+ param.setting.dec_fmtp.param[0].name = pj_str("mode");
+ param.setting.dec_fmtp.param[0].val = pj_str("20");
+ ...
+ \endcode
+ *
+ *
+ * \section pjmedia_codec_passthrough_amr Passthrough AMR
+ *
+ * IPP AMR supports 16-bit PCM audio signal with sampling rate 8000Hz,
+ * 20ms frame length and producing various bitrates that ranges from 4.75kbps
+ * to 12.2kbps.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsubsection bitrate Bitrate
+ *
+ * By default, encoding bitrate is 7400bps. This default setting can be
+ * modified using #pjmedia_codec_mgr_set_default_param() by specifying
+ * prefered AMR bitrate in field <tt>info::avg_bps</tt> of
+ * #pjmedia_codec_param. Valid bitrates could be seen in
+ * #pjmedia_codec_amrnb_bitrates.
+ *
+ * \subsubsection payload_format Payload Format
+ *
+ * There are two AMR payload format types, bandwidth-efficient and
+ * octet-aligned. Default setting is using octet-aligned. This default payload
+ * format can be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, payload format can be set by specifying SDP
+ * format parameters "octet-align" in the SDP "a=fmtp" attribute for
+ * decoding direction. Valid values are "0" (for bandwidth efficient mode)
+ * and "1" (for octet-aligned mode).
+ *
+ * \subsubsection mode_set Mode-Set
+ *
+ * Mode-set is used for restricting AMR modes in decoding direction.
+ *
+ * By default, no mode-set restriction applied. This default setting can be
+ * be modified using #pjmedia_codec_mgr_set_default_param().
+ *
+ * In #pjmedia_codec_param, mode-set could be specified via format parameters
+ * "mode-set" in the SDP "a=fmtp" attribute for decoding direction. Valid
+ * value is a comma separated list of modes from the set 0 - 7, e.g:
+ * "4,5,6,7". When this parameter is omitted, no mode-set restrictions applied.
+ *
+ * Here is an example of modifying AMR default codec param:
+ \code
+ pjmedia_codec_param param;
+
+ pjmedia_codec_mgr_get_default_param(.., &param);
+ ...
+ // set default encoding bitrate to the highest 12.2kbps
+ param.info.avg_bps = 12200;
+
+ // restrict decoding bitrate to 10.2kbps and 12.2kbps only
+ param.setting.dec_fmtp.param[0].name = pj_str("mode-set");
+ param.setting.dec_fmtp.param[0].val = pj_str("6,7");
+
+ // also set to use bandwidth-efficient payload format
+ param.setting.dec_fmtp.param[1].name = pj_str("octet-align");
+ param.setting.dec_fmtp.param[1].val = pj_str("0");
+
+ param.setting.dec_fmtp.cnt = 2;
+ ...
+ pjmedia_codec_mgr_set_default_param(.., &param);
+ \endcode
+ *
+ *
+ * \section pjmedia_codec_passthrough_g711 Passthrough G.711
+ *
+ * The G.711 is an ultra low complexity codecs and in trade-off it results
+ * in high bitrate, i.e: 64kbps for 16-bit PCM with sampling rate 8000Hz.
+ *
+ * The factory contains two main compression algorithms, PCMU/u-Law and
+ * PCMA/A-Law.
+ *
+ * \subsection codec_setting Codec Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Codec passthrough configuration settings.
+ */
+typedef struct pjmedia_codec_passthrough_setting
+{
+ unsigned fmt_cnt; /**< Number of encoding formats
+ to be enabled. */
+ pjmedia_format *fmts; /**< Encoding formats to be
+ enabled. */
+ unsigned ilbc_mode; /**< iLBC default mode. */
+} pjmedia_codec_passthrough_setting;
+
+
+/**
+ * Initialize and register passthrough codecs factory to pjmedia endpoint,
+ * all supported encoding formats will be enabled.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init( pjmedia_endpt *endpt );
+
+
+/**
+ * Initialize and register passthrough codecs factory to pjmedia endpoint
+ * with only specified encoding formats enabled.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param setting The settings.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_init2(
+ pjmedia_endpt *endpt,
+ const pjmedia_codec_passthrough_setting *setting);
+
+
+/**
+ * Unregister passthrough codecs factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_passthrough_deinit(void);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODECS_PASSTHROUGH_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/speex.h b/pjmedia/include/pjmedia-codec/speex.h
new file mode 100644
index 0000000..12b3fa4
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/speex.h
@@ -0,0 +1,150 @@
+/* $Id: speex.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_SPEEX_H__
+#define __PJMEDIA_CODEC_SPEEX_H__
+
+/**
+ * @file speex.h
+ * @brief Speex codec header.
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_SPEEX Speex Codec Family
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Implementation of Speex codecs (narrow/wide/ultrawide-band).
+ * @{
+ *
+ * This section describes functions to initialize and register speex codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The Speex codec uses multiple bit rates, and supports ultra-wideband
+ * (32 kHz sampling rate), wideband (16 kHz sampling rate) and narrowband
+ * (telephone quality, 8 kHz sampling rate)
+ *
+ * By default, the speex codec factory registers three Speex codecs:
+ * "speex/8000" narrowband codec, "speex/16000" wideband codec, and
+ * "speex/32000" ultra-wideband codec. This behavior can be changed by
+ * specifying #pjmedia_speex_options flags during initialization.
+ *
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * The following settings are applicable for this codec.
+ *
+ * \subsubsection quality_vs_complexity Quality vs Complexity
+ *
+ * The Speex codec quality versus computational complexity and bandwidth
+ * requirement can be adjusted by modifying the quality and complexity
+ * setting, by calling #pjmedia_codec_speex_set_param(). The RFC 5574
+ * Section 5 shows the relationship between quality setting and the
+ * resulting bitrate.
+ *
+ * The default setting of quality is specified in
+ * #PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY. And the default setting of
+ * complexity is specified in #PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Bitmask options to be passed during Speex codec factory initialization.
+ */
+enum pjmedia_speex_options
+{
+ PJMEDIA_SPEEX_NO_NB = 1, /**< Disable narrowband mode. */
+ PJMEDIA_SPEEX_NO_WB = 2, /**< Disable wideband mode. */
+ PJMEDIA_SPEEX_NO_UWB = 4, /**< Disable ultra-wideband mode. */
+};
+
+
+/**
+ * Initialize and register Speex codec factory to pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ * @param options Bitmask of pjmedia_speex_options (default=0).
+ * @param quality Specify encoding quality, or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).
+ * @param complexity Specify encoding complexity , or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_init( pjmedia_endpt *endpt,
+ unsigned options,
+ int quality,
+ int complexity );
+
+
+/**
+ * Initialize Speex codec factory using default settings and register to
+ * pjmedia endpoint.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_init_default(pjmedia_endpt *endpt);
+
+
+/**
+ * Change the settings of Speex codec.
+ *
+ * @param clock_rate Clock rate of Speex mode to be set.
+ * @param quality Specify encoding quality, or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY).
+ * @param complexity Specify encoding complexity , or use -1 for default
+ * (@see PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_set_param(unsigned clock_rate,
+ int quality,
+ int complexity);
+
+
+/**
+ * Unregister Speex codec factory from pjmedia endpoint and deinitialize
+ * the Speex codec library.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_speex_deinit(void);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_CODEC_SPEEX_H__ */
+
diff --git a/pjmedia/include/pjmedia-codec/types.h b/pjmedia/include/pjmedia-codec/types.h
new file mode 100644
index 0000000..a18fa30
--- /dev/null
+++ b/pjmedia/include/pjmedia-codec/types.h
@@ -0,0 +1,126 @@
+/* $Id: types.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_TYPES_H__
+#define __PJMEDIA_CODEC_TYPES_H__
+
+/**
+ * @file types.h
+ * @brief PJMEDIA-CODEC types and constants
+ */
+
+#include <pjmedia-codec/config.h>
+#include <pjmedia/codec.h>
+
+/**
+ * @defgroup pjmedia_codec_types PJMEDIA-CODEC Types and Constants
+ * @ingroup PJMEDIA_CODEC
+ * @brief Constants used by PJMEDIA-CODEC
+ * @{
+ */
+
+
+
+/**
+ * These are the dynamic payload types that are used by audio codecs in
+ * this library. Also see the header file <pjmedia/codec.h> for list
+ * of static payload types.
+ */
+enum pjmedia_audio_pt
+{
+ /* According to IANA specifications, dynamic payload types are to be in
+ * the range 96-127 (inclusive). This enum is structured to place the
+ * values of the payload types specified below into that range.
+ *
+ * PJMEDIA_RTP_PT_DYNAMIC is defined in <pjmedia/codec.h>. It is defined
+ * to be 96.
+ *
+ * PJMEDIA_RTP_PT_TELEPHONE_EVENTS is defined in <pjmedia/config.h>.
+ * The default value is 96.
+ */
+#if PJMEDIA_RTP_PT_TELEPHONE_EVENTS
+ PJMEDIA_RTP_PT_START = PJMEDIA_RTP_PT_TELEPHONE_EVENTS,
+#else
+ PJMEDIA_RTP_PT_START = (PJMEDIA_RTP_PT_DYNAMIC-1),
+#endif
+
+ PJMEDIA_RTP_PT_SPEEX_NB, /**< Speex narrowband/8KHz */
+ PJMEDIA_RTP_PT_SPEEX_WB, /**< Speex wideband/16KHz */
+ PJMEDIA_RTP_PT_SPEEX_UWB, /**< Speex 32KHz */
+ PJMEDIA_RTP_PT_L16_8KHZ_MONO, /**< L16 @ 8KHz, mono */
+ PJMEDIA_RTP_PT_L16_8KHZ_STEREO, /**< L16 @ 8KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_11KHZ_MONO, /**< L16 @ 11KHz, mono */
+ //PJMEDIA_RTP_PT_L16_11KHZ_STEREO, /**< L16 @ 11KHz, stereo */
+ PJMEDIA_RTP_PT_L16_16KHZ_MONO, /**< L16 @ 16KHz, mono */
+ PJMEDIA_RTP_PT_L16_16KHZ_STEREO, /**< L16 @ 16KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_22KHZ_MONO, /**< L16 @ 22KHz, mono */
+ //PJMEDIA_RTP_PT_L16_22KHZ_STEREO, /**< L16 @ 22KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_32KHZ_MONO, /**< L16 @ 32KHz, mono */
+ //PJMEDIA_RTP_PT_L16_32KHZ_STEREO, /**< L16 @ 32KHz, stereo */
+ //PJMEDIA_RTP_PT_L16_48KHZ_MONO, /**< L16 @ 48KHz, mono */
+ //PJMEDIA_RTP_PT_L16_48KHZ_STEREO, /**< L16 @ 48KHz, stereo */
+ PJMEDIA_RTP_PT_ILBC, /**< iLBC (13.3/15.2Kbps) */
+ PJMEDIA_RTP_PT_AMR, /**< AMR (4.75 - 12.2Kbps) */
+ PJMEDIA_RTP_PT_AMRWB, /**< AMRWB (6.6 - 23.85Kbps)*/
+ PJMEDIA_RTP_PT_AMRWBE, /**< AMRWBE */
+ PJMEDIA_RTP_PT_G726_16, /**< G726 @ 16Kbps */
+ PJMEDIA_RTP_PT_G726_24, /**< G726 @ 24Kbps */
+ PJMEDIA_RTP_PT_G726_32, /**< G726 @ 32Kbps */
+ PJMEDIA_RTP_PT_G726_40, /**< G726 @ 40Kbps */
+ PJMEDIA_RTP_PT_G722_1_16, /**< G722.1 (16Kbps) */
+ PJMEDIA_RTP_PT_G722_1_24, /**< G722.1 (24Kbps) */
+ PJMEDIA_RTP_PT_G722_1_32, /**< G722.1 (32Kbps) */
+ PJMEDIA_RTP_PT_G7221C_24, /**< G722.1 Annex C (24Kbps)*/
+ PJMEDIA_RTP_PT_G7221C_32, /**< G722.1 Annex C (32Kbps)*/
+ PJMEDIA_RTP_PT_G7221C_48, /**< G722.1 Annex C (48Kbps)*/
+ PJMEDIA_RTP_PT_G7221_RSV1, /**< G722.1 reserve */
+ PJMEDIA_RTP_PT_G7221_RSV2, /**< G722.1 reserve */
+
+ /* Caution!
+ * Ensure the value of the last pt above is <= 127.
+ */
+};
+
+/**
+ * These are the dynamic payload types that are used by video codecs in
+ * this library.
+ */
+enum pjmedia_video_pt
+{
+ /* Video payload types */
+ PJMEDIA_RTP_PT_VID_START = (PJMEDIA_RTP_PT_DYNAMIC-1),
+ PJMEDIA_RTP_PT_H263P,
+ PJMEDIA_RTP_PT_H264,
+ PJMEDIA_RTP_PT_H264_RSV1,
+ PJMEDIA_RTP_PT_H264_RSV2,
+ PJMEDIA_RTP_PT_H264_RSV3,
+ PJMEDIA_RTP_PT_H264_RSV4,
+
+ /* Caution!
+ * Ensure the value of the last pt above is <= 127.
+ */
+};
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CODEC_TYPES_H__ */
diff --git a/pjmedia/include/pjmedia-videodev/avi_dev.h b/pjmedia/include/pjmedia-videodev/avi_dev.h
new file mode 100644
index 0000000..e5b1e8e
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/avi_dev.h
@@ -0,0 +1,139 @@
+/* $Id: avi_dev.h 4016 2012-04-04 05:05:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef PJMEDIA_VIDEODEV_AVI_DEV_H__
+#define PJMEDIA_VIDEODEV_AVI_DEV_H__
+
+/**
+ * @file avi_dev.h
+ * @brief AVI player virtual device
+ */
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia/avi_stream.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup avi_dev AVI Player Virtual Device
+ * @ingroup video_device_api
+ * @brief AVI player virtual device
+ * @{
+ * This describes a virtual capture device which takes its input from an AVI
+ * file.
+ */
+
+/**
+ * Settings for the AVI player virtual device. This param corresponds to
+ * PJMEDIA_VID_DEV_CAP_AVI_PLAY capability of the video device/stream.
+ */
+typedef struct pjmedia_avi_dev_param
+{
+ /**
+ * Specifies the full path of the AVI file to be played.
+ */
+ pj_str_t path;
+
+ /**
+ * If this setting is specified when setting the device, this specifies
+ * the title to be assigned as the device name. If this setting not
+ * specified, the filename part of the path will be used.
+ */
+ pj_str_t title;
+
+ /**
+ * The underlying AVI streams created by the device. If the value is NULL,
+ * that means the device has not been configured yet. Application can use
+ * this field to retrieve the audio stream of the AVI. This setting is
+ * "get"-only and will be ignored in "set capability" operation.
+ */
+ pjmedia_avi_streams *avi_streams;
+
+} pjmedia_avi_dev_param;
+
+
+/**
+ * Reset pjmedia_avi_dev_param with the default settings. This mostly will
+ * reset all values to NULL or zero.
+ *
+ * @param p The parameter to be initialized.
+ */
+PJ_DECL(void) pjmedia_avi_dev_param_default(pjmedia_avi_dev_param *p);
+
+
+/**
+ * Create a AVI device factory, and register it to the video device
+ * subsystem. At least one factory needs to be created before an AVI
+ * device can be allocated and used, and normally only one factory is
+ * needed per application.
+ *
+ * @param pf Pool factory to be used.
+ * @param max_dev Number of devices to be reserved.
+ * @param p_ret Pointer to return the factory instance, to be
+ * used when allocating a virtual device.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_avi_dev_create_factory(
+ pj_pool_factory *pf,
+ unsigned max_dev,
+ pjmedia_vid_dev_factory **p_ret);
+
+/**
+ * Allocate one device ID to be used to play the specified AVI file in
+ * the parameter.
+ *
+ * @param param The parameter, with at least the AVI file path
+ * set.
+ * @param p_id Optional pointer to receive device ID to play
+ * the file.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ *
+ */
+PJ_DECL(pj_status_t) pjmedia_avi_dev_alloc(pjmedia_vid_dev_factory *f,
+ pjmedia_avi_dev_param *param,
+ pjmedia_vid_dev_index *p_id);
+
+/**
+ * Retrieve the parameters set for the virtual device.
+ *
+ * @param id Device ID.
+ * @param prm Structure to receive the settings.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_avi_dev_get_param(pjmedia_vid_dev_index id,
+ pjmedia_avi_dev_param *param);
+
+/**
+ * Free the resources associated with the virtual device.
+ *
+ * @param id The device ID.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_avi_dev_free(pjmedia_vid_dev_index id);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* PJMEDIA_VIDEODEV_AVI_DEV_H__ */
diff --git a/pjmedia/include/pjmedia-videodev/config.h b/pjmedia/include/pjmedia-videodev/config.h
new file mode 100644
index 0000000..12a251a
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/config.h
@@ -0,0 +1,203 @@
+/* $Id: config.h 4016 2012-04-04 05:05:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_CONFIG_H__
+#define __PJMEDIA_VIDEODEV_CONFIG_H__
+
+/**
+ * @file config.h
+ * @brief Video config.
+ */
+#include <pjmedia/types.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_api Video Device API
+ * @brief PJMEDIA video device abstraction API.
+ */
+
+/**
+ * @defgroup s1_video_device_config Compile time configurations
+ * @ingroup video_device_api
+ * @brief Compile time configurations
+ * @{
+ */
+
+/**
+ * This setting controls the maximum number of formats that can be
+ * supported by a video device.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_VID_DEV_INFO_FMT_CNT
+# define PJMEDIA_VID_DEV_INFO_FMT_CNT 16
+#endif
+
+
+/**
+ * This setting controls whether SDL support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_SDL
+# define PJMEDIA_VIDEO_DEV_HAS_SDL 0
+# define PJMEDIA_VIDEO_DEV_SDL_HAS_OPENGL 0
+#endif
+
+
+/**
+ * This setting controls whether QT support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_QT
+# define PJMEDIA_VIDEO_DEV_HAS_QT 0
+#endif
+
+
+/**
+ * This setting controls whether IOS support should be included.
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_IOS
+# define PJMEDIA_VIDEO_DEV_HAS_IOS 0
+#endif
+
+
+/**
+ * This setting controls whether Direct Show support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_DSHOW
+# define PJMEDIA_VIDEO_DEV_HAS_DSHOW 0 //PJ_WIN32
+#endif
+
+
+/**
+ * This setting controls whether colorbar source support should be included.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC
+# define PJMEDIA_VIDEO_DEV_HAS_CBAR_SRC 1
+#endif
+
+
+/**
+ * This setting controls whether ffmpeg support should be included.
+ *
+ * Default: 0 (unfinished)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_FFMPEG
+# define PJMEDIA_VIDEO_DEV_HAS_FFMPEG 0
+#endif
+
+
+/**
+ * Video4Linux2
+ *
+ * Default: 0 (or detected by configure)
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_V4L2
+# define PJMEDIA_VIDEO_DEV_HAS_V4L2 0
+#endif
+
+
+/**
+ * Enable support for AVI player virtual capture device.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_VIDEO_DEV_HAS_AVI
+# define PJMEDIA_VIDEO_DEV_HAS_AVI 1
+#endif
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VIDEODEV_CONFIG_H__ */
+
+/*
+ --------------------- DOCUMENTATION FOLLOWS ---------------------------
+ */
+
+/**
+ * @addtogroup video_device_api Video Device API
+ * @{
+
+PJMEDIA Video Device API is a cross-platform video API appropriate for use with
+VoIP applications and many other types of video streaming applications.
+
+The API abstracts many different video API's on various platforms, such as:
+ - native Direct Show video for Win32 and Windows Mobile devices
+ - null-video implementation
+ - and more to be implemented in the future
+
+The Video Device API/library is an evolution from PJMEDIA @ref PJMED_SND and
+contains many enhancements:
+
+ - Forward compatibility:
+\n
+ The new API has been designed to be extensible, it will support new API's as
+ well as new features that may be introduced in the future without breaking
+ compatibility with applications that use this API as well as compatibility
+ with existing device implementations.
+
+ - Device capabilities:
+\n
+ At the heart of the API is device capabilities management, where all possible
+ video capabilities of video devices should be able to be handled in a generic
+ manner. With this framework, new capabilities that may be discovered in the
+ future can be handled in manner without breaking existing applications.
+
+ - Built-in features:
+\n
+ The device capabilities framework enables applications to use and control
+ video features built-in in the device, such as:
+ - built-in formats,
+ - etc.
+
+ - Codec support:
+\n
+ Some video devices support built-in hardware video codecs, and application
+ can use the video device in encoded mode to make use of these hardware
+ codecs.
+
+ - Multiple backends:
+\n
+ The new API supports multiple video backends (called factories or drivers in
+ the code) to be active simultaneously, and video backends may be added or
+ removed during run-time.
+
+*/
+
+
+/**
+ * @}
+ */
+
diff --git a/pjmedia/include/pjmedia-videodev/errno.h b/pjmedia/include/pjmedia-videodev/errno.h
new file mode 100644
index 0000000..9b4c49d
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/errno.h
@@ -0,0 +1,159 @@
+/* $Id: errno.h 3715 2011-08-19 09:35:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__
+#define __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief Videodev specific error codes.
+ */
+
+#include <pjmedia-videodev/config.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup error_codes Error Codes
+ * @ingroup video_device_api
+ * @brief Video device library specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ * This value is 520000.
+ */
+#define PJMEDIA_VIDEODEV_ERRNO_START \
+ (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE*7)
+#define PJMEDIA_VIDEODEV_ERRNO_END \
+ (PJMEDIA_VIDEODEV_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/************************************************************
+ * Video Device API error codes
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown error.
+ */
+#define PJMEDIA_EVID_ERR (PJMEDIA_VIDEODEV_ERRNO_START+1) /* 520001 */
+
+/**
+ * @hideinitializer
+ * Unknown error from video driver
+ */
+#define PJMEDIA_EVID_SYSERR (PJMEDIA_VIDEODEV_ERRNO_START+2) /* 520002 */
+
+/**
+ * @hideinitializer
+ * Video subsystem not initialized
+ */
+#define PJMEDIA_EVID_INIT (PJMEDIA_VIDEODEV_ERRNO_START+3) /* 520003 */
+
+/**
+ * @hideinitializer
+ * Invalid video device
+ */
+#define PJMEDIA_EVID_INVDEV (PJMEDIA_VIDEODEV_ERRNO_START+4) /* 520004 */
+
+/**
+ * @hideinitializer
+ * Found no devices
+ */
+#define PJMEDIA_EVID_NODEV (PJMEDIA_VIDEODEV_ERRNO_START+5) /* 520005 */
+
+/**
+ * @hideinitializer
+ * Unable to find default device
+ */
+#define PJMEDIA_EVID_NODEFDEV (PJMEDIA_VIDEODEV_ERRNO_START+6) /* 520006 */
+
+/**
+ * @hideinitializer
+ * Device not ready
+ */
+#define PJMEDIA_EVID_NOTREADY (PJMEDIA_VIDEODEV_ERRNO_START+7) /* 520007 */
+
+/**
+ * @hideinitializer
+ * The video capability is invalid or not supported
+ */
+#define PJMEDIA_EVID_INVCAP (PJMEDIA_VIDEODEV_ERRNO_START+8) /* 520008 */
+
+/**
+ * @hideinitializer
+ * The operation is invalid or not supported
+ */
+#define PJMEDIA_EVID_INVOP (PJMEDIA_VIDEODEV_ERRNO_START+9) /* 520009 */
+
+/**
+ * @hideinitializer
+ * Bad or invalid video device format
+ */
+#define PJMEDIA_EVID_BADFORMAT (PJMEDIA_VIDEODEV_ERRNO_START+10) /* 520010 */
+
+/**
+ * @hideinitializer
+ * Invalid video device sample format
+ */
+#define PJMEDIA_EVID_SAMPFORMAT (PJMEDIA_VIDEODEV_ERRNO_START+11) /* 520011 */
+
+/**
+ * @hideinitializer
+ * Bad latency setting
+ */
+#define PJMEDIA_EVID_BADLATENCY (PJMEDIA_VIDEODEV_ERRNO_START+12) /* 520012 */
+
+/**
+ * @hideinitializer
+ * Bad/unsupported video size
+ */
+#define PJMEDIA_EVID_BADSIZE (PJMEDIA_VIDEODEV_ERRNO_START+13) /* 520013 */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA Videodev specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_videodev_strerror(pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_VIDEODEV_VIDEODEV_ERRNO_H__ */
+
diff --git a/pjmedia/include/pjmedia-videodev/videodev.h b/pjmedia/include/pjmedia-videodev/videodev.h
new file mode 100644
index 0000000..9ba4982
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/videodev.h
@@ -0,0 +1,827 @@
+/* $Id: videodev.h 4167 2012-06-15 08:13:43Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_VIDEODEV_H__
+#define __PJMEDIA_VIDEODEV_VIDEODEV_H__
+
+/**
+ * @file videodev.h
+ * @brief Video device API.
+ */
+#include <pjmedia-videodev/config.h>
+#include <pjmedia-videodev/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pj/pool.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup video_device_reference Video Device API Reference
+ * @ingroup video_device_api
+ * @brief API Reference
+ * @{
+ */
+
+/**
+ * Type for device index.
+ */
+typedef pj_int32_t pjmedia_vid_dev_index;
+
+/**
+ * Enumeration of window handle type.
+ */
+typedef enum pjmedia_vid_dev_hwnd_type
+{
+ /**
+ * Type none.
+ */
+ PJMEDIA_VID_DEV_HWND_TYPE_NONE,
+
+ /**
+ * Native window handle on Windows.
+ */
+ PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS
+
+} pjmedia_vid_dev_hwnd_type;
+
+/**
+ * Type for window handle.
+ */
+typedef struct pjmedia_vid_dev_hwnd
+{
+ /**
+ * The window handle type.
+ */
+ pjmedia_vid_dev_hwnd_type type;
+
+ /**
+ * The window handle.
+ */
+ union
+ {
+ struct {
+ void *hwnd; /**< HWND */
+ } win;
+ struct {
+ void *window; /**< Window */
+ void *display; /**< Display */
+ } x11;
+ struct {
+ void *window; /**< Window */
+ } cocoa;
+ struct {
+ void *window; /**< Window */
+ } ios;
+ void *window;
+ } info;
+
+} pjmedia_vid_dev_hwnd;
+
+/**
+ * Parameter for switching device with PJMEDIA_VID_DEV_CAP_SWITCH capability.
+ * Initialize this with pjmedia_vid_dev_switch_param_default()
+ */
+typedef struct pjmedia_vid_dev_switch_param
+{
+ /**
+ * Target device ID to switch to. Once the switching is successful, the
+ * video stream will use this device and the old device will be closed.
+ */
+ pjmedia_vid_dev_index target_id;
+
+} pjmedia_vid_dev_switch_param;
+
+
+/**
+ * Enumeration of window flags.
+ */
+typedef enum pjmedia_vid_dev_wnd_flag
+{
+ /**
+ * Window with border.
+ */
+ PJMEDIA_VID_DEV_WND_BORDER = 1,
+
+ /**
+ * Window can be resized.
+ */
+ PJMEDIA_VID_DEV_WND_RESIZABLE = 2
+
+} pjmedia_vid_dev_wnd_flag;
+
+
+/**
+ * Device index constants.
+ */
+enum
+{
+ /**
+ * Constant to denote default capture device
+ */
+ PJMEDIA_VID_DEFAULT_CAPTURE_DEV = -1,
+
+ /**
+ * Constant to denote default render device
+ */
+ PJMEDIA_VID_DEFAULT_RENDER_DEV = -2,
+
+ /**
+ * Constant to denote invalid device index.
+ */
+ PJMEDIA_VID_INVALID_DEV = -3
+};
+
+
+/**
+ * This enumeration identifies various video device capabilities. These video
+ * capabilities indicates what features are supported by the underlying
+ * video device implementation.
+ *
+ * Applications get these capabilities in the #pjmedia_vid_dev_info structure.
+ *
+ * Application can also set the specific features/capabilities when opening
+ * the video stream by setting the \a flags member of #pjmedia_vid_dev_param
+ * structure.
+ *
+ * Once video stream is running, application can also retrieve or set some
+ * specific video capability, by using #pjmedia_vid_dev_stream_get_cap() and
+ * #pjmedia_vid_dev_stream_set_cap() and specifying the desired capability. The
+ * value of the capability is specified as pointer, and application needs to
+ * supply the pointer with the correct value, according to the documentation
+ * of each of the capability.
+ */
+typedef enum pjmedia_vid_dev_cap
+{
+ /**
+ * Support for video formats. The value of this capability
+ * is represented by #pjmedia_format structure.
+ */
+ PJMEDIA_VID_DEV_CAP_FORMAT = 1,
+
+ /**
+ * Support for video input scaling
+ */
+ PJMEDIA_VID_DEV_CAP_INPUT_SCALE = 2,
+
+ /**
+ * Support for returning the native window handle of the video window.
+ * For renderer, this means the window handle of the renderer window,
+ * while for capture, this means the window handle of the native preview,
+ * only if the device supports PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW
+ * capability.
+ *
+ * The value of this capability is pointer to pjmedia_vid_dev_hwnd
+ * structure.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW = 4,
+
+ /**
+ * Support for resizing video output. This capability SHOULD be
+ * implemented by renderer, to alter the video output dimension on the fly.
+ * Value is pjmedia_rect_size.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE = 8,
+
+ /**
+ * Support for setting the video window's position.
+ * Value is pjmedia_coord specifying the window's new coordinate.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION = 16,
+
+ /**
+ * Support for setting the video output's visibility.
+ * The value of this capability is a pj_bool_t containing boolean
+ * PJ_TRUE or PJ_FALSE.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE = 32,
+
+ /**
+ * Support for native preview capability in capture devices. Value is
+ * pj_bool_t. With native preview, capture device can be instructed to
+ * show or hide a preview window showing video directly from the camera
+ * by setting this capability to PJ_TRUE or PJ_FALSE. Once the preview
+ * is started, application may use PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW
+ * capability to query the vidow window.
+ *
+ * The value of this capability is a pj_bool_t containing boolean
+ * PJ_TRUE or PJ_FALSE.
+ */
+ PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW = 64,
+
+ /**
+ * Support for changing video orientation in renderer and querying
+ * video orientation info in capture. Changing video orientation in
+ * a renderer will potentially affect the size of render window,
+ * i.e: width and height swap. When a capture device supports this
+ * capability, it will generate event PJMEDIA_EVENT_ORIENT_CHANGED
+ * (see #pjmedia_event) everytime the capture orientation is changed.
+ *
+ * The value of this capability is pjmedia_orient.
+ */
+ PJMEDIA_VID_DEV_CAP_ORIENTATION = 128,
+
+ /**
+ * Support for fast switching to another device. A video stream with this
+ * capability allows replacing of its underlying device with another
+ * device, saving the user from opening a new video stream and gets a much
+ * faster and smoother switching action.
+ *
+ * Note that even when this capability is supported by a device, it may
+ * not be able to switch to arbitrary device. Application must always
+ * check the return value of the operation to verify that switching has
+ * occurred.
+ *
+ * This capability is currently write-only (i.e. set-only).
+ *
+ * The value of this capability is pointer to pjmedia_vid_dev_switch_param
+ * structure.
+ */
+ PJMEDIA_VID_DEV_CAP_SWITCH = 256,
+
+ /**
+ * Support for setting the output video window's flags.
+ * The value of this capability is a bitmask combination of
+ * #pjmedia_vid_dev_wnd_flag.
+ */
+ PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS = 512,
+
+ /**
+ * End of standard capability
+ */
+ PJMEDIA_VID_DEV_CAP_MAX = 16384
+
+} pjmedia_vid_dev_cap;
+
+/**
+ * Device information structure returned by #pjmedia_vid_dev_get_info().
+ */
+typedef struct pjmedia_vid_dev_info
+{
+ /** The device ID */
+ pjmedia_vid_dev_index id;
+
+ /** The device name */
+ char name[64];
+
+ /** The underlying driver name */
+ char driver[32];
+
+ /**
+ * The supported direction of the video device, i.e. whether it supports
+ * capture only, render only, or both.
+ */
+ pjmedia_dir dir;
+
+ /**
+ * Specify whether the device supports callback. Devices that implement
+ * "active interface" will actively call the callbacks to give or ask for
+ * video frames. If the device doesn't support callback, application
+ * must actively request or give video frames from/to the device by using
+ * pjmedia_vid_dev_stream_get_frame()/pjmedia_vid_dev_stream_put_frame().
+ */
+ pj_bool_t has_callback;
+
+ /** Device capabilities, as bitmask combination of #pjmedia_vid_dev_cap */
+ unsigned caps;
+
+ /** Number of video formats supported by this device */
+ unsigned fmt_cnt;
+
+ /**
+ * Array of supported video formats. Some fields in each supported video
+ * format may be set to zero or of "unknown" value, to indicate that the
+ * value is unknown or should be ignored. When these value are not set
+ * to zero, it indicates that the exact format combination is being used.
+ */
+ pjmedia_format fmt[PJMEDIA_VID_DEV_INFO_FMT_CNT];
+
+} pjmedia_vid_dev_info;
+
+
+/** Forward declaration for pjmedia_vid_dev_stream */
+typedef struct pjmedia_vid_dev_stream pjmedia_vid_dev_stream;
+
+typedef struct pjmedia_vid_dev_cb
+{
+ /**
+ * This callback is called by capturer stream when it has captured the
+ * whole packet worth of video samples.
+ *
+ * @param stream The video stream.
+ * @param user_data User data associated with the stream.
+ * @param frame Captured frame.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the video
+ * stream to stop
+ */
+ pj_status_t (*capture_cb)(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+
+ /**
+ * This callback is called by renderer stream when it needs additional
+ * data to be rendered by the device. Application must fill in the whole
+ * of output buffer with video samples.
+ *
+ * The frame argument contains the following values:
+ * - timestamp Rendering timestamp, in samples.
+ * - buf Buffer to be filled out by application.
+ * - size The size requested in bytes, which will be equal
+ * to the size of one whole packet.
+ *
+ * @param stream The video stream.
+ * @param user_data User data associated with the stream.
+ * @param frame Video frame, which buffer is to be filled in by
+ * the application.
+ *
+ * @return Returning non-PJ_SUCCESS will cause the video
+ * stream to stop
+ */
+ pj_status_t (*render_cb)(pjmedia_vid_dev_stream *stream,
+ void *user_data,
+ pjmedia_frame *frame);
+
+} pjmedia_vid_dev_cb;
+
+
+/**
+ * This structure specifies the parameters to open the video stream.
+ */
+typedef struct pjmedia_vid_dev_param
+{
+ /**
+ * The video direction. This setting is mandatory.
+ */
+ pjmedia_dir dir;
+
+ /**
+ * The video capture device ID. This setting is mandatory if the video
+ * direction includes input/capture direction.
+ */
+ pjmedia_vid_dev_index cap_id;
+
+ /**
+ * The video render device ID. This setting is mandatory if the video
+ * direction includes output/render direction.
+ */
+ pjmedia_vid_dev_index rend_id;
+
+ /**
+ * Video clock rate. This setting is mandatory if the video
+ * direction includes input/capture direction
+ */
+ unsigned clock_rate;
+
+ /**
+ * Video frame rate. This setting is mandatory if the video
+ * direction includes input/capture direction
+ */
+// pjmedia_ratio frame_rate;
+
+ /**
+ * This flags specifies which of the optional settings are valid in this
+ * structure. The flags is bitmask combination of pjmedia_vid_dev_cap.
+ */
+ unsigned flags;
+
+ /**
+ * Set the video format. This setting is mandatory.
+ */
+ pjmedia_format fmt;
+
+ /**
+ * Window for the renderer to display the video. This setting is optional,
+ * and will only be used if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW is set in
+ * the flags.
+ */
+ pjmedia_vid_dev_hwnd window;
+
+ /**
+ * Video display size. This setting is optional, and will only be used
+ * if PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE is set in the flags.
+ */
+ pjmedia_rect_size disp_size;
+
+ /**
+ * Video window position. This setting is optional, and will only be used
+ * if PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION is set in the flags.
+ */
+ pjmedia_coord window_pos;
+
+ /**
+ * Video window's visibility. This setting is optional, and will only be
+ * used if PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE is set in the flags.
+ */
+ pj_bool_t window_hide;
+
+ /**
+ * Enable built-in preview. This setting is optional and is only used
+ * if PJMEDIA_VID_DEV_CAP_INPUT_PREVIEW capability is supported and
+ * set in the flags.
+ */
+ pj_bool_t native_preview;
+
+ /**
+ * Video orientation. This setting is optional and is only used if
+ * PJMEDIA_VID_DEV_CAP_ORIENTATION capability is supported and is
+ * set in the flags.
+ */
+ pjmedia_orient orient;
+
+ /**
+ * Video window flags. This setting is optional, and will only be used
+ * if PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS is set in the flags.
+ */
+ unsigned window_flags;
+
+} pjmedia_vid_dev_param;
+
+
+/** Forward declaration for video device factory */
+typedef struct pjmedia_vid_dev_factory pjmedia_vid_dev_factory;
+
+/* typedef for factory creation function */
+typedef pjmedia_vid_dev_factory*
+(*pjmedia_vid_dev_factory_create_func_ptr)(pj_pool_factory*);
+
+/**
+ * Initialize pjmedia_vid_dev_switch_param.
+ *
+ * @param p Parameter to be initialized.
+ */
+PJ_INLINE(void)
+pjmedia_vid_dev_switch_param_default(pjmedia_vid_dev_switch_param *p)
+{
+ pj_bzero(p, sizeof(*p));
+ p->target_id = PJMEDIA_VID_INVALID_DEV;
+}
+
+/**
+ * Get string info for the specified capability.
+ *
+ * @param cap The capability ID.
+ * @param p_desc Optional pointer which will be filled with longer
+ * description about the capability.
+ *
+ * @return Capability name.
+ */
+PJ_DECL(const char*) pjmedia_vid_dev_cap_name(pjmedia_vid_dev_cap cap,
+ const char **p_desc);
+
+
+/**
+ * Set a capability field value in #pjmedia_vid_dev_param structure. This will
+ * also set the flags field for the specified capability in the structure.
+ *
+ * @param param The structure.
+ * @param cap The video capability which value is to be set.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_set_cap(pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ const void *pval);
+
+
+/**
+ * Get a capability field value from #pjmedia_vid_dev_param structure. This
+ * function will return PJMEDIA_EVID_INVCAP error if the flag for that
+ * capability is not set in the flags field in the structure.
+ *
+ * @param param The structure.
+ * @param cap The video capability which value is to be retrieved.
+ * @param pval Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_param_get_cap(const pjmedia_vid_dev_param *param,
+ pjmedia_vid_dev_cap cap,
+ void *pval);
+
+/**
+ * Initialize the video device subsystem. This will register all supported
+ * video device factories to the video device subsystem. This function may be
+ * called more than once, but each call to this function must have the
+ * corresponding #pjmedia_vid_dev_subsys_shutdown() call.
+ *
+ * @param pf The pool factory.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf);
+
+
+/**
+ * Get the pool factory registered to the video device subsystem.
+ *
+ * @return The pool factory.
+ */
+PJ_DECL(pj_pool_factory*) pjmedia_vid_dev_subsys_get_pool_factory(void);
+
+
+/**
+ * Shutdown the video device subsystem. This will destroy all video device
+ * factories registered in the video device subsystem. Note that currently
+ * opened video streams may or may not be closed, depending on the
+ * implementation of the video device factories.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_subsys_shutdown(void);
+
+
+/**
+ * Register a supported video device factory to the video device subsystem.
+ * Application can either register a function to create the factory, or
+ * an instance of an already created factory.
+ *
+ * This function can only be called after calling
+ * #pjmedia_vid_dev_subsys_init().
+ *
+ * @param vdf The factory creation function. Either vdf or factory
+ * argument must be specified.
+ * @param factory Factory instance. Either vdf or factory
+ * argument must be specified.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_register_factory(pjmedia_vid_dev_factory_create_func_ptr vdf,
+ pjmedia_vid_dev_factory *factory);
+
+
+/**
+ * Unregister a video device factory from the video device subsystem. This
+ * function can only be called after calling #pjmedia_vid_dev_subsys_init().
+ * Devices from this factory will be unlisted. If a device from this factory
+ * is currently in use, then the behavior is undefined.
+ *
+ * @param vdf The video device factory. Either vdf or factory argument
+ * must be specified.
+ * @param factory The factory instance. Either vdf or factory argument
+ * must be specified.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_unregister_factory(pjmedia_vid_dev_factory_create_func_ptr vdf,
+ pjmedia_vid_dev_factory *factory);
+
+
+/**
+ * Refresh the list of video devices installed in the system. This function
+ * will only refresh the list of videoo device so all active video streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to video devices (i.e. all variables of type
+ * pjmedia_vid_dev_index) before calling any function that accepts video device
+ * index as its parameter.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_refresh(void);
+
+
+/**
+ * Get the number of video devices installed in the system.
+ *
+ * @return The number of video devices installed in the system.
+ */
+PJ_DECL(unsigned) pjmedia_vid_dev_count(void);
+
+
+/**
+ * Get device information.
+ *
+ * @param id The video device ID.
+ * @param info The device information which will be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_get_info(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_info *info);
+
+
+/**
+ * Lookup device index based on the driver and device name.
+ *
+ * @param drv_name The driver name.
+ * @param dev_name The device name.
+ * @param id Pointer to store the returned device ID.
+ *
+ * @return PJ_SUCCESS if the device can be found.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_lookup(const char *drv_name,
+ const char *dev_name,
+ pjmedia_vid_dev_index *id);
+
+
+/**
+ * Initialize the video device parameters with default values for the
+ * specified device.
+ *
+ * @param id The video device ID.
+ * @param param The video device parameters which will be initialized
+ * by this function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_default_param(pj_pool_t *pool,
+ pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_param *param);
+
+
+/**
+ * Open video stream object using the specified parameters. If stream is
+ * created successfully, this function will return PJ_SUCCESS and the
+ * stream pointer will be returned in the p_strm argument.
+ *
+ * The opened stream may have been opened with different size and fps
+ * than the requested values in the \a param argument. Application should
+ * check the actual size and fps that the stream was opened with by inspecting
+ * the values in the \a param argument and see if they have changed. Also
+ * if the device ID in the \a param specifies default device, it may be
+ * replaced with the actual device ID upon return.
+ *
+ * @param param On input, it specifies the video device parameters
+ * to be used for the stream. On output, this will be
+ * set to the actual video device parameters used to
+ * open the stream.
+ * @param cb Pointer to structure containing video stream
+ * callbacks.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ * @param p_strm Pointer to receive the video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_create(
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_strm);
+
+/**
+ * Get the running parameters for the specified video stream.
+ *
+ * @param strm The video stream.
+ * @param param Video stream parameters to be filled in by this
+ * function once it returns successfully.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_param(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+
+/**
+ * Get the value of a specific capability of the video stream.
+ *
+ * @param strm The video stream.
+ * @param cap The video capability which value is to be retrieved.
+ * @param value Pointer to value to be filled in by this function
+ * once it returns successfully. Please see the type
+ * of value to be supplied in the pjmedia_vid_dev_cap
+ * documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+
+/**
+ * Set the value of a specific capability of the video stream.
+ *
+ * @param strm The video stream.
+ * @param cap The video capability which value is to be set.
+ * @param value Pointer to value. Please see the type of value to
+ * be supplied in the pjmedia_vid_dev_cap documentation.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_set_cap(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+
+/**
+ * Start the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_start(
+ pjmedia_vid_dev_stream *strm);
+
+/**
+ * Query whether the stream has been started.
+ *
+ * @param strm The video stream
+ *
+ * @return PJ_TRUE if the video stream has been started.
+ */
+PJ_DECL(pj_bool_t) pjmedia_vid_dev_stream_is_running(pjmedia_vid_dev_stream *strm);
+
+
+/**
+ * Request one frame from the stream. Application needs to call this function
+ * periodically only if the stream doesn't support "active interface", i.e.
+ * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
+ *
+ * @param strm The video stream.
+ * @param frame The video frame to be filled by the device.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_get_frame(
+ pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+
+/**
+ * Put one frame to the stream. Application needs to call this function
+ * periodically only if the stream doesn't support "active interface", i.e.
+ * the pjmedia_vid_dev_info.has_callback member is PJ_FALSE.
+ *
+ * @param strm The video stream.
+ * @param frame The video frame to put to the device.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_put_frame(
+ pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+
+/**
+ * Stop the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_stop(
+ pjmedia_vid_dev_stream *strm);
+
+/**
+ * Destroy the stream.
+ *
+ * @param strm The video stream.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_dev_stream_destroy(
+ pjmedia_vid_dev_stream *strm);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VIDEODEV_VIDEODEV_H__ */
diff --git a/pjmedia/include/pjmedia-videodev/videodev_imp.h b/pjmedia/include/pjmedia-videodev/videodev_imp.h
new file mode 100644
index 0000000..9924809
--- /dev/null
+++ b/pjmedia/include/pjmedia-videodev/videodev_imp.h
@@ -0,0 +1,230 @@
+/* $Id: videodev_imp.h 4016 2012-04-04 05:05:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __VIDEODEV_IMP_H__
+#define __VIDEODEV_IMP_H__
+
+#include <pjmedia-videodev/videodev.h>
+
+/**
+ * @defgroup s8_video_device_implementors_api Video Device Implementors API
+ * @ingroup video_device_api
+ * @brief API for video device implementors
+ * @{
+ */
+
+/**
+ * Video device factory operations.
+ */
+typedef struct pjmedia_vid_dev_factory_op
+{
+ /**
+ * Initialize the video device factory.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*init)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Close this video device factory and release all resources back to the
+ * operating system.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*destroy)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Get the number of video devices installed in the system.
+ *
+ * @param f The video device factory.
+ */
+ unsigned (*get_dev_count)(pjmedia_vid_dev_factory *f);
+
+ /**
+ * Get the video device information and capabilities.
+ *
+ * @param f The video device factory.
+ * @param index Device index.
+ * @param info The video device information structure which will be
+ * initialized by this function once it returns
+ * successfully.
+ */
+ pj_status_t (*get_dev_info)(pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_info *info);
+
+ /**
+ * Initialize the specified video device parameter with the default
+ * values for the specified device.
+ *
+ * @param f The video device factory.
+ * @param index Device index.
+ * @param param The video device parameter.
+ */
+ pj_status_t (*default_param)(pj_pool_t *pool,
+ pjmedia_vid_dev_factory *f,
+ unsigned index,
+ pjmedia_vid_dev_param *param);
+
+ /**
+ * Open the video device and create video stream. See
+ * #pjmedia_vid_dev_stream_create()
+ */
+ pj_status_t (*create_stream)(pjmedia_vid_dev_factory *f,
+ pjmedia_vid_dev_param *param,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data,
+ pjmedia_vid_dev_stream **p_vid_strm);
+
+ /**
+ * Refresh the list of video devices installed in the system.
+ *
+ * @param f The video device factory.
+ */
+ pj_status_t (*refresh)(pjmedia_vid_dev_factory *f);
+
+} pjmedia_vid_dev_factory_op;
+
+
+/**
+ * This structure describes a video device factory.
+ */
+struct pjmedia_vid_dev_factory
+{
+ /** Internal data to be initialized by video subsystem. */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+ } sys;
+
+ /** Operations */
+ pjmedia_vid_dev_factory_op *op;
+};
+
+
+/**
+ * Video stream operations.
+ */
+typedef struct pjmedia_vid_dev_stream_op
+{
+ /**
+ * See #pjmedia_vid_dev_stream_get_param()
+ */
+ pj_status_t (*get_param)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_param *param);
+
+ /**
+ * See #pjmedia_vid_dev_stream_get_cap()
+ */
+ pj_status_t (*get_cap)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ void *value);
+
+ /**
+ * See #pjmedia_vid_dev_stream_set_cap()
+ */
+ pj_status_t (*set_cap)(pjmedia_vid_dev_stream *strm,
+ pjmedia_vid_dev_cap cap,
+ const void *value);
+
+ /**
+ * See #pjmedia_vid_dev_stream_start()
+ */
+ pj_status_t (*start)(pjmedia_vid_dev_stream *strm);
+
+ /**
+ * See #pjmedia_vid_dev_stream_get_frame()
+ */
+ pj_status_t (*get_frame)(pjmedia_vid_dev_stream *strm,
+ pjmedia_frame *frame);
+
+ /**
+ * See #pjmedia_vid_dev_stream_put_frame()
+ */
+ pj_status_t (*put_frame)(pjmedia_vid_dev_stream *strm,
+ const pjmedia_frame *frame);
+
+ /**
+ * See #pjmedia_vid_dev_stream_stop().
+ */
+ pj_status_t (*stop)(pjmedia_vid_dev_stream *strm);
+
+ /**
+ * See #pjmedia_vid_dev_stream_destroy().
+ */
+ pj_status_t (*destroy)(pjmedia_vid_dev_stream *strm);
+
+} pjmedia_vid_dev_stream_op;
+
+
+/**
+ * This structure describes the video device stream.
+ */
+struct pjmedia_vid_dev_stream
+{
+ /** Internal data to be initialized by video subsystem */
+ struct {
+ /** Driver index */
+ unsigned drv_idx;
+
+ /** Has it been started? */
+ pj_bool_t is_running;
+ } sys;
+
+ /** Operations */
+ pjmedia_vid_dev_stream_op *op;
+};
+
+
+/**
+ * Internal API: return the factory instance and device index that's local
+ * to the factory for a given device ID.
+ *
+ * @param id Device id.
+ * @param p_f Out: factory instance
+ * @param p_local_index Out: device index within the factory
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_dev_get_local_index(pjmedia_vid_dev_index id,
+ pjmedia_vid_dev_factory **p_f,
+ unsigned *p_local_index);
+
+/**
+ * Internal API: return the global device index given a factory instance and
+ * a local device index.
+ *
+ * @param f Factory.
+ * @param local_idx Local index.
+ * @param pid Returned global index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DEF(pj_status_t)
+pjmedia_vid_dev_get_global_index(const pjmedia_vid_dev_factory *f,
+ unsigned local_idx,
+ pjmedia_vid_dev_index *pid);
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __VIDEODEV_IMP_H__ */
diff --git a/pjmedia/include/pjmedia.h b/pjmedia/include/pjmedia.h
new file mode 100644
index 0000000..5fef796
--- /dev/null
+++ b/pjmedia/include/pjmedia.h
@@ -0,0 +1,81 @@
+/* $Id: pjmedia.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_H__
+#define __PJMEDIA_H__
+
+/**
+ * @file pjmedia.h
+ * @brief PJMEDIA main header file.
+ */
+#include <pjmedia/alaw_ulaw.h>
+#include <pjmedia/avi_stream.h>
+#include <pjmedia/bidirectional.h>
+#include <pjmedia/circbuf.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/codec.h>
+#include <pjmedia/conference.h>
+#include <pjmedia/converter.h>
+#include <pjmedia/delaybuf.h>
+#include <pjmedia/echo.h>
+#include <pjmedia/echo_port.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/errno.h>
+#include <pjmedia/event.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pjmedia/g711.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/master_port.h>
+#include <pjmedia/mem_port.h>
+#include <pjmedia/null_port.h>
+#include <pjmedia/plc.h>
+#include <pjmedia/port.h>
+#include <pjmedia/resample.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/rtcp_xr.h>
+#include <pjmedia/rtp.h>
+#include <pjmedia/sdp.h>
+#include <pjmedia/sdp_neg.h>
+//#include <pjmedia/session.h>
+#include <pjmedia/silencedet.h>
+#include <pjmedia/sound.h>
+#include <pjmedia/sound_port.h>
+#include <pjmedia/splitcomb.h>
+#include <pjmedia/stereo.h>
+#include <pjmedia/stream.h>
+#include <pjmedia/stream_common.h>
+#include <pjmedia/tonegen.h>
+#include <pjmedia/transport.h>
+#include <pjmedia/transport_adapter_sample.h>
+#include <pjmedia/transport_ice.h>
+#include <pjmedia/transport_loop.h>
+#include <pjmedia/transport_srtp.h>
+#include <pjmedia/transport_udp.h>
+#include <pjmedia/vid_port.h>
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/vid_stream.h>
+#include <pjmedia/vid_tee.h>
+#include <pjmedia/wav_playlist.h>
+#include <pjmedia/wav_port.h>
+#include <pjmedia/wave.h>
+#include <pjmedia/wsola.h>
+
+#endif /* __PJMEDIA_H__ */
+
diff --git a/pjmedia/include/pjmedia/alaw_ulaw.h b/pjmedia/include/pjmedia/alaw_ulaw.h
new file mode 100644
index 0000000..60da9a6
--- /dev/null
+++ b/pjmedia/include/pjmedia/alaw_ulaw.h
@@ -0,0 +1,213 @@
+/* $Id: alaw_ulaw.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_ALAW_ULAW_H__
+#define __PJMEDIA_ALAW_ULAW_H__
+
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+#if defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) && PJMEDIA_HAS_ALAW_ULAW_TABLE!=0
+
+extern const pj_uint8_t pjmedia_linear2ulaw_tab[16384];
+extern const pj_uint8_t pjmedia_linear2alaw_tab[16384];
+extern const pj_int16_t pjmedia_ulaw2linear_tab[256];
+extern const pj_int16_t pjmedia_alaw2linear_tab[256];
+
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit A-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return 8-bit A-Law value.
+ */
+#define pjmedia_linear2alaw(pcm_val) \
+ pjmedia_linear2alaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]
+
+/**
+ * Convert 8-bit A-Law value to 16-bit linear PCM value.
+ *
+ * @param chara_val 8-bit A-Law value.
+ * @return 16-bit linear PCM value.
+ */
+#define pjmedia_alaw2linear(chara_val) \
+ pjmedia_alaw2linear_tab[chara_val]
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit U-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return U-bit A-Law value.
+ */
+#define pjmedia_linear2ulaw(pcm_val) \
+ pjmedia_linear2ulaw_tab[(((pj_int16_t)pcm_val) >> 2) & 0x3fff]
+
+/**
+ * Convert 8-bit U-Law value to 16-bit linear PCM value.
+ *
+ * @param u_val 8-bit U-Law value.
+ * @return 16-bit linear PCM value.
+ */
+#define pjmedia_ulaw2linear(u_val) \
+ pjmedia_ulaw2linear_tab[u_val]
+
+/**
+ * Convert 8-bit A-Law value to 8-bit U-Law value.
+ *
+ * @param aval 8-bit A-Law value.
+ * @return 8-bit U-Law value.
+ */
+#define pjmedia_alaw2ulaw(aval) \
+ pjmedia_linear2ulaw(pjmedia_alaw2linear(aval))
+
+/**
+ * Convert 8-bit U-Law value to 8-bit A-Law value.
+ *
+ * @param uval 8-bit U-Law value.
+ * @return 8-bit A-Law value.
+ */
+#define pjmedia_ulaw2alaw(uval) \
+ pjmedia_linear2alaw(pjmedia_ulaw2linear(uval))
+
+
+#else
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit A-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return 8-bit A-Law value.
+ */
+PJ_DECL(pj_uint8_t) pjmedia_linear2alaw(int pcm_val);
+
+/**
+ * Convert 8-bit A-Law value to 16-bit linear PCM value.
+ *
+ * @param chara_val 8-bit A-Law value.
+ * @return 16-bit linear PCM value.
+ */
+PJ_DECL(int) pjmedia_alaw2linear(unsigned chara_val);
+
+/**
+ * Convert 16-bit linear PCM value to 8-bit U-Law.
+ *
+ * @param pcm_val 16-bit linear PCM value.
+ * @return U-bit A-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_linear2ulaw(int pcm_val);
+
+/**
+ * Convert 8-bit U-Law value to 16-bit linear PCM value.
+ *
+ * @param u_val 8-bit U-Law value.
+ * @return 16-bit linear PCM value.
+ */
+PJ_DECL(int) pjmedia_ulaw2linear(unsigned char u_val);
+
+/**
+ * Convert 8-bit A-Law value to 8-bit U-Law value.
+ *
+ * @param aval 8-bit A-Law value.
+ * @return 8-bit U-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_alaw2ulaw(unsigned char aval);
+
+/**
+ * Convert 8-bit U-Law value to 8-bit A-Law value.
+ *
+ * @param uval 8-bit U-Law value.
+ * @return 8-bit A-Law value.
+ */
+PJ_DECL(unsigned char) pjmedia_ulaw2alaw(unsigned char uval);
+
+#endif
+
+/**
+ * Encode 16-bit linear PCM data to 8-bit U-Law data.
+ *
+ * @param dst Destination buffer for 8-bit U-Law data.
+ * @param src Source, 16-bit linear PCM data.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src,
+ pj_size_t count)
+{
+ const pj_int16_t *end = src + count;
+
+ while (src < end) {
+ *dst++ = pjmedia_linear2ulaw(*src++);
+ }
+}
+
+/**
+ * Encode 16-bit linear PCM data to 8-bit A-Law data.
+ *
+ * @param dst Destination buffer for 8-bit A-Law data.
+ * @param src Source, 16-bit linear PCM data.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src,
+ pj_size_t count)
+{
+ const pj_int16_t *end = src + count;
+
+ while (src < end) {
+ *dst++ = pjmedia_linear2alaw(*src++);
+ }
+}
+
+/**
+ * Decode 8-bit U-Law data to 16-bit linear PCM data.
+ *
+ * @param dst Destination buffer for 16-bit PCM data.
+ * @param src Source, 8-bit U-Law data.
+ * @param len Encoded frame/source length in bytes.
+ */
+PJ_INLINE(void) pjmedia_ulaw_decode(pj_int16_t *dst, const pj_uint8_t *src,
+ pj_size_t len)
+{
+ const pj_uint8_t *end = src + len;
+
+ while (src < end) {
+ *dst++ = pjmedia_ulaw2linear(*src++);
+ }
+}
+
+/**
+ * Decode 8-bit A-Law data to 16-bit linear PCM data.
+ *
+ * @param dst Destination buffer for 16-bit PCM data.
+ * @param src Source, 8-bit A-Law data.
+ * @param len Encoded frame/source length in bytes.
+ */
+PJ_INLINE(void) pjmedia_alaw_decode(pj_int16_t *dst, const pj_uint8_t *src,
+ pj_size_t len)
+{
+ const pj_uint8_t *end = src + len;
+
+ while (src < end) {
+ *dst++ = pjmedia_alaw2linear(*src++);
+ }
+}
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_ALAW_ULAW_H__ */
+
diff --git a/pjmedia/include/pjmedia/avi.h b/pjmedia/include/pjmedia/avi.h
new file mode 100644
index 0000000..1223669
--- /dev/null
+++ b/pjmedia/include/pjmedia/avi.h
@@ -0,0 +1,202 @@
+/* $Id: avi.h 4058 2012-04-17 06:57:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AVI_H__
+#define __PJMEDIA_AVI_H__
+
+
+/**
+ * @file avi.h
+ * @brief AVI file manipulation.
+ */
+
+/**
+ * @defgroup PJMEDIA_FILE_FORMAT File Formats
+ * @brief Supported file formats
+ */
+
+
+/**
+ * @defgroup PJMEDIA_AVI AVI Header
+ * @ingroup PJMEDIA_FILE_FORMAT
+ * @brief Representation of RIFF/AVI file format
+ * @{
+ *
+ * This the the low level representation of RIFF/AVI file format. For
+ * higher abstraction, please see \ref PJMEDIA_FILE_PLAY and
+ * \ref PJMEDIA_FILE_REC.
+ */
+
+
+PJ_BEGIN_DECL
+
+#define PJMEDIA_AVI_MAX_NUM_STREAMS 4
+
+static const char avi_tags[][4] = {
+ { 'R', 'I', 'F', 'F' }, { 'A', 'V', 'I', ' ' },
+ { 'h', 'd', 'r', 'l' }, { 'a', 'v', 'i', 'h' },
+ { 's', 't', 'r', 'l' }, { 's', 't', 'r', 'h' },
+ { 'a', 'u', 'd', 's' }, { 'v', 'i', 'd', 's' },
+ { 's', 't', 'r', 'f' }, { 'm', 'o', 'v', 'i' },
+ { 'L', 'I', 'S', 'T' }, { 'J', 'U', 'N', 'K' },
+};
+
+typedef enum {
+ PJMEDIA_AVI_RIFF_TAG = 0,
+ PJMEDIA_AVI_AVI_TAG,
+ PJMEDIA_AVI_HDRL_TAG,
+ PJMEDIA_AVI_AVIH_TAG,
+ PJMEDIA_AVI_STRL_TAG,
+ PJMEDIA_AVI_STRH_TAG,
+ PJMEDIA_AVI_AUDS_TAG,
+ PJMEDIA_AVI_VIDS_TAG,
+ PJMEDIA_AVI_STRF_TAG,
+ PJMEDIA_AVI_MOVI_TAG,
+ PJMEDIA_AVI_LIST_TAG,
+ PJMEDIA_AVI_JUNK_TAG,
+} pjmedia_avi_tag;
+
+
+/**
+ * These types describe the simpler/canonical version of an AVI file.
+ * They do not support the full AVI RIFF format specification.
+ */
+#pragma pack(2)
+
+/** This structure describes RIFF AVI file header */
+typedef struct riff_hdr_t {
+ pj_uint32_t riff; /**< "RIFF" ASCII tag. */
+ pj_uint32_t file_len; /**< File length minus 8 bytes */
+ pj_uint32_t avi; /**< "AVI" ASCII tag. */
+} riff_hdr_t;
+
+/** This structure describes avih header */
+typedef struct avih_hdr_t {
+ pj_uint32_t list_tag;
+ pj_uint32_t list_sz;
+ pj_uint32_t hdrl_tag;
+ pj_uint32_t avih;
+ pj_uint32_t size;
+ pj_uint32_t usec_per_frame; /**< microsecs between frames */
+ pj_uint32_t max_Bps;
+ pj_uint32_t pad;
+ pj_uint32_t flags;
+ pj_uint32_t tot_frames;
+ pj_uint32_t init_frames;
+ pj_uint32_t num_streams;
+ pj_uint32_t buf_size;
+ pj_uint32_t width;
+ pj_uint32_t height;
+ pj_uint32_t reserved[4];
+} avih_hdr_t;
+
+/** This structure describes strl header */
+typedef struct strl_hdr_t {
+ pj_uint32_t list_tag;
+ pj_uint32_t list_sz;
+ pj_uint32_t strl_tag;
+
+ pj_uint32_t strh;
+ pj_uint32_t strh_size;
+ pj_uint32_t data_type;
+ pj_uint32_t codec;
+ pj_uint32_t flags;
+ pj_uint32_t bogus_priority_language; /**< Do not access this data */
+ pj_uint32_t init_frames;
+ pj_uint32_t scale;
+ pj_uint32_t rate;
+ pj_uint32_t start;
+ pj_uint32_t length;
+ pj_uint32_t buf_size;
+ pj_uint32_t quality;
+ pj_uint32_t sample_size;
+ pj_uint32_t bogus_frame[2]; /**< Do not access this data */
+} strl_hdr_t;
+
+typedef struct {
+ pj_uint32_t strf;
+ pj_uint32_t strf_size;
+ pj_uint16_t fmt_tag; /**< 1 for PCM */
+ pj_uint16_t nchannels; /**< Number of channels. */
+ pj_uint32_t sample_rate; /**< Sampling rate. */
+ pj_uint32_t bytes_per_sec; /**< Average bytes per second. */
+ pj_uint16_t block_align; /**< nchannels * bits / 8 */
+ pj_uint16_t bits_per_sample; /**< Bits per sample. */
+ pj_uint16_t extra_size;
+} strf_audio_hdr_t;
+
+/**
+ * Sizes of strf_audio_hdr_t struct, started by the size (in bytes) of
+ * 32-bits struct members, alternated with the size of 16-bits members.
+ */
+static const pj_uint8_t strf_audio_hdr_sizes [] = {8, 4, 8, 6};
+
+typedef struct {
+ pj_uint32_t strf;
+ pj_uint32_t strf_size;
+ pj_uint32_t biSize;
+ pj_int32_t biWidth;
+ pj_int32_t biHeight;
+ pj_uint16_t biPlanes;
+ pj_uint16_t biBitCount;
+ pj_uint32_t biCompression;
+ pj_uint32_t biSizeImage;
+ pj_int32_t biXPelsPerMeter;
+ pj_int32_t biYPelsPerMeter;
+ pj_uint32_t biClrUsed;
+ pj_uint32_t biClrImportant;
+} strf_video_hdr_t;
+
+static const pj_uint8_t strf_video_hdr_sizes [] = {20, 4, 24};
+
+struct pjmedia_avi_hdr
+{
+ riff_hdr_t riff_hdr;
+ avih_hdr_t avih_hdr;
+ strl_hdr_t strl_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];
+ union {
+ strf_audio_hdr_t strf_audio_hdr;
+ strf_video_hdr_t strf_video_hdr;
+ } strf_hdr[PJMEDIA_AVI_MAX_NUM_STREAMS];
+};
+
+#pragma pack()
+
+/**
+ * @see pjmedia_avi_hdr
+ */
+typedef struct pjmedia_avi_hdr pjmedia_avi_hdr;
+
+/**
+ * This structure describes generic RIFF subchunk header.
+ */
+typedef struct pjmedia_avi_subchunk
+{
+ pj_uint32_t id; /**< Subchunk ASCII tag. */
+ pj_uint32_t len; /**< Length following this field */
+} pjmedia_avi_subchunk;
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AVI_H__ */
diff --git a/pjmedia/include/pjmedia/avi_stream.h b/pjmedia/include/pjmedia/avi_stream.h
new file mode 100644
index 0000000..ff4bf53
--- /dev/null
+++ b/pjmedia/include/pjmedia/avi_stream.h
@@ -0,0 +1,170 @@
+/* $Id: avi_stream.h 3715 2011-08-19 09:35:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AVI_STREAM_H__
+#define __PJMEDIA_AVI_STREAM_H__
+
+/**
+ * @file avi_stream.h
+ * @brief AVI file player.
+ */
+#include <pjmedia/port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_FILE_PLAY AVI File Player
+ * @ingroup PJMEDIA_PORT
+ * @brief Video and audio playback from AVI file
+ * @{
+ */
+
+/**
+ * AVI file player options.
+ */
+enum pjmedia_avi_file_player_option
+{
+ /**
+ * Tell the file player to return NULL frame when the whole
+ * file has been played.
+ */
+ PJMEDIA_AVI_FILE_NO_LOOP = 1
+};
+
+/**
+ * AVI stream data type.
+ */
+typedef pjmedia_port pjmedia_avi_stream;
+
+/**
+ * Opaque data type for AVI streams. AVI streams is a collection of
+ * zero or more AVI stream.
+ */
+typedef struct pjmedia_avi_streams pjmedia_avi_streams;
+
+/**
+ * Create avi streams to play an AVI file. AVI player supports
+ * reading AVI file with uncompressed video format and
+ * 16 bit PCM or compressed G.711 A-law/U-law audio format.
+ *
+ * @param pool Pool to create the streams.
+ * @param filename File name to open.
+ * @param flags Avi streams creation flags.
+ * @param p_streams Pointer to receive the avi streams instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_avi_player_create_streams(pj_pool_t *pool,
+ const char *filename,
+ unsigned flags,
+ pjmedia_avi_streams **p_streams);
+
+/**
+ * Get the number of AVI stream.
+ *
+ * @param streams The AVI streams.
+ *
+ * @return The number of AVI stream.
+ */
+PJ_DECL(unsigned)
+pjmedia_avi_streams_get_num_streams(pjmedia_avi_streams *streams);
+
+/**
+ * Return the idx-th stream of the AVI streams.
+ *
+ * @param streams The AVI streams.
+ * @param idx The stream index.
+ *
+ * @return The AVI stream or NULL if it does not exist.
+ */
+PJ_DECL(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream(pjmedia_avi_streams *streams,
+ unsigned idx);
+
+/**
+ * Return an AVI stream with a certain media type from the AVI streams.
+ *
+ * @param streams The AVI streams.
+ * @param start_idx The starting index.
+ * @param media_type The media type of the stream.
+ *
+ * @return The AVI stream or NULL if it does not exist.
+ */
+PJ_DECL(pjmedia_avi_stream *)
+pjmedia_avi_streams_get_stream_by_media(pjmedia_avi_streams *streams,
+ unsigned start_idx,
+ pjmedia_type media_type);
+
+/**
+ * Return the media port of an AVI stream.
+ *
+ * @param stream The AVI stream.
+ *
+ * @return The media port.
+ */
+PJ_INLINE(pjmedia_port *)
+pjmedia_avi_stream_get_port(pjmedia_avi_stream *stream)
+{
+ return (pjmedia_port *)stream;
+}
+
+/**
+ * Get the data length, in bytes.
+ *
+ * @param stream The AVI stream.
+ *
+ * @return The length of the data, in bytes. Upon error it will
+ * return negative value.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_avi_stream_get_len(pjmedia_avi_stream *stream);
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file. If the file is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each AVI stream.
+ *
+ * @param stream The AVI stream.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_avi_stream_set_eof_cb(pjmedia_avi_stream *stream,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_avi_stream *stream,
+ void *usr_data));
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_AVI_STREAM_H__ */
diff --git a/pjmedia/include/pjmedia/bidirectional.h b/pjmedia/include/pjmedia/bidirectional.h
new file mode 100644
index 0000000..0a7e5e0
--- /dev/null
+++ b/pjmedia/include/pjmedia/bidirectional.h
@@ -0,0 +1,67 @@
+/* $Id: bidirectional.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_BIDIRECTIONAL_H__
+#define __PJMEDIA_BIDIRECTIONAL_H__
+
+/**
+ * @file bidirectional.h
+ * @brief Bidirectional media port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @defgroup PJMEDIA_BIDIRECTIONAL_PORT Bidirectional Port
+ * @ingroup PJMEDIA_PORT
+ * @brief A bidirectional port combines two unidirectional ports into one
+ * bidirectional port
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create bidirectional port from two unidirectional ports
+ *
+ * @param pool Pool to allocate memory.
+ * @param get_port Port where get_frame() will be directed to.
+ * @param put_port Port where put_frame() will be directed to.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_bidirectional_port_create(pj_pool_t *pool,
+ pjmedia_port *get_port,
+ pjmedia_port *put_port,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_BIDIRECTIONAL_H__ */
+
diff --git a/pjmedia/include/pjmedia/circbuf.h b/pjmedia/include/pjmedia/circbuf.h
new file mode 100644
index 0000000..80a774c
--- /dev/null
+++ b/pjmedia/include/pjmedia/circbuf.h
@@ -0,0 +1,436 @@
+/* $Id: circbuf.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJMEDIA_CIRC_BUF_H__
+#define __PJMEDIA_CIRC_BUF_H__
+
+/**
+ * @file circbuf.h
+ * @brief Circular Buffer.
+ */
+
+#include <pj/assert.h>
+#include <pj/errno.h>
+#include <pj/pool.h>
+#include <pjmedia/frame.h>
+
+/**
+ * @defgroup PJMED_CIRCBUF Circular Buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Circular buffer manages read and write contiguous audio samples in a
+ * non-contiguous buffer as if the buffer were contiguous. This should give
+ * better performance than keeping contiguous samples in a contiguous buffer,
+ * since read/write operations will only update the pointers, instead of
+ * shifting audio samples.
+ *
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of circular buffer.
+ */
+
+/* Algorithm checkings, for development purpose only */
+#if 0
+# define PJMEDIA_CIRC_BUF_CHECK(x) pj_assert(x)
+#else
+# define PJMEDIA_CIRC_BUF_CHECK(x)
+#endif
+
+PJ_BEGIN_DECL
+
+/**
+ * Circular buffer structure
+ */
+typedef struct pjmedia_circ_buf {
+ pj_int16_t *buf; /**< The buffer */
+ unsigned capacity; /**< Buffer capacity, in samples */
+
+ pj_int16_t *start; /**< Pointer to the first sample */
+ unsigned len; /**< Audio samples length,
+ in samples */
+} pjmedia_circ_buf;
+
+
+/**
+ * Create the circular buffer.
+ *
+ * @param pool Pool where the circular buffer will be allocated
+ * from.
+ * @param capacity Capacity of the buffer, in samples.
+ * @param p_cb Pointer to receive the circular buffer instance.
+ *
+ * @return PJ_SUCCESS if the circular buffer has been
+ * created successfully, otherwise the appropriate
+ * error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_create(pj_pool_t *pool,
+ unsigned capacity,
+ pjmedia_circ_buf **p_cb)
+{
+ pjmedia_circ_buf *cbuf;
+
+ cbuf = PJ_POOL_ZALLOC_T(pool, pjmedia_circ_buf);
+ cbuf->buf = (pj_int16_t*) pj_pool_calloc(pool, capacity,
+ sizeof(pj_int16_t));
+ cbuf->capacity = capacity;
+ cbuf->start = cbuf->buf;
+ cbuf->len = 0;
+
+ *p_cb = cbuf;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Reset the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_reset(pjmedia_circ_buf *circbuf)
+{
+ circbuf->start = circbuf->buf;
+ circbuf->len = 0;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Get the circular buffer length, it is number of samples buffered in the
+ * circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return The buffer length.
+ */
+PJ_INLINE(unsigned) pjmedia_circ_buf_get_len(pjmedia_circ_buf *circbuf)
+{
+ return circbuf->len;
+}
+
+
+/**
+ * Set circular buffer length. This is useful when audio buffer is manually
+ * manipulated by the user, e.g: shrinked, expanded.
+ *
+ * @param circbuf The circular buffer.
+ * @param len The new buffer length.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_set_len(pjmedia_circ_buf *circbuf,
+ unsigned len)
+{
+ PJMEDIA_CIRC_BUF_CHECK(len <= circbuf->capacity);
+ circbuf->len = len;
+}
+
+
+/**
+ * Advance the read pointer of circular buffer. This function will discard
+ * the skipped samples while advancing the read pointer, thus reducing
+ * the buffer length.
+ *
+ * @param circbuf The circular buffer.
+ * @param count Distance from current read pointer, can only be
+ * possitive number, in samples.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_read_ptr(pjmedia_circ_buf *circbuf,
+ unsigned count)
+{
+ if (count >= circbuf->len)
+ return pjmedia_circ_buf_reset(circbuf);
+
+ PJMEDIA_CIRC_BUF_CHECK(count <= circbuf->len);
+
+ circbuf->start += count;
+ if (circbuf->start >= circbuf->buf + circbuf->capacity)
+ circbuf->start -= circbuf->capacity;
+ circbuf->len -= count;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Advance the write pointer of circular buffer. Since write pointer is always
+ * pointing to a sample after the end of sample, so this function also means
+ * increasing the buffer length.
+ *
+ * @param circbuf The circular buffer.
+ * @param count Distance from current write pointer, can only be
+ * possitive number, in samples.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_adv_write_ptr(pjmedia_circ_buf *circbuf,
+ unsigned count)
+{
+ if (count + circbuf->len > circbuf->capacity)
+ return PJ_ETOOBIG;
+
+ circbuf->len += count;
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Get the real buffer addresses containing the audio samples.
+ *
+ * @param circbuf The circular buffer.
+ * @param reg1 Pointer to store the first buffer address.
+ * @param reg1_len Pointer to store the length of the first buffer,
+ * in samples.
+ * @param reg2 Pointer to store the second buffer address.
+ * @param reg2_len Pointer to store the length of the second buffer,
+ * in samples.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_get_read_regions(pjmedia_circ_buf *circbuf,
+ pj_int16_t **reg1,
+ unsigned *reg1_len,
+ pj_int16_t **reg2,
+ unsigned *reg2_len)
+{
+ *reg1 = circbuf->start;
+ *reg1_len = circbuf->len;
+ if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {
+ *reg1_len = circbuf->buf + circbuf->capacity - circbuf->start;
+ *reg2 = circbuf->buf;
+ *reg2_len = circbuf->len - *reg1_len;
+ } else {
+ *reg2 = NULL;
+ *reg2_len = 0;
+ }
+
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 &&
+ circbuf->len == 0));
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->len);
+}
+
+
+/**
+ * Get the real buffer addresses that is empty or writeable.
+ *
+ * @param circbuf The circular buffer.
+ * @param reg1 Pointer to store the first buffer address.
+ * @param reg1_len Pointer to store the length of the first buffer,
+ * in samples.
+ * @param reg2 Pointer to store the second buffer address.
+ * @param reg2_len Pointer to store the length of the second buffer,
+ * in samples.
+ */
+PJ_INLINE(void) pjmedia_circ_buf_get_write_regions(pjmedia_circ_buf *circbuf,
+ pj_int16_t **reg1,
+ unsigned *reg1_len,
+ pj_int16_t **reg2,
+ unsigned *reg2_len)
+{
+ *reg1 = circbuf->start + circbuf->len;
+ if (*reg1 >= circbuf->buf + circbuf->capacity)
+ *reg1 -= circbuf->capacity;
+ *reg1_len = circbuf->capacity - circbuf->len;
+ if (*reg1 + *reg1_len > circbuf->buf + circbuf->capacity) {
+ *reg1_len = circbuf->buf + circbuf->capacity - *reg1;
+ *reg2 = circbuf->buf;
+ *reg2_len = circbuf->start - circbuf->buf;
+ } else {
+ *reg2 = NULL;
+ *reg2_len = 0;
+ }
+
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len != 0 || (*reg1_len == 0 &&
+ circbuf->len == 0));
+ PJMEDIA_CIRC_BUF_CHECK(*reg1_len + *reg2_len == circbuf->capacity -
+ circbuf->len);
+}
+
+
+/**
+ * Read audio samples from the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ * @param data Buffer to store the read audio samples.
+ * @param count Number of samples being read.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_read(pjmedia_circ_buf *circbuf,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data in the buffer is less than requested */
+ if (count > circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt >= count) {
+ pjmedia_copy_samples(data, reg1, count);
+ } else {
+ pjmedia_copy_samples(data, reg1, reg1cnt);
+ pjmedia_copy_samples(data + reg1cnt, reg2, count - reg1cnt);
+ }
+
+ return pjmedia_circ_buf_adv_read_ptr(circbuf, count);
+}
+
+
+/**
+ * Write audio samples to the circular buffer.
+ *
+ * @param circbuf The circular buffer.
+ * @param data Audio samples to be written.
+ * @param count Number of samples being written.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_write(pjmedia_circ_buf *circbuf,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data to write is larger than buffer can store */
+ if (count > circbuf->capacity - circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_write_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt >= count) {
+ pjmedia_copy_samples(reg1, data, count);
+ } else {
+ pjmedia_copy_samples(reg1, data, reg1cnt);
+ pjmedia_copy_samples(reg2, data + reg1cnt, count - reg1cnt);
+ }
+
+ return pjmedia_circ_buf_adv_write_ptr(circbuf, count);
+}
+
+
+/**
+ * Copy audio samples from the circular buffer without changing its state.
+ *
+ * @param circbuf The circular buffer.
+ * @param start_idx Starting sample index to be copied.
+ * @param data Buffer to store the read audio samples.
+ * @param count Number of samples being read.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_copy(pjmedia_circ_buf *circbuf,
+ unsigned start_idx,
+ pj_int16_t *data,
+ unsigned count)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+
+ /* Data in the buffer is less than requested */
+ if (count + start_idx > circbuf->len)
+ return PJ_ETOOBIG;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+ if (reg1cnt > start_idx) {
+ unsigned tmp_len;
+ tmp_len = reg1cnt - start_idx;
+ if (tmp_len > count)
+ tmp_len = count;
+ pjmedia_copy_samples(data, reg1 + start_idx, tmp_len);
+ if (tmp_len < count)
+ pjmedia_copy_samples(data + tmp_len, reg2, count - tmp_len);
+ } else {
+ pjmedia_copy_samples(data, reg2 + start_idx - reg1cnt, count);
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Pack the buffer so the first sample will be in the beginning of the buffer.
+ * This will also make the buffer contiguous.
+ *
+ * @param circbuf The circular buffer.
+ *
+ * @return PJ_SUCCESS when successful, otherwise
+ * the appropriate error will be returned.
+ */
+PJ_INLINE(pj_status_t) pjmedia_circ_buf_pack_buffer(pjmedia_circ_buf *circbuf)
+{
+ pj_int16_t *reg1, *reg2;
+ unsigned reg1cnt, reg2cnt;
+ unsigned gap;
+
+ pjmedia_circ_buf_get_read_regions(circbuf, &reg1, &reg1cnt,
+ &reg2, &reg2cnt);
+
+ /* Check if not contigue */
+ if (reg2cnt != 0) {
+ /* Check if no space left to roll the buffer
+ * (or should this function provide temporary buffer?)
+ */
+ gap = circbuf->capacity - pjmedia_circ_buf_get_len(circbuf);
+ if (gap == 0)
+ return PJ_ETOOBIG;
+
+ /* Roll buffer left using the gap until reg2cnt == 0 */
+ do {
+ if (gap > reg2cnt)
+ gap = reg2cnt;
+ pjmedia_move_samples(reg1 - gap, reg1, reg1cnt);
+ pjmedia_copy_samples(reg1 + reg1cnt - gap, reg2, gap);
+ if (gap < reg2cnt)
+ pjmedia_move_samples(reg2, reg2 + gap, reg2cnt - gap);
+ reg1 -= gap;
+ reg1cnt += gap;
+ reg2cnt -= gap;
+ } while (reg2cnt > 0);
+ }
+
+ /* Finally, Shift samples to the left edge */
+ if (reg1 != circbuf->buf)
+ pjmedia_move_samples(circbuf->buf, reg1,
+ pjmedia_circ_buf_get_len(circbuf));
+ circbuf->start = circbuf->buf;
+
+ return PJ_SUCCESS;
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/pjmedia/include/pjmedia/clock.h b/pjmedia/include/pjmedia/clock.h
new file mode 100644
index 0000000..2433eed
--- /dev/null
+++ b/pjmedia/include/pjmedia/clock.h
@@ -0,0 +1,335 @@
+/* $Id: clock.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CLOCK_H__
+#define __PJMEDIA_CLOCK_H__
+
+/**
+ * @file clock.h
+ * @brief Media clock.
+ */
+#include <pjmedia/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_PORT_CLOCK Clock/Timing
+ * @ingroup PJMEDIA_PORT
+ * @brief Various types of classes that provide timing.
+ * @{
+
+ The media clock/timing extends the media port concept that is explained
+ in @ref PJMEDIA_PORT. When clock is present in the ports
+ interconnection, media will flow automatically (and with correct timing too!)
+ from one media port to another.
+
+ There are few objects in PJMEDIA that are able to provide clock/timing
+ to media ports interconnection:
+
+ - @ref PJMED_SND_PORT\n
+ The sound device makes a good candidate as the clock source, and
+ PJMEDIA @ref PJMED_SND is designed so that it is able to invoke
+ operations according to timing driven by the sound hardware clock
+ (this may sound complicated, but actually it just means that
+ the sound device abstraction provides callbacks to be called when
+ it has/wants media frames).\n
+ See @ref PJMED_SND_PORT for more details.
+
+ - @ref PJMEDIA_MASTER_PORT\n
+ The master port uses @ref PJMEDIA_CLOCK as the clock source. By using
+ @ref PJMEDIA_MASTER_PORT, it is possible to interconnect passive
+ media ports and let the frames flow automatically in timely manner.\n
+ Please see @ref PJMEDIA_MASTER_PORT for more details.
+
+ @}
+ */
+
+
+/**
+ * @addtogroup PJMEDIA_CLOCK Clock Generator
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Interface for generating clock.
+ * @{
+ *
+ * The clock generator provides the application with media timing,
+ * and it is used by the @ref PJMEDIA_MASTER_PORT for its sound clock.
+ *
+ * The clock generator may be configured to run <b>asynchronously</b>
+ * (the default behavior) or <b>synchronously</b>. When it is run
+ * asynchronously, it will call the application's callback every time
+ * the clock <b>tick</b> expires. When it is run synchronously,
+ * application must continuously polls the clock generator to synchronize
+ * the timing.
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Media clock source.
+ */
+typedef struct pjmedia_clock_src
+{
+ pjmedia_type media_type; /**< Media type. */
+ unsigned clock_rate; /**< Clock rate. */
+ unsigned ptime_usec; /**< Frame interval (in usec). */
+ /**
+ * The timestamp field holds an increasing value in samples and its
+ * value is expected to be increased by clock_rate samples per second.
+ */
+ pj_timestamp timestamp;
+ /**
+ * Timestamp's last update. The last_update field contains a value in
+ * ticks, and it is expected to be increased by pj_get_timestamp_freq()
+ * ticks per second.
+ */
+ pj_timestamp last_update;
+} pjmedia_clock_src;
+
+/**
+ * This is an auxiliary function to initialize the media clock source.
+ *
+ * @param clocksrc The clock source to be initialized.
+ * @param media_type The media type.
+ * @param clock_rate The clock rate.
+ * @param ptime_usec Media frame interval (in usec).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_src_init( pjmedia_clock_src *clocksrc,
+ pjmedia_type media_type,
+ unsigned clock_rate,
+ unsigned ptime_usec );
+
+/**
+ * This function updates the clock source's timestamp. Application should
+ * use this function instead of updating the timestamp directly since this
+ * function will also update the last_update field of the clock source.
+ *
+ * @param clocksrc The clock source to be updated.
+ * @param timestamp The new timestamp, can be NULL if the current
+ * timestamp does not change (in this case it
+ * will only update the last_update field).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_src_update( pjmedia_clock_src *clocksrc,
+ const pj_timestamp *timestamp );
+
+/**
+ * This function gets the clock source's current timestamp. Application
+ * should use this function instead of accessing the timestamp directly
+ * since this function will calculate the predicted timestamp for current
+ * time, based on the values of timestamp, last_update, and clock_rate.
+ *
+ * @param clocksrc The clock source.
+ * @param timestamp Argument to receive the current timestamp
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,
+ pj_timestamp *timestamp);
+
+/**
+ * This function gets the clock source's time in msec.
+ *
+ * @param clocksrc The clock source.
+ *
+ * @return The clock source's time (in msec).
+ */
+PJ_DECL(pj_uint32_t)
+pjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc );
+
+
+/**
+ * Opaque declaration for media clock.
+ */
+typedef struct pjmedia_clock pjmedia_clock;
+
+
+/**
+ * Options when creating the clock.
+ */
+enum pjmedia_clock_options
+{
+ /**
+ * Prevents the clock from running asynchronously. In this case,
+ * application must poll the clock continuously by calling
+ * #pjmedia_clock_wait() in order to synchronize timing.
+ */
+ PJMEDIA_CLOCK_NO_ASYNC = 1,
+
+ /**
+ * Prevent the clock from setting it's thread to highest priority.
+ */
+ PJMEDIA_CLOCK_NO_HIGHEST_PRIO = 2
+};
+
+
+typedef struct pjmedia_clock_param
+{
+ /**
+ * The frame interval, in microseconds.
+ */
+ unsigned usec_interval;
+ /**
+ * The media clock rate, to determine timestamp
+ * increment for each call.
+ */
+ unsigned clock_rate;
+} pjmedia_clock_param;
+
+/**
+ * Type of media clock callback.
+ *
+ * @param ts Current timestamp, in samples.
+ * @param user_data Application data that is passed when
+ * the clock was created.
+ */
+typedef void pjmedia_clock_callback(const pj_timestamp *ts,
+ void *user_data);
+
+
+
+/**
+ * Create media clock. This creates a media clock object that will run
+ * periodically at an interval that is calculated from the audio parameters.
+ * Once created, application must call #pjmedia_clock_start() to actually
+ * start the clock.
+ *
+ * @see pjmedia_clock_create2()
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Number of samples per second.
+ * @param channel_count Number of channel.
+ * @param samples_per_frame Number of samples per frame. This argument
+ * along with clock_rate and channel_count, specifies
+ * the interval of each clock run (or clock ticks).
+ * @param options Bitmask of pjmedia_clock_options.
+ * @param cb Callback to be called for each clock tick.
+ * @param user_data User data, which will be passed to the callback.
+ * @param p_clock Pointer to receive the clock instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned options,
+ pjmedia_clock_callback *cb,
+ void *user_data,
+ pjmedia_clock **p_clock);
+
+
+/**
+ * Create media clock. This creates a media clock object that will run
+ * periodically at the specified interval. Once created, application must
+ * call #pjmedia_clock_start() to actually start the clock.
+ *
+ * @param pool Pool to allocate memory.
+ * @param param The clock parameter.
+ * @param options Bitmask of pjmedia_clock_options.
+ * @param cb Callback to be called for each clock tick.
+ * @param user_data User data, which will be passed to the callback.
+ * @param p_clock Pointer to receive the clock instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_create2(pj_pool_t *pool,
+ const pjmedia_clock_param *param,
+ unsigned options,
+ pjmedia_clock_callback *cb,
+ void *user_data,
+ pjmedia_clock **p_clock);
+
+/**
+ * Start the clock. For clock created with asynchronous flag set to TRUE,
+ * this may start a worker thread for the clock (depending on the
+ * backend clock implementation being used).
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock);
+
+
+/**
+ * Stop the clock.
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock);
+
+
+/**
+ * Modify the clock's parameter.
+ *
+ * @param clock The media clock.
+ * @param param The clock's new parameter.
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_modify(pjmedia_clock *clock,
+ const pjmedia_clock_param *param);
+
+
+/**
+ * Poll the media clock, and execute the callback when the clock tick has
+ * elapsed. This operation is only valid if the clock is created with async
+ * flag set to FALSE.
+ *
+ * @param clock The media clock.
+ * @param wait If non-zero, then the function will block until
+ * a clock tick elapsed and callback has been called.
+ * @param ts Optional argument to receive the current
+ * timestamp.
+ *
+ * @return Non-zero if clock tick has elapsed, or FALSE if
+ * the function returns before a clock tick has
+ * elapsed.
+ */
+PJ_DECL(pj_bool_t) pjmedia_clock_wait(pjmedia_clock *clock,
+ pj_bool_t wait,
+ pj_timestamp *ts);
+
+
+/**
+ * Destroy the clock.
+ *
+ * @param clock The media clock.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CLOCK_H__ */
+
diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h
new file mode 100644
index 0000000..62c79e0
--- /dev/null
+++ b/pjmedia/include/pjmedia/codec.h
@@ -0,0 +1,1126 @@
+/* $Id: codec.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CODEC_H__
+#define __PJMEDIA_CODEC_H__
+
+
+/**
+ * @file codec.h
+ * @brief Codec framework.
+ */
+
+#include <pjmedia/port.h>
+#include <pj/errno.h>
+#include <pj/list.h>
+#include <pj/pool.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_CODEC Codec Framework
+ * @brief Media codec framework and management
+ * @{
+ *
+ * @section codec_mgmt_sec Codec Management
+ * @subsection codec_fact_sec Codec Manager
+ *
+ * The codec manager is used to manage all codec capabilities in the endpoint.
+ * When used with media endpoint (pjmedia_endpt), application can retrieve
+ * the codec manager instance by calling #pjmedia_endpt_get_codec_mgr().
+ *
+ * @subsection reg_new_codec Registering New Codec
+ *
+ * New codec types can be registered to PJMEDIA (or to be precise, to the
+ * codec manager) during run-time.
+ * To do this, application needs to initialize an instance of
+ * codec factory (#pjmedia_codec_factory) and registers this codec factory
+ * by calling #pjmedia_codec_mgr_register_factory().
+ *
+ * For codecs implemented/supported by PJMEDIA, this process is normally
+ * concealed in an easy to use function such as #pjmedia_codec_g711_init().
+ *
+ * @subsection codec_factory Codec Factory
+ *
+ * A codec factory (#pjmedia_codec_factory) is registered to codec manager,
+ * and it is used to create and release codec instance.
+ *
+ * The most important member of the codec factory is the "virtual" function
+ * table #pjmedia_codec_factory_op, where it contains, among other thing,
+ * pointer to functions to allocate and deallocate codec instance.
+ *
+ * @subsection codec_inst Codec Instance
+ *
+ * Application allocates codec instance by calling #pjmedia_codec_mgr_alloc_codec().
+ * One codec instance (#pjmedia_codec) can be used for simultaneous encoding
+ * and decoding.
+ *
+ * The most important member of the codec instance is the "virtual" function
+ * table #pjmedia_codec_op, where it holds pointer to functions to
+ * encode/decode media frames.
+ *
+ * @subsection codec_ident Codec Identification
+ *
+ * A particular codec type in PJMEDIA can be uniquely identified by two
+ * keys: by #pjmedia_codec_info, or by #pjmedia_codec_id string. A fully
+ * qualified codec ID string consists of codec name, sampling rate, and
+ * number of channels. However, application may use only first parts of
+ * the tokens as long as it will make to codec ID unique. For example, "gsm"
+ * is a fully qualified codec name, since it will always have 8000 clock
+ * rate and 1 channel. Other examples of fully qualified codec ID strings
+ * are "pcma", "speex/8000", "speex/16000", and "L16/16000/1". A codec
+ * id "speex" (without clock rate) is not fully qualified, since it will
+ * match the narrowband, wideband, and ultrawideband Speex codec.
+ *
+ * The two keys can be converted to one another, with
+ * #pjmedia_codec_info_to_id() and #pjmedia_codec_mgr_find_codecs_by_id()
+ * functions.
+ *
+ * Codec ID string is not case sensitive.
+ *
+ *
+ * @section using_codec Using the Codec Framework
+ * @subsection init_alloc_codec Allocating Codec
+ *
+ * Application needs to allocate one codec instance for encoding and decoding
+ * media frames. One codec instance can be used to perform both encoding
+ * and decoding.
+ *
+ * Application allocates codec by calling #pjmedia_codec_mgr_alloc_codec().
+ * This function takes #pjmedia_codec_info argument, which is used to locate
+ * the particular codec factory to be used to allocate the codec.
+ *
+ * Application can build #pjmedia_codec_info structure manually for
+ * the specific codec, or alternatively it may get the #pjmedia_codec_info
+ * from the codec ID string, by using #pjmedia_codec_mgr_find_codecs_by_id()
+ * function.
+ *
+ * The following snippet shows an example to allocate a codec:
+ *
+ \code
+ pj_str_t codec_id;
+ pjmedia_codec_info *codec_info;
+ unsigned count = 1;
+ pjmedia_codec *codec;
+
+ codec_id = pj_str("pcma");
+
+ // Find codec info for the specified coded ID (i.e. "pcma").
+ status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr, &codec_id,
+ &count, &codec_info, NULL);
+
+ // Allocate the codec.
+ status = pjmedia_codec_mgr_alloc_codec( codec_mgr, codec_info, &codec );
+
+ \endcode
+ *
+ *
+ * @subsection opening_codec Initializing Codec
+ *
+ * Once codec is allocated, application needs to initialize the codec
+ * by calling <b><tt>open</tt></b> member of the codec. This function
+ * takes #pjmedia_codec_param as the argument, which contains the
+ * settings for the codec.
+ *
+ * Application shoud use #pjmedia_codec_mgr_get_default_param() function
+ * to initiaize #pjmedia_codec_param. The <tt>setting</tt> part of
+ * #pjmedia_codec_param then can be tuned to suit the application's
+ * requirements.
+ *
+ * The following snippet shows an example to initialize codec:
+ *
+ \code
+ pjmedia_codec_param param;
+
+ // Retrieve default codec param for the specified codec.
+ pjmedia_codec_mgr_get_default_param(codec_mgr, codec_info
+ &param);
+
+ // Application may change the "settings" part of codec param,
+ // for example, to disable VAD
+ param.setting.vad = 0;
+
+ // Open the codec using the specified settings.
+ codec->op->open( codec, &param );
+
+ \endcode
+ *
+ *
+ * @subsection enc_dec_codec Encoding and Decoding Media Frames
+ *
+ * Application encodes and decodes media frames by calling
+ * <tt>encode</tt> and <tt>decode</tt> member of the codec's "virtual"
+ * function table (#pjmedia_codec_op).
+ *
+ * @subsection plc_codec Concealing Lost Frames
+ *
+ * All codecs has Packet Lost Concealment (PLC) feature, and application
+ * can activate the PLC to conceal lost frames by calling <tt>recover</tt>
+ * member of the codec's "virtual" function table (#pjmedia_codec_op).
+ *
+ * If the codec's algorithm supports PLC, the <tt>recover</tt> function
+ * will use the codec's PLC. Otherwise for codecs that don't have
+ * intrinsic PLC, PJMEDIA will suply the PLC implementation from the
+ * @ref PJMED_PLC implementation.
+ *
+ * @subsection close_codec Closing and Releasing the Codec
+ *
+ * The codec must be closed by calling <tt>close</tt> member of the codec's
+ * operation. Then it must be released by calling
+ * #pjmedia_codec_mgr_dealloc_codec().
+ */
+
+
+/**
+ * Standard RTP static payload types, as defined by RFC 3551.
+ * The header file <pjmedia-codec/types.h> also declares dynamic payload
+ * type numbers that are used by PJMEDIA when advertising the capability
+ * for example in SDP message.
+ */
+enum pjmedia_rtp_pt
+{
+ PJMEDIA_RTP_PT_PCMU = 0, /**< audio PCMU */
+ PJMEDIA_RTP_PT_G721 = 2, /**< audio G721 (old def for G726-32) */
+ PJMEDIA_RTP_PT_GSM = 3, /**< audio GSM */
+ PJMEDIA_RTP_PT_G723 = 4, /**< audio G723 */
+ PJMEDIA_RTP_PT_DVI4_8K = 5, /**< audio DVI4 8KHz */
+ PJMEDIA_RTP_PT_DVI4_16K = 6, /**< audio DVI4 16Khz */
+ PJMEDIA_RTP_PT_LPC = 7, /**< audio LPC */
+ PJMEDIA_RTP_PT_PCMA = 8, /**< audio PCMA */
+ PJMEDIA_RTP_PT_G722 = 9, /**< audio G722 */
+ PJMEDIA_RTP_PT_L16_2 = 10, /**< audio 16bit linear 44.1KHz stereo */
+ PJMEDIA_RTP_PT_L16_1 = 11, /**< audio 16bit linear 44.1KHz mono */
+ PJMEDIA_RTP_PT_QCELP = 12, /**< audio QCELP */
+ PJMEDIA_RTP_PT_CN = 13, /**< audio Comfort Noise */
+ PJMEDIA_RTP_PT_MPA = 14, /**< audio MPEG1/MPEG2 elemetr. streams */
+ PJMEDIA_RTP_PT_G728 = 15, /**< audio G728 */
+ PJMEDIA_RTP_PT_DVI4_11K = 16, /**< audio DVI4 11.025KHz mono */
+ PJMEDIA_RTP_PT_DVI4_22K = 17, /**< audio DVI4 22.050KHz mono */
+ PJMEDIA_RTP_PT_G729 = 18, /**< audio G729 */
+
+ PJMEDIA_RTP_PT_CELB = 25, /**< video/comb Cell-B by Sun (RFC2029) */
+ PJMEDIA_RTP_PT_JPEG = 26, /**< video JPEG */
+ PJMEDIA_RTP_PT_NV = 28, /**< video NV by nv program by Xerox */
+ PJMEDIA_RTP_PT_H261 = 31, /**< video H261 */
+ PJMEDIA_RTP_PT_MPV = 32, /**< video MPEG1 or MPEG2 elementary */
+ PJMEDIA_RTP_PT_MP2T = 33, /**< video MPEG2 transport */
+ PJMEDIA_RTP_PT_H263 = 34, /**< video H263 */
+
+ PJMEDIA_RTP_PT_DYNAMIC = 96 /**< start of dynamic RTP payload */
+
+};
+
+
+/**
+ * Identification used to search for codec factory that supports specific
+ * codec specification.
+ */
+typedef struct pjmedia_codec_info
+{
+ pjmedia_type type; /**< Media type. */
+ unsigned pt; /**< Payload type (can be dynamic). */
+ pj_str_t encoding_name; /**< Encoding name. */
+ unsigned clock_rate; /**< Sampling rate. */
+ unsigned channel_cnt; /**< Channel count. */
+} pjmedia_codec_info;
+
+/**
+ * Structure of codec specific parameters which contains name=value pairs.
+ * The codec specific parameters are to be used with SDP according to
+ * the standards (e.g: RFC 3555) in SDP 'a=fmtp' attribute.
+ */
+typedef struct pjmedia_codec_fmtp
+{
+ pj_uint8_t cnt; /**< Number of parameters. */
+ struct param {
+ pj_str_t name; /**< Parameter name. */
+ pj_str_t val; /**< Parameter value. */
+ } param [PJMEDIA_CODEC_MAX_FMTP_CNT]; /**< The parameters. */
+} pjmedia_codec_fmtp;
+
+/**
+ * Detailed codec attributes used in configuring a codec and in querying
+ * the capability of codec factories. Default attributes of any codecs could
+ * be queried using #pjmedia_codec_mgr_get_default_param() and modified
+ * using #pjmedia_codec_mgr_set_default_param().
+ *
+ * Please note that codec parameter also contains SDP specific setting,
+ * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on
+ * the effective setting. See each codec documentation for more detail.
+ */
+typedef struct pjmedia_codec_param
+{
+ /**
+ * The "info" part of codec param describes the capability of the codec,
+ * and the value should NOT be changed by application.
+ */
+ struct {
+ unsigned clock_rate; /**< Sampling rate in Hz */
+ unsigned channel_cnt; /**< Channel count. */
+ pj_uint32_t avg_bps; /**< Average bandwidth in bits/sec */
+ pj_uint32_t max_bps; /**< Maximum bandwidth in bits/sec */
+ pj_uint16_t frm_ptime; /**< Decoder frame ptime in msec. */
+ pj_uint16_t enc_ptime; /**< Encoder ptime, or zero if it's
+ equal to decoder ptime. */
+ pj_uint8_t pcm_bits_per_sample; /**< Bits/sample in the PCM side */
+ pj_uint8_t pt; /**< Payload type. */
+ pjmedia_format_id fmt_id; /**< Source format, it's format of
+ encoder input and decoder
+ output. */
+ } info;
+
+ /**
+ * The "setting" part of codec param describes various settings to be
+ * applied to the codec. When the codec param is retrieved from the codec
+ * or codec factory, the values of these will be filled by the capability
+ * of the codec. Any features that are supported by the codec (e.g. vad
+ * or plc) will be turned on, so that application can query which
+ * capabilities are supported by the codec. Application may change the
+ * settings here before instantiating the codec/stream.
+ */
+ struct {
+ pj_uint8_t frm_per_pkt; /**< Number of frames per packet. */
+ unsigned vad:1; /**< Voice Activity Detector. */
+ unsigned cng:1; /**< Comfort Noise Generator. */
+ unsigned penh:1; /**< Perceptual Enhancement */
+ unsigned plc:1; /**< Packet loss concealment */
+ unsigned reserved:1; /**< Reserved, must be zero. */
+ pjmedia_codec_fmtp enc_fmtp;/**< Encoder's fmtp params. */
+ pjmedia_codec_fmtp dec_fmtp;/**< Decoder's fmtp params. */
+ } setting;
+} pjmedia_codec_param;
+
+
+
+/*
+ * Forward declaration for pjmedia_codec.
+ */
+typedef struct pjmedia_codec pjmedia_codec;
+
+
+/**
+ * This structure describes codec operations. Each codec MUST implement
+ * all of these functions.
+ */
+typedef struct pjmedia_codec_op
+{
+ /**
+ * Initialize codec using the specified attribute.
+ *
+ * Application should call #pjmedia_codec_init() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate
+ * some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*init)(pjmedia_codec *codec,
+ pj_pool_t *pool );
+
+ /**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as enc_ptime, when
+ * encoder ptime is different than decoder ptime).
+ *
+ * Application should call #pjmedia_codec_open() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*open)(pjmedia_codec *codec,
+ pjmedia_codec_param *param );
+
+ /**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * Application should call #pjmedia_codec_close() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*close)(pjmedia_codec *codec);
+
+ /**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * Application can expect changing trivial codec settings such as
+ * changing VAD setting to succeed.
+ *
+ * Application should call #pjmedia_codec_modify() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*modify)(pjmedia_codec *codec,
+ const pjmedia_codec_param *param );
+
+ /**
+ * Instruct the codec to inspect the specified payload/packet and
+ * split the packet into individual base frames. Each output frames will
+ * have ptime that is equal to basic frame ptime (i.e. the value of
+ * info.frm_ptime in #pjmedia_codec_param).
+ *
+ * Application should call #pjmedia_codec_parse() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*parse)( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *timestamp,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[]);
+
+ /**
+ * Instruct the codec to encode the specified input frame. The input
+ * PCM samples MUST have ptime that is multiplication of base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ *
+ * Application should call #pjmedia_codec_encode() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*encode)(pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST have ptime that is exactly equal to base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ * Application can achieve this by parsing the packet into base
+ * frames before decoding each frame.
+ *
+ * Application should call #pjmedia_codec_decode() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*decode)(pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+
+ /**
+ * Instruct the codec to recover a missing frame.
+ *
+ * Application should call #pjmedia_codec_recover() instead of
+ * calling this function directly.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+ pj_status_t (*recover)(pjmedia_codec *codec,
+ unsigned out_size,
+ struct pjmedia_frame *output);
+} pjmedia_codec_op;
+
+
+
+/*
+ * Forward declaration for pjmedia_codec_factory.
+ */
+typedef struct pjmedia_codec_factory pjmedia_codec_factory;
+
+
+/**
+ * This structure describes a codec instance.
+ */
+struct pjmedia_codec
+{
+ /** Entries to put this codec instance in codec factory's list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_codec);
+
+ /** Codec's private data. */
+ void *codec_data;
+
+ /** Codec factory where this codec was allocated. */
+ pjmedia_codec_factory *factory;
+
+ /** Operations to codec. */
+ pjmedia_codec_op *op;
+};
+
+
+
+/**
+ * This structure describes operations that must be supported by codec
+ * factories.
+ */
+typedef struct pjmedia_codec_factory_op
+{
+ /**
+ * Check whether the factory can create codec with the specified
+ * codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ *
+ * @return PJ_SUCCESS if this factory is able to create an
+ * instance of codec with the specified info.
+ */
+ pj_status_t (*test_alloc)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info );
+
+ /**
+ * Create default attributes for the specified codec ID. This function
+ * can be called by application to get the capability of the codec.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param attr The attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+ pj_status_t (*default_attr)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info,
+ pjmedia_codec_param *attr );
+
+ /**
+ * Enumerate supported codecs that can be created using this factory.
+ *
+ * @param factory The codec factory.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*enum_info)(pjmedia_codec_factory *factory,
+ unsigned *count,
+ pjmedia_codec_info codecs[]);
+
+ /**
+ * Create one instance of the codec with the specified codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*alloc_codec)(pjmedia_codec_factory *factory,
+ const pjmedia_codec_info *info,
+ pjmedia_codec **p_codec);
+
+ /**
+ * This function is called by codec manager to return a particular
+ * instance of codec back to the codec factory.
+ *
+ * @param factory The codec factory.
+ * @param codec The codec instance to be returned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*dealloc_codec)(pjmedia_codec_factory *factory,
+ pjmedia_codec *codec );
+
+ /**
+ * This callback will be called to deinitialize and destroy this factory.
+ */
+ pj_status_t (*destroy)(void);
+
+} pjmedia_codec_factory_op;
+
+
+
+/**
+ * Codec factory describes a module that is able to create codec with specific
+ * capabilities. These capabilities can be queried by codec manager to create
+ * instances of codec.
+ */
+struct pjmedia_codec_factory
+{
+ /** Entries to put this structure in the codec manager list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_codec_factory);
+
+ /** The factory's private data. */
+ void *factory_data;
+
+ /** Operations to the factory. */
+ pjmedia_codec_factory_op *op;
+
+};
+
+
+/**
+ * Declare maximum codecs
+ */
+#define PJMEDIA_CODEC_MGR_MAX_CODECS 32
+
+
+/**
+ * Specify these values to set the codec priority, by calling
+ * #pjmedia_codec_mgr_set_codec_priority().
+ */
+typedef enum pjmedia_codec_priority
+{
+ /**
+ * This priority makes the codec the highest in the order.
+ * The last codec specified with this priority will get the
+ * highest place in the order, and will change the priority
+ * of previously highest priority codec to NEXT_HIGHER.
+ */
+ PJMEDIA_CODEC_PRIO_HIGHEST = 255,
+
+ /**
+ * This priority will put the codec as the next codec after
+ * codecs with this same priority.
+ */
+ PJMEDIA_CODEC_PRIO_NEXT_HIGHER = 254,
+
+ /**
+ * This is the initial codec priority when it is registered to
+ * codec manager by codec factory.
+ */
+ PJMEDIA_CODEC_PRIO_NORMAL = 128,
+
+ /**
+ * This priority makes the codec the lowest in the order.
+ * The last codec specified with this priority will be put
+ * in the last place in the order.
+ */
+ PJMEDIA_CODEC_PRIO_LOWEST = 1,
+
+ /**
+ * This priority will prevent the codec from being listed in the
+ * SDP created by media endpoint, thus should prevent the codec
+ * from being used in the sessions. However, the codec will still
+ * be listed by #pjmedia_codec_mgr_enum_codecs() and other codec
+ * query functions.
+ */
+ PJMEDIA_CODEC_PRIO_DISABLED = 0
+
+} pjmedia_codec_priority;
+
+
+/**
+ * Codec identification (e.g. "pcmu/8000/1").
+ * See @ref codec_ident for more info.
+ */
+typedef char pjmedia_codec_id[32];
+
+
+/**
+ * Opaque declaration of default codecs parameters.
+ */
+typedef struct pjmedia_codec_default_param pjmedia_codec_default_param;
+
+/**
+ * Codec manager maintains array of these structs for each supported
+ * codec.
+ */
+struct pjmedia_codec_desc
+{
+ pjmedia_codec_info info; /**< Codec info. */
+ pjmedia_codec_id id; /**< Fully qualified name */
+ pjmedia_codec_priority prio; /**< Priority. */
+ pjmedia_codec_factory *factory; /**< The factory. */
+ pjmedia_codec_default_param *param; /**< Default codecs
+ parameters. */
+};
+
+
+/**
+ * The declaration for codec manager. Application doesn't normally need
+ * to see this declaration, but nevertheless this declaration is needed
+ * by media endpoint to instantiate the codec manager.
+ */
+typedef struct pjmedia_codec_mgr
+{
+ /** Media endpoint instance. */
+ pj_pool_factory *pf;
+
+ /** Codec manager pool. */
+ pj_pool_t *pool;
+
+ /** Codec manager mutex. */
+ pj_mutex_t *mutex;
+
+ /** List of codec factories registered to codec manager. */
+ pjmedia_codec_factory factory_list;
+
+ /** Number of supported codecs. */
+ unsigned codec_cnt;
+
+ /** Array of codec descriptor. */
+ struct pjmedia_codec_desc codec_desc[PJMEDIA_CODEC_MGR_MAX_CODECS];
+
+} pjmedia_codec_mgr;
+
+
+
+/**
+ * Initialize codec manager. Normally this function is called by pjmedia
+ * endpoint's initialization code.
+ *
+ * @param mgr Codec manager instance.
+ * @param pf Pool factory instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_init(pjmedia_codec_mgr *mgr,
+ pj_pool_factory *pf);
+
+
+/**
+ * Destroy codec manager. Normally this function is called by pjmedia
+ * endpoint's deinitialization code.
+ *
+ * @param mgr Codec manager instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_destroy(pjmedia_codec_mgr *mgr);
+
+
+/**
+ * Register codec factory to codec manager. This will also register
+ * all supported codecs in the factory to the codec manager.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param factory The codec factory to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_register_factory( pjmedia_codec_mgr *mgr,
+ pjmedia_codec_factory *factory);
+
+/**
+ * Unregister codec factory from the codec manager. This will also
+ * remove all the codecs registered by the codec factory from the
+ * codec manager's list of supported codecs. This function should
+ * only be called by the codec implementers and not by application.
+ *
+ * @param mgr The codec manager instance, use
+ * #pjmedia_endpt_get_codec_mgr().
+ * @param factory The codec factory to be unregistered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_unregister_factory( pjmedia_codec_mgr *mgr,
+ pjmedia_codec_factory *factory);
+
+/**
+ * Enumerate all supported codecs that have been registered to the
+ * codec manager by codec factories.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ * @param prio Optional pointer to receive array of codec priorities.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_enum_codecs( pjmedia_codec_mgr *mgr,
+ unsigned *count,
+ pjmedia_codec_info info[],
+ unsigned *prio);
+
+/**
+ * Get codec info for the specified static payload type. Note that
+ * this can only find codec with static payload types. This function can
+ * be used to find codec info for a payload type inside SDP which doesn't
+ * have the corresponding rtpmap attribute.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param pt Static payload type/number.
+ * @param inf Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_get_codec_info( pjmedia_codec_mgr *mgr,
+ unsigned pt,
+ const pjmedia_codec_info **inf);
+
+/**
+ * Convert codec info struct into a unique codec identifier.
+ * A codec identifier looks something like "L16/44100/2".
+ *
+ * @param info The codec info
+ * @param id Buffer to put the codec info string.
+ * @param max_len The length of the buffer.
+ *
+ * @return The null terminated codec info string, or NULL if
+ * the buffer is not long enough.
+ */
+PJ_DECL(char*) pjmedia_codec_info_to_id(const pjmedia_codec_info *info,
+ char *id, unsigned max_len );
+
+
+/**
+ * Find codecs by the unique codec identifier. This function will find
+ * all codecs that match the codec identifier prefix. For example, if
+ * "L16" is specified, then it will find "L16/8000/1", "L16/16000/1",
+ * and so on, up to the maximum count specified in the argument.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param count Maximum number of codecs to find. On return, it
+ * contains the actual number of codecs found.
+ * @param p_info Array of pointer to codec info to be filled. This
+ * argument may be NULL, which in this case, only
+ * codec count will be returned.
+ * @param prio Optional array of codec priorities.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_find_codecs_by_id( pjmedia_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ unsigned *count,
+ const pjmedia_codec_info *p_info[],
+ unsigned prio[]);
+
+
+/**
+ * Set codec priority. The codec priority determines the order of
+ * the codec in the SDP created by the endpoint. If more than one codecs
+ * are found with the same codec_id prefix, then the function sets the
+ * priorities of all those codecs.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param prio Priority to be set. The priority can have any value
+ * between 1 to 255. When the priority is set to zero,
+ * the codec will be disabled.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_set_codec_priority(pjmedia_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ pj_uint8_t prio);
+
+
+/**
+ * Get default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param info The codec info, which default parameter's is being
+ * queried.
+ * @param param On return, will be filled with the default codec
+ * parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_get_default_param( pjmedia_codec_mgr *mgr,
+ const pjmedia_codec_info *info,
+ pjmedia_codec_param *param );
+
+
+/**
+ * Set default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param info The codec info, which default parameter's is being
+ * updated.
+ * @param param The new default codec parameter. Set to NULL to reset
+ * codec parameter to library default settings.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_set_default_param( pjmedia_codec_mgr *mgr,
+ const pjmedia_codec_info *info,
+ const pjmedia_codec_param *param );
+
+
+/**
+ * Request the codec manager to allocate one instance of codec with the
+ * specified codec info. The codec will enumerate all codec factories
+ * until it finds factory that is able to create the specified codec.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param info The information about the codec to be created.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_codec_mgr_alloc_codec( pjmedia_codec_mgr *mgr,
+ const pjmedia_codec_info *info,
+ pjmedia_codec **p_codec);
+
+/**
+ * Deallocate the specified codec instance. The codec manager will return
+ * the instance of the codec back to its factory.
+ *
+ * @param mgr The codec manager instance. Application can get the
+ * instance by calling #pjmedia_endpt_get_codec_mgr().
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_mgr_dealloc_codec(pjmedia_codec_mgr *mgr,
+ pjmedia_codec *codec);
+
+
+
+/**
+ * Initialize codec using the specified attribute.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_init( pjmedia_codec *codec,
+ pj_pool_t *pool )
+{
+ return (*codec->op->init)(codec, pool);
+}
+
+
+/**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as enc_ptime, when
+ * encoder ptime is different than decoder ptime).
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_open( pjmedia_codec *codec,
+ pjmedia_codec_param *param )
+{
+ return (*codec->op->open)(codec, param);
+}
+
+
+/**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_close( pjmedia_codec *codec )
+{
+ return (*codec->op->close)(codec);
+}
+
+
+/**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * Application can expect changing trivial codec settings such as
+ * changing VAD setting to succeed.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_modify(pjmedia_codec *codec,
+ const pjmedia_codec_param *param)
+{
+ return (*codec->op->modify)(codec, param);
+}
+
+
+/**
+ * Instruct the codec to inspect the specified payload/packet and
+ * split the packet into individual base frames. Each output frames will
+ * have ptime that is equal to basic frame ptime (i.e. the value of
+ * info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance
+ * @param pkt The input packet.
+ * @param pkt_size Size of the packet.
+ * @param timestamp The timestamp of the first sample in the packet.
+ * @param frame_cnt On input, specifies the maximum number of frames
+ * in the array. On output, the codec must fill
+ * with number of frames detected in the packet.
+ * @param frames On output, specifies the frames that have been
+ * detected in the packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_parse( pjmedia_codec *codec,
+ void *pkt,
+ pj_size_t pkt_size,
+ const pj_timestamp *timestamp,
+ unsigned *frame_cnt,
+ pjmedia_frame frames[] )
+{
+ return (*codec->op->parse)(codec, pkt, pkt_size, timestamp,
+ frame_cnt, frames);
+}
+
+
+/**
+ * Instruct the codec to encode the specified input frame. The input
+ * PCM samples MUST have ptime that is multiplication of base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_encode(
+ pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ return (*codec->op->encode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to decode the specified input frame. The input
+ * frame MUST have ptime that is exactly equal to base frame
+ * ptime (i.e. the value of info.frm_ptime in #pjmedia_codec_param).
+ * Application can achieve this by parsing the packet into base
+ * frames before decoding each frame.
+ *
+ * @param codec The codec instance.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_decode(
+ pjmedia_codec *codec,
+ const struct pjmedia_frame *input,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ return (*codec->op->decode)(codec, input, out_size, output);
+}
+
+
+/**
+ * Instruct the codec to recover a missing frame.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_codec_recover( pjmedia_codec *codec,
+ unsigned out_size,
+ struct pjmedia_frame *output )
+{
+ if (codec->op && codec->op->recover)
+ return (*codec->op->recover)(codec, out_size, output);
+ else
+ return PJ_ENOTSUP;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_CODEC_CODECS Supported codecs
+ * @ingroup PJMEDIA_CODEC
+ * @brief Documentation about individual codec supported by PJMEDIA
+ * @{
+ * Please see the APIs provided by the individual codecs below.
+ */
+/**
+ * @}
+ */
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_CODEC_H__ */
diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h
new file mode 100644
index 0000000..d392fbf
--- /dev/null
+++ b/pjmedia/include/pjmedia/conference.h
@@ -0,0 +1,509 @@
+/* $Id: conference.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CONF_H__
+#define __PJMEDIA_CONF_H__
+
+
+/**
+ * @file conference.h
+ * @brief Conference bridge.
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_CONF Conference Bridge
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio conference bridge implementation
+ * @{
+ *
+ * This describes the conference bridge implementation in PJMEDIA. The
+ * conference bridge provides powerful and very efficient mechanism to
+ * route the audio flow and mix the audio signal when required.
+ *
+ * Some more information about the media flow when conference bridge is
+ * used is described in http://www.pjsip.org/trac/wiki/media-flow .
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * The conference bridge signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_BRIDGE_SIGNATURE PJMEDIA_SIG_PORT_CONF
+
+/**
+ * The audio switchboard signature in pjmedia_port_info.
+ */
+#define PJMEDIA_CONF_SWITCH_SIGNATURE PJMEDIA_SIG_PORT_CONF_SWITCH
+
+
+/**
+ * Opaque type for conference bridge.
+ */
+typedef struct pjmedia_conf pjmedia_conf;
+
+/**
+ * Conference port info.
+ */
+typedef struct pjmedia_conf_port_info
+{
+ unsigned slot; /**< Slot number. */
+ pj_str_t name; /**< Port name. */
+ pjmedia_format format; /**< Format. */
+ pjmedia_port_op tx_setting; /**< Transmit settings. */
+ pjmedia_port_op rx_setting; /**< Receive settings. */
+ unsigned listener_cnt; /**< Number of listeners. */
+ unsigned *listener_slots; /**< Array of listeners. */
+ unsigned transmitter_cnt; /**< Number of transmitter. */
+ unsigned clock_rate; /**< Clock rate of the port. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned samples_per_frame; /**< Samples per frame */
+ unsigned bits_per_sample; /**< Bits per sample. */
+ int tx_adj_level; /**< Tx level adjustment. */
+ int rx_adj_level; /**< Rx level adjustment. */
+} pjmedia_conf_port_info;
+
+
+/**
+ * Conference port options. The values here can be combined in bitmask to
+ * be specified when the conference bridge is created.
+ */
+enum pjmedia_conf_option
+{
+ PJMEDIA_CONF_NO_MIC = 1, /**< Disable audio streams from the
+ microphone device. */
+ PJMEDIA_CONF_NO_DEVICE = 2, /**< Do not create sound device. */
+ PJMEDIA_CONF_SMALL_FILTER=4,/**< Use small filter table when resampling */
+ PJMEDIA_CONF_USE_LINEAR=8 /**< Use linear resampling instead of filter
+ based. */
+};
+
+
+/**
+ * Create conference bridge with the specified parameters. The sampling rate,
+ * samples per frame, and bits per sample will be used for the internal
+ * operation of the bridge (e.g. when mixing audio frames). However, ports
+ * with different configuration may be connected to the bridge. In this case,
+ * the bridge is able to perform sampling rate conversion, and buffering in
+ * case the samples per frame is different.
+ *
+ * For this version of PJMEDIA, only 16bits per sample is supported.
+ *
+ * For this version of PJMEDIA, the channel count of the ports MUST match
+ * the channel count of the bridge.
+ *
+ * Under normal operation (i.e. when PJMEDIA_CONF_NO_DEVICE option is NOT
+ * specified), the bridge internally create an instance of sound device
+ * and connect the sound device to port zero of the bridge.
+ *
+ * If PJMEDIA_CONF_NO_DEVICE options is specified, no sound device will
+ * be created in the conference bridge. Application MUST acquire the port
+ * interface of the bridge by calling #pjmedia_conf_get_master_port(), and
+ * connect this port interface to a sound device port by calling
+ * #pjmedia_snd_port_connect(), or to a master port (pjmedia_master_port)
+ * if application doesn't want to instantiate any sound devices.
+ *
+ * The sound device or master port are crucial for the bridge's operation,
+ * because it provides the bridge with necessary clock to process the audio
+ * frames periodically. Internally, the bridge runs when get_frame() to
+ * port zero is called.
+ *
+ * @param pool Pool to use to allocate the bridge and
+ * additional buffers for the sound device.
+ * @param max_slots Maximum number of slots/ports to be created in
+ * the bridge. Note that the bridge internally uses
+ * one port for the sound device, so the actual
+ * maximum number of ports will be less one than
+ * this value.
+ * @param sampling_rate Set the sampling rate of the bridge. This value
+ * is also used to set the sampling rate of the
+ * sound device.
+ * @param channel_count Number of channels in the PCM stream. Normally
+ * the value will be 1 for mono, but application may
+ * specify a value of 2 for stereo. Note that all
+ * ports that will be connected to the bridge MUST
+ * have the same number of channels as the bridge.
+ * @param samples_per_frame Set the number of samples per frame. This value
+ * is also used to set the sound device.
+ * @param bits_per_sample Set the number of bits per sample. This value
+ * is also used to set the sound device. Currently
+ * only 16bit per sample is supported.
+ * @param options Bitmask options to be set for the bridge. The
+ * options are constructed from #pjmedia_conf_option
+ * enumeration.
+ * @param p_conf Pointer to receive the conference bridge instance.
+ *
+ * @return PJ_SUCCESS if conference bridge can be created.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,
+ unsigned max_slots,
+ unsigned sampling_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_conf **p_conf );
+
+
+/**
+ * Destroy conference bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_destroy( pjmedia_conf *conf );
+
+
+/**
+ * Get the master port interface of the conference bridge. The master port
+ * corresponds to the port zero of the bridge. This is only usefull when
+ * application wants to manage the sound device by itself, instead of
+ * allowing the bridge to automatically create a sound device implicitly.
+ *
+ * This function will only return a port interface if PJMEDIA_CONF_NO_DEVICE
+ * option was specified when the bridge was created.
+ *
+ * Application can connect the port returned by this function to a
+ * sound device by calling #pjmedia_snd_port_connect().
+ *
+ * @param conf The conference bridge.
+ *
+ * @return The port interface of port zero of the bridge,
+ * only when PJMEDIA_CONF_NO_DEVICE options was
+ * specified when the bridge was created.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_conf_get_master_port(pjmedia_conf *conf);
+
+
+/**
+ * Set master port name.
+ *
+ * @param conf The conference bridge.
+ * @param name Name to be assigned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_set_port0_name(pjmedia_conf *conf,
+ const pj_str_t *name);
+
+
+/**
+ * Add media port to the conference bridge.
+ *
+ * By default, the new conference port will have both TX and RX enabled,
+ * but it is not connected to any other ports. Application SHOULD call
+ * #pjmedia_conf_connect_port() to enable audio transmission and receipt
+ * to/from this port.
+ *
+ * Once the media port is connected to other port(s) in the bridge,
+ * the bridge will continuosly call get_frame() and put_frame() to the
+ * port, allowing media to flow to/from the port.
+ *
+ * @param conf The conference bridge.
+ * @param pool Pool to allocate buffers for this port.
+ * @param strm_port Stream port interface.
+ * @param name Optional name for the port. If this value is NULL,
+ * the name will be taken from the name in the port
+ * info.
+ * @param p_slot Pointer to receive the slot index of the port in
+ * the conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_add_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ pjmedia_port *strm_port,
+ const pj_str_t *name,
+ unsigned *p_slot );
+
+
+/**
+ * <i><b>Warning:</b> This API has been deprecated since 1.3 and will be
+ * removed in the future release, use @ref PJMEDIA_SPLITCOMB instead.</i>
+ *
+ * Create and add a passive media port to the conference bridge. Unlike
+ * "normal" media port that is added with #pjmedia_conf_add_port(), media
+ * port created with this function will not have its get_frame() and
+ * put_frame() called by the bridge; instead, application MUST continuosly
+ * call these functions to the port, to allow media to flow from/to the
+ * port.
+ *
+ * Upon return of this function, application will be given two objects:
+ * the slot number of the port in the bridge, and pointer to the media
+ * port where application MUST start calling get_frame() and put_frame()
+ * to the port.
+ *
+ * @param conf The conference bridge.
+ * @param pool Pool to allocate buffers etc for this port.
+ * @param name Name to be assigned to the port.
+ * @param clock_rate Clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Options (should be zero at the moment).
+ * @param p_slot Pointer to receive the slot index of the port in
+ * the conference bridge.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_add_passive_port( pjmedia_conf *conf,
+ pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ unsigned *p_slot,
+ pjmedia_port **p_port );
+
+
+/**
+ * Change TX and RX settings for the port.
+ *
+ * @param conf The conference bridge.
+ * @param slot Port number/slot in the conference bridge.
+ * @param tx Settings for the transmission TO this port.
+ * @param rx Settings for the receipt FROM this port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_configure_port( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_port_op tx,
+ pjmedia_port_op rx);
+
+
+/**
+ * Enable unidirectional audio from the specified source slot to the
+ * specified sink slot.
+ *
+ * @param conf The conference bridge.
+ * @param src_slot Source slot.
+ * @param sink_slot Sink slot.
+ * @param level This argument is reserved for future improvements
+ * where it is possible to adjust the level of signal
+ * transmitted in a specific connection. For now,
+ * this argument MUST be zero.
+ *
+ * @return PJ_SUCCES on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot,
+ int level );
+
+
+/**
+ * Disconnect unidirectional audio from the specified source to the specified
+ * sink slot.
+ *
+ * @param conf The conference bridge.
+ * @param src_slot Source slot.
+ * @param sink_slot Sink slot.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
+ unsigned src_slot,
+ unsigned sink_slot );
+
+
+/**
+ * Get number of ports currently registered to the conference bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return Number of ports currently registered to the conference
+ * bridge.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf);
+
+
+/**
+ * Get total number of ports connections currently set up in the bridge.
+ *
+ * @param conf The conference bridge.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(unsigned) pjmedia_conf_get_connect_count(pjmedia_conf *conf);
+
+
+/**
+ * Remove the specified port from the conference bridge.
+ *
+ * @param conf The conference bridge.
+ * @param slot The port index to be removed.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
+ unsigned slot );
+
+
+
+/**
+ * Enumerate occupied ports in the bridge.
+ *
+ * @param conf The conference bridge.
+ * @param ports Array of port numbers to be filled in.
+ * @param count On input, specifies the maximum number of ports
+ * in the array. On return, it will be filled with
+ * the actual number of ports.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_enum_ports( pjmedia_conf *conf,
+ unsigned ports[],
+ unsigned *count );
+
+
+/**
+ * Get port info.
+ *
+ * @param conf The conference bridge.
+ * @param slot Port index.
+ * @param info Pointer to receive the info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_port_info( pjmedia_conf *conf,
+ unsigned slot,
+ pjmedia_conf_port_info *info);
+
+
+/**
+ * Get occupied ports info.
+ *
+ * @param conf The conference bridge.
+ * @param size On input, contains maximum number of infos
+ * to be retrieved. On output, contains the actual
+ * number of infos that have been copied.
+ * @param info Array of info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_ports_info(pjmedia_conf *conf,
+ unsigned *size,
+ pjmedia_conf_port_info info[]
+ );
+
+
+/**
+ * Get last signal level transmitted to or received from the specified port.
+ * This will retrieve the "real-time" signal level of the audio as they are
+ * transmitted or received by the specified port. Application may call this
+ * function periodically to display the signal level to a VU meter.
+ *
+ * The signal level is an integer value in zero to 255, with zero indicates
+ * no signal, and 255 indicates the loudest signal level.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number.
+ * @param tx_level Optional argument to receive the level of signal
+ * transmitted to the specified port (i.e. the direction
+ * is from the bridge to the port).
+ * @param rx_level Optional argument to receive the level of signal
+ * received from the port (i.e. the direction is from the
+ * port to the bridge).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_get_signal_level(pjmedia_conf *conf,
+ unsigned slot,
+ unsigned *tx_level,
+ unsigned *rx_level);
+
+
+/**
+ * Adjust the level of signal received from the specified port.
+ * Application may adjust the level to make signal received from the port
+ * either louder or more quiet. The level adjustment is calculated with this
+ * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using
+ * this, zero indicates no adjustment, the value -128 will mute the signal,
+ * and the value of +128 will make the signal 100% louder, +256 will make it
+ * 200% louder, etc.
+ *
+ * The level adjustment value will stay with the port until the port is
+ * removed from the bridge or new adjustment value is set. The current
+ * level adjustment value is reported in the media port info when
+ * the #pjmedia_conf_get_port_info() function is called.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number of the port.
+ * @param adj_level Adjustment level, which must be greater than or equal
+ * to -128. A value of zero means there is no level
+ * adjustment to be made, the value -128 will mute the
+ * signal, and the value of +128 will make the signal
+ * 100% louder, +256 will make it 200% louder, etc.
+ * See the function description for the formula.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_adjust_rx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level );
+
+
+/**
+ * Adjust the level of signal to be transmitted to the specified port.
+ * Application may adjust the level to make signal transmitted to the port
+ * either louder or more quiet. The level adjustment is calculated with this
+ * formula: <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using
+ * this, zero indicates no adjustment, the value -128 will mute the signal,
+ * and the value of +128 will make the signal 100% louder, +256 will make it
+ * 200% louder, etc.
+ *
+ * The level adjustment value will stay with the port until the port is
+ * removed from the bridge or new adjustment value is set. The current
+ * level adjustment value is reported in the media port info when
+ * the #pjmedia_conf_get_port_info() function is called.
+ *
+ * @param conf The conference bridge.
+ * @param slot Slot number of the port.
+ * @param adj_level Adjustment level, which must be greater than or equal
+ * to -128. A value of zero means there is no level
+ * adjustment to be made, the value -128 will mute the
+ * signal, and the value of +128 will make the signal
+ * 100% louder, +256 will make it 200% louder, etc.
+ * See the function description for the formula.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_conf_adjust_tx_level( pjmedia_conf *conf,
+ unsigned slot,
+ int adj_level );
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONF_H__ */
+
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
new file mode 100644
index 0000000..d5a598f
--- /dev/null
+++ b/pjmedia/include/pjmedia/config.h
@@ -0,0 +1,1181 @@
+/* $Id: config.h 4130 2012-05-17 08:35:51Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CONFIG_H__
+#define __PJMEDIA_CONFIG_H__
+
+/**
+ * @file pjmedia/config.h Compile time config
+ * @brief Contains some compile time constants.
+ */
+#include <pj/config.h>
+
+/**
+ * @defgroup PJMEDIA_BASE Base Types and Configurations
+ */
+
+/**
+ * @defgroup PJMEDIA_CONFIG Compile time configuration
+ * @ingroup PJMEDIA_BASE
+ * @brief Some compile time configuration settings.
+ * @{
+ */
+
+/*
+ * Include config_auto.h if autoconf is used (PJ_AUTOCONF is set)
+ */
+#if defined(PJ_AUTOCONF)
+# include <pjmedia/config_auto.h>
+#endif
+
+/**
+ * Specify whether we prefer to use audio switch board rather than
+ * conference bridge.
+ *
+ * Audio switch board is a kind of simplified version of conference
+ * bridge, but not really the subset of conference bridge. It has
+ * stricter rules on audio routing among the pjmedia ports and has
+ * no audio mixing capability. The power of it is it could work with
+ * encoded audio frames where conference brigde couldn't.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_CONF_USE_SWITCH_BOARD
+# define PJMEDIA_CONF_USE_SWITCH_BOARD 0
+#endif
+
+/*
+ * Types of sound stream backends.
+ */
+
+/**
+ * This macro has been deprecated in releasee 1.1. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.
+ */
+#if defined(PJMEDIA_SOUND_IMPLEMENTATION)
+# error PJMEDIA_SOUND_IMPLEMENTATION has been deprecated
+#endif
+
+/**
+ * This macro has been deprecated in releasee 1.1. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information.
+ */
+#if defined(PJMEDIA_PREFER_DIRECT_SOUND)
+# error PJMEDIA_PREFER_DIRECT_SOUND has been deprecated
+#endif
+
+/**
+ * This macro controls whether the legacy sound device API is to be
+ * implemented, for applications that still use the old sound device
+ * API (sound.h). If this macro is set to non-zero, the sound_legacy.c
+ * will be included in the compilation. The sound_legacy.c is an
+ * implementation of old sound device (sound.h) using the new Audio
+ * Device API.
+ *
+ * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * info.
+ */
+#ifndef PJMEDIA_HAS_LEGACY_SOUND_API
+# define PJMEDIA_HAS_LEGACY_SOUND_API 1
+#endif
+
+/**
+ * Specify default sound device latency, in milisecond.
+ */
+#ifndef PJMEDIA_SND_DEFAULT_REC_LATENCY
+# define PJMEDIA_SND_DEFAULT_REC_LATENCY 100
+#endif
+
+/**
+ * Specify default sound device latency, in milisecond.
+ *
+ * Default is 160ms for Windows Mobile and 140ms for other platforms.
+ */
+#ifndef PJMEDIA_SND_DEFAULT_PLAY_LATENCY
+# if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
+# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 160
+# else
+# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 140
+# endif
+#endif
+
+
+/*
+ * Types of WSOLA backend algorithm.
+ */
+
+/**
+ * This denotes implementation of WSOLA using null algorithm. Expansion
+ * will generate zero frames, and compression will just discard some
+ * samples from the input.
+ *
+ * This type of implementation may be used as it requires the least
+ * processing power.
+ */
+#define PJMEDIA_WSOLA_IMP_NULL 0
+
+/**
+ * This denotes implementation of WSOLA using fixed or floating point WSOLA
+ * algorithm. This implementation provides the best quality of the result,
+ * at the expense of one frame delay and intensive processing power
+ * requirement.
+ */
+#define PJMEDIA_WSOLA_IMP_WSOLA 1
+
+/**
+ * This denotes implementation of WSOLA algorithm with faster waveform
+ * similarity calculation. This implementation provides fair quality of
+ * the result with the main advantage of low processing power requirement.
+ */
+#define PJMEDIA_WSOLA_IMP_WSOLA_LITE 2
+
+/**
+ * Specify type of Waveform based Similarity Overlap and Add (WSOLA) backend
+ * implementation to be used. WSOLA is an algorithm to expand and/or compress
+ * audio frames without changing the pitch, and used by the delaybuf and as PLC
+ * backend algorithm.
+ *
+ * Default is PJMEDIA_WSOLA_IMP_WSOLA
+ */
+#ifndef PJMEDIA_WSOLA_IMP
+# define PJMEDIA_WSOLA_IMP PJMEDIA_WSOLA_IMP_WSOLA
+#endif
+
+
+/**
+ * Specify the default maximum duration of synthetic audio that is generated
+ * by WSOLA. This value should be long enough to cover burst of packet losses.
+ * but not too long, because as the duration increases the quality would
+ * degrade considerably.
+ *
+ * Note that this limit is only applied when fading is enabled in the WSOLA
+ * session.
+ *
+ * Default: 80
+ */
+#ifndef PJMEDIA_WSOLA_MAX_EXPAND_MSEC
+# define PJMEDIA_WSOLA_MAX_EXPAND_MSEC 80
+#endif
+
+
+/**
+ * Specify WSOLA template length, in milliseconds. The longer the template,
+ * the smoother signal to be generated at the expense of more computation
+ * needed, since the algorithm will have to compare more samples to find
+ * the most similar pitch.
+ *
+ * Default: 5
+ */
+#ifndef PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC
+# define PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC 5
+#endif
+
+
+/**
+ * Specify WSOLA algorithm delay, in milliseconds. The algorithm delay is
+ * used to merge synthetic samples with real samples in the transition
+ * between real to synthetic and vice versa. The longer the delay, the
+ * smoother signal to be generated, at the expense of longer latency and
+ * a slighty more computation.
+ *
+ * Default: 5
+ */
+#ifndef PJMEDIA_WSOLA_DELAY_MSEC
+# define PJMEDIA_WSOLA_DELAY_MSEC 5
+#endif
+
+
+/**
+ * Set this to non-zero to disable fade-out/in effect in the PLC when it
+ * instructs WSOLA to generate synthetic frames. The use of fading may
+ * or may not improve the quality of audio, depending on the nature of
+ * packet loss and the type of audio input (e.g. speech vs music).
+ * Disabling fading also implicitly remove the maximum limit of synthetic
+ * audio samples generated by WSOLA (see PJMEDIA_WSOLA_MAX_EXPAND_MSEC).
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_WSOLA_PLC_NO_FADING
+# define PJMEDIA_WSOLA_PLC_NO_FADING 0
+#endif
+
+
+/**
+ * Limit the number of calls by stream to the PLC to generate synthetic
+ * frames to this duration. If packets are still lost after this maximum
+ * duration, silence will be generated by the stream instead. Since the
+ * PLC normally should have its own limit on the maximum duration of
+ * synthetic frames to be generated (for PJMEDIA's PLC, the limit is
+ * PJMEDIA_WSOLA_MAX_EXPAND_MSEC), we can set this value to a large number
+ * to give additional flexibility should the PLC wants to do something
+ * clever with the lost frames.
+ *
+ * Default: 240 ms
+ */
+#ifndef PJMEDIA_MAX_PLC_DURATION_MSEC
+# define PJMEDIA_MAX_PLC_DURATION_MSEC 240
+#endif
+
+
+/**
+ * Specify number of sound buffers. Larger number is better for sound
+ * stability and to accommodate sound devices that are unable to send frames
+ * in timely manner, however it would probably cause more audio delay (and
+ * definitely will take more memory). One individual buffer is normally 10ms
+ * or 20 ms long, depending on ptime settings (samples_per_frame value).
+ *
+ * The setting here currently is used by the conference bridge, the splitter
+ * combiner port, and dsound.c.
+ *
+ * Default: (PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20
+ */
+#ifndef PJMEDIA_SOUND_BUFFER_COUNT
+# define PJMEDIA_SOUND_BUFFER_COUNT ((PJMEDIA_SND_DEFAULT_PLAY_LATENCY+20)/20)
+#endif
+
+
+/**
+ * Specify which A-law/U-law conversion algorithm to use.
+ * By default the conversion algorithm uses A-law/U-law table which gives
+ * the best performance, at the expense of 33 KBytes of static data.
+ * If this option is disabled, a smaller but slower algorithm will be used.
+ */
+#ifndef PJMEDIA_HAS_ALAW_ULAW_TABLE
+# define PJMEDIA_HAS_ALAW_ULAW_TABLE 1
+#endif
+
+
+/**
+ * Unless specified otherwise, G711 codec is included by default.
+ */
+#ifndef PJMEDIA_HAS_G711_CODEC
+# define PJMEDIA_HAS_G711_CODEC 1
+#endif
+
+
+/*
+ * Warn about obsolete macros.
+ *
+ * PJMEDIA_HAS_SMALL_FILTER has been deprecated in 0.7.
+ */
+#if defined(PJMEDIA_HAS_SMALL_FILTER)
+# ifdef _MSC_VER
+# pragma message("Warning: PJMEDIA_HAS_SMALL_FILTER macro is deprecated"\
+ " and has no effect")
+# else
+# warning "PJMEDIA_HAS_SMALL_FILTER macro is deprecated and has no effect"
+# endif
+#endif
+
+
+/*
+ * Warn about obsolete macros.
+ *
+ * PJMEDIA_HAS_LARGE_FILTER has been deprecated in 0.7.
+ */
+#if defined(PJMEDIA_HAS_LARGE_FILTER)
+# ifdef _MSC_VER
+# pragma message("Warning: PJMEDIA_HAS_LARGE_FILTER macro is deprecated"\
+ " and has no effect")
+# else
+# warning "PJMEDIA_HAS_LARGE_FILTER macro is deprecated"
+# endif
+#endif
+
+
+/*
+ * These macros are obsolete in 0.7.1 so it will trigger compilation error.
+ * Please use PJMEDIA_RESAMPLE_IMP to select the resample implementation
+ * to use.
+ */
+#ifdef PJMEDIA_HAS_LIBRESAMPLE
+# error "PJMEDIA_HAS_LIBRESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE'"
+#endif
+
+#ifdef PJMEDIA_HAS_SPEEX_RESAMPLE
+# error "PJMEDIA_HAS_SPEEX_RESAMPLE macro is deprecated. Use '#define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_SPEEX'"
+#endif
+
+
+/*
+ * Sample rate conversion backends.
+ * Select one of these backends in PJMEDIA_RESAMPLE_IMP.
+ */
+#define PJMEDIA_RESAMPLE_NONE 1 /**< No resampling. */
+#define PJMEDIA_RESAMPLE_LIBRESAMPLE 2 /**< Sample rate conversion
+ using libresample. */
+#define PJMEDIA_RESAMPLE_SPEEX 3 /**< Sample rate conversion
+ using Speex. */
+#define PJMEDIA_RESAMPLE_LIBSAMPLERATE 4 /**< Sample rate conversion
+ using libsamplerate
+ (a.k.a Secret Rabbit Code)
+ */
+
+/**
+ * Select which resample implementation to use. Currently pjmedia supports:
+ * - #PJMEDIA_RESAMPLE_LIBRESAMPLE, to use libresample-1.7, this is the default
+ * implementation to be used.
+ * - #PJMEDIA_RESAMPLE_LIBSAMPLERATE, to use libsamplerate implementation
+ * (a.k.a. Secret Rabbit Code).
+ * - #PJMEDIA_RESAMPLE_SPEEX, to use experimental sample rate conversion in
+ * Speex library.
+ * - #PJMEDIA_RESAMPLE_NONE, to disable sample rate conversion. Any calls to
+ * resample function will return error.
+ *
+ * Default is PJMEDIA_RESAMPLE_LIBRESAMPLE
+ */
+#ifndef PJMEDIA_RESAMPLE_IMP
+# define PJMEDIA_RESAMPLE_IMP PJMEDIA_RESAMPLE_LIBRESAMPLE
+#endif
+
+
+/**
+ * Specify whether libsamplerate, when used, should be linked statically
+ * into the application. This option is only useful for Visual Studio
+ * projects, and when this static linking is enabled
+ */
+
+
+/**
+ * Default file player/writer buffer size.
+ */
+#ifndef PJMEDIA_FILE_PORT_BUFSIZE
+# define PJMEDIA_FILE_PORT_BUFSIZE 4000
+#endif
+
+
+/**
+ * Maximum frame duration (in msec) to be supported.
+ * This (among other thing) will affect the size of buffers to be allocated
+ * for outgoing packets.
+ */
+#ifndef PJMEDIA_MAX_FRAME_DURATION_MS
+# define PJMEDIA_MAX_FRAME_DURATION_MS 200
+#endif
+
+
+/**
+ * Max packet size to support.
+ */
+#ifndef PJMEDIA_MAX_MTU
+# define PJMEDIA_MAX_MTU 1500
+#endif
+
+
+/**
+ * DTMF/telephone-event duration, in timestamp.
+ */
+#ifndef PJMEDIA_DTMF_DURATION
+# define PJMEDIA_DTMF_DURATION 1600 /* in timestamp */
+#endif
+
+
+/**
+ * Number of RTP packets received from different source IP address from the
+ * remote address required to make the stream switch transmission
+ * to the source address.
+ */
+#ifndef PJMEDIA_RTP_NAT_PROBATION_CNT
+# define PJMEDIA_RTP_NAT_PROBATION_CNT 10
+#endif
+
+
+/**
+ * Number of RTCP packets received from different source IP address from the
+ * remote address required to make the stream switch RTCP transmission
+ * to the source address.
+ */
+#ifndef PJMEDIA_RTCP_NAT_PROBATION_CNT
+# define PJMEDIA_RTCP_NAT_PROBATION_CNT 3
+#endif
+
+
+/**
+ * Specify whether RTCP should be advertised in SDP. This setting would
+ * affect whether RTCP candidate will be added in SDP when ICE is used.
+ * Application might want to disable RTCP advertisement in SDP to
+ * reduce the message size.
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_ADVERTISE_RTCP
+# define PJMEDIA_ADVERTISE_RTCP 1
+#endif
+
+
+/**
+ * Interval to send RTCP packets, in msec
+ */
+#ifndef PJMEDIA_RTCP_INTERVAL
+# define PJMEDIA_RTCP_INTERVAL 5000 /* msec*/
+#endif
+
+
+/**
+ * Tell RTCP to ignore the first N packets when calculating the
+ * jitter statistics. From experimentation, the first few packets
+ * (25 or so) have relatively big jitter, possibly because during
+ * this time, the program is also busy setting up the signaling,
+ * so they make the average jitter big.
+ *
+ * Default: 25.
+ */
+#ifndef PJMEDIA_RTCP_IGNORE_FIRST_PACKETS
+# define PJMEDIA_RTCP_IGNORE_FIRST_PACKETS 25
+#endif
+
+
+/**
+ * Specify whether RTCP statistics includes raw jitter statistics.
+ * Raw jitter is defined as absolute value of network transit time
+ * difference of two consecutive packets; refering to "difference D"
+ * term in interarrival jitter calculation in RFC 3550 section 6.4.1.
+ *
+ * Default: 0 (no).
+ */
+#ifndef PJMEDIA_RTCP_STAT_HAS_RAW_JITTER
+# define PJMEDIA_RTCP_STAT_HAS_RAW_JITTER 0
+#endif
+
+/**
+ * Specify the factor with wich RTCP RTT statistics should be normalized
+ * if exceptionally high. For e.g. mobile networks with potentially large
+ * fluctuations, this might be unwanted.
+ *
+ * Use (0) to disable this feature.
+ *
+ * Default: 3.
+ */
+#ifndef PJMEDIA_RTCP_NORMALIZE_FACTOR
+# define PJMEDIA_RTCP_NORMALIZE_FACTOR 3
+#endif
+
+
+/**
+ * Specify whether RTCP statistics includes IP Delay Variation statistics.
+ * IPDV is defined as network transit time difference of two consecutive
+ * packets. The IPDV statistic can be useful to inspect clock skew existance
+ * and level, e.g: when the IPDV mean values were stable in positive numbers,
+ * then the remote clock (used in sending RTP packets) is faster than local
+ * system clock. Ideally, the IPDV mean values are always equal to 0.
+ *
+ * Default: 0 (no).
+ */
+#ifndef PJMEDIA_RTCP_STAT_HAS_IPDV
+# define PJMEDIA_RTCP_STAT_HAS_IPDV 0
+#endif
+
+
+/**
+ * Specify whether RTCP XR support should be built into PJMEDIA. Disabling
+ * this feature will reduce footprint slightly. Note that even when this
+ * setting is enabled, RTCP XR processing will only be performed in stream
+ * if it is enabled on run-time on per stream basis. See
+ * PJMEDIA_STREAM_ENABLE_XR setting for more info.
+ *
+ * Default: 0 (no).
+ */
+#ifndef PJMEDIA_HAS_RTCP_XR
+# define PJMEDIA_HAS_RTCP_XR 0
+#endif
+
+
+/**
+ * The RTCP XR feature is activated and used by stream if \a enable_rtcp_xr
+ * field of \a pjmedia_stream_info structure is non-zero. This setting
+ * controls the default value of this field.
+ *
+ * Default: 0 (disabled)
+ */
+#ifndef PJMEDIA_STREAM_ENABLE_XR
+# define PJMEDIA_STREAM_ENABLE_XR 0
+#endif
+
+
+/**
+ * Specify the buffer length for storing any received RTCP SDES text
+ * in a stream session. Usually RTCP contains only the mandatory SDES
+ * field, i.e: CNAME.
+ *
+ * Default: 64 bytes.
+ */
+#ifndef PJMEDIA_RTCP_RX_SDES_BUF_LEN
+# define PJMEDIA_RTCP_RX_SDES_BUF_LEN 64
+#endif
+
+
+/**
+ * Specify how long (in miliseconds) the stream should suspend the
+ * silence detector/voice activity detector (VAD) during the initial
+ * period of the session. This feature is useful to open bindings in
+ * all NAT routers between local and remote endpoint since most NATs
+ * do not allow incoming packet to get in before local endpoint sends
+ * outgoing packets.
+ *
+ * Specify zero to disable this feature.
+ *
+ * Default: 600 msec (which gives good probability that some RTP
+ * packets will reach the destination, but without
+ * filling up the jitter buffer on the remote end).
+ */
+#ifndef PJMEDIA_STREAM_VAD_SUSPEND_MSEC
+# define PJMEDIA_STREAM_VAD_SUSPEND_MSEC 600
+#endif
+
+/**
+ * Perform RTP payload type checking in the stream. Normally the peer
+ * MUST send RTP with payload type as we specified in our SDP. Certain
+ * agents may not be able to follow this hence the only way to have
+ * communication is to disable this check.
+ *
+ * Default: 1
+ */
+#ifndef PJMEDIA_STREAM_CHECK_RTP_PT
+# define PJMEDIA_STREAM_CHECK_RTP_PT 1
+#endif
+
+/**
+ * Reserve some space for application extra data, e.g: SRTP auth tag,
+ * in RTP payload, so the total payload length will not exceed the MTU.
+ */
+#ifndef PJMEDIA_STREAM_RESV_PAYLOAD_LEN
+# define PJMEDIA_STREAM_RESV_PAYLOAD_LEN 20
+#endif
+
+
+/**
+ * Specify the maximum duration of silence period in the codec, in msec.
+ * This is useful for example to keep NAT binding open in the firewall
+ * and to prevent server from disconnecting the call because no
+ * RTP packet is received.
+ *
+ * This only applies to codecs that use PJMEDIA's VAD (pretty much
+ * everything including iLBC, except Speex, which has its own DTX
+ * mechanism).
+ *
+ * Use (-1) to disable this feature.
+ *
+ * Default: 5000 ms
+ *
+ */
+#ifndef PJMEDIA_CODEC_MAX_SILENCE_PERIOD
+# define PJMEDIA_CODEC_MAX_SILENCE_PERIOD 5000
+#endif
+
+
+/**
+ * Suggested or default threshold to be set for fixed silence detection
+ * or as starting threshold for adaptive silence detection. The threshold
+ * has the range from zero to 0xFFFF.
+ */
+#ifndef PJMEDIA_SILENCE_DET_THRESHOLD
+# define PJMEDIA_SILENCE_DET_THRESHOLD 4
+#endif
+
+
+/**
+ * Maximum silence threshold in the silence detector. The silence detector
+ * will not cut the audio transmission if the audio level is above this
+ * level.
+ *
+ * Use 0x10000 (or greater) to disable this feature.
+ *
+ * Default: 0x10000 (disabled)
+ */
+#ifndef PJMEDIA_SILENCE_DET_MAX_THRESHOLD
+# define PJMEDIA_SILENCE_DET_MAX_THRESHOLD 0x10000
+#endif
+
+
+/**
+ * Speex Accoustic Echo Cancellation (AEC).
+ * By default is enabled.
+ */
+#ifndef PJMEDIA_HAS_SPEEX_AEC
+# define PJMEDIA_HAS_SPEEX_AEC 1
+#endif
+
+
+/**
+ * Maximum number of parameters in SDP fmtp attribute.
+ *
+ * Default: 16
+ */
+#ifndef PJMEDIA_CODEC_MAX_FMTP_CNT
+# define PJMEDIA_CODEC_MAX_FMTP_CNT 16
+#endif
+
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * If set to non-zero, the negotiator will use the codec order as specified
+ * by remote in the offer.
+ *
+ * Note that this behavior can be changed during run-time by calling
+ * pjmedia_sdp_neg_set_prefer_remote_codec_order().
+ *
+ * Default is 1 (to maintain backward compatibility)
+ */
+#ifndef PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER
+# define PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER 1
+#endif
+
+
+/**
+ * This specifies the maximum number of the customized SDP format
+ * negotiation callbacks.
+ */
+#ifndef PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB
+# define PJMEDIA_SDP_NEG_MAX_CUSTOM_FMT_NEG_CB 8
+#endif
+
+
+/**
+ * This specifies if the SDP negotiator should rewrite answer payload
+ * type numbers to use the same payload type numbers as the remote offer
+ * for all matched codecs.
+ *
+ * Default is 1 (yes)
+ */
+#ifndef PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT
+# define PJMEDIA_SDP_NEG_ANSWER_SYMMETRIC_PT 1
+#endif
+
+
+/**
+ * Support for sending and decoding RTCP port in SDP (RFC 3605).
+ * Default is equal to PJMEDIA_ADVERTISE_RTCP setting.
+ */
+#ifndef PJMEDIA_HAS_RTCP_IN_SDP
+# define PJMEDIA_HAS_RTCP_IN_SDP (PJMEDIA_ADVERTISE_RTCP)
+#endif
+
+
+/**
+ * This macro controls whether pjmedia should include SDP rtpmap
+ * attribute for static payload types. SDP rtpmap for static
+ * payload types are optional, although they are normally included
+ * for interoperability reason.
+ *
+ * Note that there is also a run-time variable to turn this setting
+ * on or off, defined in endpoint.c. To access this variable, use
+ * the following construct
+ *
+ \verbatim
+ extern pj_bool_t pjmedia_add_rtpmap_for_static_pt;
+
+ // Do not include rtpmap for static payload types (<96)
+ pjmedia_add_rtpmap_for_static_pt = PJ_FALSE;
+ \endverbatim
+ *
+ * Default: 1 (yes)
+ */
+#ifndef PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT
+# define PJMEDIA_ADD_RTPMAP_FOR_STATIC_PT 1
+#endif
+
+
+/**
+ * This macro declares the payload type for telephone-event
+ * that is advertised by PJMEDIA for outgoing SDP. If this macro
+ * is set to zero, telephone events would not be advertised nor
+ * supported.
+ *
+ * If this value is changed to other number, please update the
+ * PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR too.
+ */
+#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS
+# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS 96
+#endif
+
+
+/**
+ * Macro to get the string representation of the telephone-event
+ * payload type.
+ */
+#ifndef PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR
+# define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR "96"
+#endif
+
+
+/**
+ * Maximum tones/digits that can be enqueued in the tone generator.
+ */
+#ifndef PJMEDIA_TONEGEN_MAX_DIGITS
+# define PJMEDIA_TONEGEN_MAX_DIGITS 32
+#endif
+
+
+/*
+ * Below specifies the various tone generator backend algorithm.
+ */
+
+/**
+ * The math's sine(), floating point. This has very good precision
+ * but it's the slowest and requires floating point support and
+ * linking with the math library.
+ */
+#define PJMEDIA_TONEGEN_SINE 1
+
+/**
+ * Floating point approximation of sine(). This has relatively good
+ * precision and much faster than plain sine(), but it requires floating-
+ * point support and linking with the math library.
+ */
+#define PJMEDIA_TONEGEN_FLOATING_POINT 2
+
+/**
+ * Fixed point using sine signal generated by Cordic algorithm. This
+ * algorithm can be tuned to provide balance between precision and
+ * performance by tuning the PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP
+ * setting, and may be suitable for platforms that lack floating-point
+ * support.
+ */
+#define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC 3
+
+/**
+ * Fast fixed point using some approximation to generate sine waves.
+ * The tone generated by this algorithm is not very precise, however
+ * the algorithm is very fast.
+ */
+#define PJMEDIA_TONEGEN_FAST_FIXED_POINT 4
+
+
+/**
+ * Specify the tone generator algorithm to be used. Please see
+ * http://trac.pjsip.org/repos/wiki/Tone_Generator for the performance
+ * analysis results of the various tone generator algorithms.
+ *
+ * Default value:
+ * - PJMEDIA_TONEGEN_FLOATING_POINT when PJ_HAS_FLOATING_POINT is set
+ * - PJMEDIA_TONEGEN_FIXED_POINT_CORDIC when PJ_HAS_FLOATING_POINT is not set
+ */
+#ifndef PJMEDIA_TONEGEN_ALG
+# if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT
+# define PJMEDIA_TONEGEN_ALG PJMEDIA_TONEGEN_FLOATING_POINT
+# else
+# define PJMEDIA_TONEGEN_ALG PJMEDIA_TONEGEN_FIXED_POINT_CORDIC
+# endif
+#endif
+
+
+/**
+ * Specify the number of calculation loops to generate the tone, when
+ * PJMEDIA_TONEGEN_FIXED_POINT_CORDIC algorithm is used. With more calculation
+ * loops, the tone signal gets more precise, but this will add more
+ * processing.
+ *
+ * Valid values are 1 to 28.
+ *
+ * Default value: 10
+ */
+#ifndef PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP
+# define PJMEDIA_TONEGEN_FIXED_POINT_CORDIC_LOOP 10
+#endif
+
+
+/**
+ * Enable high quality of tone generation, the better quality will cost
+ * more CPU load. This is only applied to floating point enabled machines.
+ *
+ * By default it is enabled when PJ_HAS_FLOATING_POINT is set.
+ *
+ * This macro has been deprecated in version 1.0-rc3.
+ */
+#ifdef PJMEDIA_USE_HIGH_QUALITY_TONEGEN
+# error "The PJMEDIA_USE_HIGH_QUALITY_TONEGEN macro is obsolete"
+#endif
+
+
+/**
+ * Fade-in duration for the tone, in milliseconds. Set to zero to disable
+ * this feature.
+ *
+ * Default: 1 (msec)
+ */
+#ifndef PJMEDIA_TONEGEN_FADE_IN_TIME
+# define PJMEDIA_TONEGEN_FADE_IN_TIME 1
+#endif
+
+
+/**
+ * Fade-out duration for the tone, in milliseconds. Set to zero to disable
+ * this feature.
+ *
+ * Default: 2 (msec)
+ */
+#ifndef PJMEDIA_TONEGEN_FADE_OUT_TIME
+# define PJMEDIA_TONEGEN_FADE_OUT_TIME 2
+#endif
+
+
+/**
+ * The default tone generator amplitude (1-32767).
+ *
+ * Default value: 12288
+ */
+#ifndef PJMEDIA_TONEGEN_VOLUME
+# define PJMEDIA_TONEGEN_VOLUME 12288
+#endif
+
+
+/**
+ * Enable support for SRTP media transport. This will require linking
+ * with libsrtp from the third_party directory.
+ *
+ * By default it is enabled.
+ */
+#ifndef PJMEDIA_HAS_SRTP
+# define PJMEDIA_HAS_SRTP 1
+#endif
+
+
+/**
+ * Enable support to handle codecs with inconsistent clock rate
+ * between clock rate in SDP/RTP & the clock rate that is actually used.
+ * This happens for example with G.722 and MPEG audio codecs.
+ * See:
+ * - G.722 : RFC 3551 4.5.2
+ * - MPEG audio : RFC 3551 4.5.13 & RFC 3119
+ *
+ * Also when this feature is enabled, some handling will be performed
+ * to deal with clock rate incompatibilities of some phones.
+ *
+ * By default it is enabled.
+ */
+#ifndef PJMEDIA_HANDLE_G722_MPEG_BUG
+# define PJMEDIA_HANDLE_G722_MPEG_BUG 1
+#endif
+
+
+/**
+ * Transport info (pjmedia_transport_info) contains a socket info and list
+ * of transport specific info, since transports can be chained together
+ * (for example, SRTP transport uses UDP transport as the underlying
+ * transport). This constant specifies maximum number of transport specific
+ * infos that can be held in a transport info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT 4
+#endif
+
+
+/**
+ * Maximum size in bytes of storage buffer of a transport specific info.
+ */
+#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE (36*sizeof(long))
+#endif
+
+
+/**
+ * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.
+ * This indicates that an empty RTP packet should be used as
+ * the keep-alive packet.
+ */
+#define PJMEDIA_STREAM_KA_EMPTY_RTP 1
+
+/**
+ * Value to be specified in PJMEDIA_STREAM_ENABLE_KA setting.
+ * This indicates that a user defined packet should be used
+ * as the keep-alive packet. The content of the user-defined
+ * packet is specified by PJMEDIA_STREAM_KA_USER_PKT. Default
+ * content is a CR-LF packet.
+ */
+#define PJMEDIA_STREAM_KA_USER 2
+
+/**
+ * The content of the user defined keep-alive packet. The format
+ * of the packet is initializer to pj_str_t structure. Note that
+ * the content may contain NULL character.
+ */
+#ifndef PJMEDIA_STREAM_KA_USER_PKT
+# define PJMEDIA_STREAM_KA_USER_PKT { "\r\n", 2 }
+#endif
+
+/**
+ * Specify another type of keep-alive and NAT hole punching
+ * mechanism (the other type is PJMEDIA_STREAM_VAD_SUSPEND_MSEC
+ * and PJMEDIA_CODEC_MAX_SILENCE_PERIOD) to be used by stream.
+ * When this feature is enabled, the stream will initially
+ * transmit one packet to punch a hole in NAT, and periodically
+ * transmit keep-alive packets.
+ *
+ * When this alternative keep-alive mechanism is used, application
+ * may disable the other keep-alive mechanisms, i.e: by setting
+ * PJMEDIA_STREAM_VAD_SUSPEND_MSEC to zero and
+ * PJMEDIA_CODEC_MAX_SILENCE_PERIOD to -1.
+ *
+ * The value of this macro specifies the type of packet used
+ * for the keep-alive mechanism. Valid values are
+ * PJMEDIA_STREAM_KA_EMPTY_RTP and PJMEDIA_STREAM_KA_USER.
+ *
+ * The duration of the keep-alive interval further can be set
+ * with PJMEDIA_STREAM_KA_INTERVAL setting.
+ *
+ * Default: 0 (disabled)
+ */
+#ifndef PJMEDIA_STREAM_ENABLE_KA
+# define PJMEDIA_STREAM_ENABLE_KA 0
+#endif
+
+
+/**
+ * Specify the keep-alive interval of PJMEDIA_STREAM_ENABLE_KA
+ * mechanism, in seconds.
+ *
+ * Default: 5 seconds
+ */
+#ifndef PJMEDIA_STREAM_KA_INTERVAL
+# define PJMEDIA_STREAM_KA_INTERVAL 5
+#endif
+
+
+/*
+ * .... new stuffs ...
+ */
+
+/*
+ * Video
+ */
+
+/**
+ * Top level option to enable/disable video features.
+ *
+ * Default: 0 (disabled)
+ */
+#ifndef PJMEDIA_HAS_VIDEO
+# define PJMEDIA_HAS_VIDEO 0
+#endif
+
+
+/**
+ * Specify if FFMPEG is available. The value here will be used as the default
+ * value for other FFMPEG settings below.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_HAS_FFMPEG
+# define PJMEDIA_HAS_FFMPEG 0
+#endif
+
+/**
+ * Specify if FFMPEG libavformat is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVFORMAT
+# define PJMEDIA_HAS_LIBAVFORMAT PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavformat is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVCODEC
+# define PJMEDIA_HAS_LIBAVCODEC PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavutil is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVUTIL
+# define PJMEDIA_HAS_LIBAVUTIL PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libswscale is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBSWSCALE
+# define PJMEDIA_HAS_LIBSWSCALE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavdevice is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVDEVICE
+# define PJMEDIA_HAS_LIBAVDEVICE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Specify if FFMPEG libavcore is available.
+ *
+ * Default: PJMEDIA_HAS_FFMPEG (or detected by configure)
+ */
+#ifndef PJMEDIA_HAS_LIBAVCORE
+# define PJMEDIA_HAS_LIBAVCORE PJMEDIA_HAS_FFMPEG
+#endif
+
+/**
+ * Maximum video planes.
+ *
+ * Default: 4
+ */
+#ifndef PJMEDIA_MAX_VIDEO_PLANES
+# define PJMEDIA_MAX_VIDEO_PLANES 4
+#endif
+
+/**
+ * Maximum number of video formats.
+ *
+ * Default: 32
+ */
+#ifndef PJMEDIA_MAX_VIDEO_FORMATS
+# define PJMEDIA_MAX_VIDEO_FORMATS 32
+#endif
+
+/**
+ * Specify the maximum time difference (in ms) for synchronization between
+ * two medias. If the synchronization media source is ahead of time
+ * greater than this duration, it is considered to make a very large jump
+ * and the synchronization will be reset.
+ *
+ * Default: 20000
+ */
+#ifndef PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC
+# define PJMEDIA_CLOCK_SYNC_MAX_SYNC_MSEC 20000
+#endif
+
+/**
+ * Maximum video frame size.
+ * Default: 128kB
+ */
+#ifndef PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE
+# define PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE (1<<17)
+#endif
+
+
+/**
+ * Specify the maximum duration (in ms) for resynchronization. When a media
+ * is late to another media it is supposed to be synchronized to, it is
+ * guaranteed to be synchronized again after this duration. While if the
+ * media is ahead/early by t ms, it is guaranteed to be synchronized after
+ * t + this duration. This timing only applies if there is no additional
+ * resynchronization required during the specified duration.
+ *
+ * Default: 2000
+ */
+#ifndef PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION
+# define PJMEDIA_CLOCK_SYNC_MAX_RESYNC_DURATION 2000
+#endif
+
+
+/**
+ * Minimum gap between two consecutive discards in jitter buffer,
+ * in milliseconds.
+ *
+ * Default: 200 ms
+ */
+#ifndef PJMEDIA_JBUF_DISC_MIN_GAP
+# define PJMEDIA_JBUF_DISC_MIN_GAP 200
+#endif
+
+
+/**
+ * Minimum burst level reference used for calculating discard duration
+ * in jitter buffer progressive discard algorithm, in frames.
+ *
+ * Default: 1 frame
+ */
+#ifndef PJMEDIA_JBUF_PRO_DISC_MIN_BURST
+# define PJMEDIA_JBUF_PRO_DISC_MIN_BURST 1
+#endif
+
+
+/**
+ * Maximum burst level reference used for calculating discard duration
+ * in jitter buffer progressive discard algorithm, in frames.
+ *
+ * Default: 200 frames
+ */
+#ifndef PJMEDIA_JBUF_PRO_DISC_MAX_BURST
+# define PJMEDIA_JBUF_PRO_DISC_MAX_BURST 100
+#endif
+
+
+/**
+ * Duration for progressive discard algotithm in jitter buffer to discard
+ * an excessive frame when burst is equal to or lower than
+ * PJMEDIA_JBUF_PRO_DISC_MIN_BURST, in milliseconds.
+ *
+ * Default: 2000 ms
+ */
+#ifndef PJMEDIA_JBUF_PRO_DISC_T1
+# define PJMEDIA_JBUF_PRO_DISC_T1 2000
+#endif
+
+
+/**
+ * Duration for progressive discard algotithm in jitter buffer to discard
+ * an excessive frame when burst is equal to or greater than
+ * PJMEDIA_JBUF_PRO_DISC_MAX_BURST, in milliseconds.
+ *
+ * Default: 10000 ms
+ */
+#ifndef PJMEDIA_JBUF_PRO_DISC_T2
+# define PJMEDIA_JBUF_PRO_DISC_T2 10000
+#endif
+
+
+/**
+ * Video stream will discard old picture from the jitter buffer as soon as
+ * new picture is received, to reduce latency.
+ *
+ * Default: 0
+ */
+#ifndef PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY
+# define PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY 0
+#endif
+
+
+/**
+ * Maximum video payload size. Note that this must not be greater than
+ * PJMEDIA_MAX_MTU.
+ *
+ * Default: (PJMEDIA_MAX_MTU - 100)
+ */
+#ifndef PJMEDIA_MAX_VID_PAYLOAD_SIZE
+# define PJMEDIA_MAX_VID_PAYLOAD_SIZE (PJMEDIA_MAX_MTU - 100)
+#endif
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONFIG_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/config_auto.h.in b/pjmedia/include/pjmedia/config_auto.h.in
new file mode 100644
index 0000000..378ddcd
--- /dev/null
+++ b/pjmedia/include/pjmedia/config_auto.h.in
@@ -0,0 +1,43 @@
+/* $Id: config_auto.h.in 3295 2010-08-25 12:51:29Z bennylp $ */
+/*
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CONFIG_AUTO_H_
+#define __PJMEDIA_CONFIG_AUTO_H_
+
+/**
+ * @file config_auto.h
+ * @brief PJMEDIA configuration as set by autoconf script
+ */
+
+/*
+ * Note:
+ * The configuration in config_site.h overrides any other settings,
+ * including the setting as detected by autoconf.
+ */
+
+/* G711 codec */
+#ifndef PJMEDIA_HAS_G711_CODEC
+#undef PJMEDIA_HAS_G711_CODEC
+#endif
+
+
+#endif /* __PJMEDIA_CONFIG_AUTO_H_ */
+
+
+
diff --git a/pjmedia/include/pjmedia/converter.h b/pjmedia/include/pjmedia/converter.h
new file mode 100644
index 0000000..d649007
--- /dev/null
+++ b/pjmedia/include/pjmedia/converter.h
@@ -0,0 +1,322 @@
+/* $Id: converter.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_CONVERTER_H__
+#define __PJMEDIA_CONVERTER_H__
+
+
+/**
+ * @file pjmedia/converter.h Format conversion utilities
+ * @brief Format conversion utilities
+ */
+
+#include <pjmedia/frame.h>
+#include <pjmedia/format.h>
+#include <pj/list.h>
+#include <pj/pool.h>
+
+
+/**
+ * @defgroup PJMEDIA_CONVERTER Format converter
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Audio and video converter utilities
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * This describes conversion parameter. It specifies the source and
+ * destination formats of the conversion.
+ */
+typedef struct pjmedia_conversion_param
+{
+ pjmedia_format src; /**< Source format. */
+ pjmedia_format dst; /**< Destination format. */
+} pjmedia_conversion_param;
+
+
+/** Forward declaration of factory operation structure */
+typedef struct pjmedia_converter_factory_op pjmedia_converter_factory_op;
+
+/**
+ * Converter priority guides. Converter priority determines which converter
+ * instance to be used if more than one converters are able to perform the
+ * requested conversion. Converter implementor can use this value to order
+ * the preference based on attributes such as quality or performance. Higher
+ * number indicates higher priority.
+ */
+typedef enum pjmedia_converter_priority_guide
+{
+ /** Lowest priority. */
+ PJMEDIA_CONVERTER_PRIORITY_LOWEST = 0,
+
+ /** Normal priority. */
+ PJMEDIA_CONVERTER_PRIORITY_NORMAL = 15000,
+
+ /** Highest priority. */
+ PJMEDIA_CONVERTER_PRIORITY_HIGHEST = 32000
+} pjmedia_converter_priority_guide;
+
+/**
+ * Converter factory. The converter factory registers a callback function
+ * to create converters.
+ */
+typedef struct pjmedia_converter_factory
+{
+ /**
+ * Standard list members.
+ */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_converter_factory);
+
+ /**
+ * Factory name.
+ */
+ const char *name;
+
+ /**
+ * Converter priority determines which converter instance to be used if
+ * more than one converters are able to perform the requested conversion.
+ * Converter implementor can use this value to order the preference based
+ * on attributes such as quality or performance. Higher number indicates
+ * higher priority. The pjmedia_converter_priority_guide enumeration shall
+ * be used as the base value to set the priority.
+ */
+ int priority;
+
+ /**
+ * Pointer to factory operation.
+ */
+ pjmedia_converter_factory_op *op;
+
+} pjmedia_converter_factory;
+
+/** Forward declaration for converter operation. */
+typedef struct pjmedia_converter_op pjmedia_converter_op;
+
+/**
+ * This structure describes a converter instance.
+ */
+typedef struct pjmedia_converter
+{
+ /**
+ * Pointer to converter operation.
+ */
+ pjmedia_converter_op *op;
+
+} pjmedia_converter;
+
+
+/**
+ * Converter factory operation.
+ */
+struct pjmedia_converter_factory_op
+{
+ /**
+ * This function creates a converter with the specified conversion format,
+ * if such format is supported.
+ *
+ * @param cf The converter factory.
+ * @param pool Pool to allocate memory from.
+ * @param prm Conversion parameter.
+ * @param p_cv Pointer to hold the created converter instance.
+ *
+ * @return PJ_SUCCESS if converter has been created successfully.
+ */
+ pj_status_t (*create_converter)(pjmedia_converter_factory *cf,
+ pj_pool_t *pool,
+ const pjmedia_conversion_param *prm,
+ pjmedia_converter **p_cv);
+
+ /**
+ * Destroy the factory.
+ *
+ * @param cf The converter factory.
+ */
+ void (*destroy_factory)(pjmedia_converter_factory *cf);
+};
+
+/**
+ * Converter operation.
+ */
+struct pjmedia_converter_op
+{
+ /**
+ * Convert the buffer in the source frame and save the result in the
+ * buffer of the destination frame, according to conversion format that
+ * was specified when the converter was created.
+ *
+ * Note that application should use #pjmedia_converter_convert() instead
+ * of calling this function directly.
+ *
+ * @param cv The converter instance.
+ * @param src_frame The source frame.
+ * @param dst_frame The destination frame.
+ *
+ * @return PJ_SUCCESS if conversion has been performed
+ * successfully.
+ */
+ pj_status_t (*convert)(pjmedia_converter *cv,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame);
+
+ /**
+ * Destroy the converter instance.
+ *
+ * Note that application should use #pjmedia_converter_destroy() instead
+ * of calling this function directly.
+ *
+ * @param cv The converter.
+ */
+ void (*destroy)(pjmedia_converter *cv);
+
+};
+
+
+/**
+ * Opaque data type for conversion manager. Typically, the conversion manager
+ * is a singleton instance, although application may instantiate more than one
+ * instances of this if required.
+ */
+typedef struct pjmedia_converter_mgr pjmedia_converter_mgr;
+
+
+/**
+ * Create a new conversion manager instance. This will also set the pointer
+ * to the singleton instance if the value is still NULL.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param mgr Pointer to hold the created instance of the
+ * conversion manager.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_mgr_create(pj_pool_t *pool,
+ pjmedia_converter_mgr **mgr);
+
+/**
+ * Get the singleton instance of the conversion manager.
+ *
+ * @return The instance.
+ */
+PJ_DECL(pjmedia_converter_mgr*) pjmedia_converter_mgr_instance(void);
+
+/**
+ * Manually assign a specific video manager instance as the singleton
+ * instance. Normally this is not needed if only one instance is ever
+ * going to be created, as the library automatically assign the singleton
+ * instance.
+ *
+ * @param mgr The instance to be used as the singleton instance.
+ * Application may specify NULL to clear the singleton
+ * singleton instance.
+ */
+PJ_DECL(void) pjmedia_converter_mgr_set_instance(pjmedia_converter_mgr *mgr);
+
+/**
+ * Destroy a converter manager. If the manager happens to be the singleton
+ * instance, the singleton instance will be set to NULL.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ */
+PJ_DECL(void) pjmedia_converter_mgr_destroy(pjmedia_converter_mgr *mgr);
+
+/**
+ * Register a converter factory to the converter manager.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param f The converter factory to be registered.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_converter_mgr_register_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *f);
+
+/**
+ * Unregister a previously registered converter factory from the converter
+ * manager.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param f The converter factory to be unregistered.
+ * @param call_destroy If this is set to non-zero, the \a destroy_factory()
+ * callback of the factory will be called while
+ * unregistering the factory from the manager.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_converter_mgr_unregister_factory(pjmedia_converter_mgr *mgr,
+ pjmedia_converter_factory *f,
+ pj_bool_t call_destroy);
+
+/**
+ * Create a converter instance to perform the specified format conversion
+ * as specified in \a param.
+ *
+ * @param mgr The converter manager. Specify NULL to use
+ * the singleton instance.
+ * @param pool Pool to allocate the memory from.
+ * @param param Conversion parameter.
+ * @param p_cv Pointer to hold the created converter.
+ *
+ * @return PJ_SUCCESS if a converter has been created successfully
+ * or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_create(pjmedia_converter_mgr *mgr,
+ pj_pool_t *pool,
+ pjmedia_conversion_param *param,
+ pjmedia_converter **p_cv);
+
+/**
+ * Convert the buffer in the source frame and save the result in the
+ * buffer of the destination frame, according to conversion format that
+ * was specified when the converter was created.
+ *
+ * @param cv The converter instance.
+ * @param src_frame The source frame.
+ * @param dst_frame The destination frame.
+ *
+ * @return PJ_SUCCESS if conversion has been performed
+ * successfully.
+ */
+PJ_DECL(pj_status_t) pjmedia_converter_convert(pjmedia_converter *cv,
+ pjmedia_frame *src_frame,
+ pjmedia_frame *dst_frame);
+
+/**
+ * Destroy the converter.
+ *
+ * @param cv The converter instance.
+ */
+PJ_DECL(void) pjmedia_converter_destroy(pjmedia_converter *cv);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_CONVERTER_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/delaybuf.h b/pjmedia/include/pjmedia/delaybuf.h
new file mode 100644
index 0000000..4617c4d
--- /dev/null
+++ b/pjmedia/include/pjmedia/delaybuf.h
@@ -0,0 +1,176 @@
+/* $Id: delaybuf.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJMEDIA_DELAYBUF_H__
+#define __PJMEDIA_DELAYBUF_H__
+
+
+/**
+ * @file delaybuf.h
+ * @brief Delay Buffer.
+ */
+
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_DELAYBUF Adaptive Delay Buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive delay buffer with high-quality time-scale
+ * modification
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of delay buffer.
+ * Delay buffer works quite similarly like a fixed jitter buffer, that
+ * is it will delay the frame retrieval by some interval so that caller
+ * will get continuous frame from the buffer. This can be useful when
+ * the put() and get() operations are not evenly interleaved, for example
+ * when caller performs burst of put() operations and then followed by
+ * burst of get() operations. With using this delay buffer, the buffer
+ * will put the burst frames into a buffer so that get() operations
+ * will always get a frame from the buffer (assuming that the number of
+ * get() and put() are matched).
+ *
+ * The buffer is adaptive, that is it continuously learns the optimal delay
+ * to be applied to the audio flow at run-time. Once the optimal delay has
+ * been learned, the delay buffer will apply this delay to the audio flow,
+ * expanding or shrinking the audio samples as necessary when the actual
+ * audio samples in the buffer are too low or too high. It does this without
+ * distorting the audio quality of the audio, by using \a PJMED_WSOLA.
+ *
+ * The delay buffer is used in \ref PJMED_SND_PORT, \ref PJMEDIA_SPLITCOMB,
+ * and \ref PJMEDIA_CONF.
+ */
+
+PJ_BEGIN_DECL
+
+/** Opaque declaration for delay buffer. */
+typedef struct pjmedia_delay_buf pjmedia_delay_buf;
+
+/**
+ * Delay buffer options.
+ */
+typedef enum pjmedia_delay_buf_flag
+{
+ /**
+ * Use simple FIFO mechanism for the delay buffer, i.e.
+ * without WSOLA for expanding and shrinking audio samples.
+ */
+ PJMEDIA_DELAY_BUF_SIMPLE_FIFO = 1
+
+} pjmedia_delay_buf_flag;
+
+/**
+ * Create the delay buffer. Once the delay buffer is created, it will
+ * enter learning state unless the delay argument is specified, which
+ * in this case it will directly enter the running state.
+ *
+ * @param pool Pool where the delay buffer will be allocated
+ * from.
+ * @param name Optional name for the buffer for log
+ * identification.
+ * @param clock_rate Number of samples processed per second.
+ * @param samples_per_frame Number of samples per frame.
+ * @param channel_count Number of channel per frame.
+ * @param max_delay Maximum number of delay to be accommodated,
+ * in ms, if this value is negative or less than
+ * one frame time, default maximum delay used is
+ * 400 ms.
+ * @param options Options. If PJMEDIA_DELAY_BUF_SIMPLE_FIFO is
+ * specified, then a simple FIFO mechanism
+ * will be used instead of the adaptive
+ * implementation (which uses WSOLA to expand
+ * or shrink audio samples).
+ * See #pjmedia_delay_buf_flag for other options.
+ * @param p_b Pointer to receive the delay buffer instance.
+ *
+ * @return PJ_SUCCESS if the delay buffer has been
+ * created successfully, otherwise the appropriate
+ * error will be returned.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_create(pj_pool_t *pool,
+ const char *name,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned channel_count,
+ unsigned max_delay,
+ unsigned options,
+ pjmedia_delay_buf **p_b);
+
+/**
+ * Put one frame into the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Frame to be put into the buffer. This frame
+ * must have samples_per_frame length.
+ *
+ * @return PJ_SUCCESS if frames can be put successfully.
+ * PJ_EPENDING if the buffer is still at learning
+ * state. PJ_ETOOMANY if the number of frames
+ * will exceed maximum delay level, which in this
+ * case the new frame will overwrite the oldest
+ * frame in the buffer.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Get one frame from the buffer.
+ *
+ * @param b The delay buffer.
+ * @param frame Buffer to receive the frame from the delay
+ * buffer.
+ *
+ * @return PJ_SUCCESS if frame has been copied successfully.
+ * PJ_EPENDING if no frame is available, either
+ * because the buffer is still at learning state or
+ * no buffer is available during running state.
+ * On non-successful return, the frame will be
+ * filled with zeroes.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_get(pjmedia_delay_buf *b,
+ pj_int16_t frame[]);
+
+/**
+ * Reset delay buffer. This will clear the buffer's content. But keep
+ * the learning result.
+ *
+ * @param b The delay buffer.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b);
+
+/**
+ * Destroy delay buffer.
+ *
+ * @param b Delay buffer session.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_DELAYBUF_H__ */
diff --git a/pjmedia/include/pjmedia/doxygen.h b/pjmedia/include/pjmedia/doxygen.h
new file mode 100644
index 0000000..bf93ca2
--- /dev/null
+++ b/pjmedia/include/pjmedia/doxygen.h
@@ -0,0 +1,244 @@
+/* $Id: doxygen.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_DOXYGEN_H__
+#define __PJMEDIA_DOXYGEN_H__
+
+/**
+ * @file doxygen.h
+ * @brief Doxygen's mainpage.
+ */
+
+
+/*////////////////////////////////////////////////////////////////////////// */
+/*
+ INTRODUCTION PAGE
+ */
+
+/**
+ * @mainpage PJMEDIA
+ *
+ * \n
+ * @section intro2 Introduction to PJMEDIA
+ *
+ * PJMEDIA is a fully featured media stack, distributed under Open Source/GPL
+ * terms, and featuring small footprint and good extensibility and excellent
+ * portability. Here are some brief overview of PJMEDIA benefits.
+ *
+ * @subsection benefit Benefits
+ * @subsubsection full_feature Many Features
+ * PJMEDIA has many features, and rather than to list them all here, please
+ * see the <A HREF="modules.htm"><b>Modules</b></A> page for more info.
+ *
+ * Video is planned to arrive at version 2.
+ *
+ * @subsubsection portable Excellent Portability
+ * It's been ported to all desktop systems and many mobile platforms including
+ * Symbian, Windows Mobile, iPhone, and Android. Thanks to its zero thread
+ * design, users have been able to run PJMEDIA on deeply embedded platforms,
+ * even without operating systems (those typically found in DSP platforms).
+ * Except the echo suppressor, all other PJMEDIA components have fixed point
+ * implementation, which makes it ideal for embedded systems which lack FPU.
+ * PJMEDIA also has tiny footprint, as explained below
+ *
+ * @subsubsection footprint Tiny Footprint
+ * Lets not talk about less meaningful and potentially misleading term such as
+ * core footprint, and instead here is the footprint of all components
+ * typically used to build a full streaming media:
+ *
+ * \verbatim
+Category Component text data bss dec filename
+-------------------------------------------------------------------------------
+Core Error subsystem 135 0 0 135 errno.o
+Core Endpoint 4210 4 4 4218 endpoint.o
+Core Port framework 652 0 0 652 port.o
+Core Codec framework 6257 0 0 6257 codec.o
+Codec Alaw/ulaw conv. 1060 16 0 1076 alaw_ulaw.o
+Codec G.711 3298 128 96 3522 g711.o
+Codec PLC 883 24 0 907 plc_common.o
+Codec PLC 7130 0 0 7130 wsola.o
+Session Stream 12222 0 1920 14142 stream.o
+Transport RTCP 3732 0 0 3732 rtcp.o
+Transport RTP 2568 0 0 2568 rtp.o
+Transport UDP 6612 96 0 6708 transport_udp.o
+Transport Jitter buffer 6473 0 0 6473 jbuf.o
+-------------------------------------------------------------------------------
+TOTAL 55,232 268 2,020 57,520
+
+ \endverbatim
+ * The 56KB are for media streaming components, complete with codec, RTP, and
+ * RTCP. The footprint above was done for PJSIP version 1.8.2 on a Linux x86
+ * machine, using footprintopimization as explained in PJSIP FAQ. Numbers are
+ * in bytes.
+ *
+ * @subsubsection quality Good Quality
+ * PJMEDIA supports wideband, ultra-wideband, and beyond, as well as multiple
+ * audio channels. The jitter buffer has been proven to work on lower
+ * bandwidth links such as 3G, and to some extent, Edge and GPRS. We've grown
+ * our own algorithm to compensate for packet losses and clock drifts in audio
+ * transmission, as well as feature to use codec's built in PLC if available.
+ *
+ * @subsubsection hw Hardware Support
+ * PJMEDIA supports hardware, firmware, or other built-in feature that comes
+ * with the device. These are crucial for mobile devices to allow the best
+ * use of the very limited CPU and battery power of the device. Among other
+ * things, device's on-board codec and echo cancellation may be used if
+ * available.
+ *
+ * @subsubsection extensible Extensible
+ * Despite its tiny footprint, PJMEDIA uses a flexible port concept, which is
+ * adapted from filter based concept found in other media framework. It is not
+ * as flexible as those found in Direct Show or gstreamer (and that would be
+ * unnecessary since it serves different purpose), but it's flexible enough
+ * to allow components to be assembled one after another to achieve certain
+ * task, and easy creation of such components by application and interconnect
+ * them to the rest of the framework.
+ *
+ * @subsubsection doc (Fairly Okay) Documentation
+ * We understand that any documentation can always be improved, but we put
+ * a lot of efforts in creating and maintaining our documentation, because
+ * we know it matters.
+ *
+ * \n
+ * @subsection org1 Organization
+ *
+ * At the top-most level, PJMEDIA library suite contains the following
+ * libraries.
+ *
+ * @subsubsection libpjmedia PJMEDIA
+ * This contains all main media components. Please see the
+ * <A HREF="modules.htm"><b>Modules</b></A> page for complete list of
+ * components that PJMEDIA provides.
+ *
+ * @subsubsection libpjmediacodec PJMEDIA Codec
+ * PJMEDIA-CODEC is a static library containing various codec implementations,
+ * wrapped into PJMEDIA codec framework. The static library is designed as
+ * such so that only codecs that are explicitly initialized are linked with
+ * the application, therefore keeping the application size in control.
+ *
+ * Please see @ref PJMEDIA_CODEC for more info.
+ *
+ * @subsubsection libpjmediaaudiodev PJMEDIA Audio Device
+ * PJMEDIA-Audiodev is audio device framework and abstraction library. Please
+ * see @ref audio_device_api for more info.
+ *
+ * \n
+ * @section pjmedia_concepts PJMEDIA Key Concepts
+ * Below are some key concepts in PJMEDIA:
+ * - @ref PJMEDIA_PORT
+ * - @ref PJMEDIA_PORT_CLOCK
+ * - @ref PJMEDIA_TRANSPORT
+ * - @ref PJMEDIA_SESSION
+ */
+
+
+/**
+ @page page_pjmedia_samples PJMEDIA and PJMEDIA-CODEC Examples
+
+ @section pjmedia_samples_sec PJMEDIA and PJMEDIA-CODEC Examples
+
+ Please find below some PJMEDIA related examples that may help in giving
+ some more info:
+
+ - @ref page_pjmedia_samples_level_c\n
+ This is a good place to start learning about @ref PJMEDIA_PORT,
+ as it shows that @ref PJMEDIA_PORT are only "passive" objects
+ with <tt>get_frame()</tt> and <tt>put_frame()</tt> interface, and
+ someone has to call these to retrieve/store media frames.
+
+ - @ref page_pjmedia_samples_playfile_c\n
+ This example shows that when application connects a media port (in this
+ case a @ref PJMEDIA_FILE_PLAY) to @ref PJMED_SND_PORT, media will flow
+ automatically since the @ref PJMED_SND_PORT provides @ref PJMEDIA_PORT_CLOCK.
+
+ - @ref page_pjmedia_samples_recfile_c\n
+ Demonstrates how to capture audio from microphone to WAV file.
+
+ - @ref page_pjmedia_samples_playsine_c\n
+ Demonstrates how to create a custom @ref PJMEDIA_PORT (in this
+ case a sine wave generator) and integrate it to PJMEDIA.
+
+ - @ref page_pjmedia_samples_confsample_c\n
+ This demonstrates how to use the @ref PJMEDIA_CONF. The sample program can
+ open multiple WAV files, and instruct the conference bridge to mix the
+ signal before playing it to the sound device.
+
+ - @ref page_pjmedia_samples_confbench_c\n
+ I use this to benchmark/optimize the conference bridge algorithm, but
+ readers may find the source useful.
+
+ - @ref page_pjmedia_samples_resampleplay_c\n
+ Demonstrates how to use @ref PJMEDIA_RESAMPLE_PORT to change the
+ sampling rate of a media port (in this case, a @ref PJMEDIA_FILE_PLAY).
+
+ - @ref page_pjmedia_samples_sndtest_c\n
+ This program performs some tests to the sound device to get some
+ quality parameters (such as sound jitter and clock drifts).\n
+ Screenshots on WinXP: \image html sndtest.jpg "sndtest screenshot on WinXP"
+
+ - @ref page_pjmedia_samples_streamutil_c\n
+ This example mainly demonstrates how to stream media (in this case a
+ @ref PJMEDIA_FILE_PLAY) to remote peer using RTP.
+
+ - @ref page_pjmedia_samples_siprtp_c\n
+ This is a useful program (integrated with PJSIP) to actively measure
+ the network quality/impairment parameters by making one or more SIP
+ calls (or receiving one or more SIP calls) and display the network
+ impairment of each stream direction at the end of the call.
+ The program is able to measure network quality parameters such as
+ jitter, packet lost/reorder/duplicate, round trip time, etc.\n
+ Note that the remote peer MUST support RTCP so that network quality
+ of each direction can be calculated. Using siprtp for both endpoints
+ is recommended.\n
+ Screenshots on WinXP: \image html siprtp.jpg "siprtp screenshot on WinXP"
+
+ - @ref page_pjmedia_samples_tonegen_c\n
+ This is a simple program to generate a tone and write the samples to
+ a raw PCM file. The main purpose of this file is to analyze the
+ quality of the tones/sine wave generated by PJMEDIA tone/sine wave
+ generator.
+
+ - @ref page_pjmedia_samples_aectest_c\n
+ Play a file to speaker, run AEC, and record the microphone input
+ to see if echo is coming.
+ */
+
+/**
+ * \page page_pjmedia_samples_siprtp_c Samples: Using SIP and Custom RTP/RTCP to Monitor Quality
+ *
+ * This source is an example to demonstrate using SIP and RTP/RTCP framework
+ * to measure the network quality/impairment from the SIP call. This
+ * program can be used to make calls or to receive calls from other
+ * SIP endpoint (or other siprtp program), and to display the media
+ * quality statistics at the end of the call.
+ *
+ * Note that the remote peer must support RTCP.
+ *
+ * The layout of the program has been designed so that custom reporting
+ * can be generated instead of plain human readable text.
+ *
+ * The source code of the file is pjsip-apps/src/samples/siprtp.c
+ *
+ * Screenshots on WinXP: \image html siprtp.jpg
+ *
+ * \includelineno siprtp.c
+ */
+
+#endif /* __PJMEDIA_DOXYGEN_H__ */
+
diff --git a/pjmedia/include/pjmedia/echo.h b/pjmedia/include/pjmedia/echo.h
new file mode 100644
index 0000000..d581e9a
--- /dev/null
+++ b/pjmedia/include/pjmedia/echo.h
@@ -0,0 +1,260 @@
+/* $Id: echo.h 4082 2012-04-24 13:09:14Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_ECHO_H__
+#define __PJMEDIA_ECHO_H__
+
+
+/**
+ * @file echo.h
+ * @brief Echo Cancellation API.
+ */
+#include <pjmedia/types.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_Echo_Cancel Accoustic Echo Cancellation API
+ * @ingroup PJMEDIA_PORT
+ * @brief Echo Cancellation API.
+ * @{
+ *
+ * This section describes API to perform echo cancellation to audio signal.
+ * There may be multiple echo canceller implementation in PJMEDIA, ranging
+ * from simple echo suppressor to a full Accoustic Echo Canceller/AEC. By
+ * using this API, application should be able to use which EC backend to
+ * use base on the requirement and capability of the platform.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque type for PJMEDIA Echo Canceller state.
+ */
+typedef struct pjmedia_echo_state pjmedia_echo_state;
+
+
+/**
+ * Echo cancellation options.
+ */
+typedef enum pjmedia_echo_flag
+{
+ /**
+ * Use any available backend echo canceller algorithm. This is
+ * the default settings. This setting is mutually exclusive with
+ * PJMEDIA_ECHO_SIMPLE and PJMEDIA_ECHO_SPEEX.
+ */
+ PJMEDIA_ECHO_DEFAULT= 0,
+
+ /**
+ * Force to use Speex AEC as the backend echo canceller algorithm.
+ * This setting is mutually exclusive with PJMEDIA_ECHO_SIMPLE.
+ */
+ PJMEDIA_ECHO_SPEEX = 1,
+
+ /**
+ * If PJMEDIA_ECHO_SIMPLE flag is specified during echo canceller
+ * creation, then a simple echo suppressor will be used instead of
+ * an accoustic echo cancellation. This setting is mutually exclusive
+ * with PJMEDIA_ECHO_SPEEX.
+ */
+ PJMEDIA_ECHO_SIMPLE = 2,
+
+ /**
+ * For internal use.
+ */
+ PJMEDIA_ECHO_ALGO_MASK = 15,
+
+ /**
+ * If PJMEDIA_ECHO_NO_LOCK flag is specified, no mutex will be created
+ * for the echo canceller, but application will guarantee that echo
+ * canceller will not be called by different threads at the same time.
+ */
+ PJMEDIA_ECHO_NO_LOCK = 16,
+
+ /**
+ * If PJMEDIA_ECHO_USE_SIMPLE_FIFO flag is specified, the delay buffer
+ * created for the echo canceller will use simple FIFO mechanism, i.e.
+ * without using WSOLA to expand and shrink audio samples.
+ */
+ PJMEDIA_ECHO_USE_SIMPLE_FIFO = 32,
+
+ /**
+ * If PJMEDIA_ECHO_USE_SW_ECHO flag is specified, software echo canceller
+ * will be used instead of device EC.
+ */
+ PJMEDIA_ECHO_USE_SW_ECHO = 64
+
+} pjmedia_echo_flag;
+
+
+
+
+/**
+ * Create the echo canceller.
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Media clock rate/sampling rate.
+ * @param samples_per_frame Number of samples per frame.
+ * @param tail_ms Tail length, miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options. If PJMEDIA_ECHO_SIMPLE is specified,
+ * then a simple echo suppressor implementation
+ * will be used instead of an accoustic echo
+ * cancellation.
+ * See #pjmedia_echo_flag for other options.
+ * @param p_echo Pointer to receive the Echo Canceller state.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate status.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_echo_state **p_echo );
+
+/**
+ * Create multi-channel the echo canceller.
+ *
+ * @param pool Pool to allocate memory.
+ * @param clock_rate Media clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param tail_ms Tail length, miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options. If PJMEDIA_ECHO_SIMPLE is specified,
+ * then a simple echo suppressor implementation
+ * will be used instead of an accoustic echo
+ * cancellation.
+ * See #pjmedia_echo_flag for other options.
+ * @param p_echo Pointer to receive the Echo Canceller state.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate status.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_echo_state **p_echo );
+
+/**
+ * Destroy the Echo Canceller.
+ *
+ * @param echo The Echo Canceller.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_destroy(pjmedia_echo_state *echo );
+
+
+/**
+ * Reset the echo canceller.
+ *
+ * @param echo The Echo Canceller.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_reset(pjmedia_echo_state *echo );
+
+
+/**
+ * Let the Echo Canceller know that a frame has been played to the speaker.
+ * The Echo Canceller will keep the frame in its internal buffer, to be used
+ * when cancelling the echo with #pjmedia_echo_capture().
+ *
+ * @param echo The Echo Canceller.
+ * @param play_frm Sample buffer containing frame to be played
+ * (or has been played) to the playback device.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_playback(pjmedia_echo_state *echo,
+ pj_int16_t *play_frm );
+
+
+/**
+ * Let the Echo Canceller know that a frame has been captured from the
+ * microphone. The Echo Canceller will cancel the echo from the captured
+ * signal, using the internal buffer (supplied by #pjmedia_echo_playback())
+ * as the FES (Far End Speech) reference.
+ *
+ * @param echo The Echo Canceller.
+ * @param rec_frm On input, it contains the input signal (captured
+ * from microphone) which echo is to be removed.
+ * Upon returning this function, this buffer contain
+ * the processed signal with the echo removed.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ * @param options Echo cancellation options, reserved for future use.
+ * Put zero for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_capture(pjmedia_echo_state *echo,
+ pj_int16_t *rec_frm,
+ unsigned options );
+
+
+/**
+ * Perform echo cancellation.
+ *
+ * @param echo The Echo Canceller.
+ * @param rec_frm On input, it contains the input signal (captured
+ * from microphone) which echo is to be removed.
+ * Upon returning this function, this buffer contain
+ * the processed signal with the echo removed.
+ * @param play_frm Sample buffer containing frame to be played
+ * (or has been played) to the playback device.
+ * The frame must contain exactly samples_per_frame
+ * number of samples.
+ * @param options Echo cancellation options, reserved for future use.
+ * Put zero for now.
+ * @param reserved Reserved for future use, put NULL for now.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_cancel( pjmedia_echo_state *echo,
+ pj_int16_t *rec_frm,
+ const pj_int16_t *play_frm,
+ unsigned options,
+ void *reserved );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_ECHO_H__ */
+
diff --git a/pjmedia/include/pjmedia/echo_port.h b/pjmedia/include/pjmedia/echo_port.h
new file mode 100644
index 0000000..9895601
--- /dev/null
+++ b/pjmedia/include/pjmedia/echo_port.h
@@ -0,0 +1,74 @@
+/* $Id: echo_port.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AEC_PORT_H__
+#define __PJMEDIA_AEC_PORT_H__
+
+/**
+ * @file echo_port.h
+ * @brief AEC (Accoustic Echo Cancellation) media port.
+ */
+#include <pjmedia/port.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_ECHO_PORT Echo Cancellation Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Echo Cancellation
+ * @{
+ *
+ * Wrapper to \ref PJMEDIA_Echo_Cancel into media port interface.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create echo canceller port.
+ *
+ * @param pool Pool to allocate memory.
+ * @param dn_port Downstream port.
+ * @param tail_ms Tail length in miliseconds.
+ * @param latency_ms Total lacency introduced by playback and
+ * recording device. Set to zero if the latency
+ * is not known.
+ * @param options Options, as in #pjmedia_echo_create().
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_echo_port_create(pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned tail_ms,
+ unsigned latency_ms,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_AEC_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/endpoint.h b/pjmedia/include/pjmedia/endpoint.h
new file mode 100644
index 0000000..440cfe8
--- /dev/null
+++ b/pjmedia/include/pjmedia/endpoint.h
@@ -0,0 +1,295 @@
+/* $Id: endpoint.h 3999 2012-03-30 07:10:13Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_MEDIAMGR_H__
+#define __PJMEDIA_MEDIAMGR_H__
+
+
+/**
+ * @file endpoint.h
+ * @brief Media endpoint.
+ */
+/**
+ * @defgroup PJMED_ENDPT The Endpoint
+ * @{
+ *
+ * The media endpoint acts as placeholder for endpoint capabilities. Each
+ * media endpoint will have a codec manager to manage list of codecs installed
+ * in the endpoint and a sound device factory.
+ *
+ * A reference to media endpoint instance is required when application wants
+ * to create a media session (#pjmedia_session_create()).
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/sdp.h>
+#include <pjmedia/transport.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * This enumeration describes various flags that can be set or retrieved in
+ * the media endpoint, by using pjmedia_endpt_set_flag() and
+ * pjmedia_endpt_get_flag() respectively.
+ */
+typedef enum pjmedia_endpt_flag
+{
+ /**
+ * This flag controls whether telephony-event should be offered in SDP.
+ * Value is boolean.
+ */
+ PJMEDIA_ENDPT_HAS_TELEPHONE_EVENT_FLAG
+
+} pjmedia_endpt_flag;
+
+
+/**
+ * Type of callback to register to pjmedia_endpt_atexit().
+ */
+typedef void (*pjmedia_endpt_exit_callback)(pjmedia_endpt *endpt);
+
+
+/**
+ * Create an instance of media endpoint.
+ *
+ * @param pf Pool factory, which will be used by the media endpoint
+ * throughout its lifetime.
+ * @param ioqueue Optional ioqueue instance to be registered to the
+ * endpoint. The ioqueue instance is used to poll all RTP
+ * and RTCP sockets. If this argument is NULL, the
+ * endpoint will create an internal ioqueue instance.
+ * @param worker_cnt Specify the number of worker threads to be created
+ * to poll the ioqueue.
+ * @param p_endpt Pointer to receive the endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create( pj_pool_factory *pf,
+ pj_ioqueue_t *ioqueue,
+ unsigned worker_cnt,
+ pjmedia_endpt **p_endpt);
+
+/**
+ * Destroy media endpoint instance.
+ *
+ * @param endpt Media endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_destroy(pjmedia_endpt *endpt);
+
+/**
+ * Change the value of a flag.
+ *
+ * @param endpt Media endpoint.
+ * @param flag The flag.
+ * @param value Pointer to the value to be set.
+ *
+ * @reurn PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_set_flag(pjmedia_endpt *endpt,
+ pjmedia_endpt_flag flag,
+ const void *value);
+
+/**
+ * Retrieve the value of a flag.
+ *
+ * @param endpt Media endpoint.
+ * @param flag The flag.
+ * @param value Pointer to store the result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_get_flag(pjmedia_endpt *endpt,
+ pjmedia_endpt_flag flag,
+ void *value);
+
+/**
+ * Get the ioqueue instance of the media endpoint.
+ *
+ * @param endpt The media endpoint instance.
+ *
+ * @return The ioqueue instance of the media endpoint.
+ */
+PJ_DECL(pj_ioqueue_t*) pjmedia_endpt_get_ioqueue(pjmedia_endpt *endpt);
+
+
+/**
+ * Get the number of worker threads on the media endpoint
+ *
+ * @param endpt The media endpoint instance.
+ * @return The number of worker threads on the media endpoint
+ */
+PJ_DECL(unsigned) pjmedia_endpt_get_thread_count(pjmedia_endpt *endpt);
+
+/**
+ * Get a reference to one of the worker threads of the media endpoint
+ *
+ * @param endpt The media endpoint instance.
+ * @param index The index of the thread: 0<= index < thread_cnt
+ *
+ * @return pj_thread_t or NULL
+ */
+PJ_DECL(pj_thread_t*) pjmedia_endpt_get_thread(pjmedia_endpt *endpt,
+ unsigned index);
+
+
+/**
+ * Request the media endpoint to create pool.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Name to be assigned to the pool.
+ * @param initial Initial pool size, in bytes.
+ * @param increment Increment size, in bytes.
+ *
+ * @return Memory pool.
+ */
+PJ_DECL(pj_pool_t*) pjmedia_endpt_create_pool( pjmedia_endpt *endpt,
+ const char *name,
+ pj_size_t initial,
+ pj_size_t increment);
+
+/**
+ * Get the codec manager instance of the media endpoint.
+ *
+ * @param endpt The media endpoint instance.
+ *
+ * @return The instance of codec manager belonging to
+ * this media endpoint.
+ */
+PJ_DECL(pjmedia_codec_mgr*) pjmedia_endpt_get_codec_mgr(pjmedia_endpt *endpt);
+
+
+/**
+ * Create a SDP session description that describes the endpoint
+ * capability.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to use to create the SDP descriptor.
+ * @param stream_cnt Number of elements in the sock_info array. This
+ * also denotes the maximum number of streams (i.e.
+ * the "m=" lines) that will be created in the SDP.
+ * By convention, if this value is greater than one,
+ * the first media will be audio and the remaining
+ * media is video.
+ * @param sock_info Array of socket transport information. One
+ * transport is needed for each media stream, and
+ * each transport consists of an RTP and RTCP socket
+ * pair.
+ * @param p_sdp Pointer to receive SDP session descriptor.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_sdp( pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ unsigned stream_cnt,
+ const pjmedia_sock_info sock_info[],
+ pjmedia_sdp_session **p_sdp );
+
+/**
+ * Create a "blank" SDP session description. The SDP will contain basic SDP
+ * fields such as origin, time, and name, but without any media lines.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param sess_name Optional SDP session name, or NULL to use default
+ * value.
+ * @param origin Address to put in the origin field.
+ * @param p_sdp Pointer to receive the created SDP session.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_base_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pj_str_t *sess_name,
+ const pj_sockaddr *origin,
+ pjmedia_sdp_session **p_sdp);
+
+/**
+ * Create SDP media line for audio media.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param si Socket information.
+ * @param options Option flags, must be zero for now.
+ * @param p_m Pointer to receive the created SDP media.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_audio_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info*si,
+ unsigned options,
+ pjmedia_sdp_media **p_m);
+
+/**
+ * Create SDP media line for video media.
+ *
+ * @param endpt The media endpoint.
+ * @param pool Pool to allocate memory from.
+ * @param si Socket information.
+ * @param options Option flags, must be zero for now.
+ * @param p_m Pointer to receive the created SDP media.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_create_video_sdp(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_sock_info*si,
+ unsigned options,
+ pjmedia_sdp_media **p_m);
+
+/**
+ * Dump media endpoint capabilities.
+ *
+ * @param endpt The media endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_dump(pjmedia_endpt *endpt);
+
+
+/**
+ * Register cleanup function to be called by media endpoint when
+ * #pjmedia_endpt_destroy() is called. Note that application should not
+ * use or access any endpoint resource (such as pool, ioqueue) from within
+ * the callback as such resource may have been released when the callback
+ * function is invoked.
+ *
+ * @param endpt The media endpoint.
+ * @param func The function to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_endpt_atexit(pjmedia_endpt *endpt,
+ pjmedia_endpt_exit_callback func);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+
+#endif /* __PJMEDIA_MEDIAMGR_H__ */
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
new file mode 100644
index 0000000..b7cca81
--- /dev/null
+++ b/pjmedia/include/pjmedia/errno.h
@@ -0,0 +1,650 @@
+/* $Id: errno.h 3945 2012-01-27 09:12:59Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_ERRNO_H__
+#define __PJMEDIA_ERRNO_H__
+
+/**
+ * @file errno.h Error Codes
+ * @brief PJMEDIA specific error codes.
+ */
+
+#include <pjmedia/types.h>
+#include <pj/errno.h>
+
+/**
+ * @defgroup PJMEDIA_ERRNO Error Codes
+ * @ingroup PJMEDIA_BASE
+ * @brief PJMEDIA specific error codes.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Start of error code relative to PJ_ERRNO_START_USER.
+ */
+#define PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
+#define PJMEDIA_ERRNO_END (PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE - 1)
+
+
+/**
+ * Mapping from PortAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_PORTAUDIO_ERRNO_START (PJMEDIA_ERRNO_END-10000)
+#define PJMEDIA_PORTAUDIO_ERRNO_END (PJMEDIA_PORTAUDIO_ERRNO_START + 10000 -1)
+/**
+ * Convert PortAudio error code to PJMEDIA error code.
+ * PortAudio error code range: 0 >= err >= -10000
+ */
+#define PJMEDIA_ERRNO_FROM_PORTAUDIO(err) ((int)PJMEDIA_PORTAUDIO_ERRNO_START-err)
+
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+
+ /**
+ * Mapping from LibSRTP error codes to pjmedia error space.
+ */
+#define PJMEDIA_LIBSRTP_ERRNO_START (PJMEDIA_ERRNO_END-10200)
+#define PJMEDIA_LIBSRTP_ERRNO_END (PJMEDIA_LIBSRTP_ERRNO_START + 200 - 1)
+/**
+ * Convert LibSRTP error code to PJMEDIA error code.
+ * LibSRTP error code range: 0 <= err < 200
+ */
+#define PJMEDIA_ERRNO_FROM_LIBSRTP(err) (PJMEDIA_LIBSRTP_ERRNO_START+err)
+
+#endif
+
+/************************************************************
+ * GENERIC/GENERAL PJMEDIA ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General/unknown PJMEDIA error.
+ */
+#define PJMEDIA_ERROR (PJMEDIA_ERRNO_START+1) /* 220001 */
+
+
+/************************************************************
+ * SDP ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Generic invalid SDP descriptor.
+ */
+#define PJMEDIA_SDP_EINSDP (PJMEDIA_ERRNO_START+20) /* 220020 */
+/**
+ * @hideinitializer
+ * Invalid SDP version.
+ */
+#define PJMEDIA_SDP_EINVER (PJMEDIA_ERRNO_START+21) /* 220021 */
+/**
+ * @hideinitializer
+ * Invalid SDP origin (o=) line.
+ */
+#define PJMEDIA_SDP_EINORIGIN (PJMEDIA_ERRNO_START+22) /* 220022 */
+/**
+ * @hideinitializer
+ * Invalid SDP time (t=) line.
+ */
+#define PJMEDIA_SDP_EINTIME (PJMEDIA_ERRNO_START+23) /* 220023 */
+/**
+ * @hideinitializer
+ * Empty SDP subject/name (s=) line.
+ */
+#define PJMEDIA_SDP_EINNAME (PJMEDIA_ERRNO_START+24) /* 220024 */
+/**
+ * @hideinitializer
+ * Invalid SDP connection info (c=) line.
+ */
+#define PJMEDIA_SDP_EINCONN (PJMEDIA_ERRNO_START+25) /* 220025 */
+/**
+ * @hideinitializer
+ * Missing SDP connection info line.
+ */
+#define PJMEDIA_SDP_EMISSINGCONN (PJMEDIA_ERRNO_START+26) /* 220026 */
+/**
+ * @hideinitializer
+ * Invalid attribute (a=) line.
+ */
+#define PJMEDIA_SDP_EINATTR (PJMEDIA_ERRNO_START+27) /* 220027 */
+/**
+ * @hideinitializer
+ * Invalid rtpmap attribute.
+ */
+#define PJMEDIA_SDP_EINRTPMAP (PJMEDIA_ERRNO_START+28) /* 220028 */
+/**
+ * @hideinitializer
+ * rtpmap attribute is too long.
+ */
+#define PJMEDIA_SDP_ERTPMAPTOOLONG (PJMEDIA_ERRNO_START+29) /* 220029 */
+/**
+ * @hideinitializer
+ * rtpmap is missing for dynamic payload type.
+ */
+#define PJMEDIA_SDP_EMISSINGRTPMAP (PJMEDIA_ERRNO_START+30) /* 220030 */
+/**
+ * @hideinitializer
+ * Invalid SDP media (m=) line.
+ */
+#define PJMEDIA_SDP_EINMEDIA (PJMEDIA_ERRNO_START+31) /* 220031 */
+/**
+ * @hideinitializer
+ * No payload format in the media stream.
+ */
+#define PJMEDIA_SDP_ENOFMT (PJMEDIA_ERRNO_START+32) /* 220032 */
+/**
+ * @hideinitializer
+ * Invalid payload type in media.
+ */
+#define PJMEDIA_SDP_EINPT (PJMEDIA_ERRNO_START+33) /* 220033 */
+/**
+ * @hideinitializer
+ * Invalid SDP "fmtp" attribute.
+ */
+#define PJMEDIA_SDP_EINFMTP (PJMEDIA_ERRNO_START+34) /* 220034 */
+/**
+ * @hideinitializer
+ * Invalid SDP "rtcp" attribute.
+ */
+#define PJMEDIA_SDP_EINRTCP (PJMEDIA_ERRNO_START+35) /* 220035 */
+/**
+ * @hideinitializer
+ * Invalid SDP media transport protocol.
+ */
+#define PJMEDIA_SDP_EINPROTO (PJMEDIA_ERRNO_START+36) /* 220036 */
+/**
+ * @hideinitializer
+ * Invalid SDP bandwidth info (b=) line.
+ */
+#define PJMEDIA_SDP_EINBANDW (PJMEDIA_ERRNO_START+37) /* 220037 */
+
+
+/************************************************************
+ * SDP NEGOTIATOR ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid state to perform the specified operation.
+ */
+#define PJMEDIA_SDPNEG_EINSTATE (PJMEDIA_ERRNO_START+40) /* 220040 */
+/**
+ * @hideinitializer
+ * No initial local SDP.
+ */
+#define PJMEDIA_SDPNEG_ENOINITIAL (PJMEDIA_ERRNO_START+41) /* 220041 */
+/**
+ * @hideinitializer
+ * No currently active SDP.
+ */
+#define PJMEDIA_SDPNEG_ENOACTIVE (PJMEDIA_ERRNO_START+42) /* 220042 */
+/**
+ * @hideinitializer
+ * No current offer or answer.
+ */
+#define PJMEDIA_SDPNEG_ENONEG (PJMEDIA_ERRNO_START+43) /* 220043 */
+/**
+ * @hideinitializer
+ * Media count mismatch in offer and answer.
+ */
+#define PJMEDIA_SDPNEG_EMISMEDIA (PJMEDIA_ERRNO_START+44) /* 220044 */
+/**
+ * @hideinitializer
+ * Media type is different in the remote answer.
+ */
+#define PJMEDIA_SDPNEG_EINVANSMEDIA (PJMEDIA_ERRNO_START+45) /* 220045 */
+/**
+ * @hideinitializer
+ * Transport type is different in the remote answer.
+ */
+#define PJMEDIA_SDPNEG_EINVANSTP (PJMEDIA_ERRNO_START+46) /* 220046 */
+/**
+ * @hideinitializer
+ * No common media payload is provided in the answer.
+ */
+#define PJMEDIA_SDPNEG_EANSNOMEDIA (PJMEDIA_ERRNO_START+47) /* 220047 */
+/**
+ * @hideinitializer
+ * No media is active after negotiation.
+ */
+#define PJMEDIA_SDPNEG_ENOMEDIA (PJMEDIA_ERRNO_START+48) /* 220048 */
+/**
+ * @hideinitializer
+ * No suitable codec for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSCODEC (PJMEDIA_ERRNO_START+49) /* 220049 */
+/**
+ * @hideinitializer
+ * No suitable telephone-event for remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSTELEVENT (PJMEDIA_ERRNO_START+50) /* 220050 */
+/**
+ * @hideinitializer
+ * No suitable answer for unknown remote offer.
+ */
+#define PJMEDIA_SDPNEG_NOANSUNKNOWN (PJMEDIA_ERRNO_START+51) /* 220051 */
+
+
+/************************************************************
+ * SDP COMPARISON STATUS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SDP media stream not equal.
+ */
+#define PJMEDIA_SDP_EMEDIANOTEQUAL (PJMEDIA_ERRNO_START+60) /* 220060 */
+/**
+ * @hideinitializer
+ * Port number in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_EPORTNOTEQUAL (PJMEDIA_ERRNO_START+61) /* 220061 */
+/**
+ * @hideinitializer
+ * Transport in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_ETPORTNOTEQUAL (PJMEDIA_ERRNO_START+62) /* 220062 */
+/**
+ * @hideinitializer
+ * Media format in SDP media descriptor not equal.
+ */
+#define PJMEDIA_SDP_EFORMATNOTEQUAL (PJMEDIA_ERRNO_START+63) /* 220063 */
+/**
+ * @hideinitializer
+ * SDP connection description not equal.
+ */
+#define PJMEDIA_SDP_ECONNNOTEQUAL (PJMEDIA_ERRNO_START+64) /* 220064 */
+/**
+ * @hideinitializer
+ * SDP attributes not equal.
+ */
+#define PJMEDIA_SDP_EATTRNOTEQUAL (PJMEDIA_ERRNO_START+65) /* 220065 */
+/**
+ * @hideinitializer
+ * SDP media direction not equal.
+ */
+#define PJMEDIA_SDP_EDIRNOTEQUAL (PJMEDIA_ERRNO_START+66) /* 220066 */
+/**
+ * @hideinitializer
+ * SDP fmtp attribute not equal.
+ */
+#define PJMEDIA_SDP_EFMTPNOTEQUAL (PJMEDIA_ERRNO_START+67) /* 220067 */
+/**
+ * @hideinitializer
+ * SDP ftpmap attribute not equal.
+ */
+#define PJMEDIA_SDP_ERTPMAPNOTEQUAL (PJMEDIA_ERRNO_START+68) /* 220068 */
+/**
+ * @hideinitializer
+ * SDP session descriptor not equal.
+ */
+#define PJMEDIA_SDP_ESESSNOTEQUAL (PJMEDIA_ERRNO_START+69) /* 220069 */
+/**
+ * @hideinitializer
+ * SDP origin not equal.
+ */
+#define PJMEDIA_SDP_EORIGINNOTEQUAL (PJMEDIA_ERRNO_START+70) /* 220070 */
+/**
+ * @hideinitializer
+ * SDP name/subject not equal.
+ */
+#define PJMEDIA_SDP_ENAMENOTEQUAL (PJMEDIA_ERRNO_START+71) /* 220071 */
+/**
+ * @hideinitializer
+ * SDP time not equal.
+ */
+#define PJMEDIA_SDP_ETIMENOTEQUAL (PJMEDIA_ERRNO_START+72) /* 220072 */
+
+
+/************************************************************
+ * CODEC
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Unsupported codec.
+ */
+#define PJMEDIA_CODEC_EUNSUP (PJMEDIA_ERRNO_START+80) /* 220080 */
+/**
+ * @hideinitializer
+ * Codec internal creation error.
+ */
+#define PJMEDIA_CODEC_EFAILED (PJMEDIA_ERRNO_START+81) /* 220081 */
+/**
+ * @hideinitializer
+ * Codec frame is too short.
+ */
+#define PJMEDIA_CODEC_EFRMTOOSHORT (PJMEDIA_ERRNO_START+82) /* 220082 */
+/**
+ * @hideinitializer
+ * PCM buffer is too short.
+ */
+#define PJMEDIA_CODEC_EPCMTOOSHORT (PJMEDIA_ERRNO_START+83) /* 220083 */
+/**
+ * @hideinitializer
+ * Invalid codec frame length.
+ */
+#define PJMEDIA_CODEC_EFRMINLEN (PJMEDIA_ERRNO_START+84) /* 220084 */
+/**
+ * @hideinitializer
+ * Invalid PCM frame length.
+ */
+#define PJMEDIA_CODEC_EPCMFRMINLEN (PJMEDIA_ERRNO_START+85) /* 220085 */
+/**
+ * @hideinitializer
+ * Invalid mode.
+ */
+#define PJMEDIA_CODEC_EINMODE (PJMEDIA_ERRNO_START+86) /* 220086 */
+/**
+ * @hideinitializer
+ * Bad or corrupted bitstream.
+ */
+#define PJMEDIA_CODEC_EBADBITSTREAM (PJMEDIA_ERRNO_START+87) /* 220087 */
+
+
+/************************************************************
+ * MEDIA
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Invalid remote IP address (in SDP).
+ */
+#define PJMEDIA_EINVALIDIP (PJMEDIA_ERRNO_START+100) /* 220100 */
+/**
+ * @hideinitializer
+ * Asymetric codec is not supported.
+ */
+#define PJMEDIA_EASYMCODEC (PJMEDIA_ERRNO_START+101) /* 220101 */
+/**
+ * @hideinitializer
+ * Invalid payload type.
+ */
+#define PJMEDIA_EINVALIDPT (PJMEDIA_ERRNO_START+102) /* 220102 */
+/**
+ * @hideinitializer
+ * Missing rtpmap.
+ */
+#define PJMEDIA_EMISSINGRTPMAP (PJMEDIA_ERRNO_START+103) /* 220103 */
+/**
+ * @hideinitializer
+ * Invalid media type.
+ */
+#define PJMEDIA_EINVALIMEDIATYPE (PJMEDIA_ERRNO_START+104) /* 220104 */
+/**
+ * @hideinitializer
+ * Remote does not support DTMF.
+ */
+#define PJMEDIA_EREMOTENODTMF (PJMEDIA_ERRNO_START+105) /* 220105 */
+/**
+ * @hideinitializer
+ * Invalid DTMF digit.
+ */
+#define PJMEDIA_RTP_EINDTMF (PJMEDIA_ERRNO_START+106) /* 220106 */
+/**
+ * @hideinitializer
+ * Remote does not support RFC 2833
+ */
+#define PJMEDIA_RTP_EREMNORFC2833 (PJMEDIA_ERRNO_START+107) /* 220107 */
+/**
+ * @hideinitializer
+ * Invalid or bad format
+ */
+#define PJMEDIA_EBADFMT (PJMEDIA_ERRNO_START+108) /* 220108 */
+
+
+/************************************************************
+ * RTP SESSION ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * General invalid RTP packet error.
+ */
+#define PJMEDIA_RTP_EINPKT (PJMEDIA_ERRNO_START+120) /* 220120 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet packing.
+ */
+#define PJMEDIA_RTP_EINPACK (PJMEDIA_ERRNO_START+121) /* 220121 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet version.
+ */
+#define PJMEDIA_RTP_EINVER (PJMEDIA_ERRNO_START+122) /* 220122 */
+/**
+ * @hideinitializer
+ * RTP SSRC id mismatch.
+ */
+#define PJMEDIA_RTP_EINSSRC (PJMEDIA_ERRNO_START+123) /* 220123 */
+/**
+ * @hideinitializer
+ * RTP payload type mismatch.
+ */
+#define PJMEDIA_RTP_EINPT (PJMEDIA_ERRNO_START+124) /* 220124 */
+/**
+ * @hideinitializer
+ * Invalid RTP packet length.
+ */
+#define PJMEDIA_RTP_EINLEN (PJMEDIA_ERRNO_START+125) /* 220125 */
+/**
+ * @hideinitializer
+ * RTP session restarted.
+ */
+#define PJMEDIA_RTP_ESESSRESTART (PJMEDIA_ERRNO_START+130) /* 220130 */
+/**
+ * @hideinitializer
+ * RTP session in probation
+ */
+#define PJMEDIA_RTP_ESESSPROBATION (PJMEDIA_ERRNO_START+131) /* 220131 */
+/**
+ * @hideinitializer
+ * Bad RTP sequence number
+ */
+#define PJMEDIA_RTP_EBADSEQ (PJMEDIA_ERRNO_START+132) /* 220132 */
+/**
+ * @hideinitializer
+ * RTP media port destination is not configured
+ */
+#define PJMEDIA_RTP_EBADDEST (PJMEDIA_ERRNO_START+133) /* 220133 */
+/**
+ * @hideinitializer
+ * RTP is not configured.
+ */
+#define PJMEDIA_RTP_ENOCONFIG (PJMEDIA_ERRNO_START+134) /* 220134 */
+
+
+/************************************************************
+ * PORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Generic incompatible port error.
+ */
+#define PJMEDIA_ENOTCOMPATIBLE (PJMEDIA_ERRNO_START+160) /* 220160 */
+/**
+ * @hideinitializer
+ * Incompatible clock rate
+ */
+#define PJMEDIA_ENCCLOCKRATE (PJMEDIA_ERRNO_START+161) /* 220161 */
+/**
+ * @hideinitializer
+ * Incompatible samples per frame
+ */
+#define PJMEDIA_ENCSAMPLESPFRAME (PJMEDIA_ERRNO_START+162) /* 220162 */
+/**
+ * @hideinitializer
+ * Incompatible media type
+ */
+#define PJMEDIA_ENCTYPE (PJMEDIA_ERRNO_START+163) /* 220163 */
+/**
+ * @hideinitializer
+ * Incompatible bits per sample
+ */
+#define PJMEDIA_ENCBITS (PJMEDIA_ERRNO_START+164) /* 220164 */
+/**
+ * @hideinitializer
+ * Incompatible bytes per frame
+ */
+#define PJMEDIA_ENCBYTES (PJMEDIA_ERRNO_START+165) /* 220165 */
+/**
+ * @hideinitializer
+ * Incompatible number of channels
+ */
+#define PJMEDIA_ENCCHANNEL (PJMEDIA_ERRNO_START+166) /* 220166 */
+
+
+/************************************************************
+ * FILE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * Not a valid WAVE file.
+ */
+#define PJMEDIA_ENOTVALIDWAVE (PJMEDIA_ERRNO_START+180) /* 220180 */
+/**
+ * @hideinitializer
+ * Unsupported WAVE file.
+ */
+#define PJMEDIA_EWAVEUNSUPP (PJMEDIA_ERRNO_START+181) /* 220181 */
+/**
+ * @hideinitializer
+ * Wave file too short.
+ */
+#define PJMEDIA_EWAVETOOSHORT (PJMEDIA_ERRNO_START+182) /* 220182 */
+/**
+ * @hideinitializer
+ * Sound frame is too large for file buffer.
+ */
+#define PJMEDIA_EFRMFILETOOBIG (PJMEDIA_ERRNO_START+183) /* 220183 */
+/**
+ * @hideinitializer
+ * Unsupported AVI file.
+ */
+#define PJMEDIA_EAVIUNSUPP (PJMEDIA_ERRNO_START+191) /* 220191 */
+
+
+/************************************************************
+ * SOUND DEVICE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * No suitable audio capture device.
+ */
+#define PJMEDIA_ENOSNDREC (PJMEDIA_ERRNO_START+200) /* 220200 */
+/**
+ * @hideinitializer
+ * No suitable audio playback device.
+ */
+#define PJMEDIA_ENOSNDPLAY (PJMEDIA_ERRNO_START+201) /* 220201 */
+/**
+ * @hideinitializer
+ * Invalid sound device ID.
+ */
+#define PJMEDIA_ESNDINDEVID (PJMEDIA_ERRNO_START+202) /* 220202 */
+/**
+ * @hideinitializer
+ * Invalid sample format for sound device.
+ */
+#define PJMEDIA_ESNDINSAMPLEFMT (PJMEDIA_ERRNO_START+203) /* 220203 */
+
+
+#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
+/************************************************************
+ * SRTP TRANSPORT ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * SRTP crypto-suite name not match the offerer tag.
+ */
+#define PJMEDIA_SRTP_ECRYPTONOTMATCH (PJMEDIA_ERRNO_START+220) /* 220220 */
+/**
+ * @hideinitializer
+ * Invalid SRTP key length for specific crypto.
+ */
+#define PJMEDIA_SRTP_EINKEYLEN (PJMEDIA_ERRNO_START+221) /* 220221 */
+/**
+ * @hideinitializer
+ * Unsupported SRTP crypto-suite.
+ */
+#define PJMEDIA_SRTP_ENOTSUPCRYPTO (PJMEDIA_ERRNO_START+222) /* 220222 */
+/**
+ * @hideinitializer
+ * SRTP SDP contains ambigue answer.
+ */
+#define PJMEDIA_SRTP_ESDPAMBIGUEANS (PJMEDIA_ERRNO_START+223) /* 220223 */
+/**
+ * @hideinitializer
+ * Duplicated crypto tag.
+ */
+#define PJMEDIA_SRTP_ESDPDUPCRYPTOTAG (PJMEDIA_ERRNO_START+224) /* 220224 */
+/**
+ * @hideinitializer
+ * Invalid crypto attribute.
+ */
+#define PJMEDIA_SRTP_ESDPINCRYPTO (PJMEDIA_ERRNO_START+225) /* 220225 */
+/**
+ * @hideinitializer
+ * Invalid crypto tag.
+ */
+#define PJMEDIA_SRTP_ESDPINCRYPTOTAG (PJMEDIA_ERRNO_START+226) /* 220226 */
+/**
+ * @hideinitializer
+ * Invalid SDP media transport for SRTP.
+ */
+#define PJMEDIA_SRTP_ESDPINTRANSPORT (PJMEDIA_ERRNO_START+227) /* 220227 */
+/**
+ * @hideinitializer
+ * SRTP crypto attribute required in SDP.
+ */
+#define PJMEDIA_SRTP_ESDPREQCRYPTO (PJMEDIA_ERRNO_START+228) /* 220228 */
+/**
+ * @hideinitializer
+ * Secure transport required in SDP media descriptor.
+ */
+#define PJMEDIA_SRTP_ESDPREQSECTP (PJMEDIA_ERRNO_START+229) /* 220229 */
+
+#endif /* PJMEDIA_HAS_SRTP */
+
+
+/**
+ * Get error message for the specified error code. Note that this
+ * function is only able to decode PJMEDIA specific error code.
+ * Application should use pj_strerror(), which should be able to
+ * decode all error codes belonging to all subsystems (e.g. pjlib,
+ * pjmedia, pjsip, etc).
+ *
+ * @param status The error code.
+ * @param buffer The buffer where to put the error message.
+ * @param bufsize Size of the buffer.
+ *
+ * @return The error message as NULL terminated string,
+ * wrapped with pj_str_t.
+ */
+PJ_DECL(pj_str_t) pjmedia_strerror( pj_status_t status, char *buffer,
+ pj_size_t bufsize);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_ERRNO_H__ */
+
diff --git a/pjmedia/include/pjmedia/event.h b/pjmedia/include/pjmedia/event.h
new file mode 100644
index 0000000..3a9c773
--- /dev/null
+++ b/pjmedia/include/pjmedia/event.h
@@ -0,0 +1,395 @@
+/* $Id: event.h 3905 2011-12-09 05:15:39Z ming $ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_EVENT_H__
+#define __PJMEDIA_EVENT_H__
+
+/**
+ * @file pjmedia/event.h
+ * @brief Event framework
+ */
+#include <pjmedia/format.h>
+#include <pjmedia/signatures.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_EVENT Event Framework
+ * @brief PJMEDIA event framework
+ * @{
+ */
+
+/**
+ * This enumeration describes list of media events.
+ */
+typedef enum pjmedia_event_type
+{
+ /**
+ * No event.
+ */
+ PJMEDIA_EVENT_NONE,
+
+ /**
+ * Media format has changed event.
+ */
+ PJMEDIA_EVENT_FMT_CHANGED = PJMEDIA_FOURCC('F', 'M', 'C', 'H'),
+
+ /**
+ * Video window is being closed.
+ */
+ PJMEDIA_EVENT_WND_CLOSING = PJMEDIA_FOURCC('W', 'N', 'C', 'L'),
+
+ /**
+ * Video window has been closed event.
+ */
+ PJMEDIA_EVENT_WND_CLOSED = PJMEDIA_FOURCC('W', 'N', 'C', 'O'),
+
+ /**
+ * Video window has been resized event.
+ */
+ PJMEDIA_EVENT_WND_RESIZED = PJMEDIA_FOURCC('W', 'N', 'R', 'Z'),
+
+ /**
+ * Mouse button has been pressed event.
+ */
+ PJMEDIA_EVENT_MOUSE_BTN_DOWN = PJMEDIA_FOURCC('M', 'S', 'D', 'N'),
+
+ /**
+ * Video keyframe has just been decoded event.
+ */
+ PJMEDIA_EVENT_KEYFRAME_FOUND = PJMEDIA_FOURCC('I', 'F', 'R', 'F'),
+
+ /**
+ * Video decoding error due to missing keyframe event.
+ */
+ PJMEDIA_EVENT_KEYFRAME_MISSING = PJMEDIA_FOURCC('I', 'F', 'R', 'M'),
+
+ /**
+ * Video orientation has been changed event.
+ */
+ PJMEDIA_EVENT_ORIENT_CHANGED = PJMEDIA_FOURCC('O', 'R', 'N', 'T')
+
+} pjmedia_event_type;
+
+/**
+ * Additional data/parameters for media format changed event
+ * (PJMEDIA_EVENT_FMT_CHANGED).
+ */
+typedef struct pjmedia_event_fmt_changed_data
+{
+ /** The media flow direction */
+ pjmedia_dir dir;
+
+ /** The new media format. */
+ pjmedia_format new_fmt;
+} pjmedia_event_fmt_changed_data;
+
+/**
+ * Additional data/parameters are not needed.
+ */
+typedef struct pjmedia_event_dummy_data
+{
+ /** Dummy data */
+ int dummy;
+} pjmedia_event_dummy_data;
+
+/**
+ * Additional data/parameters for window resized event
+ * (PJMEDIA_EVENT_WND_RESIZED).
+ */
+typedef struct pjmedia_event_wnd_resized_data
+{
+ /**
+ * The new window size.
+ */
+ pjmedia_rect_size new_size;
+} pjmedia_event_wnd_resized_data;
+
+/**
+ * Additional data/parameters for window closing event.
+ */
+typedef struct pjmedia_event_wnd_closing_data
+{
+ /** Consumer may set this field to PJ_TRUE to cancel the closing */
+ pj_bool_t cancel;
+} pjmedia_event_wnd_closing_data;
+
+/** Additional parameters for window changed event. */
+typedef pjmedia_event_dummy_data pjmedia_event_wnd_closed_data;
+
+/** Additional parameters for mouse button down event */
+typedef pjmedia_event_dummy_data pjmedia_event_mouse_btn_down_data;
+
+/** Additional parameters for keyframe found event */
+typedef pjmedia_event_dummy_data pjmedia_event_keyframe_found_data;
+
+/** Additional parameters for keyframe missing event */
+typedef pjmedia_event_dummy_data pjmedia_event_keyframe_missing_data;
+
+/**
+ * Maximum size of additional parameters section in pjmedia_event structure
+ */
+#define PJMEDIA_EVENT_DATA_MAX_SIZE sizeof(pjmedia_event_fmt_changed_data)
+
+/** Type of storage to hold user data in pjmedia_event structure */
+typedef char pjmedia_event_user_data[PJMEDIA_EVENT_DATA_MAX_SIZE];
+
+/**
+ * This structure describes a media event. It consists mainly of the event
+ * type and additional data/parameters for the event. Applications can
+ * use #pjmedia_event_init() to initialize this event structure with
+ * basic information about the event.
+ */
+typedef struct pjmedia_event
+{
+ /**
+ * The event type.
+ */
+ pjmedia_event_type type;
+
+ /**
+ * The media timestamp when the event occurs.
+ */
+ pj_timestamp timestamp;
+
+ /**
+ * Pointer information about the source of this event. This field
+ * is provided mainly for comparison purpose so that event subscribers
+ * can check which source the event originated from. Usage of this
+ * pointer for other purpose may require special care such as mutex
+ * locking or checking whether the object is already destroyed.
+ */
+ const void *src;
+
+ /**
+ * Pointer information about the publisher of this event. This field
+ * is provided mainly for comparison purpose so that event subscribers
+ * can check which object published the event. Usage of this
+ * pointer for other purpose may require special care such as mutex
+ * locking or checking whether the object is already destroyed.
+ */
+ const void *epub;
+
+ /**
+ * Additional data/parameters about the event. The type of data
+ * will be specific to the event type being reported.
+ */
+ union {
+ /** Media format changed event data. */
+ pjmedia_event_fmt_changed_data fmt_changed;
+
+ /** Window resized event data */
+ pjmedia_event_wnd_resized_data wnd_resized;
+
+ /** Window closing event data. */
+ pjmedia_event_wnd_closing_data wnd_closing;
+
+ /** Window closed event data */
+ pjmedia_event_wnd_closed_data wnd_closed;
+
+ /** Mouse button down event data */
+ pjmedia_event_mouse_btn_down_data mouse_btn_down;
+
+ /** Keyframe found event data */
+ pjmedia_event_keyframe_found_data keyframe_found;
+
+ /** Keyframe missing event data */
+ pjmedia_event_keyframe_missing_data keyframe_missing;
+
+ /** Storage for user event data */
+ pjmedia_event_user_data user;
+
+ /** Pointer to storage to user event data, if it's outside
+ * this struct
+ */
+ void *ptr;
+ } data;
+} pjmedia_event;
+
+/**
+ * The callback to receive media events.
+ *
+ * @param event The media event.
+ * @param user_data The user data associated with the callback.
+ *
+ * @return If the callback returns non-PJ_SUCCESS, this return
+ * code may be propagated back to the caller.
+ */
+typedef pj_status_t pjmedia_event_cb(pjmedia_event *event,
+ void *user_data);
+
+/**
+ * This enumeration describes flags for event publication via
+ * #pjmedia_event_publish().
+ */
+typedef enum pjmedia_event_publish_flag
+{
+ /**
+ * Publisher will only post the event to the event manager. It is the
+ * event manager that will later notify all the publisher's subscribers.
+ */
+ PJMEDIA_EVENT_PUBLISH_POST_EVENT = 1
+
+} pjmedia_event_publish_flag;
+
+/**
+ * Event manager flag.
+ */
+typedef enum pjmedia_event_mgr_flag
+{
+ /**
+ * Tell the event manager not to create any event worker thread.
+ */
+ PJMEDIA_EVENT_MGR_NO_THREAD = 1
+
+} pjmedia_event_mgr_flag;
+
+/**
+ * Opaque data type for event manager. Typically, the event manager
+ * is a singleton instance, although application may instantiate more than one
+ * instances of this if required.
+ */
+typedef struct pjmedia_event_mgr pjmedia_event_mgr;
+
+/**
+ * Create a new event manager instance. This will also set the pointer
+ * to the singleton instance if the value is still NULL.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param options Options. Bitmask flags from #pjmedia_event_mgr_flag
+ * @param mgr Pointer to hold the created instance of the
+ * event manager.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_mgr_create(pj_pool_t *pool,
+ unsigned options,
+ pjmedia_event_mgr **mgr);
+
+/**
+ * Get the singleton instance of the event manager.
+ *
+ * @return The instance.
+ */
+PJ_DECL(pjmedia_event_mgr*) pjmedia_event_mgr_instance(void);
+
+/**
+ * Manually assign a specific event manager instance as the singleton
+ * instance. Normally this is not needed if only one instance is ever
+ * going to be created, as the library automatically assign the singleton
+ * instance.
+ *
+ * @param mgr The instance to be used as the singleton instance.
+ * Application may specify NULL to clear the singleton
+ * singleton instance.
+ */
+PJ_DECL(void) pjmedia_event_mgr_set_instance(pjmedia_event_mgr *mgr);
+
+/**
+ * Destroy an event manager. If the manager happens to be the singleton
+ * instance, the singleton instance will be set to NULL.
+ *
+ * @param mgr The eventmanager. Specify NULL to use
+ * the singleton instance.
+ */
+PJ_DECL(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr);
+
+/**
+ * Initialize event structure with basic data about the event.
+ *
+ * @param event The event to be initialized.
+ * @param type The event type to be set for this event.
+ * @param ts Event timestamp. May be set to NULL to set the event
+ * timestamp to zero.
+ * @param src Event source.
+ */
+PJ_DECL(void) pjmedia_event_init(pjmedia_event *event,
+ pjmedia_event_type type,
+ const pj_timestamp *ts,
+ const void *src);
+
+/**
+ * Subscribe a callback function to events published by the specified
+ * publisher. Note that the subscriber may receive not only events emitted by
+ * the specific publisher specified in the argument, but also from other
+ * publishers contained by the publisher, if the publisher is republishing
+ * events from other publishers.
+ *
+ * @param mgr The event manager.
+ * @param cb The callback function to receive the event.
+ * @param user_data The user data to be associated with the callback
+ * function.
+ * @param epub The event publisher.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_subscribe(pjmedia_event_mgr *mgr,
+ pjmedia_event_cb *cb,
+ void *user_data,
+ void *epub);
+
+/**
+ * Unsubscribe the callback associated with the user data from a publisher.
+ * If the user data is not specified, this function will do the
+ * unsubscription for all user data. If the publisher, epub, is not
+ * specified, this function will do the unsubscription from all publishers.
+ *
+ * @param mgr The event manager.
+ * @param cb The callback function.
+ * @param user_data The user data associated with the callback
+ * function, can be NULL.
+ * @param epub The event publisher, can be NULL.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_event_unsubscribe(pjmedia_event_mgr *mgr,
+ pjmedia_event_cb *cb,
+ void *user_data,
+ void *epub);
+
+/**
+ * Publish the specified event to all subscribers of the specified event
+ * publisher. By default, the function will call all the subcribers'
+ * callbacks immediately. If the publisher uses the flag
+ * PJMEDIA_EVENT_PUBLISH_POST_EVENT, publisher will only post the event
+ * to the event manager and return immediately. It is the event manager
+ * that will later notify all the publisher's subscribers.
+ *
+ * @param mgr The event manager.
+ * @param epub The event publisher.
+ * @param event The event to be published.
+ * @param flag Publication flag.
+ *
+ * @return PJ_SUCCESS only if all subscription callbacks returned
+ * PJ_SUCCESS.
+ */
+PJ_DECL(pj_status_t) pjmedia_event_publish(pjmedia_event_mgr *mgr,
+ void *epub,
+ pjmedia_event *event,
+ pjmedia_event_publish_flag flag);
+
+
+/**
+ * @} PJMEDIA_EVENT
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_EVENT_H__ */
diff --git a/pjmedia/include/pjmedia/format.h b/pjmedia/include/pjmedia/format.h
new file mode 100644
index 0000000..0bfe3c6
--- /dev/null
+++ b/pjmedia/include/pjmedia/format.h
@@ -0,0 +1,766 @@
+/* $Id: format.h 4158 2012-06-06 09:56:14Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_FORMAT_H__
+#define __PJMEDIA_FORMAT_H__
+
+/**
+ * @file pjmedia/format.h Media format
+ * @brief Media format
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_FORMAT Media format
+ * @ingroup PJMEDIA_TYPES
+ * @brief Media format
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * Macro for packing format from a four character code, similar to FOURCC.
+ * This macro is used for building the constants in pjmedia_format_id
+ * enumeration.
+ */
+#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) PJMEDIA_FOURCC(C1, C2, C3, C4)
+
+/**
+ * This enumeration uniquely identify audio sample and/or video pixel formats.
+ * Some well known formats are listed here. The format ids are built by
+ * combining four character codes, similar to FOURCC. The format id is
+ * extensible, as application may define and use format ids not declared
+ * on this enumeration.
+ *
+ * This format id along with other information will fully describe the media
+ * in #pjmedia_format structure.
+ */
+typedef enum pjmedia_format_id
+{
+ /*
+ * Audio formats
+ */
+
+ /** 16bit signed integer linear PCM audio */
+ PJMEDIA_FORMAT_L16 = 0,
+
+ /** Alias for PJMEDIA_FORMAT_L16 */
+ PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16,
+
+ /** G.711 ALAW */
+ PJMEDIA_FORMAT_PCMA = PJMEDIA_FORMAT_PACK('A', 'L', 'A', 'W'),
+
+ /** Alias for PJMEDIA_FORMAT_PCMA */
+ PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA,
+
+ /** G.711 ULAW */
+ PJMEDIA_FORMAT_PCMU = PJMEDIA_FORMAT_PACK('u', 'L', 'A', 'W'),
+
+ /** Aliaw for PJMEDIA_FORMAT_PCMU */
+ PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU,
+
+ /** AMR narrowband */
+ PJMEDIA_FORMAT_AMR = PJMEDIA_FORMAT_PACK(' ', 'A', 'M', 'R'),
+
+ /** ITU G.729 */
+ PJMEDIA_FORMAT_G729 = PJMEDIA_FORMAT_PACK('G', '7', '2', '9'),
+
+ /** Internet Low Bit-Rate Codec (ILBC) */
+ PJMEDIA_FORMAT_ILBC = PJMEDIA_FORMAT_PACK('I', 'L', 'B', 'C'),
+
+
+ /*
+ * Video formats.
+ */
+ /**
+ * 24bit RGB
+ */
+ PJMEDIA_FORMAT_RGB24 = PJMEDIA_FORMAT_PACK('R', 'G', 'B', '3'),
+
+ /**
+ * 32bit RGB with alpha channel
+ */
+ PJMEDIA_FORMAT_RGBA = PJMEDIA_FORMAT_PACK('R', 'G', 'B', 'A'),
+ PJMEDIA_FORMAT_BGRA = PJMEDIA_FORMAT_PACK('B', 'G', 'R', 'A'),
+
+ /**
+ * Alias for PJMEDIA_FORMAT_RGBA
+ */
+ PJMEDIA_FORMAT_RGB32 = PJMEDIA_FORMAT_RGBA,
+
+ /**
+ * Device Independent Bitmap, alias for 24 bit RGB
+ */
+ PJMEDIA_FORMAT_DIB = PJMEDIA_FORMAT_PACK('D', 'I', 'B', ' '),
+
+ /**
+ * This is planar 4:4:4/24bpp RGB format, the data can be treated as
+ * three planes of color components, where the first plane contains
+ * only the G samples, the second plane contains only the B samples,
+ * and the third plane contains only the R samples.
+ */
+ PJMEDIA_FORMAT_GBRP = PJMEDIA_FORMAT_PACK('G', 'B', 'R', 'P'),
+
+ /**
+ * This is a packed 4:4:4/32bpp format, where each pixel is encoded as
+ * four consecutive bytes, arranged in the following sequence: V0, U0,
+ * Y0, A0. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#ayuv
+ */
+ PJMEDIA_FORMAT_AYUV = PJMEDIA_FORMAT_PACK('A', 'Y', 'U', 'V'),
+
+ /**
+ * This is packed 4:2:2/16bpp YUV format, the data can be treated as
+ * an array of unsigned char values, where the first byte contains
+ * the first Y sample, the second byte contains the first U (Cb) sample,
+ * the third byte contains the second Y sample, and the fourth byte
+ * contains the first V (Cr) sample, and so forth. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#yuy2
+ */
+ PJMEDIA_FORMAT_YUY2 = PJMEDIA_FORMAT_PACK('Y', 'U', 'Y', '2'),
+
+ /**
+ * This format is the same as the YUY2 format except the byte order is
+ * reversed -- that is, the chroma and luma bytes are flipped. If the
+ * image is addressed as an array of two little-endian WORD values, the
+ * first WORD contains U in the LSBs and Y0 in the MSBs, and the second
+ * WORD contains V in the LSBs and Y1 in the MSBs. Source:
+ * http://msdn.microsoft.com/en-us/library/dd206750%28v=VS.85%29.aspx#uyvy
+ */
+ PJMEDIA_FORMAT_UYVY = PJMEDIA_FORMAT_PACK('U', 'Y', 'V', 'Y'),
+
+ /**
+ * This format is the same as the YUY2 and UYVY format except the byte
+ * order is reversed -- that is, the chroma and luma bytes are flipped.
+ * If the image is addressed as an array of two little-endian WORD values,
+ * the first WORD contains Y0 in the LSBs and V in the MSBs, and the second
+ * WORD contains Y1 in the LSBs and U in the MSBs.
+ */
+ PJMEDIA_FORMAT_YVYU = PJMEDIA_FORMAT_PACK('Y', 'V', 'Y', 'U'),
+
+ /**
+ * This is planar 4:2:0/12bpp YUV format, the data can be treated as
+ * three planes of color components, where the first plane contains
+ * only the Y samples, the second plane contains only the U (Cb) samples,
+ * and the third plane contains only the V (Cr) sample.
+ */
+ PJMEDIA_FORMAT_I420 = PJMEDIA_FORMAT_PACK('I', '4', '2', '0'),
+
+ /**
+ * IYUV is alias for I420.
+ */
+ PJMEDIA_FORMAT_IYUV = PJMEDIA_FORMAT_I420,
+
+ /**
+ * This is planar 4:2:0/12bpp YUV format, similar to I420 or IYUV but
+ * the U (Cb) and V (Cr) planes order is switched, i.e: the second plane
+ * contains the V (Cb) samples and the third plane contains the V (Cr)
+ * samples.
+ */
+ PJMEDIA_FORMAT_YV12 = PJMEDIA_FORMAT_PACK('Y', 'V', '1', '2'),
+
+ /**
+ * This is planar 4:2:2/16bpp YUV format, the data can be treated as
+ * three planes of color components, where the first plane contains
+ * only the Y samples, the second plane contains only the U (Cb) samples,
+ * and the third plane contains only the V (Cr) sample.
+ */
+ PJMEDIA_FORMAT_I422 = PJMEDIA_FORMAT_PACK('I', '4', '2', '2'),
+
+ /**
+ * The JPEG version of planar 4:2:0/12bpp YUV format.
+ */
+ PJMEDIA_FORMAT_I420JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '0'),
+
+ /**
+ * The JPEG version of planar 4:2:2/16bpp YUV format.
+ */
+ PJMEDIA_FORMAT_I422JPEG = PJMEDIA_FORMAT_PACK('J', '4', '2', '2'),
+
+ /**
+ * Encoded video formats
+ */
+
+ PJMEDIA_FORMAT_H261 = PJMEDIA_FORMAT_PACK('H', '2', '6', '1'),
+ PJMEDIA_FORMAT_H263 = PJMEDIA_FORMAT_PACK('H', '2', '6', '3'),
+ PJMEDIA_FORMAT_H263P = PJMEDIA_FORMAT_PACK('P', '2', '6', '3'),
+ PJMEDIA_FORMAT_H264 = PJMEDIA_FORMAT_PACK('H', '2', '6', '4'),
+
+ PJMEDIA_FORMAT_MJPEG = PJMEDIA_FORMAT_PACK('M', 'J', 'P', 'G'),
+ PJMEDIA_FORMAT_MPEG1VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '1', 'V'),
+ PJMEDIA_FORMAT_MPEG2VIDEO = PJMEDIA_FORMAT_PACK('M', 'P', '2', 'V'),
+ PJMEDIA_FORMAT_MPEG4 = PJMEDIA_FORMAT_PACK('M', 'P', 'G', '4'),
+
+} pjmedia_format_id;
+
+/**
+ * This enumeration specifies what type of detail is included in a
+ * #pjmedia_format structure.
+ */
+typedef enum pjmedia_format_detail_type
+{
+ /** Format detail is not specified. */
+ PJMEDIA_FORMAT_DETAIL_NONE,
+
+ /** Audio format detail. */
+ PJMEDIA_FORMAT_DETAIL_AUDIO,
+
+ /** Video format detail. */
+ PJMEDIA_FORMAT_DETAIL_VIDEO,
+
+ /** Number of format detail type that has been defined. */
+ PJMEDIA_FORMAT_DETAIL_MAX
+
+} pjmedia_format_detail_type;
+
+/**
+ * This structure is put in \a detail field of #pjmedia_format to describe
+ * detail information about an audio media.
+ */
+typedef struct pjmedia_audio_format_detail
+{
+ unsigned clock_rate; /**< Audio clock rate in samples or Hz. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned frame_time_usec;/**< Frame interval, in microseconds. */
+ unsigned bits_per_sample;/**< Number of bits per sample. */
+ pj_uint32_t avg_bps; /**< Average bitrate */
+ pj_uint32_t max_bps; /**< Maximum bitrate */
+} pjmedia_audio_format_detail;
+
+/**
+ * This structure is put in \a detail field of #pjmedia_format to describe
+ * detail information about a video media.
+ *
+ * Additional information about a video format can also be retrieved by
+ * calling #pjmedia_get_video_format_info().
+ */
+typedef struct pjmedia_video_format_detail
+{
+ pjmedia_rect_size size; /**< Video size (width, height) */
+ pjmedia_ratio fps; /**< Number of frames per second. */
+ pj_uint32_t avg_bps;/**< Average bitrate. */
+ pj_uint32_t max_bps;/**< Maximum bitrate. */
+} pjmedia_video_format_detail;
+
+/**
+ * This macro declares the size of the detail section in #pjmedia_format
+ * to be reserved for user defined detail.
+ */
+#ifndef PJMEDIA_FORMAT_DETAIL_USER_SIZE
+# define PJMEDIA_FORMAT_DETAIL_USER_SIZE 1
+#endif
+
+/**
+ * This structure contains all the information needed to completely describe
+ * a media.
+ */
+typedef struct pjmedia_format
+{
+ /**
+ * The format id that specifies the audio sample or video pixel format.
+ * Some well known formats ids are declared in pjmedia_format_id
+ * enumeration.
+ *
+ * @see pjmedia_format_id
+ */
+ pj_uint32_t id;
+
+ /**
+ * The top-most type of the media, as an information.
+ */
+ pjmedia_type type;
+
+ /**
+ * The type of detail structure in the \a detail pointer.
+ */
+ pjmedia_format_detail_type detail_type;
+
+ /**
+ * Detail section to describe the media.
+ */
+ union
+ {
+ /**
+ * Detail section for audio format.
+ */
+ pjmedia_audio_format_detail aud;
+
+ /**
+ * Detail section for video format.
+ */
+ pjmedia_video_format_detail vid;
+
+ /**
+ * Reserved area for user-defined format detail.
+ */
+ char user[PJMEDIA_FORMAT_DETAIL_USER_SIZE];
+ } det;
+
+} pjmedia_format;
+
+/**
+ * This enumeration describes video color model. It mostly serves as
+ * information only.
+ */
+typedef enum pjmedia_color_model
+{
+ /** The color model is unknown or unspecified. */
+ PJMEDIA_COLOR_MODEL_NONE,
+
+ /** RGB color model. */
+ PJMEDIA_COLOR_MODEL_RGB,
+
+ /** YUV color model. */
+ PJMEDIA_COLOR_MODEL_YUV
+} pjmedia_color_model;
+
+/**
+ * This structure holds information to apply a specific video format
+ * against size and buffer information, and get additional information
+ * from it. To do that, application fills up the input fields of this
+ * structure, and give this structure to \a apply_fmt() function
+ * of #pjmedia_video_format_info structure.
+ */
+typedef struct pjmedia_video_apply_fmt_param
+{
+ /* input fields: */
+
+ /**
+ * [IN] The image size. This field is mandatory, and has to be set
+ * correctly prior to calling \a apply_fmt() function.
+ */
+ pjmedia_rect_size size;
+
+ /**
+ * [IN] Pointer to the buffer that holds the frame. The \a apply_fmt()
+ * function uses this pointer to calculate the pointer for each video
+ * planes of the media. This field is optional -- however, the
+ * \a apply_fmt() would still fill up the \a planes[] array with the
+ * correct pointer even though the buffer is set to NULL. This could be
+ * useful to calculate the size (in bytes) of each plane.
+ */
+ pj_uint8_t *buffer;
+
+ /* output fields: */
+
+ /**
+ * [OUT] The size (in bytes) required of the buffer to hold the video
+ * frame of the particular frame size (width, height).
+ */
+ pj_size_t framebytes;
+
+ /**
+ * [OUT] Array of strides value (in bytes) for each video plane.
+ */
+ int strides[PJMEDIA_MAX_VIDEO_PLANES];
+
+ /**
+ * [OUT] Array of pointers to each of the video planes. The values are
+ * calculated from the \a buffer field.
+ */
+ pj_uint8_t *planes[PJMEDIA_MAX_VIDEO_PLANES];
+
+ /**
+ * [OUT] Array of video plane sizes.
+ */
+ pj_size_t plane_bytes[PJMEDIA_MAX_VIDEO_PLANES];
+
+} pjmedia_video_apply_fmt_param;
+
+/**
+ * This structure holds information to describe a video format. Application
+ * can retrieve this structure by calling #pjmedia_get_video_format_info()
+ * funcion.
+ */
+typedef struct pjmedia_video_format_info
+{
+ /**
+ * The unique format ID of the media. Well known format ids are declared
+ * in pjmedia_format_id enumeration.
+ */
+ pj_uint32_t id;
+
+ /**
+ * Null terminated string containing short identification about the
+ * format.
+ */
+ char name[8];
+
+ /**
+ * Information about the color model of this video format.
+ */
+ pjmedia_color_model color_model;
+
+ /**
+ * Number of bits needed to store one pixel of this video format.
+ */
+ pj_uint8_t bpp;
+
+ /**
+ * Number of video planes that this format uses. Value 1 indicates
+ * packed format, while value greater than 1 indicates planar format.
+ */
+ pj_uint8_t plane_cnt;
+
+ /**
+ * Pointer to function to apply this format against size and buffer
+ * information in pjmedia_video_apply_fmt_param argument. Application
+ * uses this function to obtain various information such as the
+ * memory size of a frame buffer, strides value of the image, the
+ * location of the planes, and so on. See pjmedia_video_apply_fmt_param
+ * for additional information.
+ *
+ * @param vfi The video format info.
+ * @param vafp The parameters to investigate.
+ *
+ * @return PJ_SUCCESS if the function has calculated the
+ * information in \a vafp successfully.
+ */
+ pj_status_t (*apply_fmt)(const struct pjmedia_video_format_info *vfi,
+ pjmedia_video_apply_fmt_param *vafp);
+
+} pjmedia_video_format_info;
+
+
+/*****************************************************************************
+ * UTILITIES:
+ */
+
+/**
+ * General utility routine to calculate samples per frame value from clock
+ * rate, ptime (in usec), and channel count. Application should use this
+ * macro whenever possible due to possible overflow in the math calculation.
+ *
+ * @param clock_rate Clock rate.
+ * @param usec_ptime Frame interval, in microsecond.
+ * @param channel_count Number of channels.
+ *
+ * @return The samples per frame value.
+ */
+PJ_INLINE(unsigned) PJMEDIA_SPF(unsigned clock_rate, unsigned usec_ptime,
+ unsigned channel_count)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)usec_ptime * \
+ clock_rate * channel_count / 1000000));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0*usec_ptime * clock_rate * channel_count / 1000000));
+#else
+ return ((unsigned)(usec_ptime / 1000L * clock_rate * \
+ channel_count / 1000));
+#endif
+}
+
+/**
+ * Variant of #PJMEDIA_SPF() which takes frame rate instead of ptime.
+ */
+PJ_INLINE(unsigned) PJMEDIA_SPF2(unsigned clock_rate, const pjmedia_ratio *fr,
+ unsigned channel_count)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)clock_rate * fr->denum \
+ / fr->num / channel_count));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0* clock_rate * fr->denum / fr->num /channel_count));
+#else
+ return ((unsigned)(1L * clock_rate * fr->denum / fr->num / channel_count));
+#endif
+}
+
+
+/**
+ * Utility routine to calculate frame size (in bytes) from bitrate and frame
+ * interval values. Application should use this macro whenever possible due
+ * to possible overflow in the math calculation.
+ *
+ * @param bps The bitrate of the stream.
+ * @param usec_ptime Frame interval, in microsecond.
+ *
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_FSZ(unsigned bps, unsigned usec_ptime)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)bps * usec_ptime / PJ_UINT64(8000000)));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1.0 * bps * usec_ptime / 8000000.0));
+#else
+ return ((unsigned)(bps / 8L * usec_ptime / 1000000));
+#endif
+}
+
+/**
+ * General utility routine to calculate ptime value from frame rate.
+ * Application should use this macro whenever possible due to possible
+ * overflow in the math calculation.
+ *
+ * @param frame_rate Frame rate
+ *
+ * @return The ptime value (in usec).
+ */
+PJ_INLINE(unsigned) PJMEDIA_PTIME(const pjmedia_ratio *frame_rate)
+{
+#if PJ_HAS_INT64
+ return ((unsigned)((pj_uint64_t)1000000 * \
+ frame_rate->denum / frame_rate->num));
+#elif PJ_HAS_FLOATING_POINT
+ return ((unsigned)(1000000.0 * frame_rate->denum / \
+ frame_rate->num));
+#else
+ return ((unsigned)((1000L * frame_rate->denum / \
+ frame_rate->num) * 1000);
+#endif
+}
+
+/**
+ * Utility to retrieve samples_per_frame value from
+ * pjmedia_audio_format_detail.
+ *
+ * @param pafd Pointer to pjmedia_audio_format_detail
+ * @return Samples per frame
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_SPF(const pjmedia_audio_format_detail *pafd)
+{
+ return PJMEDIA_SPF(pafd->clock_rate, pafd->frame_time_usec,
+ pafd->channel_count);
+}
+
+/**
+ * Utility to retrieve average frame size from pjmedia_audio_format_detail.
+ * The average frame size is derived from the average bitrate of the audio
+ * stream.
+ *
+ * @param afd Pointer to pjmedia_audio_format_detail
+ * @return Average frame size.
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_AVG_FSZ(const pjmedia_audio_format_detail *afd)
+{
+ return PJMEDIA_FSZ(afd->avg_bps, afd->frame_time_usec);
+}
+
+/**
+ * Utility to retrieve maximum frame size from pjmedia_audio_format_detail.
+ * The maximum frame size is derived from the maximum bitrate of the audio
+ * stream.
+ *
+ * @param afd Pointer to pjmedia_audio_format_detail
+ * @return Average frame size.
+ */
+PJ_INLINE(unsigned) PJMEDIA_AFD_MAX_FSZ(const pjmedia_audio_format_detail *afd)
+{
+ return PJMEDIA_FSZ(afd->max_bps, afd->frame_time_usec);
+}
+
+
+/**
+ * Initialize the format as audio format with the specified parameters.
+ *
+ * @param fmt The format to be initialized.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param clock_rate Audio clock rate.
+ * @param channel_count Number of channels.
+ * @param bits_per_sample Number of bits per sample.
+ * @param frame_time_usec Frame interval, in microsecond.
+ * @param avg_bps Average bitrate.
+ * @param max_bps Maximum bitrate.
+ */
+PJ_DECL(void) pjmedia_format_init_audio(pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned bits_per_sample,
+ unsigned frame_time_usec,
+ pj_uint32_t avg_bps,
+ pj_uint32_t max_bps);
+
+/**
+ * Initialize the format as video format with the specified parameters.
+ * A format manager should have been created, as this function will need
+ * to consult to a format manager in order to fill in detailed
+ * information about the format.
+ *
+ * @param fmt The format to be initialised.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param width Image width.
+ * @param height Image heigth.
+ * @param fps_num FPS numerator.
+ * @param fps_denum FPS denumerator.
+ * @param avg_bps Average bitrate.
+ * @param max_bps Maximum bitrate.
+ */
+PJ_DECL(void) pjmedia_format_init_video(pjmedia_format *fmt,
+ pj_uint32_t fmt_id,
+ unsigned width,
+ unsigned height,
+ unsigned fps_num,
+ unsigned fps_denum);
+
+/**
+ * Copy format to another.
+ *
+ * @param dst The destination format.
+ * @param src The source format.
+ *
+ * @return Pointer to destination format.
+ */
+PJ_DECL(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,
+ const pjmedia_format *src);
+
+/**
+ * Check if the format contains audio format, and retrieve the audio format
+ * detail in the format.
+ *
+ * @param fmt The format structure.
+ * @param assert_valid If this is set to non-zero, an assertion will be
+ * raised if the detail type is not audio or if the
+ * the detail is NULL.
+ *
+ * @return The instance of audio format detail in the format
+ * structure, or NULL if the format doesn't contain
+ * audio detail.
+ */
+PJ_DECL(pjmedia_audio_format_detail*)
+pjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid);
+
+/**
+ * Check if the format contains video format, and retrieve the video format
+ * detail in the format.
+ *
+ * @param fmt The format structure.
+ * @param assert_valid If this is set to non-zero, an assertion will be
+ * raised if the detail type is not video or if the
+ * the detail is NULL.
+ *
+ * @return The instance of video format detail in the format
+ * structure, or NULL if the format doesn't contain
+ * video detail.
+ */
+PJ_DECL(pjmedia_video_format_detail*)
+pjmedia_format_get_video_format_detail(const pjmedia_format *fmt,
+ pj_bool_t assert_valid);
+
+/*****************************************************************************
+ * FORMAT MANAGEMENT:
+ */
+
+/**
+ * Opaque data type for video format manager. The video format manager manages
+ * the repository of video formats that the framework recognises. Typically it
+ * is a singleton instance, although application may instantiate more than one
+ * instances of this if required.
+ */
+typedef struct pjmedia_video_format_mgr pjmedia_video_format_mgr;
+
+
+/**
+ * Create a new video format manager instance. This will also set the pointer
+ * to the singleton instance if the value is still NULL.
+ *
+ * @param pool The pool to allocate memory.
+ * @param max_fmt Maximum number of formats to accommodate.
+ * @param options Option flags. Must be zero for now.
+ * @param p_mgr Pointer to hold the created instance.
+ *
+ * @return PJ_SUCCESS on success, or the appripriate error value.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_video_format_mgr_create(pj_pool_t *pool,
+ unsigned max_fmt,
+ unsigned options,
+ pjmedia_video_format_mgr **p_mgr);
+
+/**
+ * Get the singleton instance of the video format manager.
+ *
+ * @return The instance.
+ */
+PJ_DECL(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void);
+
+/**
+ * Manually assign a specific video manager instance as the singleton
+ * instance. Normally this is not needed if only one instance is ever
+ * going to be created, as the library automatically assign the singleton
+ * instance.
+ *
+ * @param mgr The instance to be used as the singleton instance.
+ * Application may specify NULL to clear the singleton
+ * singleton instance.
+ */
+PJ_DECL(void)
+pjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr);
+
+/**
+ * Retrieve a video format info for the specified format id.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ * @param id The format id which format info is to be
+ * retrieved.
+ *
+ * @return The video format info.
+ */
+PJ_DECL(const pjmedia_video_format_info*)
+pjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,
+ pj_uint32_t id);
+
+/**
+ * Register a new video format to the framework. By default, built-in
+ * formats will be registered automatically to the format manager when
+ * it is created (note: built-in formats are ones which format id is
+ * listed in pjmedia_format_id enumeration). This function allows
+ * application to use user defined format id by registering that format
+ * into the framework.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ * @param vfi The video format info to be registered. This
+ * structure must remain valid until the format
+ * manager is destroyed.
+ *
+ * @return PJ_SUCCESS on success, or the appripriate error value.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,
+ pjmedia_video_format_info *vfi);
+
+/**
+ * Destroy a video format manager. If the manager happens to be the singleton
+ * instance, the singleton instance will be set to NULL.
+ *
+ * @param mgr The video format manager. Specify NULL to use
+ * the singleton instance (however, a video format
+ * manager still must have been created prior to
+ * calling this function).
+ */
+PJ_DECL(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr);
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_FORMAT_H__ */
+
diff --git a/pjmedia/include/pjmedia/frame.h b/pjmedia/include/pjmedia/frame.h
new file mode 100644
index 0000000..c41f078
--- /dev/null
+++ b/pjmedia/include/pjmedia/frame.h
@@ -0,0 +1,332 @@
+/* $Id: frame.h 3715 2011-08-19 09:35:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_FRAME_H__
+#define __PJMEDIA_FRAME_H__
+
+/**
+ * @file pjmedia/frame.h Media frame
+ * @brief Frame
+ */
+#include <pjmedia/types.h>
+#include <pj/string.h>
+
+/**
+ * @defgroup PJMEDIA_FRAME Media frame
+ * @ingroup PJMEDIA_TYPES
+ * @brief Frame
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Types of media frame.
+ */
+typedef enum pjmedia_frame_type
+{
+ PJMEDIA_FRAME_TYPE_NONE, /**< No frame. */
+ PJMEDIA_FRAME_TYPE_AUDIO, /**< Normal audio frame. */
+ PJMEDIA_FRAME_TYPE_EXTENDED, /**< Extended audio frame. */
+ PJMEDIA_FRAME_TYPE_VIDEO /**< Video frame. */
+
+} pjmedia_frame_type;
+
+
+/**
+ * This structure describes a media frame.
+ */
+typedef struct pjmedia_frame
+{
+ pjmedia_frame_type type; /**< Frame type. */
+ void *buf; /**< Pointer to buffer. */
+ pj_size_t size; /**< Frame size in bytes. */
+ pj_timestamp timestamp; /**< Frame timestamp. */
+ pj_uint32_t bit_info; /**< Bit info of the frame, sample case:
+ a frame may not exactly start and end
+ at the octet boundary, so this field
+ may be used for specifying start &
+ end bit offset. */
+} pjmedia_frame;
+
+
+/**
+ * The pjmedia_frame_ext is used to carry a more complex audio frames than
+ * the typical PCM audio frames, and it is signaled by setting the "type"
+ * field of a pjmedia_frame to PJMEDIA_FRAME_TYPE_EXTENDED. With this set,
+ * application may typecast pjmedia_frame to pjmedia_frame_ext.
+ *
+ * This structure may contain more than one audio frames, which subsequently
+ * will be called subframes in this structure. The subframes section
+ * immediately follows the end of this structure, and each subframe is
+ * represented by pjmedia_frame_ext_subframe structure. Every next
+ * subframe immediately follows the previous subframe, and all subframes
+ * are byte-aligned although its payload may not be byte-aligned.
+ */
+
+#pragma pack(1)
+typedef struct pjmedia_frame_ext {
+ pjmedia_frame base; /**< Base frame info */
+ pj_uint16_t samples_cnt; /**< Number of samples in this frame */
+ pj_uint16_t subframe_cnt; /**< Number of (sub)frames in this frame */
+
+ /* Zero or more (sub)frames follows immediately after this,
+ * each will be represented by pjmedia_frame_ext_subframe
+ */
+} pjmedia_frame_ext;
+#pragma pack()
+
+/**
+ * This structure represents the individual subframes in the
+ * pjmedia_frame_ext structure.
+ */
+#pragma pack(1)
+typedef struct pjmedia_frame_ext_subframe {
+ pj_uint16_t bitlen; /**< Number of bits in the data */
+ pj_uint8_t data[1]; /**< Start of encoded data */
+} pjmedia_frame_ext_subframe;
+
+#pragma pack()
+
+/**
+ * Copy one frame to another. If the destination frame's size is smaller than
+ * the source frame's, the destination buffer will be truncated.
+ *
+ * @param src Source frame.
+ * @param dst Destination frame.
+ */
+PJ_INLINE(void) pjmedia_frame_copy(pjmedia_frame *dst,
+ const pjmedia_frame *src)
+{
+ dst->type = src->type;
+ dst->timestamp = src->timestamp;
+ dst->bit_info = src->bit_info;
+ dst->size = (dst->size < src->size? dst->size: src->size);
+ pj_memcpy(dst->buf, src->buf, dst->size);
+}
+
+/**
+ * Append one subframe to #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param src Subframe data.
+ * @param bitlen Length of subframe, in bits.
+ * @param samples_cnt Number of audio samples in subframe.
+ */
+PJ_INLINE(void) pjmedia_frame_ext_append_subframe(pjmedia_frame_ext *frm,
+ const void *src,
+ unsigned bitlen,
+ unsigned samples_cnt)
+{
+ pjmedia_frame_ext_subframe *fsub;
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < frm->subframe_cnt; ++i) {
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(fsub->bitlen) + ((fsub->bitlen+7) >> 3);
+ }
+
+ fsub = (pjmedia_frame_ext_subframe*) p;
+ fsub->bitlen = (pj_uint16_t)bitlen;
+ if (bitlen)
+ pj_memcpy(fsub->data, src, (bitlen+7) >> 3);
+
+ frm->subframe_cnt++;
+ frm->samples_cnt = (pj_uint16_t)(frm->samples_cnt + samples_cnt);
+}
+
+/**
+ * Get a subframe from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Subframe index, zero based.
+ *
+ * @return The n-th subframe, or NULL if n is out-of-range.
+ */
+PJ_INLINE(pjmedia_frame_ext_subframe*)
+pjmedia_frame_ext_get_subframe(const pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf = NULL;
+
+ if (n < frm->subframe_cnt) {
+ pj_uint8_t *p;
+ unsigned i;
+
+ p = (pj_uint8_t*)frm + sizeof(pjmedia_frame_ext);
+ for (i = 0; i < n; ++i) {
+ sf = (pjmedia_frame_ext_subframe*) p;
+ p += sizeof(sf->bitlen) + ((sf->bitlen+7) >> 3);
+ }
+
+ sf = (pjmedia_frame_ext_subframe*) p;
+ }
+
+ return sf;
+}
+
+/**
+ * Extract all frame payload to the specified buffer.
+ *
+ * @param frm The frame.
+ * @param dst Destination buffer.
+ * @param maxlen Maximum size to copy (i.e. the size of the
+ * destination buffer).
+ *
+ * @return Total size of payload copied.
+ */
+PJ_INLINE(unsigned)
+pjmedia_frame_ext_copy_payload(const pjmedia_frame_ext *frm,
+ void *dst,
+ unsigned maxlen)
+{
+ unsigned i, copied=0;
+ for (i=0; i<frm->subframe_cnt; ++i) {
+ pjmedia_frame_ext_subframe *sf;
+ unsigned sz;
+
+ sf = pjmedia_frame_ext_get_subframe(frm, i);
+ if (!sf)
+ continue;
+
+ sz = ((sf->bitlen + 7) >> 3);
+ if (sz + copied > maxlen)
+ break;
+
+ pj_memcpy(((pj_uint8_t*)dst) + copied, sf->data, sz);
+ copied += sz;
+ }
+ return copied;
+}
+
+
+/**
+ * Pop out first n subframes from #pjmedia_frame_ext.
+ *
+ * @param frm The #pjmedia_frame_ext.
+ * @param n Number of first subframes to be popped out.
+ *
+ * @return PJ_SUCCESS when successful.
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_frame_ext_pop_subframes(pjmedia_frame_ext *frm, unsigned n)
+{
+ pjmedia_frame_ext_subframe *sf;
+ pj_uint8_t *move_src;
+ unsigned move_len;
+
+ if (frm->subframe_cnt <= n) {
+ frm->subframe_cnt = 0;
+ frm->samples_cnt = 0;
+ return PJ_SUCCESS;
+ }
+
+ move_src = (pj_uint8_t*)pjmedia_frame_ext_get_subframe(frm, n);
+ sf = pjmedia_frame_ext_get_subframe(frm, frm->subframe_cnt-1);
+ move_len = (pj_uint8_t*)sf - move_src + sizeof(sf->bitlen) +
+ ((sf->bitlen+7) >> 3);
+ pj_memmove((pj_uint8_t*)frm+sizeof(pjmedia_frame_ext),
+ move_src, move_len);
+
+ frm->samples_cnt = (pj_uint16_t)
+ (frm->samples_cnt - n*frm->samples_cnt/frm->subframe_cnt);
+ frm->subframe_cnt = (pj_uint16_t) (frm->subframe_cnt - n);
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * This is a general purpose function set PCM samples to zero.
+ * Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ *
+ * @param samples The 16bit PCM samples.
+ * @param count Number of samples.
+ */
+PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count)
+{
+#if 1
+ pj_bzero(samples, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) samples[i] = 0;
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i) ((pj_int32_t*)samples)[i] = (pj_int32_t)0;
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memcpy(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+
+/**
+ * This is a general purpose function to copy samples from/to buffers with
+ * equal size. Since this function is needed by many parts of the library,
+ * by putting this functionality in one place, it enables some.
+ * clever people to optimize this function.
+ */
+PJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src,
+ unsigned count)
+{
+#if 1
+ pj_memmove(dst, src, (count<<1));
+#elif 0
+ unsigned i;
+ for (i=0; i<count; ++i) dst[i] = src[i];
+#else
+ unsigned i;
+ count >>= 1;
+ for (i=0; i<count; ++i)
+ ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i];
+#endif
+}
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_FRAME_H__ */
diff --git a/pjmedia/include/pjmedia/g711.h b/pjmedia/include/pjmedia/g711.h
new file mode 100644
index 0000000..e6266f6
--- /dev/null
+++ b/pjmedia/include/pjmedia/g711.h
@@ -0,0 +1,89 @@
+/* $Id: g711.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_G711_H__
+#define __PJMEDIA_G711_H__
+
+/**
+ * @file g711.h
+ * @brief G711 Codec
+ */
+
+#include <pjmedia-codec/types.h>
+
+/**
+ * @defgroup PJMED_G711 G.711 Codec
+ * @ingroup PJMEDIA_CODEC_CODECS
+ * @brief Standard G.711/PCMA and PCMU codec.
+ * @{
+ *
+ * This section describes functions to initialize and register G.711 codec
+ * factory to the codec manager. After the codec factory has been registered,
+ * application can use @ref PJMEDIA_CODEC API to manipulate the codec.
+ *
+ * The G.711 is an ultra low complexity codecs and in trade-off it results
+ * in high bitrate, i.e: 64kbps for 16-bit PCM with sampling rate 8000Hz.
+ *
+ * The factory contains two main compression algorithms, PCMU/u-Law and
+ * PCMA/A-Law.
+ *
+ * \section codec_setting Codec Settings
+ *
+ * \subsection general_setting General Settings
+ *
+ * General codec settings for this codec such as VAD and PLC can be
+ * manipulated through the <tt>setting</tt> field in #pjmedia_codec_param.
+ * Please see the documentation of #pjmedia_codec_param for more info.
+ *
+ * \subsection specific_setting Codec Specific Settings
+ *
+ * Currently none.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Initialize and register G711 codec factory to pjmedia endpoint.
+ * This will register PCMU and PCMA codec, in that order.
+ *
+ * @param endpt The pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g711_init(pjmedia_endpt *endpt);
+
+
+
+/**
+ * Unregister G711 codec factory from pjmedia endpoint.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_codec_g711_deinit(void);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_G711_H__ */
+
diff --git a/pjmedia/include/pjmedia/jbuf.h b/pjmedia/include/pjmedia/jbuf.h
new file mode 100644
index 0000000..488bb33
--- /dev/null
+++ b/pjmedia/include/pjmedia/jbuf.h
@@ -0,0 +1,451 @@
+/* $Id: jbuf.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Based on implementation kindly contributed by Switchlab, Ltd.
+ */
+#ifndef __PJMEDIA_JBUF_H__
+#define __PJMEDIA_JBUF_H__
+
+
+/**
+ * @file jbuf.h
+ * @brief Adaptive jitter buffer implementation.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_JBUF Adaptive jitter buffer
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive de-jitter buffering implementation
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of de-jitter buffer.
+ * The de-jitter buffer may be set to operate in adaptive mode or fixed
+ * delay mode.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Types of frame returned by the jitter buffer.
+ */
+typedef enum pjmedia_jb_frame_type
+{
+ PJMEDIA_JB_MISSING_FRAME = 0, /**< No frame because it's missing */
+ PJMEDIA_JB_NORMAL_FRAME = 1, /**< Normal frame is being returned */
+ PJMEDIA_JB_ZERO_PREFETCH_FRAME = 2, /**< Zero frame is being returned
+ because JB is bufferring. */
+ PJMEDIA_JB_ZERO_EMPTY_FRAME = 3 /**< Zero frame is being returned
+ because JB is empty. */
+} pjmedia_jb_frame_type;
+
+
+/**
+ * Enumeration of jitter buffer discard algorithm. The jitter buffer
+ * continuously calculates the jitter level to get the optimum latency at
+ * any time and in order to adjust the latency, the jitter buffer may need
+ * to discard some frames.
+ */
+typedef enum pjmedia_jb_discard_algo
+{
+ /**
+ * Jitter buffer should not discard any frame, except when the jitter
+ * buffer is full and a new frame arrives, one frame will be discarded
+ * to make space for the new frame.
+ */
+ PJMEDIA_JB_DISCARD_NONE = 0,
+
+ /**
+ * Only discard one frame in at least 200ms when the latency is considered
+ * much higher than it should be. When the jitter buffer is full and a new
+ * frame arrives, one frame will be discarded to make space for the new
+ * frame.
+ */
+ PJMEDIA_JB_DISCARD_STATIC,
+
+ /**
+ * The discard rate is dynamically calculated based on actual parameters
+ * such as jitter level and latency. When the jitter buffer is full and
+ * a new frame arrives, one frame will be discarded to make space for the
+ * new frame.
+ */
+ PJMEDIA_JB_DISCARD_PROGRESSIVE
+
+} pjmedia_jb_discard_algo;
+
+
+/**
+ * This structure describes jitter buffer state.
+ */
+typedef struct pjmedia_jb_state
+{
+ /* Setting */
+ unsigned frame_size; /**< Individual frame size, in bytes. */
+ unsigned min_prefetch; /**< Minimum allowed prefetch, in frms. */
+ unsigned max_prefetch; /**< Maximum allowed prefetch, in frms. */
+
+ /* Status */
+ unsigned burst; /**< Current burst level, in frames */
+ unsigned prefetch; /**< Current prefetch value, in frames */
+ unsigned size; /**< Current buffer size, in frames. */
+
+ /* Statistic */
+ unsigned avg_delay; /**< Average delay, in ms. */
+ unsigned min_delay; /**< Minimum delay, in ms. */
+ unsigned max_delay; /**< Maximum delay, in ms. */
+ unsigned dev_delay; /**< Standard deviation of delay, in ms.*/
+ unsigned avg_burst; /**< Average burst, in frames. */
+ unsigned lost; /**< Number of lost frames. */
+ unsigned discard; /**< Number of discarded frames. */
+ unsigned empty; /**< Number of empty on GET events. */
+} pjmedia_jb_state;
+
+
+/**
+ * The constant PJMEDIA_JB_DEFAULT_INIT_DELAY specifies default jitter
+ * buffer prefetch count during jitter buffer creation.
+ */
+#define PJMEDIA_JB_DEFAULT_INIT_DELAY 15
+
+/**
+ * Opaque declaration for jitter buffer.
+ */
+typedef struct pjmedia_jbuf pjmedia_jbuf;
+
+
+/**
+ * Create an adaptive jitter buffer according to the specification. If
+ * application wants to have a fixed jitter buffer, it may call
+ * #pjmedia_jbuf_set_fixed() after the jitter buffer is created. Also
+ * if application wants to alter the discard algorithm, which the default
+ * PJMEDIA_JB_DISCARD_PROGRESSIVE, it may call #pjmedia_jbuf_set_discard().
+ *
+ * This function may allocate large chunk of memory to keep the frames in
+ * the buffer.
+ *
+ * @param pool The pool to allocate memory.
+ * @param name Name to identify the jitter buffer for logging
+ * purpose.
+ * @param frame_size The size of each frame that will be kept in the
+ * jitter buffer, in bytes. This should correspond
+ * to the minimum frame size supported by the codec.
+ * For example, a 10ms frame (80 bytes) would be
+ * recommended for G.711 codec.
+ * @param max_count Maximum number of frames that can be kept in the
+ * jitter buffer. This effectively means the maximum
+ * delay that may be introduced by this jitter
+ * buffer.
+ * @param ptime Indication of frame duration, used to calculate
+ * the interval between jitter recalculation.
+ * @param p_jb Pointer to receive jitter buffer instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned frame_size,
+ unsigned ptime,
+ unsigned max_count,
+ pjmedia_jbuf **p_jb);
+
+/**
+ * Set the jitter buffer to fixed delay mode. The default behavior
+ * is to adapt the delay with actual packet delay.
+ *
+ * @param jb The jitter buffer
+ * @param prefetch The fixed delay value, in number of frames.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
+ unsigned prefetch);
+
+
+/**
+ * Set the jitter buffer to adaptive mode.
+ *
+ * @param jb The jitter buffer.
+ * @param prefetch The initial prefetch value to be applied to the
+ * jitter buffer. Setting this to other than 0 will
+ * activate prefetch buffering, a jitter buffer feature
+ * that each time it gets empty, it won't return a
+ * normal frame until its size reaches the number
+ * specified here.
+ * @param min_prefetch The minimum delay that must be applied to each
+ * incoming packets, in number of frames.
+ * @param max_prefetch The maximum allowable value for prefetch delay,
+ * in number of frames.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_set_adaptive( pjmedia_jbuf *jb,
+ unsigned prefetch,
+ unsigned min_prefetch,
+ unsigned max_prefetch);
+
+
+/**
+ * Set the jitter buffer discard algorithm. The default discard algorithm,
+ * set in jitter buffer creation, is PJMEDIA_JB_DISCARD_PROGRESSIVE.
+ *
+ * @param jb The jitter buffer.
+ * @param algo The discard algorithm to be used.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_set_discard(pjmedia_jbuf *jb,
+ pjmedia_jb_discard_algo algo);
+
+
+/**
+ * Destroy jitter buffer instance.
+ *
+ * @param jb The jitter buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb);
+
+
+/**
+ * Restart jitter. This function flushes all packets in the buffer and
+ * reset the internal sequence number.
+ *
+ * @param jb The jitter buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_reset(pjmedia_jbuf *jb);
+
+/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param frame_seq The frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ int frame_seq);
+
+/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param frame_seq The frame sequence number.
+ * @param discarded Flag whether the frame is discarded by jitter buffer.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame2( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ pj_uint32_t bit_info,
+ int frame_seq,
+ pj_bool_t *discarded);
+
+/**
+ * Put a frame to the jitter buffer. If the frame can be accepted (based
+ * on the sequence number), the jitter buffer will copy the frame and put
+ * it in the appropriate position in the buffer.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Pointer to frame buffer to be stored in the jitter
+ * buffer.
+ * @param size The frame size.
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param frame_seq The frame sequence number.
+ * @param frame_ts The frame timestamp.
+ * @param discarded Flag whether the frame is discarded by jitter buffer.
+ */
+PJ_DECL(void) pjmedia_jbuf_put_frame3( pjmedia_jbuf *jb,
+ const void *frame,
+ pj_size_t size,
+ pj_uint32_t bit_info,
+ int frame_seq,
+ pj_uint32_t frame_ts,
+ pj_bool_t *discarded);
+/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * Application MUST manage it's own synchronization when multiple threads
+ * are accessing the jitter buffer at the same time.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * Application MUST make sure that the buffer has
+ * appropriate size (i.e. not less than the frame size,
+ * as specified when the jitter buffer was created).
+ * The jitter buffer only copied a frame to this
+ * buffer when the frame type returned by this function
+ * is PJMEDIA_JB_NORMAL_FRAME.
+ * @param p_frm_type Pointer to receive frame type. If jitter buffer is
+ * currently empty or bufferring, the frame type will
+ * be set to PJMEDIA_JB_ZERO_FRAME, and no frame will
+ * be copied. If the jitter buffer detects that frame is
+ * missing with current sequence number, the frame type
+ * will be set to PJMEDIA_JB_MISSING_FRAME, and no
+ * frame will be copied. If there is a frame, the jitter
+ * buffer will copy the frame to the buffer, and frame
+ * type will be set to PJMEDIA_JB_NORMAL_FRAME.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
+ void *frame,
+ char *p_frm_type);
+
+/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
+ void *frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info);
+
+
+/**
+ * Get a frame from the jitter buffer. The jitter buffer will return the
+ * oldest frame from it's buffer, when it is available.
+ *
+ * @param jb The jitter buffer.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param ts Frame timestamp.
+ * @param seq Frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
+ void *frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq);
+
+
+/**
+ * Peek a frame from the jitter buffer. The jitter buffer state will not be
+ * modified.
+ *
+ * @param jb The jitter buffer.
+ * @param offset Offset from the oldest frame to be peeked.
+ * @param frame Buffer to receive the payload from the jitter buffer.
+ * @see pjmedia_jbuf_get_frame().
+ * @param size Pointer to receive frame size.
+ * @param p_frm_type Pointer to receive frame type.
+ * @see pjmedia_jbuf_get_frame().
+ * @param bit_info Bit precise info of the frame, e.g: a frame may not
+ * exactly start and end at the octet boundary, so this
+ * field may be used for specifying start & end bit offset.
+ * @param ts Frame timestamp.
+ * @param seq Frame sequence number.
+ */
+PJ_DECL(void) pjmedia_jbuf_peek_frame(pjmedia_jbuf *jb,
+ unsigned offset,
+ const void **frame,
+ pj_size_t *size,
+ char *p_frm_type,
+ pj_uint32_t *bit_info,
+ pj_uint32_t *ts,
+ int *seq);
+
+
+/**
+ * Remove frames from the jitter buffer.
+ *
+ * @param jb The jitter buffer.
+ * @param frame_cnt Number of frames to be removed.
+ *
+ * @return The number of frame successfully removed.
+ */
+PJ_DECL(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
+ unsigned frame_cnt);
+
+/**
+ * Check if the jitter buffer is full.
+ *
+ * @param jb The jitter buffer.
+ *
+ * @return PJ_TRUE if it is full.
+ */
+PJ_DECL(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb);
+
+
+/**
+ * Get jitter buffer current state/settings.
+ *
+ * @param jb The jitter buffer.
+ * @param state Buffer to receive jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
+ pjmedia_jb_state *state );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_JBUF_H__ */
diff --git a/pjmedia/include/pjmedia/master_port.h b/pjmedia/include/pjmedia/master_port.h
new file mode 100644
index 0000000..4ab89b9
--- /dev/null
+++ b/pjmedia/include/pjmedia/master_port.h
@@ -0,0 +1,199 @@
+/* $Id: master_port.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_MASTER_PORT_H__
+#define __PJMEDIA_MASTER_PORT_H__
+
+
+/**
+ * @file master_port.h
+ * @brief Master port.
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_MASTER_PORT Master Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Thread based media clock provider
+ * @{
+ *
+ * A master port has two media ports connected to it, and by convention
+ * thay are called downstream and upstream ports. The media stream flowing to
+ * the downstream port is called encoding or send direction, and media stream
+ * flowing to the upstream port is called decoding or receive direction
+ * (imagine the downstream as stream to remote endpoint, and upstream as
+ * local media port; media flowing to remote endpoint (downstream) will need
+ * to be encoded before it is transmitted to remote endpoint).
+ *
+ * A master port internally has an instance of @ref PJMEDIA_CLOCK, which
+ * provides the essensial timing for the master port. The @ref PJMEDIA_CLOCK
+ * runs asynchronously, and whenever a clock <b>tick</b> expires, a callback
+ * will be called, and the master port performs the following tasks:
+ * - it calls <b><tt>get_frame()</tt></b> from the downstream port,
+ * when give the frame to the upstream port by calling <b><tt>put_frame
+ * </tt></b> to the upstream port, and
+ * - performs the same task, but on the reverse direction (i.e. get the stream
+ * from upstream port and give it to the downstream port).
+ *
+ * Because master port enables media stream to flow automatically, it is
+ * said that the master port supplies @ref PJMEDIA_PORT_CLOCK to the
+ * media ports interconnection.
+ *
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for master port.
+ */
+typedef struct pjmedia_master_port pjmedia_master_port;
+
+
+/**
+ * Create a master port.
+ *
+ * @param pool Pool to allocate master port from.
+ * @param u_port Upstream port.
+ * @param d_port Downstream port.
+ * @param options Options flags, from bitmask combinations from
+ * pjmedia_clock_options.
+ * @param p_m Pointer to receive the master port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_create(pj_pool_t *pool,
+ pjmedia_port *u_port,
+ pjmedia_port *d_port,
+ unsigned options,
+ pjmedia_master_port **p_m);
+
+
+/**
+ * Start the media flow.
+ *
+ * @param m The master port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_start(pjmedia_master_port *m);
+
+
+/**
+ * Stop the media flow.
+ *
+ * @param m The master port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_stop(pjmedia_master_port *m);
+
+
+/**
+ * Poll the master port clock and execute the callback when the clock tick has
+ * elapsed. This operation is only valid if the master port is created with
+ * #PJMEDIA_CLOCK_NO_ASYNC flag.
+ *
+ * @param m The master port.
+ * @param wait If non-zero, then the function will block until
+ * a clock tick elapsed and callback has been called.
+ * @param ts Optional argument to receive the current
+ * timestamp.
+ *
+ * @return Non-zero if clock tick has elapsed, or FALSE if
+ * the function returns before a clock tick has
+ * elapsed.
+ */
+PJ_DECL(pj_bool_t) pjmedia_master_port_wait(pjmedia_master_port *m,
+ pj_bool_t wait,
+ pj_timestamp *ts);
+
+
+/**
+ * Change the upstream port. Note that application is responsible to destroy
+ * current upstream port (the one that is going to be replaced with the
+ * new port).
+ *
+ * @param m The master port.
+ * @param port Port to be used for upstream port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_set_uport(pjmedia_master_port *m,
+ pjmedia_port *port);
+
+
+/**
+ * Get the upstream port.
+ *
+ * @param m The master port.
+ *
+ * @return The upstream port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_master_port_get_uport(pjmedia_master_port*m);
+
+
+/**
+ * Change the downstream port. Note that application is responsible to destroy
+ * current downstream port (the one that is going to be replaced with the
+ * new port).
+ *
+ * @param m The master port.
+ * @param port Port to be used for downstream port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_set_dport(pjmedia_master_port *m,
+ pjmedia_port *port);
+
+
+/**
+ * Get the downstream port.
+ *
+ * @param m The master port.
+ *
+ * @return The downstream port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_master_port_get_dport(pjmedia_master_port*m);
+
+
+/**
+ * Destroy the master port, and optionally destroy the upstream and
+ * downstream ports.
+ *
+ * @param m The master port.
+ * @param destroy_ports If non-zero, the function will destroy both
+ * upstream and downstream ports too.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_master_port_destroy(pjmedia_master_port *m,
+ pj_bool_t destroy_ports);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_MASTER_PORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/mem_port.h b/pjmedia/include/pjmedia/mem_port.h
new file mode 100644
index 0000000..bb45504
--- /dev/null
+++ b/pjmedia/include/pjmedia/mem_port.h
@@ -0,0 +1,195 @@
+/* $Id: mem_port.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_MEM_PORT_H__
+#define __PJMEDIA_MEM_PORT_H__
+
+/**
+ * @file mem_port.h
+ * @brief Memory based media playback/capture port
+ */
+#include <pjmedia/port.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_MEM_PLAYER Memory/Buffer-based Playback Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Media playback from a fixed size memory buffer
+ * @{
+ *
+ * A memory/buffer based playback port is used to play media from a fixed
+ * size buffer. This is useful over @ref PJMEDIA_FILE_PLAY for
+ * situation where filesystems are not available in the target system.
+ */
+
+
+/**
+ * Memory player options.
+ */
+enum pjmedia_mem_player_option
+{
+ /**
+ * Tell the memory player to return NULL frame when the whole
+ * buffer has been played instead of rewinding the buffer back
+ * to start position.
+ */
+ PJMEDIA_MEM_NO_LOOP = 1
+};
+
+
+/**
+ * Create the buffer based playback to play the media from the specified
+ * buffer.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param buffer The buffer to play the media from, which should
+ * be available throughout the life time of the port.
+ * The player plays the media directly from this
+ * buffer (i.e. no copying is done).
+ * @param size The size of the buffer, in bytes.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Option flags, see #pjmedia_mem_player_option
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_mem_player_create(pj_pool_t *pool,
+ const void *buffer,
+ pj_size_t size,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+/**
+ * Register a callback to be called when the buffer reading has reached the
+ * end of buffer. If the player is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each player port.
+ *
+ * @param port The memory player port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the player port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_MEM_CAPTURE Memory/Buffer-based Capture Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Media capture to fixed size memory buffer
+ * @{
+ *
+ * A memory based capture is used to save media streams to a fixed size
+ * buffer. This is useful over @ref PJMEDIA_FILE_REC for
+ * situation where filesystems are not available in the target system.
+ */
+
+/**
+ * Create media port to capture/record media into a fixed size buffer.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param buffer The buffer to record the media to, which should
+ * be available throughout the life time of the port.
+ * @param size The maximum size of the buffer, in bytes.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param options Option flags.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_mem_capture_create(pj_pool_t *pool,
+ void *buffer,
+ pj_size_t size,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Register a callback to be called when no space left in the buffer.
+ * Note that when a callback is registered, this callback will also be
+ * called when application destroys the port and the callback has not
+ * been called before.
+ *
+ * @param port The memory recorder port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the recording will stop. In other cases
+ * recording will be restarted and the rest of the frame
+ * will be stored starting from the beginning of the
+ * buffer. Note that if application destroys the capture
+ * port in the callback, it must return non-PJ_SUCCESS
+ * here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_mem_capture_set_eof_cb(pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+/**
+ * Return the current size of the recorded data in the buffer.
+ *
+ * @param port The memory recorder port.
+ * @return The size of buffer data..
+ */
+PJ_DECL(pj_size_t)
+pjmedia_mem_capture_get_size(pjmedia_port *port);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_MEM_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/null_port.h b/pjmedia/include/pjmedia/null_port.h
new file mode 100644
index 0000000..abff44a
--- /dev/null
+++ b/pjmedia/include/pjmedia/null_port.h
@@ -0,0 +1,70 @@
+/* $Id: null_port.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_NULL_PORT_H__
+#define __PJMEDIA_NULL_PORT_H__
+
+/**
+ * @file null_port.h
+ * @brief Null media port.
+ */
+#include <pjmedia/port.h>
+
+
+
+/**
+ * @defgroup PJMEDIA_NULL_PORT Null Port
+ * @ingroup PJMEDIA_PORT
+ * @brief The simplest type of media port which does nothing.
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create Null port.
+ *
+ * @param pool Pool to allocate memory.
+ * @param sampling_rate Sampling rate of the port.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_null_port_create( pj_pool_t *pool,
+ unsigned sampling_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_port **p_port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_NULL_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/plc.h b/pjmedia/include/pjmedia/plc.h
new file mode 100644
index 0000000..fc417fd
--- /dev/null
+++ b/pjmedia/include/pjmedia/plc.h
@@ -0,0 +1,115 @@
+/* $Id: plc.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_PLC_H__
+#define __PJMEDIA_PLC_H__
+
+
+/**
+ * @file plc.h
+ * @brief Packet Lost Concealment (PLC) API.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_PLC Packet Lost Concealment (PLC)
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Packet lost compensation algorithm
+ * @{
+ *
+ * This section describes PJMEDIA's implementation of Packet Lost
+ * Concealment algorithm. This algorithm is used to implement PLC for
+ * codecs that do not have built-in support for one (e.g. G.711 or GSM
+ * codecs).
+ *
+ * The PLC algorithm (either built-in or external) is embedded in
+ * PJMEDIA codec instance, and application can conceal lost frames
+ * by calling <b><tt>recover()</tt></b> member of the codec's member
+ * operation (#pjmedia_codec_op).
+ *
+ * See also @ref plc_codec for more info.
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for PLC.
+ */
+typedef struct pjmedia_plc pjmedia_plc;
+
+
+
+/**
+ * Create PLC session. This function will select the PLC algorithm to
+ * use based on the arguments.
+ *
+ * @param pool Pool to allocate memory for the PLC.
+ * @param clock_rate Media sampling rate.
+ * @param samples_per_frame Number of samples per frame.
+ * @param options Must be zero for now.
+ * @param p_plc Pointer to receive the PLC instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned options,
+ pjmedia_plc **p_plc);
+
+
+/**
+ * Save a good frame to PLC.
+ *
+ * @param plc The PLC session.
+ * @param frame The good frame to be stored to PLC. This frame
+ * must have the same length as the configured
+ * samples per frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_save( pjmedia_plc *plc,
+ pj_int16_t *frame );
+
+
+/**
+ * Generate a replacement for lost frame.
+ *
+ * @param plc The PLC session.
+ * @param frame Buffer to receive the generated frame. This buffer
+ * must be able to store the frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_plc_generate( pjmedia_plc *plc,
+ pj_int16_t *frame );
+
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_PLC_H__ */
+
diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h
new file mode 100644
index 0000000..0a5ab7f
--- /dev/null
+++ b/pjmedia/include/pjmedia/port.h
@@ -0,0 +1,499 @@
+/* $Id: port.h 3893 2011-12-01 10:49:07Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_PORT_H__
+#define __PJMEDIA_PORT_H__
+
+/**
+ * @file port.h
+ * @brief Port interface declaration
+ */
+#include <pjmedia/clock.h>
+#include <pjmedia/event.h>
+#include <pjmedia/format.h>
+#include <pjmedia/frame.h>
+#include <pjmedia/signatures.h>
+#include <pj/assert.h>
+#include <pj/os.h>
+
+
+/**
+ @addtogroup PJMEDIA_PORT Media Ports Framework
+ @{
+
+ @section media_port_intro Media Port Concepts
+
+ @subsection The Media Port
+ A media port (represented with pjmedia_port "class") provides a generic
+ and extensible framework for implementing media elements. Media element
+ itself could be a media source, sink, or processing element. 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.),
+ - optional pointer to function to acquire frames from the port (the
+ <tt>get_frame() </tt> interface), which will be called by
+ #pjmedia_port_get_frame() public API, and
+ - optional pointer to function to store frames to the port (the
+ <tt>put_frame()</tt> interface) which will be called by
+ #pjmedia_port_put_frame() public API.
+
+ The <tt>get_frame()</tt> and <tt>put_frame()</tt> interface of course
+ would only need to be implemented if the media port emits and/or takes
+ media frames respectively.
+
+ Media ports are passive "objects". By default, there is no worker thread
+ to run the media flow. Applications (or other PJMEDIA
+ components, as explained in @ref PJMEDIA_PORT_CLOCK) must actively call
+ #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 @ref PJMEDIA_CONF and @ref PJMEDIA_RESAMPLE_PORT)
+ may be interconnected with (or encapsulate) other port, to perform the
+ combined task of the ports, while some
+ others represent the ultimate source/sink termination for the media.
+ Interconnection means the upstream media port will call <tt>get_frame()</tt>
+ and <tt>put_frame()</tt> to its downstream media port. For this to happen,
+ the media ports need to have the same format, where format is defined as
+ combination of sample format, clock rate, channel count, bits per sample,
+ and samples per frame for audio media.
+
+
+ @subsection port_clock_ex1 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:
+
+ \image html sample-manual-resampling.jpg
+
+ Application would setup the media ports using the following pseudo-
+ code:
+
+ \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);
+
+ \endcode
+
+
+ After the ports have been set up, application can perform the conversion
+ process by running this loop:
+
+ \code
+
+ 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;
+ }
+ }
+
+ \endcode
+
+ For the sake of completeness, after the resampling process is done,
+ application would need to destroy the ports:
+
+ \code
+ // Note: by default, destroying resample port will destroy the
+ // the downstream port too.
+ pjmedia_port_destroy(resample);
+ pjmedia_port_destroy(writer);
+ \endcode
+
+
+ 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
+ @ref PJMEDIA_PORT_CLOCK section.
+
+
+ @subsection media_port_autom Automating Media Flow
+
+ PJMEDIA provides few mechanisms to make media flows automatically
+ among media ports. This concept is described in @ref PJMEDIA_PORT_CLOCK
+ section.
+*/
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create 32bit port signature from ASCII characters.
+ */
+#define PJMEDIA_PORT_SIG(a,b,c,d) PJMEDIA_OBJ_SIG(a,b,c,d)
+
+
+/**
+ * Port operation setting.
+ */
+typedef enum pjmedia_port_op
+{
+ /**
+ * No change to the port TX or RX settings.
+ */
+ PJMEDIA_PORT_NO_CHANGE,
+
+ /**
+ * TX or RX is disabled from the port. It means get_frame() or
+ * put_frame() WILL NOT be called for this port.
+ */
+ PJMEDIA_PORT_DISABLE,
+
+ /**
+ * 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_MUTE,
+
+ /**
+ * Enable TX and RX to/from this port.
+ */
+ PJMEDIA_PORT_ENABLE
+
+} pjmedia_port_op;
+
+
+/**
+ * Port info.
+ */
+typedef struct pjmedia_port_info
+{
+ pj_str_t name; /**< Port name. */
+ pj_uint32_t signature; /**< Port signature. */
+ pjmedia_dir dir; /**< Port direction. */
+ pjmedia_format fmt; /**< Format. */
+} pjmedia_port_info;
+
+/**
+ * Utility to retrieve audio clock rate/sampling rate value from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Audio clock rate.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.clock_rate;
+}
+
+/**
+ * Utility to retrieve audio channel count value from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Audio channel count.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.channel_count;
+}
+
+/**
+ * Utility to retrieve audio bits per sample value from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Number of bits per sample.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_BITS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.bits_per_sample;
+}
+
+/**
+ * Utility to retrieve audio frame interval (ptime) value from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame interval in msec.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_PTIME(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.frame_time_usec / 1000;
+}
+
+/**
+ * This is a utility routine to retrieve the audio samples_per_frame value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Samples per frame value.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_SPF(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_SPF(&pia->fmt.det.aud);
+}
+
+/**
+ * This is a utility routine to retrieve the average bitrate value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Bitrate, in bits per second.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_BPS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.avg_bps;
+}
+
+/**
+ * This is a utility routine to retrieve the maximum bitrate value
+ * from port info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Bitrate, in bits per second.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_BPS(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return pia->fmt.det.aud.max_bps;
+}
+
+/**
+ * This is a utility routine to retrieve the average audio frame size value
+ * from pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_AVG_FSZ(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_AVG_FSZ(&pia->fmt.det.aud);
+}
+
+/**
+ * Utility to retrieve audio frame size from maximum bitrate from
+ * pjmedia_port_info.
+ *
+ * @param pia Pointer to port info containing audio format.
+ * @return Frame size in bytes.
+ */
+PJ_INLINE(unsigned) PJMEDIA_PIA_MAX_FSZ(const pjmedia_port_info *pia)
+{
+ pj_assert(pia->fmt.type==PJMEDIA_TYPE_AUDIO &&
+ pia->fmt.detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO);
+ return PJMEDIA_AFD_MAX_FSZ(&pia->fmt.det.aud);
+}
+
+/**
+ * Port interface.
+ */
+typedef struct pjmedia_port
+{
+ pjmedia_port_info info; /**< Port information. */
+
+ /** Port data can be used by the port creator to attach arbitrary
+ * value to be associated with the port.
+ */
+ struct port_data {
+ void *pdata; /**< Pointer data. */
+ long ldata; /**< Long data. */
+ } port_data;
+
+ /**
+ * Get clock source.
+ * This should only be called by #pjmedia_port_get_clock_src().
+ */
+ pjmedia_clock_src* (*get_clock_src)(struct pjmedia_port *this_port,
+ pjmedia_dir dir);
+
+ /**
+ * Sink interface.
+ * This should only be called by #pjmedia_port_put_frame().
+ */
+ pj_status_t (*put_frame)(struct pjmedia_port *this_port,
+ pjmedia_frame *frame);
+
+ /**
+ * Source interface.
+ * This should only be called by #pjmedia_port_get_frame().
+ */
+ pj_status_t (*get_frame)(struct pjmedia_port *this_port,
+ pjmedia_frame *frame);
+
+ /**
+ * Called to destroy this port.
+ */
+ pj_status_t (*on_destroy)(struct pjmedia_port *this_port);
+
+} pjmedia_port;
+
+
+/**
+ * This is an auxiliary function to initialize port info for
+ * ports which deal with PCM audio.
+ *
+ * @param info The port info to be initialized.
+ * @param name Port name.
+ * @param signature Port signature.
+ * @param clock_rate Port's clock rate.
+ * @param channel_count Number of channels.
+ * @param bits_per_sample Bits per sample.
+ * @param samples_per_frame Number of samples per frame.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(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.
+ *
+ * @param info The port info to be initialized.
+ * @param name Port name.
+ * @param signature Port signature.
+ * @param dir Port's direction.
+ * @param fmt Port's media format.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_info_init2(pjmedia_port_info *info,
+ const pj_str_t *name,
+ unsigned signature,
+ pjmedia_dir dir,
+ const pjmedia_format *fmt);
+
+
+/**
+ * Get a clock source from the port.
+ *
+ * @param port The media port.
+ * @param dir Media port's direction.
+ *
+ * @return The clock source or NULL if clock source is not present
+ * in the port.
+ */
+PJ_DECL(pjmedia_clock_src *) pjmedia_port_get_clock_src( pjmedia_port *port,
+ pjmedia_dir dir );
+
+
+/**
+ * Get a frame from the port (and subsequent downstream ports).
+ *
+ * @param port The media port.
+ * @param frame Frame to store samples.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_get_frame( pjmedia_port *port,
+ pjmedia_frame *frame );
+
+/**
+ * Put a frame to the port (and subsequent downstream ports).
+ *
+ * @param port The media port.
+ * @param frame Frame to the put to the port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_put_frame( pjmedia_port *port,
+ pjmedia_frame *frame );
+
+/**
+ * Destroy port (and subsequent downstream ports)
+ *
+ * @param port The media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_port_destroy( pjmedia_port *port );
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_PORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/resample.h b/pjmedia/include/pjmedia/resample.h
new file mode 100644
index 0000000..7cdd111
--- /dev/null
+++ b/pjmedia/include/pjmedia/resample.h
@@ -0,0 +1,200 @@
+/* $Id: resample.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_RESAMPLE_H__
+#define __PJMEDIA_RESAMPLE_H__
+
+
+
+/**
+ * @file resample.h
+ * @brief Sample rate converter.
+ */
+#include <pjmedia/types.h>
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_RESAMPLE Resampling Algorithm
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Sample rate conversion algorithm
+ * @{
+ *
+ * This section describes the base resampling functions. In addition to this,
+ * application can use the @ref PJMEDIA_RESAMPLE_PORT which provides
+ * media port abstraction for the base resampling algorithm.
+ */
+
+PJ_BEGIN_DECL
+
+/*
+ * This file declares two types of API:
+ *
+ * Application can use #pjmedia_resample_create() and #pjmedia_resample_run()
+ * to convert a frame from source rate to destination rate. The inpuit frame
+ * must have a constant length.
+ *
+ * Alternatively, application can create a resampling port with
+ * #pjmedia_resample_port_create() and connect the port to other ports to
+ * change the sampling rate of the samples.
+ */
+
+
+/**
+ * Opaque resample session.
+ */
+typedef struct pjmedia_resample pjmedia_resample;
+
+/**
+ * Create a frame based resample session.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param high_quality If true, then high quality conversion will be
+ * used, at the expense of more CPU and memory,
+ * because temporary buffer needs to be created.
+ * @param large_filter If true, large filter size will be used.
+ * @param channel_count Number of channels.
+ * @param rate_in Clock rate of the input samples.
+ * @param rate_out Clock rate of the output samples.
+ * @param samples_per_frame Number of samples per frame in the input.
+ * @param p_resample Pointer to receive the resample session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_resample_create(pj_pool_t *pool,
+ pj_bool_t high_quality,
+ pj_bool_t large_filter,
+ unsigned channel_count,
+ unsigned rate_in,
+ unsigned rate_out,
+ unsigned samples_per_frame,
+ pjmedia_resample **p_resample);
+
+
+/**
+ * Use the resample session to resample a frame. The frame must have the
+ * same size and settings as the resample session, or otherwise the
+ * behavior is undefined.
+ *
+ * @param resample The resample session.
+ * @param input Buffer containing the input samples.
+ * @param output Buffer to store the output samples.
+ */
+PJ_DECL(void) pjmedia_resample_run( pjmedia_resample *resample,
+ const pj_int16_t *input,
+ pj_int16_t *output );
+
+
+/**
+ * Get the input frame size of a resample session.
+ *
+ * @param resample The resample session.
+ *
+ * @return The frame size, in number of samples.
+ */
+PJ_DECL(unsigned) pjmedia_resample_get_input_size(pjmedia_resample *resample);
+
+
+/**
+ * Destroy the resample.
+ *
+ * @param resample The resample session.
+ */
+PJ_DECL(void) pjmedia_resample_destroy(pjmedia_resample *resample);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_RESAMPLE_PORT Resample Port
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio sample rate conversion
+ * @{
+ *
+ * This section describes media port abstraction for @ref PJMEDIA_RESAMPLE.
+ */
+
+
+/**
+ * Option flags that can be specified when creating resample port.
+ */
+enum pjmedia_resample_port_options
+{
+ /**
+ * Do not use high quality resampling algorithm, but use linear
+ * algorithm instead.
+ */
+ PJMEDIA_RESAMPLE_USE_LINEAR = 1,
+
+ /**
+ * Use small filter workspace when high quality resampling is
+ * used.
+ */
+ PJMEDIA_RESAMPLE_USE_SMALL_FILTER = 2,
+
+ /**
+ * Do not destroy downstream port when resample port is destroyed.
+ */
+ PJMEDIA_RESAMPLE_DONT_DESTROY_DN = 4
+};
+
+
+
+/**
+ * Create a resample port. This creates a bidirectional resample session,
+ * which will resample frames when the port's get_frame() and put_frame()
+ * is called.
+ *
+ * When the resample port's get_frame() is called, this port will get
+ * a frame from the downstream port and resample the frame to the target
+ * clock rate before returning it to the caller.
+ *
+ * When the resample port's put_frame() is called, this port will resample
+ * the frame to the downstream port's clock rate before giving the frame
+ * to the downstream port.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param dn_port The downstream port, which clock rate is to
+ * be converted to the target clock rate.
+ * @param clock_rate Target clock rate.
+ * @param options Flags from #pjmedia_resample_port_options.
+ * When this flag is zero, the default behavior
+ * is to use high quality resampling with
+ * large filter, and to destroy downstream port
+ * when resample port is destroyed.
+ * @param p_port Pointer to receive the resample port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_resample_port_create( pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned clock_rate,
+ unsigned options,
+ pjmedia_port **p_port );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_RESAMPLE_H__ */
+
diff --git a/pjmedia/include/pjmedia/rtcp.h b/pjmedia/include/pjmedia/rtcp.h
new file mode 100644
index 0000000..6584f63
--- /dev/null
+++ b/pjmedia/include/pjmedia/rtcp.h
@@ -0,0 +1,486 @@
+/* $Id: rtcp.h 3999 2012-03-30 07:10:13Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_RTCP_H__
+#define __PJMEDIA_RTCP_H__
+
+/**
+ * @file rtcp.h
+ * @brief RTCP implementation.
+ */
+
+#include <pjmedia/types.h>
+#include <pjmedia/rtcp_xr.h>
+#include <pjmedia/rtp.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTCP RTCP Session and Encapsulation (RFC 3550)
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTCP format and session management
+ * @{
+ *
+ * PJMEDIA implements subsets of RTCP specification (RFC 3550) to monitor
+ * the quality of the real-time media (audio/video) transmission. In
+ * addition to the standard quality monitoring and reporting with RTCP
+ * SR and RR types, PJMEDIA's RTCP implementation is able to report
+ * extended statistics for incoming streams, such as packet duplications,
+ * reorder, discarded, and loss period (to distinguish between random
+ * and burst loss).
+ *
+ * The bidirectional media quality statistic is represented with
+ * #pjmedia_rtcp_stat structure.
+ *
+ * When application uses the stream interface (see @ref PJMED_STRM),
+ * application may retrieve the RTCP statistic by calling
+ * #pjmedia_stream_get_stat() function.
+ */
+
+
+#pragma pack(1)
+
+/**
+ * RTCP sender report.
+ */
+typedef struct pjmedia_rtcp_sr
+{
+ pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
+ pj_uint32_t ntp_frac; /**< NTP time, fractions part. */
+ pj_uint32_t rtp_ts; /**< RTP timestamp. */
+ pj_uint32_t sender_pcount; /**< Sender packet cound. */
+ pj_uint32_t sender_bcount; /**< Sender octet/bytes count. */
+} pjmedia_rtcp_sr;
+
+
+/**
+ * RTCP receiver report.
+ */
+typedef struct pjmedia_rtcp_rr
+{
+ pj_uint32_t ssrc; /**< SSRC identification. */
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ pj_uint32_t fract_lost:8; /**< Fraction lost. */
+ pj_uint32_t total_lost_2:8; /**< Total lost, bit 16-23. */
+ pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */
+ pj_uint32_t total_lost_0:8; /**< Total lost, bit 0-7. */
+#else
+ pj_uint32_t fract_lost:8; /**< Fraction lost. */
+ pj_uint32_t total_lost_2:8; /**< Total lost, bit 0-7. */
+ pj_uint32_t total_lost_1:8; /**< Total lost, bit 8-15. */
+ pj_uint32_t total_lost_0:8; /**< Total lost, bit 16-23. */
+#endif
+ pj_uint32_t last_seq; /**< Last sequence number. */
+ pj_uint32_t jitter; /**< Jitter. */
+ pj_uint32_t lsr; /**< Last SR. */
+ pj_uint32_t dlsr; /**< Delay since last SR. */
+} pjmedia_rtcp_rr;
+
+
+/**
+ * RTCP common header.
+ */
+typedef struct pjmedia_rtcp_common
+{
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ unsigned version:2; /**< packet type */
+ unsigned p:1; /**< padding flag */
+ unsigned count:5; /**< varies by payload type */
+ unsigned pt:8; /**< payload type */
+#else
+ unsigned count:5; /**< varies by payload type */
+ unsigned p:1; /**< padding flag */
+ unsigned version:2; /**< packet type */
+ unsigned pt:8; /**< payload type */
+#endif
+ unsigned length:16; /**< packet length */
+ pj_uint32_t ssrc; /**< SSRC identification */
+} pjmedia_rtcp_common;
+
+
+/**
+ * This structure declares default RTCP packet (SR) that is sent by pjmedia.
+ * Incoming RTCP packet may have different format, and must be parsed
+ * manually by application.
+ */
+typedef struct pjmedia_rtcp_sr_pkt
+{
+ pjmedia_rtcp_common common; /**< Common header. */
+ pjmedia_rtcp_sr sr; /**< Sender report. */
+ pjmedia_rtcp_rr rr; /**< variable-length list */
+} pjmedia_rtcp_sr_pkt;
+
+/**
+ * This structure declares RTCP RR (Receiver Report) packet.
+ */
+typedef struct pjmedia_rtcp_rr_pkt
+{
+ pjmedia_rtcp_common common; /**< Common header. */
+ pjmedia_rtcp_rr rr; /**< variable-length list */
+} pjmedia_rtcp_rr_pkt;
+
+
+#pragma pack()
+
+
+/**
+ * RTCP SDES structure.
+ */
+typedef struct pjmedia_rtcp_sdes
+{
+ pj_str_t cname; /**< RTCP SDES type CNAME. */
+ pj_str_t name; /**< RTCP SDES type NAME. */
+ pj_str_t email; /**< RTCP SDES type EMAIL. */
+ pj_str_t phone; /**< RTCP SDES type PHONE. */
+ pj_str_t loc; /**< RTCP SDES type LOC. */
+ pj_str_t tool; /**< RTCP SDES type TOOL. */
+ pj_str_t note; /**< RTCP SDES type NOTE. */
+} pjmedia_rtcp_sdes;
+
+
+/**
+ * NTP time representation.
+ */
+typedef struct pjmedia_rtcp_ntp_rec
+{
+ pj_uint32_t hi; /**< High order 32-bit part. */
+ pj_uint32_t lo; /**< Lo order 32-bit part. */
+} pjmedia_rtcp_ntp_rec;
+
+
+/**
+ * Unidirectional RTP stream statistics.
+ */
+typedef struct pjmedia_rtcp_stream_stat
+{
+ pj_time_val update; /**< Time of last update. */
+ unsigned update_cnt; /**< Number of updates (to calculate avg) */
+ pj_uint32_t pkt; /**< Total number of packets */
+ pj_uint32_t bytes; /**< Total number of payload/bytes */
+ unsigned discard; /**< Total number of discarded packets. */
+ unsigned loss; /**< Total number of packets lost */
+ unsigned reorder; /**< Total number of out of order packets */
+ unsigned dup; /**< Total number of duplicates packets */
+
+ pj_math_stat loss_period;/**< Loss period statistics (in usec) */
+
+ struct {
+ unsigned burst:1; /**< Burst/sequential packet lost detected */
+ unsigned random:1; /**< Random packet lost detected. */
+ } loss_type; /**< Types of loss detected. */
+
+ pj_math_stat jitter; /**< Jitter statistics (in usec) */
+
+} pjmedia_rtcp_stream_stat;
+
+
+/**
+ * Bidirectional RTP stream statistics.
+ */
+typedef struct pjmedia_rtcp_stat
+{
+ pj_time_val start; /**< Time when session was created */
+
+ pjmedia_rtcp_stream_stat tx; /**< Encoder stream statistics. */
+ pjmedia_rtcp_stream_stat rx; /**< Decoder stream statistics. */
+
+ pj_math_stat rtt; /**< Round trip delay statistic(in usec)*/
+
+ pj_uint32_t rtp_tx_last_ts; /**< Last TX RTP timestamp. */
+ pj_uint16_t rtp_tx_last_seq;/**< Last TX RTP sequence. */
+
+#if defined(PJMEDIA_RTCP_STAT_HAS_IPDV) && PJMEDIA_RTCP_STAT_HAS_IPDV!=0
+ pj_math_stat rx_ipdv;/**< Statistics of IP packet delay
+ variation in receiving direction
+ (in usec). */
+#endif
+
+#if defined(PJMEDIA_RTCP_STAT_HAS_RAW_JITTER) && PJMEDIA_RTCP_STAT_HAS_RAW_JITTER!=0
+ pj_math_stat rx_raw_jitter;/**< Statistic of raw jitter in
+ receiving direction
+ (in usec). */
+#endif
+
+ pjmedia_rtcp_sdes peer_sdes; /**< Peer SDES. */
+ char peer_sdes_buf_[PJMEDIA_RTCP_RX_SDES_BUF_LEN];
+ /**< Peer SDES buffer. */
+
+} pjmedia_rtcp_stat;
+
+
+/**
+ * RTCP session is used to monitor the RTP session of one endpoint. There
+ * should only be one RTCP session for a bidirectional RTP streams.
+ */
+typedef struct pjmedia_rtcp_session
+{
+ char *name; /**< Name identification. */
+ pjmedia_rtcp_sr_pkt rtcp_sr_pkt;/**< Cached RTCP SR packet. */
+ pjmedia_rtcp_rr_pkt rtcp_rr_pkt;/**< Cached RTCP RR packet. */
+
+ pjmedia_rtp_seq_session seq_ctrl; /**< RTCP sequence number control. */
+ unsigned rtp_last_ts;/**< Last timestamp in RX RTP pkt. */
+
+ unsigned clock_rate; /**< Clock rate of the stream */
+ unsigned pkt_size; /**< Avg pkt size, in samples. */
+ pj_uint32_t received; /**< # pkt received */
+ pj_uint32_t exp_prior; /**< # pkt expected at last interval*/
+ pj_uint32_t rx_prior; /**< # pkt received at last interval*/
+ pj_int32_t transit; /**< Rel transit time for prev pkt */
+ pj_uint32_t jitter; /**< Scaled jitter */
+ pj_time_val tv_base; /**< Base time, in seconds. */
+ pj_timestamp ts_base; /**< Base system timestamp. */
+ pj_timestamp ts_freq; /**< System timestamp frequency. */
+ pj_uint32_t rtp_ts_base;/**< Base RTP timestamp. */
+
+ pj_uint32_t rx_lsr; /**< NTP ts in last SR received */
+ pj_timestamp rx_lsr_time;/**< Time when last SR is received */
+ pj_uint32_t peer_ssrc; /**< Peer SSRC */
+
+ pjmedia_rtcp_stat stat; /**< Bidirectional stream stat. */
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+ /**
+ * Specify whether RTCP XR processing is enabled on this session.
+ */
+ pj_bool_t xr_enabled;
+
+ /**
+ * RTCP XR session, only valid if RTCP XR processing is enabled
+ * on this session.
+ */
+ pjmedia_rtcp_xr_session xr_session;
+#endif
+} pjmedia_rtcp_session;
+
+
+/**
+ * RTCP session settings.
+ */
+typedef struct pjmedia_rtcp_session_setting
+{
+ char *name; /**< RTCP session name. */
+ unsigned clock_rate; /**< Sequence. */
+ unsigned samples_per_frame; /**< Timestamp. */
+ pj_uint32_t ssrc; /**< Sender SSRC. */
+ pj_uint32_t rtp_ts_base; /**< Base RTP timestamp. */
+} pjmedia_rtcp_session_setting;
+
+
+/**
+ * Initialize RTCP session setting.
+ *
+ * @param settings The RTCP session setting to be initialized.
+ */
+PJ_DECL(void) pjmedia_rtcp_session_setting_default(
+ pjmedia_rtcp_session_setting *settings);
+
+
+/**
+ * Initialize bidirectional RTCP statistics.
+ *
+ * @param stat The bidirectional RTCP statistics.
+ */
+PJ_DECL(void) pjmedia_rtcp_init_stat(pjmedia_rtcp_stat *stat);
+
+
+/**
+ * Initialize RTCP session.
+ *
+ * @param session The session
+ * @param name Optional name to identify the session (for
+ * logging purpose).
+ * @param clock_rate Codec clock rate in samples per second.
+ * @param samples_per_frame Average number of samples per frame.
+ * @param ssrc The SSRC used in to identify the session.
+ */
+PJ_DECL(void) pjmedia_rtcp_init( pjmedia_rtcp_session *session,
+ char *name,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ pj_uint32_t ssrc );
+
+
+/**
+ * Initialize RTCP session.
+ *
+ * @param session The session
+ * @param settings The RTCP session settings.
+ */
+PJ_DECL(void) pjmedia_rtcp_init2(pjmedia_rtcp_session *session,
+ const pjmedia_rtcp_session_setting *settings);
+
+
+/**
+ * Utility function to retrieve current NTP timestamp.
+ *
+ * @param sess RTCP session.
+ * @param ntp NTP record.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_get_ntp_time(const pjmedia_rtcp_session *sess,
+ pjmedia_rtcp_ntp_rec *ntp);
+
+
+/**
+ * Deinitialize RTCP session.
+ *
+ * @param session The session.
+ */
+PJ_DECL(void) pjmedia_rtcp_fini( pjmedia_rtcp_session *session);
+
+
+/**
+ * Call this function everytime an RTP packet is received to let the RTCP
+ * session do its internal calculations.
+ *
+ * @param session The session.
+ * @param seq The RTP packet sequence number, in host byte order.
+ * @param ts The RTP packet timestamp, in host byte order.
+ * @param payload Size of the payload.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtp( pjmedia_rtcp_session *session,
+ unsigned seq,
+ unsigned ts,
+ unsigned payload);
+
+
+/**
+ * Call this function everytime an RTP packet is received to let the RTCP
+ * session do its internal calculations.
+ *
+ * @param session The session.
+ * @param seq The RTP packet sequence number, in host byte order.
+ * @param ts The RTP packet timestamp, in host byte order.
+ * @param payload Size of the payload.
+ * @param discarded Flag to specify whether the packet is discarded.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtp2(pjmedia_rtcp_session *session,
+ unsigned seq,
+ unsigned ts,
+ unsigned payload,
+ pj_bool_t discarded);
+
+
+/**
+ * Call this function everytime an RTP packet is sent to let the RTCP session
+ * do its internal calculations.
+ *
+ * @param session The session.
+ * @param ptsize The payload size of the RTP packet (ie packet minus
+ * RTP header) in bytes.
+ */
+PJ_DECL(void) pjmedia_rtcp_tx_rtp( pjmedia_rtcp_session *session,
+ unsigned ptsize );
+
+
+/**
+ * Call this function when an RTCP packet is received from remote peer.
+ * This RTCP packet received from remote is used to calculate the end-to-
+ * end delay of the network.
+ *
+ * @param session RTCP session.
+ * @param rtcp_pkt The received RTCP packet.
+ * @param size Size of the incoming packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *session,
+ const void *rtcp_pkt,
+ pj_size_t size);
+
+
+/**
+ * Build a RTCP packet to be transmitted to remote RTP peer. This will
+ * create RTCP Sender Report (SR) or Receiver Report (RR) depending on
+ * whether the endpoint has been transmitting RTP since the last interval.
+ * Note that this function will reset the interval counters (such as
+ * the ones to calculate fraction lost) in the session.
+ *
+ * @param session The RTCP session.
+ * @param rtcp_pkt Upon return, it will contain pointer to the
+ * RTCP packet, which can be RTCP SR or RR.
+ * @param len Upon return, it will indicate the size of
+ * the RTCP packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_build_rtcp( pjmedia_rtcp_session *session,
+ void **rtcp_pkt, int *len);
+
+
+/**
+ * Build an RTCP SDES (source description) packet. This packet can be
+ * appended to other RTCP packets, e.g: RTCP RR/SR, to compose a compound
+ * RTCP packet.
+ *
+ * @param session The RTCP session.
+ * @param buf The buffer to receive RTCP SDES packet.
+ * @param length On input, it will contain the buffer length.
+ * On output, it will contain the generated RTCP SDES
+ * packet length.
+ * @param sdes The source description, see #pjmedia_rtcp_sdes.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_build_rtcp_sdes(
+ pjmedia_rtcp_session *session,
+ void *buf,
+ pj_size_t *length,
+ const pjmedia_rtcp_sdes *sdes);
+
+/**
+ * Build an RTCP BYE packet. This packet can be appended to other RTCP
+ * packets, e.g: RTCP RR/SR, to compose a compound RTCP packet.
+ *
+ * @param session The RTCP session.
+ * @param buf The buffer to receive RTCP BYE packet.
+ * @param length On input, it will contain the buffer length.
+ * On output, it will contain the generated RTCP BYE
+ * packet length.
+ * @param reason Optional, the BYE reason.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_build_rtcp_bye(
+ pjmedia_rtcp_session *session,
+ void *buf,
+ pj_size_t *length,
+ const pj_str_t *reason);
+
+
+/**
+ * Call this function if RTCP XR needs to be enabled/disabled in the
+ * RTCP session.
+ *
+ * @param session The RTCP session.
+ * @param enable Enable/disable RTCP XR.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_enable_xr( pjmedia_rtcp_session *session,
+ pj_bool_t enable);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTCP_H__ */
diff --git a/pjmedia/include/pjmedia/rtcp_xr.h b/pjmedia/include/pjmedia/rtcp_xr.h
new file mode 100644
index 0000000..9050f25
--- /dev/null
+++ b/pjmedia/include/pjmedia/rtcp_xr.h
@@ -0,0 +1,478 @@
+/* $Id: rtcp_xr.h 3999 2012-03-30 07:10:13Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_RTCP_XR_H__
+#define __PJMEDIA_RTCP_XR_H__
+
+/**
+ * @file rtcp_xr.h
+ * @brief RTCP XR implementation.
+ */
+
+#include <pjmedia/types.h>
+#include <pj/math.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTCP_XR RTCP Extended Report (XR) - RFC 3611
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTCP XR extension to RTCP session
+ * @{
+ *
+ * PJMEDIA implements subsets of RTCP XR specification (RFC 3611) to monitor
+ * the quality of the real-time media (audio/video) transmission.
+ */
+
+/**
+ * Enumeration of report types of RTCP XR. Useful for user to enable varying
+ * combinations of RTCP XR report blocks.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_LOSS_RLE = (1 << 0),
+ PJMEDIA_RTCP_XR_DUP_RLE = (1 << 1),
+ PJMEDIA_RTCP_XR_RCPT_TIMES = (1 << 2),
+ PJMEDIA_RTCP_XR_RR_TIME = (1 << 3),
+ PJMEDIA_RTCP_XR_DLRR = (1 << 4),
+ PJMEDIA_RTCP_XR_STATS = (1 << 5),
+ PJMEDIA_RTCP_XR_VOIP_METRICS = (1 << 6)
+} pjmedia_rtcp_xr_type;
+
+/**
+ * Enumeration of info need to be updated manually to RTCP XR. Most info
+ * could be updated automatically each time RTP received.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL = 1,
+ PJMEDIA_RTCP_XR_INFO_NOISE_LVL = 2,
+ PJMEDIA_RTCP_XR_INFO_RERL = 3,
+ PJMEDIA_RTCP_XR_INFO_R_FACTOR = 4,
+ PJMEDIA_RTCP_XR_INFO_MOS_LQ = 5,
+ PJMEDIA_RTCP_XR_INFO_MOS_CQ = 6,
+ PJMEDIA_RTCP_XR_INFO_CONF_PLC = 7,
+ PJMEDIA_RTCP_XR_INFO_CONF_JBA = 8,
+ PJMEDIA_RTCP_XR_INFO_CONF_JBR = 9,
+ PJMEDIA_RTCP_XR_INFO_JB_NOM = 10,
+ PJMEDIA_RTCP_XR_INFO_JB_MAX = 11,
+ PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX = 12
+} pjmedia_rtcp_xr_info;
+
+/**
+ * Enumeration of PLC types definitions for RTCP XR report.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_PLC_UNK = 0,
+ PJMEDIA_RTCP_XR_PLC_DIS = 1,
+ PJMEDIA_RTCP_XR_PLC_ENH = 2,
+ PJMEDIA_RTCP_XR_PLC_STD = 3
+} pjmedia_rtcp_xr_plc_type;
+
+/**
+ * Enumeration of jitter buffer types definitions for RTCP XR report.
+ */
+typedef enum {
+ PJMEDIA_RTCP_XR_JB_UNKNOWN = 0,
+ PJMEDIA_RTCP_XR_JB_FIXED = 2,
+ PJMEDIA_RTCP_XR_JB_ADAPTIVE = 3
+} pjmedia_rtcp_xr_jb_type;
+
+
+#pragma pack(1)
+
+/**
+ * This type declares RTCP XR Report Header.
+ */
+typedef struct pjmedia_rtcp_xr_rb_header
+{
+ pj_uint8_t bt; /**< Block type. */
+ pj_uint8_t specific; /**< Block specific data. */
+ pj_uint16_t length; /**< Block length. */
+} pjmedia_rtcp_xr_rb_header;
+
+/**
+ * This type declares RTCP XR Receiver Reference Time Report Block.
+ */
+typedef struct pjmedia_rtcp_xr_rb_rr_time
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ntp_sec; /**< NTP time, seconds part. */
+ pj_uint32_t ntp_frac; /**< NTP time, fractions part. */
+} pjmedia_rtcp_xr_rb_rr_time;
+
+
+/**
+ * This type declares RTCP XR DLRR Report Sub-block
+ */
+typedef struct pjmedia_rtcp_xr_rb_dlrr_item
+{
+ pj_uint32_t ssrc; /**< receiver SSRC */
+ pj_uint32_t lrr; /**< last receiver report */
+ pj_uint32_t dlrr; /**< delay since last receiver
+ report */
+} pjmedia_rtcp_xr_rb_dlrr_item;
+
+/**
+ * This type declares RTCP XR DLRR Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_dlrr
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pjmedia_rtcp_xr_rb_dlrr_item item; /**< Block contents,
+ variable length list */
+} pjmedia_rtcp_xr_rb_dlrr;
+
+/**
+ * This type declares RTCP XR Statistics Summary Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_stats
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ssrc; /**< Receiver SSRC */
+ pj_uint16_t begin_seq; /**< Begin RTP sequence reported */
+ pj_uint16_t end_seq; /**< End RTP sequence reported */
+ pj_uint32_t lost; /**< Number of packet lost in this
+ interval */
+ pj_uint32_t dup; /**< Number of duplicated packet in
+ this interval */
+ pj_uint32_t jitter_min; /**< Minimum jitter in this interval */
+ pj_uint32_t jitter_max; /**< Maximum jitter in this interval */
+ pj_uint32_t jitter_mean; /**< Average jitter in this interval */
+ pj_uint32_t jitter_dev; /**< Jitter deviation in this
+ interval */
+ pj_uint32_t toh_min:8; /**< Minimum ToH in this interval */
+ pj_uint32_t toh_max:8; /**< Maximum ToH in this interval */
+ pj_uint32_t toh_mean:8; /**< Average ToH in this interval */
+ pj_uint32_t toh_dev:8; /**< ToH deviation in this interval */
+} pjmedia_rtcp_xr_rb_stats;
+
+/**
+ * This type declares RTCP XR VoIP Metrics Report Block
+ */
+typedef struct pjmedia_rtcp_xr_rb_voip_mtc
+{
+ pjmedia_rtcp_xr_rb_header header; /**< Block header. */
+ pj_uint32_t ssrc; /**< Receiver SSRC */
+ pj_uint8_t loss_rate; /**< Packet loss rate */
+ pj_uint8_t discard_rate; /**< Packet discarded rate */
+ pj_uint8_t burst_den; /**< Burst density */
+ pj_uint8_t gap_den; /**< Gap density */
+ pj_uint16_t burst_dur; /**< Burst duration */
+ pj_uint16_t gap_dur; /**< Gap duration */
+ pj_uint16_t rnd_trip_delay;/**< Round trip delay */
+ pj_uint16_t end_sys_delay; /**< End system delay */
+ pj_uint8_t signal_lvl; /**< Signal level */
+ pj_uint8_t noise_lvl; /**< Noise level */
+ pj_uint8_t rerl; /**< Residual Echo Return Loss */
+ pj_uint8_t gmin; /**< The gap threshold */
+ pj_uint8_t r_factor; /**< Voice quality metric carried
+ over this RTP session */
+ pj_uint8_t ext_r_factor; /**< Voice quality metric carried
+ outside of this RTP session*/
+ pj_uint8_t mos_lq; /**< Mean Opinion Score for
+ Listening Quality */
+ pj_uint8_t mos_cq; /**< Mean Opinion Score for
+ Conversation Quality */
+ pj_uint8_t rx_config; /**< Receiver configuration */
+ pj_uint8_t reserved2; /**< Not used */
+ pj_uint16_t jb_nom; /**< Current delay by jitter
+ buffer */
+ pj_uint16_t jb_max; /**< Maximum delay by jitter
+ buffer */
+ pj_uint16_t jb_abs_max; /**< Maximum possible delay by
+ jitter buffer */
+} pjmedia_rtcp_xr_rb_voip_mtc;
+
+
+/**
+ * Constant of RTCP-XR content size.
+ */
+#define PJMEDIA_RTCP_XR_BUF_SIZE \
+ sizeof(pjmedia_rtcp_xr_rb_rr_time) + \
+ sizeof(pjmedia_rtcp_xr_rb_dlrr) + \
+ sizeof(pjmedia_rtcp_xr_rb_stats) + \
+ sizeof(pjmedia_rtcp_xr_rb_voip_mtc)
+
+
+/**
+ * This structure declares RTCP XR (Extended Report) packet.
+ */
+typedef struct pjmedia_rtcp_xr_pkt
+{
+ struct {
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+ unsigned version:2; /**< packet type */
+ unsigned p:1; /**< padding flag */
+ unsigned count:5; /**< varies by payload type */
+ unsigned pt:8; /**< payload type */
+#else
+ unsigned count:5; /**< varies by payload type */
+ unsigned p:1; /**< padding flag */
+ unsigned version:2; /**< packet type */
+ unsigned pt:8; /**< payload type */
+#endif
+ unsigned length:16; /**< packet length */
+ pj_uint32_t ssrc; /**< SSRC identification */
+ } common;
+
+ pj_int8_t buf[PJMEDIA_RTCP_XR_BUF_SIZE];
+ /**< Content buffer */
+} pjmedia_rtcp_xr_pkt;
+
+#pragma pack()
+
+
+/**
+ * This structure describes RTCP XR statitic.
+ */
+typedef struct pjmedia_rtcp_xr_stream_stat
+{
+ struct {
+ pj_time_val update; /**< Time of last update. */
+
+ pj_uint32_t begin_seq; /**< Begin # seq of this interval. */
+ pj_uint32_t end_seq; /**< End # seq of this interval. */
+ unsigned count; /**< Number of packets. */
+
+ /**
+ * Flags represent whether the such report is valid/updated
+ */
+ unsigned l:1; /**< Lost flag */
+ unsigned d:1; /**< Duplicated flag */
+ unsigned j:1; /**< Jitter flag */
+ unsigned t:2; /**< TTL or Hop Limit,
+ 0=none, 1=TTL, 2=HL */
+
+ unsigned lost; /**< Number of packets lost */
+ unsigned dup; /**< Number of duplicated packets */
+ pj_math_stat jitter; /**< Jitter statistics (in usec) */
+ pj_math_stat toh; /**< TTL of hop limit statistics. */
+ } stat_sum;
+
+ struct {
+ pj_time_val update; /**< Time of last update. */
+
+ pj_uint8_t loss_rate; /**< Packet loss rate */
+ pj_uint8_t discard_rate; /**< Packet discarded rate */
+ pj_uint8_t burst_den; /**< Burst density */
+ pj_uint8_t gap_den; /**< Gap density */
+ pj_uint16_t burst_dur; /**< Burst duration */
+ pj_uint16_t gap_dur; /**< Gap duration */
+ pj_uint16_t rnd_trip_delay; /**< Round trip delay */
+ pj_uint16_t end_sys_delay; /**< End system delay */
+ pj_int8_t signal_lvl; /**< Signal level */
+ pj_int8_t noise_lvl; /**< Noise level */
+ pj_uint8_t rerl; /**< Residual Echo Return Loss */
+ pj_uint8_t gmin; /**< The gap threshold */
+ pj_uint8_t r_factor; /**< Voice quality metric carried
+ over this RTP session */
+ pj_uint8_t ext_r_factor; /**< Voice quality metric carried
+ outside of this RTP session*/
+ pj_uint8_t mos_lq; /**< Mean Opinion Score for
+ Listening Quality */
+ pj_uint8_t mos_cq; /**< Mean Opinion Score for
+ Conversation Quality */
+ pj_uint8_t rx_config; /**< Receiver configuration */
+ pj_uint16_t jb_nom; /**< Current delay by jitter
+ buffer */
+ pj_uint16_t jb_max; /**< Maximum delay by jitter
+ buffer */
+ pj_uint16_t jb_abs_max; /**< Maximum possible delay by
+ jitter buffer */
+ } voip_mtc;
+
+} pjmedia_rtcp_xr_stream_stat;
+
+typedef struct pjmedia_rtcp_xr_stat
+{
+ pjmedia_rtcp_xr_stream_stat rx; /**< Decoding direction statistics. */
+ pjmedia_rtcp_xr_stream_stat tx; /**< Encoding direction statistics. */
+ pj_math_stat rtt; /**< Round-trip delay stat (in usec)
+ the value is calculated from
+ receiver side. */
+} pjmedia_rtcp_xr_stat;
+
+/**
+ * Forward declaration of RTCP session
+ */
+struct pjmedia_rtcp_session;
+
+/**
+ * RTCP session is used to monitor the RTP session of one endpoint. There
+ * should only be one RTCP session for a bidirectional RTP streams.
+ */
+struct pjmedia_rtcp_xr_session
+{
+ char *name; /**< Name identification. */
+ pjmedia_rtcp_xr_pkt pkt; /**< Cached RTCP XR packet. */
+
+ pj_uint32_t rx_lrr; /**< NTP ts in last RR received. */
+ pj_timestamp rx_lrr_time;/**< Time when last RR is received. */
+ pj_uint32_t rx_last_rr; /**< # pkt received since last
+ sending RR time. */
+
+ pjmedia_rtcp_xr_stat stat; /**< RTCP XR statistics. */
+
+ /* The reference sequence number is an extended sequence number
+ * that serves as the basis for determining whether a new 16 bit
+ * sequence number comes earlier or later in the 32 bit sequence
+ * space.
+ */
+ pj_uint32_t src_ref_seq;
+ pj_bool_t uninitialized_src_ref_seq;
+
+ /* This structure contains variables needed for calculating
+ * burst metrics.
+ */
+ struct {
+ pj_uint32_t pkt;
+ pj_uint32_t lost;
+ pj_uint32_t loss_count;
+ pj_uint32_t discard_count;
+ pj_uint32_t c11;
+ pj_uint32_t c13;
+ pj_uint32_t c14;
+ pj_uint32_t c22;
+ pj_uint32_t c23;
+ pj_uint32_t c33;
+ } voip_mtc_stat;
+
+ unsigned ptime; /**< Packet time. */
+ unsigned frames_per_packet; /**< # frames per packet. */
+
+ struct pjmedia_rtcp_session *rtcp_session;
+ /**< Parent/RTCP session. */
+};
+
+typedef struct pjmedia_rtcp_xr_session pjmedia_rtcp_xr_session;
+
+/**
+ * Build an RTCP XR packet which contains one or more RTCP XR report blocks.
+ * There are seven report types as defined in RFC 3611.
+ *
+ * @param session The RTCP XR session.
+ * @param rpt_types Report types to be included in the packet, report types
+ * are defined in pjmedia_rtcp_xr_type, set this to zero
+ * will make this function build all reports appropriately.
+ * @param rtcp_pkt Upon return, it will contain pointer to the RTCP XR packet.
+ * @param len Upon return, it will indicate the size of the generated
+ * RTCP XR packet.
+ */
+PJ_DECL(void) pjmedia_rtcp_build_rtcp_xr( pjmedia_rtcp_xr_session *session,
+ unsigned rpt_types,
+ void **rtcp_pkt, int *len);
+
+/**
+ * Call this function to manually update some info needed by RTCP XR to
+ * generate report which could not be populated directly when receiving
+ * RTP.
+ *
+ * @param session The RTCP XR session.
+ * @param info Info type to be updated, @see pjmedia_rtcp_xr_info.
+ * @param val Value.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtcp_xr_update_info(
+ pjmedia_rtcp_xr_session *session,
+ unsigned info,
+ pj_int32_t val);
+
+/*
+ * Private APIs:
+ */
+
+/**
+ * This function is called internally by RTCP session when RTCP XR is enabled
+ * to initialize the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ * @param r_session RTCP session.
+ * @param gmin Gmin value (defined in RFC 3611), set to 0 for default (16).
+ * @param frames_per_packet
+ Number of frames per packet.
+ */
+void pjmedia_rtcp_xr_init( pjmedia_rtcp_xr_session *session,
+ struct pjmedia_rtcp_session *r_session,
+ pj_uint8_t gmin,
+ unsigned frames_per_packet);
+
+/**
+ * This function is called internally by RTCP session to destroy
+ * the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ */
+void pjmedia_rtcp_xr_fini( pjmedia_rtcp_xr_session *session );
+
+/**
+ * This function is called internally by RTCP session when it receives
+ * incoming RTCP XR packets.
+ *
+ * @param session RTCP XR session.
+ * @param rtcp_pkt The received RTCP XR packet.
+ * @param size Size of the incoming packet.
+ */
+void pjmedia_rtcp_xr_rx_rtcp_xr( pjmedia_rtcp_xr_session *session,
+ const void *rtcp_pkt,
+ pj_size_t size);
+
+/**
+ * This function is called internally by RTCP session whenever an RTP packet
+ * is received or lost to let the RTCP XR session update its statistics.
+ * Data passed to this function is a result of analyzation by RTCP and the
+ * jitter buffer. Whenever some info is available, the value should be zero
+ * or more (no negative info), otherwise if info is not available the info
+ * should be -1 so no update will be done for this info in the RTCP XR session.
+ *
+ * @param session RTCP XR session.
+ * @param seq Sequence number of RTP packet.
+ * @param lost Info if this packet is lost.
+ * @param dup Info if this packet is a duplication.
+ * @param discarded Info if this packet is discarded
+ * (not because of duplication).
+ * @param jitter Info jitter of this packet.
+ * @param toh Info Time To Live or Hops Limit of this packet.
+ * @param toh_ipv4 Set PJ_TRUE if packet is transported over IPv4.
+ */
+void pjmedia_rtcp_xr_rx_rtp( pjmedia_rtcp_xr_session *session,
+ unsigned seq,
+ int lost,
+ int dup,
+ int discarded,
+ int jitter,
+ int toh, pj_bool_t toh_ipv4);
+
+/**
+ * This function is called internally by RTCP session whenever an RTP
+ * packet is sent to let the RTCP XR session do its internal calculations.
+ *
+ * @param session RTCP XR session.
+ * @param ptsize Size of RTP payload being sent.
+ */
+void pjmedia_rtcp_xr_tx_rtp( pjmedia_rtcp_xr_session *session,
+ unsigned ptsize );
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTCP_XR_H__ */
diff --git a/pjmedia/include/pjmedia/rtp.h b/pjmedia/include/pjmedia/rtp.h
new file mode 100644
index 0000000..f8634b1
--- /dev/null
+++ b/pjmedia/include/pjmedia/rtp.h
@@ -0,0 +1,394 @@
+/* $Id: rtp.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_RTP_H__
+#define __PJMEDIA_RTP_H__
+
+
+/**
+ * @file rtp.h
+ * @brief RTP packet and RTP session declarations.
+ */
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_RTP RTP Session and Encapsulation (RFC 3550)
+ * @ingroup PJMEDIA_SESSION
+ * @brief RTP format and session management
+ * @{
+ *
+ * The RTP module is designed to be dependent only to PJLIB, it does not depend
+ * on any other parts of PJMEDIA library. The RTP module does not even depend
+ * on any transports (sockets), to promote even more use, such as in DSP
+ * development (where transport may be handled by different processor).
+ *
+ * An RTCP implementation is available, in separate module. Please see
+ * @ref PJMED_RTCP.
+ *
+ * The functions that are provided by this module:
+ * - creating RTP header for each outgoing packet.
+ * - decoding RTP packet into RTP header and payload.
+ * - provide simple RTP session management (sequence number, etc.)
+ *
+ * The RTP module does not use any dynamic memory at all.
+ *
+ * \section P1 How to Use the RTP Module
+ *
+ * First application must call #pjmedia_rtp_session_init() to initialize the RTP
+ * session.
+ *
+ * When application wants to send RTP packet, it needs to call
+ * #pjmedia_rtp_encode_rtp() to build the RTP header. Note that this WILL NOT build
+ * the complete RTP packet, but instead only the header. Application can
+ * then either concatenate the header with the payload, or send the two
+ * fragments (the header and the payload) using scatter-gather transport API
+ * (e.g. \a sendv()).
+ *
+ * When application receives an RTP packet, first it should call
+ * #pjmedia_rtp_decode_rtp to decode RTP header and payload, then it should call
+ * #pjmedia_rtp_session_update to check whether we can process the RTP payload,
+ * and to let the RTP session updates its internal status. The decode function
+ * is guaranteed to point the payload to the correct position regardless of
+ * any options present in the RTP packet.
+ *
+ */
+
+#ifdef _MSC_VER
+# pragma warning(disable:4214) // bit field types other than int
+#endif
+
+
+/**
+ * RTP packet header. Note that all RTP functions here will work with this
+ * header in network byte order.
+ */
+#pragma pack(1)
+struct pjmedia_rtp_hdr
+{
+#if defined(PJ_IS_BIG_ENDIAN) && (PJ_IS_BIG_ENDIAN!=0)
+ pj_uint16_t v:2; /**< packet type/version */
+ pj_uint16_t p:1; /**< padding flag */
+ pj_uint16_t x:1; /**< extension flag */
+ pj_uint16_t cc:4; /**< CSRC count */
+ pj_uint16_t m:1; /**< marker bit */
+ pj_uint16_t pt:7; /**< payload type */
+#else
+ pj_uint16_t cc:4; /**< CSRC count */
+ pj_uint16_t x:1; /**< header extension flag */
+ pj_uint16_t p:1; /**< padding flag */
+ pj_uint16_t v:2; /**< packet type/version */
+ pj_uint16_t pt:7; /**< payload type */
+ pj_uint16_t m:1; /**< marker bit */
+#endif
+ pj_uint16_t seq; /**< sequence number */
+ pj_uint32_t ts; /**< timestamp */
+ pj_uint32_t ssrc; /**< synchronization source */
+};
+#pragma pack()
+
+/**
+ * @see pjmedia_rtp_hdr
+ */
+typedef struct pjmedia_rtp_hdr pjmedia_rtp_hdr;
+
+
+/**
+ * RTP extendsion header.
+ */
+struct pjmedia_rtp_ext_hdr
+{
+ pj_uint16_t profile_data; /**< Profile data. */
+ pj_uint16_t length; /**< Length. */
+};
+
+/**
+ * @see pjmedia_rtp_ext_hdr
+ */
+typedef struct pjmedia_rtp_ext_hdr pjmedia_rtp_ext_hdr;
+
+
+#pragma pack(1)
+
+/**
+ * Declaration for DTMF telephony-events (RFC2833).
+ */
+struct pjmedia_rtp_dtmf_event
+{
+ pj_uint8_t event; /**< Event type ID. */
+ pj_uint8_t e_vol; /**< Event volume. */
+ pj_uint16_t duration; /**< Event duration. */
+};
+
+/**
+ * @see pjmedia_rtp_dtmf_event
+ */
+typedef struct pjmedia_rtp_dtmf_event pjmedia_rtp_dtmf_event;
+
+#pragma pack()
+
+
+/**
+ * A generic sequence number management, used by both RTP and RTCP.
+ */
+struct pjmedia_rtp_seq_session
+{
+ pj_uint16_t max_seq; /**< Highest sequence number heard */
+ pj_uint32_t cycles; /**< Shifted count of seq number cycles */
+ pj_uint32_t base_seq; /**< Base seq number */
+ pj_uint32_t bad_seq; /**< Last 'bad' seq number + 1 */
+ pj_uint32_t probation; /**< Sequ. packets till source is valid */
+};
+
+/**
+ * @see pjmedia_rtp_seq_session
+ */
+typedef struct pjmedia_rtp_seq_session pjmedia_rtp_seq_session;
+
+
+/**
+ * RTP session descriptor.
+ */
+struct pjmedia_rtp_session
+{
+ pjmedia_rtp_hdr out_hdr; /**< Saved hdr for outgoing pkts. */
+ pjmedia_rtp_seq_session seq_ctrl; /**< Sequence number management. */
+ pj_uint16_t out_pt; /**< Default outgoing payload type. */
+ pj_uint32_t out_extseq; /**< Outgoing extended seq #. */
+ pj_uint32_t peer_ssrc; /**< Peer SSRC. */
+ pj_uint32_t received; /**< Number of received packets. */
+};
+
+/**
+ * @see pjmedia_rtp_session
+ */
+typedef struct pjmedia_rtp_session pjmedia_rtp_session;
+
+
+/**
+ * This structure is used to receive additional information about the
+ * state of incoming RTP packet.
+ */
+struct pjmedia_rtp_status
+{
+ union {
+ struct flag {
+ int bad:1; /**< General flag to indicate that sequence is
+ bad, and application should not process
+ this packet. More information will be given
+ in other flags. */
+ int badpt:1; /**< Bad payload type. */
+ int badssrc:1; /**< Bad SSRC */
+ int dup:1; /**< Indicates duplicate packet */
+ int outorder:1; /**< Indicates out of order packet */
+ int probation:1;/**< Indicates that session is in probation
+ until more packets are received. */
+ int restart:1; /**< Indicates that sequence number has made
+ a large jump, and internal base sequence
+ number has been adjusted. */
+ } flag; /**< Status flags. */
+
+ pj_uint16_t value; /**< Status value, to conveniently address all
+ flags. */
+
+ } status; /**< Status information union. */
+
+ pj_uint16_t diff; /**< Sequence number difference from previous
+ packet. Normally the value should be 1.
+ Value greater than one may indicate packet
+ loss. If packet with lower sequence is
+ received, the value will be set to zero.
+ If base sequence has been restarted, the
+ value will be one. */
+};
+
+
+/**
+ * RTP session settings.
+ */
+typedef struct pjmedia_rtp_session_setting
+{
+ pj_uint8_t flags; /**< Bitmask flags to specify whether such
+ field is set. Bitmask contents are:
+ (bit #0 is LSB)
+ bit #0: default payload type
+ bit #1: sender SSRC
+ bit #2: sequence
+ bit #3: timestamp */
+ int default_pt; /**< Default payload type. */
+ pj_uint32_t sender_ssrc; /**< Sender SSRC. */
+ pj_uint16_t seq; /**< Sequence. */
+ pj_uint32_t ts; /**< Timestamp. */
+} pjmedia_rtp_session_setting;
+
+
+/**
+ * @see pjmedia_rtp_status
+ */
+typedef struct pjmedia_rtp_status pjmedia_rtp_status;
+
+
+/**
+ * This function will initialize the RTP session according to given parameters.
+ *
+ * @param ses The session.
+ * @param default_pt Default payload type.
+ * @param sender_ssrc SSRC used for outgoing packets, in host byte order.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_session_init( pjmedia_rtp_session *ses,
+ int default_pt,
+ pj_uint32_t sender_ssrc );
+
+/**
+ * This function will initialize the RTP session according to given parameters
+ * defined in RTP session settings.
+ *
+ * @param ses The session.
+ * @param settings RTP session settings.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_session_init2(
+ pjmedia_rtp_session *ses,
+ pjmedia_rtp_session_setting settings);
+
+
+/**
+ * Create the RTP header based on arguments and current state of the RTP
+ * session.
+ *
+ * @param ses The session.
+ * @param pt Payload type.
+ * @param m Marker flag.
+ * @param payload_len Payload length in bytes.
+ * @param ts_len Timestamp length.
+ * @param rtphdr Upon return will point to RTP packet header.
+ * @param hdrlen Upon return will indicate the size of RTP packet header
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_encode_rtp( pjmedia_rtp_session *ses,
+ int pt, int m,
+ int payload_len, int ts_len,
+ const void **rtphdr,
+ int *hdrlen );
+
+/**
+ * This function decodes incoming packet into RTP header and payload.
+ * The decode function is guaranteed to point the payload to the correct
+ * position regardless of any options present in the RTP packet.
+ *
+ * Note that this function does not modify the returned RTP header to
+ * host byte order.
+ *
+ * @param ses The session.
+ * @param pkt The received RTP packet.
+ * @param pkt_len The length of the packet.
+ * @param hdr Upon return will point to the location of the RTP
+ * header inside the packet. Note that the RTP header
+ * will be given back as is, meaning that the fields
+ * will be in network byte order.
+ * @param payload Upon return will point to the location of the
+ * payload inside the packet.
+ * @param payloadlen Upon return will indicate the size of the payload.
+ *
+ * @return PJ_SUCCESS if successfull.
+ */
+PJ_DECL(pj_status_t) pjmedia_rtp_decode_rtp( pjmedia_rtp_session *ses,
+ const void *pkt, int pkt_len,
+ const pjmedia_rtp_hdr **hdr,
+ const void **payload,
+ unsigned *payloadlen);
+
+/**
+ * Call this function everytime an RTP packet is received to check whether
+ * the packet can be received and to let the RTP session performs its internal
+ * calculations.
+ *
+ * @param ses The session.
+ * @param hdr The RTP header of the incoming packet. The header must
+ * be given with fields in network byte order.
+ * @param seq_st Optional structure to receive the status of the RTP packet
+ * processing.
+ */
+PJ_DECL(void) pjmedia_rtp_session_update( pjmedia_rtp_session *ses,
+ const pjmedia_rtp_hdr *hdr,
+ pjmedia_rtp_status *seq_st);
+
+
+/**
+ * Call this function everytime an RTP packet is received to check whether
+ * the packet can be received and to let the RTP session performs its internal
+ * calculations.
+ *
+ * @param ses The session.
+ * @param hdr The RTP header of the incoming packet. The header must
+ * be given with fields in network byte order.
+ * @param seq_st Optional structure to receive the status of the RTP packet
+ * processing.
+ * @param check_pt Flag to indicate whether payload type needs to be validate.
+ *
+ * @see pjmedia_rtp_session_update()
+ */
+PJ_DECL(void) pjmedia_rtp_session_update2(pjmedia_rtp_session *ses,
+ const pjmedia_rtp_hdr *hdr,
+ pjmedia_rtp_status *seq_st,
+ pj_bool_t check_pt);
+
+
+/*
+ * INTERNAL:
+ */
+
+/**
+ * Internal function for creating sequence number control, shared by RTCP
+ * implementation.
+ *
+ * @param seq_ctrl The sequence control instance.
+ * @param seq Sequence number to initialize.
+ */
+void pjmedia_rtp_seq_init(pjmedia_rtp_seq_session *seq_ctrl,
+ pj_uint16_t seq);
+
+
+/**
+ * Internal function update sequence control, shared by RTCP implementation.
+ *
+ * @param seq_ctrl The sequence control instance.
+ * @param seq Sequence number to update.
+ * @param seq_status Optional structure to receive additional information
+ * about the packet.
+ */
+void pjmedia_rtp_seq_update( pjmedia_rtp_seq_session *seq_ctrl,
+ pj_uint16_t seq,
+ pjmedia_rtp_status *seq_status);
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_RTP_H__ */
diff --git a/pjmedia/include/pjmedia/sdp.h b/pjmedia/include/pjmedia/sdp.h
new file mode 100644
index 0000000..2dc58d6
--- /dev/null
+++ b/pjmedia/include/pjmedia/sdp.h
@@ -0,0 +1,736 @@
+/* $Id: sdp.h 3945 2012-01-27 09:12:59Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SDP_H__
+#define __PJMEDIA_SDP_H__
+
+/**
+ * @file sdp.h
+ * @brief SDP header file.
+ */
+#include <pjmedia/types.h>
+#include <pj/sock.h>
+
+/**
+ * @defgroup PJMEDIA_SDP SDP Parsing and Data Structure
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP data structure representation and parsing
+ * @{
+ *
+ * The basic SDP session descriptor and elements are described in header
+ * file <b><pjmedia/sdp.h></b>. This file contains declaration for
+ * SDP session descriptor and SDP media descriptor, along with their
+ * attributes. This file also declares functions to parse SDP message.
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * The PJMEDIA_MAX_SDP_FMT macro defines maximum format in a media line.
+ */
+#ifndef PJMEDIA_MAX_SDP_FMT
+# define PJMEDIA_MAX_SDP_FMT 32
+#endif
+
+/**
+ * The PJMEDIA_MAX_SDP_BANDW macro defines maximum bandwidth information
+ * lines in a media line.
+ */
+#ifndef PJMEDIA_MAX_SDP_BANDW
+# define PJMEDIA_MAX_SDP_BANDW 4
+#endif
+
+/**
+ * The PJMEDIA_MAX_SDP_ATTR macro defines maximum SDP attributes in media and
+ * session descriptor.
+ */
+#ifndef PJMEDIA_MAX_SDP_ATTR
+# define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*2 + 4)
+#endif
+
+/**
+ * The PJMEDIA_MAX_SDP_MEDIA macro defines maximum SDP media lines in a
+ * SDP session descriptor.
+ */
+#ifndef PJMEDIA_MAX_SDP_MEDIA
+# define PJMEDIA_MAX_SDP_MEDIA 16
+#endif
+
+
+/* **************************************************************************
+ * SDP ATTRIBUTES
+ ***************************************************************************
+ */
+
+/**
+ * Generic representation of attribute.
+ */
+struct pjmedia_sdp_attr
+{
+ pj_str_t name; /**< Attribute name. */
+ pj_str_t value; /**< Attribute value. */
+};
+
+/**
+ * @see pjmedia_sdp_attr
+ */
+typedef struct pjmedia_sdp_attr pjmedia_sdp_attr;
+
+
+/**
+ * Create SDP attribute.
+ *
+ * @param pool Pool to create the attribute.
+ * @param name Attribute name.
+ * @param value Optional attribute value.
+ *
+ * @return The new SDP attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create(pj_pool_t *pool,
+ const char *name,
+ const pj_str_t *value);
+
+/**
+ * Clone attribute
+ *
+ * @param pool Pool to be used.
+ * @param attr The attribute to clone.
+ *
+ * @return New attribute as cloned from the attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_clone(pj_pool_t *pool,
+ const pjmedia_sdp_attr*attr);
+
+/**
+ * Find the first attribute with the specified type.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ * @param fmt Optional string to indicate which payload format
+ * to find for \a rtpmap and \a fmt attributes. For other
+ * types of attributes, the value should be NULL.
+ *
+ * @return The specified attribute, or NULL if it can't be found.
+ *
+ * @see pjmedia_sdp_attr_find2, pjmedia_sdp_media_find_attr,
+ * pjmedia_sdp_media_find_attr2
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_attr_find(unsigned count,
+ pjmedia_sdp_attr *const attr_array[],
+ const pj_str_t *name, const pj_str_t *fmt);
+
+/**
+ * Find the first attribute with the specified type.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ * @param fmt Optional string to indicate which payload format
+ * to find for \a rtpmap and \a fmt attributes. For other
+ * types of attributes, the value should be NULL.
+ *
+ * @return The specified attribute, or NULL if it can't be found.
+ *
+ * @see pjmedia_sdp_attr_find, pjmedia_sdp_media_find_attr,
+ * pjmedia_sdp_media_find_attr2
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_attr_find2(unsigned count,
+ pjmedia_sdp_attr *const attr_array[],
+ const char *name, const pj_str_t *fmt);
+
+/**
+ * Add a new attribute to array of attributes.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param attr The attribute to add.
+ *
+ * @return PJ_SUCCESS or the error code.
+ *
+ * @see pjmedia_sdp_media_add_attr
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_add(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ pjmedia_sdp_attr *attr);
+
+/**
+ * Remove all attributes with the specified name in array of attributes.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param name Attribute name to find.
+ *
+ * @return Number of attributes removed.
+ *
+ * @see pjmedia_sdp_media_remove_all_attr
+ */
+PJ_DECL(unsigned) pjmedia_sdp_attr_remove_all(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ const char *name);
+
+
+/**
+ * Remove the specified attribute from the attribute array.
+ *
+ * @param count Number of attributes in the array.
+ * @param attr_array Array of attributes.
+ * @param attr The attribute instance to remove.
+ *
+ * @return PJ_SUCCESS when attribute has been removed, or
+ * PJ_ENOTFOUND when the attribute can not be found.
+ *
+ * @see pjmedia_sdp_media_remove_attr
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_remove(unsigned *count,
+ pjmedia_sdp_attr *attr_array[],
+ pjmedia_sdp_attr *attr);
+
+
+/**
+ * This structure declares SDP \a rtpmap attribute.
+ */
+struct pjmedia_sdp_rtpmap
+{
+ pj_str_t pt; /**< Payload type. */
+ pj_str_t enc_name; /**< Encoding name. */
+ unsigned clock_rate; /**< Clock rate. */
+ pj_str_t param; /**< Parameter. */
+};
+
+/**
+ * @see pjmedia_sdp_rtpmap
+ */
+typedef struct pjmedia_sdp_rtpmap pjmedia_sdp_rtpmap;
+
+
+/**
+ * Convert generic attribute to SDP \a rtpmap. This function allocates
+ * a new attribute and call #pjmedia_sdp_attr_get_rtpmap().
+ *
+ * @param pool Pool used to create the rtpmap attribute.
+ * @param attr Generic attribute to be converted to rtpmap, which
+ * name must be "rtpmap".
+ * @param p_rtpmap Pointer to receive SDP rtpmap attribute.
+ *
+ * @return PJ_SUCCESS if the attribute can be successfully
+ * converted to \a rtpmap type.
+ *
+ * @see pjmedia_sdp_attr_get_rtpmap
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_to_rtpmap(pj_pool_t *pool,
+ const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtpmap **p_rtpmap);
+
+
+/**
+ * Get the rtpmap representation of the same SDP attribute.
+ *
+ * @param attr Generic attribute to be converted to rtpmap, which
+ * name must be "rtpmap".
+ * @param rtpmap SDP \a rtpmap attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if the attribute can be successfully
+ * converted to \a rtpmap attribute.
+ *
+ * @see pjmedia_sdp_attr_to_rtpmap
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtpmap(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtpmap *rtpmap);
+
+
+/**
+ * Convert \a rtpmap attribute to generic attribute.
+ *
+ * @param pool Pool to be used.
+ * @param rtpmap The \a rtpmap attribute.
+ * @param p_attr Pointer to receive the generic SDP attribute.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_rtpmap_to_attr( pj_pool_t *pool,
+ const pjmedia_sdp_rtpmap *rtpmap,
+ pjmedia_sdp_attr **p_attr);
+
+
+/**
+ * This structure describes SDP \a fmtp attribute.
+ */
+typedef struct pjmedia_sdp_fmtp
+{
+ pj_str_t fmt; /**< Format type. */
+ pj_str_t fmt_param; /**< Format specific parameter. */
+} pjmedia_sdp_fmtp;
+
+
+/**
+ * Get the fmtp representation of the same SDP attribute.
+ *
+ * @param attr Generic attribute to be converted to fmtp, which
+ * name must be "fmtp".
+ * @param fmtp SDP fmtp attribute to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_fmtp(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_fmtp *fmtp);
+
+
+/**
+ * This structure describes SDP \a rtcp attribute.
+ */
+typedef struct pjmedia_sdp_rtcp_attr
+{
+ unsigned port; /**< RTCP port number. */
+ pj_str_t net_type; /**< Optional network type. */
+ pj_str_t addr_type; /**< Optional address type. */
+ pj_str_t addr; /**< Optional address. */
+} pjmedia_sdp_rtcp_attr;
+
+
+/**
+ * Parse a generic SDP attribute to get SDP rtcp attribute values.
+ *
+ * @param attr Generic attribute to be converted to rtcp, which
+ * name must be "rtcp".
+ * @param rtcp SDP rtcp attribute to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,
+ pjmedia_sdp_rtcp_attr *rtcp);
+
+
+/**
+ * Create a=rtcp attribute.
+ *
+ * @param pool Pool to create the attribute.
+ * @param a Socket address.
+ *
+ * @return SDP RTCP attribute.
+ */
+PJ_DECL(pjmedia_sdp_attr*) pjmedia_sdp_attr_create_rtcp(pj_pool_t *pool,
+ const pj_sockaddr *a);
+
+
+/* **************************************************************************
+ * SDP CONNECTION INFO
+ ****************************************************************************
+ */
+
+/**
+ * This structure describes SDP connection info ("c=" line).
+ */
+struct pjmedia_sdp_conn
+{
+ pj_str_t net_type; /**< Network type ("IN"). */
+ pj_str_t addr_type; /**< Address type ("IP4", "IP6"). */
+ pj_str_t addr; /**< The address. */
+};
+
+
+/**
+ * @see pjmedia_sdp_conn
+ */
+typedef struct pjmedia_sdp_conn pjmedia_sdp_conn;
+
+
+/**
+ * Clone connection info.
+ *
+ * @param pool Pool to allocate memory for the new connection info.
+ * @param rhs The connection into to clone.
+ *
+ * @return The new connection info.
+ */
+PJ_DECL(pjmedia_sdp_conn*) pjmedia_sdp_conn_clone(pj_pool_t *pool,
+ const pjmedia_sdp_conn *rhs);
+
+
+/**
+ * Compare connection info.
+ *
+ * @param conn1 The first connection info to compare.
+ * @param conn1 The second connection info to compare.
+ * @param option Comparison option, which should be zero for now.
+ *
+ * @return PJ_SUCCESS when both connection info are equal, otherwise
+ * returns PJMEDIA_SDP_ECONNNOTEQUAL.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_conn_cmp(const pjmedia_sdp_conn *conn1,
+ const pjmedia_sdp_conn *conn2,
+ unsigned option);
+
+
+/* **************************************************************************
+ * SDP BANDWIDTH INFO
+ ****************************************************************************
+ */
+
+/**
+ * This structure describes SDP bandwidth info ("b=" line).
+ */
+typedef struct pjmedia_sdp_bandw
+{
+ pj_str_t modifier; /**< Bandwidth modifier. */
+ pj_uint32_t value; /**< Bandwidth value. */
+} pjmedia_sdp_bandw;
+
+
+/**
+ * Clone bandwidth info.
+ *
+ * @param pool Pool to allocate memory for the new bandwidth info.
+ * @param rhs The bandwidth into to clone.
+ *
+ * @return The new bandwidth info.
+ */
+PJ_DECL(pjmedia_sdp_bandw*)
+pjmedia_sdp_bandw_clone(pj_pool_t *pool, const pjmedia_sdp_bandw *rhs);
+
+
+
+/* **************************************************************************
+ * SDP MEDIA INFO/LINE
+ ****************************************************************************
+ */
+
+/**
+ * This structure describes SDP media descriptor. A SDP media descriptor
+ * starts with "m=" line and contains the media attributes and optional
+ * connection line.
+ */
+struct pjmedia_sdp_media
+{
+ /** Media descriptor line ("m=" line) */
+ struct
+ {
+ pj_str_t media; /**< Media type ("audio", "video") */
+ pj_uint16_t port; /**< Port number. */
+ unsigned port_count; /**< Port count, used only when >2 */
+ pj_str_t transport; /**< Transport ("RTP/AVP") */
+ unsigned fmt_count; /**< Number of formats. */
+ pj_str_t fmt[PJMEDIA_MAX_SDP_FMT]; /**< Media formats. */
+ } desc;
+
+ pjmedia_sdp_conn *conn; /**< Optional connection info. */
+ unsigned bandw_count; /**< Number of bandwidth info. */
+ pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW]; /**< Bandwidth info. */
+ unsigned attr_count; /**< Number of attributes. */
+ pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes. */
+
+};
+
+
+/**
+ * @see pjmedia_sdp_media
+ */
+typedef struct pjmedia_sdp_media pjmedia_sdp_media;
+
+
+/**
+ * Clone SDP media description.
+ *
+ * @param pool Pool to allocate memory for the new media description.
+ * @param rhs The media descriptin to clone.
+ *
+ * @return New media description.
+ */
+PJ_DECL(pjmedia_sdp_media*)
+pjmedia_sdp_media_clone( pj_pool_t *pool,
+ const pjmedia_sdp_media *rhs);
+
+/**
+ * Find the first occurence of the specified attribute name in the media
+ * descriptor. Optionally the format may be specified.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to find.
+ * @param fmt Optional payload type to match in the
+ * attribute list, when the attribute is \a rtpmap
+ * or \a fmtp. For other types of SDP attributes, this
+ * value should be NULL.
+ *
+ * @return The first instance of the specified attribute or NULL.
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_media_find_attr(const pjmedia_sdp_media *m,
+ const pj_str_t *name, const pj_str_t *fmt);
+
+
+/**
+ * Find the first occurence of the specified attribute name in the SDP media
+ * descriptor. Optionally the format may be specified.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to find.
+ * @param fmt Optional payload type to match in the
+ * attribute list, when the attribute is \a rtpmap
+ * or \a fmtp. For other types of SDP attributes, this
+ * value should be NULL.
+ *
+ * @return The first instance of the specified attribute or NULL.
+ */
+PJ_DECL(pjmedia_sdp_attr*)
+pjmedia_sdp_media_find_attr2(const pjmedia_sdp_media *m,
+ const char *name, const pj_str_t *fmt);
+
+/**
+ * Add new attribute to the media descriptor.
+ *
+ * @param m The SDP media description.
+ * @param attr Attribute to add.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_add_attr(pjmedia_sdp_media *m,
+ pjmedia_sdp_attr *attr);
+
+/**
+ * Remove all attributes with the specified name from the SDP media
+ * descriptor.
+ *
+ * @param m The SDP media description.
+ * @param name Attribute name to remove.
+ *
+ * @return The number of attributes removed.
+ */
+PJ_DECL(unsigned)
+pjmedia_sdp_media_remove_all_attr(pjmedia_sdp_media *m,
+ const char *name);
+
+
+/**
+ * Remove the occurence of the specified attribute from the SDP media
+ * descriptor.
+ *
+ * @param m The SDP media descriptor.
+ * @param attr The attribute to find and remove.
+ *
+ * @return PJ_SUCCESS if the attribute can be found and has
+ * been removed from the array.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_media_remove_attr(pjmedia_sdp_media *m,
+ pjmedia_sdp_attr *attr);
+
+
+/**
+ * Compare two SDP media for equality.
+ *
+ * @param sd1 The first SDP media to compare.
+ * @param sd2 The second SDP media to compare.
+ * @param option Comparison option, which should be zero for now.
+ *
+ * @return PJ_SUCCESS when both SDP medias are equal, or the
+ * appropriate status code describing which part of
+ * the descriptors that are not equal.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_cmp(const pjmedia_sdp_media *sd1,
+ const pjmedia_sdp_media *sd2,
+ unsigned option);
+
+
+/**
+ * Compare two media transports for compatibility.
+ *
+ * @param t1 The first media transport to compare.
+ * @param t2 The second media transport to compare.
+ *
+ * @return PJ_SUCCESS when both media transports are compatible,
+ * otherwise returns PJMEDIA_SDP_ETPORTNOTEQUAL.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_transport_cmp(const pj_str_t *t1,
+ const pj_str_t *t2);
+
+
+/**
+ * Deactivate SDP media.
+ *
+ * @param pool Memory pool to allocate memory from.
+ * @param m The SDP media to deactivate.
+ *
+ * @return PJ_SUCCESS when SDP media successfully deactivated,
+ * otherwise appropriate status code returned.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool,
+ pjmedia_sdp_media *m);
+
+
+/**
+ * Clone SDP media description and deactivate the new SDP media.
+ *
+ * @param pool Memory pool to allocate memory for the clone.
+ * @param rhs The SDP media to clone.
+ *
+ * @return New media descrption with deactivated indication.
+ */
+PJ_DECL(pjmedia_sdp_media*) pjmedia_sdp_media_clone_deactivate(
+ pj_pool_t *pool,
+ const pjmedia_sdp_media *rhs);
+
+
+/* **************************************************************************
+ * SDP SESSION DESCRIPTION
+ ****************************************************************************
+ */
+
+
+/**
+ * This structure describes SDP session description. A SDP session descriptor
+ * contains complete information about a session, and normally is exchanged
+ * with remote media peer using signaling protocol such as SIP.
+ */
+struct pjmedia_sdp_session
+{
+ /** Session origin (o= line) */
+ struct
+ {
+ pj_str_t user; /**< User */
+ pj_uint32_t id; /**< Session ID */
+ pj_uint32_t version; /**< Session version */
+ pj_str_t net_type; /**< Network type ("IN") */
+ pj_str_t addr_type; /**< Address type ("IP4", "IP6") */
+ pj_str_t addr; /**< The address. */
+ } origin;
+
+ pj_str_t name; /**< Subject line (s=) */
+ pjmedia_sdp_conn *conn; /**< Connection line (c=) */
+ unsigned bandw_count; /**< Number of bandwidth info (b=) */
+ pjmedia_sdp_bandw *bandw[PJMEDIA_MAX_SDP_BANDW];
+ /**< Bandwidth info array (b=) */
+
+ /** Session time (t= line) */
+ struct
+ {
+ pj_uint32_t start; /**< Start time. */
+ pj_uint32_t stop; /**< Stop time. */
+ } time;
+
+ unsigned attr_count; /**< Number of attributes. */
+ pjmedia_sdp_attr *attr[PJMEDIA_MAX_SDP_ATTR]; /**< Attributes array. */
+
+ unsigned media_count; /**< Number of media. */
+ pjmedia_sdp_media *media[PJMEDIA_MAX_SDP_MEDIA]; /**< Media array. */
+
+};
+
+/**
+ * @see pjmedia_sdp_session
+ */
+typedef struct pjmedia_sdp_session pjmedia_sdp_session;
+
+
+
+/**
+ * Parse SDP message.
+ *
+ * @param pool The pool to allocate SDP session description.
+ * @param buf The message buffer.
+ * @param len The length of the message.
+ * @param p_sdp Pointer to receive the SDP session descriptor.
+ *
+ * @return PJ_SUCCESS if message was successfully parsed into
+ * SDP session descriptor.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,
+ char *buf, pj_size_t len,
+ pjmedia_sdp_session **p_sdp );
+
+/**
+ * Print SDP description to a buffer.
+ *
+ * @param sdp The SDP session description.
+ * @param buf The buffer.
+ * @param size The buffer length.
+ *
+ * @return the length printed, or -1 if the buffer is too
+ * short.
+ */
+PJ_DECL(int) pjmedia_sdp_print( const pjmedia_sdp_session *sdp,
+ char *buf, pj_size_t size);
+
+
+/**
+ * Perform semantic validation for the specified SDP session descriptor.
+ * This function perform validation beyond just syntactic verification,
+ * such as to verify the value of network type and address type, check
+ * the connection line, and verify that \a rtpmap attribute is present
+ * when dynamic payload type is used.
+ *
+ * @param sdp The SDP session descriptor to validate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_validate(const pjmedia_sdp_session *sdp);
+
+
+/**
+ * Clone SDP session descriptor.
+ *
+ * @param pool The pool used to clone the session.
+ * @param sdp The SDP session to clone.
+ *
+ * @return New SDP session.
+ */
+PJ_DECL(pjmedia_sdp_session*)
+pjmedia_sdp_session_clone( pj_pool_t *pool,
+ const pjmedia_sdp_session *sdp);
+
+
+/**
+ * Compare two SDP session for equality.
+ *
+ * @param sd1 The first SDP session to compare.
+ * @param sd2 The second SDP session to compare.
+ * @param option Must be zero for now.
+ *
+ * @return PJ_SUCCESS when both SDPs are equal, or otherwise
+ * the status code indicates which part of the session
+ * descriptors are not equal.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_session_cmp(const pjmedia_sdp_session *sd1,
+ const pjmedia_sdp_session *sd2,
+ unsigned option);
+
+
+/**
+ * Add new attribute to the session descriptor.
+ *
+ * @param s The SDP session description.
+ * @param attr Attribute to add.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_session_add_attr(pjmedia_sdp_session *s,
+ pjmedia_sdp_attr *attr);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_SDP_H__ */
+
diff --git a/pjmedia/include/pjmedia/sdp_neg.h b/pjmedia/include/pjmedia/sdp_neg.h
new file mode 100644
index 0000000..74fcb16
--- /dev/null
+++ b/pjmedia/include/pjmedia/sdp_neg.h
@@ -0,0 +1,765 @@
+/* $Id: sdp_neg.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SDP_NEG_H__
+#define __PJMEDIA_SDP_NEG_H__
+
+
+/**
+ * @file sdp_neg.h
+ * @brief SDP negotiator header file.
+ */
+/**
+ * @defgroup PJMEDIA_SDP_NEG SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @ingroup PJMEDIA_SESSION
+ * @brief SDP Negotiation State Machine (Offer/Answer Model, RFC 3264)
+ * @{
+ *
+ * The header file <b><pjmedia/sdp_neg.h></b> contains the declaration
+ * of SDP offer and answer negotiator. SDP offer and answer model is described
+ * in RFC 3264 <b>"An Offer/Answer Model with Session Description Protocol
+ * (SDP)"</b>.
+ *
+ * The SDP negotiator is represented with opaque type \a pjmedia_sdp_neg.
+ * This structure contains negotiation state and several SDP session
+ * descriptors currently being used in the negotiation.
+ *
+ *
+ * \section sdpneg_state_dia SDP Negotiator State Diagram
+ *
+ * The following diagram describes the state transition diagram of the
+ * SDP negotiator.
+ *
+ * <pre>
+ *
+ * modify_local_offer()
+ * create_w_local_offer() +-------------+ send_local_offer()
+ * ----------------------->| LOCAL_OFFER |<-----------------------
+ * | +-------------+______ |
+ * | | \______ cancel() |
+ * | set_remote_answer() | \______ |
+ * | V \ |
+ * +--+---+ +-----------+ negotiate() +-~----+
+ * | NULL | | WAIT_NEGO |-------------------->| DONE |
+ * +------+ +-----------+ +------+
+ * | A |
+ * | set_local_answer() | |
+ * | | |
+ * | +--------------+ set_remote_offer() |
+ * ----------------------->| REMOTE_OFFER |<----------------------
+ * create_w_remote_offer() +--------------+
+ *
+ * </pre>
+ *
+ *
+ *
+ * \section sdpneg_offer_answer SDP Offer/Answer Model with Negotiator
+ *
+ * \subsection sdpneg_create_offer Creating Initial Offer
+ *
+ * Application creates an offer by manualy building the SDP session descriptor
+ * (pjmedia_sdp_session), or request PJMEDIA endpoint (pjmedia_endpt) to
+ * create SDP session descriptor based on capabilities that present in the
+ * endpoint by calling #pjmedia_endpt_create_sdp().
+ *
+ * Application then creates SDP negotiator instance by calling
+ * #pjmedia_sdp_neg_create_w_local_offer(), passing the SDP offer in the
+ * function arguments. The SDP negotiator keeps a copy of current local offer,
+ * and update its state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER.
+ *
+ * Application can then send the initial SDP offer that it creates to
+ * remote peer using signaling protocol such as SIP.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Generating Subsequent Offer
+ *
+ * The negotiator can only create subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ * If any previous negotiation process was successfull (i.e. the return
+ * value of #pjmedia_sdp_neg_negotiate() was PJ_SUCCESS), the negotiator
+ * keeps both active local and active remote SDP.
+ *
+ * If application does not want send modified offer, it can just send
+ * the active local SDP as the offer. In this case, application calls
+ * #pjmedia_sdp_neg_send_local_offer() to get the active local SDP.
+ *
+ * If application wants to modify it's local offer, it MUST inform
+ * the negotiator about the modified SDP by calling
+ * #pjmedia_sdp_neg_modify_local_offer().
+ *
+ * In both cases, the negotiator will internally create a copy of the offer,
+ * and move it's state to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it
+ * waits until application passes the remote answer.
+ *
+ *
+ * \subsection sdpneg_receive_offer Receiving Initial Offer
+ *
+ * Application receives an offer in the incoming request from remote to
+ * establish multimedia session, such as incoming INVITE message with SDP
+ * body.
+ *
+ * Initially, when the initial offer is received, application creates the
+ * SDP negotiator by calling #pjmedia_sdp_neg_create_w_remote_offer(),
+ * specifying the remote SDP offer in one of the argument.
+ *
+ * At this stage, application may or may not ready to create an answer.
+ * For example, a SIP B2BUA needs to make outgoing call and receive SDP
+ * from the outgoing call leg in order to create a SDP answer to the
+ * incoming call leg.
+ *
+ * If application is not ready to create an answer, it passes NULL as
+ * the local SDP when it calls #pjmedia_sdp_neg_create_w_remote_offer().
+ *
+ * The section @ref sdpneg_create_answer describes the case when
+ * application is ready to create a SDP answer.
+ *
+ *
+ * \subsection sdpneg_subseq_offer Receiving Subsequent Offer
+ *
+ * Application passes subsequent SDP offer received from remote by
+ * calling #pjmedia_sdp_neg_set_remote_offer().
+ *
+ * The negotiator can only receive subsequent offer after it has finished
+ * the negotiation process of previous offer/answer session (i.e. the
+ * negotiator state is PJMEDIA_SDP_NEG_STATE_DONE).
+ *
+ *
+ * \subsection sdpneg_recv_answer Receiving SDP Answer
+ *
+ * When application receives SDP answer from remote, it informs the
+ * negotiator by calling #pjmedia_sdp_neg_set_remote_answer(). The
+ * negotiator validates the answer (#pjmedia_sdp_validate()), and if
+ * succeeds, it moves it's state to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO.
+ *
+ * Application then instruct the negotiator to negotiate the remote
+ * answer by calling #pjmedia_sdp_neg_negotiate(). The purpose of
+ * this negotiation is to verify remote answer, and update the initial
+ * offer according to the answer. For example, the initial offer may
+ * specify that a stream is \a sendrecv, while the answer specifies
+ * that remote stream is \a inactive. In this case, the negotiator
+ * will update the stream in the local active media as \a inactive
+ * too.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the updated local answer and remote answer internally. These two
+ * SDPs are called active local SDP and active remote SDP, as it describes
+ * currently active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and active remote SDP by calling
+ * #pjmedia_sdp_neg_get_active_remote().
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ * \subsection sdpneg_cancel_offer Cancelling an Offer
+ *
+ * In other case, after an offer is generated (negotiator state is in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER), the answer may not be received, and
+ * application wants the negotiator to reset itself to its previous state.
+ * Consider this example:
+ *
+ * - media has been established, and negotiator state is
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ * - application generates a new offer for re-INVITE, so in this case
+ * it would either call #pjmedia_sdp_neg_send_local_offer() or
+ * #pjmedia_sdp_neg_modify_local_offer()
+ * - the negotiator state moves to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * - the re-INVITE was rejected with an error
+ *
+ * Since an answer is not received, it is necessary to reset the negotiator
+ * state back to PJMEDIA_SDP_NEG_STATE_DONE so that the negotiator can
+ * create or receive new offer.
+ *
+ * This can be accomplished by calling #pjmedia_sdp_neg_cancel_offer(),
+ * to reset the negotiator state back to PJMEDIA_SDP_NEG_STATE_DONE. In
+ * this case, both active local and active remote will not be modified.
+ *
+ * \subsection sdpneg_create_answer Generating SDP Answer
+ *
+ * After remote offer has been set in the negotiator, application can
+ * request the SDP negotiator to generate appropriate answer based on local
+ * capability.
+ *
+ * To do this, first the application MUST have an SDP describing its local
+ * capabilities. This SDP can be built manually, or application can generate
+ * SDP to describe local media endpoint capability by calling
+ * #pjmedia_endpt_create_sdp(). When the application is a SIP B2BUA,
+ * application can treat the SDP received from the outgoing call leg as if
+ * it was it's local capability.
+ *
+ * The local SDP session descriptor DOES NOT have to match the SDP offer.
+ * For example, it can have more or less media lines than the offer, or
+ * their order may be different than the offer. The negotiator is capable
+ * to match and reorder local SDP according to remote offer, and create
+ * an answer that is suitable for the offer.
+ *
+ * After local SDP capability has been acquired, application can create
+ * a SDP answer.
+ *
+ * If application does not already have the negotiator instance, it creates
+ * one by calling #pjmedia_sdp_neg_create_w_remote_offer(), specifying
+ * both remote SDP offer and local SDP as the arguments. The SDP negotiator
+ * validates both remote and local SDP by calling #pjmedia_sdp_validate(),
+ * and if both SDPs are valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * If application already has the negotiator instance, it sets the local
+ * SDP in the negotiator by calling #pjmedia_sdp_neg_set_local_answer().
+ * The SDP negotiator then validates local SDP (#pjmedia_sdp_validate() ),
+ * and if it is valid, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO where it is ready to negotiate the
+ * offer and answer.
+ *
+ * After the SDP negotiator state has moved to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+ * application calls #pjmedia_sdp_neg_negotiate() to instruct the SDP
+ * negotiator to negotiate both offer and answer. This function returns
+ * PJ_SUCCESS if an answer can be generated AND at least one media stream
+ * is active in the session.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns PJ_SUCCESS, the negotiator will
+ * keep the remote offer and local answer internally. These two SDPs are
+ * called active local SDP and active remote SDP, as it describes currently
+ * active session.
+ *
+ * Application can retrieve the active local SDP by calling
+ * #pjmedia_sdp_neg_get_active_local(), and send this SDP to remote as the
+ * SDP answer.
+ *
+ * If #pjmedia_sdp_neg_negotiate() returns failure (i.e. not PJ_SUCCESS),
+ * it WILL NOT update its active local and active remote SDP.
+ *
+ * Regardless of the return status of the #pjmedia_sdp_neg_negotiate(),
+ * the negotiator state will move to PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ *
+ */
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * This enumeration describes SDP negotiation state.
+ */
+enum pjmedia_sdp_neg_state
+{
+ /**
+ * This is the state of SDP negoator before it is initialized.
+ */
+ PJMEDIA_SDP_NEG_STATE_NULL,
+
+ /**
+ * This state occurs when SDP negotiator has sent our offer to remote and
+ * it is waiting for answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+
+ /**
+ * This state occurs when SDP negotiator has received offer from remote
+ * and currently waiting for local answer.
+ */
+ PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER,
+
+ /**
+ * This state occurs when an offer (either local or remote) has been
+ * provided with answer. The SDP negotiator is ready to negotiate both
+ * session descriptors. Application can call #pjmedia_sdp_neg_negotiate()
+ * immediately to begin negotiation process.
+ */
+ PJMEDIA_SDP_NEG_STATE_WAIT_NEGO,
+
+ /**
+ * This state occurs when SDP negotiation has completed, either
+ * successfully or not.
+ */
+ PJMEDIA_SDP_NEG_STATE_DONE
+};
+
+
+/**
+ * @see pjmedia_sdp_neg_state
+ */
+typedef enum pjmedia_sdp_neg_state pjmedia_sdp_neg_state;
+
+
+/**
+ * Opaque declaration of SDP negotiator.
+ */
+typedef struct pjmedia_sdp_neg pjmedia_sdp_neg;
+
+
+/**
+ * Get the state string description of the specified state.
+ *
+ * @param state Negotiator state.
+ *
+ * @return String description of the state.
+ */
+PJ_DECL(const char*) pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_state state);
+
+
+/**
+ * Create the SDP negotiator with local offer. The SDP negotiator then
+ * will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER state, where it waits
+ * until it receives answer from remote. When SDP answer from remote is
+ * received, application must call #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * After calling this function, application should send the local SDP offer
+ * to remote party using signaling protocol such as SIP and wait for SDP
+ * answer.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param local The initial local capability.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_local_offer( pj_pool_t *pool,
+ const pjmedia_sdp_session *local,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * Initialize the SDP negotiator with remote offer, and optionally
+ * specify the initial local capability, if known. Application normally
+ * calls this function when it receives initial offer from remote.
+ *
+ * If local media capability is specified, this capability will be set as
+ * initial local capability of the negotiator, and after this function is
+ * called, the SDP negotiator state will move to state
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and the negotiation function can be
+ * called.
+ *
+ * If local SDP is not specified, the negotiator will not have initial local
+ * capability, and after this function is called the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER state. Application MUST supply
+ * local answer later with #pjmedia_sdp_neg_set_local_answer(), before
+ * calling the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param initial Optional initial local capability.
+ * @param remote The remote offer.
+ * @param p_neg Pointer to receive the negotiator instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_create_w_remote_offer(pj_pool_t *pool,
+ const pjmedia_sdp_session *initial,
+ const pjmedia_sdp_session *remote,
+ pjmedia_sdp_neg **p_neg);
+
+/**
+ * This specifies the behavior of the SDP negotiator when responding to an
+ * offer, whether it should rather use the codec preference as set by
+ * remote, or should it rather use the codec preference as specified by
+ * local endpoint.
+ *
+ * For example, suppose incoming call has codec order "8 0 3", while
+ * local codec order is "3 0 8". If remote codec order is preferable,
+ * the selected codec will be 8, while if local codec order is preferable,
+ * the selected codec will be 3.
+ *
+ * By default, the value in PJMEDIA_SDP_NEG_PREFER_REMOTE_CODEC_ORDER will
+ * be used.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param prefer_remote If non-zero, the negotiator will use the codec
+ * order as specified in remote offer. If zero, it
+ * will prefer to use the local codec order.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_prefer_remote_codec_order(pjmedia_sdp_neg *neg,
+ pj_bool_t prefer_remote);
+
+
+/**
+ * Get SDP negotiator state.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return The negotiator state.
+ */
+PJ_DECL(pjmedia_sdp_neg_state)
+pjmedia_sdp_neg_get_state( pjmedia_sdp_neg *neg );
+
+/**
+ * Get the currently active local SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the local active SDP.
+ *
+ * @return PJ_SUCCESS if local active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Get the currently active remote SDP. Application can only call this
+ * function after negotiation has been done, or otherwise there won't be
+ * active SDPs. Calling this function will not change the state of the
+ * negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the remote active SDP.
+ *
+ * @return PJ_SUCCESS if remote active SDP is present.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_active_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Determine whether remote sent answer (as opposed to offer) on the
+ * last negotiation. This function can only be called in state
+ * PJMEDIA_SDP_NEG_STATE_DONE.
+ *
+ * @param neg The SDP negotiator instance.
+ *
+ * @return Non-zero if it was remote who sent answer,
+ * otherwise zero if it was local who supplied
+ * answer.
+ */
+PJ_DECL(pj_bool_t)
+pjmedia_sdp_neg_was_answer_remote(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Get the current remote SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be remote
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param remote Pointer to receive the current remote offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * remote offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_remote( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **remote);
+
+
+/**
+ * Get the current local SDP offer or answer. Application can only
+ * call this function in state PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or
+ * PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, or otherwise there won't be local
+ * SDP offer/answer. Calling this function will not change the state
+ * of the negotiator.
+ *
+ * @param neg The SDP negotiator instance.
+ * @param local Pointer to receive the current local offer or
+ * answer.
+ *
+ * @return PJ_SUCCESS if the negotiator currently has
+ * local offer or answer.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_get_neg_local( pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **local);
+
+/**
+ * Modify local session with a new SDP and treat this as a new offer.
+ * This function can only be called in state PJMEDIA_SDP_NEG_STATE_DONE.
+ * After calling this function, application can send the SDP as offer
+ * to remote party, using signaling protocol such as SIP.
+ * The negotiator state will move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER,
+ * where it waits for SDP answer from remote.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local The new local SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_modify_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function to retrieve currently active
+ * local SDP, and then send the SDP to remote as an offer. The negotiator
+ * state will then move to PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER, where it waits
+ * for SDP answer from remote.
+ *
+ * When SDP answer has been received from remote, application must call
+ * #pjmedia_sdp_neg_set_remote_answer().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param offer Pointer to receive active local SDP to be
+ * offered to remote.
+ *
+ * @return PJ_SUCCESS if local offer can be created.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_send_local_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session **offer);
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_send_local_offer()
+ * function. Application calls this function when it receives SDP answer
+ * from remote. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote answer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_DONE state.
+ * Application calls this function when it receives SDP offer from remote.
+ * After this function is called, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER, and application MUST call the
+ * #pjmedia_sdp_neg_set_local_answer() to set local answer before it can
+ * call the negotiation function.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param remote The remote offer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_remote_offer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *remote);
+
+
+
+/**
+ * This function can only be called in PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state, i.e. after application calls #pjmedia_sdp_neg_set_remote_offer()
+ * function. After this function is called, the negotiator state will
+ * move to PJMEDIA_SDP_NEG_STATE_WAIT_NEGO, and application can call the
+ * negotiation function #pjmedia_sdp_neg_negotiate().
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param local Optional local answer. If negotiator has initial
+ * local capability, application can specify NULL on
+ * this argument; in this case, the negotiator will
+ * create answer by by negotiating remote offer with
+ * initial local capability. If negotiator doesn't have
+ * initial local capability, application MUST specify
+ * local answer here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_sdp_neg_set_local_answer( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ const pjmedia_sdp_session *local);
+
+
+/**
+ * Call this function when the negotiator is in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO
+ * state to see if it was local who is answering the offer (instead of
+ * remote).
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_TRUE if it is local is answering an offer, PJ_FALSE
+ * if remote has answered local offer.
+ */
+PJ_DECL(pj_bool_t) pjmedia_sdp_neg_has_local_answer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Cancel any pending offer, whether the offer is initiated by local or
+ * remote, and move negotiator state back to previous stable state
+ * (PJMEDIA_SDP_NEG_STATE_DONE). The negotiator must be in
+ * PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER or PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER
+ * state.
+ *
+ * @param neg The negotiator.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_cancel_offer(pjmedia_sdp_neg *neg);
+
+
+/**
+ * Negotiate local and remote answer. Before calling this function, the
+ * SDP negotiator must be in PJMEDIA_SDP_NEG_STATE_WAIT_NEGO state.
+ * After calling this function, the negotiator state will move to
+ * PJMEDIA_SDP_NEG_STATE_DONE regardless whether the negotiation has
+ * been successfull or not.
+ *
+ * If the negotiation succeeds (i.e. the return value is PJ_SUCCESS),
+ * the active local and remote SDP will be replaced with the new SDP
+ * from the negotiation process.
+ *
+ * If the negotiation fails, the active local and remote SDP will not
+ * change.
+ *
+ * @param pool Pool to allocate memory. The pool's lifetime needs
+ * to be valid for the duration of the negotiator.
+ * @param neg The SDP negotiator instance.
+ * @param allow_asym Should be zero.
+ *
+ * @return PJ_SUCCESS when there is at least one media
+ * is actuve common in both offer and answer, or
+ * failure code when negotiation has failed.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_negotiate( pj_pool_t *pool,
+ pjmedia_sdp_neg *neg,
+ pj_bool_t allow_asym);
+
+
+/**
+ * Enumeration of customized SDP format matching option flags. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ */
+typedef enum pjmedia_sdp_neg_fmt_match_flag
+{
+ /**
+ * In generating answer, the SDP fmtp in the answer candidate may need
+ * to be modified by the customized SDP format matching callback to
+ * achieve flexible SDP negotiation, e.g: AMR fmtp 'octet-align' field
+ * can be adjusted with the offer when the codec implementation support
+ * both packetization modes octet-aligned and bandwidth-efficient.
+ */
+ PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER = 1,
+
+} pjmedia_sdp_neg_fmt_match_flag;
+
+
+/**
+ * The declaration of customized SDP format matching callback. See
+ * #pjmedia_sdp_neg_register_fmt_match_cb() for more info.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+typedef pj_status_t (*pjmedia_sdp_neg_fmt_match_cb)(pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+/**
+ * Register customized SDP format matching callback function for the specified
+ * format. The customized SDP format matching is needed when the format
+ * identification in a media stream session cannot be simply determined by
+ * encoding name and clock rate, but also involves one or more format specific
+ * parameters, which are specified in SDP fmtp attribute. For example,
+ * an H.264 video stream is also identified by profile, level, and
+ * packetization-mode parameters. As those parameters are format specifics,
+ * the negotiation must be done by the format or codec implementation.
+ *
+ * To unregister the callback of specific format, just call this function with
+ * parameter #cb set to NULL.
+ *
+ * @param fmt_name The format name, e.g: "H.264", "AMR", "G7221". Note
+ * that the string buffer must remain valid until the
+ * callback is unregistered.
+ * @param cb The customized SDP format negotiation callback or
+ * NULL to unregister the specified format callback.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb(
+ const pj_str_t *fmt_name,
+ pjmedia_sdp_neg_fmt_match_cb cb);
+
+
+/**
+ * Match format in the SDP media offer and answer. The matching mechanism
+ * will be done by comparing the encoding name and clock rate, and if the
+ * custom format matching callback for the specified format is registered,
+ * see #pjmedia_sdp_neg_register_fmt_match_cb(), it will be called for more
+ * detail verification, e.g: format parameters specified in SDP fmtp.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_sdp_neg_fmt_match( pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_SDP_NEG_H__ */
+
diff --git a/pjmedia/include/pjmedia/session.h b/pjmedia/include/pjmedia/session.h
new file mode 100644
index 0000000..3115600
--- /dev/null
+++ b/pjmedia/include/pjmedia/session.h
@@ -0,0 +1,436 @@
+/* $Id: session.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SESSION_H__
+#define __PJMEDIA_SESSION_H__
+
+
+/**
+ * @file session.h
+ * @brief Media Session.
+ */
+
+#include <pjmedia/endpoint.h>
+#include <pjmedia/stream.h>
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_SESSION Media Sessions
+ * @brief Management of media sessions
+ * @{
+ *
+ * A media session represents multimedia communication between two
+ * parties. A media session represents the multimedia session that
+ * is described by SDP session descriptor. A media session consists
+ * of one or more media streams (pjmedia_stream), where each stream
+ * represents one media line (m= line) in SDP.
+ *
+ * This module provides functions to create and manage multimedia
+ * sessions.
+ *
+ * Application creates the media session by calling #pjmedia_session_create(),
+ * normally after it has completed negotiating both SDP offer and answer.
+ * The session creation function creates the media session (including
+ * media streams) based on the content of local and remote SDP.
+ */
+
+
+/**
+ * Session info, retrieved from a session by calling
+ * #pjmedia_session_get_info().
+ */
+struct pjmedia_session_info
+{
+ /** Number of streams. */
+ unsigned stream_cnt;
+
+ /** Individual stream info. */
+ pjmedia_stream_info stream_info[PJMEDIA_MAX_SDP_MEDIA];
+};
+
+
+/**
+ * Opaque declaration of media session.
+ */
+typedef struct pjmedia_session pjmedia_session;
+
+
+/**
+ * @see pjmedia_session_info.
+ */
+typedef struct pjmedia_session_info pjmedia_session_info;
+
+
+/**
+ * This function will initialize the session info based on information
+ * in both SDP session descriptors. The remaining information will be
+ * taken from default codec parameters. If socket info array is specified,
+ * the socket will be copied to the session info as well.
+ *
+ * @param pool Pool to allocate memory.
+ * @param endpt Pjmedia endpoint.
+ * @param max_streams Maximum number of stream infos to be created.
+ * @param si Session info structure to be initialized.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_info_from_sdp( pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ unsigned max_streams,
+ pjmedia_session_info *si,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote);
+
+
+/**
+ * This function will initialize the stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_info_from_sdp( pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
+
+/**
+ * Create media session based on the local and remote SDP. After the session
+ * has been created, application normally would want to get the media port
+ * interface of each streams, by calling #pjmedia_session_get_port(). The
+ * media port interface exports put_frame() and get_frame() function, used
+ * to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the session.
+ *
+ * @param endpt The PJMEDIA endpoint instance.
+ * @param si Session info containing stream count and array of
+ * stream info. The stream count indicates how many
+ * streams to be created in the session.
+ * @param transports Array of media stream transports, with
+ * sufficient number of elements (one for each stream).
+ * @param user_data Arbitrary user data to be kept in the session.
+ * @param p_session Pointer to receive the media session.
+ *
+ * @return PJ_SUCCESS if media session can be created
+ * successfully.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_create( pjmedia_endpt *endpt,
+ const pjmedia_session_info *si,
+ pjmedia_transport *transports[],
+ void *user_data,
+ pjmedia_session **p_session );
+
+
+/**
+ * Get media session info of the session.
+ *
+ * @param session The session which info is being queried.
+ * @param info Pointer to receive session info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_info( pjmedia_session *session,
+ pjmedia_session_info *info );
+
+/**
+ * Get user data of the session.
+ *
+ * @param session The session being queried.
+ *
+ * @return User data of the session.
+ */
+PJ_DECL(void*) pjmedia_session_get_user_data( pjmedia_session *session);
+
+
+/**
+ * Activate all streams in media session for the specified direction.
+ * Application only needs to call this function if it previously paused
+ * the session.
+ *
+ * @param session The media session.
+ * @param dir The direction to activate.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_resume(pjmedia_session *session,
+ pjmedia_dir dir);
+
+
+/**
+ * Suspend receipt and transmission of all streams in media session
+ * for the specified direction.
+ *
+ * @param session The media session.
+ * @param dir The media direction to suspend.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_pause(pjmedia_session *session,
+ pjmedia_dir dir);
+
+/**
+ * Suspend receipt and transmission of individual stream in media session
+ * for the specified direction.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param dir The media direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_pause_stream( pjmedia_session *session,
+ unsigned index,
+ pjmedia_dir dir);
+
+/**
+ * Activate individual stream in media session for the specified direction.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param dir The media direction to activate.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_resume_stream(pjmedia_session *session,
+ unsigned index,
+ pjmedia_dir dir);
+
+/**
+ * Send RTCP SDES for the session.
+ *
+ * @param session The media session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_send_rtcp_sdes( const pjmedia_session *session );
+
+/**
+ * Send RTCP BYE for the session.
+ *
+ * @param session The media session.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_send_rtcp_bye( const pjmedia_session *session );
+
+/**
+ * Enumerate media streams in the session.
+ *
+ * @param session The media session.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the number will be filled
+ * with number of streams in the session.
+ * @param strm_info Array of stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_enum_streams( const pjmedia_session *session,
+ unsigned *count,
+ pjmedia_stream_info strm_info[]);
+
+
+/**
+ * Get the media port interface of the specified stream. The media port
+ * interface declares put_frame() and get_frame() function, which is the
+ * only way for application to transmit and receive media frames from the
+ * stream.
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param p_port Pointer to receive the media port interface for
+ * the specified stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_port( pjmedia_session *session,
+ unsigned index,
+ pjmedia_port **p_port);
+
+
+/**
+ * Get session statistics. The stream statistic shows various
+ * indicators such as packet count, packet lost, jitter, delay, etc.
+ * See also #pjmedia_session_get_stream_stat_jbuf()
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param stat Stream statistic.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat(pjmedia_session *session,
+ unsigned index,
+ pjmedia_rtcp_stat *stat);
+
+
+/**
+ * Reset session statistics.
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_reset_stream_stat(pjmedia_session *session,
+ unsigned index);
+
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+/**
+ * Get extended session statistics. The extended statistic shows reports
+ * from RTCP XR, such as per interval statistics summary (packet count,
+ * packet lost, jitter, etc), VoIP metrics (delay, quality, etc)
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param stat_xr Stream extended statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_xr(
+ pjmedia_session *session,
+ unsigned index,
+ pjmedia_rtcp_xr_stat *stat_xr);
+#endif
+
+
+/**
+ * Get current jitter buffer state for the specified stream.
+ * See also #pjmedia_session_get_stream_stat()
+ *
+ * @param session The media session.
+ * @param index Stream index.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_stream_stat_jbuf(
+ pjmedia_session *session,
+ unsigned index,
+ pjmedia_jb_state *state);
+
+/**
+ * Dial DTMF digit to the stream, using RFC 2833 mechanism.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param ascii_digits String of ASCII digits (i.e. 0-9*##A-B).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_dial_dtmf( pjmedia_session *session,
+ unsigned index,
+ const pj_str_t *ascii_digits );
+
+
+/**
+ * Check if the specified stream has received DTMF digits.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has DTMF digits.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_check_dtmf( pjmedia_session *session,
+ unsigned index);
+
+
+/**
+ * Retrieve DTMF digits from the specified stream.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param ascii_digits Buffer to receive the digits. The length of this
+ * buffer is indicated in the "size" argument.
+ * @param size On input, contains the maximum digits to be copied
+ * to the buffer.
+ * On output, it contains the actual digits that has
+ * been copied to the buffer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_get_dtmf( pjmedia_session *session,
+ unsigned index,
+ char *ascii_digits,
+ unsigned *size );
+
+/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param session The media session.
+ * @param index The stream index.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_session_set_dtmf_callback(pjmedia_session *session,
+ unsigned index,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+/**
+ * Destroy media session.
+ *
+ * @param session The media session.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pjmedia_session_destroy(pjmedia_session *session);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_SESSION_H__ */
diff --git a/pjmedia/include/pjmedia/signatures.h b/pjmedia/include/pjmedia/signatures.h
new file mode 100644
index 0000000..6fadbc3
--- /dev/null
+++ b/pjmedia/include/pjmedia/signatures.h
@@ -0,0 +1,217 @@
+/* $Id: signatures.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2011-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SIGNATURES_H__
+#define __PJMEDIA_SIGNATURES_H__
+
+/**
+ * @file pjmedia/signatures.h
+ * @brief Standard PJMEDIA object signatures
+ */
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_SIG Object Signatures
+ * @ingroup PJMEDIA_BASE
+ * @brief Standard PJMEDIA object signatures
+ * @{
+ *
+ * Object signature is a 32-bit integral value similar to FOURCC to help
+ * identify PJMEDIA objects such as media ports, transports, codecs, etc.
+ * There are several uses of this signature, for example a media port can
+ * use the port object signature to verify that the given port instance
+ * is the one that it created, and a receiver of \ref PJMEDIA_EVENT can
+ * use the signature of the publisher to know which object emitted the
+ * event.
+ *
+ * The 32-bit value of an object signature is generated by the following
+ * macro:
+ *
+ * \verbatim
+ #define PJMEDIA_SIGNATURE(a,b,c,d) (a<<24 | b<<16 | c<<8 | d)
+ * \endverbatim
+ *
+ * The following convention is used to maintain order to the signature
+ * values so that application can make use of it more effectively, and to
+ * avoid conflict between the values themselves. For each object type or
+ * class, a specific prefix will be assigned as signature, and a macro
+ * is created to build a signature for such object:
+ *
+ * \verbatim
+ Class Signature Signature creation and test macros
+ ---------------------------------------------------------------
+ Codec Cxxx PJMEDIA_SIG_CLASS_CODEC(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_CODEC(sig)
+
+ Audio codec CAxx PJMEDIA_SIG_CLASS_AUD_CODEC(c,d)
+ PJMEDIA_SIG_IS_CLASS_AUD_CODEC(sig)
+
+ Video codec CVxx PJMEDIA_SIG_CLASS_VID_CODEC(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig)
+
+ Media port Pxxx PJMEDIA_SIG_CLASS_PORT(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT(sig)
+
+ Audio media port PAxx PJMEDIA_SIG_CLASS_PORT_AUD(c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT_AUD(sig)
+
+ Video media port PVxx PJMEDIA_SIG_CLASS_PORT_VID(c,d)
+ PJMEDIA_SIG_IS_CLASS_PORT_VID(sig)
+
+ Video device VDxx PJMEDIA_SIG_CLASS_VID_DEV(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_DEV(sig)
+
+ Video other VOxx PJMEDIA_SIG_CLASS_VID_OTHER(c,d)
+ PJMEDIA_SIG_IS_CLASS_VID_OTHER(sig)
+
+ Application object Axxx PJMEDIA_SIG_CLASS_APP(b,c,d)
+ PJMEDIA_SIG_IS_CLASS_APP(sig)
+
+ * \endverbatim
+ *
+ * In addition, signatures created in application code should have lowercase
+ * letters to avoid conflict with built-in objects.
+ */
+
+/**
+ * Type to store object signature.
+ */
+typedef pj_uint32_t pjmedia_obj_sig;
+
+/**
+ * A utility function to convert signature to four letters string.
+ *
+ * @param sig The signature value.
+ * @param buf Buffer to store the string, which MUST be at least
+ * five bytes long.
+ *
+ * @return The string.
+ */
+PJ_INLINE(const char*) pjmedia_sig_name(pjmedia_obj_sig sig, char buf[])
+{
+ return pjmedia_fourcc_name(sig, buf);
+}
+
+/**
+ * Macro to generate signature from four ASCII letters.
+ */
+#define PJMEDIA_SIGNATURE(a,b,c,d) PJMEDIA_FOURCC(a,b,c,d)
+
+/*************************************************************************
+ * Codec signature ('Cxxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_CODEC(b,c,d) PJMEDIA_SIGNATURE('C',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_CODEC(sig) ((sig) >> 24 == 'C')
+
+/*************************************************************************
+ * Audio codec signatures ('CAxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_AUD_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('A',c,d)
+#define PJMEDIA_SIG_IS_CLASS_AUD_CODEC(s) ((s)>>24=='C' && (s)>>16=='A')
+
+/*************************************************************************
+ * Video codec signatures ('CVxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_CODEC(c,d) PJMEDIA_SIG_CLASS_CODEC('V',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_CODEC(sig) ((s)>>24=='C' && (s)>>16=='V')
+
+#define PJMEDIA_SIG_VID_CODEC_FFMPEG PJMEDIA_SIG_CLASS_VID_CODEC('F','F')
+
+/*************************************************************************
+ * Port signatures ('Pxxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT(b,c,d) PJMEDIA_SIGNATURE('P',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT(sig) ((sig) >> 24 == 'P')
+
+/*************************************************************************
+ * Audio ports signatures ('PAxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT_AUD(c,d) PJMEDIA_SIG_CLASS_PORT('A',c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT_AUD(s) ((s)>>24=='P' && (s)>>16=='A')
+
+#define PJMEDIA_SIG_PORT_BIDIR PJMEDIA_SIG_CLASS_PORT_AUD('B','D')
+#define PJMEDIA_SIG_PORT_CONF PJMEDIA_SIG_CLASS_PORT_AUD('C','F')
+#define PJMEDIA_SIG_PORT_CONF_PASV PJMEDIA_SIG_CLASS_PORT_AUD('C','P')
+#define PJMEDIA_SIG_PORT_CONF_SWITCH PJMEDIA_SIG_CLASS_PORT_AUD('C','S')
+#define PJMEDIA_SIG_PORT_ECHO PJMEDIA_SIG_CLASS_PORT_AUD('E','C')
+#define PJMEDIA_SIG_PORT_MEM_CAPTURE PJMEDIA_SIG_CLASS_PORT_AUD('M','C')
+#define PJMEDIA_SIG_PORT_MEM_PLAYER PJMEDIA_SIG_CLASS_PORT_AUD('M','P')
+#define PJMEDIA_SIG_PORT_NULL PJMEDIA_SIG_CLASS_PORT_AUD('N','U')
+#define PJMEDIA_SIG_PORT_RESAMPLE PJMEDIA_SIG_CLASS_PORT_AUD('R','E')
+#define PJMEDIA_SIG_PORT_SPLIT_COMB PJMEDIA_SIG_CLASS_PORT_AUD('S','C')
+#define PJMEDIA_SIG_PORT_SPLIT_COMB_P PJMEDIA_SIG_CLASS_PORT_AUD('S','P')
+#define PJMEDIA_SIG_PORT_STEREO PJMEDIA_SIG_CLASS_PORT_AUD('S','R')
+#define PJMEDIA_SIG_PORT_STREAM PJMEDIA_SIG_CLASS_PORT_AUD('S','T')
+#define PJMEDIA_SIG_PORT_TONEGEN PJMEDIA_SIG_CLASS_PORT_AUD('T','O')
+#define PJMEDIA_SIG_PORT_WAV_PLAYER PJMEDIA_SIG_CLASS_PORT_AUD('W','P')
+#define PJMEDIA_SIG_PORT_WAV_PLAYLIST PJMEDIA_SIG_CLASS_PORT_AUD('W','Y')
+#define PJMEDIA_SIG_PORT_WAV_WRITER PJMEDIA_SIG_CLASS_PORT_AUD('W','W')
+
+
+/*************************************************************************
+ * Video ports signatures ('PVxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_PORT_VID(c,d) PJMEDIA_SIG_CLASS_PORT('V',c,d)
+#define PJMEDIA_SIG_IS_CLASS_PORT_VID(s) ((s)>>24=='P' && (s)>>16=='V')
+
+/** AVI player signature. */
+#define PJMEDIA_SIG_PORT_VID_AVI_PLAYER PJMEDIA_SIG_CLASS_PORT_VID('A','V')
+#define PJMEDIA_SIG_PORT_VID_STREAM PJMEDIA_SIG_CLASS_PORT_VID('S','T')
+#define PJMEDIA_SIG_PORT_VID_TEE PJMEDIA_SIG_CLASS_PORT_VID('T','E')
+
+
+/**************************************************************************
+ * Video device signatures ('VDxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_DEV(c,d) PJMEDIA_SIGNATURE('V','D',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_DEV(s) ((s)>>24=='V' && (s)>>16=='D')
+
+#define PJMEDIA_SIG_VID_DEV_COLORBAR PJMEDIA_SIG_CLASS_VID_DEV('C','B')
+#define PJMEDIA_SIG_VID_DEV_SDL PJMEDIA_SIG_CLASS_VID_DEV('S','D')
+#define PJMEDIA_SIG_VID_DEV_V4L2 PJMEDIA_SIG_CLASS_VID_DEV('V','2')
+#define PJMEDIA_SIG_VID_DEV_DSHOW PJMEDIA_SIG_CLASS_VID_DEV('D','S')
+#define PJMEDIA_SIG_VID_DEV_QT PJMEDIA_SIG_CLASS_VID_DEV('Q','T')
+#define PJMEDIA_SIG_VID_DEV_IOS PJMEDIA_SIG_CLASS_VID_DEV('I','P')
+
+
+/*********************************************************************
+ * Other video objects ('VOxx'). Please keep the constant names sorted.
+ */
+#define PJMEDIA_SIG_CLASS_VID_OTHER(c,d) PJMEDIA_SIGNATURE('V','O',c,d)
+#define PJMEDIA_SIG_IS_CLASS_VID_OTHER(s) ((s)>>24=='V' && (s)>>16=='O')
+
+#define PJMEDIA_SIG_VID_PORT PJMEDIA_SIG_CLASS_VID_OTHER('P','O')
+
+
+/*********************************************************************
+ * Application class ('Axxx').
+ */
+#define PJMEDIA_SIG_CLASS_APP(b,c,d) PJMEDIA_SIGNATURE('A',b,c,d)
+#define PJMEDIA_SIG_IS_CLASS_APP(s) ((s)>>24=='A')
+
+
+/**
+ * @} PJSIP_MSG
+ */
+
+
+PJ_END_DECL
+
+#endif /* __PJMEDIA_SIGNATURES_H__ */
diff --git a/pjmedia/include/pjmedia/silencedet.h b/pjmedia/include/pjmedia/silencedet.h
new file mode 100644
index 0000000..82741de
--- /dev/null
+++ b/pjmedia/include/pjmedia/silencedet.h
@@ -0,0 +1,200 @@
+/* $Id: silencedet.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SILENCE_DET_H__
+#define __PJMEDIA_SILENCE_DET_H__
+
+
+/**
+ * @file silencedet.h
+ * @brief Adaptive silence detector.
+ */
+#include <pjmedia/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_SILENCEDET Adaptive Silence Detection
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Adaptive Silence Detector
+ * @{
+ */
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for silence detector.
+ */
+typedef struct pjmedia_silence_det pjmedia_silence_det;
+
+
+
+/**
+ * Create voice activity detector with default settings. The default settings
+ * are set to adaptive silence detection with the default threshold.
+ *
+ * @param pool Pool for allocating the structure.
+ * @param clock_rate Clock rate.
+ * @param samples_per_frame Number of samples per frame. The clock_rate and
+ * samples_per_frame is only used to calculate the
+ * frame time, from which some timing parameters
+ * are calculated from.
+ * @param p_sd Pointer to receive the silence detector instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ pjmedia_silence_det **p_sd );
+
+
+/**
+ * Set silence detector name to identify the particular silence detector
+ * instance in the log.
+ *
+ * @param sd The silence detector.
+ * @param name Name.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_name(pjmedia_silence_det *sd,
+ const char *name);
+
+
+/**
+ * Set the sd to operate in fixed threshold mode. With fixed threshold mode,
+ * the threshold will not be changed adaptively.
+ *
+ * @param sd The silence detector
+ * @param threshold The silence threshold, or -1 to use default
+ * threshold.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd,
+ int threshold );
+
+/**
+ * Set the sd to operate in adaptive mode. This is the default mode
+ * when the silence detector is created.
+ *
+ * @param sd The silence detector
+ * @param threshold Initial threshold to be set, or -1 to use default
+ * threshold.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd,
+ int threshold);
+
+/**
+ * Set other silence detector parameters.
+ *
+ * @param sd The silence detector
+ * @param before_silence Minimum duration of silence (in msec) before
+ * silence is reported. If -1 is specified, then
+ * the default value will be used. The default is
+ * 400 msec.
+ * @param recalc_time1 The interval (in msec) to recalculate threshold
+ * in non-silence condition when adaptive silence
+ * detection is set. If -1 is specified, then the
+ * default value will be used. The default is 4000
+ * (msec).
+ * @param recalc_time2 The interval (in msec) to recalculate threshold
+ * in silence condition when adaptive silence detection
+ * is set. If -1 is specified, then the default value
+ * will be used. The default value is 2000 (msec).
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd,
+ int before_silence,
+ int recalc_time1,
+ int recalc_time2);
+
+
+/**
+ * Disable the silence detector.
+ *
+ * @param sd The silence detector
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd );
+
+
+/**
+ * Perform voice activity detection on the given input samples. This
+ * function uses #pjmedia_calc_avg_signal() and #pjmedia_silence_det_apply()
+ * for its calculation.
+ *
+ * @param sd The silence detector instance.
+ * @param samples Pointer to 16-bit PCM input samples.
+ * @param count Number of samples in the input.
+ * @param p_level Optional pointer to receive average signal level
+ * of the input samples.
+ *
+ * @return Non zero if signal is silence.
+ */
+PJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd,
+ const pj_int16_t samples[],
+ pj_size_t count,
+ pj_int32_t *p_level);
+
+
+/**
+ * Calculate average signal level for the given samples.
+ *
+ * @param samples Pointer to 16-bit PCM samples.
+ * @param count Number of samples in the input.
+ *
+ * @return The average signal level, which simply is total level
+ * divided by number of samples.
+ */
+PJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[],
+ pj_size_t count );
+
+
+
+/**
+ * Perform voice activity detection, given the specified average signal
+ * level.
+ *
+ * @param sd The silence detector instance.
+ * @param level Signal level.
+ *
+ * @return Non zero if signal is silence.
+ */
+PJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd,
+ pj_uint32_t level);
+
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_SILENCE_DET_H__ */
+
diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h
new file mode 100644
index 0000000..03c8f1b
--- /dev/null
+++ b/pjmedia/include/pjmedia/sound.h
@@ -0,0 +1,336 @@
+/* $Id: sound.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SOUND_H__
+#define __PJMEDIA_SOUND_H__
+
+
+/**
+ * @file sound.h
+ * @brief Legacy sound device API
+ */
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/types.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_SND Portable Sound Hardware Abstraction
+ * @ingroup PJMED_SND_PORT
+ * @brief PJMEDIA abstraction for sound device hardware
+ * @{
+ *
+ * <strong>Warning: this sound device API has been deprecated
+ * and replaced by PJMEDIA Audio Device API. Please see
+ * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more
+ * information.</strong>
+ *
+ * This section describes lower level abstraction for sound device
+ * hardware. Application normally uses the higher layer @ref
+ * PJMED_SND_PORT abstraction since it works seamlessly with
+ * @ref PJMEDIA_PORT.
+ *
+ * The sound hardware abstraction basically runs <b>asychronously</b>,
+ * and application must register callbacks to be called to receive/
+ * supply audio frames from/to the sound hardware.
+ *
+ * A full duplex sound stream (created with #pjmedia_snd_open())
+ * requires application to supply two callbacks:
+ * - <b><tt>rec_cb</tt></b> callback to be called when it has finished
+ * capturing one media frame, and
+ * - <b><tt>play_cb</tt></b> callback to be called when it needs media
+ * frame to be played to the sound playback hardware.
+ *
+ * Half duplex sound stream (created with #pjmedia_snd_open_rec() or
+ * #pjmedia_snd_open_player()) will only need one of the callback to
+ * be specified.
+ *
+ * After sound stream is created, application need to call
+ * #pjmedia_snd_stream_start() to start capturing/playing back media
+ * frames from/to the sound device.
+ */
+
+/** Opaque declaration for pjmedia_snd_stream. */
+typedef struct pjmedia_snd_stream pjmedia_snd_stream;
+
+/**
+ * Device information structure returned by #pjmedia_snd_get_dev_info.
+ */
+typedef struct pjmedia_snd_dev_info
+{
+ char name[64]; /**< Device name. */
+ unsigned input_count; /**< Max number of input channels. */
+ unsigned output_count; /**< Max number of output channels. */
+ unsigned default_samples_per_sec;/**< Default sampling rate. */
+} pjmedia_snd_dev_info;
+
+/**
+ * Stream information, can be retrieved from a live stream by calling
+ * #pjmedia_snd_stream_get_info().
+ */
+typedef struct pjmedia_snd_stream_info
+{
+ pjmedia_dir dir; /**< Stream direction. */
+ int play_id; /**< Playback dev id, or -1 for rec only*/
+ int rec_id; /**< Capture dev id, or -1 for play only*/
+ unsigned clock_rate; /**< Actual clock rate. */
+ unsigned channel_count; /**< Number of channels. */
+ unsigned samples_per_frame; /**< Samples per frame. */
+ unsigned bits_per_sample; /**< Bits per sample. */
+ unsigned rec_latency; /**< Record latency, in samples. */
+ unsigned play_latency; /**< Playback latency, in samples. */
+} pjmedia_snd_stream_info;
+
+/**
+ * This callback is called by player stream when it needs additional data
+ * to be played by the device. Application must fill in the whole of output
+ * buffer with sound samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param timestamp Timestamp, in samples.
+ * @param output Buffer to be filled out by application.
+ * @param size The size requested in bytes, which will be equal to
+ * the size of one whole packet.
+ *
+ * @return Non-zero to stop the stream.
+ */
+typedef pj_status_t (*pjmedia_snd_play_cb)(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* out */ void *output,
+ /* out */ unsigned size);
+
+/**
+ * This callback is called by recorder stream when it has captured the whole
+ * packet worth of audio samples.
+ *
+ * @param user_data User data associated with the stream.
+ * @param timestamp Timestamp, in samples.
+ * @param output Buffer containing the captured audio samples.
+ * @param size The size of the data in the buffer, in bytes.
+ *
+ * @return Non-zero to stop the stream.
+ */
+typedef pj_status_t (*pjmedia_snd_rec_cb)(/* in */ void *user_data,
+ /* in */ pj_uint32_t timestamp,
+ /* in */ void *input,
+ /* in*/ unsigned size);
+
+/**
+ * Init the sound library.
+ *
+ * @param factory The sound factory.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory);
+
+
+/**
+ * Get the number of devices detected by the library.
+ *
+ * @return Number of devices.
+ */
+PJ_DECL(int) pjmedia_snd_get_dev_count(void);
+
+
+/**
+ * Get device info.
+ *
+ * @param index The index of the device, which should be in the range
+ * from zero to #pjmedia_snd_get_dev_count - 1.
+ */
+PJ_DECL(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index);
+
+
+/**
+ * Set sound device latency, this function must be called before sound device
+ * opened, or otherwise default latency setting will be used, @see
+ * PJMEDIA_SND_DEFAULT_REC_LATENCY & PJMEDIA_SND_DEFAULT_PLAY_LATENCY.
+ *
+ * Choosing latency value is not straightforward, it should accomodate both
+ * minimum latency and stability. Lower latency tends to cause sound device
+ * less reliable (producing audio dropouts) on CPU load disturbance. Moreover,
+ * the best latency setting may vary based on many aspects, e.g: sound card,
+ * CPU, OS, kernel, etc.
+ *
+ * @param input_latency The latency of input device, in ms, set to 0
+ * for default PJMEDIA_SND_DEFAULT_REC_LATENCY.
+ * @param output_latency The latency of output device, in ms, set to 0
+ * for default PJMEDIA_SND_DEFAULT_PLAY_LATENCY.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_set_latency(unsigned input_latency,
+ unsigned output_latency);
+
+
+/**
+ * Create sound stream for both capturing audio and audio playback, from the
+ * same device. This is the recommended way to create simultaneous recorder
+ * and player streams (instead of creating separate capture and playback
+ * streams), because it works on backends that does not allow
+ * a device to be opened more than once.
+ *
+ * @param rec_id Device index for recorder/capture stream, or
+ * -1 to use the first capable device.
+ * @param play_id Device index for playback stream, or -1 to use
+ * the first capable device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param rec_cb Callback to handle captured audio samples.
+ * @param play_cb Callback to be called when the sound player needs
+ * more audio samples to play.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open(int rec_id,
+ int play_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_rec_cb rec_cb,
+ pjmedia_snd_play_cb play_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm);
+
+
+/**
+ * Create a unidirectional audio stream for capturing audio samples from
+ * the sound device.
+ *
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param rec_cb Callback to handle captured audio samples.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open_rec( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_rec_cb rec_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm);
+
+/**
+ * Create a unidirectional audio stream for playing audio samples to the
+ * sound device.
+ *
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param play_cb Callback to be called when the sound player needs
+ * more audio samples to play.
+ * @param user_data User data to be associated with the stream.
+ * @param p_snd_strm Pointer to receive the stream instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_open_player( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pjmedia_snd_play_cb play_cb,
+ void *user_data,
+ pjmedia_snd_stream **p_snd_strm );
+
+
+/**
+ * Get information about live stream.
+ *
+ * @param strm The stream to be queried.
+ * @param pi Pointer to stream information to be filled up with
+ * information about the stream.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_get_info(pjmedia_snd_stream *strm,
+ pjmedia_snd_stream_info *pi);
+
+
+/**
+ * Start the stream.
+ *
+ * @param stream The recorder or player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream);
+
+/**
+ * Stop the stream.
+ *
+ * @param stream The recorder or player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream);
+
+/**
+ * Destroy the stream.
+ *
+ * @param stream The recorder of player stream.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream);
+
+/**
+ * Deinitialize sound library.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_deinit(void);
+
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SOUND_H__ */
diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h
new file mode 100644
index 0000000..a58c933
--- /dev/null
+++ b/pjmedia/include/pjmedia/sound_port.h
@@ -0,0 +1,352 @@
+/* $Id: sound_port.h 4082 2012-04-24 13:09:14Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SOUND_PORT_H__
+#define __PJMEDIA_SOUND_PORT_H__
+
+/**
+ * @file sound_port.h
+ * @brief Media port connection abstraction to sound device.
+ */
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia/clock.h>
+#include <pjmedia/port.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMED_SND_PORT Sound Device Port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Media Port Connection Abstraction to the Sound Device
+ @{
+
+ As explained in @ref PJMED_SND, the sound hardware abstraction provides
+ some callbacks for its user:
+ - it calls <b><tt>rec_cb</tt></b> callback when it has finished capturing
+ one media frame, and
+ - it calls <b><tt>play_cb</tt></b> when it needs media frame to be
+ played to the sound playback hardware.
+
+ The @ref PJMED_SND_PORT (the object being explained here) add a
+ thin wrapper to the hardware abstraction:
+ - it will call downstream port's <tt>put_frame()</tt>
+ when <b><tt>rec_cb()</tt></b> is called (i.e. when the sound hardware
+ has finished capturing frame), and
+ - it will call downstream port's <tt>get_frame()</tt> when
+ <b><tt>play_cb()</tt></b> is called (i.e. every time the
+ sound hardware needs more frames to be played to the playback hardware).
+
+ This simple abstraction enables media to flow automatically (and
+ in timely manner) from the downstream media port to the sound device.
+ In other words, the sound device port supplies media clock to
+ the ports. The media clock concept is explained in @ref PJMEDIA_PORT_CLOCK
+ section.
+
+ Application registers downstream port to the sound device port by
+ calling #pjmedia_snd_port_connect();
+
+ */
+
+/**
+ * Sound port options.
+ */
+enum pjmedia_snd_port_option
+{
+ /**
+ * Don't start the audio device when creating a sound port.
+ */
+ PJMEDIA_SND_PORT_NO_AUTO_START = 1
+};
+
+/**
+ * This structure specifies the parameters to create the sound port.
+ * Use pjmedia_snd_port_param_default() to initialize this structure with
+ * default values (mostly zeroes)
+ */
+typedef struct pjmedia_snd_port_param
+{
+ /**
+ * Base structure.
+ */
+ pjmedia_aud_param base;
+
+ /**
+ * Sound port creation options.
+ */
+ unsigned options;
+
+ /**
+ * Echo cancellation options/flags.
+ */
+ unsigned ec_options;
+
+} pjmedia_snd_port_param;
+
+/**
+ * Initialize pjmedia_snd_port_param with default values.
+ *
+ * @param prm The parameter.
+ */
+PJ_DECL(void) pjmedia_snd_port_param_default(pjmedia_snd_port_param *prm);
+
+/**
+ * This opaque type describes sound device port connection.
+ * Sound device port is not a media port, but it is used to connect media
+ * port to the sound device.
+ */
+typedef struct pjmedia_snd_port pjmedia_snd_port;
+
+
+/**
+ * Create bidirectional sound port for both capturing and playback of
+ * audio samples.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param rec_id Device index for recorder/capture stream, or
+ * -1 to use the first capable device.
+ * @param play_id Device index for playback stream, or -1 to use
+ * the first capable device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,
+ int rec_id,
+ int play_id,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+/**
+ * Create unidirectional sound device port for capturing audio streams from
+ * the sound device with the specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create_rec(pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+/**
+ * Create unidirectional sound device port for playing audio streams with the
+ * specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param index Device index, or -1 to let the library choose the
+ * first available device.
+ * @param clock_rate Sound device's clock rate to set.
+ * @param channel_count Set number of channels, 1 for mono, or 2 for
+ * stereo. The channel count determines the format
+ * of the frame.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Set the number of bits per sample. The normal
+ * value for this parameter is 16 bits per sample.
+ * @param options Options flag.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create_player(pj_pool_t *pool,
+ int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_snd_port **p_port);
+
+
+/**
+ * Create sound device port according to the specified parameters.
+ *
+ * @param pool Pool to allocate sound port structure.
+ * @param prm Sound port parameter.
+ * @param p_port Pointer to receive the sound device port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
+ const pjmedia_snd_port_param *prm,
+ pjmedia_snd_port **p_port);
+
+
+/**
+ * Destroy sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Retrieve the sound stream associated by this sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return The sound stream instance.
+ */
+PJ_DECL(pjmedia_aud_stream*) pjmedia_snd_port_get_snd_stream(
+ pjmedia_snd_port *snd_port);
+
+
+/**
+ * Change the echo cancellation settings. The echo cancellation settings
+ * should have been specified when this sound port was created, by setting
+ * the appropriate fields in the pjmedia_aud_param, because not all sound
+ * device implementation supports changing the EC setting once the device
+ * has been opened.
+ *
+ * The behavior of this function depends on whether device or software AEC
+ * is being used. If the device supports AEC, this function will forward
+ * the change request to the device and it will be up to the device whether
+ * to support the request. If software AEC is being used (the software EC
+ * will be used if the device does not support AEC), this function will
+ * change the software EC settings.
+ *
+ * @param snd_port The sound device port.
+ * @param pool Pool to re-create the echo canceller if necessary.
+ * @param tail_ms Maximum echo tail length to be supported, in
+ * miliseconds. If zero is specified, the EC would
+ * be disabled.
+ * @param options The options to be passed to #pjmedia_echo_create().
+ * This is only used if software EC is being used.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_set_ec( pjmedia_snd_port *snd_port,
+ pj_pool_t *pool,
+ unsigned tail_ms,
+ unsigned options);
+
+
+/**
+ * Get current echo canceller tail length, in miliseconds. The tail length
+ * will be zero if EC is not enabled.
+ *
+ * @param snd_port The sound device port.
+ * @param p_length Pointer to receive the tail length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_get_ec_tail(pjmedia_snd_port *snd_port,
+ unsigned *p_length);
+
+
+/**
+ * Get a clock source from the sound port.
+ *
+ * @param snd_port The sound port.
+ * @param dir Sound port's direction.
+ *
+ * @return The clock source.
+ */
+PJ_DECL(pjmedia_clock_src *)
+pjmedia_snd_port_get_clock_src( pjmedia_snd_port *snd_port,
+ pjmedia_dir dir );
+
+
+/**
+ * Connect a port to the sound device port. If the sound device port has a
+ * sound recorder device, then this will start periodic function call to
+ * the port's put_frame() function. If the sound device has a sound player
+ * device, then this will start periodic function call to the port's
+ * get_frame() function.
+ *
+ * For this version of PJMEDIA, the media port MUST have the same audio
+ * settings as the sound device port, or otherwise the connection will
+ * fail. This means the port MUST have the same clock_rate, channel count,
+ * samples per frame, and bits per sample as the sound device port.
+ *
+ * @param snd_port The sound device port.
+ * @param port The media port to be connected.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_connect(pjmedia_snd_port *snd_port,
+ pjmedia_port *port);
+
+
+/**
+ * Retrieve the port instance currently attached to the sound port, if any.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return The port instance currently attached to the
+ * sound device port, or NULL if there is no port
+ * currently attached to the sound device port.
+ */
+PJ_DECL(pjmedia_port*) pjmedia_snd_port_get_port(pjmedia_snd_port *snd_port);
+
+
+/**
+ * Disconnect currently attached port from the sound device port.
+ *
+ * @param snd_port The sound device port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_port_disconnect(pjmedia_snd_port *snd_port);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SOUND_PORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/splitcomb.h b/pjmedia/include/pjmedia/splitcomb.h
new file mode 100644
index 0000000..24110f4
--- /dev/null
+++ b/pjmedia/include/pjmedia/splitcomb.h
@@ -0,0 +1,140 @@
+/* $Id: splitcomb.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SPLITCOMB_H__
+#define __PJMEDIA_SPLITCOMB_H__
+
+
+/**
+ * @file splitcomb.h
+ * @brief Media channel splitter/combiner port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @addtogroup PJMEDIA_SPLITCOMB Media channel splitter/combiner
+ * @ingroup PJMEDIA_PORT
+ * @brief Split and combine multiple mono-channel media ports into
+ * a single multiple-channels media port
+ * @{
+ *
+ * This section describes media port to split and combine media
+ * channels in the stream.
+ *
+ * A splitter/combiner splits a single stereo/multichannels audio frame into
+ * multiple audio frames to each channel when put_frame() is called,
+ * and combines mono frames from each channel into a stereo/multichannel
+ * frame when get_frame() is called. A common application for the splitter/
+ * combiner is to split frames from stereo to mono and vise versa.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create a media splitter/combiner with the specified parameters.
+ * When the splitter/combiner is created, it creates an instance of
+ * pjmedia_port. This media port represents the stereo/multichannel side
+ * of the splitter/combiner. Application needs to supply the splitter/
+ * combiner with a media port for each audio channels.
+ *
+ * @param pool Pool to allocate memory to create the splitter/
+ * combiner.
+ * @param clock_rate Audio clock rate/sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Bits per sample.
+ * @param options Optional flags.
+ * @param p_splitcomb Pointer to receive the splitter/combiner.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_splitcomb_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_splitcomb);
+
+/**
+ * Supply the splitter/combiner with media port for the specified channel
+ * number. The media port will be called at the
+ * same phase as the splitter/combiner; which means that when application
+ * calls get_frame() of the splitter/combiner, it will call get_frame()
+ * for all ports that have the same phase. And similarly for put_frame().
+ *
+ * @param splitcomb The splitter/combiner.
+ * @param ch_num Audio channel starting number (zero based).
+ * @param options Must be zero at the moment.
+ * @param port The media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_splitcomb_set_channel(pjmedia_port *splitcomb,
+ unsigned ch_num,
+ unsigned options,
+ pjmedia_port *port);
+
+/**
+ * Create a reverse phase media port for the specified channel number.
+ * For channels with reversed phase, when application calls put_frame() to
+ * the splitter/combiner, the splitter/combiner will only put the frame to
+ * a buffer. Later on, when application calls get_frame() on the channel's
+ * media port, it will return the frame that are available in the buffer.
+ * The same process happens when application calls put_frame() to the
+ * channel's media port, it will only put the frame to another buffer, which
+ * will be returned when application calls get_frame() to the splitter's
+ * media port. So this effectively reverse the phase of the media port.
+ *
+ * @param pool The pool to allocate memory for the port and
+ * buffers.
+ * @param splitcomb The splitter/combiner.
+ * @param ch_num Audio channel starting number (zero based).
+ * @param options Normally is zero, but the lower 8-bit of the
+ * options can be used to specify the number of
+ * buffers in the circular buffer. If zero, then
+ * default number will be used (default: 8).
+ * @param p_chport The media port created with reverse phase for
+ * the specified audio channel.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_splitcomb_create_rev_channel( pj_pool_t *pool,
+ pjmedia_port *splitcomb,
+ unsigned ch_num,
+ unsigned options,
+ pjmedia_port **p_chport);
+
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_SPLITCOMB_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/stereo.h b/pjmedia/include/pjmedia/stereo.h
new file mode 100644
index 0000000..7786922
--- /dev/null
+++ b/pjmedia/include/pjmedia/stereo.h
@@ -0,0 +1,206 @@
+/* $Id: stereo.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_STEREO_H__
+#define __PJMEDIA_STEREO_H__
+
+/**
+ * @file stereo.h
+ * @brief Monochannel and multichannel converter.
+ */
+
+#include <pjmedia/errno.h>
+#include <pjmedia/port.h>
+#include <pjmedia/types.h>
+#include <pj/assert.h>
+
+
+/**
+ * @defgroup PJMEDIA_STEREO Monochannel and multichannel audio frame converter
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Mono - multi-channels audio conversion
+ * @{
+ *
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Multichannel to monochannel conversion mixes samples from all channels
+ * into the monochannel.
+ */
+#define PJMEDIA_STEREO_MIX PJ_TRUE
+
+
+
+/**
+ * Multichannel to monochannel conversion, it has two operation mode specified
+ * by param options, @see pjmedia_stereo_options. This function can work safely
+ * using the same buffer (in place conversion).
+ *
+ * @param mono Output buffer to store the mono frame extracted
+ * from the multichannels frame.
+ * @param multi Input frame containing multichannels audio.
+ * @param channel_count Number of channels in the input frame.
+ * @param samples_per_frame Number of samples in the input frame.
+ * @param mix If the value is PJ_TRUE then the input channels
+ * will be mixed to produce output frame, otherwise
+ * only frame from channel_src will be copied to the
+ * output frame.
+ * @param channel_src When mixing is disabled, the mono output frame
+ * will be copied from this channel number.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_convert_channel_nto1(pj_int16_t mono[],
+ const pj_int16_t multi[],
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ pj_bool_t mix,
+ unsigned channel_src)
+{
+ unsigned i;
+
+ PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame &&
+ channel_src < channel_count, PJ_EINVAL);
+
+ if (mix==PJ_FALSE) {
+ for (i = channel_src; i < samples_per_frame; i += channel_count) {
+ *mono = multi[i];
+ ++mono;
+ }
+ } else {
+ unsigned j;
+ for (i = 0; i < samples_per_frame; i += channel_count) {
+ int tmp = 0;
+ for(j = 0; j < channel_count; ++j)
+ tmp += multi[i+j];
+
+ if (tmp > 32767) tmp = 32767;
+ else if (tmp < -32768) tmp = -32768;
+ *mono = (pj_int16_t) tmp;
+ ++mono;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Monochannel to multichannel conversion, it will just duplicate the samples
+ * from monochannel frame to all channels in the multichannel frame.
+ * This function can work safely using the same buffer (in place conversion)
+ * as long as the buffer is big enough for the multichannel samples.
+ *
+ * @param multi Output buffer to store the multichannels frame
+ * mixed from the mono frame.
+ * @param mono The input monochannel audio frame.
+ * @param channel_count Desired number of channels in the output frame.
+ * @param samples_per_frame Number of samples in the input frame.
+ * @param options Options for conversion, currently must be zero.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_convert_channel_1ton(pj_int16_t multi[],
+ const pj_int16_t mono[],
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned options)
+{
+ const pj_int16_t *src;
+
+ PJ_ASSERT_RETURN(mono && multi && channel_count && samples_per_frame,
+ PJ_EINVAL);
+ PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
+
+ PJ_UNUSED_ARG(options);
+
+ src = mono + samples_per_frame - 1;
+ samples_per_frame *= channel_count;
+ while (samples_per_frame) {
+ unsigned i;
+ for (i=1; i<=channel_count; ++i)
+ multi[samples_per_frame-i] = *src;
+ samples_per_frame -= channel_count;
+ --src;
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+/**
+ * Options for channel converter port. The #pjmedia_stereo_options is also
+ * valid for this port options.
+ */
+typedef enum pjmedia_stereo_port_options
+{
+ /**
+ * Specifies whether this port should not destroy downstream port when
+ * this port is destroyed.
+ */
+ PJMEDIA_STEREO_DONT_DESTROY_DN = 4
+} pjmedia_stereo_port_options;
+
+
+/**
+ * Create a mono-multi channel converter port. This creates a converter session,
+ * which will adjust the samples of audio frame to a different channel count
+ * when the port's get_frame() and put_frame() is called.
+ *
+ * When the port's get_frame() is called, this port will get a frame from
+ * the downstream port and convert the frame to the target channel count before
+ * returning it to the caller.
+ *
+ * When the port's put_frame() is called, this port will convert the frame
+ * to the downstream port's channel count before giving the frame to the
+ * downstream port.
+ *
+ * @param pool Pool to allocate the structure and buffers.
+ * @param dn_port The downstream port, which channel count is to
+ * be converted to the target channel count.
+ * @param channel_count This port channel count.
+ * @param options Bitmask flags from #pjmedia_stereo_port_options
+ * and also application may add PJMEDIA_STEREO_MIX
+ * to mix channels.
+ * When this flag is zero, the default behavior
+ * is to use simple N-to-1 channel converter and
+ * to destroy downstream port when this port is
+ * destroyed.
+ * @param p_port Pointer to receive the stereo port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stereo_port_create( pj_pool_t *pool,
+ pjmedia_port *dn_port,
+ unsigned channel_count,
+ unsigned options,
+ pjmedia_port **p_port );
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_STEREO_H__ */
+
diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h
new file mode 100644
index 0000000..23df1c4
--- /dev/null
+++ b/pjmedia/include/pjmedia/stream.h
@@ -0,0 +1,436 @@
+/* $Id: stream.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_STREAM_H__
+#define __PJMEDIA_STREAM_H__
+
+
+/**
+ * @file stream.h
+ * @brief Media Stream.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/endpoint.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/port.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/transport.h>
+#include <pjmedia/vid_codec.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_STRM Streams
+ * @ingroup PJMEDIA_PORT
+ * @brief Communicating with remote peer via the network
+ * @{
+ *
+ * A media stream is a bidirectional multimedia communication between two
+ * endpoints. It corresponds to a media description (m= line) in SDP
+ * session descriptor.
+ *
+ * A media stream consists of two unidirectional channels:
+ * - encoding channel, which transmits unidirectional media to remote, and
+ * - decoding channel, which receives unidirectional media from remote.
+ *
+ * A media stream exports media port interface (see @ref PJMEDIA_PORT)
+ * and application normally uses this interface to interconnect the stream
+ * to other PJMEDIA components.
+ *
+ * A media stream internally manages the following objects:
+ * - an instance of media codec (see @ref PJMEDIA_CODEC),
+ * - an @ref PJMED_JBUF,
+ * - two instances of RTP sessions (#pjmedia_rtp_session, one for each
+ * direction),
+ * - one instance of RTCP session (#pjmedia_rtcp_session),
+ * - and a reference to media transport to send and receive packets
+ * to/from the network (see @ref PJMEDIA_TRANSPORT).
+ *
+ * Streams are created by calling #pjmedia_stream_create(), specifying
+ * #pjmedia_stream_info structure in the parameter. Application can construct
+ * the #pjmedia_stream_info structure manually, or use
+ * #pjmedia_stream_info_from_sdp() or #pjmedia_session_info_from_sdp()
+ * functions to construct the #pjmedia_stream_info from local and remote
+ * SDP session descriptors.
+ *
+ * Application can also use @ref PJMEDIA_SESSION to indirectly create the
+ * streams.
+ */
+
+/**
+ * Opaque declaration for media channel.
+ * Media channel is unidirectional flow of media from sender to
+ * receiver.
+ */
+typedef struct pjmedia_channel pjmedia_channel;
+
+/**
+ * This structure describes media stream information. Each media stream
+ * corresponds to one "m=" line in SDP session descriptor, and it has
+ * its own RTP/RTCP socket pair.
+ */
+typedef struct pjmedia_stream_info
+{
+ pjmedia_type type; /**< Media type (audio, video) */
+ pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
+ pjmedia_dir dir; /**< Media direction. */
+ pj_sockaddr rem_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If
+ sin_family is zero, the RTP address
+ will be calculated from RTP. */
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+ pj_bool_t rtcp_xr_enabled;
+ /**< Specify whether RTCP XR is enabled.*/
+ pj_uint32_t rtcp_xr_interval; /**< RTCP XR interval. */
+ pj_sockaddr rtcp_xr_dest;/**<Additional remote RTCP XR address.
+ This is useful for third-party (e.g:
+ network monitor) to monitor the
+ stream. If sin_family is zero,
+ this will be ignored. */
+#endif
+ pjmedia_codec_info fmt; /**< Incoming codec format info. */
+ pjmedia_codec_param *param; /**< Optional codec param. */
+ unsigned tx_pt; /**< Outgoing codec paylaod type. */
+ unsigned rx_pt; /**< Incoming codec paylaod type. */
+ unsigned tx_maxptime;/**< Outgoing codec max ptime. */
+ int tx_event_pt;/**< Outgoing pt for telephone-events. */
+ int rx_event_pt;/**< Incoming pt for telephone-events. */
+ pj_uint32_t ssrc; /**< RTP SSRC. */
+ pj_uint32_t rtp_ts; /**< Initial RTP timestamp. */
+ pj_uint16_t rtp_seq; /**< Initial RTP sequence number. */
+ pj_uint8_t rtp_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+ int jb_init; /**< Jitter buffer init delay in msec.
+ (-1 for default). */
+ int jb_min_pre; /**< Jitter buffer minimum prefetch
+ delay in msec (-1 for default). */
+ int jb_max_pre; /**< Jitter buffer maximum prefetch
+ delay in msec (-1 for default). */
+ int jb_max; /**< Jitter buffer max delay in msec. */
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ pj_bool_t use_ka; /**< Stream keep-alive and NAT hole punch
+ (see #PJMEDIA_STREAM_ENABLE_KA)
+ is enabled? */
+#endif
+ pj_bool_t rtcp_sdes_bye_disabled;
+ /**< Disable automatic sending of RTCP
+ SDES and BYE. */
+} pjmedia_stream_info;
+
+
+/**
+ * This function will initialize the stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_info_from_sdp( pjmedia_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
+
+
+/**
+ * Create a media stream based on the specified parameter. After the stream
+ * has been created, application normally would want to get the media port
+ * interface of the streams, by calling pjmedia_stream_get_port(). The
+ * media port interface exports put_frame() and get_frame() function, used
+ * to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the stream.
+ *
+ * @param endpt Media endpoint.
+ * @param pool Pool to allocate memory for the stream. A large
+ * number of memory may be needed because jitter
+ * buffer needs to preallocate some storage.
+ * @param info Stream information.
+ * @param tp Stream transport instance used to transmit
+ * and receive RTP/RTCP packets to/from the underlying
+ * transport.
+ * @param user_data Arbitrary user data (for future callback feature).
+ * @param p_stream Pointer to receive the media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_create(pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ const pjmedia_stream_info *info,
+ pjmedia_transport *tp,
+ void *user_data,
+ pjmedia_stream **p_stream);
+
+/**
+ * Destroy the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_destroy(pjmedia_stream *stream);
+
+
+/**
+ * Get the last frame type retreived from the jitter buffer.
+ *
+ * @param stream The media stream.
+ *
+ * @return Jitter buffer frame type.
+ */
+PJ_DEF(char) pjmedia_stream_get_last_jb_frame_type(pjmedia_stream *stream);
+
+
+/**
+ * Get the media port interface of the stream. The media port interface
+ * declares put_frame() and get_frame() function, which is the only
+ * way for application to transmit and receive media frames from the
+ * stream.
+ *
+ * @param stream The media stream.
+ * @param p_port Pointer to receive the port interface.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_port(pjmedia_stream *stream,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get the media transport object associated with this stream.
+ *
+ * @param st The media stream.
+ *
+ * @return The transport object being used by the stream.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_stream_get_transport(pjmedia_stream *st);
+
+
+/**
+ * Start the media stream. This will start the appropriate channels
+ * in the media stream, depending on the media direction that was set
+ * when the stream was created.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_start(pjmedia_stream *stream);
+
+
+/**
+ * Get the stream info.
+ *
+ * @param stream The media stream.
+ * @param info Stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_info( const pjmedia_stream *stream,
+ pjmedia_stream_info *info);
+
+/**
+ * Get the stream statistics. See also
+ * #pjmedia_stream_get_stat_jbuf()
+ *
+ * @param stream The media stream.
+ * @param stat Media stream statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat( const pjmedia_stream *stream,
+ pjmedia_rtcp_stat *stat);
+
+
+/**
+ * Reset the stream statistics.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_reset_stat(pjmedia_stream *stream);
+
+
+#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
+/**
+ * Get the stream extended report statistics (RTCP XR).
+ *
+ * @param stream The media stream.
+ * @param stat Media stream extended report statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat_xr( const pjmedia_stream *stream,
+ pjmedia_rtcp_xr_stat *stat);
+#endif
+
+/**
+ * Get current jitter buffer state. See also
+ * #pjmedia_stream_get_stat()
+ *
+ * @param stream The media stream.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_stat_jbuf(const pjmedia_stream *stream,
+ pjmedia_jb_state *state);
+
+
+/**
+ * Pause the individual channel in the stream.
+ *
+ * @param stream The media channel.
+ * @param dir Which direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_pause( pjmedia_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Resume the individual channel in the stream.
+ *
+ * @param stream The media channel.
+ * @param dir Which direction to resume.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_resume(pjmedia_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Transmit DTMF to this stream. The DTMF will be transmitted uisng
+ * RTP telephone-events as described in RFC 2833. This operation is
+ * only valid for audio stream.
+ *
+ * @param stream The media stream.
+ * @param ascii_digit String containing digits to be sent to remote.
+ * Currently the maximum number of digits are 32.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_dial_dtmf(pjmedia_stream *stream,
+ const pj_str_t *ascii_digit);
+
+
+/**
+ * Check if the stream has incoming DTMF digits in the incoming DTMF
+ * queue. Incoming DTMF digits received via RFC 2833 mechanism are
+ * saved in the incoming digits queue.
+ *
+ * @param stream The media stream.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has received DTMF
+ * digits in the .
+ */
+PJ_DECL(pj_bool_t) pjmedia_stream_check_dtmf(pjmedia_stream *stream);
+
+
+/**
+ * Retrieve the incoming DTMF digits from the stream, and remove the digits
+ * from stream's DTMF buffer. Note that the digits buffer will not be NULL
+ * terminated.
+ *
+ * @param stream The media stream.
+ * @param ascii_digits Buffer to receive the digits. The length of this
+ * buffer is indicated in the "size" argument.
+ * @param size On input, contains the maximum digits to be copied
+ * to the buffer.
+ * On output, it contains the actual digits that has
+ * been copied to the buffer.
+ *
+ * @return Non-zero (PJ_TRUE) if the stream has received DTMF
+ * digits in the .
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
+ char *ascii_digits,
+ unsigned *size);
+
+
+/**
+ * Set callback to be called upon receiving DTMF digits. If callback is
+ * registered, the stream will not buffer incoming DTMF but rather call
+ * the callback as soon as DTMF digit is received completely.
+ *
+ * @param stream The media stream.
+ * @param cb Callback to be called upon receiving DTMF digits.
+ * The DTMF digits will be given to the callback as
+ * ASCII digits.
+ * @param user_data User data to be returned back when the callback
+ * is called.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
+ void (*cb)(pjmedia_stream*,
+ void *user_data,
+ int digit),
+ void *user_data);
+
+
+/**
+ * Send RTCP SDES for the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_send_rtcp_sdes( pjmedia_stream *stream );
+
+/**
+ * Send RTCP BYE for the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_stream_send_rtcp_bye( pjmedia_stream *stream );
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_STREAM_H__ */
diff --git a/pjmedia/include/pjmedia/stream_common.h b/pjmedia/include/pjmedia/stream_common.h
new file mode 100644
index 0000000..b9aa0f8
--- /dev/null
+++ b/pjmedia/include/pjmedia/stream_common.h
@@ -0,0 +1,57 @@
+/* $Id: stream_common.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_STREAM_COMMON_H__
+#define __PJMEDIA_STREAM_COMMON_H__
+
+
+/**
+ * @file stream_common.h
+ * @brief Stream common functions.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/sdp.h>
+
+
+PJ_BEGIN_DECL
+
+/**
+ * This is internal function for parsing SDP format parameter of specific
+ * format or payload type, used by stream in generating stream info from SDP.
+ *
+ * @param pool Pool to allocate memory, if pool is NULL, the fmtp
+ * string pointers will point to the original string in
+ * the SDP media descriptor.
+ * @param m The SDP media containing the format parameter to
+ * be parsed.
+ * @param pt The format or payload type.
+ * @param fmtp The format parameter to store the parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_stream_info_parse_fmtp(pj_pool_t *pool,
+ const pjmedia_sdp_media *m,
+ unsigned pt,
+ pjmedia_codec_fmtp *fmtp);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_STREAM_COMMON_H__ */
diff --git a/pjmedia/include/pjmedia/symbian_sound_aps.h b/pjmedia/include/pjmedia/symbian_sound_aps.h
new file mode 100644
index 0000000..096e1fa
--- /dev/null
+++ b/pjmedia/include/pjmedia/symbian_sound_aps.h
@@ -0,0 +1,48 @@
+/* $Id: symbian_sound_aps.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_SYMBIAN_SOUND_APS_H__
+#define __PJMEDIA_SYMBIAN_SOUND_APS_H__
+
+
+/**
+ * @file symbian_sound_aps.h
+ * @brief Sound device wrapper using Audio Proxy Server on
+ * Symbian S60 3rd edition.
+ */
+#include <pjmedia/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * Set audio routing for APS sound device.
+ *
+ * @param stream The sound device stream, the stream should be started
+ * before calling this function.
+ * @param route Audio routing to be set.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_snd_aps_set_route( pjmedia_snd_stream *stream,
+ pjmedia_snd_route route);
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_SYMBIAN_SOUND_APS_H__ */
diff --git a/pjmedia/include/pjmedia/tonegen.h b/pjmedia/include/pjmedia/tonegen.h
new file mode 100644
index 0000000..38dc602
--- /dev/null
+++ b/pjmedia/include/pjmedia/tonegen.h
@@ -0,0 +1,293 @@
+/* $Id: tonegen.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TONEGEN_PORT_H__
+#define __PJMEDIA_TONEGEN_PORT_H__
+
+/**
+ * @file tonegen.h
+ * @brief Tone (sine, MF, DTMF) generator media port.
+ */
+#include <pjmedia/port.h>
+
+
+/**
+ * @defgroup PJMEDIA_MF_DTMF_TONE_GENERATOR Multi-frequency tone generator
+ * @ingroup PJMEDIA_PORT
+ * @brief Multi-frequency tone generator
+ * @{
+ *
+ * This page describes tone generator media port. A tone generator can be
+ * used to generate a single frequency sine wave or dual frequency tones
+ * such as DTMF.
+ *
+ * The tone generator media port provides two functions to generate tones.
+ * The function #pjmedia_tonegen_play() can be used to generate arbitrary
+ * single or dual frequency tone, and #pjmedia_tonegen_play_digits() is
+ * used to play digits such as DTMF. Each tone specified in the playback
+ * function has individual on and off signal duration that must be
+ * specified by application.
+ *
+ * In order to play digits such as DTMF, the tone generator is equipped
+ * with digit map, which contain information about the frequencies of
+ * the digits. The default digit map is DTMF (0-9,a-d,*,#), but application
+ * may specifiy different digit map to the tone generator by calling
+ * #pjmedia_tonegen_set_digit_map() function.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * This structure describes individual MF digits to be played
+ * with #pjmedia_tonegen_play().
+ */
+typedef struct pjmedia_tone_desc
+{
+ short freq1; /**< First frequency. */
+ short freq2; /**< Optional second frequency. */
+ short on_msec; /**< Playback ON duration, in miliseconds. */
+ short off_msec; /**< Playback OFF duration, ini miliseconds. */
+ short volume; /**< Volume (1-32767), or 0 for default, which
+ PJMEDIA_TONEGEN_VOLUME will be used. */
+ short flags; /**< Currently internal flags, must be 0 */
+} pjmedia_tone_desc;
+
+
+
+/**
+ * This structure describes individual MF digits to be played
+ * with #pjmedia_tonegen_play_digits().
+ */
+typedef struct pjmedia_tone_digit
+{
+ char digit; /**< The ASCI identification for the digit. */
+ short on_msec; /**< Playback ON duration, in miliseconds. */
+ short off_msec; /**< Playback OFF duration, ini miliseconds. */
+ short volume; /**< Volume (1-32767), or 0 for default, which
+ PJMEDIA_TONEGEN_VOLUME will be used. */
+} pjmedia_tone_digit;
+
+
+/**
+ * This structure describes the digit map which is used by the tone generator
+ * to produce tones from an ASCII digits.
+ * Digit map used by a particular tone generator can be retrieved/set with
+ * #pjmedia_tonegen_get_digit_map() and #pjmedia_tonegen_set_digit_map().
+ */
+typedef struct pjmedia_tone_digit_map
+{
+ unsigned count; /**< Number of digits in the map. */
+
+ struct {
+ char digit; /**< The ASCI identification for the digit. */
+ short freq1; /**< First frequency. */
+ short freq2; /**< Optional second frequency. */
+ } digits[16]; /**< Array of digits in the digit map. */
+} pjmedia_tone_digit_map;
+
+
+/**
+ * Tone generator options.
+ */
+enum
+{
+ /**
+ * Play the tones in loop, restarting playing the first tone after
+ * the last tone has been played.
+ */
+ PJMEDIA_TONEGEN_LOOP = 1,
+
+ /**
+ * Disable mutex protection to the tone generator.
+ */
+ PJMEDIA_TONEGEN_NO_LOCK = 2
+};
+
+
+/**
+ * Create an instance of tone generator with the specified parameters.
+ * When the tone generator is first created, it will be loaded with the
+ * default digit map.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels. Currently only mono and stereo
+ * are supported.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample. This version of PJMEDIA
+ * only supports 16bit per sample.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Create an instance of tone generator with the specified parameters.
+ * When the tone generator is first created, it will be loaded with the
+ * default digit map.
+ *
+ * @param pool Pool to allocate memory for the port structure.
+ * @param name Optional name for the tone generator.
+ * @param clock_rate Sampling rate.
+ * @param channel_count Number of channels. Currently only mono and stereo
+ * are supported.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample. This version of PJMEDIA
+ * only supports 16bit per sample.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ * @param p_port Pointer to receive the port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool,
+ const pj_str_t *name,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned options,
+ pjmedia_port **p_port);
+
+
+/**
+ * Check if the tone generator is still busy producing some tones.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return Non-zero if busy.
+ */
+PJ_DECL(pj_bool_t) pjmedia_tonegen_is_busy(pjmedia_port *tonegen);
+
+
+/**
+ * Instruct the tone generator to stop current processing.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_stop(pjmedia_port *tonegen);
+
+
+/**
+ * Rewind the playback. This will start the playback to the first
+ * tone in the playback list.
+ *
+ * @param tonegen The tone generator instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_rewind(pjmedia_port *tonegen);
+
+
+/**
+ * Instruct the tone generator to play single or dual frequency tones
+ * with the specified duration. The new tones will be appended to currently
+ * playing tones, unless #pjmedia_tonegen_stop() is called before calling
+ * this function. The playback will begin as soon as the first get_frame()
+ * is called to the generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param count The number of tones in the array.
+ * @param tones Array of tones to be played.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ *
+ * @return PJ_SUCCESS on success, or PJ_ETOOMANY if
+ * there are too many digits in the queue.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_play(pjmedia_port *tonegen,
+ unsigned count,
+ const pjmedia_tone_desc tones[],
+ unsigned options);
+
+/**
+ * Instruct the tone generator to play multiple MF digits with each of
+ * the digits having individual ON/OFF duration. Each of the digit in the
+ * digit array must have the corresponding descriptor in the digit map.
+ * The new tones will be appended to currently playing tones, unless
+ * #pjmedia_tonegen_stop() is called before calling this function.
+ * The playback will begin as soon as the first get_frame() is called
+ * to the generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param count Number of digits in the array.
+ * @param digits Array of MF digits.
+ * @param options Option flags. Application may specify
+ * PJMEDIA_TONEGEN_LOOP to play the tone in a loop.
+ *
+ * @return PJ_SUCCESS on success, or PJ_ETOOMANY if
+ * there are too many digits in the queue, or
+ * PJMEDIA_RTP_EINDTMF if invalid digit is
+ * specified.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_play_digits(pjmedia_port *tonegen,
+ unsigned count,
+ const pjmedia_tone_digit digits[],
+ unsigned options);
+
+
+/**
+ * Get the digit-map currently used by this tone generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param m On output, it will be filled with the pointer to
+ * the digitmap currently used by the tone generator.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_get_digit_map(pjmedia_port *tonegen,
+ const pjmedia_tone_digit_map **m);
+
+
+/**
+ * Set digit map to be used by the tone generator.
+ *
+ * @param tonegen The tone generator instance.
+ * @param m Digitmap to be used by the tone generator.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_tonegen_set_digit_map(pjmedia_port *tonegen,
+ pjmedia_tone_digit_map *m);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TONEGEN_PORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/transport.h b/pjmedia/include/pjmedia/transport.h
new file mode 100644
index 0000000..dca9f29
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport.h
@@ -0,0 +1,853 @@
+/* $Id: transport.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_H__
+#define __PJMEDIA_TRANSPORT_H__
+
+
+/**
+ * @file transport.h Media Transport Interface
+ * @brief Transport interface.
+ */
+
+#include <pjmedia/types.h>
+#include <pjmedia/errno.h>
+#include <pj/string.h>
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT Media Transport
+ * @brief Transports.
+ * @{
+ * The media transport (#pjmedia_transport) is the object to send and
+ * receive media packets over the network. The media transport interface
+ * allows the library to be extended to support different types of
+ * transports to send and receive packets.
+ *
+ * The media transport is declared as #pjmedia_transport "class", which
+ * declares "interfaces" to use the class in #pjmedia_transport_op
+ * structure. For the user of the media transport (normally the user of
+ * media transport is media stream, see \ref PJMED_STRM), these transport
+ * "methods" are wrapped with API such as #pjmedia_transport_attach(),
+ * so it should not need to call the function pointer inside
+ * #pjmedia_transport_op directly.
+ *
+ * The connection between \ref PJMED_STRM and media transport is shown in
+ * the diagram below:
+
+ \image html media-transport.PNG
+
+
+ * \section PJMEDIA_TRANSPORT_H_USING Basic Media Transport Usage
+ *
+ * The media transport's life-cycle normally follows the following stages.
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_CREATE Creating the Media Transport
+ *
+ * Application creates the media transport when it needs to establish
+ * media session to remote peer. The media transport is created using
+ * specific function to create that particular transport; for example,
+ * for UDP media transport, it is created with #pjmedia_transport_udp_create()
+ * or #pjmedia_transport_udp_create2() functions. Different media
+ * transports will provide different API to create those transports.
+ *
+ * Alternatively, application may create pool of media transports when
+ * it is first started up. Using this approach probably is better, since
+ * application has to specify the RTP port when sending the initial
+ * session establishment request (e.g. SIP INVITE request), thus if
+ * application only creates the media transport later when media is to be
+ * established (normally when 200/OK is received, or when 18x is received
+ * for early media), there is a possibility that the particular RTP
+ * port might have been occupied by other programs. Also it is more
+ * efficient since sockets don't need to be closed and re-opened between
+ * calls.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_ATTACH Attaching and Using the Media Transport.
+ *
+ * Application specifies the media transport instance when creating
+ * the media session (#pjmedia_session_create()). Alternatively, it
+ * may create the media stream directly with #pjmedia_stream_create()
+ * and specify the transport instance in the argument. (Note: media
+ * session is a high-level abstraction for media communications between
+ * two endpoints, and it may contain more than one media streams, for
+ * example, an audio stream and a video stream).
+ *
+ * When stream is created, it will "attach" itself to the media
+ * transport by calling #pjmedia_transport_attach(), which is a thin
+ * wrapper which calls "attach()" method of the media transport's
+ * "virtual function pointer" (#pjmedia_transport_op). Among other things,
+ * the stream specifies two callback functions to the transport: one
+ * callback function will be called by transport when it receives RTP
+ * packet, and another callback for incoming RTCP packet. The
+ * #pjmedia_transport_attach() function also establish the destination
+ * of the outgoing RTP and RTCP packets.
+ *
+ * When the stream needs to send outgoing RTP/RTCP packets, it will
+ * call #pjmedia_transport_send_rtp() and #pjmedia_transport_send_rtcp()
+ * of the media transport API, which is a thin wrapper to call send_rtp()
+ * and send_rtcp() methods in the media transport's "virtual function
+ * pointer" (#pjmedia_transport_op).
+ *
+ * When the stream is destroyed, it will "detach" itself from
+ * the media transport by calling #pjmedia_transport_detach(), which is
+ * a thin wrapper which calls "detach()" method of the media transport's
+ * "virtual function pointer" (#pjmedia_transport_op). After the transport
+ * is detached from its user (the stream), it will no longer report
+ * incoming RTP/RTCP packets to the stream, and it will refuse to send
+ * outgoing packets since the destination has been cleared.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_REUSE Reusing the Media Transport.
+ *
+ * After transport has been detached, application may re-attach the
+ * transport to another stream if it wants to. Detaching and re-attaching
+ * media transport may be preferable than closing and re-opening the
+ * transport, since it is more efficient (sockets don't need to be
+ * closed and re-opened). However it is up to the application to choose
+ * which method is most suitable for its uses.
+ *
+ *
+ * \subsection PJMEDIA_TRANSPORT_H_DESTROY Destroying the Media Transport.
+ *
+ * Finally if application no longer needs the media transport, it will
+ * call #pjmedia_transport_close() function, which is thin wrapper which
+ * calls "destroy()" method of the media transport's "virtual function
+ * pointer" (#pjmedia_transport_op). This function releases
+ * all resources used by the transport, such as sockets and memory.
+ *
+ *
+ * \section offer_answer Interaction with SDP Offer/Answer
+
+ For basic UDP transport, the \ref PJMEDIA_TRANSPORT_H_USING above is
+ sufficient to use the media transport. However, more complex media
+ transports such as \ref PJMEDIA_TRANSPORT_SRTP and \ref
+ PJMEDIA_TRANSPORT_ICE requires closer interactions with SDP offer and
+ answer negotiation.
+
+ The media transports can interact with the SDP offer/answer via
+ these APIs:
+ - #pjmedia_transport_media_create(), to initialize the media transport
+ for new media session,
+ - #pjmedia_transport_encode_sdp(), to encode SDP offer or answer,
+ - #pjmedia_transport_media_start(), to activate the settings that
+ have been negotiated by SDP offer answer, and
+ - #pjmedia_transport_media_stop(), to deinitialize the media transport
+ and reset the transport to its idle state.
+
+ The usage of these API in the context of SDP offer answer will be
+ described below.
+
+ \subsection media_create Initializing Transport for New Session
+
+ Application must call #pjmedia_transport_media_create() before using
+ the transport for a new session.
+
+ \subsection creat_oa Creating SDP Offer and Answer
+
+ The #pjmedia_transport_encode_sdp() is used to put additional information
+ from the transport to the local SDP, before the SDP is sent and negotiated
+ with remote SDP.
+
+ When creating an offer, call #pjmedia_transport_encode_sdp() with
+ local SDP (and NULL as \a rem_sdp). The media transport will add the
+ relevant attributes in the local SDP. Application then gives the local
+ SDP to the invite session to be sent to remote agent.
+
+ When creating an answer, also call #pjmedia_transport_encode_sdp(),
+ but this time specify both local and remote SDP to the function. The
+ media transport will once again modify the local SDP and add relevant
+ attributes to the local SDP, if the appropriate attributes related to
+ the transport functionality are present in remote offer. The remote
+ SDP does not contain the relevant attributes, then the specific transport
+ functionality will not be activated for the session.
+
+ The #pjmedia_transport_encode_sdp() should also be called when application
+ sends subsequent SDP offer or answer. The media transport will encode
+ the appropriate attributes based on the state of the session.
+
+ \subsection media_start Offer/Answer Completion
+
+ Once both local and remote SDP have been negotiated by the
+ \ref PJMEDIA_SDP_NEG (normally this is part of PJSIP invite session),
+ application should give both local and remote SDP to
+ #pjmedia_transport_media_start() so that the settings are activated
+ for the session. This function should be called for both initial and
+ subsequent SDP negotiation.
+
+ \subsection media_stop Stopping Transport
+
+ Once session is stop application must call #pjmedia_transport_media_stop()
+ to deactivate the transport feature. Application may reuse the transport
+ for subsequent media session by repeating the #pjmedia_transport_media_create(),
+ #pjmedia_transport_encode_sdp(), #pjmedia_transport_media_start(), and
+ #pjmedia_transport_media_stop() above.
+
+ * \section PJMEDIA_TRANSPORT_H_IMPL Implementing Media Transport
+ *
+ * To implement a new type of media transport, one needs to "subclass" the
+ * media transport "class" (#pjmedia_transport) by providing the "methods"
+ * in the media transport "interface" (#pjmedia_transport_op), and provides
+ * a function to create this new type of transport (similar to
+ * #pjmedia_transport_udp_create() function).
+ *
+ * The media transport is expected to run indepently, that is there should
+ * be no polling like function to poll the transport for incoming RTP/RTCP
+ * packets. This normally can be done by registering the media sockets to
+ * the media endpoint's IOQueue, which allows the transport to be notified
+ * when incoming packet has arrived.
+ *
+ * Alternatively, media transport may utilize thread(s) internally to wait
+ * for incoming packets. The thread then will call the appropriate RTP or
+ * RTCP callback provided by its user (stream) whenever packet is received.
+ * If the transport's user is a stream, then the callbacks provided by the
+ * stream will be thread-safe, so the transport may call these callbacks
+ * without having to serialize the access with some mutex protection. But
+ * the media transport may still have to protect its internal data with
+ * mutex protection, since it may be called by application's thread (for
+ * example, to send RTP/RTCP packets).
+ *
+ */
+
+
+#include <pjmedia/sdp.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Forward declaration for media transport.
+ */
+typedef struct pjmedia_transport pjmedia_transport;
+
+/**
+ * Forward declaration for media transport info.
+ */
+typedef struct pjmedia_transport_info pjmedia_transport_info;
+
+/**
+ * This enumeration specifies the general behaviour of media processing
+ */
+typedef enum pjmedia_tranport_media_option
+{
+ /**
+ * When this flag is specified, the transport will not perform media
+ * transport validation, this is useful when transport is stacked with
+ * other transport, for example when transport UDP is stacked under
+ * transport SRTP, media transport validation only need to be done by
+ * transport SRTP.
+ */
+ PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1
+
+} pjmedia_tranport_media_option;
+
+
+/**
+ * Media socket info is used to describe the underlying sockets
+ * to be used as media transport.
+ */
+typedef struct pjmedia_sock_info
+{
+ /** The RTP socket handle */
+ pj_sock_t rtp_sock;
+
+ /** Address to be advertised as the local address for the RTP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtp_addr_name;
+
+ /** The RTCP socket handle. */
+ pj_sock_t rtcp_sock;
+
+ /** Address to be advertised as the local address for the RTCP
+ * socket, which does not need to be equal as the bound
+ * address (for example, this address can be the address resolved
+ * with STUN).
+ */
+ pj_sockaddr rtcp_addr_name;
+
+} pjmedia_sock_info;
+
+
+/**
+ * This structure describes the operations for the stream transport.
+ */
+struct pjmedia_transport_op
+{
+ /**
+ * Get media socket info from the specified transport.
+ *
+ * Application should call #pjmedia_transport_get_info() instead
+ */
+ pj_status_t (*get_info)(pjmedia_transport *tp,
+ pjmedia_transport_info *info);
+
+ /**
+ * This function is called by the stream when the transport is about
+ * to be used by the stream for the first time, and it tells the transport
+ * about remote RTP address to send the packet and some callbacks to be
+ * called for incoming packets.
+ *
+ * Application should call #pjmedia_transport_attach() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*attach)(pjmedia_transport *tp,
+ void *user_data,
+ const pj_sockaddr_t *rem_addr,
+ const pj_sockaddr_t *rem_rtcp,
+ unsigned addr_len,
+ void (*rtp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t size),
+ void (*rtcp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t size));
+
+ /**
+ * This function is called by the stream when the stream no longer
+ * needs the transport (normally when the stream is about to be closed).
+ * After the transport is detached, it will ignore incoming
+ * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
+ * Application may re-attach the media transport to another transport
+ * user (e.g. stream) after the transport has been detached.
+ *
+ * Application should call #pjmedia_transport_detach() instead of
+ * calling this function directly.
+ */
+ void (*detach)(pjmedia_transport *tp,
+ void *user_data);
+
+ /**
+ * This function is called by the stream to send RTP packet using the
+ * transport.
+ *
+ * Application should call #pjmedia_transport_send_rtp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function is called by the stream to send RTCP packet using the
+ * transport.
+ *
+ * Application should call #pjmedia_transport_send_rtcp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtcp)(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * This function is called by the stream to send RTCP packet using the
+ * transport with destination address other than default specified in
+ * #pjmedia_transport_attach().
+ *
+ * Application should call #pjmedia_transport_send_rtcp2() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*send_rtcp2)(pjmedia_transport *tp,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len,
+ const void *pkt,
+ pj_size_t size);
+
+ /**
+ * Prepare the transport for a new media session.
+ *
+ * Application should call #pjmedia_transport_media_create() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_create)(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ unsigned options,
+ const pjmedia_sdp_session *remote_sdp,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to generate the SDP parts
+ * related to transport type, e.g: ICE, SRTP.
+ *
+ * Application should call #pjmedia_transport_encode_sdp() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*encode_sdp)(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to start the transport
+ * based on local and remote SDP.
+ *
+ * Application should call #pjmedia_transport_media_start() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_start) (pjmedia_transport *tp,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *sdp_remote,
+ unsigned media_index);
+
+ /**
+ * This function is called by application to stop the transport.
+ *
+ * Application should call #pjmedia_transport_media_stop() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*media_stop) (pjmedia_transport *tp);
+
+ /**
+ * This function can be called to simulate packet lost.
+ *
+ * Application should call #pjmedia_transport_simulate_lost() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*simulate_lost)(pjmedia_transport *tp,
+ pjmedia_dir dir,
+ unsigned pct_lost);
+
+ /**
+ * This function can be called to destroy this transport.
+ *
+ * Application should call #pjmedia_transport_close() instead of
+ * calling this function directly.
+ */
+ pj_status_t (*destroy)(pjmedia_transport *tp);
+};
+
+
+/**
+ * @see pjmedia_transport_op.
+ */
+typedef struct pjmedia_transport_op pjmedia_transport_op;
+
+
+/**
+ * Media transport type.
+ */
+typedef enum pjmedia_transport_type
+{
+ /** Media transport using standard UDP */
+ PJMEDIA_TRANSPORT_TYPE_UDP,
+
+ /** Media transport using ICE */
+ PJMEDIA_TRANSPORT_TYPE_ICE,
+
+ /**
+ * Media transport SRTP, this transport is actually security adapter to be
+ * stacked with other transport to enable encryption on the underlying
+ * transport.
+ */
+ PJMEDIA_TRANSPORT_TYPE_SRTP,
+
+ /**
+ * Start of user defined transport.
+ */
+ PJMEDIA_TRANSPORT_TYPE_USER
+
+} pjmedia_transport_type;
+
+
+/**
+ * This structure declares media transport. A media transport is called
+ * by the stream to transmit a packet, and will notify stream when
+ * incoming packet is arrived.
+ */
+struct pjmedia_transport
+{
+ /** Transport name (for logging purpose). */
+ char name[PJ_MAX_OBJ_NAME];
+
+ /** Transport type. */
+ pjmedia_transport_type type;
+
+ /** Transport's "virtual" function table. */
+ pjmedia_transport_op *op;
+
+ /** Application/user data */
+ void *user_data;
+};
+
+/**
+ * This structure describes storage buffer of transport specific info.
+ * The actual transport specific info contents will be defined by transport
+ * implementation. Note that some transport implementations do not need to
+ * provide specific info, since the general socket info is enough.
+ */
+typedef struct pjmedia_transport_specific_info
+{
+ /**
+ * Specify media transport type.
+ */
+ pjmedia_transport_type type;
+
+ /**
+ * Specify storage buffer size of transport specific info.
+ */
+ int cbsize;
+
+ /**
+ * Storage buffer of transport specific info.
+ */
+ char buffer[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE];
+
+} pjmedia_transport_specific_info;
+
+
+/**
+ * This structure describes transport informations, including general
+ * socket information and specific information of single transport or
+ * stacked transports (e.g: SRTP stacked on top of UDP)
+ */
+struct pjmedia_transport_info
+{
+ /**
+ * General socket info.
+ */
+ pjmedia_sock_info sock_info;
+
+ /**
+ * Remote address where RTP/RTCP originated from. In case this transport
+ * hasn't ever received packet, the
+ */
+ pj_sockaddr src_rtp_name;
+ pj_sockaddr src_rtcp_name;
+
+ /**
+ * Specifies number of transport specific info included.
+ */
+ unsigned specific_info_cnt;
+
+ /**
+ * Buffer storage of transport specific info.
+ */
+ pjmedia_transport_specific_info spc_info[PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT];
+
+};
+
+
+/**
+ * Initialize transport info.
+ *
+ * @param info Transport info to be initialized.
+ */
+PJ_INLINE(void) pjmedia_transport_info_init(pjmedia_transport_info *info)
+{
+ pj_bzero(&info->sock_info, sizeof(pjmedia_sock_info));
+ info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET;
+ info->specific_info_cnt = 0;
+}
+
+
+/**
+ * Get media transport info from the specified transport and all underlying
+ * transports if any. The transport also contains information about socket info
+ * which describes the local address of the transport, and would be needed
+ * for example to fill in the "c=" and "m=" line of local SDP.
+ *
+ * @param tp The transport.
+ * @param info Media socket info to be initialized.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_get_info(pjmedia_transport *tp,
+ pjmedia_transport_info *info)
+{
+ if (tp && tp->op && tp->op->get_info)
+ return (*tp->op->get_info)(tp, info);
+
+ return PJ_ENOTSUP;
+}
+
+
+/**
+ * Attach callbacks to be called on receipt of incoming RTP/RTCP packets.
+ * This is just a simple wrapper which calls <tt>attach()</tt> member of
+ * the transport.
+ *
+ * @param tp The media transport.
+ * @param user_data Arbitrary user data to be set when the callbacks are
+ * called.
+ * @param rem_addr Remote RTP address to send RTP packet to.
+ * @param rem_rtcp Optional remote RTCP address. If the argument is NULL
+ * or if the address is zero, the RTCP address will be
+ * calculated from the RTP address (which is RTP port
+ * plus one).
+ * @param addr_len Length of the remote address.
+ * @param rtp_cb Callback to be called when RTP packet is received on
+ * the transport.
+ * @param rtcp_cb Callback to be called when RTCP packet is received on
+ * the transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_attach(pjmedia_transport *tp,
+ void *user_data,
+ const pj_sockaddr_t *rem_addr,
+ const pj_sockaddr_t *rem_rtcp,
+ unsigned addr_len,
+ void (*rtp_cb)(void *user_data,
+ void *pkt,
+ pj_ssize_t),
+ void (*rtcp_cb)(void *usr_data,
+ void*pkt,
+ pj_ssize_t))
+{
+ return tp->op->attach(tp, user_data, rem_addr, rem_rtcp, addr_len,
+ rtp_cb, rtcp_cb);
+}
+
+
+/**
+ * Detach callbacks from the transport.
+ * This is just a simple wrapper which calls <tt>detach()</tt> member of
+ * the transport. After the transport is detached, it will ignore incoming
+ * RTP/RTCP packets, and will refuse to send outgoing RTP/RTCP packets.
+ * Application may re-attach the media transport to another transport user
+ * (e.g. stream) after the transport has been detached.
+ *
+ * @param tp The media transport.
+ * @param user_data User data which must match the previously set value
+ * on attachment.
+ */
+PJ_INLINE(void) pjmedia_transport_detach(pjmedia_transport *tp,
+ void *user_data)
+{
+ tp->op->detach(tp, user_data);
+}
+
+
+/**
+ * Send RTP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtp()</tt> member of the transport. The
+ * RTP packet will be delivered to the destination address specified in
+ * #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtp(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtp)(tp, pkt, size);
+}
+
+
+/**
+ * Send RTCP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtcp()</tt> member of the transport. The
+ * RTCP packet will be delivered to the destination address specified in
+ * #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp(pjmedia_transport *tp,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtcp)(tp, pkt, size);
+}
+
+
+/**
+ * Send RTCP packet with the specified media transport. This is just a simple
+ * wrapper which calls <tt>send_rtcp2()</tt> member of the transport. The
+ * RTCP packet will be delivered to the destination address specified in
+ * param addr, if addr is NULL, RTCP packet will be delivered to destination
+ * address specified in #pjmedia_transport_attach() function.
+ *
+ * @param tp The media transport.
+ * @param addr The destination address.
+ * @param addr_len Length of destination address.
+ * @param pkt The packet to send.
+ * @param size Size of the packet.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_send_rtcp2(pjmedia_transport *tp,
+ const pj_sockaddr_t *addr,
+ unsigned addr_len,
+ const void *pkt,
+ pj_size_t size)
+{
+ return (*tp->op->send_rtcp2)(tp, addr, addr_len, pkt, size);
+}
+
+
+/**
+ * Prepare the media transport for a new media session, Application must
+ * call this function before starting a new media session using this
+ * transport.
+ *
+ * This is just a simple wrapper which calls <tt>media_create()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param sdp_pool Pool object to allocate memory related to SDP
+ * messaging components.
+ * @param options Option flags, from #pjmedia_tranport_media_option
+ * @param rem_sdp Remote SDP if local SDP is an answer, otherwise
+ * specify NULL if SDP is an offer.
+ * @param media_index Media index in SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ unsigned options,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index)
+{
+ return (*tp->op->media_create)(tp, sdp_pool, options, rem_sdp,
+ media_index);
+}
+
+
+/**
+ * Put transport specific information into the SDP. This function can be
+ * called to put transport specific information in the initial or
+ * subsequent SDP offer or answer.
+ *
+ * This is just a simple wrapper which calls <tt>encode_sdp()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param sdp_pool Pool object to allocate memory related to SDP
+ * messaging components.
+ * @param sdp The local SDP to be filled in information from the
+ * media transport.
+ * @param rem_sdp Remote SDP if local SDP is an answer, otherwise
+ * specify NULL if SDP is an offer.
+ * @param media_index Media index in SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_encode_sdp(pjmedia_transport *tp,
+ pj_pool_t *sdp_pool,
+ pjmedia_sdp_session *sdp,
+ const pjmedia_sdp_session *rem_sdp,
+ unsigned media_index)
+{
+ return (*tp->op->encode_sdp)(tp, sdp_pool, sdp, rem_sdp, media_index);
+}
+
+
+/**
+ * Start the transport session with the settings in both local and remote
+ * SDP. The actual work that is done by this function depends on the
+ * underlying transport type. For SRTP, this will activate the encryption
+ * and decryption based on the keys found the SDPs. For ICE, this will
+ * start ICE negotiation according to the information found in the SDPs.
+ *
+ * This is just a simple wrapper which calls <tt>media_start()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ * @param tmp_pool The memory pool for allocating temporary objects.
+ * @param sdp_local Local SDP.
+ * @param sdp_remote Remote SDP.
+ * @param media_index Media index in the SDP.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_start(pjmedia_transport *tp,
+ pj_pool_t *tmp_pool,
+ const pjmedia_sdp_session *sdp_local,
+ const pjmedia_sdp_session *sdp_remote,
+ unsigned media_index)
+{
+ return (*tp->op->media_start)(tp, tmp_pool, sdp_local, sdp_remote,
+ media_index);
+}
+
+
+/**
+ * This API should be called when the session is stopped, to allow the media
+ * transport to release its resources used for the session.
+ *
+ * This is just a simple wrapper which calls <tt>media_stop()</tt> member
+ * of the transport.
+ *
+ * @param tp The media transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_media_stop(pjmedia_transport *tp)
+{
+ return (*tp->op->media_stop)(tp);
+}
+
+/**
+ * Close media transport. This is just a simple wrapper which calls
+ * <tt>destroy()</tt> member of the transport. This function will free
+ * all resources created by this transport (such as sockets, memory, etc.).
+ *
+ * @param tp The media transport.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_close(pjmedia_transport *tp)
+{
+ if (tp->op->destroy)
+ return (*tp->op->destroy)(tp);
+ else
+ return PJ_SUCCESS;
+}
+
+/**
+ * Simulate packet lost in the specified direction (for testing purposes).
+ * When enabled, the transport will randomly drop packets to the specified
+ * direction.
+ *
+ * @param tp The media transport.
+ * @param dir Media direction to which packets will be randomly dropped.
+ * @param pct_lost Percent lost (0-100). Set to zero to disable packet
+ * lost simulation.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_transport_simulate_lost(pjmedia_transport *tp,
+ pjmedia_dir dir,
+ unsigned pct_lost)
+{
+ return (*tp->op->simulate_lost)(tp, dir, pct_lost);
+}
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/transport_adapter_sample.h b/pjmedia/include/pjmedia/transport_adapter_sample.h
new file mode 100644
index 0000000..be991a3
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport_adapter_sample.h
@@ -0,0 +1,76 @@
+/* $Id: transport_adapter_sample.h 3841 2011-10-24 09:28:13Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__
+#define __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__
+
+
+/**
+ * @file transport_adapter_sample.h
+ * @brief Sample Media Transport Adapter
+ */
+
+#include <pjmedia/transport.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_ADAPTER_SAMPLE Sample Transport Adapter
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Example on how to create transport adapter.
+ * @{
+ *
+ * This describes a sample implementation of transport adapter, similar to
+ * the way the SRTP transport adapter works.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create the transport adapter, specifying the underlying transport to be
+ * used to send and receive RTP/RTCP packets.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this media transport
+ * for logging purposes.
+ * @param base_tp The base/underlying media transport to send and
+ * receive RTP/RTCP packets.
+ * @param del_base Specify whether the base transport should also be
+ * destroyed when destroy() is called upon us.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_tp_adapter_create( pjmedia_endpt *endpt,
+ const char *name,
+ pjmedia_transport *base_tp,
+ pj_bool_t del_base,
+ pjmedia_transport **p_tp);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_ADAPTER_SAMPLE_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/transport_ice.h b/pjmedia/include/pjmedia/transport_ice.h
new file mode 100644
index 0000000..4500fae
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport_ice.h
@@ -0,0 +1,228 @@
+/* $Id: transport_ice.h 3872 2011-10-28 04:27:41Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_ICE_H__
+#define __PJMEDIA_TRANSPORT_ICE_H__
+
+
+/**
+ * @file transport_ice.h
+ * @brief ICE capable media transport.
+ */
+
+#include <pjmedia/stream.h>
+#include <pjnath/ice_strans.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_ICE ICE Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Interactive Connectivity Establishment (ICE) transport
+ * @{
+ *
+ * This describes the implementation of media transport using
+ * Interactive Connectivity Establishment (ICE) protocol.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Structure containing callbacks to receive ICE notifications.
+ */
+typedef struct pjmedia_ice_cb
+{
+ /**
+ * This callback will be called when ICE negotiation completes.
+ *
+ * @param tp PJMEDIA ICE transport.
+ * @param op The operation
+ * @param status Operation status.
+ */
+ void (*on_ice_complete)(pjmedia_transport *tp,
+ pj_ice_strans_op op,
+ pj_status_t status);
+
+} pjmedia_ice_cb;
+
+
+/**
+ * This structure specifies ICE transport specific info. This structure
+ * will be filled in media transport specific info.
+ */
+typedef struct pjmedia_ice_transport_info
+{
+ /**
+ * ICE sesion state.
+ */
+ pj_ice_strans_state sess_state;
+
+ /**
+ * Session role.
+ */
+ pj_ice_sess_role role;
+
+ /**
+ * Number of components in the component array. Before ICE negotiation
+ * is complete, the number represents the number of components of the
+ * local agent. After ICE negotiation has been completed successfully,
+ * the number represents the number of common components between local
+ * and remote agents.
+ */
+ unsigned comp_cnt;
+
+ /**
+ * Array of ICE components. Typically the first element denotes RTP and
+ * second element denotes RTCP.
+ */
+ struct
+ {
+ /**
+ * Local candidate type.
+ */
+ pj_ice_cand_type lcand_type;
+
+ /**
+ * The local address.
+ */
+ pj_sockaddr lcand_addr;
+
+ /**
+ * Remote candidate type.
+ */
+ pj_ice_cand_type rcand_type;
+
+ /**
+ * Remote address.
+ */
+ pj_sockaddr rcand_addr;
+
+ } comp[2];
+
+} pjmedia_ice_transport_info;
+
+
+/**
+ * Options that can be specified when creating ICE transport.
+ */
+enum pjmedia_transport_ice_options
+{
+ /**
+ * Normally when remote doesn't use ICE, the ICE transport will
+ * continuously check the source address of incoming packets to see
+ * if it is different than the configured remote address, and switch
+ * the remote address to the source address of the packet if they
+ * are different after several packets are received.
+ * Specifying this option will disable this feature.
+ */
+ PJMEDIA_ICE_NO_SRC_ADDR_CHECKING = 1
+};
+
+
+/**
+ * Create the Interactive Connectivity Establishment (ICE) media transport
+ * using the specified configuration. When STUN or TURN (or both) is used,
+ * the creation operation will complete asynchronously, when STUN resolution
+ * and TURN allocation completes. When the initialization completes, the
+ * \a on_ice_complete() complete will be called with \a op parameter equal
+ * to PJ_ICE_STRANS_OP_INIT.
+ *
+ * In addition, this transport will also notify the application about the
+ * result of ICE negotiation, also in \a on_ice_complete() callback. In this
+ * case the callback will be called with \a op parameter equal to
+ * PJ_ICE_STRANS_OP_NEGOTIATION.
+ *
+ * Other than this, application should use the \ref PJMEDIA_TRANSPORT API
+ * to manipulate this media transport.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * The same as #pjmedia_ice_create() with additional \a options param.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param options Options, see #pjmedia_transport_ice_options.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+/**
+ * The same as #pjmedia_ice_create2() with additional \a user_data param.
+ *
+ * @param endpt The media endpoint.
+ * @param name Optional name to identify this ICE media transport
+ * for logging purposes.
+ * @param comp_cnt Number of components to be created.
+ * @param cfg Pointer to configuration settings.
+ * @param cb Optional structure containing ICE specific callbacks.
+ * @param options Options, see #pjmedia_transport_ice_options.
+ * @param user_data User data to be attached to the transport.
+ * @param p_tp Pointer to receive the media transport instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
+ const char *name,
+ unsigned comp_cnt,
+ const pj_ice_strans_cfg *cfg,
+ const pjmedia_ice_cb *cb,
+ unsigned options,
+ void *user_data,
+ pjmedia_transport **p_tp);
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_ICE_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/transport_loop.h b/pjmedia/include/pjmedia/transport_loop.h
new file mode 100644
index 0000000..4f1a5ba
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport_loop.h
@@ -0,0 +1,82 @@
+/* $Id: transport_loop.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_LOOP_H__
+#define __PJMEDIA_TRANSPORT_LOOP_H__
+
+
+/**
+ * @file transport_loop.h
+ * @brief Loopback transport
+ */
+
+#include <pjmedia/stream.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_LOOP Loopback Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Loopback transport for testing.
+ * @{
+ *
+ * This is the loopback media transport, where packets sent to this transport
+ * will be sent back to the streams attached to this transport. Unlike the
+ * other PJMEDIA transports, the loop transport may be attached to multiple
+ * streams (in other words, application should specify the same loop transport
+ * instance when calling #pjmedia_stream_create()). Any RTP or RTCP packets
+ * sent by one stream to this transport by default will be sent back to all
+ * streams that are attached to this transport, including to the stream that
+ * sends the packet. Application may individually select which stream to
+ * receive packets by calling #pjmedia_transport_loop_disable_rx().
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Create the loopback transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_loop_create(pjmedia_endpt *endpt,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Set this stream as the receiver of incoming packets.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_loop_disable_rx(pjmedia_transport *tp,
+ void *user,
+ pj_bool_t disabled);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_LOOP_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/transport_srtp.h b/pjmedia/include/pjmedia/transport_srtp.h
new file mode 100644
index 0000000..1f2bda4
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport_srtp.h
@@ -0,0 +1,317 @@
+/* $Id: transport_srtp.h 3999 2012-03-30 07:10:13Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_SRTP_H__
+#define __PJMEDIA_TRANSPORT_SRTP_H__
+
+/**
+ * @file transport_srtp.h
+ * @brief Secure RTP (SRTP) transport.
+ */
+
+#include <pjmedia/transport.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_SRTP Secure RTP (SRTP) Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Media transport adapter to add SRTP feature to existing transports
+ * @{
+ *
+ * This module implements SRTP as described by RFC 3711, using RFC 4568 as
+ * key exchange method. It implements \ref PJMEDIA_TRANSPORT to integrate
+ * with the rest of PJMEDIA framework.
+ *
+ * As we know, media transport is separated from the stream object (which
+ * does the encoding/decoding of PCM frames, (de)packetization of RTP/RTCP
+ * packets, and de-jitter buffering). The connection between stream and media
+ * transport is established when the stream is created (we need to specify
+ * media transport during stream creation), and the interconnection can be
+ * depicted from the diagram below:
+ *
+ \image html media-transport.PNG
+
+ * I think the diagram above is self-explanatory.
+ *
+ * SRTP functionality is implemented as some kind of "adapter", which is
+ * plugged between the stream and the actual media transport that does
+ * sending/receiving RTP/RTCP packets. When SRTP is used, the interconnection
+ * between stream and transport is like the diagram below:
+ *
+ \image html media-srtp-transport.PNG
+
+ * So to stream, the SRTP transport behaves as if it is a media transport
+ * (because it is a media transport), and to the media transport it behaves
+ * as if it is a stream. The SRTP object then forwards RTP packets back and
+ * forth between stream and the actual transport, encrypting/decrypting
+ * the RTP/RTCP packets as necessary.
+ *
+ * The neat thing about this design is the SRTP "adapter" then can be used
+ * to encrypt any kind of media transports. We currently have UDP and ICE
+ * media transports that can benefit SRTP, and we could add SRTP to any
+ * media transports that will be added in the future.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Crypto option.
+ */
+typedef enum pjmedia_srtp_crypto_option
+{
+ /** When this flag is specified, encryption will be disabled. */
+ PJMEDIA_SRTP_NO_ENCRYPTION = 1,
+
+ /** When this flag is specified, authentication will be disabled. */
+ PJMEDIA_SRTP_NO_AUTHENTICATION = 2
+
+} pjmedia_srtp_crypto_option;
+
+
+/**
+ * This structure describes an individual crypto setting.
+ */
+typedef struct pjmedia_srtp_crypto
+{
+ /** Optional key. If empty, a random key will be autogenerated. */
+ pj_str_t key;
+
+ /** Crypto name. */
+ pj_str_t name;
+
+ /** Flags, bitmask from #pjmedia_srtp_crypto_option */
+ unsigned flags;
+
+} pjmedia_srtp_crypto;
+
+
+/**
+ * This enumeration specifies the behavior of the SRTP transport regarding
+ * media security offer and answer.
+ */
+typedef enum pjmedia_srtp_use
+{
+ /**
+ * When this flag is specified, SRTP will be disabled, and the transport
+ * will reject RTP/SAVP offer.
+ */
+ PJMEDIA_SRTP_DISABLED,
+
+ /**
+ * When this flag is specified, SRTP will be advertised as optional and
+ * incoming SRTP offer will be accepted.
+ */
+ PJMEDIA_SRTP_OPTIONAL,
+
+ /**
+ * When this flag is specified, the transport will require that RTP/SAVP
+ * media shall be used.
+ */
+ PJMEDIA_SRTP_MANDATORY
+
+} pjmedia_srtp_use;
+
+
+/**
+ * Settings to be given when creating SRTP transport. Application should call
+ * #pjmedia_srtp_setting_default() to initialize this structure with its
+ * default values.
+ */
+typedef struct pjmedia_srtp_setting
+{
+ /**
+ * Specify the usage policy. Default is PJMEDIA_SRTP_OPTIONAL.
+ */
+ pjmedia_srtp_use use;
+
+ /**
+ * Specify whether the SRTP transport should close the member transport
+ * when it is destroyed. Default: PJ_TRUE.
+ */
+ pj_bool_t close_member_tp;
+
+ /**
+ * Specify the number of crypto suite settings.
+ */
+ unsigned crypto_count;
+
+ /**
+ * Specify individual crypto suite setting.
+ */
+ pjmedia_srtp_crypto crypto[8];
+
+} pjmedia_srtp_setting;
+
+
+/**
+ * This structure specifies SRTP transport specific info. This will fit
+ * into \a buffer field of pjmedia_transport_specific_info.
+ */
+typedef struct pjmedia_srtp_info
+{
+ /**
+ * Specify whether the SRTP transport is active for SRTP session.
+ */
+ pj_bool_t active;
+
+ /**
+ * Specify the policy used by the SRTP session for receive direction.
+ */
+ pjmedia_srtp_crypto rx_policy;
+
+ /**
+ * Specify the policy used by the SRTP session for transmit direction.
+ */
+ pjmedia_srtp_crypto tx_policy;
+
+ /**
+ * Specify the usage policy.
+ */
+ pjmedia_srtp_use use;
+
+ /**
+ * Specify the peer's usage policy.
+ */
+ pjmedia_srtp_use peer_use;
+
+} pjmedia_srtp_info;
+
+
+/**
+ * Initialize SRTP library. This function should be called before
+ * any SRTP functions, however calling #pjmedia_transport_srtp_create()
+ * will also invoke this function. This function will also register SRTP
+ * library deinitialization to #pj_atexit(), so the deinitialization
+ * of SRTP library will be performed automatically by PJLIB destructor.
+ *
+ * @param endpt The media endpoint instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt);
+
+
+/**
+ * Initialize SRTP setting with its default values.
+ *
+ * @param opt SRTP setting to be initialized.
+ */
+PJ_DECL(void) pjmedia_srtp_setting_default(pjmedia_srtp_setting *opt);
+
+
+/**
+ * Create an SRTP media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param tp The actual media transport to send and receive
+ * RTP/RTCP packets. This media transport will be
+ * kept as member transport of this SRTP instance.
+ * @param opt Optional settings. If NULL is given, default
+ * settings will be used.
+ * @param p_tp Pointer to receive the transport SRTP instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_create(
+ pjmedia_endpt *endpt,
+ pjmedia_transport *tp,
+ const pjmedia_srtp_setting *opt,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Manually start SRTP session with the given parameters. Application only
+ * needs to call this function when the SRTP transport is used without SDP
+ * offer/answer. When SDP offer/answer framework is used, the SRTP transport
+ * will be started/stopped by #pjmedia_transport_media_start() and
+ * #pjmedia_transport_media_stop() respectively.
+ *
+ * Please note that even if an RTP stream is only one direction, application
+ * will still need to provide both crypto suites, because it is needed by
+ * RTCP.
+
+ * If application specifies the crypto keys, the keys for transmit and receive
+ * direction MUST be different.
+ *
+ * @param srtp The SRTP transport.
+ * @param tx Crypto suite setting for transmit direction.
+ * @param rx Crypto suite setting for receive direction.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_start(
+ pjmedia_transport *srtp,
+ const pjmedia_srtp_crypto *tx,
+ const pjmedia_srtp_crypto *rx);
+
+/**
+ * Stop SRTP session.
+ *
+ * @param srtp The SRTP media transport.
+ *
+ * @return PJ_SUCCESS on success.
+ *
+ * @see #pjmedia_transport_srtp_start()
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp);
+
+
+/**
+ * This is a utility function to decrypt SRTP packet using SRTP transport.
+ * This function is not part of SRTP transport's API, but it can be used
+ * to decrypt SRTP packets from non-network (for example, from a saved file)
+ * without having to use the transport framework. See pcaputil.c in the
+ * samples collection on how to use this function.
+ *
+ * @param tp The SRTP transport.
+ * @param is_rtp Set to non-zero if the packet is SRTP, otherwise set
+ * to zero if the packet is SRTCP.
+ * @param pkt On input, it contains SRTP or SRTCP packet. On
+ * output, it contains the decrypted RTP/RTCP packet.
+ * @param pkt_len On input, specify the length of the buffer. On
+ * output, it will be filled with the actual length
+ * of decrypted packet.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,
+ pj_bool_t is_rtp,
+ void *pkt,
+ int *pkt_len);
+
+
+/**
+ * Query member transport of SRTP.
+ *
+ * @param srtp The SRTP media transport.
+ *
+ * @return member media transport.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_transport_srtp_get_member(
+ pjmedia_transport *srtp);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_TRANSPORT_SRTP_H__ */
diff --git a/pjmedia/include/pjmedia/transport_udp.h b/pjmedia/include/pjmedia/transport_udp.h
new file mode 100644
index 0000000..d7e8982
--- /dev/null
+++ b/pjmedia/include/pjmedia/transport_udp.h
@@ -0,0 +1,162 @@
+/* $Id: transport_udp.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TRANSPORT_UDP_H__
+#define __PJMEDIA_TRANSPORT_UDP_H__
+
+
+/**
+ * @file transport_udp.h
+ * @brief Stream transport with UDP.
+ */
+
+#include <pjmedia/stream.h>
+
+
+/**
+ * @defgroup PJMEDIA_TRANSPORT_UDP UDP Media Transport
+ * @ingroup PJMEDIA_TRANSPORT
+ * @brief Implementation of media transport with UDP sockets.
+ * @{
+ *
+ * The UDP media transport is the standard based media transport
+ * as described by RFC 3550/3551. It can be used to facilitate RTP/RTCP
+ * unicast or multicast communication.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Options that can be specified when creating UDP transport.
+ */
+enum pjmedia_transport_udp_options
+{
+ /**
+ * Normally the UDP transport will continuously check the source address
+ * of incoming packets to see if it is different than the configured
+ * remote address, and switch the remote address to the source address
+ * of the packet if they are different after several packets are
+ * received.
+ * Specifying this option will disable this feature.
+ */
+ PJMEDIA_UDP_NO_SRC_ADDR_CHECKING = 1
+};
+
+
+/**
+ * Create an RTP and RTCP sockets and bind the sockets to the specified
+ * port to create media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create(pjmedia_endpt *endpt,
+ const char *name,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Create an RTP and RTCP sockets and bind the sockets to the specified
+ * address and port to create media transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param addr Optional local address to bind the sockets to. If this
+ * argument is NULL or empty, the sockets will be bound
+ * to all interface.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create2(pjmedia_endpt *endpt,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+/**
+ * Another variant of #pjmedia_transport_udp_create() which allows
+ * the creation of IPv6 transport.
+ *
+ * @param endpt The media endpoint instance.
+ * @param af Address family, which can be pj_AF_INET() for IPv4 or
+ * pj_AF_INET6() for IPv6.
+ * @param name Optional name to be assigned to the transport.
+ * @param addr Optional local address to bind the sockets to. If this
+ * argument is NULL or empty, the sockets will be bound
+ * to all interface.
+ * @param port UDP port number for the RTP socket. The RTCP port number
+ * will be set to one above RTP port.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt,
+ int af,
+ const char *name,
+ const pj_str_t *addr,
+ int port,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+/**
+ * Create UDP stream transport from existing sockets. Use this function when
+ * the sockets have previously been created.
+ *
+ * @param endpt The media endpoint instance.
+ * @param name Optional name to be assigned to the transport.
+ * @param si Media socket info containing the RTP and RTCP sockets.
+ * @param options Options, bitmask of #pjmedia_transport_udp_options.
+ * @param p_tp Pointer to receive the transport instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_transport_udp_attach(pjmedia_endpt *endpt,
+ const char *name,
+ const pjmedia_sock_info *si,
+ unsigned options,
+ pjmedia_transport **p_tp);
+
+
+PJ_END_DECL
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TRANSPORT_UDP_H__ */
+
+
diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h
new file mode 100644
index 0000000..93e411c
--- /dev/null
+++ b/pjmedia/include/pjmedia/types.h
@@ -0,0 +1,272 @@
+/* $Id: types.h 3774 2011-09-27 05:24:06Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_TYPES_H__
+#define __PJMEDIA_TYPES_H__
+
+/**
+ * @file pjmedia/types.h Basic Types
+ * @brief Basic PJMEDIA types.
+ */
+
+#include <pjmedia/config.h>
+#include <pj/sock.h>
+#include <pj/types.h>
+
+
+/**
+ * @defgroup PJMEDIA_PORT Media Ports Framework
+ * @brief Extensible framework for media terminations
+ */
+
+
+/**
+ * @defgroup PJMEDIA_FRAME_OP Audio Manipulation Algorithms
+ * @brief Algorithms to manipulate audio frames
+ */
+
+/**
+ * @defgroup PJMEDIA_TYPES Basic Types
+ * @ingroup PJMEDIA_BASE
+ * @brief Basic PJMEDIA types and operations.
+ * @{
+ */
+
+/**
+ * Top most media type. See also #pjmedia_type_name().
+ */
+typedef enum pjmedia_type
+{
+ /** Type is not specified. */
+ PJMEDIA_TYPE_NONE,
+
+ /** The media is audio */
+ PJMEDIA_TYPE_AUDIO,
+
+ /** The media is video. */
+ PJMEDIA_TYPE_VIDEO,
+
+ /** The media is application. */
+ PJMEDIA_TYPE_APPLICATION,
+
+ /** The media type is unknown or unsupported. */
+ PJMEDIA_TYPE_UNKNOWN
+
+} pjmedia_type;
+
+
+/**
+ * Media transport protocol.
+ */
+typedef enum pjmedia_tp_proto
+{
+ /** No transport type */
+ PJMEDIA_TP_PROTO_NONE = 0,
+
+ /** RTP using A/V profile */
+ PJMEDIA_TP_PROTO_RTP_AVP,
+
+ /** Secure RTP */
+ PJMEDIA_TP_PROTO_RTP_SAVP,
+
+ /** Unknown */
+ PJMEDIA_TP_PROTO_UNKNOWN
+
+} pjmedia_tp_proto;
+
+
+/**
+ * Media direction.
+ */
+typedef enum pjmedia_dir
+{
+ /** None */
+ PJMEDIA_DIR_NONE = 0,
+
+ /** Encoding (outgoing to network) stream, also known as capture */
+ PJMEDIA_DIR_ENCODING = 1,
+
+ /** Same as encoding direction. */
+ PJMEDIA_DIR_CAPTURE = PJMEDIA_DIR_ENCODING,
+
+ /** Decoding (incoming from network) stream, also known as playback. */
+ PJMEDIA_DIR_DECODING = 2,
+
+ /** Same as decoding. */
+ PJMEDIA_DIR_PLAYBACK = PJMEDIA_DIR_DECODING,
+
+ /** Same as decoding. */
+ PJMEDIA_DIR_RENDER = PJMEDIA_DIR_DECODING,
+
+ /** Incoming and outgoing stream, same as PJMEDIA_DIR_CAPTURE_PLAYBACK */
+ PJMEDIA_DIR_ENCODING_DECODING = 3,
+
+ /** Same as ENCODING_DECODING */
+ PJMEDIA_DIR_CAPTURE_PLAYBACK = PJMEDIA_DIR_ENCODING_DECODING,
+
+ /** Same as ENCODING_DECODING */
+ PJMEDIA_DIR_CAPTURE_RENDER = PJMEDIA_DIR_ENCODING_DECODING
+
+} pjmedia_dir;
+
+
+/**
+ * Opaque declaration of media endpoint.
+ */
+typedef struct pjmedia_endpt pjmedia_endpt;
+
+/*
+ * Forward declaration for stream (needed by transport).
+ */
+typedef struct pjmedia_stream pjmedia_stream;
+
+/**
+ * Enumeration for picture coordinate base.
+ */
+typedef enum pjmedia_coord_base
+{
+ /**
+ * This specifies that the pixel [0, 0] location is at the left-top
+ * position.
+ */
+ PJMEDIA_COORD_BASE_LEFT_TOP,
+
+ /**
+ * This specifies that the pixel [0, 0] location is at the left-bottom
+ * position.
+ */
+ PJMEDIA_COORD_BASE_LEFT_BOTTOM
+
+} pjmedia_coord_base;
+
+/**
+ * This structure is used to represent rational numbers.
+ */
+typedef struct pjmedia_ratio
+{
+ int num; /** < Numerator. */
+ int denum; /** < Denumerator. */
+} pjmedia_ratio;
+
+/**
+ * This structure represent a coordinate.
+ */
+typedef struct pjmedia_coord
+{
+ int x; /**< X position of the coordinate */
+ int y; /**< Y position of the coordinate */
+} pjmedia_coord;
+
+/**
+ * This structure represents rectangle size.
+ */
+typedef struct pjmedia_rect_size
+{
+ unsigned w; /**< The width. */
+ unsigned h; /**< The height. */
+} pjmedia_rect_size;
+
+/**
+ * This structure describes a rectangle.
+ */
+typedef struct pjmedia_rect
+{
+ pjmedia_coord coord; /**< The position. */
+ pjmedia_rect_size size; /**< The size. */
+} pjmedia_rect;
+
+/**
+ * Enumeration for video/picture orientation.
+ */
+typedef enum pjmedia_orient
+{
+ /**
+ * Unknown orientation.
+ */
+ PJMEDIA_ORIENT_UNKNOWN,
+
+ /**
+ * Natural orientation, e.g: sky upside on landscape view, head upside
+ * on human portrait.
+ */
+ PJMEDIA_ORIENT_NATURAL,
+
+ /**
+ * Specifies that the video/picture needs to be rotated 90 degrees
+ * clockwise to be displayed in natural orientation.
+ */
+ PJMEDIA_ORIENT_ROTATE_90DEG,
+
+ /**
+ * Specifies that the video/picture needs to be rotated 180 degrees
+ * clockwise to be displayed in natural orientation.
+ */
+ PJMEDIA_ORIENT_ROTATE_180DEG,
+
+ /**
+ * Specifies that the video/picture needs to be rotated 270 degrees
+ * clockwise to be displayed in natural orientation.
+ */
+ PJMEDIA_ORIENT_ROTATE_270DEG
+
+} pjmedia_orient;
+
+
+/**
+ * Macro for packing format from a four character code, similar to FOURCC.
+ */
+#define PJMEDIA_FOURCC(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 )
+
+
+/**
+ * Utility function to return the string name for a pjmedia_type.
+ *
+ * @param t The media type.
+ *
+ * @return String.
+ */
+PJ_DECL(const char*) pjmedia_type_name(pjmedia_type t);
+
+/**
+ * A utility function to convert fourcc type of value to four letters string.
+ *
+ * @param sig The fourcc value.
+ * @param buf Buffer to store the string, which MUST be at least
+ * five bytes long.
+ *
+ * @return The string.
+ */
+PJ_INLINE(const char*) pjmedia_fourcc_name(pj_uint32_t sig, char buf[])
+{
+ buf[3] = (char)((sig >> 24) & 0xFF);
+ buf[2] = (char)((sig >> 16) & 0xFF);
+ buf[1] = (char)((sig >> 8) & 0xFF);
+ buf[0] = (char)((sig >> 0) & 0xFF);
+ buf[4] = '\0';
+ return buf;
+}
+
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_TYPES_H__ */
+
diff --git a/pjmedia/include/pjmedia/vid_codec.h b/pjmedia/include/pjmedia/vid_codec.h
new file mode 100644
index 0000000..67c6083
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_codec.h
@@ -0,0 +1,871 @@
+/* $Id: vid_codec.h 3956 2012-02-21 08:31:26Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_CODEC_H__
+#define __PJMEDIA_VID_CODEC_H__
+
+
+/**
+ * @file vid_codec.h
+ * @brief Video codec framework.
+ */
+
+#include <pjmedia/codec.h>
+#include <pjmedia/event.h>
+#include <pjmedia/format.h>
+#include <pjmedia/types.h>
+#include <pj/list.h>
+#include <pj/pool.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJMEDIA_VID_CODEC Video Codecs
+ * @ingroup PJMEDIA_CODEC
+ * @{
+ */
+
+#define PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT 8
+#define PJMEDIA_VID_CODEC_MAX_FPS_CNT 16
+
+/**
+ * This enumeration specifies the packetization property of video encoding
+ * process. The value is bitmask, and smaller value will have higher priority
+ * to be used.
+ */
+typedef enum pjmedia_vid_packing
+{
+ /**
+ * This specifies that the packetization is unknown, or if nothing
+ * is supported.
+ */
+ PJMEDIA_VID_PACKING_UNKNOWN,
+
+ /**
+ * This specifies that the result of video encoding process will be
+ * segmented into packets, which is suitable for RTP transmission.
+ * The maximum size of the packets is set in \a enc_mtu field of
+ * pjmedia_vid_codec_param.
+ */
+ PJMEDIA_VID_PACKING_PACKETS = 1,
+
+ /**
+ * This specifies that video encoding function will produce a whole
+ * or full frame from the source frame. This is normally used for
+ * encoding video for offline storage such as to an AVI file. The
+ * maximum size of the packets is set in \a enc_mtu field of
+ * pjmedia_vid_codec_param.
+ */
+ PJMEDIA_VID_PACKING_WHOLE = 2
+
+} pjmedia_vid_packing;
+
+
+/**
+ * Enumeration of video frame info flag for the bit_info field in the
+ * pjmedia_frame.
+ */
+typedef enum pjmedia_vid_frm_bit_info
+{
+ /**
+ * The video frame is keyframe.
+ */
+ PJMEDIA_VID_FRM_KEYFRAME = 1
+
+} pjmedia_vid_frm_bit_info;
+
+
+/**
+ * Encoding option.
+ */
+typedef struct pjmedia_vid_encode_opt
+{
+ /**
+ * Flag to force the encoder to generate keyframe for the specified input
+ * frame. When this flag is set, application can verify the result by
+ * examining PJMEDIA_VID_FRM_KEYFRAME flag in the bit_info field of the
+ * output frame.
+ */
+ pj_bool_t force_keyframe;
+
+} pjmedia_vid_encode_opt;
+
+
+/**
+ * Identification used to search for codec factory that supports specific
+ * codec specification.
+ */
+typedef struct pjmedia_vid_codec_info
+{
+ pjmedia_format_id fmt_id; /**< Encoded format ID */
+ unsigned pt; /**< Payload type */
+ pj_str_t encoding_name; /**< Encoding name */
+ pj_str_t encoding_desc; /**< Encoding desc */
+ unsigned clock_rate; /**< Clock rate */
+ pjmedia_dir dir; /**< Direction */
+ unsigned dec_fmt_id_cnt; /**< # of supported encoding source
+ format IDs */
+ pjmedia_format_id dec_fmt_id[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];
+ /**< Supported encoding source
+ format IDs */
+ unsigned packings; /**< Supported or requested packings,
+ strategies, bitmask from
+ pjmedia_vid_packing */
+ unsigned fps_cnt; /**< # of supported frame-rates, can be
+ zero (support any frame-rate) */
+ pjmedia_ratio fps[PJMEDIA_VID_CODEC_MAX_FPS_CNT];
+ /**< Supported frame-rates */
+
+} pjmedia_vid_codec_info;
+
+
+/**
+ * Detailed codec attributes used in configuring a codec and in querying
+ * the capability of codec factories. Default attributes of any codecs could
+ * be queried using #pjmedia_vid_codec_mgr_get_default_param() and modified
+ * using #pjmedia_vid_codec_mgr_set_default_param().
+ *
+ * Please note that codec parameter also contains SDP specific setting,
+ * #dec_fmtp and #enc_fmtp, which may need to be set appropriately based on
+ * the effective setting. See each codec documentation for more detail.
+ */
+typedef struct pjmedia_vid_codec_param
+{
+ pjmedia_dir dir; /**< Direction */
+ pjmedia_vid_packing packing; /**< Packetization strategy. */
+
+ pjmedia_format enc_fmt; /**< Encoded format */
+ pjmedia_codec_fmtp enc_fmtp; /**< Encoder fmtp params */
+ unsigned enc_mtu; /**< MTU or max payload size setting*/
+
+ pjmedia_format dec_fmt; /**< Decoded format */
+ pjmedia_codec_fmtp dec_fmtp; /**< Decoder fmtp params */
+
+ pj_bool_t ignore_fmtp; /**< Ignore fmtp params. If set to
+ PJ_TRUE, the codec will apply
+ format settings specified in
+ enc_fmt and dec_fmt only. */
+
+} pjmedia_vid_codec_param;
+
+
+/**
+ * Duplicate video codec parameter.
+ *
+ * @param pool The pool.
+ * @param src The video codec parameter to be duplicated.
+ *
+ * @return Duplicated codec parameter.
+ */
+PJ_DECL(pjmedia_vid_codec_param*) pjmedia_vid_codec_param_clone(
+ pj_pool_t *pool,
+ const pjmedia_vid_codec_param *src);
+
+/**
+ * Forward declaration for video codec.
+ */
+typedef struct pjmedia_vid_codec pjmedia_vid_codec;
+
+
+/**
+ * This structure describes codec operations. Each codec MUST implement
+ * all of these functions.
+ */
+typedef struct pjmedia_vid_codec_op
+{
+ /**
+ * See #pjmedia_vid_codec_init().
+ */
+ pj_status_t (*init)(pjmedia_vid_codec *codec,
+ pj_pool_t *pool );
+
+ /**
+ * See #pjmedia_vid_codec_open().
+ */
+ pj_status_t (*open)(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param );
+
+ /**
+ * See #pjmedia_vid_codec_close().
+ */
+ pj_status_t (*close)(pjmedia_vid_codec *codec);
+
+ /**
+ * See #pjmedia_vid_codec_modify().
+ */
+ pj_status_t (*modify)(pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *param);
+
+ /**
+ * See #pjmedia_vid_codec_get_param().
+ */
+ pj_status_t (*get_param)(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param);
+
+ /**
+ * See #pjmedia_vid_codec_encode_begin().
+ */
+ pj_status_t (*encode_begin)(pjmedia_vid_codec *codec,
+ const pjmedia_vid_encode_opt *opt,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output,
+ pj_bool_t *has_more);
+
+ /**
+ * See #pjmedia_vid_codec_encode_more()
+ */
+ pj_status_t (*encode_more)(pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output,
+ pj_bool_t *has_more);
+
+
+ /*
+ * See #pjmedia_vid_codec_decode().
+ */
+ pj_status_t (*decode)(pjmedia_vid_codec *codec,
+ pj_size_t count,
+ pjmedia_frame packets[],
+ unsigned out_size,
+ pjmedia_frame *output);
+
+ /**
+ * See #pjmedia_vid_codec_recover()
+ */
+ pj_status_t (*recover)(pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output);
+
+} pjmedia_vid_codec_op;
+
+
+
+/*
+ * Forward declaration for pjmedia_vid_codec_factory.
+ */
+typedef struct pjmedia_vid_codec_factory pjmedia_vid_codec_factory;
+
+
+/**
+ * This structure describes a video codec instance. Codec implementers
+ * should use #pjmedia_vid_codec_init() to initialize this structure with
+ * default values.
+ */
+struct pjmedia_vid_codec
+{
+ /** Entries to put this codec instance in codec factory's list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec);
+
+ /** Codec's private data. */
+ void *codec_data;
+
+ /** Codec factory where this codec was allocated. */
+ pjmedia_vid_codec_factory *factory;
+
+ /** Operations to codec. */
+ pjmedia_vid_codec_op *op;
+};
+
+
+
+/**
+ * This structure describes operations that must be supported by codec
+ * factories.
+ */
+typedef struct pjmedia_vid_codec_factory_op
+{
+ /**
+ * Check whether the factory can create codec with the specified
+ * codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ *
+ * @return PJ_SUCCESS if this factory is able to create an
+ * instance of codec with the specified info.
+ */
+ pj_status_t (*test_alloc)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info );
+
+ /**
+ * Create default attributes for the specified codec ID. This function
+ * can be called by application to get the capability of the codec.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param attr The attribute to be initialized.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+ pj_status_t (*default_attr)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *attr );
+
+ /**
+ * Enumerate supported codecs that can be created using this factory.
+ *
+ * @param factory The codec factory.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*enum_info)(pjmedia_vid_codec_factory *factory,
+ unsigned *count,
+ pjmedia_vid_codec_info codecs[]);
+
+ /**
+ * Create one instance of the codec with the specified codec info.
+ *
+ * @param factory The codec factory.
+ * @param info The codec info.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*alloc_codec)(pjmedia_vid_codec_factory *factory,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec);
+
+ /**
+ * This function is called by codec manager to return a particular
+ * instance of codec back to the codec factory.
+ *
+ * @param factory The codec factory.
+ * @param codec The codec instance to be returned.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+ pj_status_t (*dealloc_codec)(pjmedia_vid_codec_factory *factory,
+ pjmedia_vid_codec *codec );
+
+} pjmedia_vid_codec_factory_op;
+
+
+
+/**
+ * Codec factory describes a module that is able to create codec with specific
+ * capabilities. These capabilities can be queried by codec manager to create
+ * instances of codec.
+ */
+struct pjmedia_vid_codec_factory
+{
+ /** Entries to put this structure in the codec manager list. */
+ PJ_DECL_LIST_MEMBER(struct pjmedia_vid_codec_factory);
+
+ /** The factory's private data. */
+ void *factory_data;
+
+ /** Operations to the factory. */
+ pjmedia_vid_codec_factory_op *op;
+
+};
+
+
+/**
+ * Opaque declaration for codec manager.
+ */
+typedef struct pjmedia_vid_codec_mgr pjmedia_vid_codec_mgr;
+
+/**
+ * Declare maximum codecs
+ */
+#define PJMEDIA_VID_CODEC_MGR_MAX_CODECS 32
+
+
+/**
+ * Initialize codec manager. If there is no the default video codec manager,
+ * this function will automatically set the default video codec manager to
+ * the new codec manager instance. Normally this function is called by pjmedia
+ * endpoint's initialization code.
+ *
+ * @param pool The pool instance.
+ * @param mgr The pointer to the new codec manager instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_create(pj_pool_t *pool,
+ pjmedia_vid_codec_mgr **mgr);
+
+
+/**
+ * Destroy codec manager. Normally this function is called by pjmedia
+ * endpoint's deinitialization code.
+ *
+ * @param mgr Codec manager instance. If NULL, it is the default codec
+ * manager instance will be destroyed.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr *mgr);
+
+
+/**
+ * Get the default codec manager instance.
+ *
+ * @return The default codec manager instance or NULL if none.
+ */
+PJ_DECL(pjmedia_vid_codec_mgr*) pjmedia_vid_codec_mgr_instance(void);
+
+
+/**
+ * Set the default codec manager instance.
+ *
+ * @param mgr The codec manager instance.
+ */
+PJ_DECL(void) pjmedia_vid_codec_mgr_set_instance(pjmedia_vid_codec_mgr* mgr);
+
+
+/**
+ * Register codec factory to codec manager. This will also register
+ * all supported codecs in the factory to the codec manager.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param factory The codec factory to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_register_factory( pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory);
+
+/**
+ * Unregister codec factory from the codec manager. This will also
+ * remove all the codecs registered by the codec factory from the
+ * codec manager's list of supported codecs.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param factory The codec factory to be unregistered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_unregister_factory( pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec_factory *factory);
+
+/**
+ * Enumerate all supported codecs that have been registered to the
+ * codec manager by codec factories.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param count On input, specifies the number of elements in
+ * the array. On output, the value will be set to
+ * the number of elements that have been initialized
+ * by this function.
+ * @param info The codec info array, which contents will be
+ * initialized upon return.
+ * @param prio Optional pointer to receive array of codec priorities.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_enum_codecs(pjmedia_vid_codec_mgr *mgr,
+ unsigned *count,
+ pjmedia_vid_codec_info info[],
+ unsigned *prio);
+
+
+/**
+ * Get codec info for the specified payload type. The payload type must be
+ * static or locally defined in #pjmedia_video_pt.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param pt The payload type/number.
+ * @param info Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_codec_info( pjmedia_vid_codec_mgr *mgr,
+ unsigned pt,
+ const pjmedia_vid_codec_info **info);
+
+
+/**
+ * Get codec info for the specified format ID.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param fmt_id Format ID. See #pjmedia_format_id
+ * @param info Pointer to receive codec info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_codec_info2(pjmedia_vid_codec_mgr *mgr,
+ pjmedia_format_id fmt_id,
+ const pjmedia_vid_codec_info **info);
+
+
+/**
+ * Convert codec info struct into a unique codec identifier.
+ * A codec identifier looks something like "H263/90000".
+ *
+ * @param info The codec info
+ * @param id Buffer to put the codec info string.
+ * @param max_len The length of the buffer.
+ *
+ * @return The null terminated codec info string, or NULL if
+ * the buffer is not long enough.
+ */
+PJ_DECL(char*) pjmedia_vid_codec_info_to_id(const pjmedia_vid_codec_info *info,
+ char *id, unsigned max_len );
+
+
+/**
+ * Find codecs by the unique codec identifier. This function will find
+ * all codecs that match the codec identifier prefix. For example, if
+ * "H26" is specified, then it will find "H263/90000", "H264/90000",
+ * and so on, up to the maximum count specified in the argument.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param count Maximum number of codecs to find. On return, it
+ * contains the actual number of codecs found.
+ * @param p_info Array of pointer to codec info to be filled. This
+ * argument may be NULL, which in this case, only
+ * codec count will be returned.
+ * @param prio Optional array of codec priorities.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_find_codecs_by_id(pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ unsigned *count,
+ const pjmedia_vid_codec_info *p_info[],
+ unsigned prio[]);
+
+
+/**
+ * Set codec priority. The codec priority determines the order of
+ * the codec in the SDP created by the endpoint. If more than one codecs
+ * are found with the same codec_id prefix, then the function sets the
+ * priorities of all those codecs.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec_id The full codec ID or codec ID prefix. If an empty
+ * string is given, it will match all codecs.
+ * @param prio Priority to be set. The priority can have any value
+ * between 1 to 255. When the priority is set to zero,
+ * the codec will be disabled.
+ *
+ * @return PJ_SUCCESS if at least one codec info is found.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_set_codec_priority(pjmedia_vid_codec_mgr *mgr,
+ const pj_str_t *codec_id,
+ pj_uint8_t prio);
+
+
+/**
+ * Get default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param info The codec info, which default parameter's is being
+ * queried.
+ * @param param On return, will be filled with the default codec
+ * parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_get_default_param(pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec_param *param);
+
+
+/**
+ * Set default codec param for the specified codec info.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param pool The pool instance.
+ * @param info The codec info, which default parameter's is being
+ * updated.
+ * @param param The new default codec parameter. Set to NULL to reset
+ * codec parameter to library default settings.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_set_default_param(pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ const pjmedia_vid_codec_param *param);
+
+
+/**
+ * Request the codec manager to allocate one instance of codec with the
+ * specified codec info. The codec will enumerate all codec factories
+ * until it finds factory that is able to create the specified codec.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param info The information about the codec to be created.
+ * @param p_codec Pointer to receive the codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_codec_mgr_alloc_codec( pjmedia_vid_codec_mgr *mgr,
+ const pjmedia_vid_codec_info *info,
+ pjmedia_vid_codec **p_codec);
+
+/**
+ * Deallocate the specified codec instance. The codec manager will return
+ * the instance of the codec back to its factory.
+ *
+ * @param mgr The codec manager instance. If NULL, the default codec
+ * manager instance will be used.
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_mgr_dealloc_codec(
+ pjmedia_vid_codec_mgr *mgr,
+ pjmedia_vid_codec *codec);
+
+
+
+/**
+ * Initialize codec using the specified attribute.
+ *
+ * @param codec The codec instance.
+ * @param pool Pool to use when the codec needs to allocate
+ * some memory.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_init( pjmedia_vid_codec *codec,
+ pj_pool_t *pool )
+{
+ return (*codec->op->init)(codec, pool);
+}
+
+
+/**
+ * Open the codec and initialize with the specified parameter.
+ * Upon successful initialization, the codec may modify the parameter
+ * and fills in the unspecified values (such as size or frame rate of
+ * the encoder format, as it may need to be negotiated with remote
+ * preferences via SDP fmtp).
+ *
+ * @param codec The codec instance.
+ * @param param Codec initialization parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_open(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param)
+{
+ return (*codec->op->open)(codec, param);
+}
+
+
+/**
+ * Close and shutdown codec, releasing all resources allocated by
+ * this codec, if any.
+ *
+ * @param codec The codec instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_close( pjmedia_vid_codec *codec )
+{
+ return (*codec->op->close)(codec);
+}
+
+
+/**
+ * Modify the codec parameter after the codec is open.
+ * Note that not all codec parameters can be modified during run-time.
+ * When the parameter cannot be changed, this function will return
+ * non-PJ_SUCCESS, and the original parameters will not be changed.
+ *
+ * @param codec The codec instance.
+ * @param param The new codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_vid_codec_modify(pjmedia_vid_codec *codec,
+ const pjmedia_vid_codec_param *param)
+{
+ return (*codec->op->modify)(codec, param);
+}
+
+
+/**
+ * Get the codec parameter after the codec is opened.
+ *
+ * @param codec The codec instance.
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_vid_codec_get_param(pjmedia_vid_codec *codec,
+ pjmedia_vid_codec_param *param)
+{
+ return (*codec->op->get_param)(codec, param);
+}
+
+/**
+ * Encode the specified input frame. The input MUST contain only one picture
+ * with the appropriate format as specified when opening the codec. Depending
+ * on the packing or packetization set in the \a packing param, the process
+ * may produce multiple encoded packets or payloads to represent the picture.
+ * This is true for example for PJMEDIA_VID_PACKING_PACKETS packing. In this
+ * case, the \a has_more field will be set to PJ_TRUE, and application should
+ * call pjmedia_vid_codec_encode_more() to get the remaining results from the
+ * codec.
+ *
+ * @param codec The codec instance.
+ * @param opt Optional encoding options.
+ * @param input The input frame.
+ * @param out_size The length of buffer in the output frame. This
+ * should be at least the same as the configured
+ * encoding MTU of the codec.
+ * @param output The output frame.
+ * @param has_more PJ_TRUE if more payloads are available; application
+ * should then call pjmedia_vid_codec_encode_more()
+ * to retrieve the remaining results.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_vid_codec_encode_begin( pjmedia_vid_codec *codec,
+ const pjmedia_vid_encode_opt *opt,
+ const pjmedia_frame *input,
+ unsigned out_size,
+ pjmedia_frame *output,
+ pj_bool_t *has_more)
+{
+ return (*codec->op->encode_begin)(codec, opt, input, out_size, output,
+ has_more);
+}
+
+/**
+ * Retrieve more encoded packets/payloads from the codec. Application
+ * should call this function repeatedly until \a has_more flag is set
+ * to PJ_FALSE.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame. This
+ * should be at least the same as as the configured
+ * encoding MTU of the codec.
+ * @param output The output frame.
+ * @param has_more PJ_TRUE if more payloads are available, which in
+ * this case application should call \a encode_more()
+ * to retrieve them.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t)
+pjmedia_vid_codec_encode_more( pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output,
+ pj_bool_t *has_more)
+{
+ return (*codec->op->encode_more)(codec, out_size, output, has_more);
+}
+
+/**
+ * Decode the input packets into one picture. If the packing is set to
+ * PJMEDIA_VID_PACKING_PACKETS when opening the codec, the codec is set
+ * to decode multiple encoded packets into one picture. These encoded
+ * packets are typically retrieved from the jitter buffer. If the packing
+ * is set to PJMEDIA_VID_PACKING_WHOLE, then this decode function can only
+ * accept one frame as the input.
+ *
+ * Note that the decoded picture format may different to the configured
+ * setting (i.e. the format specified in the #pjmedia_vid_codec_param when
+ * opening the codec), in this case the PJMEDIA_EVENT_FMT_CHANGED event will
+ * be emitted by the codec to notify the event. The codec parameter will
+ * also be updated, and application can query the format by using
+ * pjmedia_vid_codec_get_param().
+ *
+ * @param codec The codec instance.
+ * @param pkt_count Number of packets in the input.
+ * @param packets Array of input packets, each containing an encoded
+ * frame.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_decode(pjmedia_vid_codec *codec,
+ pj_size_t pkt_count,
+ pjmedia_frame packets[],
+ unsigned out_size,
+ pjmedia_frame *output)
+{
+ return (*codec->op->decode)(codec, pkt_count, packets, out_size, output);
+}
+
+/**
+ * Recover a missing frame.
+ *
+ * @param codec The codec instance.
+ * @param out_size The length of buffer in the output frame.
+ * @param output The output frame where generated signal
+ * will be placed.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_INLINE(pj_status_t) pjmedia_vid_codec_recover(pjmedia_vid_codec *codec,
+ unsigned out_size,
+ pjmedia_frame *output)
+{
+ if (codec->op && codec->op->recover)
+ return (*codec->op->recover)(codec, out_size, output);
+ else
+ return PJ_ENOTSUP;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup PJMEDIA_CODEC_VID_CODECS Supported video codecs
+ * @ingroup PJMEDIA_VID_CODEC
+ */
+
+
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_CODEC_H__ */
diff --git a/pjmedia/include/pjmedia/vid_codec_util.h b/pjmedia/include/pjmedia/vid_codec_util.h
new file mode 100644
index 0000000..4b32e57
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_codec_util.h
@@ -0,0 +1,158 @@
+/* $Id: vid_codec_util.h 3715 2011-08-19 09:35:25Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_CODEC_UTIL_H__
+#define __PJMEDIA_VID_CODEC_UTIL_H__
+
+
+/**
+ * @file vid_codec_util.h
+ * @brief Video codec utilities.
+ */
+
+#include <pjmedia/vid_codec.h>
+#include <pjmedia/sdp_neg.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Definition of H.263 parameters.
+ */
+typedef struct pjmedia_vid_codec_h263_fmtp
+{
+ unsigned mpi_cnt; /**< # of parsed MPI param */
+ struct mpi {
+ pjmedia_rect_size size; /**< Picture size/resolution */
+ unsigned val; /**< MPI value */
+ } mpi[32]; /**< Minimum Picture Interval parameter */
+
+} pjmedia_vid_codec_h263_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.263.
+ *
+ * @param fmtp The H.263 SDP fmtp to be parsed.
+ * @param h263_fmtp The parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_parse_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h263_fmtp *h263_fmtp);
+
+
+/**
+ * Parse, negotiate, and apply the encoding and decoding SDP fmtp of H.263
+ * in the specified codec parameter.
+ *
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h263_apply_fmtp(
+ pjmedia_vid_codec_param *param);
+
+
+/**
+ * Definition of H.264 parameters.
+ */
+typedef struct pjmedia_vid_codec_h264_fmtp
+{
+ /* profile-level-id */
+ pj_uint8_t profile_idc; /**< Profile ID */
+ pj_uint8_t profile_iop; /**< Profile constraints bits */
+ pj_uint8_t level; /**< Level */
+
+ /* packetization-mode */
+ pj_uint8_t packetization_mode; /**< Packetization mode */
+
+ /* max-mbps, max-fs, max-cpb, max-dpb, and max-br */
+ unsigned max_mbps; /**< Max macroblock processing rate */
+ unsigned max_fs; /**< Max frame size (in macroblocks) */
+ unsigned max_cpb; /**< Max coded picture buffer size */
+ unsigned max_dpb; /**< Max decoded picture buffer size */
+ unsigned max_br; /**< Max video bit rate */
+
+ /* sprop-parameter-sets, in NAL units */
+ pj_size_t sprop_param_sets_len; /**< Parameter set length */
+ pj_uint8_t sprop_param_sets[256]; /**< Parameter set (SPS & PPS),
+ in NAL unit bitstream */
+
+} pjmedia_vid_codec_h264_fmtp;
+
+
+/**
+ * Parse SDP fmtp of H.264.
+ *
+ * @param fmtp The H.264 SDP fmtp to be parsed.
+ * @param h264_fmtp The parsing result.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_parse_fmtp(
+ const pjmedia_codec_fmtp *fmtp,
+ pjmedia_vid_codec_h264_fmtp *h264_fmtp);
+
+
+/**
+ * Match H.264 format in the SDP media offer and answer. This will compare
+ * H.264 identifier parameters in SDP fmtp, i.e: "profile-level-id" and
+ * "packetization-mode" fields. For better interoperability, when the option
+ * #PJMEDIA_SDP_NEG_FMT_MATCH_ALLOW_MODIFY_ANSWER is set, this function
+ * may update the answer so the parameters in the answer match to ones
+ * in the offer.
+ *
+ * @param pool The memory pool.
+ * @param offer The SDP media offer.
+ * @param o_fmt_idx Index of the H.264 format in the SDP media offer.
+ * @param answer The SDP media answer.
+ * @param a_fmt_idx Index of the H.264 format in the SDP media answer.
+ * @param option The format matching option, see
+ * #pjmedia_sdp_neg_fmt_match_flag.
+ *
+ * @return PJ_SUCCESS when the formats in offer and answer match.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_match_sdp(
+ pj_pool_t *pool,
+ pjmedia_sdp_media *offer,
+ unsigned o_fmt_idx,
+ pjmedia_sdp_media *answer,
+ unsigned a_fmt_idx,
+ unsigned option);
+
+
+/**
+ * Parse and apply the encoding and decoding SDP fmtp of H.264 in the
+ * specified codec parameter. This will validate size and fps to conform
+ * to H.264 level specified in SDP fmtp "profile-level-id".
+ *
+ * @param param The codec parameter.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_codec_h264_apply_fmtp(
+ pjmedia_vid_codec_param *param);
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_CODEC_UTIL_H__ */
diff --git a/pjmedia/include/pjmedia/vid_port.h b/pjmedia/include/pjmedia/vid_port.h
new file mode 100644
index 0000000..a5a66d1
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_port.h
@@ -0,0 +1,243 @@
+/* $Id: vid_port.h 4168 2012-06-18 05:59:08Z ming $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDPORT_H__
+#define __PJMEDIA_VIDPORT_H__
+
+/**
+ * @file pjmedia/videoport.h Video media port
+ * @brief Video media port
+ */
+
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia/port.h>
+
+/**
+ * @defgroup PJMEDIA_VIDEO_PORT Video media port
+ * @ingroup PJMEDIA_PORT_CLOCK
+ * @brief Video media port
+ * @{
+ */
+
+PJ_BEGIN_DECL
+
+/**
+ * This structure describes the parameters to create a video port
+ */
+typedef struct pjmedia_vid_port_param
+{
+ /**
+ * Video stream parameter.
+ */
+ pjmedia_vid_dev_param vidparam;
+
+ /**
+ * Specify whether the video port should use active or passive interface.
+ * If active interface is selected, the video port will perform as
+ * a media clock, automatically calls pjmedia_port_get_frame() and
+ * pjmedia_port_put_frame() of its slave port (depending on the direction
+ * that is specified when opening the video stream). If passive interface
+ * is selected, application can retrieve the media port of this video
+ * port by calling pjmedia_vid_port_get_passive_port(), and subsequently
+ * calls pjmedia_port_put_frame() or pjmedia_port_get_frame() to that
+ * media port.
+ *
+ * Default: PJ_TRUE
+ */
+ pj_bool_t active;
+
+} pjmedia_vid_port_param;
+
+/**
+ * Opaque data type for video port.
+ */
+typedef struct pjmedia_vid_port pjmedia_vid_port;
+
+/**
+ * Initialize the parameter with the default values. Note that this typically
+ * would only fill the structure to zeroes unless they have different default
+ * values.
+ *
+ * @param prm The parameter.
+ */
+PJ_DECL(void) pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm);
+
+/**
+ * Create a video port with the specified parameter. When video port opens
+ * the video stream with different parameter than the requested values in
+ * the \a prm.vidparam argument, it will automatically do the necessary
+ * conversion.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param prm The video port parameter.
+ * @param p_vp Pointer to receive the result.
+ *
+ * @return PJ_SUCCESS if video port has been created
+ * successfully, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_create(pj_pool_t *pool,
+ const pjmedia_vid_port_param *prm,
+ pjmedia_vid_port **p_vp);
+
+/**
+ * Set the callbacks of the video port's underlying video stream.
+ *
+ * @param vid_port The video port.
+ * @param cb Pointer to structure containing video stream
+ * callbacks.
+ * @param user_data Arbitrary user data, which will be given back in the
+ * callbacks.
+ */
+PJ_DECL(void) pjmedia_vid_port_set_cb(pjmedia_vid_port *vid_port,
+ const pjmedia_vid_dev_cb *cb,
+ void *user_data);
+
+/**
+ * Return the underlying video stream of the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The video stream.
+ */
+PJ_DECL(pjmedia_vid_dev_stream*)
+pjmedia_vid_port_get_stream(pjmedia_vid_port *vid_port);
+
+/**
+ * Return the (passive) media port of the video port. This operation
+ * is only valid for video ports created with passive interface selected.
+ * Retrieving the media port for active video ports may raise an
+ * assertion.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The media port instance, or NULL.
+ */
+PJ_DECL(pjmedia_port*)
+pjmedia_vid_port_get_passive_port(pjmedia_vid_port *vid_port);
+
+/**
+ * Get a clock source from the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return The clock source.
+ */
+PJ_DECL(pjmedia_clock_src *)
+pjmedia_vid_port_get_clock_src( pjmedia_vid_port *vid_port );
+
+/**
+ * Set a clock source for the video port.
+ *
+ * @param vid_port The video port.
+ * @param clocksrc The clock source.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_port_set_clock_src( pjmedia_vid_port *vid_port,
+ pjmedia_clock_src *clocksrc );
+
+/**
+ * Connect the video port to a downstream (slave) media port. This operation
+ * is only valid for video ports created with active interface selected.
+ * Connecting a passive video port may raise an assertion.
+ *
+ * @param vid_port The video port.
+ * @param port A downstream media port to be connected to
+ * this video port.
+ * @param destroy Specify if the downstream media port should also be
+ * destroyed by this video port when the video port
+ * is destroyed.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_connect(pjmedia_vid_port *vid_port,
+ pjmedia_port *port,
+ pj_bool_t destroy);
+
+/**
+ * Disconnect the video port from its downstream (slave) media port, if any.
+ * This operation is only valid for video ports created with active interface
+ * selected, and assertion may be triggered if this is invoked on a passive
+ * video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_disconnect(pjmedia_vid_port *vid_port);
+
+/**
+ * Retrieve the media port currently connected as downstream media port of the
+ * specified video port. This operation is only valid for video ports created
+ * with active interface selected, and assertion may be triggered if this is
+ * invoked on a passive video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return Media port currently connected to the video port,
+ * if any.
+ */
+PJ_DECL(pjmedia_port*)
+pjmedia_vid_port_get_connected_port(pjmedia_vid_port *vid_port);
+
+/**
+ * Start the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_start(pjmedia_vid_port *vid_port);
+
+/**
+ * Query whether the video port has been started.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_TRUE if the video port has been started.
+ */
+PJ_DECL(pj_bool_t) pjmedia_vid_port_is_running(pjmedia_vid_port *vid_port);
+
+/**
+ * Stop the video port.
+ *
+ * @param vid_port The video port.
+ *
+ * @return PJ_SUCCESS on success or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_port_stop(pjmedia_vid_port *vid_port);
+
+/**
+ * Destroy the video port, along with its video stream. If the video port is
+ * an active one, this may also destroy the downstream media port, if the
+ * destroy flag is set when the media port is connected.
+ *
+ * @param vid_port The video port.
+ */
+PJ_DECL(void) pjmedia_vid_port_destroy(pjmedia_vid_port *vid_port);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_VIDPORT_H__ */
+
diff --git a/pjmedia/include/pjmedia/vid_stream.h b/pjmedia/include/pjmedia/vid_stream.h
new file mode 100644
index 0000000..1a2cbd8
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_stream.h
@@ -0,0 +1,423 @@
+/* $Id: vid_stream.h 4043 2012-04-12 13:41:50Z nanang $ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_STREAM_H__
+#define __PJMEDIA_VID_STREAM_H__
+
+
+/**
+ * @file vid_stream.h
+ * @brief Video Stream.
+ */
+
+#include <pjmedia/endpoint.h>
+#include <pjmedia/jbuf.h>
+#include <pjmedia/port.h>
+#include <pjmedia/rtcp.h>
+#include <pjmedia/transport.h>
+#include <pjmedia/vid_codec.h>
+#include <pj/sock.h>
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMED_VID_STRM Video streams
+ * @ingroup PJMEDIA_PORT
+ * @brief Video communication via the network
+ * @{
+ *
+ * A video stream is a bidirectional video communication between two
+ * endpoints. It corresponds to a video media description ("m=video" line)
+ * in SDP session descriptor.
+ *
+ * A video stream consists of two unidirectional channels:
+ * - encoding channel, which transmits unidirectional video to remote, and
+ * - decoding channel, which receives unidirectional media from remote.
+ *
+ * A video stream exports two media port interface (see @ref PJMEDIA_PORT),
+ * one for each direction, and application normally uses this interface to
+ * interconnect the stream to other PJMEDIA components, e.g: the video
+ * capture port supplies frames to the encoding port and video renderer
+ * consumes frames from the decoding port.
+ *
+ * A video stream internally manages the following objects:
+ * - an instance of video codec (see @ref PJMEDIA_VID_CODEC),
+ * - an @ref PJMED_JBUF,
+ * - two instances of RTP sessions (#pjmedia_rtp_session, one for each
+ * direction),
+ * - one instance of RTCP session (#pjmedia_rtcp_session),
+ * - and a reference to video transport to send and receive packets
+ * to/from the network (see @ref PJMEDIA_TRANSPORT).
+ *
+ * Video streams are created by calling #pjmedia_vid_stream_create(),
+ * specifying #pjmedia_stream_info structure in the parameter. Application
+ * can construct the #pjmedia_vid_stream_info structure manually, or use
+ * #pjmedia_vid_stream_info_from_sdp() function to construct the
+ * #pjmedia_vid stream_info from local and remote SDP session descriptors.
+ */
+
+
+/**
+ * Enumeration of video stream sending rate control.
+ */
+typedef enum pjmedia_vid_stream_rc_method
+{
+ /**
+ * No sending rate control. All outgoing RTP packets will be transmitted
+ * immediately right after encoding process is done.
+ */
+ PJMEDIA_VID_STREAM_RC_NONE = 0,
+
+ /**
+ * Simple blocking. Each outgoing RTP packet transmission may be delayed
+ * to avoid peak bandwidth that is much higher than specified. The thread
+ * invoking the video stream put_frame(), e.g: video capture device thread,
+ * will be blocked whenever transmission delay takes place.
+ */
+ PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING = 1
+
+} pjmedia_vid_stream_rc_method;
+
+
+/**
+ * Structure of configuration settings for video stream sending rate control.
+ */
+typedef struct pjmedia_vid_stream_rc_config
+{
+ /**
+ * Rate control method.
+ *
+ * Default: PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING.
+ */
+ pjmedia_vid_stream_rc_method method;
+
+ /**
+ * Upstream/outgoing bandwidth. If this is set to zero, the video stream
+ * will use codec maximum bitrate setting.
+ *
+ * Default: 0 (follow codec maximum bitrate).
+ */
+ unsigned bandwidth;
+
+} pjmedia_vid_stream_rc_config;
+
+
+/**
+ * This structure describes video stream information. Each video stream
+ * corresponds to one "m=" line in SDP session descriptor, and it has
+ * its own RTP/RTCP socket pair.
+ */
+typedef struct pjmedia_vid_stream_info
+{
+ pjmedia_type type; /**< Media type (audio, video) */
+ pjmedia_tp_proto proto; /**< Transport protocol (RTP/AVP, etc.) */
+ pjmedia_dir dir; /**< Media direction. */
+ pj_sockaddr rem_addr; /**< Remote RTP address */
+ pj_sockaddr rem_rtcp; /**< Optional remote RTCP address. If
+ sin_family is zero, the RTP address
+ will be calculated from RTP. */
+ unsigned tx_pt; /**< Outgoing codec paylaod type. */
+ unsigned rx_pt; /**< Incoming codec paylaod type. */
+ pj_uint32_t ssrc; /**< RTP SSRC. */
+ pj_uint32_t rtp_ts; /**< Initial RTP timestamp. */
+ pj_uint16_t rtp_seq; /**< Initial RTP sequence number. */
+ pj_uint8_t rtp_seq_ts_set;
+ /**< Bitmask flags if initial RTP sequence
+ and/or timestamp for sender are set.
+ bit 0/LSB : sequence flag
+ bit 1 : timestamp flag */
+ int jb_init; /**< Jitter buffer init delay in msec.
+ (-1 for default). */
+ int jb_min_pre; /**< Jitter buffer minimum prefetch
+ delay in msec (-1 for default). */
+ int jb_max_pre; /**< Jitter buffer maximum prefetch
+ delay in msec (-1 for default). */
+ int jb_max; /**< Jitter buffer max delay in msec. */
+
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA!=0
+ pj_bool_t use_ka; /**< Stream keep-alive and NAT hole punch
+ (see #PJMEDIA_STREAM_ENABLE_KA)
+ is enabled? */
+#endif
+
+ pjmedia_vid_codec_info codec_info; /**< Incoming codec format info. */
+ pjmedia_vid_codec_param *codec_param; /**< Optional codec param. */
+
+ pj_bool_t rtcp_sdes_bye_disabled;
+ /**< Disable automatic sending of RTCP
+ SDES and BYE. */
+
+ pjmedia_vid_stream_rc_config rc_cfg;
+ /**< Stream send rate control settings. */
+} pjmedia_vid_stream_info;
+
+
+/**
+ * This function will initialize the video stream info based on information
+ * in both SDP session descriptors for the specified stream index.
+ * The remaining information will be taken from default codec parameters.
+ * If socket info array is specified, the socket will be copied to the
+ * session info as well.
+ *
+ * @param si Stream info structure to be initialized.
+ * @param pool Pool to allocate memory.
+ * @param endpt PJMEDIA endpoint instance.
+ * @param local Local SDP session descriptor.
+ * @param remote Remote SDP session descriptor.
+ * @param stream_idx Media stream index in the session descriptor.
+ *
+ * @return PJ_SUCCESS if stream info is successfully initialized.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si,
+ pj_pool_t *pool,
+ pjmedia_endpt *endpt,
+ const pjmedia_sdp_session *local,
+ const pjmedia_sdp_session *remote,
+ unsigned stream_idx);
+
+
+/**
+ * Initialize the video stream rate control with default settings.
+ *
+ * @param cfg Video stream rate control structure to be initialized.
+ */
+PJ_DECL(void)
+pjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg);
+
+
+/*
+ * Opaque declaration for video stream.
+ */
+typedef struct pjmedia_vid_stream pjmedia_vid_stream;
+
+
+/**
+ * Create a video stream based on the specified parameter. After the video
+ * stream has been created, application normally would want to get the media
+ * port interface of the stream, by calling pjmedia_vid_stream_get_port().
+ * The media port interface exports put_frame() and get_frame() function,
+ * used to transmit and receive media frames from the stream.
+ *
+ * Without application calling put_frame() and get_frame(), there will be
+ * no media frames transmitted or received by the stream.
+ *
+ * @param endpt Media endpoint.
+ * @param pool Optional pool to allocate memory for the stream. If
+ * this is not specified, one will be created internally.
+ * A large number of memory may be needed because jitter
+ * buffer needs to preallocate some storage.
+ * @param info Stream information to create the stream. Upon return,
+ * this info will be updated with the information from
+ * the instantiated codec. Note that if the "pool"
+ * argument is NULL, some fields in this "info" parameter
+ * will be allocated from the internal pool of the
+ * stream, which means that they will only remain valid
+ * as long as the stream is not destroyed.
+ * @param tp Media transport instance used to transmit and receive
+ * RTP/RTCP packets to/from the underlying network.
+ * @param user_data Arbitrary user data (for future callback feature).
+ * @param p_stream Pointer to receive the video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_create(
+ pjmedia_endpt *endpt,
+ pj_pool_t *pool,
+ pjmedia_vid_stream_info *info,
+ pjmedia_transport *tp,
+ void *user_data,
+ pjmedia_vid_stream **p_stream);
+
+/**
+ * Destroy the video stream.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream);
+
+
+/**
+ * Get the media port interface of the stream. The media port interface
+ * declares put_frame() and get_frame() function, which is the only
+ * way for application to transmit and receive media frames from the
+ * stream. As bidirectional video streaming may have different video
+ * formats in the encoding and decoding direction, there are two media
+ * ports exported by the video stream, one for each direction.
+ *
+ * @param stream The video stream.
+ * @param dir The video direction.
+ * @param p_port Pointer to receive the port interface.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_port(
+ pjmedia_vid_stream *stream,
+ pjmedia_dir dir,
+ pjmedia_port **p_port);
+
+
+/**
+ * Get the media transport object associated with this stream.
+ *
+ * @param st The video stream.
+ *
+ * @return The transport object being used by the stream.
+ */
+PJ_DECL(pjmedia_transport*) pjmedia_vid_stream_get_transport(
+ pjmedia_vid_stream *st);
+
+
+/**
+ * Get the stream statistics. See also #pjmedia_stream_get_stat_jbuf()
+ *
+ * @param stream The video stream.
+ * @param stat Media stream statistics.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat(
+ const pjmedia_vid_stream *stream,
+ pjmedia_rtcp_stat *stat);
+
+/**
+ * Reset the video stream statistics.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_reset_stat(pjmedia_vid_stream *stream);
+
+
+/**
+ * Get current jitter buffer state. See also #pjmedia_stream_get_stat()
+ *
+ * @param stream The video stream.
+ * @param state Jitter buffer state.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_stat_jbuf(
+ const pjmedia_vid_stream *stream,
+ pjmedia_jb_state *state);
+
+
+/**
+ * Get the stream info.
+ *
+ * @param stream The video stream.
+ * @param info Video stream info.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_get_info(
+ const pjmedia_vid_stream *stream,
+ pjmedia_vid_stream_info *info);
+
+
+/**
+ * Start the video stream. This will start the appropriate channels
+ * in the video stream, depending on the video direction that was set
+ * when the stream was created.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_start(pjmedia_vid_stream *stream);
+
+
+/**
+ * Query if the stream is started on the specified direction.
+ *
+ * @param stream The video stream.
+ * @param dir The direction to be checked.
+ *
+ * @return PJ_TRUE if stream is started.
+ */
+PJ_DECL(pj_bool_t) pjmedia_vid_stream_is_running(pjmedia_vid_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Pause stream channels.
+ *
+ * @param stream The video stream.
+ * @param dir Which channel direction to pause.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_pause(pjmedia_vid_stream *stream,
+ pjmedia_dir dir);
+
+/**
+ * Resume stream channels.
+ *
+ * @param stream The video stream.
+ * @param dir Which channel direction to resume.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_resume(pjmedia_vid_stream *stream,
+ pjmedia_dir dir);
+
+
+/**
+ * Force stream to send video keyframe on the next transmission.
+ *
+ * @param stream The video stream.
+ *
+ * @return PJ_SUCCESS on success;
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_send_keyframe(
+ pjmedia_vid_stream *stream);
+
+
+/**
+ * Send RTCP SDES for the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_sdes(
+ pjmedia_vid_stream *stream);
+
+
+/**
+ * Send RTCP BYE for the media stream.
+ *
+ * @param stream The media stream.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_bye(
+ pjmedia_vid_stream *stream);
+
+
+/**
+ * @}
+ */
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_VID_STREAM_H__ */
diff --git a/pjmedia/include/pjmedia/vid_tee.h b/pjmedia/include/pjmedia/vid_tee.h
new file mode 100644
index 0000000..faff8ab
--- /dev/null
+++ b/pjmedia/include/pjmedia/vid_tee.h
@@ -0,0 +1,142 @@
+/* $Id: vid_tee.h 3664 2011-07-19 03:42:28Z nanang $ */
+/*
+ * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VID_TEE_H__
+#define __PJMEDIA_VID_TEE_H__
+
+/**
+ * @file vid_tee.h
+ * @brief Video tee (source duplicator).
+ */
+#include <pjmedia/port.h>
+
+/**
+ * @addtogroup PJMEDIA_VID_TEE Video source duplicator
+ * @ingroup PJMEDIA_PORT
+ * @brief Duplicate video data from a media port into multiple media port
+ * destinations
+ * @{
+ *
+ * This section describes media port to duplicate video data in the stream.
+ *
+ * A video tee branches video stream flow from one source port to multiple
+ * destination ports by simply duplicating the video data supplied by the
+ * source port and delivering the copy to all registered destinations.
+ *
+ * The video tee is a unidirectional port, i.e: data flows from source port
+ * to destination ports only. Also, the video source port MUST actively call
+ * pjmedia_port_put_frame() to the video tee and the video destination ports
+ * MUST NEVER call pjmedia_port_get_frame() to the video tee. Please note that
+ * there is no specific order of which destination port will receive a frame
+ * from the video tee.
+ *
+ * The video tee is not thread-safe, so it is application responsibility
+ * to synchronize video tee operations, e.g: make sure the source port is
+ * paused during adding or removing a destination port.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Enumeration of video tee flags.
+ */
+typedef enum pjmedia_vid_tee_flag
+{
+ /**
+ * Tell the video tee that the destination port will do in-place
+ * processing, so the delivered data may be modified by this port.
+ * If this flag is used, buffer will be copied before being given to
+ * the destination port.
+ */
+ PJMEDIA_VID_TEE_DST_DO_IN_PLACE_PROC = 4,
+
+} pjmedia_vid_tee_flag;
+
+
+/**
+ * Create a video tee port with the specified source media port. Application
+ * should destroy the tee with pjmedia_port_destroy() as usual. Note that
+ * destroying the tee does not destroy its destination ports.
+ *
+ * @param pool The pool.
+ * @param fmt The source media port's format.
+ * @param max_dst_cnt The maximum number of destination ports supported.
+ * @param p_vid_tee Pointer to receive the video tee port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_create(pj_pool_t *pool,
+ const pjmedia_format *fmt,
+ unsigned max_dst_cnt,
+ pjmedia_port **p_vid_tee);
+
+/**
+ * Add a destination media port to the video tee. For this function, the
+ * destination port's media format must match the source format.
+ *
+ * @param vid_tee The video tee.
+ * @param option Video tee option, see @pjmedia_vid_tee_flag.
+ * @param port The destination media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port);
+
+
+/**
+ * Add a destination media port to the video tee. This function will also
+ * create a converter if the destination port's media format does not match
+ * the source format.
+ *
+ * @param vid_tee The video tee.
+ * @param option Video tee option, see @pjmedia_vid_tee_flag.
+ * @param port The destination media port.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_add_dst_port2(pjmedia_port *vid_tee,
+ unsigned option,
+ pjmedia_port *port);
+
+
+/**
+ * Remove a destination media port from the video tee.
+ *
+ * @param vid_tee The video tee.
+ * @param port The destination media port to be removed.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error
+ * code.
+ */
+PJ_DECL(pj_status_t) pjmedia_vid_tee_remove_dst_port(pjmedia_port *vid_tee,
+ pjmedia_port *port);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_VID_TEE_H__ */
diff --git a/pjmedia/include/pjmedia/wav_playlist.h b/pjmedia/include/pjmedia/wav_playlist.h
new file mode 100644
index 0000000..a81e16e
--- /dev/null
+++ b/pjmedia/include/pjmedia/wav_playlist.h
@@ -0,0 +1,105 @@
+/* $Id: wav_playlist.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_WAV_PLAYLIST_H__
+#define __PJMEDIA_WAV_PLAYLIST_H__
+
+/**
+ * @file wav_playlist.h
+ * @brief WAV file playlist.
+ */
+#include <pjmedia/wav_port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_WAV_PLAYLIST WAV File Play List
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio playback of multiple WAV files
+ * @{
+ *
+ * The WAV play list port enables application to play back multiple
+ * WAV files in a playlist.
+ */
+
+/**
+ * Create a WAV playlist from the array of WAV file names. The WAV
+ * files must have the same clock rate, number of channels, and bits
+ * per sample, or otherwise this function will return error.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param port_label Optional label to set as the port name.
+ * @param file_list Array of WAV file names.
+ * @param file_count Number of files in the array.
+ * @param ptime The duration (in miliseconds) of each frame read
+ * from this port. If the value is zero, the default
+ * duration (20ms) will be used.
+ * @param options Optional options. Application may specify
+ * PJMEDIA_FILE_NO_LOOP to prevent play back loop.
+ * @param buff_size Buffer size to be allocated. If the value is zero or
+ * negative, the port will use default buffer size (which
+ * is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool,
+ const pj_str_t *port_label,
+ const pj_str_t file_list[],
+ int file_count,
+ unsigned ptime,
+ unsigned options,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port);
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file of the last file. If the file is set to play repeatedly,
+ * then the callback will be called multiple times. Note that only one
+ * callback can be registered for each file port.
+ *
+ * @param port The WAV play list port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_playlist_set_eof_cb(pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_WAV_PLAYLIST_H__ */
diff --git a/pjmedia/include/pjmedia/wav_port.h b/pjmedia/include/pjmedia/wav_port.h
new file mode 100644
index 0000000..365d889
--- /dev/null
+++ b/pjmedia/include/pjmedia/wav_port.h
@@ -0,0 +1,250 @@
+/* $Id: wav_port.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_WAV_PORT_H__
+#define __PJMEDIA_WAV_PORT_H__
+
+/**
+ * @file wav_port.h
+ * @brief WAV file player and writer.
+ */
+#include <pjmedia/port.h>
+
+
+
+PJ_BEGIN_DECL
+
+
+/**
+ * @defgroup PJMEDIA_FILE_PLAY WAV File Player
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio playback from WAV file
+ * @{
+ */
+
+/**
+ * WAV file player options.
+ */
+enum pjmedia_file_player_option
+{
+ /**
+ * Tell the file player to return NULL frame when the whole
+ * file has been played.
+ */
+ PJMEDIA_FILE_NO_LOOP = 1
+};
+
+
+/**
+ * Create a media port to play streams from a WAV file. WAV player port
+ * supports for reading WAV file with uncompressed 16 bit PCM format or
+ * compressed G.711 A-law/U-law format.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param filename File name to open.
+ * @param ptime The duration (in miliseconds) of each frame read
+ * from this port. If the value is zero, the default
+ * duration (20ms) will be used.
+ * @param flags Port creation flags.
+ * @param buff_size Buffer size to be allocated. If the value is zero or
+ * negative, the port will use default buffer size (which
+ * is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_player_port_create( pj_pool_t *pool,
+ const char *filename,
+ unsigned ptime,
+ unsigned flags,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get the data length, in bytes.
+ *
+ * @param port The file player port.
+ *
+ * @return The length of the data, in bytes. Upon error it will
+ * return negative value.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_player_get_len(pjmedia_port *port);
+
+
+/**
+ * Set the file play position of WAV player.
+ *
+ * @param port The file player port.
+ * @param offset Playback position in bytes, relative to the start of
+ * the payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_player_port_set_pos( pjmedia_port *port,
+ pj_uint32_t offset );
+
+
+/**
+ * Get the file play position of WAV player.
+ *
+ * @param port The file player port.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_player_port_get_pos( pjmedia_port *port );
+
+
+/**
+ * Register a callback to be called when the file reading has reached the
+ * end of file. If the file is set to play repeatedly, then the callback
+ * will be called multiple times. Note that only one callback can be
+ * registered for each file port.
+ *
+ * @param port The file player port.
+ * @param user_data User data to be specified in the callback
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the playback will stop. Note that if
+ * application destroys the file port in the callback,
+ * it must return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_player_set_eof_cb( pjmedia_port *port,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup PJMEDIA_FILE_REC File Writer (Recorder)
+ * @ingroup PJMEDIA_PORT
+ * @brief Audio capture/recording to WAV file
+ * @{
+ */
+
+
+/**
+ * WAV file writer options.
+ */
+enum pjmedia_file_writer_option
+{
+ /**
+ * Tell the file writer to save the audio in PCM format.
+ */
+ PJMEDIA_FILE_WRITE_PCM = 0,
+
+ /**
+ * Tell the file writer to save the audio in G711 Alaw format.
+ */
+ PJMEDIA_FILE_WRITE_ALAW = 1,
+
+ /**
+ * Tell the file writer to save the audio in G711 Alaw format.
+ */
+ PJMEDIA_FILE_WRITE_ULAW = 2,
+};
+
+
+/**
+ * Create a media port to record streams to a WAV file. Note that the port
+ * must be closed properly (with #pjmedia_port_destroy()) so that the WAV
+ * header can be filled with correct values (such as the file length).
+ * WAV writer port supports for writing audio in uncompressed 16 bit PCM format
+ * or compressed G.711 U-law/A-law format, this needs to be specified in
+ * \a flags param.
+ *
+ * @param pool Pool to create memory buffers for this port.
+ * @param filename File name.
+ * @param clock_rate The sampling rate.
+ * @param channel_count Number of channels.
+ * @param samples_per_frame Number of samples per frame.
+ * @param bits_per_sample Number of bits per sample (eg 16).
+ * @param flags Port creation flags, see
+ * #pjmedia_file_writer_option.
+ * @param buff_size Buffer size to be allocated. If the value is
+ * zero or negative, the port will use default buffer
+ * size (which is about 4KB).
+ * @param p_port Pointer to receive the file port instance.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_wav_writer_port_create(pj_pool_t *pool,
+ const char *filename,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ unsigned flags,
+ pj_ssize_t buff_size,
+ pjmedia_port **p_port );
+
+
+/**
+ * Get current writing position. Note that this does not necessarily match
+ * the size written to the file, since the WAV writer employs some internal
+ * buffering. Also the value reported here only indicates the payload size
+ * (it does not include the size of the WAV header),
+ *
+ * @param port The file writer port.
+ *
+ * @return Positive value to indicate the position (in bytes),
+ * or negative value containing the error code.
+ */
+PJ_DECL(pj_ssize_t) pjmedia_wav_writer_port_get_pos( pjmedia_port *port );
+
+
+/**
+ * Register the callback to be called when the file writing has reached
+ * certain size. Application can use this callback, for example, to limit
+ * the size of the output file.
+ *
+ * @param port The file writer port.
+ * @param pos The file position on which the callback will be called.
+ * @param user_data User data to be specified in the callback, and will be
+ * given on the callback.
+ * @param cb Callback to be called. If the callback returns non-
+ * PJ_SUCCESS, the writing will stop. Note that if
+ * application destroys the port in the callback, it must
+ * return non-PJ_SUCCESS here.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t)
+pjmedia_wav_writer_port_set_cb( pjmedia_port *port,
+ pj_size_t pos,
+ void *user_data,
+ pj_status_t (*cb)(pjmedia_port *port,
+ void *usr_data));
+
+
+/**
+ * @}
+ */
+
+
+PJ_END_DECL
+
+
+#endif /* __PJMEDIA_WAV_PORT_H__ */
diff --git a/pjmedia/include/pjmedia/wave.h b/pjmedia/include/pjmedia/wave.h
new file mode 100644
index 0000000..a1fec7c
--- /dev/null
+++ b/pjmedia/include/pjmedia/wave.h
@@ -0,0 +1,184 @@
+/* $Id: wave.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_WAVE_H__
+#define __PJMEDIA_WAVE_H__
+
+
+/**
+ * @file wave.h
+ * @brief WAVE file manipulation.
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMEDIA_FILE_FORMAT File Formats
+ * @brief Supported file formats
+ */
+
+
+/**
+ * @defgroup PJMEDIA_WAVE WAVE Header
+ * @ingroup PJMEDIA_FILE_FORMAT
+ * @brief Representation of RIFF/WAVE file format
+ * @{
+ *
+ * This the the low level representation of RIFF/WAVE file format. For
+ * higher abstraction, please see \ref PJMEDIA_FILE_PLAY and
+ * \ref PJMEDIA_FILE_REC.
+ */
+
+
+PJ_BEGIN_DECL
+
+/**
+ * Standard RIFF tag to identify RIFF file format in the WAVE header.
+ */
+#define PJMEDIA_RIFF_TAG ('F'<<24|'F'<<16|'I'<<8|'R')
+
+/**
+ * Standard WAVE tag to identify WAVE header.
+ */
+#define PJMEDIA_WAVE_TAG ('E'<<24|'V'<<16|'A'<<8|'W')
+
+/**
+ * Standard FMT tag to identify format chunks.
+ */
+#define PJMEDIA_FMT_TAG (' '<<24|'t'<<16|'m'<<8|'f')
+
+/**
+ * Standard DATA tag to identify data chunks.
+ */
+#define PJMEDIA_DATA_TAG ('a'<<24|'t'<<16|'a'<<8|'d')
+
+/**
+ * Standard FACT tag to identify fact chunks.
+ */
+#define PJMEDIA_FACT_TAG ('t'<<24|'c'<<16|'a'<<8|'f')
+
+
+/**
+ * Enumeration of format compression tag.
+ */
+typedef enum {
+ PJMEDIA_WAVE_FMT_TAG_PCM = 1,
+ PJMEDIA_WAVE_FMT_TAG_ALAW = 6,
+ PJMEDIA_WAVE_FMT_TAG_ULAW = 7
+} pjmedia_wave_fmt_tag;
+
+
+/**
+ * This file describes the simpler/canonical version of a WAVE file.
+ * It does not support the full RIFF format specification.
+ */
+#pragma pack(2)
+struct pjmedia_wave_hdr
+{
+ /** This structure describes RIFF WAVE file header */
+ struct {
+ pj_uint32_t riff; /**< "RIFF" ASCII tag. */
+ pj_uint32_t file_len; /**< File length minus 8 bytes */
+ pj_uint32_t wave; /**< "WAVE" ASCII tag. */
+ } riff_hdr;
+
+ /** This structure describes format chunks/header */
+ struct {
+ pj_uint32_t fmt; /**< "fmt " ASCII tag. */
+ pj_uint32_t len; /**< 16 for PCM. */
+ pj_uint16_t fmt_tag; /**< 1 for PCM */
+ pj_uint16_t nchan; /**< Number of channels. */
+ pj_uint32_t sample_rate; /**< Sampling rate. */
+ pj_uint32_t bytes_per_sec; /**< Average bytes per second. */
+ pj_uint16_t block_align; /**< nchannels * bits / 8 */
+ pj_uint16_t bits_per_sample; /**< Bits per sample. */
+ } fmt_hdr;
+
+ /** The data header preceeds the actual data in the file. */
+ struct {
+ pj_uint32_t data; /**< "data" ASCII tag. */
+ pj_uint32_t len; /**< Data length. */
+ } data_hdr;
+};
+#pragma pack()
+
+/**
+ * @see pjmedia_wave_hdr
+ */
+typedef struct pjmedia_wave_hdr pjmedia_wave_hdr;
+
+/**
+ * This structure describes generic RIFF subchunk header.
+ */
+typedef struct pjmedia_wave_subchunk
+{
+ pj_uint32_t id; /**< Subchunk ASCII tag. */
+ pj_uint32_t len; /**< Length following this field */
+} pjmedia_wave_subchunk;
+
+
+/**
+ * Normalize subchunk header from little endian (the representation of
+ * RIFF file) into host's endian.
+ */
+#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
+# define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch) \
+ do { \
+ (ch)->id = pj_swap32((ch)->id); \
+ (ch)->len = pj_swap32((ch)->len); \
+ } while (0)
+#else
+# define PJMEDIA_WAVE_NORMALIZE_SUBCHUNK(ch)
+#endif
+
+
+/**
+ * On big-endian hosts, this function swaps the byte order of the values
+ * in the WAVE header fields. On little-endian hosts, this function does
+ * nothing.
+ *
+ * Application SHOULD call this function after reading the WAVE header
+ * chunks from a file.
+ *
+ * @param hdr The WAVE header.
+ */
+PJ_DECL(void) pjmedia_wave_hdr_file_to_host( pjmedia_wave_hdr *hdr );
+
+
+/**
+ * On big-endian hosts, this function swaps the byte order of the values
+ * in the WAVE header fields. On little-endian hosts, this function does
+ * nothing.
+ *
+ * Application SHOULD call this function before writing the WAVE header
+ * to a file.
+ *
+ * @param hdr The WAVE header.
+ */
+PJ_DECL(void) pjmedia_wave_hdr_host_to_file( pjmedia_wave_hdr *hdr );
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+
+#endif /* __PJMEDIA_WAVE_H__ */
+
diff --git a/pjmedia/include/pjmedia/wsola.h b/pjmedia/include/pjmedia/wsola.h
new file mode 100644
index 0000000..8f76025
--- /dev/null
+++ b/pjmedia/include/pjmedia/wsola.h
@@ -0,0 +1,219 @@
+/* $Id: wsola.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_WSOLA_H__
+#define __PJMEDIA_WSOLA_H__
+
+/**
+ * @file wsola.h
+ * @brief Waveform Similarity Based Overlap-Add (WSOLA)
+ */
+#include <pjmedia/types.h>
+
+/**
+ * @defgroup PJMED_WSOLA Waveform Similarity Based Overlap-Add (WSOLA)
+ * @ingroup PJMEDIA_FRAME_OP
+ * @brief Time-scale modification to audio without affecting the pitch
+ * @{
+ *
+ * This section describes Waveform Similarity Based Overlap-Add (WSOLA)
+ * implementation in PJMEDIA. The WSOLA API here can be used both to
+ * compress (speed-up) and stretch (expand, slow down) audio playback
+ * without altering the pitch, or as a mean for performing packet loss
+ * concealment (WSOLA).
+ *
+ * The WSOLA implementation is used by \ref PJMED_DELAYBUF and \ref PJMED_PLC.
+ */
+
+PJ_BEGIN_DECL
+
+
+/**
+ * Opaque declaration for WSOLA structure.
+ */
+typedef struct pjmedia_wsola pjmedia_wsola;
+
+
+/**
+ * WSOLA options, can be combined with bitmask operation.
+ */
+enum pjmedia_wsola_option
+{
+ /**
+ * Disable Hanning window to conserve memory.
+ */
+ PJMEDIA_WSOLA_NO_HANNING = 1,
+
+ /**
+ * Specify that the WSOLA will not be used for PLC.
+ */
+ PJMEDIA_WSOLA_NO_PLC = 2,
+
+ /**
+ * Specify that the WSOLA will not be used to discard frames in
+ * non-contiguous buffer.
+ */
+ PJMEDIA_WSOLA_NO_DISCARD = 4,
+
+ /**
+ * Disable fade-in and fade-out feature in the transition between
+ * actual and synthetic frames in WSOLA. With fade feature enabled,
+ * WSOLA will only generate a limited number of synthetic frames
+ * (configurable with #pjmedia_wsola_set_max_expand()), fading out
+ * the volume on every more samples it generates, and when it reaches
+ * the limit it will only generate silence.
+ */
+ PJMEDIA_WSOLA_NO_FADING = 8
+};
+
+
+
+/**
+ * Create and initialize WSOLA.
+ *
+ * @param pool Pool to allocate memory for WSOLA.
+ * @param clock_rate Sampling rate of audio playback.
+ * @param samples_per_frame Number of samples per frame.
+ * @param channel_count Number of channels.
+ * @param options Option flags, bitmask combination of
+ * #pjmedia_wsola_option.
+ * @param p_wsola Pointer to receive WSOLA structure.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_create(pj_pool_t *pool,
+ unsigned clock_rate,
+ unsigned samples_per_frame,
+ unsigned channel_count,
+ unsigned options,
+ pjmedia_wsola **p_wsola);
+
+
+/**
+ * Specify maximum number of continuous synthetic frames that can be
+ * generated by WSOLA, in milliseconds. This option will only take
+ * effect if fading is not disabled via the option when the WSOLA
+ * session was created. Default value is PJMEDIA_WSOLA_MAX_EXPAND_MSEC
+ * (see also the documentation of PJMEDIA_WSOLA_MAX_EXPAND_MSEC for
+ * more information).
+ *
+ * @param wsola The WSOLA session
+ * @param msec The duration.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola,
+ unsigned msec);
+
+
+/**
+ * Destroy WSOLA.
+ *
+ * @param wsola WSOLA session.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_destroy(pjmedia_wsola *wsola);
+
+
+/**
+ * Reset the buffer contents of WSOLA.
+ *
+ * @param wsola WSOLA session.
+ * @param options Reset options, must be zero for now.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_reset(pjmedia_wsola *wsola,
+ unsigned options);
+
+
+/**
+ * Give one good frame to WSOLA to be kept as reference. Application
+ * must continuously give WSOLA good frames to keep its session up to
+ * date with current playback. Depending on the WSOLA implementation,
+ * this function may modify the content of the frame.
+ *
+ * @param wsola WSOLA session.
+ * @param frm The frame, which length must match the samples per
+ * frame setting of the WSOLA session.
+ * @param prev_lost If application previously generated a synthetic
+ * frame with #pjmedia_wsola_generate() before calling
+ * this function, specify whether that was because of
+ * packet lost. If so, set this parameter to PJ_TRUE
+ * to make WSOLA interpolate this frame with its buffer.
+ * Otherwise if this value is PJ_FALSE, WSOLA will
+ * just append this frame to the end of its buffer.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_save(pjmedia_wsola *wsola,
+ pj_int16_t frm[],
+ pj_bool_t prev_lost);
+
+/**
+ * Generate one synthetic frame from WSOLA.
+ *
+ * @param wsola WSOLA session.
+ * @param frm Buffer to receive the frame.
+ *
+ * @return PJ_SUCCESS normally.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_generate(pjmedia_wsola *wsola,
+ pj_int16_t frm[]);
+
+
+/**
+ * Compress or compact the specified buffer by removing some audio samples
+ * from the buffer, without altering the pitch. For this function to work,
+ * total length of the buffer must be more than twice \a erase_cnt.
+ *
+ * @param wsola WSOLA session.
+ * @param buf1 Pointer to buffer.
+ * @param buf1_cnt Number of samples in the buffer.
+ * @param buf2 Pointer to second buffer, if the buffer is not
+ * contiguous. Otherwise this parameter must be NULL.
+ * @param buf2_cnt Number of samples in the second buffer, if the buffer
+ * is not contiguous. Otherwise this parameter should be
+ * zero.
+ * @param erase_cnt On input, specify the number of samples to be erased.
+ * This function may erase more or less than the requested
+ * number, and the actual number of samples erased will be
+ * given on this argument upon returning from the function.
+ *
+ * @return PJ_SUCCESS if some samples have been erased, PJ_ETOOSMALL
+ * if buffer is too small to be reduced, PJ_EINVAL if any
+ * of the parameters are not valid.
+ */
+PJ_DECL(pj_status_t) pjmedia_wsola_discard(pjmedia_wsola *wsola,
+ pj_int16_t buf1[],
+ unsigned buf1_cnt,
+ pj_int16_t buf2[],
+ unsigned buf2_cnt,
+ unsigned *erase_cnt);
+
+
+PJ_END_DECL
+
+/**
+ * @}
+ */
+
+#endif /* __PJMEDIA_WSOLA_H__ */
+
diff --git a/pjmedia/include/pjmedia_audiodev.h b/pjmedia/include/pjmedia_audiodev.h
new file mode 100644
index 0000000..867a1b7
--- /dev/null
+++ b/pjmedia/include/pjmedia_audiodev.h
@@ -0,0 +1,33 @@
+/* $Id: pjmedia_audiodev.h 3553 2011-05-05 06:14:19Z nanang $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_AUDIODEV_H__
+#define __PJMEDIA_AUDIODEV_H__
+
+/**
+ * @file pjmedia_audiodev.h
+ * @brief PJMEDIA main header file.
+ */
+
+#include <pjmedia-audiodev/audiodev.h>
+#include <pjmedia-audiodev/audiodev_imp.h>
+#include <pjmedia-audiodev/audiotest.h>
+
+#endif /* __PJMEDIA_AUDIODEV_H__ */
+
diff --git a/pjmedia/include/pjmedia_videodev.h b/pjmedia/include/pjmedia_videodev.h
new file mode 100644
index 0000000..c3c9bb0
--- /dev/null
+++ b/pjmedia/include/pjmedia_videodev.h
@@ -0,0 +1,31 @@
+/* $Id: pjmedia_videodev.h 4016 2012-04-04 05:05:50Z bennylp $ */
+/*
+ * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PJMEDIA_VIDEODEV_H__
+#define __PJMEDIA_VIDEODEV_H__
+
+/**
+ * @file pjmedia_videodev.h
+ * @brief PJMEDIA main header file.
+ */
+
+#include <pjmedia-videodev/videodev.h>
+#include <pjmedia-videodev/videodev_imp.h>
+#include <pjmedia-videodev/avi_dev.h>
+
+#endif /* __PJMEDIA_VIDEODEV_H__ */