diff options
Diffstat (limited to 'pjmedia/include/pjmedia')
-rw-r--r-- | pjmedia/include/pjmedia/alaw_ulaw.h | 16 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/codec.h | 3 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/conference.h | 14 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/config.h | 92 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/endpoint.h | 1 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/port.h | 30 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/sound.h | 13 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/sound_port.h | 40 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/stream.h | 1 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/symbian_sound_aps.h | 15 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/types.h | 306 |
11 files changed, 403 insertions, 128 deletions
diff --git a/pjmedia/include/pjmedia/alaw_ulaw.h b/pjmedia/include/pjmedia/alaw_ulaw.h index 3b97ad3d..a6aae811 100644 --- a/pjmedia/include/pjmedia/alaw_ulaw.h +++ b/pjmedia/include/pjmedia/alaw_ulaw.h @@ -144,12 +144,12 @@ PJ_DECL(unsigned char) pjmedia_ulaw2alaw(unsigned char uval); * * @param dst Destination buffer for 8-bit U-Law data. * @param src Source, 16-bit linear PCM data. - * @param len Number of samples. + * @param count Number of samples. */ PJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src, - pj_size_t len) + pj_size_t count) { - const pj_int16_t *end = src + len; + const pj_int16_t *end = src + count; while (src < end) { *dst++ = pjmedia_linear2ulaw(*src++); @@ -161,12 +161,12 @@ PJ_INLINE(void) pjmedia_ulaw_encode(pj_uint8_t *dst, const pj_int16_t *src, * * @param dst Destination buffer for 8-bit A-Law data. * @param src Source, 16-bit linear PCM data. - * @param len Number of samples. + * @param count Number of samples. */ PJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src, - pj_size_t len) + pj_size_t count) { - const pj_int16_t *end = src + len; + const pj_int16_t *end = src + count; while (src < end) { *dst++ = pjmedia_linear2alaw(*src++); @@ -178,7 +178,7 @@ PJ_INLINE(void) pjmedia_alaw_encode(pj_uint8_t *dst, const pj_int16_t *src, * * @param dst Destination buffer for 16-bit PCM data. * @param src Source, 8-bit U-Law data. - * @param len Number of samples. + * @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) @@ -195,7 +195,7 @@ PJ_INLINE(void) pjmedia_ulaw_decode(pj_int16_t *dst, const pj_uint8_t *src, * * @param dst Destination buffer for 16-bit PCM data. * @param src Source, 8-bit A-Law data. - * @param len Number of samples. + * @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) diff --git a/pjmedia/include/pjmedia/codec.h b/pjmedia/include/pjmedia/codec.h index 199e3989..dcaae626 100644 --- a/pjmedia/include/pjmedia/codec.h +++ b/pjmedia/include/pjmedia/codec.h @@ -275,6 +275,9 @@ typedef struct pjmedia_codec_param 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; /** diff --git a/pjmedia/include/pjmedia/conference.h b/pjmedia/include/pjmedia/conference.h index bc14c543..584e56ce 100644 --- a/pjmedia/include/pjmedia/conference.h +++ b/pjmedia/include/pjmedia/conference.h @@ -43,6 +43,18 @@ PJ_BEGIN_DECL +/** + * The conference bridge signature in pjmedia_port_info. + */ +#define PJMEDIA_CONF_BRIDGE_SIGNATURE \ + PJMEDIA_PORT_SIGNATURE('C', 'O', 'N', 'F') + +/** + * The audio switchboard signature in pjmedia_port_info. + */ +#define PJMEDIA_CONF_SWITCH_SIGNATURE \ + PJMEDIA_PORT_SIGNATURE('A', 'S', 'W', 'I') + /** * Opaque type for conference bridge. @@ -56,10 +68,12 @@ 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 */ diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h index 735192ef..9a3eea9b 100644 --- a/pjmedia/include/pjmedia/config.h +++ b/pjmedia/include/pjmedia/config.h @@ -44,79 +44,69 @@ # 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. */ -/** Constant for NULL sound backend. */ -#define PJMEDIA_SOUND_NULL_SOUND 0 - -/** Constant for PortAudio sound backend. */ -#define PJMEDIA_SOUND_PORTAUDIO_SOUND 1 - -/** Constant for Win32 DirectSound sound backend. */ -#define PJMEDIA_SOUND_WIN32_DIRECT_SOUND 2 - -/** Constant for Win32 MME sound backend. */ -#define PJMEDIA_SOUND_WIN32_MME_SOUND 3 - -/** When this is set, pjmedia will not provide any sound device backend. - * Application will have to provide its own sound device backend - * and link the application with it. +/** + * This macro has been deprecated in releasee 1.1. Please see + * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information. */ -#define PJMEDIA_SOUND_EXTERNAL 255 - +#if defined(PJMEDIA_SOUND_IMPLEMENTATION) +# error PJMEDIA_SOUND_IMPLEMENTATION has been deprecated +#endif /** - * Unless specified otherwise, sound device uses PortAudio implementation - * by default. + * This macro has been deprecated in releasee 1.1. Please see + * http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more information. */ -#ifndef PJMEDIA_SOUND_IMPLEMENTATION -# if defined(PJ_WIN32) && PJ_WIN32!=0 -/*# define PJMEDIA_SOUND_IMPLEMENTATION PJMEDIA_SOUND_WIN32_DIRECT_SOUND*/ -/*# define PJMEDIA_SOUND_IMPLEMENTATION PJMEDIA_SOUND_WIN32_MME_SOUND*/ -# define PJMEDIA_SOUND_IMPLEMENTATION PJMEDIA_SOUND_PORTAUDIO_SOUND -# else -# define PJMEDIA_SOUND_IMPLEMENTATION PJMEDIA_SOUND_PORTAUDIO_SOUND -# endif +#if defined(PJMEDIA_PREFER_DIRECT_SOUND) +# error PJMEDIA_PREFER_DIRECT_SOUND has been deprecated #endif - /** - * Specify whether we prefer to use DirectSound on Windows. + * 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. * - * Default: 0 + * Please see http://trac.pjsip.org/repos/wiki/Audio_Dev_API for more + * info. */ -#ifndef PJMEDIA_PREFER_DIRECT_SOUND -# define PJMEDIA_PREFER_DIRECT_SOUND 0 +#ifndef PJMEDIA_HAS_LEGACY_SOUND_API +# define PJMEDIA_HAS_LEGACY_SOUND_API 1 #endif - /** - * Specify sound device latency default, in milisecond. + * Specify default sound device latency, in milisecond. */ #ifndef PJMEDIA_SND_DEFAULT_REC_LATENCY # define PJMEDIA_SND_DEFAULT_REC_LATENCY 100 #endif -#ifndef PJMEDIA_SND_DEFAULT_PLAY_LATENCY -# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 100 -#endif - - /** - * Specify whether delay buffer is used for sound device. - * When delay buffer is enabled, the sound device callback - * will be called one after another evenly. - * The delay buffer also performs the best delay calculation - * for the sound device, and will try to limit the delay caused - * by uneven callback calls to this delay. - * - * When this setting is enabled, the PJMEDIA_SOUND_BUFFER_COUNT - * macro will specify the maximum size of the delay buffer. + * Specify default sound device latency, in milisecond. */ -#ifndef PJMEDIA_SOUND_USE_DELAYBUF -# define PJMEDIA_SOUND_USE_DELAYBUF 0 +#ifndef PJMEDIA_SND_DEFAULT_PLAY_LATENCY +# define PJMEDIA_SND_DEFAULT_PLAY_LATENCY 100 #endif @@ -285,7 +275,7 @@ * Default file player/writer buffer size. */ #ifndef PJMEDIA_FILE_PORT_BUFSIZE -# define PJMEDIA_FILE_PORT_BUFSIZE 4000 +# define PJMEDIA_FILE_PORT_BUFSIZE 4000 #endif diff --git a/pjmedia/include/pjmedia/endpoint.h b/pjmedia/include/pjmedia/endpoint.h index 0d8dd39d..2cc386f5 100644 --- a/pjmedia/include/pjmedia/endpoint.h +++ b/pjmedia/include/pjmedia/endpoint.h @@ -37,7 +37,6 @@ * to create a media session (#pjmedia_session_create()). */ -#include <pjmedia/sound.h> #include <pjmedia/codec.h> #include <pjmedia/sdp.h> diff --git a/pjmedia/include/pjmedia/port.h b/pjmedia/include/pjmedia/port.h index 9d7c86c6..447c429d 100644 --- a/pjmedia/include/pjmedia/port.h +++ b/pjmedia/include/pjmedia/port.h @@ -25,6 +25,7 @@ * @brief Port interface declaration */ #include <pjmedia/types.h> +#include <pj/assert.h> #include <pj/os.h> @@ -211,6 +212,7 @@ typedef struct pjmedia_port_info pj_bool_t has_info; /**< Has info? */ pj_bool_t need_info; /**< Need info on connect? */ unsigned pt; /**< Payload type (can be dynamic). */ + pjmedia_format format; /**< Format. */ pj_str_t encoding_name; /**< Encoding name. */ unsigned clock_rate; /**< Sampling rate. */ unsigned channel_count; /**< Number of channels. */ @@ -220,34 +222,6 @@ typedef struct pjmedia_port_info } pjmedia_port_info; -/** - * 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; - - -/** - * 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; - - /** * Port interface. */ diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h index 962bfe96..dca9905b 100644 --- a/pjmedia/include/pjmedia/sound.h +++ b/pjmedia/include/pjmedia/sound.h @@ -23,10 +23,11 @@ /** * @file sound.h - * @brief Sound player and recorder device framework. + * @brief Legacy sound device API */ +#include <pjmedia-audiodev/audiodev.h> #include <pjmedia/types.h> -#include <pj/pool.h> + PJ_BEGIN_DECL @@ -36,6 +37,11 @@ PJ_BEGIN_DECL * @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 @@ -61,7 +67,7 @@ PJ_BEGIN_DECL * frames from/to the sound device. */ -/** Opaque data type for audio stream. */ +/** Opaque declaration for pjmedia_snd_stream. */ typedef struct pjmedia_snd_stream pjmedia_snd_stream; /** @@ -92,7 +98,6 @@ typedef struct pjmedia_snd_stream_info 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 diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h index a41357c8..7293a4d7 100644 --- a/pjmedia/include/pjmedia/sound_port.h +++ b/pjmedia/include/pjmedia/sound_port.h @@ -24,7 +24,7 @@ * @file sound_port.h * @brief Media port connection abstraction to sound device. */ -#include <pjmedia/sound.h> +#include <pjmedia-audiodev/audiodev.h> #include <pjmedia/port.h> PJ_BEGIN_DECL @@ -159,7 +159,22 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_create_player(pj_pool_t *pool, 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 device settings. + * @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_aud_param *prm, + pjmedia_snd_port **p_port); + /** * Destroy sound device port. @@ -179,19 +194,23 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port); * * @return The sound stream instance. */ -PJ_DECL(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream( +PJ_DECL(pjmedia_aud_stream*) pjmedia_snd_port_get_snd_stream( pjmedia_snd_port *snd_port); /** - * Configure the echo cancellation tail length. By default, echo canceller - * is enabled in the sound device with the default tail length. After the - * sound port is created, application can query the current echo canceller - * tail length by calling #pjmedia_snd_port_get_ec_tail. + * 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. * - * Note that you should only change the EC settings when the sound port - * is not connected to any downstream ports, otherwise race condition may - * occur. + * 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. @@ -199,6 +218,7 @@ PJ_DECL(pjmedia_snd_stream*) pjmedia_snd_port_get_snd_stream( * 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. */ diff --git a/pjmedia/include/pjmedia/stream.h b/pjmedia/include/pjmedia/stream.h index cf5ef47f..0227f645 100644 --- a/pjmedia/include/pjmedia/stream.h +++ b/pjmedia/include/pjmedia/stream.h @@ -26,7 +26,6 @@ * @brief Media Stream. */ -#include <pjmedia/sound.h> #include <pjmedia/codec.h> #include <pjmedia/endpoint.h> #include <pjmedia/port.h> diff --git a/pjmedia/include/pjmedia/symbian_sound_aps.h b/pjmedia/include/pjmedia/symbian_sound_aps.h index 3208b416..bd9e0439 100644 --- a/pjmedia/include/pjmedia/symbian_sound_aps.h +++ b/pjmedia/include/pjmedia/symbian_sound_aps.h @@ -31,21 +31,16 @@ PJ_BEGIN_DECL /** - * Activate/deactivate loudspeaker, when loudspeaker is inactive, audio - * will be routed to earpiece. + * Set audio routing for APS sound device. * * @param stream The sound device stream, the stream should be started - * before calling this function. This param can be NULL - * to set the behaviour of next opened stream. - * @param active Specify PJ_TRUE to activate loudspeaker, and PJ_FALSE - * otherwise. + * before calling this function. + * @param route Audio routing to be set. * * @return PJ_SUCCESS on success. */ -PJ_DECL(pj_status_t) pjmedia_snd_aps_activate_loudspeaker( - pjmedia_snd_stream *stream, - pj_bool_t active); - +PJ_DECL(pj_status_t) pjmedia_snd_aps_set_route( pjmedia_snd_stream *stream, + pjmedia_snd_route route); PJ_END_DECL diff --git a/pjmedia/include/pjmedia/types.h b/pjmedia/include/pjmedia/types.h index e456e34e..a4c71743 100644 --- a/pjmedia/include/pjmedia/types.h +++ b/pjmedia/include/pjmedia/types.h @@ -47,8 +47,8 @@ * @{ */ -/** - * Top most media type. +/** + * Top most media type. */ typedef enum pjmedia_type { @@ -61,7 +61,7 @@ typedef enum pjmedia_type /** The media is video. */ PJMEDIA_TYPE_VIDEO = 2, - /** Unknown media type, in this case the name will be specified in + /** Unknown media type, in this case the name will be specified in * encoding_name. */ PJMEDIA_TYPE_UNKNOWN = 3, @@ -72,8 +72,8 @@ typedef enum pjmedia_type } pjmedia_type; -/** - * Media transport protocol. +/** + * Media transport protocol. */ typedef enum pjmedia_tp_proto { @@ -92,8 +92,8 @@ typedef enum pjmedia_tp_proto } pjmedia_tp_proto; -/** - * Media direction. +/** + * Media direction. */ typedef enum pjmedia_dir { @@ -138,8 +138,8 @@ typedef enum pjmedia_dir (a<<24 | b<<16 | c<<8 | d) -/** - * Opague declaration of media endpoint. +/** + * Opaque declaration of media endpoint. */ typedef struct pjmedia_endpt pjmedia_endpt; @@ -150,7 +150,7 @@ typedef struct pjmedia_endpt pjmedia_endpt; typedef struct pjmedia_stream pjmedia_stream; -/** +/** * Media socket info is used to describe the underlying sockets * to be used as media transport. */ @@ -180,8 +180,84 @@ typedef struct pjmedia_sock_info /** + * Macro for packing format. + */ +#define PJMEDIA_FORMAT_PACK(C1, C2, C3, C4) ( C4<<24 | C3<<16 | C2<<8 | C1 ) + +/** + * This enumeration describes format ID. + */ +typedef enum pjmedia_format_id +{ + /** + * 16bit linear + */ + 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') + +} pjmedia_format_id; + + +/** + * Media format information. + */ +typedef struct pjmedia_format +{ + /** Format ID */ + pjmedia_format_id id; + + /** Bitrate. */ + pj_uint32_t bitrate; + + /** Flag to indicate whether VAD is enabled */ + pj_bool_t vad; + +} pjmedia_format; + + + +/** * This is a general purpose function set PCM samples to zero. - * Since this function is needed by many parts of the library, + * 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. * @@ -205,7 +281,7 @@ PJ_INLINE(void) pjmedia_zero_samples(pj_int16_t *samples, unsigned count) /** * 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, + * 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. */ @@ -220,7 +296,7 @@ PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src, #else unsigned i; count >>= 1; - for (i=0; i<count; ++i) + for (i=0; i<count; ++i) ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i]; #endif } @@ -228,7 +304,7 @@ PJ_INLINE(void) pjmedia_copy_samples(pj_int16_t *dst, const pj_int16_t *src, /** * 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, + * 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. */ @@ -243,11 +319,211 @@ PJ_INLINE(void) pjmedia_move_samples(pj_int16_t *dst, const pj_int16_t *src, #else unsigned i; count >>= 1; - for (i=0; i<count; ++i) + for (i=0; i<count; ++i) ((pj_int32_t*)dst)[i] = ((pj_int32_t*)src)[i]; #endif } +/** + * 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; + + +/** + * 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() + + +/** + * Append one subframe to #pjmedia_frame_ext. + * + * @param frm The #pjmedia_frame_ext. + * @param src Subframe data. + * @param bitlen Lenght 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 maxsize 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; +} + + /** * @} */ |