summaryrefslogtreecommitdiff
path: root/include/asterisk
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-07-20 22:06:33 +0000
committerMatthew Jordan <mjordan@digium.com>2014-07-20 22:06:33 +0000
commita2c912e9972c91973ea66902d217746133f96026 (patch)
tree50e01d14ba62950e3f78766d5ba435ba51ca327d /include/asterisk
parentb299052e203807c9a2111eb2cd919246d7589cb3 (diff)
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was fast but had a few limitations. 1. Asterisk was limited in how many formats it could handle. 2. Formats, being a bit field, could not include any attribute information. A format was strictly its type, e.g., "this is ulaw". This was changed in Asterisk 10 (see https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for notes on that work) which led to the creation of the ast_format structure. This structure allowed Asterisk to handle attributes and bundle information with a format. Additionally, ast_format_cap was created to act as a container for multiple formats that, together, formed the capability of some entity. Another mechanism was added to allow logic to be registered which performed format attribute negotiation. Everywhere throughout the codebase Asterisk was changed to use this strategy. Unfortunately, in software, there is no free lunch. These new capabilities came at a cost. Performance analysis and profiling showed that we spend an inordinate amount of time comparing, copying, and generally manipulating formats and their related structures. Basic prototyping has shown that a reasonably large performance improvement could be made in this area. This patch is the result of that project, which overhauled the media format architecture and its usage in Asterisk to improve performance. Generally, the new philosophy for handling formats is as follows: * The ast_format structure is reference counted. This removed a large amount of the memory allocations and copying that was done in prior versions. * In order to prevent race conditions while keeping things performant, the ast_format structure is immutable by convention and lock-free. Violate this tenet at your peril! * Because formats are reference counted, codecs are also reference counted. The Asterisk core generally provides built-in codecs and caches the ast_format structures created to represent them. Generally, to prevent inordinate amounts of module reference bumping, codecs and formats can be added at run-time but cannot be removed. * All compatibility with the bit field representation of codecs/formats has been moved to a compatibility API. The primary user of this representation is chan_iax2, which must continue to maintain its bit-field usage of formats for interoperability concerns. * When a format is negotiated with attributes, or when a format cannot be represented by one of the cached formats, a new format object is created or cloned from an existing format. That format may have the same codec underlying it, but is a different format than a version of the format with different attributes or without attributes. * While formats are reference counted objects, the reference count maintained on the format should be manipulated with care. Formats are generally cached and will persist for the lifetime of Asterisk and do not explicitly need to have their lifetime modified. An exception to this is when the user of a format does not know where the format came from *and* the user may outlive the provider of the format. This occurs, for example, when a format is read from a channel: the channel may have a format with attributes (hence, non-cached) and the user of the format may last longer than the channel (if the reference to the channel is released prior to the format's reference). For more information on this work, see the API design notes: https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite Finally, this work was the culmination of a large number of developer's efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the work in the Asterisk core, chan_sip, and was an invaluable resource in peer reviews throughout this project. There were a substantial number of patches contributed during this work; the following issues/patch names simply reflect some of the work (and will cause the release scripts to give attribution to the individuals who work on them). Reviews: https://reviewboard.asterisk.org/r/3814 https://reviewboard.asterisk.org/r/3808 https://reviewboard.asterisk.org/r/3805 https://reviewboard.asterisk.org/r/3803 https://reviewboard.asterisk.org/r/3801 https://reviewboard.asterisk.org/r/3798 https://reviewboard.asterisk.org/r/3800 https://reviewboard.asterisk.org/r/3794 https://reviewboard.asterisk.org/r/3793 https://reviewboard.asterisk.org/r/3792 https://reviewboard.asterisk.org/r/3791 https://reviewboard.asterisk.org/r/3790 https://reviewboard.asterisk.org/r/3789 https://reviewboard.asterisk.org/r/3788 https://reviewboard.asterisk.org/r/3787 https://reviewboard.asterisk.org/r/3786 https://reviewboard.asterisk.org/r/3784 https://reviewboard.asterisk.org/r/3783 https://reviewboard.asterisk.org/r/3778 https://reviewboard.asterisk.org/r/3774 https://reviewboard.asterisk.org/r/3775 https://reviewboard.asterisk.org/r/3772 https://reviewboard.asterisk.org/r/3761 https://reviewboard.asterisk.org/r/3754 https://reviewboard.asterisk.org/r/3753 https://reviewboard.asterisk.org/r/3751 https://reviewboard.asterisk.org/r/3750 https://reviewboard.asterisk.org/r/3748 https://reviewboard.asterisk.org/r/3747 https://reviewboard.asterisk.org/r/3746 https://reviewboard.asterisk.org/r/3742 https://reviewboard.asterisk.org/r/3740 https://reviewboard.asterisk.org/r/3739 https://reviewboard.asterisk.org/r/3738 https://reviewboard.asterisk.org/r/3737 https://reviewboard.asterisk.org/r/3736 https://reviewboard.asterisk.org/r/3734 https://reviewboard.asterisk.org/r/3722 https://reviewboard.asterisk.org/r/3713 https://reviewboard.asterisk.org/r/3703 https://reviewboard.asterisk.org/r/3689 https://reviewboard.asterisk.org/r/3687 https://reviewboard.asterisk.org/r/3674 https://reviewboard.asterisk.org/r/3671 https://reviewboard.asterisk.org/r/3667 https://reviewboard.asterisk.org/r/3665 https://reviewboard.asterisk.org/r/3625 https://reviewboard.asterisk.org/r/3602 https://reviewboard.asterisk.org/r/3519 https://reviewboard.asterisk.org/r/3518 https://reviewboard.asterisk.org/r/3516 https://reviewboard.asterisk.org/r/3515 https://reviewboard.asterisk.org/r/3512 https://reviewboard.asterisk.org/r/3506 https://reviewboard.asterisk.org/r/3413 https://reviewboard.asterisk.org/r/3410 https://reviewboard.asterisk.org/r/3387 https://reviewboard.asterisk.org/r/3388 https://reviewboard.asterisk.org/r/3389 https://reviewboard.asterisk.org/r/3390 https://reviewboard.asterisk.org/r/3321 https://reviewboard.asterisk.org/r/3320 https://reviewboard.asterisk.org/r/3319 https://reviewboard.asterisk.org/r/3318 https://reviewboard.asterisk.org/r/3266 https://reviewboard.asterisk.org/r/3265 https://reviewboard.asterisk.org/r/3234 https://reviewboard.asterisk.org/r/3178 ASTERISK-23114 #close Reported by: mjordan media_formats_translation_core.diff uploaded by kharwell (License 6464) rb3506.diff uploaded by mjordan (License 6283) media_format_app_file.diff uploaded by kharwell (License 6464) misc-2.diff uploaded by file (License 5000) chan_mild-3.diff uploaded by file (License 5000) chan_obscure.diff uploaded by file (License 5000) jingle.diff uploaded by file (License 5000) funcs.diff uploaded by file (License 5000) formats.diff uploaded by file (License 5000) core.diff uploaded by file (License 5000) bridges.diff uploaded by file (License 5000) mf-codecs-2.diff uploaded by file (License 5000) mf-app_fax.diff uploaded by file (License 5000) mf-apps-3.diff uploaded by file (License 5000) media-formats-3.diff uploaded by file (License 5000) ASTERISK-23715 rb3713.patch uploaded by coreyfarrell (License 5909) rb3689.patch uploaded by mjordan (License 6283) ASTERISK-23957 rb3722.patch uploaded by mjordan (License 6283) mf-attributes-3.diff uploaded by file (License 5000) ASTERISK-23958 Tested by: jrose rb3822.patch uploaded by coreyfarrell (License 5909) rb3800.patch uploaded by jrose (License 6182) chan_sip.diff uploaded by mjordan (License 6283) rb3747.patch uploaded by jrose (License 6182) ASTERISK-23959 #close Tested by: sgriepentrog, mjordan, coreyfarrell sip_cleanup.diff uploaded by opticron (License 6273) chan_sip_caps.diff uploaded by mjordan (License 6283) rb3751.patch uploaded by coreyfarrell (License 5909) chan_sip-3.diff uploaded by file (License 5000) ASTERISK-23960 #close Tested by: opticron direct_media.diff uploaded by opticron (License 6273) pjsip-direct-media.diff uploaded by file (License 5000) format_cap_remove.diff uploaded by opticron (License 6273) media_format_fixes.diff uploaded by opticron (License 6273) chan_pjsip-2.diff uploaded by file (License 5000) ASTERISK-23966 #close Tested by: rmudgett rb3803.patch uploaded by rmudgetti (License 5621) chan_dahdi.diff uploaded by file (License 5000) ASTERISK-24064 #close Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose rb3814.patch uploaded by rmudgett (License 5621) moh_cleanup.diff uploaded by opticron (License 6273) bridge_leak.diff uploaded by opticron (License 6273) translate.diff uploaded by file (License 5000) rb3795.patch uploaded by rmudgett (License 5621) tls_fix.diff uploaded by mjordan (License 6283) fax-mf-fix-2.diff uploaded by file (License 5000) rtp_transfer_stuff uploaded by mjordan (License 6283) rb3787.patch uploaded by rmudgett (License 5621) media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) format_cache_case_fix.diff uploaded by opticron (License 6273) rb3774.patch uploaded by rmudgett (License 5621) rb3775.patch uploaded by rmudgett (License 5621) rtp_engine_fix.diff uploaded by opticron (License 6273) rtp_crash_fix.diff uploaded by opticron (License 6273) rb3753.patch uploaded by mjordan (License 6283) rb3750.patch uploaded by mjordan (License 6283) rb3748.patch uploaded by rmudgett (License 5621) media_format_fixes.diff uploaded by opticron (License 6273) rb3740.patch uploaded by mjordan (License 6283) rb3739.patch uploaded by mjordan (License 6283) rb3734.patch uploaded by mjordan (License 6283) rb3689.patch uploaded by mjordan (License 6283) rb3674.patch uploaded by coreyfarrell (License 5909) rb3671.patch uploaded by coreyfarrell (License 5909) rb3667.patch uploaded by coreyfarrell (License 5909) rb3665.patch uploaded by mjordan (License 6283) rb3625.patch uploaded by coreyfarrell (License 5909) rb3602.patch uploaded by coreyfarrell (License 5909) format_compatibility-2.diff uploaded by file (License 5000) core.diff uploaded by file (License 5000) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk')
-rw-r--r--include/asterisk/_private.h10
-rw-r--r--include/asterisk/abstract_jb.h2
-rw-r--r--include/asterisk/audiohook.h2
-rw-r--r--include/asterisk/bridge_channel.h4
-rw-r--r--include/asterisk/callerid.h4
-rw-r--r--include/asterisk/channel.h34
-rw-r--r--include/asterisk/codec.h186
-rw-r--r--include/asterisk/config_options.h9
-rw-r--r--include/asterisk/data.h1
-rw-r--r--include/asterisk/file.h2
-rw-r--r--include/asterisk/format.h553
-rw-r--r--include/asterisk/format_cache.h301
-rw-r--r--include/asterisk/format_cap.h377
-rw-r--r--include/asterisk/format_compatibility.h129
-rw-r--r--include/asterisk/format_pref.h117
-rw-r--r--include/asterisk/frame.h80
-rw-r--r--include/asterisk/image.h2
-rw-r--r--include/asterisk/mod_format.h10
-rw-r--r--include/asterisk/res_pjsip.h2
-rw-r--r--include/asterisk/res_pjsip_session.h2
-rw-r--r--include/asterisk/rtp_engine.h127
-rw-r--r--include/asterisk/slin.h6
-rw-r--r--include/asterisk/slinfactory.h6
-rw-r--r--include/asterisk/smoother.h89
-rw-r--r--include/asterisk/speech.h2
-rw-r--r--include/asterisk/translate.h19
-rw-r--r--include/asterisk/vector.h104
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.