diff options
author | David M. Lee <dlee@digium.com> | 2013-01-07 14:24:28 -0600 |
---|---|---|
committer | David M. Lee <dlee@digium.com> | 2013-01-07 14:24:28 -0600 |
commit | f3ab456a17af1c89a6e3be4d20c5944853df1cb0 (patch) | |
tree | d00e1a332cd038a6d906a1ea0ac91e1a4458e617 /pjmedia/include |
Import pjproject-2.0.1
Diffstat (limited to 'pjmedia/include')
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, ¶m); + \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(¶m, &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(.., ¶m); + ... + // 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(.., ¶m); + \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(.., ¶m); + ... + // 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(.., ¶m); + \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(.., ¶m); + ... + // 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(.., ¶m); + \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(.., ¶m); + ... + // 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(.., ¶m); + \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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + 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, ®1, ®1cnt, + ®2, ®2cnt); + + /* 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 + ¶m); + + // 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, ¶m ); + + \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__ */ |