diff options
Diffstat (limited to 'include/asterisk')
27 files changed, 1351 insertions, 829 deletions
diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h index 67d17382b..01a8352fc 100644 --- a/include/asterisk/_private.h +++ b/include/asterisk/_private.h @@ -121,16 +121,6 @@ int ast_xmldoc_load_documentation(void); */ int ast_plc_reload(void); -/*! - * \brief Init the ast_format attribute interface register container. - */ -int ast_format_attr_init(void); - -/*! - * \brief Init the Asterisk global format list after all format attribute modules have been loaded - */ -int ast_format_list_init(void); - /*! \brief initializes the rtp engine arrays */ int ast_rtp_engine_init(void); diff --git a/include/asterisk/abstract_jb.h b/include/asterisk/abstract_jb.h index 6a4d0610d..8a5e3d27f 100644 --- a/include/asterisk/abstract_jb.h +++ b/include/asterisk/abstract_jb.h @@ -145,7 +145,7 @@ struct ast_jb /*! \brief The time the next frame should be played. */ long next; /*! \brief Voice format of the last frame in. */ - struct ast_format last_format; + struct ast_format *last_format; /*! \brief File for frame timestamp tracing. */ FILE *logfile; /*! \brief Jitterbuffer internal state flags. */ diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h index 6b0716092..375b2dd9d 100644 --- a/include/asterisk/audiohook.h +++ b/include/asterisk/audiohook.h @@ -109,7 +109,7 @@ struct ast_audiohook { struct ast_slinfactory write_factory; /*!< Factory where frames written to the channel will go through */ struct timeval read_time; /*!< Last time read factory was fed */ struct timeval write_time; /*!< Last time write factory was fed */ - struct ast_format format; /*!< Format translation path is setup as */ + struct ast_format *format; /*!< Format translation path is setup as */ struct ast_trans_pvt *trans_pvt; /*!< Translation path for reading frames */ ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */ struct ast_audiohook_options options; /*!< Applicable options */ diff --git a/include/asterisk/bridge_channel.h b/include/asterisk/bridge_channel.h index ae8369d15..387c048f8 100644 --- a/include/asterisk/bridge_channel.h +++ b/include/asterisk/bridge_channel.h @@ -133,9 +133,9 @@ struct ast_bridge_channel { * optimizing based upon talk detection. */ struct ast_bridge_tech_optimizations tech_args; /*! Copy of read format used by chan before join */ - struct ast_format read_format; + struct ast_format *read_format; /*! Copy of write format used by chan before join */ - struct ast_format write_format; + struct ast_format *write_format; /*! Call ID associated with bridge channel */ struct ast_callid *callid; /*! A clone of the roles living on chan when the bridge channel joins the bridge. This may require some opacification */ diff --git a/include/asterisk/callerid.h b/include/asterisk/callerid.h index 4f32dbf66..f7d7719d2 100644 --- a/include/asterisk/callerid.h +++ b/include/asterisk/callerid.h @@ -75,8 +75,8 @@ /*! MWI MDMF format -- generate name, callerid, date and MWI fields */ #define CID_MWI_TYPE_MDMF_FULL 0x02 -#define AST_LIN2X(a) ((codec->id == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a))) -#define AST_XLAW(a) ((codec->id == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a))) +#define AST_LIN2X(a) ((ast_format_cmp(codec, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) ? (AST_LIN2A(a)) : (AST_LIN2MU(a))) +#define AST_XLAW(a) ((ast_format_cmp(codec, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) ? (AST_ALAW(a)) : (AST_MULAW(a))) struct callerid_state; diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index dec19cba0..d118bc81f 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -1883,14 +1883,6 @@ int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap int ast_set_read_format(struct ast_channel *chan, struct ast_format *format); /*! - * \brief Sets read format on channel chan by id - * \param chan channel to change - * \param id format id to set for reading, only used for formats without attributes - * \return Returns 0 on success, -1 on failure - */ -int ast_set_read_format_by_id(struct ast_channel *chan, enum ast_format_id id); - -/*! * \brief Sets write format on channel chan * Set write format for channel to whichever component of "format" is best. * \param chan channel to change @@ -1908,14 +1900,6 @@ int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_ca int ast_set_write_format(struct ast_channel *chan, struct ast_format *format); /*! - * \brief Sets write format on channel chan - * \param chan channel to change - * \param id format id to set for writing, only used for formats without attributes - * \return Returns 0 on success, -1 on failure - */ -int ast_set_write_format_by_id(struct ast_channel *chan, enum ast_format_id id); - -/*! * \brief Sends text to a channel * * \param chan channel to act upon @@ -2103,17 +2087,6 @@ char *ast_transfercapability2str(int transfercapability) attribute_const; int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block); /*! - * \brief Pick the best codec - * - * \param cap capabilities to pick best codec out of - * \param result stucture to store the best codec in. - * \retval on success, pointer to result structure - * \retval on failure, NULL - */ -struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format *result); - - -/*! * \brief Checks the value of an option * * Query the value of an option @@ -4008,6 +3981,13 @@ struct ast_format *ast_channel_rawwriteformat(struct ast_channel *chan); struct ast_format *ast_channel_readformat(struct ast_channel *chan); struct ast_format *ast_channel_writeformat(struct ast_channel *chan); +/* Format setters - all of these functions will increment the reference count of the format passed in */ +void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format); +void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format); +void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format); +void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format); +void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format); + /* Other struct getters */ struct ast_frame *ast_channel_dtmff(struct ast_channel *chan); struct ast_jb *ast_channel_jb(struct ast_channel *chan); diff --git a/include/asterisk/codec.h b/include/asterisk/codec.h new file mode 100644 index 000000000..28befec50 --- /dev/null +++ b/include/asterisk/codec.h @@ -0,0 +1,186 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2014, Digium, Inc. + * + * Joshua Colp <jcolp@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Codec API + * + * \author Joshua Colp <jcolp@digium.com> + */ + +#ifndef _AST_CODEC_H_ +#define _AST_CODEC_H_ + +/*! \brief Types of media */ +enum ast_media_type { + AST_MEDIA_TYPE_UNKNOWN = 0, + AST_MEDIA_TYPE_AUDIO, + AST_MEDIA_TYPE_VIDEO, + AST_MEDIA_TYPE_IMAGE, + AST_MEDIA_TYPE_TEXT, +}; + +struct ast_module; + +/*! \brief Represents a media codec within Asterisk. */ +struct ast_codec { + /*! \brief Internal unique identifier for this codec, set at registration time (starts at 1) */ + unsigned int id; + /*! \brief Name for this codec */ + const char *name; + /*! \brief Brief description */ + const char *description; + /*! \brief Type of media this codec contains */ + enum ast_media_type type; + /*! \brief Sample rate (number of samples carried in a second) */ + unsigned int sample_rate; + /*! \brief Minimum length of media that can be carried (in milliseconds) in a frame */ + unsigned int minimum_ms; + /*! \brief Maximum length of media that can be carried (in milliseconds) in a frame */ + unsigned int maximum_ms; + /*! \brief Default length of media carried (in milliseconds) in a frame */ + unsigned int default_ms; + /*! \brief Length in bytes of the data payload of a minimum_ms frame */ + unsigned int minimum_bytes; + /*! + * \brief Retrieve the number of samples in a frame + * + * \param frame The frame to examine + * + * \return the number of samples + */ + int (*samples_count)(struct ast_frame *frame); + /*! + * \brief Retrieve the length of media from number of samples + * + * \param samples The number of samples + * + * \return The length of media in milliseconds + */ + int (*get_length)(unsigned int samples); + /*! \brief Whether the media can be smoothed or not */ + unsigned int smooth; + /*! \brief The module that registered this codec */ + struct ast_module *mod; +}; + +/*! + * \brief Initialize codec support within the core. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_codec_init(void); + +/*! + * \brief Initialize built-in codecs within the core. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_codec_builtin_init(void); + +/*! + * \brief This function is used to register a codec with the Asterisk core. Registering + * allows it to be passed through in frames and configured in channel drivers. + * + * \param codec to register + * \param mod the module this codec is provided by + * + * \retval 0 success + * \retval -1 failure + */ +int __ast_codec_register(struct ast_codec *codec, struct ast_module *mod); + +/*! + * \brief This function is used to register a codec with the Asterisk core. Registering + * allows it to be passed through in frames and configured in channel drivers. + * + * \param codec to register + * + * \retval 0 success + * \retval -1 failure + */ +#define ast_codec_register(codec) __ast_codec_register(codec, ast_module_info->self) + +/*! + * \brief Retrieve a codec given a name, type, and sample rate + * + * \param name The name of the codec + * \param type The type of the codec + * \param sample_rate Optional sample rate, may not be applicable for some types + * + * \retval non-NULL success + * \retval NULL failure + * + * \note The returned codec is reference counted and ao2_ref or ao2_cleanup + * must be used to release the reference. + */ +struct ast_codec *ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate); + +/*! + * \brief Retrieve a codec given the unique identifier + * + * \param id The unique identifier + * + * \retval non-NULL success + * \retval NULL failure + * + * \note Identifiers start at 1 so if iterating don't start at 0. + * + * \note The returned codec is reference counted and ao2_ref or ao2_cleanup + * must be used to release the reference. + */ +struct ast_codec *ast_codec_get_by_id(int id); + +/*! + * \brief Retrieve the current maximum identifier for codec iteration + * + * \return Maximum codec identifier + */ +int ast_codec_get_max(void); + +/*! + * \brief Conversion function to take a media type and turn it into a string + * + * \param type The media type + * + * \retval string representation of the media type + */ +const char *ast_codec_media_type2str(enum ast_media_type type); + +/*! + * \brief Get the number of samples contained within a frame + * + * \param frame The frame itself + * + * \retval number of samples in the frame + */ +unsigned int ast_codec_samples_count(struct ast_frame *frame); + +/*! + * \brief Get the length of media (in milliseconds) given a number of samples + * + * \param codec The codec itself + * \param samples The number of samples + * + * \retval length of media (in milliseconds) + */ +unsigned int ast_codec_determine_length(const struct ast_codec *codec, unsigned int samples); + +#endif /* _AST_CODEC_H */ diff --git a/include/asterisk/config_options.h b/include/asterisk/config_options.h index 11a8c5bf9..30c042176 100644 --- a/include/asterisk/config_options.h +++ b/include/asterisk/config_options.h @@ -317,21 +317,20 @@ enum aco_option_type { */ OPT_CHAR_ARRAY_T, - /*! \brief Type for default option handler for codec preferences/capabilities + /*! \brief Type for default option handler for format capabilities * \note aco_option_register flags: * non-zero : This is an "allow" style option * 0 : This is a "disallow" style option * aco_option_register varargs: - * FLDSET macro with fields representing a struct ast_codec_pref and a struct ast_format_cap * + * FLDSET macro with field representing a struct ast_format_cap * * * Example: * {code} * struct test_item { - * struct ast_codec_pref pref; * struct ast_format cap *cap; * }; - * aco_option_register(&cfg_info, "allow", ACO_EXACT, my_types, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct test_item, pref, cap)); - * aco_option_register(&cfg_info, "disallow", ACO_EXACT, my_types, "all", OPT_CODEC_T, 0, FLDSET(struct test_item, pref, cap)); + * aco_option_register(&cfg_info, "allow", ACO_EXACT, my_types, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct test_item, cap)); + * aco_option_register(&cfg_info, "disallow", ACO_EXACT, my_types, "all", OPT_CODEC_T, 0, FLDSET(struct test_item, cap)); * {endcode} */ OPT_CODEC_T, diff --git a/include/asterisk/data.h b/include/asterisk/data.h index e3253377e..3676b8df5 100644 --- a/include/asterisk/data.h +++ b/include/asterisk/data.h @@ -26,6 +26,7 @@ #define ASTERISK_DATA_H #include "asterisk/frame.h" +#include "asterisk/format_cap.h" /*! * \page AstDataRetrieval The Asterisk DATA retrieval API. diff --git a/include/asterisk/file.h b/include/asterisk/file.h index 372c0f7ed..3d8d2c97c 100644 --- a/include/asterisk/file.h +++ b/include/asterisk/file.h @@ -385,7 +385,7 @@ char *ast_format_str_reduce(char *fmts); * \retval NULL if not found * \retval A pointer to the ast_format associated with this file extension */ -const struct ast_format *ast_get_format_for_file_ext(const char *file_ext); +struct ast_format *ast_get_format_for_file_ext(const char *file_ext); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/include/asterisk/format.h b/include/asterisk/format.h index 885c62b2d..32f9f2b40 100644 --- a/include/asterisk/format.h +++ b/include/asterisk/format.h @@ -1,9 +1,9 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright (C) 2010, Digium, Inc. + * Copyright (C) 2014, Digium, Inc. * - * David Vossel <dvossel@digium.com> + * Joshua Colp <jcolp@digium.com> * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact @@ -18,464 +18,354 @@ /*! * \file - * \brief Format API + * \brief Media Format API * - * \author David Vossel <dvossel@digium.com> + * \author Joshua Colp <jcolp@digium.com> */ +#include "asterisk/codec.h" + #ifndef _AST_FORMAT_H_ #define _AST_FORMAT_H_ -#include "asterisk/astobj2.h" -#include "asterisk/silk.h" -#include "asterisk/celt.h" -#include "asterisk/opus.h" -#define AST_FORMAT_ATTR_SIZE 64 -#define AST_FORMAT_INC 100000 - -/*! This is the value that ends a var list of format attribute - * key value pairs. */ -#define AST_FORMAT_ATTR_END -1 - -/* \brief Format Categories*/ -enum ast_format_type { - AST_FORMAT_TYPE_AUDIO = 1 * AST_FORMAT_INC, - AST_FORMAT_TYPE_VIDEO = 2 * AST_FORMAT_INC, - AST_FORMAT_TYPE_IMAGE = 3 * AST_FORMAT_INC, - AST_FORMAT_TYPE_TEXT = 4 * AST_FORMAT_INC, -}; - -enum ast_format_id { - /*! G.723.1 compression */ - AST_FORMAT_G723_1 = 1 + AST_FORMAT_TYPE_AUDIO, - /*! GSM compression */ - AST_FORMAT_GSM = 2 + AST_FORMAT_TYPE_AUDIO, - /*! Raw mu-law data (G.711) */ - AST_FORMAT_ULAW = 3 + AST_FORMAT_TYPE_AUDIO, - /*! Raw A-law data (G.711) */ - AST_FORMAT_ALAW = 4 + AST_FORMAT_TYPE_AUDIO, - /*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */ - AST_FORMAT_G726_AAL2 = 5 + AST_FORMAT_TYPE_AUDIO, - /*! ADPCM (IMA) */ - AST_FORMAT_ADPCM = 6 + AST_FORMAT_TYPE_AUDIO, - /*! LPC10, 180 samples/frame */ - AST_FORMAT_LPC10 = 7 + AST_FORMAT_TYPE_AUDIO, - /*! G.729A audio */ - AST_FORMAT_G729A = 8 + AST_FORMAT_TYPE_AUDIO, - /*! SpeeX Free Compression */ - AST_FORMAT_SPEEX = 9 + AST_FORMAT_TYPE_AUDIO, - /*! iLBC Free Compression */ - AST_FORMAT_ILBC = 10 + AST_FORMAT_TYPE_AUDIO, - /*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */ - AST_FORMAT_G726 = 11 + AST_FORMAT_TYPE_AUDIO, - /*! G.722 */ - AST_FORMAT_G722 = 12 + AST_FORMAT_TYPE_AUDIO, - /*! G.722.1 (also known as Siren7, 32kbps assumed) */ - AST_FORMAT_SIREN7 = 13 + AST_FORMAT_TYPE_AUDIO, - /*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */ - AST_FORMAT_SIREN14 = 14 + AST_FORMAT_TYPE_AUDIO, - /*! G.719 (64 kbps assumed) */ - AST_FORMAT_G719 = 15 + AST_FORMAT_TYPE_AUDIO, - /*! SpeeX Wideband (16kHz) Free Compression */ - AST_FORMAT_SPEEX16 = 16 + AST_FORMAT_TYPE_AUDIO, - /*! Raw mu-law data (G.711) */ - AST_FORMAT_TESTLAW = 17 + AST_FORMAT_TYPE_AUDIO, - /*! SILK format */ - AST_FORMAT_SILK = 18 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (8000 Hz) PCM */ - AST_FORMAT_SLINEAR = 19 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (12000 Hz) PCM */ - AST_FORMAT_SLINEAR12 = 20 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (16000 Hz) PCM */ - AST_FORMAT_SLINEAR16 = 21 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (24000 Hz) PCM */ - AST_FORMAT_SLINEAR24 = 22 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (32000 Hz) PCM */ - AST_FORMAT_SLINEAR32 = 23 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (44100 Hz) PCM just because we can. */ - AST_FORMAT_SLINEAR44 = 24 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (48000 Hz) PCM */ - AST_FORMAT_SLINEAR48 = 25 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (96000 Hz) PCM */ - AST_FORMAT_SLINEAR96 = 26 + AST_FORMAT_TYPE_AUDIO, - /*! Raw 16-bit Signed Linear (192000 Hz) PCM. maybe we're taking this too far. */ - AST_FORMAT_SLINEAR192 = 27 + AST_FORMAT_TYPE_AUDIO, - AST_FORMAT_SPEEX32 = 28 + AST_FORMAT_TYPE_AUDIO, - AST_FORMAT_CELT = 29 + AST_FORMAT_TYPE_AUDIO, - /*! Opus */ - AST_FORMAT_OPUS = 30 + AST_FORMAT_TYPE_AUDIO, - - /*! H.261 Video */ - AST_FORMAT_H261 = 1 + AST_FORMAT_TYPE_VIDEO, - /*! H.263 Video */ - AST_FORMAT_H263 = 2 + AST_FORMAT_TYPE_VIDEO, - /*! H.263+ Video */ - AST_FORMAT_H263_PLUS = 3 + AST_FORMAT_TYPE_VIDEO, - /*! H.264 Video */ - AST_FORMAT_H264 = 4 + AST_FORMAT_TYPE_VIDEO, - /*! MPEG4 Video */ - AST_FORMAT_MP4_VIDEO = 5 + AST_FORMAT_TYPE_VIDEO, - /*! VP8 */ - AST_FORMAT_VP8 = 6 + AST_FORMAT_TYPE_VIDEO, - - /*! JPEG Images */ - AST_FORMAT_JPEG = 1 + AST_FORMAT_TYPE_IMAGE, - /*! PNG Images */ - AST_FORMAT_PNG = 2 + AST_FORMAT_TYPE_IMAGE, - - /*! T.140 RED Text format RFC 4103 */ - AST_FORMAT_T140RED = 1 + AST_FORMAT_TYPE_TEXT, - /*! T.140 Text format - ITU T.140, RFC 4103 */ - AST_FORMAT_T140 = 2 + AST_FORMAT_TYPE_TEXT, -}; - -/*! Determine what type of media a ast_format_id is. */ -#define AST_FORMAT_GET_TYPE(id) (((int) (id / AST_FORMAT_INC)) * AST_FORMAT_INC) - - -/*! \brief This structure contains the buffer used for format attributes */ -struct ast_format_attr { - /*! The buffer formats can use to represent attributes */ - uint32_t format_attr[AST_FORMAT_ATTR_SIZE]; - /*! If a format's payload needs to pass through that a new marker is required - * for RTP, this variable will be set. */ - uint8_t rtp_marker_bit; -}; - -/*! \brief Represents a media format within Asterisk. */ -struct ast_format { - /*! The unique id representing this format from all the other formats. */ - enum ast_format_id id; - /*! Attribute structure used to associate attributes with a format. */ - struct ast_format_attr fattr; -}; +struct ast_format; +/*! \brief Format comparison results */ enum ast_format_cmp_res { - /*! structure 1 is identical to structure 2. */ + /*! Both formats are equivalent to eachother */ AST_FORMAT_CMP_EQUAL = 0, - /*! structure 1 contains elements not in structure 2. */ + /*! Both formats are completely different and not the same in any way */ AST_FORMAT_CMP_NOT_EQUAL, - /*! structure 1 is a proper subset of the elements in structure 2.*/ + /*! Both formats are similar but not equivalent */ AST_FORMAT_CMP_SUBSET, }; -/*! \brief Definition of supported media formats (codecs) */ -struct ast_format_list { - struct ast_format format; /*!< The unique format. */ - char name[64]; /*!< short name */ - unsigned int samplespersecond; /*!< Number of samples per second (8000/16000) */ - char desc[128]; /*!< Description */ - int fr_len; /*!< Single frame length in bytes */ - int min_ms; /*!< Min value */ - int max_ms; /*!< Max value */ - int inc_ms; /*!< Increment */ - int def_ms; /*!< Default value */ - unsigned int flags; /*!< Smoother flags */ - int cur_ms; /*!< Current value */ - int custom_entry; -}; - -/*! \brief A format must register an attribute interface if it requires the use of the format attributes void pointer */ -struct ast_format_attr_interface { - /*! format type */ - enum ast_format_id id; - - /*! \brief Determine if format_attr 1 is a subset of format_attr 2. +/*! \brief Optional format interface to extend format operations */ +struct ast_format_interface { + /*! + * \brief Callback for when the format is destroyed, used to release attribute resources * - * \retval ast_format_cmp_res representing the result of comparing fattr1 and fattr2. + * \param format The format structure to destroy */ - enum ast_format_cmp_res (* const format_attr_cmp)(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2); + void (*const format_destroy)(struct ast_format *format); - /*! \brief Get joint attributes of same format type if they exist. + /*! + * \brief Callback for when the format is cloned, used to clone attributes + * + * \param src Source format of attributes + * \param dst Destination format for attributes * - * \retval 0 if joint attributes exist - * \retval -1 if no joint attributes are present + * \retval 0 success + * \retval -1 failure */ - int (* const format_attr_get_joint)(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result); - - /*! \brief Set format capabilities from a list of key value pairs ending with AST_FORMAT_ATTR_END. - * \note This function does not need to call va_end of the va_list. */ - void (* const format_attr_set)(struct ast_format_attr *format_attr, va_list ap); + int (*const format_clone)(const struct ast_format *src, struct ast_format *dst); /*! - * \brief Find out if format capabilities in va_list are in format. - * \note This function does not need to call va_end of the va_list. + * \brief Determine if format 1 is a subset of format 2. * - * \note This function is optional. In many cases the format_attr_cmp - * function can be used to derive these results. If it is possible - * that some format attributes have no bearing on the equality of two formats, this - * function must exist. + * \param format1 First format to compare + * \param format2 Second format which the first is compared against * - * \retval 0 if all attributes exist - * \retval -1 if any of the attributes not present + * \retval ast_format_cmp_res representing the result of comparing format1 and format2. */ - int (* const format_attr_isset)(const struct ast_format_attr *format_attr, va_list ap); + enum ast_format_cmp_res (* const format_cmp)(const struct ast_format *format1, + const struct ast_format *format2); - /* - * \brief Return a value for a specific format key. Return that value in the void pointer. + /*! + * \brief Get a format with the joint compatible attributes of both provided formats. + * + * \param format1 The first format + * \param format2 The second format + * + * \retval non-NULL if joint format + * \retval NULL if no joint format * - * \note It is not expected that all key value pairs can be returned, but those that can should - * be documented as such. + * \note The returned format has its reference count incremented and must be released using + * ao2_ref or ao2_cleanup. + */ + struct ast_format *(* const format_get_joint)(const struct ast_format *format1, + const struct ast_format *format2); + + /*! + * \brief Set an attribute on a format * - * \note This function is optional if key value pairs are not allowed to be accessed. This - * will result in -1 always being returned. + * \param name The name of the attribute + * \param value The value of the attribute * - * \retval 0 Success, value was found and copied into void pointer. - * \retval -1 failure, Value was either not found, or not allowed to be accessed. + * \retval non-NULL success + * \retval NULL failure */ - int (* const format_attr_get_val)(const struct ast_format_attr *format_attr, int key, void *val); + struct ast_format *(* const format_attribute_set)(const struct ast_format *format, + const char *name, const char *value); - /* - * \brief Parse SDP attribute information, interpret it, and store it in ast_format_attr structure. + /*! + * \brief Parse SDP attribute information, interpret it, and store it in the format structure. + * + * \param format Format to set attributes on + * \param attributes A string containing only the attributes from the fmtp line * - * \retval 0 Success, values were valid - * \retval -1 Failure, some values were not acceptable + * \retval non-NULL Success, values were valid + * \retval NULL Failure, some values were not acceptable */ - int (* const format_attr_sdp_parse)(struct ast_format_attr *format_attr, const char *attributes); + struct ast_format *(* const format_parse_sdp_fmtp)(const struct ast_format *format, const char *attributes); /*! * \brief Generate SDP attribute information from an ast_format_attr structure. * + * \param format The format containing attributes + * \param payload The payload number to place into the fmtp line + * \param str The generated fmtp line + * * \note This callback should generate a full fmtp line using the provided payload number. */ - void (* const format_attr_sdp_generate)(const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str); + void (* const format_generate_sdp_fmtp)(const struct ast_format *format, unsigned int payload, + struct ast_str **str); }; /*! - * \brief This function is used to have a media format aware module parse and interpret - * SDP attribute information. Once interpreted this information is stored on the format - * itself using Asterisk format attributes. + * \brief Initialize media format support * - * \param format to set - * \param attributes string containing the fmtp line from the SDP - * - * \retval 0 success, attribute values were valid - * \retval -1 failure, values were not acceptable + * \retval 0 success + * \retval -1 failure */ -int ast_format_sdp_parse(struct ast_format *format, const char *attributes); +int ast_format_init(void); /*! - * \brief This function is used to produce an fmtp SDP line for an Asterisk format. The - * attributes present on the Asterisk format are translated into the SDP equivalent. + * \brief Create a new media format * - * \param format to generate an fmtp line for - * \param payload numerical payload for the fmtp line - * \param str structure that the fmtp line will be appended to + * \param codec The codec to use + * + * \retval non-NULL success + * \retval NULL failure + * + * \note The format is returned with reference count incremented. It must be released using + * ao2_ref or ao2_cleanup. */ -void ast_format_sdp_generate(const struct ast_format *format, unsigned int payload, struct ast_str **str); +struct ast_format *ast_format_create(struct ast_codec *codec); /*! - * \brief This function is used to set an ast_format object to represent a media format - * with optional format attributes represented by format specific key value pairs. - * - * \param format to set - * \param id format id to set on format - * \param set_attributes are there attributes to set on this format. 0 == false, 1 == True. - * \param ... var list of attribute key value pairs, must end with AST_FORMAT_ATTR_END; + * \brief Create a new media format with a specific name * - * \details Example usage. - * ast_format_set(format, AST_FORMAT_ULAW, 0); // no capability attributes are needed for ULAW + * \param format_name The name to use for the format + * \param codec The codec to use * - * ast_format_set(format, AST_FORMAT_SILK, 1, // SILK has capability attributes. - * AST_FORMAT_SILK_ATTR_RATE, 24000, - * AST_FORMAT_SILK_ATTR_RATE, 16000, - * AST_FORMAT_SILK_ATTR_RATE, 12000, - * AST_FORMAT_SILK_ATTR_RATE, 8000, - * AST_FORMAT_ATTR_END); + * \note This creation function should be used when the name of the \c codec + * cannot be explicitly used for the name of the format. This is the case for + * codecs with multiple sample rates * - * \note This function will initialize the ast_format structure. + * \note The format is returned with reference count incremented. It must be released using + * ao2_ref or ao2_cleanup. * - * \return Pointer to ast_format object, same pointer that is passed in - * by the first argument. + * \retval non-NULL success + * \retval NULL failure */ -struct ast_format *ast_format_set(struct ast_format *format, enum ast_format_id id, int set_attributes, ... ); +struct ast_format *ast_format_create_named(const char *format_name, struct ast_codec *codec); /*! - * \brief After ast_format_set has been used on a function, this function can be used to - * set additional format attributes to the structure. + * \brief Clone an existing media format so it can be modified * - * \param format to set - * \param ... var list of attribute key value pairs, must end with AST_FORMAT_ATTR_END; - * - * \details Example usage. - * ast_format_set(format, AST_FORMAT_SILK, 0); - * ast_format_append(format, // SILK has capability attributes. - * AST_FORMAT_SILK_ATTR_RATE, 24000, - * AST_FORMAT_SILK_ATTR_RATE, 16000, - * AST_FORMAT_SILK_ATTR_RATE, 12000, - * AST_FORMAT_SILK_ATTR_RATE, 8000, - * AST_FORMAT_ATTR_END); - * - * \return Pointer to ast_format object, same pointer that is passed in - * by the first argument. + * \param format The existing media format + * + * \note The returned format is a new ao2 object. It must be released using ao2_cleanup. + * + * \retval non-NULL success + * \retval NULL failure */ -struct ast_format *ast_format_append(struct ast_format *format, ... ); +struct ast_format *ast_format_clone(const struct ast_format *format); /*! - * \brief Clears the format stucture. + * \brief Compare two formats + * + * \retval ast_format_cmp_res representing the result of comparing format1 and format2. */ -void ast_format_clear(struct ast_format *format); +enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2); /*! - * \brief This function is used to set an ast_format object to represent a media format - * with optional capability attributes represented by format specific key value pairs. + * \brief Get a common joint capability between two formats * - * \details Example usage. Is this SILK format capable of 8khz - * is_8khz = ast_format_isset(format, AST_FORMAT_SILK_CAP_RATE, 8000); + * \retval non-NULL if joint capability exists + * \retval NULL if no joint capability exists * - * \return 0, The format key value pairs are within the capabilities defined in this structure. - * \return -1, The format key value pairs are _NOT_ within the capabilities of this structure. + * \note The returned format must be treated as immutable. */ -int ast_format_isset(const struct ast_format *format, ... ); +struct ast_format *ast_format_joint(const struct ast_format *format1, const struct ast_format *format2); /*! - * \brief Get a value from a format containing attributes. - * \note The key represents the format attribute to be retrieved, and the void pointer - * is to the structure that value will be stored in. It must be known what structure a - * key represents. + * \brief Set an attribute on a format to a specific value * - * \retval 0, success - * \retval -1, failure - */ -int ast_format_get_value(const struct ast_format *format, int key, void *value); - -/*! - * \brief Compare ast_formats structures + * \param format The format to set the attribute on + * \param name Attribute name + * \param value Attribute value * - * \retval ast_format_cmp_res representing the result of comparing format1 and format2. + * \retval non-NULL success + * \retval NULL failure */ -enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2); +struct ast_format *ast_format_attribute_set(const struct ast_format *format, const char *name, + const char *value); /*! - * \brief Find joint format attributes of two ast_format - * structures containing the same uid and return the intersection in the - * result structure. + * \brief This function is used to have a media format aware module parse and interpret + * SDP attribute information. Once interpreted this information is stored on the format + * itself using Asterisk format attributes. * - * retval 0, joint attribute capabilities exist. - * retval -1, no joint attribute capabilities exist. + * \param format to set + * \param attributes string containing the fmtp line from the SDP + * + * \retval non-NULL success, attribute values were valid + * \retval NULL failure, values were not acceptable */ -int ast_format_joint(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result); +struct ast_format *ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes); /*! - * \brief copy format src into format dst. + * \brief This function is used to produce an fmtp SDP line for an Asterisk format. The + * attributes present on the Asterisk format are translated into the SDP equivalent. + * + * \param format to generate an fmtp line for + * \param payload numerical payload for the fmtp line + * \param str structure that the fmtp line will be appended to */ -void ast_format_copy(struct ast_format *dst, const struct ast_format *src); +void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str); /*! - * \brief Set the rtp mark value on the format to indicate to the interface - * writing this format's payload that a new RTP marker is necessary. + * \brief Register a format interface for use with the provided codec + * + * \param codec The name of codec the interface is applicable to + * \param interface A pointer to the interface implementation + * \param mod The module this format interface is provided by + * + * \retval 0 success + * \retval -1 failure */ -void ast_format_set_video_mark(struct ast_format *format); +int __ast_format_interface_register(const char *codec, const struct ast_format_interface *interface, struct ast_module *mod); /*! - * \brief Determine of the marker bit is set or not on this format. + * \brief Register a format interface for use with the provided codec * - * \retval 1, true - * \retval 0, false + * \param codec The name of codec the interface is applicable to + * \param interface A pointer to the interface implementation + * + * \retval 0 success + * \retval -1 failure */ -int ast_format_get_video_mark(const struct ast_format *format); +#define ast_format_interface_register(codec, interface) __ast_format_interface_register(codec, interface, ast_module_info->self) /*! - * \brief ast_format to old bitfield format represenatation + * \brief Get the attribute data on a format * - * \note This is only to be used for IAX2 compatibility + * \param format The media format * - * \retval iax2 representation of ast_format - * \retval 0, if no representation existis for iax2 + * \return Currently set attribute data */ -uint64_t ast_format_to_old_bitfield(const struct ast_format *format); +void *ast_format_get_attribute_data(const struct ast_format *format); /*! - * \brief ast_format_id to old bitfield format represenatation + * \brief Set the attribute data on a format * + * \param format The media format + * \param attribute_data The attribute data */ -uint64_t ast_format_id_to_old_bitfield(enum ast_format_id id); +void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data); /*! - * \brief convert old bitfield format to ast_format represenatation - * \note This is only to be used for IAX2 compatibility + * \brief Get the name associated with a format * - * \retval on success, pointer to the dst format in the input parameters - * \retval on failure, NULL + * \param format The media format + * + * \return The name of the format */ -struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src); +const char *ast_format_get_name(const struct ast_format *format); /*! - * \brief convert old bitfield format to ast_format_id value + * \brief Get the codec identifier associated with a format + * + * \param format The media format + * + * \return codec identifier */ -enum ast_format_id ast_format_id_from_old_bitfield(uint64_t src); +unsigned int ast_format_get_codec_id(const struct ast_format *format); /*! - * \brief Retrieve the global format list in a read only array. - * \note ast_format_list_destroy must be called on every format - * list retrieved from this function. + * \brief Get the codec name associated with a format + * + * \param format The media format + * + * \return The codec name */ -const struct ast_format_list *ast_format_list_get(size_t *size); +const char *ast_format_get_codec_name(const struct ast_format *format); /*! - * \brief Destroy an ast_format_list gotten from ast_format_list_get() - */ -const struct ast_format_list *ast_format_list_destroy(const struct ast_format_list *list); - -/*! \brief Get the name of a format - * \param format id of format - * \return A static string containing the name of the format or "unknown" if unknown. - */ -const char* ast_getformatname(const struct ast_format *format); - -/*! \brief Returns a string containing all formats pertaining to an format id. - * \param buf a buffer for the output string - * \param size size of buf (bytes) - * \param id format id. - * \return The return value is buf. + * \brief Get whether or not the format can be smoothed + * + * \param format The media format + * + * \retval 0 the format cannot be smoothed + * \retval 1 the format can be smoothed */ -char* ast_getformatname_multiple_byid(char *buf, size_t size, enum ast_format_id id); +int ast_format_can_be_smoothed(const struct ast_format *format); /*! - * \brief Gets a format from a name. - * \param name string of format - * \param format structure to return the format in. - * \return This returns the format pointer given to it on success and NULL on failure + * \brief Get the media type of a format + * + * \param format The media format + * + * \return the media type */ -struct ast_format *ast_getformatbyname(const char *name, struct ast_format *format); +enum ast_media_type ast_format_get_type(const struct ast_format *format); /*! - * \brief Get a name from a format - * \param format to get name of - * \return This returns a static string identifying the format on success, 0 on error. + * \brief Get the default framing size (in milliseconds) for a format + * + * \param format The media format + * + * \return default framing size in milliseconds */ -const char *ast_codec2str(struct ast_format *format); +unsigned int ast_format_get_default_ms(const struct ast_format *format); /*! - * \brief Get the sample rate for a given format. + * \brief Get the minimum amount of media carried in this format + * + * \param format The media format + * + * \return minimum framing size in milliseconds */ -int ast_format_rate(const struct ast_format *format); +unsigned int ast_format_get_minimum_ms(const struct ast_format *format); /*! - * \brief register ast_format_attr_interface with core. + * \brief Get the maximum amount of media carried in this format * - * \retval 0 success - * \retval -1 failure + * \param format The media format + * + * \return maximum framing size in milliseconds */ -int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface); +unsigned int ast_format_get_maximum_ms(const struct ast_format *format); /*! - * \brief unregister format_attr interface with core. + * \brief Get the minimum number of bytes expected in a frame for this format * - * \retval 0 success - * \retval -1 failure + * \param format The media format + * + * \return minimum expected bytes in a frame for this format */ -int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface); +unsigned int ast_format_get_minimum_bytes(const struct ast_format *format); /*! - * \brief Determine if a format is 16bit signed linear of any sample rate. + * \brief Get the sample rate of a media format + * + * \param format The media format + * + * \return sample rate */ -int ast_format_is_slinear(const struct ast_format *format); +unsigned int ast_format_get_sample_rate(const struct ast_format *format); /*! - * \brief Get the best slinear format id for a given sample rate + * \brief Get the length (in milliseconds) for the format with a given number of samples + * + * \param format The media format + * \param samples The number of samples + * + * \return length of media (in milliseconds) */ -enum ast_format_id ast_format_slin_by_rate(unsigned int rate); +unsigned int ast_format_determine_length(const struct ast_format *format, unsigned int samples); /*! * \since 12 @@ -494,4 +384,5 @@ struct stasis_message_type *ast_format_register_type(void); * \retval NULL on error */ struct stasis_message_type *ast_format_unregister_type(void); + #endif /* _AST_FORMAT_H */ diff --git a/include/asterisk/format_cache.h b/include/asterisk/format_cache.h new file mode 100644 index 000000000..e0744054e --- /dev/null +++ b/include/asterisk/format_cache.h @@ -0,0 +1,301 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2014, Digium, Inc. + * + * Joshua Colp <jcolp@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Media Format Cache API + * + * \author Joshua Colp <jcolp@digium.com> + */ + +#ifndef _AST_FORMAT_CACHE_H_ +#define _AST_FORMAT_CACHE_H_ + +struct ast_format; + +/*! + * \brief Built-in cached signed linear 8kHz format. + */ +extern struct ast_format *ast_format_slin; + +/*! + * \brief Built-in cached signed linear 12kHz format. + */ +extern struct ast_format *ast_format_slin12; + +/*! + * \brief Built-in cached signed linear 16kHz format. + */ +extern struct ast_format *ast_format_slin16; + +/*! + * \brief Built-in cached signed linear 24kHz format. + */ +extern struct ast_format *ast_format_slin24; + +/*! + * \brief Built-in cached signed linear 32kHz format. + */ +extern struct ast_format *ast_format_slin32; + +/*! + * \brief Built-in cached signed linear 44kHz format. + */ +extern struct ast_format *ast_format_slin44; + +/*! + * \brief Built-in cached signed linear 48kHz format. + */ +extern struct ast_format *ast_format_slin48; + +/*! + * \brief Built-in cached signed linear 96kHz format. + */ +extern struct ast_format *ast_format_slin96; + +/*! + * \brief Built-in cached signed linear 192kHz format. + */ +extern struct ast_format *ast_format_slin192; + +/*! + * \brief Built-in cached ulaw format. + */ +extern struct ast_format *ast_format_ulaw; + +/*! + * \brief Built-in cached alaw format. + */ +extern struct ast_format *ast_format_alaw; + +/*! + * \brief Built-in cached testlaw format. + */ +extern struct ast_format *ast_format_testlaw; + +/*! + * \brief Built-in cached gsm format. + */ +extern struct ast_format *ast_format_gsm; + +/*! + * \brief Built-in cached adpcm format. + */ +extern struct ast_format *ast_format_adpcm; + +/*! + * \brief Built-in cached g722 format. + */ +extern struct ast_format *ast_format_g722; + +/*! + * \brief Built-in cached g726 format. + */ +extern struct ast_format *ast_format_g726; + +/*! + * \brief Built-in cached g726 aal2 format. + */ +extern struct ast_format *ast_format_g726_aal2; + +/*! + * \brief Built-in cached ilbc format. + */ +extern struct ast_format *ast_format_ilbc; + +/*! + * \brief Built-in cached ilbc format. + */ +extern struct ast_format *ast_format_lpc10; + +/*! + * \brief Built-in cached speex format. + */ +extern struct ast_format *ast_format_speex; + +/*! + * \brief Built-in cached speex at 16kHz format. + */ +extern struct ast_format *ast_format_speex16; + +/*! + * \brief Built-in cached speex at 32kHz format. + */ +extern struct ast_format *ast_format_speex32; + +/*! + * \brief Built-in cached g723.1 format. + */ +extern struct ast_format *ast_format_g723; + +/*! + * \brief Built-in cached g729 format. + */ +extern struct ast_format *ast_format_g729; + +/*! + * \brief Built-in cached g719 format. + */ +extern struct ast_format *ast_format_g719; + +/*! + * \brief Built-in cached h261 format. + */ +extern struct ast_format *ast_format_h261; + +/*! + * \brief Built-in cached h263 format. + */ +extern struct ast_format *ast_format_h263; + +/*! + * \brief Built-in cached h263 plus format. + */ +extern struct ast_format *ast_format_h263p; + +/*! + * \brief Built-in cached h264 format. + */ +extern struct ast_format *ast_format_h264; + +/*! + * \brief Built-in cached mp4 format. + */ +extern struct ast_format *ast_format_mp4; + +/*! + * \brief Built-in cached vp8 format. + */ +extern struct ast_format *ast_format_vp8; + +/*! + * \brief Built-in cached jpeg format. + */ +extern struct ast_format *ast_format_jpeg; + +/*! + * \brief Built-in cached png format. + */ +extern struct ast_format *ast_format_png; + +/*! + * \brief Built-in cached siren14 format. + */ +extern struct ast_format *ast_format_siren14; + +/*! + * \brief Built-in cached siren7 format. + */ +extern struct ast_format *ast_format_siren7; + +/*! + * \brief Built-in cached opus format. + */ +extern struct ast_format *ast_format_opus; + +/*! + * \brief Built-in cached t140 format. + */ +extern struct ast_format *ast_format_t140; + +/*! + * \brief Built-in cached t140 red format. + */ +extern struct ast_format *ast_format_t140_red; + +/*! + * \brief Built-in cached vp8 format. + */ +extern struct ast_format *ast_format_vp8; + +/*! + * \brief Built-in "null" format. + */ +extern struct ast_format *ast_format_none; + +/*! + * \brief Initialize format cache support within the core. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_format_cache_init(void); + +/*! + * \brief Set a named format cache entry. + * + * \param format A pointer to the format to cache + * + * \retval 0 success + * \retval -1 failure + */ +int ast_format_cache_set(struct ast_format *format); + +/*! + * \brief Retrieve a named format from the cache. + * + * \param name Name of the cached format + * + * \retval non-NULL if found + * \retval NULL if not found + * + * \note The returned format has its reference count incremented. It must be + * dropped using ao2_ref or ao2_cleanup. + */ +struct ast_format *__ast_format_cache_get(const char *name); +struct ast_format *__ast_format_cache_get_debug(const char *name, const char *tag, const char *file, int line, const char *func); + +#ifdef REF_DEBUG +#define ast_format_cache_get(name) \ + __ast_format_cache_get_debug((name), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ast_t_format_cache_get(name, tag) \ + __ast_format_cache_get_debug((name), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#else +#define ast_format_cache_get(name) \ + __ast_format_cache_get((name)) +#define ast_t_format_cache_get(name, tag) \ + __ast_format_cache_get((name)) +#endif + + +/*! + * \brief Retrieve the best signed linear format given a sample rate. + * + * \param rate The sample rate + * + * \details + * This is a convenience function that returns one of the global + * ast_format_slinxxx formats. + * + * \return pointer to the signed linear format + * + * \note The returned format has NOT had its reference count incremented. + */ +struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate); + +/*! + * \brief Determines if a format is one of the cached slin formats + * + * \param format The format to check + * + * \retval 0 if the format is not an SLIN format + * \retval 1 if the format is an SLIN format + */ +int ast_format_cache_is_slinear(struct ast_format *format); + +#endif /* _AST_FORMAT_CACHE_H */ diff --git a/include/asterisk/format_cap.h b/include/asterisk/format_cap.h index aa4eb3bfd..f7d33fccd 100644 --- a/include/asterisk/format_cap.h +++ b/include/asterisk/format_cap.h @@ -1,9 +1,9 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright (C) 2010, Digium, Inc. + * Copyright (C) 2014, Digium, Inc. * - * David Vossel <dvossel@digium.com> + * Joshua Colp <jcolp@digium.com> * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact @@ -18,216 +18,289 @@ /*! * \file - * \brief Format Capability API + * \brief Format Capabilities API * - * \author David Vossel <dvossel@digium.com> + * \author Joshua Colp <jcolp@digium.com> */ -#ifndef _AST_FORMATCAP_H_ -#define _AST_FORMATCAP_H_ +#ifndef _AST_FORMAT_CAP_H_ +#define _AST_FORMAT_CAP_H_ -/*! Capabilities are represented by an opaque structure statically defined in format_capability.c */ +#include "asterisk/codec.h" + +/*! Capabilities are represented by an opaque structure statically defined in format_cap.c */ struct ast_format_cap; enum ast_format_cap_flags { /*! - * The ast_format_cap will be allocated with no lock. - * Useful if there is a separate lock used to protect the structure - */ - AST_FORMAT_CAP_FLAG_NOLOCK = (1 << 0), - /*! - * String representations of the formats are cached on the structure. - * Useful if string representation is frequently requested of the structure. + * Default format capabilities settings */ - AST_FORMAT_CAP_FLAG_CACHE_STRINGS = (1 << 1), + AST_FORMAT_CAP_FLAG_DEFAULT = 0, }; /*! * \brief Allocate a new ast_format_cap structure * * \param flags Modifiers of struct behavior. + * * \retval ast_format_cap object on success. * \retval NULL on failure. */ -struct ast_format_cap *ast_format_cap_alloc(enum ast_format_cap_flags flags); +struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags); +struct ast_format_cap *__ast_format_cap_alloc_debug(enum ast_format_cap_flags flags, const char *tag, const char *file, int line, const char *func); + +#ifdef REF_DEBUG +#define ast_format_cap_alloc(flags) \ + __ast_format_cap_alloc_debug((flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ast_t_format_cap_alloc(flags, tag) \ + __ast_format_cap_alloc_debug((flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#else +#define ast_format_cap_alloc(flags) \ + __ast_format_cap_alloc((flags)) +#define ast_t_format_cap_alloc(flags, tag) \ + __ast_format_cap_alloc((flags)) +#endif /*! - * \brief Destroy an ast_format_cap structure. + * \brief Set the global framing. + * + * \param cap The capabilities structure. + * \param framing The framing value (in milliseconds). * - * \return NULL + * \note This is used if a format does not provide a framing itself. Note that + * adding subsequent formats to the \c ast_format_cap structure may + * override this value, if the framing they require is less than the + * value set by this function. */ -void *ast_format_cap_destroy(struct ast_format_cap *cap); +void ast_format_cap_set_framing(struct ast_format_cap *cap, unsigned int framing); /*! - * \brief Add format capability to capabilities structure. + * \brief Get the global framing. * - * \note A copy of the input format is made and that copy is - * what is placed in the ast_format_cap structure. The actual - * input format ptr is not stored. + * \param cap The capabilities structure. + * + * \retval 0 if no formats are in the structure and no framing has been provided + * \retval The global framing value (in milliseconds) + * + * \note This will be the minimum framing allowed across all formats in the + * capabilities structure, or an overridden value */ -void ast_format_cap_add(struct ast_format_cap *cap, const struct ast_format *format); +unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap); /*! - * \brief Add all formats Asterisk knows about for a specific type to - * the capabilities structure. Formats with attributes are set, but their - * attributes are initilized to 0's. An attribute structure of 0's should - * indicate to the format attribute interface that the format has full - * capabilities. - * - * \note A copy of the input format is made and that copy is - * what is placed in the ast_format_cap structure. The actual - * input format ptr is not stored. + * \brief Add format capability to capabilities structure. + * + * \param cap The capabilities structure to add to. + * \param format The format to add. + * \param framing The framing for the format (in milliseconds). + * + * \retval 0 success + * \retval -1 failure + * + * \note A reference to the format is taken and used in the capabilities structure. + * + * \note The order in which add is called determines the format preference order. + * + * \note If framing is specified here it overrides any global framing that has been set. */ -void ast_format_cap_add_all_by_type(struct ast_format_cap *cap, enum ast_format_type type); +int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing); +int __ast_format_cap_append_debug(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func); + +#ifdef REF_DEBUG +#define ast_format_cap_append(cap, format, framing) \ + __ast_format_cap_append_debug((cap), (format), (framing), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ast_t_format_cap_append(cap, format, framing, tag) \ + __ast_format_cap_append_debug((cap), (format), (framing), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#else +#define ast_format_cap_append(cap, format, framing) \ + __ast_format_cap_append((cap), (format), (framing)) +#define ast_t_format_cap_append(cap, format, framing, tag) \ + __ast_format_cap_append((cap), (format), (framing)) +#endif /*! - * \brief Add all known formats to the capabilities structure using default format attribute. + * \brief Add all codecs Asterisk knows about for a specific type to + * the capabilities structure. + * + * \param cap The capabilities structure to add to. + * \param type The type of formats to add. + * + * \retval 0 success + * \retval -1 failure + * + * \note A generic format with no attributes is created using the codec. + * + * \note If AST_MEDIA_TYPE_UNKNOWN is passed as the type all known codecs will be added. */ -void ast_format_cap_add_all(struct ast_format_cap *cap); +int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type); /*! - * \brief Append the formats in src to dst + * \brief Append the formats of provided type in src to dst + * + * \param dst The destination capabilities structure + * \param src The source capabilities structure + * \param type The type of formats to append. + * + * \retval 0 success + * \retval -1 failure + * + * \note If AST_MEDIA_TYPE_UNKNOWN is passed as the type all known codecs will be added. */ -void ast_format_cap_append(struct ast_format_cap *dst, const struct ast_format_cap *src); +int ast_format_cap_append_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type); /*! - * \brief Copy all items in src to dst. - * \note any items in dst will be removed before copying + * \brief Replace the formats of provided type in dst with equivalent formats from src + * + * \param dst The destination capabilities structure + * \param src The source capabilities structure + * \param type The type of formats to replace. + * + * \note If AST_MEDIA_TYPE_UNKNOWN is passed as the type all known codecs will be replaced. + * \note Formats present in src but not dst will not be appended to dst. */ -void ast_format_cap_copy(struct ast_format_cap *dst, const struct ast_format_cap *src); +void ast_format_cap_replace_from_cap(struct ast_format_cap *dst, const struct ast_format_cap *src, enum ast_media_type type); /*! - * \brief create a deep copy of an ast_format_cap structure + * \brief Parse an "allow" or "deny" list and modify a format capabilities structure accordingly + * + * \param cap The capabilities structure to modify + * \param list The list containing formats to append or remove + * \param allowing If zero, start removing formats specified in the list. If non-zero, + * start appending formats specified in the list. * - * \retval cap on success - * \retval NULL on failure + * \retval 0 on success + * \retval -1 on failure */ -struct ast_format_cap *ast_format_cap_dup(const struct ast_format_cap *src); +int ast_format_cap_update_by_allow_disallow(struct ast_format_cap *cap, const char *list, int allowing); /*! - * \brief determine if a capabilities structure is empty or not + * \brief Get the number of formats present within the capabilities structure * - * \retval 1, true is empty - * \retval 0, false, not empty + * \param cap The capabilities structure + * + * \return the number of formats */ -int ast_format_cap_is_empty(const struct ast_format_cap *cap); +size_t ast_format_cap_count(const struct ast_format_cap *cap); /*! - * \brief Remove format capability from capability structure. + * \brief Get the format at a specific index * - * \note format must match Exactly to format in ast_format_cap object in order - * to be removed. + * \param cap The capabilities structure + * \param position The position to get * - * \retval 0, remove was successful - * \retval -1, remove failed. Could not find format to remove + * \retval non-NULL success + * \retval NULL failure + * + * \note This is a zero based index. + * + * \note Formats are returned in order of preference. + * + * \note The reference count of the returned format is increased. It must be released using ao2_ref + * or ao2_cleanup. */ -int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format); +struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position); /*! - * \brief Remove all format capabilities from capability - * structure for a specific format id. + * \brief Get the most preferred format for a particular media type * - * \note This will remove _ALL_ formats matching the format id from the - * capabilities structure. + * \param cap The capabilities structure + * \param type The type of media to get * - * \retval 0, remove was successful - * \retval -1, remove failed. Could not find formats to remove + * \retval non-NULL the preferred format + * \retval NULL no media of \c type present + * + * \note The reference count of the returned format is increased. It must be released using ao2_ref + * or ao2_cleanup. */ -int ast_format_cap_remove_byid(struct ast_format_cap *cap, enum ast_format_id id); +struct ast_format *ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type); /*! - * \brief Remove all formats matching a specific format type. + * \brief Get the framing for a format + * + * \param cap The capabilities structure + * \param format The format to retrieve + * + * \return the framing (in milliseconds) */ -void ast_format_cap_remove_bytype(struct ast_format_cap *cap, enum ast_format_type type); +unsigned int ast_format_cap_get_format_framing(const struct ast_format_cap *cap, const struct ast_format *format); /*! - * \brief Remove all format capabilities from capability structure + * \brief Remove format capability from capability structure. + * + * \note format must be an exact pointer match to remove from capabilities structure. + * + * \retval 0, remove was successful + * \retval -1, remove failed. Could not find format to remove */ -void ast_format_cap_remove_all(struct ast_format_cap *cap); +int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format); /*! - * \brief Remove all previous formats and set a single new format. + * \brief Remove all formats matching a specific format type. + * + * \param cap The capabilities structure + * \param type The media type to remove formats of + * + * \note All formats can be removed by using the AST_MEDIA_TYPE_UNKNOWN type. */ -void ast_format_cap_set(struct ast_format_cap *cap, struct ast_format *format); +void ast_format_cap_remove_by_type(struct ast_format_cap *cap, enum ast_media_type type); /*! * \brief Find if input ast_format is within the capabilities of the ast_format_cap object * then return the compatible format from the capabilities structure in the result. * - * \retval 1 format is compatible with formats held in ast_format_cap object. - * \retval 0 format is not compatible with any formats in ast_format_cap object. + * \retval non-NULL if format is compatible + * \retval NULL if not compatible + * + * \note The reference count of the returned format is increased. It must be released using ao2_ref + * or ao2_cleanup. */ -int ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format, struct ast_format *result); +struct ast_format *ast_format_cap_get_compatible_format(const struct ast_format_cap *cap, const struct ast_format *format); /*! * \brief Find if ast_format is within the capabilities of the ast_format_cap object. * - * \retval 1 format is compatible with formats held in ast_format_cap object. - * \retval 0 format is not compatible with any formats in ast_format_cap object. +* \retval ast_format_cmp_res representing the result of the compatibility check between cap and format. */ -int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format); +enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format); /*! - * \brief Finds the best quality audio format for a given format id and returns it in result. + * \brief Find the compatible formats between two capabilities structures * - * \retval 1 format found and set to result structure. - * \retval 0 no format found, result structure is cleared. - */ -int ast_format_cap_best_byid(const struct ast_format_cap *cap, enum ast_format_id, struct ast_format *result); - -/*! - * \brief is cap1 identical to cap2 + * \param cap1 The first capabilities structure + * \param cap2 The second capabilities structure + * \param[out] result The capabilities structure to place the results into * - * retval 1 true, identical - * retval 0 false, not identical - */ -int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); - -/*! - * \brief Get joint capability structure. + * \retval 0 success + * \retval -1 failure * - * \note returns an ast_format_cap object containing the joint capabilities on success. This new - * capabilities structure is allocated with _NO_ locking enabled. If a joint structure requires - * locking, allocate it and use the ast_format_cap_joint_copy function to fill it with the joint - * capabilities. + * \note The preference order of cap1 is respected. * - * \retval !NULL success, joint capabilties structure with _NO_ locking enabled. - * \retval NULL failure + * \note If failure occurs the result format capabilities structure may contain a partial result. */ -struct ast_format_cap *ast_format_cap_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); +int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, + struct ast_format_cap *result); /*! - * \brief Get joint capability structure, copy into result capabilities structure + * \brief Determine if any joint capabilities exist between two capabilities structures * - * \retval 1, joint capabilities exist - * \retval 0, joint capabilities do not exist - */ -int ast_format_cap_joint_copy(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result); - -/*! - * \brief Get joint capability structure, append into result capabilities structure + * \param cap1 The first capabilities structure + * \param cap2 The second capabilities structure * - * \retval 1, joint capabilities exist - * \retval 0, joint capabilities do not exist + * \retval 0 no joint capabilities exist + * \retval 1 joint capabilities exist */ -int ast_format_cap_joint_append(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result); +int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); /*! - * \brief Find out if capability structures have any joint capabilities without - * returning those capabilities. + * \brief Determine if two capabilities structures are identical * - * \retval 1 true, has joint capabilities - * \retval 0 false, failure - */ -int ast_format_cap_has_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); - -/*! - * \brief Get all capabilities for a specific media type + * \param cap1 The first capabilities structure + * \param cap2 The second capabilities structure * - * \retval !NULL success, new capabilities structure with _NO_ locking enabled on the new structure. - * \retval NULL failure + * \retval 0 capabilities are not identical + * \retval 1 capabilities are identical */ -struct ast_format_cap *ast_format_cap_get_type(const struct ast_format_cap *cap, enum ast_format_type ftype); +int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); /*! * \brief Find out if the capabilities structure has any formats @@ -236,68 +309,16 @@ struct ast_format_cap *ast_format_cap_get_type(const struct ast_format_cap *cap, * \retval 1 true * \retval 0 false, no formats of specific type. */ -int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_format_type type); - -/*! \brief Start iterating formats */ -void ast_format_cap_iter_start(struct ast_format_cap *cap); - -/*! - * \brief Next format in interation - * - * \details - * Here is how to use the ast_format_cap iterator. - * - * 1. call ast_format_cap_iter_start - * 2. call ast_format_cap_iter_next in a loop until it returns -1 - * 3. call ast_format_cap_iter_end to terminate the iterator. - * - * example: - * - * ast_format_cap_iter_start(cap); - * while (!ast_format_cap_iter_next(cap, &format)) { - * } - * ast_format_cap_iter_end(Cap); - * - * \note Unless the container was alloced using no_lock, the container - * will be locked during the entire iteration until ast_format_cap_iter_end - * is called. XXX Remember this, and do not attempt to lock any containers - * within this iteration that will violate locking order. - * - * \retval 0 on success, new format is copied into input format struct - * \retval -1, no more formats are present. - */ -int ast_format_cap_iter_next(struct ast_format_cap *cap, struct ast_format *format); - -/*! - * \brief Ends ast_format_cap iteration. - * \note this must be call after every ast_format_cap_iter_start - */ -void ast_format_cap_iter_end(struct ast_format_cap *cap); +int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type); /*! - * \brief ast_format_cap to old bitfield format represenatation + * \brief Get the names of codecs of a set of formats * - * \note This is only to be used for IAX2 compatibility + * \param cap The capabilities structure containing the formats + * \param buf A \c ast_str buffer to populate with the names of the formats * - * \retval old bitfield representation of ast_format_cap - * \retval 0, if no old bitfield capabilities are present in ast_format_cap - */ -uint64_t ast_format_cap_to_old_bitfield(const struct ast_format_cap *cap); - -/*! - * \brief convert old bitfield format to ast_format_cap represenatation - * \note This is only to be used for IAX2 compatibility - */ -void ast_format_cap_from_old_bitfield(struct ast_format_cap *dst, uint64_t src); - -/*! \brief Get the names of a set of formats - * \param buf a buffer for the output string - * \param size size of buf (bytes) - * \param cap format the format (combined IDs of codecs) - * Prints a list of readable codec names corresponding to "format". - * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)" - * \return The return value is buf. + * \return The contents of the buffer in \c buf */ -char *ast_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *cap); +const char *ast_format_cap_get_names(struct ast_format_cap *cap, struct ast_str **buf); -#endif /* _AST_FORMATCAP_H */ +#endif /* _AST_FORMAT_CAP_H */ diff --git a/include/asterisk/format_compatibility.h b/include/asterisk/format_compatibility.h new file mode 100644 index 000000000..f14b7166c --- /dev/null +++ b/include/asterisk/format_compatibility.h @@ -0,0 +1,129 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2014, Digium, Inc. + * + * Joshua Colp <jcolp@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Media Format Bitfield Compatibility API + * + * \author Joshua Colp <jcolp@digium.com> + */ + +#ifndef _AST_FORMAT_COMPATIBILITY_H_ +#define _AST_FORMAT_COMPATIBILITY_H_ + +struct ast_format; +struct ast_codec; + +/* + * Legacy bitfields for specific formats + */ + +/*! G.723.1 compression */ +#define AST_FORMAT_G723 (1ULL << 0) +/*! GSM compression */ +#define AST_FORMAT_GSM (1ULL << 1) +/*! Raw mu-law data (G.711) */ +#define AST_FORMAT_ULAW (1ULL << 2) +/*! Raw A-law data (G.711) */ +#define AST_FORMAT_ALAW (1ULL << 3) +/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */ +#define AST_FORMAT_G726_AAL2 (1ULL << 4) +/*! ADPCM (IMA) */ +#define AST_FORMAT_ADPCM (1ULL << 5) +/*! Raw 16-bit Signed Linear (8000 Hz) PCM */ +#define AST_FORMAT_SLIN (1ULL << 6) +/*! LPC10, 180 samples/frame */ +#define AST_FORMAT_LPC10 (1ULL << 7) +/*! G.729A audio */ +#define AST_FORMAT_G729 (1ULL << 8) +/*! SpeeX Free Compression */ +#define AST_FORMAT_SPEEX (1ULL << 9) +/*! iLBC Free Compression */ +#define AST_FORMAT_ILBC (1ULL << 10) +/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */ +#define AST_FORMAT_G726 (1ULL << 11) +/*! G.722 */ +#define AST_FORMAT_G722 (1ULL << 12) +/*! G.722.1 (also known as Siren7, 32kbps assumed) */ +#define AST_FORMAT_SIREN7 (1ULL << 13) +/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */ +#define AST_FORMAT_SIREN14 (1ULL << 14) +/*! Raw 16-bit Signed Linear (16000 Hz) PCM */ +#define AST_FORMAT_SLIN16 (1ULL << 15) +/*! G.719 (64 kbps assumed) */ +#define AST_FORMAT_G719 (1ULL << 32) +/*! SpeeX Wideband (16kHz) Free Compression */ +#define AST_FORMAT_SPEEX16 (1ULL << 33) +/*! Opus audio (8kHz, 16kHz, 24kHz, 48Khz) */ +#define AST_FORMAT_OPUS (1ULL << 34) +/*! Raw testing-law data (G.711) */ +#define AST_FORMAT_TESTLAW (1ULL << 47) +/*! H.261 Video */ +#define AST_FORMAT_H261 (1ULL << 18) +/*! H.263 Video */ +#define AST_FORMAT_H263 (1ULL << 19) +/*! H.263+ Video */ +#define AST_FORMAT_H263P (1ULL << 20) +/*! H.264 Video */ +#define AST_FORMAT_H264 (1ULL << 21) +/*! MPEG4 Video */ +#define AST_FORMAT_MP4 (1ULL << 22) +/*! VP8 Video */ +#define AST_FORMAT_VP8 (1ULL << 23) +/*! JPEG Images */ +#define AST_FORMAT_JPEG (1ULL << 16) +/*! PNG Images */ +#define AST_FORMAT_PNG (1ULL << 17) +/*! T.140 RED Text format RFC 4103 */ +#define AST_FORMAT_T140_RED (1ULL << 26) +/*! T.140 Text format - ITU T.140, RFC 4103 */ +#define AST_FORMAT_T140 (1ULL << 27) + +/*! + * \brief Convert a format structure to its respective bitfield + * + * \param format The media format + * + * \retval non-zero success + * \retval zero format not supported + */ +uint64_t ast_format_compatibility_format2bitfield(const struct ast_format *format); + +/*! + * \brief Convert a codec structure to its respective bitfield + * + * \param codec The media codec + * + * \retval non-zero success + * \retval zero format not supported + */ +uint64_t ast_format_compatibility_codec2bitfield(const struct ast_codec *codec); + +/*! + * \brief Convert a bitfield to its respective format structure + * + * \param bitfield The bitfield for the media format + * + * \retval non-NULL success + * \retval NULL failure + * + * \note The reference count of the returned format is NOT incremented + */ +struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield); + +#endif /* _AST_FORMAT_COMPATIBILITY_H */ diff --git a/include/asterisk/format_pref.h b/include/asterisk/format_pref.h deleted file mode 100644 index f5c3c22a7..000000000 --- a/include/asterisk/format_pref.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2010, Digium, Inc. - * - * Mark Spencer <markster@digium.com> - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief Format Preference API - */ - -#ifndef _AST_FORMATPREF_H_ -#define _AST_FORMATPREF_H_ - -#include "asterisk/format.h" -#include "asterisk/format_cap.h" - -#define AST_CODEC_PREF_SIZE 64 -struct ast_codec_pref { - /*! This array represents the each format in the pref list */ - struct ast_format formats[AST_CODEC_PREF_SIZE]; - /*! This array represents the format id's index in the global format list. */ - char order[AST_CODEC_PREF_SIZE]; - /*! This array represents the format's framing size if present. */ - int framing[AST_CODEC_PREF_SIZE]; -}; - -/*! \page AudioCodecPref Audio Codec Preferences - - In order to negotiate audio codecs in the order they are configured - in \<channel\>.conf for a device, we set up codec preference lists - in addition to the codec capabilities setting. The capabilities - setting is a bitmask of audio and video codecs with no internal - order. This will reflect the offer given to the other side, where - the prefered codecs will be added to the top of the list in the - order indicated by the "allow" lines in the device configuration. - - Video codecs are not included in the preference lists since they - can't be transcoded and we just have to pick whatever is supported -*/ - -/*! - *\brief Initialize an audio codec preference to "no preference". - * \arg \ref AudioCodecPref -*/ -void ast_codec_pref_init(struct ast_codec_pref *pref); - -/*! - * \brief Codec located at a particular place in the preference index. - * \param pref preference structure to get the codec out of - * \param index to retrieve from - * \param result ast_format structure to store the index value in - * \return pointer to input ast_format on success, NULL on failure -*/ -struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int index, struct ast_format *result); - -/*! \brief Remove audio a codec from a preference list */ -void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format); - -/*! \brief Append all codecs to a preference list, without disturbing existing order */ -void ast_codec_pref_append_all(struct ast_codec_pref *pref); - -/*! \brief Append a audio codec to a preference list, removing it first if it was already there -*/ -int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format); - -/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there -*/ -void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing); - -/*! \brief Select the best audio format according to preference list from supplied options. - * Best audio format is returned in the result format. - * - * \note If "find_best" is non-zero then if nothing is found, the "Best" format of - * the format list is selected and returned in the result structure, otherwise - * NULL is returned - * - * \retval ptr to result struture. - * \retval NULL, best codec was not found - */ -struct ast_format *ast_codec_choose(struct ast_codec_pref *pref, struct ast_format_cap *cap, int find_best, struct ast_format *result); - -/*! \brief Set packet size for codec -*/ -int ast_codec_pref_setsize(struct ast_codec_pref *pref, struct ast_format *format, int framems); - -/*! \brief Get packet size for codec -*/ -struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, struct ast_format *format); - -/*! \brief Dump audio codec preference list into a string */ -int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size); - -/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string - * \note Due to a misunderstanding in how codec preferences are stored, this - * list starts at 'B', not 'A'. For backwards compatibility reasons, this - * cannot change. - * \param pref A codec preference list structure - * \param buf A string denoting codec preference, appropriate for use in line transmission - * \param size Size of \a buf - * \param right Boolean: if 0, convert from \a buf to \a pref; if 1, convert from \a pref to \a buf. - */ -void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right); - -#endif /* _AST_FORMATPREF_H */ diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 846832aff..a981c7e72 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -31,7 +31,6 @@ extern "C" { #include <sys/time.h> -#include "asterisk/format_pref.h" #include "asterisk/format.h" #include "asterisk/endian.h" #include "asterisk/linkedlists.h" @@ -136,9 +135,13 @@ enum { AST_FRFLAG_HAS_TIMING_INFO = (1 << 0), }; -union ast_frame_subclass { +struct ast_frame_subclass { + /*! A frame specific code */ int integer; - struct ast_format format; + /*! The asterisk media format */ + struct ast_format *format; + /*! For video formats, an indication that a frame ended */ + unsigned int frame_ending; }; /*! \brief Data structure associated with a single frame of data @@ -147,7 +150,7 @@ struct ast_frame { /*! Kind of frame */ enum ast_frame_type frametype; /*! Subclass, frame dependent */ - union ast_frame_subclass subclass; + struct ast_frame_subclass subclass; /*! Length of data */ int datalen; /*! Number of samples in this frame */ @@ -384,9 +387,6 @@ struct ast_control_pvt_cause_code { char code[1]; /*!< Tech-specific cause code information, beginning with the name of the tech */ }; -#define AST_SMOOTHER_FLAG_G729 (1 << 0) -#define AST_SMOOTHER_FLAG_BE (1 << 1) - /* Option identifiers and flags */ #define AST_OPTION_FLAG_REQUEST 0 #define AST_OPTION_FLAG_ACCEPT 1 @@ -565,77 +565,11 @@ void ast_swapcopy_samples(void *dst, const void *src, int samples); #define ast_frame_byteswap_be(fr) do { ; } while(0) #endif -/*! \brief Parse an "allow" or "deny" line in a channel or device configuration - and update the capabilities and pref if provided. - Video codecs are not added to codec preference lists, since we can not transcode - \return Returns number of errors encountered during parsing - */ -int ast_parse_allow_disallow(struct ast_codec_pref *pref, struct ast_format_cap *cap, const char *list, int allowing); - -/*! \name AST_Smoother -*/ -/*@{ */ -/*! \page ast_smooth The AST Frame Smoother -The ast_smoother interface was designed specifically -to take frames of variant sizes and produce frames of a single expected -size, precisely what you want to do. - -The basic interface is: - -- Initialize with ast_smoother_new() -- Queue input frames with ast_smoother_feed() -- Get output frames with ast_smoother_read() -- when you're done, free the structure with ast_smoother_free() -- Also see ast_smoother_test_flag(), ast_smoother_set_flags(), ast_smoother_get_flags(), ast_smoother_reset() -*/ -struct ast_smoother; - -struct ast_smoother *ast_smoother_new(int bytes); -void ast_smoother_set_flags(struct ast_smoother *smoother, int flags); -int ast_smoother_get_flags(struct ast_smoother *smoother); -int ast_smoother_test_flag(struct ast_smoother *s, int flag); -void ast_smoother_free(struct ast_smoother *s); -void ast_smoother_reset(struct ast_smoother *s, int bytes); - -/*! - * \brief Reconfigure an existing smoother to output a different number of bytes per frame - * \param s the smoother to reconfigure - * \param bytes the desired number of bytes per output frame - * \return nothing - * - */ -void ast_smoother_reconfigure(struct ast_smoother *s, int bytes); - -int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap); -struct ast_frame *ast_smoother_read(struct ast_smoother *s); -#define ast_smoother_feed(s,f) __ast_smoother_feed(s, f, 0) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 1) -#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 0) -#else -#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 0) -#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 1) -#endif -/*@} Doxygen marker */ - void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix); -/*! \brief Returns the number of samples contained in the frame */ -int ast_codec_get_samples(struct ast_frame *f); - -/*! \brief Returns the number of bytes for the number of samples of the given format */ -int ast_codec_get_len(struct ast_format *format, int samples); - /*! \brief Appends a frame to the end of a list of frames, truncating the maximum length of the list */ struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe); - -/*! \brief Gets duration in ms of interpolation frame for a format */ -static inline int ast_codec_interp_len(struct ast_format *format) -{ - return (format->id == AST_FORMAT_ILBC) ? 30 : 20; -} - /*! \brief Adjusts the volume of the audio samples contained in a frame. \param f The frame containing the samples (must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR) diff --git a/include/asterisk/image.h b/include/asterisk/image.h index 302f09e85..9e358ad52 100644 --- a/include/asterisk/image.h +++ b/include/asterisk/image.h @@ -28,7 +28,7 @@ struct ast_imager { char *name; /*!< Name */ char *desc; /*!< Description */ char *exts; /*!< Extension(s) (separated by '|' ) */ - struct ast_format format; /*!< Image format */ + struct ast_format *format; /*!< Image format */ struct ast_frame *(*read_image)(int fd, int len); /*!< Read an image from a file descriptor */ int (*identify)(int fd); /*!< Identify if this is that type of file */ int (*write_image)(int fd, struct ast_frame *frame); /*!< Returns length written */ diff --git a/include/asterisk/mod_format.h b/include/asterisk/mod_format.h index ff3ab7bbf..7f17741fa 100644 --- a/include/asterisk/mod_format.h +++ b/include/asterisk/mod_format.h @@ -43,10 +43,10 @@ extern "C" { struct ast_format_def { char name[80]; /*!< Name of format */ char exts[80]; /*!< Extensions (separated by | if more than one) - this format can read. First is assumed for writing (e.g. .mp3) */ - struct ast_format format; /*!< Format of frames it uses/provides (one only) */ - /*! - * \brief Prepare an input stream for playback. + * this format can read. First is assumed for writing (e.g. .mp3) */ + struct ast_format *format; /*!< Format of frames it uses/provides (one only) */ + /*! + * \brief Prepare an input stream for playback. * \return 0 on success, -1 on error. * The FILE is already open (in s->f) so this function only needs to perform * any applicable validity checks on the file. If none is required, the @@ -110,7 +110,7 @@ struct ast_filestream { /*! Transparently translate from another format -- just once */ struct ast_trans_pvt *trans; struct ast_tranlator_pvt *tr; - struct ast_format lastwriteformat; + struct ast_format *lastwriteformat; int lasttimeout; struct ast_channel *owner; FILE *f; diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index d569710e0..45d9325ee 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -530,8 +530,6 @@ struct ast_sip_endpoint_media_configuration { struct ast_sip_direct_media_configuration direct_media; /*! T.38 (FoIP) options */ struct ast_sip_t38_configuration t38; - /*! Codec preferences */ - struct ast_codec_pref prefs; /*! Configured codecs */ struct ast_format_cap *codecs; /*! DSCP TOS bits for audio streams */ diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index 7340c6d71..51908f99b 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -126,8 +126,6 @@ struct ast_sip_session { struct ast_party_id id; /* Requested capabilities */ struct ast_format_cap *req_caps; - /* Codecs overriden by dialplan on an outgoing request */ - struct ast_codec_pref override_prefs; /* Optional DSP, used only for inband DTMF detection if configured */ struct ast_dsp *dsp; /* Whether the termination of the session should be deferred */ diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h index 81e530e85..e5f38eecc 100644 --- a/include/asterisk/rtp_engine.h +++ b/include/asterisk/rtp_engine.h @@ -1,4 +1,4 @@ -/* + /* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2009, Digium, Inc. @@ -71,10 +71,12 @@ extern "C" { #include "asterisk/astobj2.h" #include "asterisk/frame.h" +#include "asterisk/format_cap.h" #include "asterisk/netsock2.h" #include "asterisk/sched.h" #include "asterisk/res_srtp.h" #include "asterisk/stasis.h" +#include "asterisk/vector.h" /* Maximum number of payloads supported */ #if defined(LOW_MEMORY) @@ -245,7 +247,7 @@ struct ast_rtp_payload_type { int asterisk_format; /*! If asterisk_format is set, this is the internal * asterisk format represented by the payload */ - struct ast_format format; + struct ast_format *format; /*! Actual internal RTP specific value of the payload */ int rtp_code; /*! Actual payload number */ @@ -526,8 +528,6 @@ struct ast_rtp_engine { void (*prop_set)(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value); /*! Callback for setting a payload. If asterisk is to be used, asterisk_format will be set, otherwise value in code is used. */ void (*payload_set)(struct ast_rtp_instance *instance, int payload, int asterisk_format, struct ast_format *format, int code); - /*! Callback for setting packetization preferences */ - void (*packetization_set)(struct ast_rtp_instance *instance, struct ast_codec_pref *pref); /*! Callback for setting the remote address that RTP is to be sent to */ void (*remote_address_set)(struct ast_rtp_instance *instance, struct ast_sockaddr *sa); /*! Callback for changing DTMF mode */ @@ -575,11 +575,16 @@ struct ast_rtp_engine { /*! Structure that represents codec and packetization information */ struct ast_rtp_codecs { /*! Payloads present */ - struct ao2_container *payloads; - /*! Codec packetization preferences */ - struct ast_codec_pref pref; + AST_VECTOR(, struct ast_rtp_payload_type *) payloads; + /*! The framing for this media session */ + unsigned int framing; + /*! RW lock that protects elements in this structure */ + ast_rwlock_t codecs_lock; }; +#define AST_RTP_CODECS_NULL_INIT \ + { .payloads = { 0, }, .framing = 0, .codecs_lock = AST_RWLOCK_INIT_VALUE, } + /*! Structure that represents the glue that binds an RTP instance to a channel */ struct ast_rtp_glue { /*! Name of the channel driver that this glue is responsible for */ @@ -622,6 +627,18 @@ struct ast_rtp_glue { AST_RWLIST_ENTRY(ast_rtp_glue) entry; }; +/*! + * \brief Allocation routine for \ref ast_rtp_payload_type + * + * \retval NULL on error + * \retval An ao2 ref counted \c ast_rtp_payload_type on success. + * + * \note The \c ast_rtp_payload_type returned by this function is an + * ao2 ref counted object. + * + */ +struct ast_rtp_payload_type *ast_rtp_engine_alloc_payload_type(void); + #define ast_rtp_engine_register(engine) ast_rtp_engine_register2(engine, ast_module_info->self) /*! @@ -1117,25 +1134,6 @@ void ast_rtp_codecs_payloads_destroy(struct ast_rtp_codecs *codecs); void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance); /*! - * \brief Set payload information on an RTP instance to the default - * - * \param codecs The codecs structure to set defaults on - * \param instance Optionally the instance that the codecs structure belongs to - * - * Example usage: - * - * \code - * struct ast_rtp_codecs codecs; - * ast_rtp_codecs_payloads_default(&codecs, NULL); - * \endcode - * - * This sets the default payloads on the codecs structure. - * - * \since 1.8 - */ -void ast_rtp_codecs_payloads_default(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance); - -/*! * \brief Copy payload information from one RTP instance to another * * \param src The source codecs structure @@ -1249,20 +1247,36 @@ void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp * \param codecs Codecs structure to look in * \param payload Numerical payload to look up * - * \retval Payload information + * \retval Payload information. + * \retval NULL if payload does not exist. + * + * \note The payload returned by this function has its reference count increased. + * Callers are responsible for decrementing the reference count. * * Example usage: * * \code - * struct ast_rtp_payload_type payload_type; - * payload_type = ast_rtp_codecs_payload_lookup(&codecs, 0); + * struct ast_rtp_payload_type *payload_type; + * payload_type = ast_rtp_codecs_get_payload(&codecs, 0); * \endcode * * This looks up the information for payload '0' from the codecs structure. + */ +struct ast_rtp_payload_type *ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload); + +/*! + * \brief Update the format associated with a payload in a codecs structure * - * \since 1.8 + * \param codecs Codecs structure to operate on + * \param payload Numerical payload to look up + * \param format The format to replace the existing one + * + * \retval 0 success + * \retval -1 failure + * + * \since 13 */ -struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload); +int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format); /*! * \brief Retrieve the actual ast_format stored on the codecs structure for a specific payload @@ -1273,11 +1287,35 @@ struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs * \retval pointer to format structure on success * \retval NULL on failure * + * \note The format returned by this function has its reference count increased. + * Callers are responsible for decrementing the reference count. + * * \since 10.0 */ struct ast_format *ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload); /*! + * \brief Set the framing used for a set of codecs + * + * \param codecs Codecs structure to set framing on + * \param framing The framing value to set on the codecs + * + * \since 13.0.0 + */ +void ast_rtp_codecs_set_framing(struct ast_rtp_codecs *codecs, unsigned int framing); + +/*! + * \brief Get the framing used for a set of codecs + * + * \param codecs Codecs structure to get the framing from + * + * \retval The framing to be used for the media stream associated with these codecs + * + * \since 13.0.0 + */ +unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs); + +/*! * \brief Get the sample rate associated with known RTP payload types * * \param asterisk_format True if the value in format is to be used. @@ -1393,8 +1431,8 @@ const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_f * char buf[256] = ""; * struct ast_format tmp_fmt; * struct ast_format_cap *cap = ast_format_cap_alloc_nolock(); - * ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0)); - * ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0)); + * ast_format_cap_append(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0)); + * ast_format_cap_append(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0)); * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), cap, 0, 1, 0); * ast_format_cap_destroy(cap); * \endcode @@ -1406,25 +1444,6 @@ const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_f char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options); /*! - * \brief Set codec packetization preferences - * - * \param codecs Codecs structure to muck with - * \param instance Optionally the instance that the codecs structure belongs to - * \param prefs Codec packetization preferences - * - * Example usage: - * - * \code - * ast_rtp_codecs_packetization_set(&codecs, NULL, &prefs); - * \endcode - * - * This sets the packetization preferences pointed to by prefs on the codecs structure pointed to by codecs. - * - * \since 1.8 - */ -void ast_rtp_codecs_packetization_set(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, struct ast_codec_pref *prefs); - -/*! * \brief Begin sending a DTMF digit * * \param instance The RTP instance to send the DTMF on @@ -2111,12 +2130,12 @@ struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance); /*! \brief Custom formats declared in codecs.conf at startup must be communicated to the rtp_engine * so their mime type can payload number can be initialized. */ -int ast_rtp_engine_load_format(const struct ast_format *format); +int ast_rtp_engine_load_format(struct ast_format *format); /*! \brief Formats requiring the use of a format attribute interface must have that * interface registered in order for the rtp engine to handle it correctly. If an * attribute interface is unloaded, this function must be called to notify the rtp_engine. */ -int ast_rtp_engine_unload_format(const struct ast_format *format); +int ast_rtp_engine_unload_format(struct ast_format *format); /*! * \brief Obtain a pointer to the ICE support present on an RTP instance diff --git a/include/asterisk/slin.h b/include/asterisk/slin.h index ab7d843ab..148ee09ab 100644 --- a/include/asterisk/slin.h +++ b/include/asterisk/slin.h @@ -70,7 +70,8 @@ static inline struct ast_frame *slin8_sample(void) .data.ptr = ex_slin8, }; - ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0); + f.subclass.format = ast_format_slin; + return &f; } @@ -86,6 +87,7 @@ static inline struct ast_frame *slin16_sample(void) .data.ptr = ex_slin16, }; - ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0); + f.subclass.format = ast_format_slin16; + return &f; } diff --git a/include/asterisk/slinfactory.h b/include/asterisk/slinfactory.h index 324c0ae28..9a8ceae1e 100644 --- a/include/asterisk/slinfactory.h +++ b/include/asterisk/slinfactory.h @@ -39,8 +39,8 @@ struct ast_slinfactory { short *offset; /*!< Offset into the hold where audio begins */ size_t holdlen; /*!< Number of samples currently in the hold */ unsigned int size; /*!< Number of samples currently in the factory */ - struct ast_format format; /*!< Current format the translation path is converting from */ - struct ast_format output_format; /*!< The output format desired */ + struct ast_format *format; /*!< Current format the translation path is converting from */ + struct ast_format *output_format; /*!< The output format desired */ }; /*! @@ -60,7 +60,7 @@ void ast_slinfactory_init(struct ast_slinfactory *sf); * * \return 0 on success, non-zero on failure */ -int ast_slinfactory_init_with_format(struct ast_slinfactory *sf, const struct ast_format *slin_out); +int ast_slinfactory_init_with_format(struct ast_slinfactory *sf, struct ast_format *slin_out); /*! * \brief Destroy the contents of a slinfactory diff --git a/include/asterisk/smoother.h b/include/asterisk/smoother.h new file mode 100644 index 000000000..e63aa77bd --- /dev/null +++ b/include/asterisk/smoother.h @@ -0,0 +1,89 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 1999 - 2005, Digium, Inc. + * + * Mark Spencer <markster@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Asterisk internal frame definitions. + * \arg For an explanation of frames, see \ref Def_Frame + * \arg Frames are send of Asterisk channels, see \ref Def_Channel + */ + +#ifndef _ASTERISK_SMOOTHER_H +#define _ASTERISK_SMOOTHER_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/endian.h" + +#define AST_SMOOTHER_FLAG_G729 (1 << 0) +#define AST_SMOOTHER_FLAG_BE (1 << 1) + +/*! \name AST_Smoother +*/ +/*@{ */ +/*! \page ast_smooth The AST Frame Smoother +The ast_smoother interface was designed specifically +to take frames of variant sizes and produce frames of a single expected +size, precisely what you want to do. + +The basic interface is: + +- Initialize with ast_smoother_new() +- Queue input frames with ast_smoother_feed() +- Get output frames with ast_smoother_read() +- when you're done, free the structure with ast_smoother_free() +- Also see ast_smoother_test_flag(), ast_smoother_set_flags(), ast_smoother_get_flags(), ast_smoother_reset() +*/ +struct ast_smoother; + +struct ast_frame; + +struct ast_smoother *ast_smoother_new(int bytes); +void ast_smoother_set_flags(struct ast_smoother *smoother, int flags); +int ast_smoother_get_flags(struct ast_smoother *smoother); +int ast_smoother_test_flag(struct ast_smoother *s, int flag); +void ast_smoother_free(struct ast_smoother *s); +void ast_smoother_reset(struct ast_smoother *s, int bytes); + +/*! + * \brief Reconfigure an existing smoother to output a different number of bytes per frame + * \param s the smoother to reconfigure + * \param bytes the desired number of bytes per output frame + * \return nothing + * + */ +void ast_smoother_reconfigure(struct ast_smoother *s, int bytes); + +int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap); +struct ast_frame *ast_smoother_read(struct ast_smoother *s); +#define ast_smoother_feed(s,f) __ast_smoother_feed(s, f, 0) +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 1) +#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 0) +#else +#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 0) +#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 1) +#endif +/*@} Doxygen marker */ + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_SMOOTHER_H */ diff --git a/include/asterisk/speech.h b/include/asterisk/speech.h index a914f4846..0da6f5cfc 100644 --- a/include/asterisk/speech.h +++ b/include/asterisk/speech.h @@ -58,7 +58,7 @@ struct ast_speech { /*! Current state of structure */ int state; /*! Expected write format */ - struct ast_format format; + struct ast_format *format; /*! Data for speech engine */ void *data; /*! Cached results */ diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h index 602c3097c..e8e4c02d2 100644 --- a/include/asterisk/translate.h +++ b/include/asterisk/translate.h @@ -32,6 +32,8 @@ extern "C" { #include "asterisk/frame.h" #include "asterisk/plc.h" #include "asterisk/linkedlists.h" +#include "asterisk/format_cap.h" +#include "asterisk/format_cache.h" #endif struct ast_trans_pvt; /* declared below */ @@ -134,8 +136,11 @@ enum ast_trans_cost_table { */ struct ast_translator { char name[80]; /*!< Name of translator */ - struct ast_format src_format; /*!< Source format */ - struct ast_format dst_format; /*!< Destination format */ + struct ast_codec src_codec; /*!< Source codec */ + struct ast_codec dst_codec; /*!< Destination codec */ + struct ast_codec *core_src_codec; /*!< Core registered source codec */ + struct ast_codec *core_dst_codec; /*!< Core registered destination codec */ + const char *format; /*!< Optional name of a cached format this translator produces */ int table_cost; /*!< Cost value associated with this translator based * on translation cost table. */ @@ -204,12 +209,6 @@ struct ast_translator { struct ast_trans_pvt { struct ast_translator *t; struct ast_frame f; /*!< used in frameout */ - /*! If a translation path using a format with attributes requires the output - * to be a specific set of attributes, this variable will be set describing those - * attributes to the translator. Otherwise, the translator must choose a set - * of format attributes for the destination that preserves the quality of the - * audio in the best way possible. */ - struct ast_format explicit_dst; int samples; /*!< samples available in outbuf */ /*! \brief actual space used in outbuf */ int datalen; @@ -286,8 +285,8 @@ void ast_translator_deactivate(struct ast_translator *t); */ int ast_translator_best_choice(struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, - struct ast_format *dst_fmt_out, - struct ast_format *src_fmt_out); + struct ast_format **dst_fmt_out, + struct ast_format **src_fmt_out); /*! * \brief Builds a translator path diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h index 0a2c6c965..0053d8a32 100644 --- a/include/asterisk/vector.h +++ b/include/asterisk/vector.h @@ -61,7 +61,7 @@ #define AST_VECTOR_INIT(vec, size) ({ \ size_t __size = (size); \ size_t alloc_size = __size * sizeof(*((vec)->elems)); \ - (vec)->elems = alloc_size ? ast_malloc(alloc_size) : NULL; \ + (vec)->elems = alloc_size ? ast_calloc(1, alloc_size) : NULL; \ (vec)->current = 0; \ if ((vec)->elems) { \ (vec)->max = __size; \ @@ -116,6 +116,48 @@ }) /*! + * \brief Insert an element at a specific position in a vector, growing the vector if needed. + * + * \param vec Vector to insert into. + * \param idx Position to insert at. + * \param elem Element to insert. + * + * \return 0 on success. + * \return Non-zero on failure. + * + * \warning This macro will overwrite anything already present at the position provided. + * + * \warning Use of this macro with the expectation that the element will remain at the provided + * index means you can not use the UNORDERED assortment of macros. These macros alter the ordering + * of the vector itself. + */ +#define AST_VECTOR_INSERT(vec, idx, elem) ({ \ + int res = 0; \ + do { \ + if (((idx) + 1) > (vec)->max) { \ + size_t new_max = ((idx) + 1) * 2; \ + typeof((vec)->elems) new_elems = ast_calloc(1, \ + new_max * sizeof(*new_elems)); \ + if (new_elems) { \ + memcpy(new_elems, (vec)->elems, \ + (vec)->current * sizeof(*new_elems)); \ + ast_free((vec)->elems); \ + (vec)->elems = new_elems; \ + (vec)->max = new_max; \ + } else { \ + res = -1; \ + break; \ + } \ + } \ + (vec)->elems[(idx)] = (elem); \ + if (((idx) + 1) > (vec)->current) { \ + (vec)->current = (idx) + 1; \ + } \ + } while(0); \ + res; \ +}) + +/*! * \brief Remove an element from a vector by index. * * Note that elements in the vector may be reordered, so that the remove can @@ -134,6 +176,25 @@ res; \ }) +/*! + * \brief Remove an element from a vector by index while maintaining order. + * + * \param vec Vector to remove from. + * \param idx Index of the element to remove. + * \return The element that was removed. + */ +#define AST_VECTOR_REMOVE_ORDERED(vec, idx) ({ \ + typeof((vec)->elems[0]) res; \ + size_t __idx = (idx); \ + size_t __move; \ + ast_assert(__idx < (vec)->current); \ + res = (vec)->elems[__idx]; \ + __move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \ + memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \ + (vec)->current--; \ + res; \ +}) + /*! * \brief Remove an element from a vector that matches the given comparison @@ -162,6 +223,32 @@ }) /*! + * \brief Remove an element from a vector that matches the given comparison while maintaining order + * + * \param vec Vector to remove from. + * \param value Value to pass into comparator. + * \param cmp Comparator function/macros (called as \c cmp(elem, value)) + * \param cleanup How to cleanup a removed element macro/function. + * + * \return 0 if element was removed. + * \return Non-zero if element was not in the vector. + */ +#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup) ({ \ + int res = -1; \ + size_t idx; \ + typeof(value) __value = (value); \ + for (idx = 0; idx < (vec)->current; ++idx) { \ + if (cmp((vec)->elems[idx], __value)) { \ + cleanup((vec)->elems[idx]); \ + AST_VECTOR_REMOVE_ORDERED((vec), idx); \ + res = 0; \ + break; \ + } \ + } \ + res; \ +}) + +/*! * \brief Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED() * * \param elem Element to compare against @@ -197,6 +284,21 @@ }) /*! + * \brief Remove an element from a vector while maintaining order. + * + * \param vec Vector to remove from. + * \param elem Element to remove + * \param cleanup How to cleanup a removed element macro/function. + * + * \return 0 if element was removed. + * \return Non-zero if element was not in the vector. + */ +#define AST_VECTOR_REMOVE_ELEM_ORDERED(vec, elem, cleanup) ({ \ + AST_VECTOR_REMOVE_CMP_ORDERED((vec), (elem), \ + AST_VECTOR_ELEM_DEFAULT_CMP, cleanup); \ +}) + +/*! * \brief Get the number of elements in a vector. * * \param vec Vector to query. |