diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/abstract_jb.h | 4 | ||||
-rw-r--r-- | include/asterisk/astobj2.h | 28 | ||||
-rw-r--r-- | include/asterisk/audiohook.h | 5 | ||||
-rw-r--r-- | include/asterisk/bridging.h | 4 | ||||
-rw-r--r-- | include/asterisk/bridging_technology.h | 7 | ||||
-rw-r--r-- | include/asterisk/callerid.h | 20 | ||||
-rw-r--r-- | include/asterisk/channel.h | 86 | ||||
-rw-r--r-- | include/asterisk/data.h | 12 | ||||
-rw-r--r-- | include/asterisk/file.h | 3 | ||||
-rw-r--r-- | include/asterisk/format.h | 310 | ||||
-rw-r--r-- | include/asterisk/format_cap.h | 273 | ||||
-rw-r--r-- | include/asterisk/format_pref.h | 114 | ||||
-rw-r--r-- | include/asterisk/frame.h | 184 | ||||
-rw-r--r-- | include/asterisk/frame_defs.h | 38 | ||||
-rw-r--r-- | include/asterisk/image.h | 6 | ||||
-rw-r--r-- | include/asterisk/mod_format.h | 18 | ||||
-rw-r--r-- | include/asterisk/pbx.h | 6 | ||||
-rw-r--r-- | include/asterisk/rtp_engine.h | 89 | ||||
-rw-r--r-- | include/asterisk/slin.h | 4 | ||||
-rw-r--r-- | include/asterisk/slinfactory.h | 6 | ||||
-rw-r--r-- | include/asterisk/speech.h | 8 | ||||
-rw-r--r-- | include/asterisk/translate.h | 121 |
22 files changed, 1011 insertions, 335 deletions
diff --git a/include/asterisk/abstract_jb.h b/include/asterisk/abstract_jb.h index 4efa924b8..d51554b66 100644 --- a/include/asterisk/abstract_jb.h +++ b/include/asterisk/abstract_jb.h @@ -32,7 +32,7 @@ #include <sys/time.h> -#include "asterisk/frame_defs.h" +#include "asterisk/format.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -97,7 +97,7 @@ struct ast_jb /*! \brief The time the next frame should be played. */ long next; /*! \brief Voice format of the last frame in. */ - format_t 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/astobj2.h b/include/asterisk/astobj2.h index ff35599ca..bf8dd42ba 100644 --- a/include/asterisk/astobj2.h +++ b/include/asterisk/astobj2.h @@ -771,18 +771,20 @@ int ao2_container_count(struct ao2_container *c); */ #ifdef REF_DEBUG -#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_link(arg1, arg2) __ao2_link_debug((arg1), (arg2), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_link(arg1, arg2) __ao2_link_debug((arg1), (arg2), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_link_nolock(arg1, arg2) __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #else -#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2)) -#define ao2_link(arg1, arg2) __ao2_link((arg1), (arg2)) +#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2), 0) +#define ao2_link(arg1, arg2) __ao2_link((arg1), (arg2), 0) +#define ao2_link_nolock(arg1, arg2) __ao2_link((arg1), (arg2), OBJ_NOLOCK) #endif -void *__ao2_link_debug(struct ao2_container *c, void *new_obj, char *tag, char *file, int line, const char *funcname); -void *__ao2_link(struct ao2_container *c, void *newobj); +void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, char *tag, char *file, int line, const char *funcname); +void *__ao2_link(struct ao2_container *c, void *newobj, int flags); /*! * \brief Remove an object from a container @@ -803,18 +805,20 @@ void *__ao2_link(struct ao2_container *c, void *newobj); */ #ifdef REF_DEBUG -#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_unlink(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_unlink(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_unlink_nolock(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #else -#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2)) -#define ao2_unlink(arg1, arg2) __ao2_unlink((arg1), (arg2)) +#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2), 0) +#define ao2_unlink(arg1, arg2) __ao2_unlink((arg1), (arg2), 0) +#define ao2_unlink_nolock(arg1, arg2) __ao2_unlink((arg1), (arg2), OBJ_NOLOCK) #endif -void *__ao2_unlink_debug(struct ao2_container *c, void *obj, char *tag, char *file, int line, const char *funcname); -void *__ao2_unlink(struct ao2_container *c, void *obj); +void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, char *tag, char *file, int line, const char *funcname); +void *__ao2_unlink(struct ao2_container *c, void *obj, int flags); /*@} */ diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h index abf6ca345..75e2c8763 100644 --- a/include/asterisk/audiohook.h +++ b/include/asterisk/audiohook.h @@ -30,7 +30,6 @@ extern "C" { /* these two are used in struct ast_audiohook */ #include "asterisk/lock.h" #include "asterisk/linkedlists.h" -#include "asterisk/frame_defs.h" #include "asterisk/slinfactory.h" enum ast_audiohook_type { @@ -104,7 +103,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 */ - int 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 */ @@ -142,7 +141,7 @@ int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohoo * \param format Format of frame remote side wants back * \return Returns frame on success, NULL on failure */ -struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format); +struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format); /*! \brief Attach audiohook to channel * \param chan Channel diff --git a/include/asterisk/bridging.h b/include/asterisk/bridging.h index 3e3476002..810bc3705 100644 --- a/include/asterisk/bridging.h +++ b/include/asterisk/bridging.h @@ -193,7 +193,7 @@ struct ast_bridge { * This creates a simple two party bridge that will be destroyed once one of * the channels hangs up. */ -struct ast_bridge *ast_bridge_new(format_t capabilities, int flags); +struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags); /*! \brief See if it is possible to create a bridge * @@ -211,7 +211,7 @@ struct ast_bridge *ast_bridge_new(format_t capabilities, int flags); * This sees if it is possible to create a bridge capable of bridging two channels * together. */ -int ast_bridge_check(format_t capabilities); +int ast_bridge_check(uint32_t capabilities); /*! \brief Destroy a bridge * diff --git a/include/asterisk/bridging_technology.h b/include/asterisk/bridging_technology.h index 0659abd77..c3e22975c 100644 --- a/include/asterisk/bridging_technology.h +++ b/include/asterisk/bridging_technology.h @@ -44,8 +44,9 @@ enum ast_bridge_preference { struct ast_bridge_technology { /*! Unique name to this bridge technology */ const char *name; - /*! The capabilities that this bridge technology is capable of */ - format_t capabilities; + /*! The capabilities that this bridge technology is capable of. This has nothing to do with + * format capabilities. */ + uint32_t capabilities; /*! Preference level that should be used when determining whether to use this bridge technology or not */ enum ast_bridge_preference preference; /*! Callback for when a bridge is being created */ @@ -71,7 +72,7 @@ struct ast_bridge_technology { /*! Callback for poking a bridge thread */ int (*poke)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); /*! Formats that the bridge technology supports */ - format_t formats; + struct ast_format_cap *format_capabilities; /*! Bit to indicate whether the bridge technology is currently suspended or not */ unsigned int suspended:1; /*! Module this bridge technology belongs to. Is used for reference counting when creating/destroying a bridge. */ diff --git a/include/asterisk/callerid.h b/include/asterisk/callerid.h index e052f6478..c047632b9 100644 --- a/include/asterisk/callerid.h +++ b/include/asterisk/callerid.h @@ -45,7 +45,7 @@ #ifndef _ASTERISK_CALLERID_H #define _ASTERISK_CALLERID_H -#include "asterisk/frame_defs.h" +#include "asterisk/format.h" #define MAX_CALLERID_SIZE 32000 @@ -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 == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a))) -#define AST_XLAW(a) ((codec == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a))) +#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))) struct callerid_state; @@ -101,7 +101,7 @@ void callerid_init(void); * \return It returns the size * (in bytes) of the data (if it returns a size of 0, there is probably an error) */ -int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, format_t codec); +int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec); /*! \brief Create a callerID state machine * \param cid_signalling Type of signalling in use @@ -124,7 +124,7 @@ struct callerid_state *callerid_new(int cid_signalling); * \retval 0 for "needs more samples" * \retval 1 if the CallerID spill reception is complete. */ -int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec); +int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec); /*! \brief Read samples into the state machine. * \param cid Which state machine to act upon @@ -138,7 +138,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, * \retval 0 for "needs more samples" * \retval 1 if the CallerID spill reception is complete. */ -int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec); +int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec); /*! \brief Extract info out of callerID state machine. Flags are listed above * \param cid Callerid state machine to act upon @@ -177,7 +177,7 @@ void callerid_free(struct callerid_state *cid); * \details * Acts like callerid_generate except uses an asterisk format callerid string. */ -int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, format_t codec); +int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec); /*! * \brief Generate message waiting indicator @@ -192,13 +192,13 @@ int ast_callerid_generate(unsigned char *buf, const char *name, const char *numb * \see callerid_generate() for more info as it uses the same encoding * \version 1.6.1 changed mdmf parameter to type, added name, number and flags for caller id message generation */ -int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_t codec, const char *name, +int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec, const char *name, const char *number, int flags); /*! \brief Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm) * \see ast_callerid_generate() for other details */ -int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, format_t codec); +int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec); /*! \brief Destructively parse inbuf into name and location (or number) * \details @@ -223,7 +223,7 @@ int ast_callerid_parse(char *instr, char **name, char **location); * \param codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW) * \return Returns -1 on error (if len is less than 2400), 0 on success. */ -int ast_gen_cas(unsigned char *outbuf, int sas, int len, format_t codec); +int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec); /*! * \brief Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s... diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index c9156daf1..f58ffc767 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -507,12 +507,12 @@ struct ast_channel_tech { const char * const type; const char * const description; - format_t capabilities; /*!< Bitmap of formats this channel can handle */ + struct ast_format_cap *capabilities; /*!< format capabilities this channel can handle */ int properties; /*!< Technology Properties */ /*! \brief Requester - to set up call data structures (pvt's) */ - struct ast_channel *(* const requester)(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause); + struct ast_channel *(* const requester)(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause); int (* const devicestate)(void *data); /*!< Devicestate call back */ @@ -824,7 +824,7 @@ struct ast_channel { int fdno; /*!< Which fd had an event detected on */ int streamid; /*!< For streaming playback, the schedule ID */ int vstreamid; /*!< For streaming video playback, the schedule ID */ - format_t oldwriteformat; /*!< Original writer format */ + struct ast_format oldwriteformat; /*!< Original writer format */ int timingfd; /*!< Timing fd */ enum ast_channel_state _state; /*!< State of line -- Don't write directly, use ast_setstate() */ int rings; /*!< Number of rings so far */ @@ -839,11 +839,11 @@ struct ast_channel { int hangupcause; /*!< Why is the channel hanged up. See causes.h */ unsigned int flags; /*!< channel flags of AST_FLAG_ type */ int alertpipe[2]; - format_t nativeformats; /*!< Kinds of data this channel can natively handle */ - format_t readformat; /*!< Requested read format (after translation) */ - format_t writeformat; /*!< Requested write format (after translation) */ - format_t rawreadformat; /*!< Raw read format (before translation) */ - format_t rawwriteformat; /*!< Raw write format (before translation) */ + struct ast_format_cap *nativeformats; /*!< Kinds of data this channel can natively handle */ + struct ast_format readformat; /*!< Requested read format (after translation) */ + struct ast_format writeformat; /*!< Requested write format (after translation) */ + struct ast_format rawreadformat; /*!< Raw read format (before translation) */ + struct ast_format rawwriteformat; /*!< Raw write format (before translation) */ unsigned int emulate_dtmf_duration; /*!< Number of ms left to emulate DTMF for */ #ifdef HAVE_EPOLL int epfd; @@ -1252,7 +1252,7 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan); * \brief Requests a channel * * \param type type of channel to request - * \param format requested channel format (codec) + * \param format capabilities for requested channel * \param requestor channel asking for data * \param data data to pass to the channel requester * \param status status @@ -1264,14 +1264,14 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan); * \retval NULL failure * \retval non-NULL channel on success */ -struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status); +struct ast_channel *ast_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *status); /*! * \brief Request a channel of a given type, with data as optional information used * by the low level module and attempt to place a call on it * * \param type type of channel to request - * \param format requested channel format + * \param format capabilities for requested channel * \param requestor channel asking for data * \param data data to pass to the channel requester * \param timeout maximum amount of time to wait for an answer @@ -1282,14 +1282,14 @@ struct ast_channel *ast_request(const char *type, format_t format, const struct * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state * to know if the call was answered or not. */ -struct ast_channel *ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, +struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name); /*! * \brief Request a channel of a given type, with data as optional information used * by the low level module and attempt to place a call on it * \param type type of channel to request - * \param format requested channel format + * \param format capabilities for requested channel * \param requestor channel requesting data * \param data data to pass to the channel requester * \param timeout maximum amount of time to wait for an answer @@ -1300,7 +1300,7 @@ struct ast_channel *ast_request_and_dial(const char *type, format_t format, cons * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state * to know if the call was answered or not. */ -struct ast_channel *__ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, +struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh); /*! @@ -1308,12 +1308,12 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co * \param caller in channel that requested orig * \param orig channel being replaced by the call forward channel * \param timeout maximum amount of time to wait for setup of new forward channel - * \param format requested channel format + * \param format capabilities for requested channel * \param oh outgoing helper used with original channel * \param outstate reason why unsuccessful (if uncuccessful) * \return Returns the forwarded call's ast_channel on success or NULL on failure */ -struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate); +struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate); /*! * \brief Register a channel technology (a new channel driver) @@ -1743,22 +1743,54 @@ int ast_write_text(struct ast_channel *chan, struct ast_frame *frame); int ast_prod(struct ast_channel *chan); /*! - * \brief Sets read format on channel chan + * \brief Sets read format on channel chan from capabilities * Set read format for channel to whichever component of "format" is best. * \param chan channel to change - * \param format format to change to + * \param formats new formats to pick from for reading + * \return Returns 0 on success, -1 on failure + */ +int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats); + +/*! + * \brief Sets read format on channel chan + * \param chan channel to change + * \param formats, format to set for reading * \return Returns 0 on success, -1 on failure */ -int ast_set_read_format(struct ast_channel *chan, format_t format); +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 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 - * \param format new format for writing + * \param formats new formats to pick from for writing * \return Returns 0 on success, -1 on failure */ -int ast_set_write_format(struct ast_channel *chan, format_t format); +int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats); + +/*! + * \brief Sets write format on channel chan + * \param chan channel to change + * \param formats, format to set for writing + * \return Returns 0 on success, -1 on failure + */ +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 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 @@ -2023,9 +2055,15 @@ char *ast_transfercapability2str(int transfercapability) attribute_const; */ int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block); -/*! Pick the best codec - * Choose the best codec... Uhhh... Yah. */ -format_t ast_best_codec(format_t fmts); +/*! + * \brief Pick the best codec + * + * \param 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); /*! diff --git a/include/asterisk/data.h b/include/asterisk/data.h index 6851bd511..e3253377e 100644 --- a/include/asterisk/data.h +++ b/include/asterisk/data.h @@ -800,6 +800,16 @@ static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, con } /*! + * \brief Add the codec in the root node based on the format parameter. + * \param[in] root The astdata root node where to add the codec node. + * \param[in] node_name The name of the node where we are going to add the codec. + * \param[in] format The codec allowed. + * \return < 0 on error. + * \return 0 on success. + */ +int ast_data_add_codec(struct ast_data *root, const char *node_name, struct ast_format *format); + +/*! * \brief Add the list of codecs in the root node based on the capability parameter. * \param[in] root The astdata root node where to add the codecs node. * \param[in] node_name The name of the node where we are going to add the list of @@ -808,7 +818,7 @@ static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, con * \return < 0 on error. * \return 0 on success. */ -int ast_data_add_codecs(struct ast_data *root, const char *node_name, format_t capability); +int ast_data_add_codecs(struct ast_data *root, const char *node_name, struct ast_format_cap *capability); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/include/asterisk/file.h b/include/asterisk/file.h index 69de81165..4b0325101 100644 --- a/include/asterisk/file.h +++ b/include/asterisk/file.h @@ -90,7 +90,8 @@ int ast_stopstream(struct ast_channel *c); * \param fmt the format you wish to check (the extension) * \param preflang (the preferred language you wisht to find the file in) * See if a given file exists in a given format. If fmt is NULL, any format is accepted. - * \return 0 if file does not exist, non-zero positive otherwise. + * \retval 0, false. The file does not exist + * \retval 1, true. The file does exist. */ int ast_fileexists(const char *filename, const char *fmt, const char *preflang); diff --git a/include/asterisk/format.h b/include/asterisk/format.h new file mode 100644 index 000000000..09212abc8 --- /dev/null +++ b/include/asterisk/format.h @@ -0,0 +1,310 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2010, Digium, Inc. + * + * David Vossel <dvossel@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 API + * + * \author David Vossel <dvossel@digium.com> + */ + +#ifndef _AST_FORMAT_H_ +#define _AST_FORMAT_H_ + +#define AST_FORMAT_ATTR_SIZE 128 + +#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, + /*! Raw 16-bit Signed Linear (8000 Hz) PCM */ + AST_FORMAT_SLINEAR = 7 + AST_FORMAT_TYPE_AUDIO, + /*! LPC10, 180 samples/frame */ + AST_FORMAT_LPC10 = 8 + AST_FORMAT_TYPE_AUDIO, + /*! G.729A audio */ + AST_FORMAT_G729A = 9 + AST_FORMAT_TYPE_AUDIO, + /*! SpeeX Free Compression */ + AST_FORMAT_SPEEX = 10 + AST_FORMAT_TYPE_AUDIO, + /*! iLBC Free Compression */ + AST_FORMAT_ILBC = 11 + AST_FORMAT_TYPE_AUDIO, + /*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */ + AST_FORMAT_G726 = 12 + AST_FORMAT_TYPE_AUDIO, + /*! G.722 */ + AST_FORMAT_G722 = 13 + AST_FORMAT_TYPE_AUDIO, + /*! G.722.1 (also known as Siren7, 32kbps assumed) */ + AST_FORMAT_SIREN7 = 14 + AST_FORMAT_TYPE_AUDIO, + /*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */ + AST_FORMAT_SIREN14 = 15 + AST_FORMAT_TYPE_AUDIO, + /*! Raw 16-bit Signed Linear (16000 Hz) PCM */ + AST_FORMAT_SLINEAR16 = 16 + AST_FORMAT_TYPE_AUDIO, + /*! G.719 (64 kbps assumed) */ + AST_FORMAT_G719 = 17 + AST_FORMAT_TYPE_AUDIO, + /*! SpeeX Wideband (16kHz) Free Compression */ + AST_FORMAT_SPEEX16 = 18 + AST_FORMAT_TYPE_AUDIO, + /*! Raw mu-law data (G.711) */ + AST_FORMAT_TESTLAW = 19 + 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, + + /*! 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 */ + uint8_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; +}; + +enum ast_format_cmp_res { + /*! structure 1 is identical to structure 2. */ + AST_FORMAT_CMP_EQUAL = 0, + /*! structure 1 contains elements not in structure 2. */ + AST_FORMAT_CMP_NOT_EQUAL, + /*! structure 1 is a proper subset of the elements in structure 2.*/ + AST_FORMAT_CMP_SUBSET, +}; + +/*! \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. + * + * \retval ast_format_cmp_res representing the result of comparing fattr1 and fattr2. + */ + enum ast_format_cmp_res (* const format_attr_cmp)(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2); + + /*! \brief Get joint attributes of same format type if they exist. + * + * \retval 0 if joint attributes exist + * \retval -1 if no joint attributes are present + */ + 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); +}; + +/*! + * \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; + * + * \details Example usage. + * ast_format_set(format, AST_FORMAT_ULAW, 0); // no capability attributes are needed for ULAW + * + * 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 function will initialize the ast_format structure. + * + * \return Pointer to ast_format object, same pointer that is passed in + * by the first argument. + */ +struct ast_format *ast_format_set(struct ast_format *format, enum ast_format_id id, int set_attributes, ... ); + +/*! + * \brief After ast_format_set has been used on a function, this function can be used to + * set additional format attributes to the structure. + * + * \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. + */ +struct ast_format *ast_format_append(struct ast_format *format, ... ); + +/*! + * \brief Clears the format stucture. + */ +void ast_format_clear(struct ast_format *format); + +/*! + * \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. + * + * \details Example usage. Is this SILK format capable of 8khz + * is_8khz = ast_format_isset(format, AST_FORMAT_SILK_CAP_RATE, 8000); + * + * \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. + */ +int ast_format_isset(struct ast_format *format, ... ); + +/*! + * \brief Compare ast_formats structures + * + * \retval ast_format_cmp_res representing the result of comparing format1 and format2. + */ +enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2); + +/*! + * \brief Find joint format attributes of two ast_format + * structures containing the same uid and return the intersection in the + * result structure. + * + * retval 0, joint attribute capabilities exist. + * retval -1, no joint attribute capabilities exist. + */ +int ast_format_joint(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result); + +/*! + * \brief copy format src into format dst. + */ +void ast_format_copy(struct ast_format *dst, const struct ast_format *src); + +/*! + * \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. + */ +void ast_format_set_video_mark(struct ast_format *format); + +/*! + * \brief Determine of the marker bit is set or not on this format. + * + * \retval 1, true + * \retval 0, false + */ +int ast_format_get_video_mark(const struct ast_format *format); + +/*! + * \brief ast_format to old bitfield format represenatation + * + * \note This is only to be used for IAX2 compatibility + * + * \retval iax2 representation of ast_format + * \retval 0, if no representation existis for iax2 + */ +uint64_t ast_format_to_old_bitfield(const struct ast_format *format); + +/*! + * \brief ast_format_id to old bitfield format represenatation + * + */ +uint64_t ast_format_id_to_old_bitfield(enum ast_format_id id); + +/*! + * \brief convert old bitfield format to ast_format represenatation + * \note This is only to be used for IAX2 compatibility + * + * \retval on success, pointer to the dst format in the input parameters + * \retval on failure, NULL + */ +struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src); + +/*! + * \brief convert old bitfield format to ast_format_id value + */ +enum ast_format_id ast_format_id_from_old_bitfield(uint64_t src); + +/*! + * \brief register ast_format_attr_interface with core. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface); + +/*! + * \brief unregister format_attr interface with core. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface); + +/*! + * \brief Init the ast_format attribute interface register container. + */ +int ast_format_attr_init(void); + +#endif /* _AST_FORMAT_H */ diff --git a/include/asterisk/format_cap.h b/include/asterisk/format_cap.h new file mode 100644 index 000000000..301ec1471 --- /dev/null +++ b/include/asterisk/format_cap.h @@ -0,0 +1,273 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2010, Digium, Inc. + * + * David Vossel <dvossel@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 Capability API + * + * \author David Vossel <dvossel@digium.com> + */ + +#ifndef _AST_FORMATCAP_H_ +#define _AST_FORMATCAP_H_ + +/*! Capabilities are represented by an opaque structure statically defined in format_capability.c */ +struct ast_format_cap; + +/*! + * \brief Allocate a new ast_format_cap structure. + * + * \note Allocation of this object assumes locking + * is already occuring and that the point of contention + * is above this capabilities structure. For example, + * a tech_pvt object referencing a capabilities structure + * can use this function as long as it always holds the + * tech_pvt lock while accessing its capabilities. + * + * \retval ast_format_cap object on success. + * \retval NULL on failure. + */ +struct ast_format_cap *ast_format_cap_alloc_nolock(void); + +/*! + * \brief Allocate a new ast_format_cap structure with locking + * + * \note If no other form of locking is taking place, use this function. + * This function makes most sense for globally accessible capabilities structures + * that have no other means of locking. + * + * \retval ast_format_cap object on success. + * \retval NULL on failure. + */ +struct ast_format_cap *ast_format_cap_alloc(void); + +/*! + * \brief Destroy an ast_format_cap structure. + * + * \return NULL + */ +void *ast_format_cap_destroy(struct ast_format_cap *cap); + +/*! + * \brief Add format capability to capabilities structure. + * + * \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. + */ +void ast_format_cap_add(struct ast_format_cap *cap, struct ast_format *format); + +/*! + * \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. + */ +void ast_format_cap_add_all_by_type(struct ast_format_cap *cap, enum ast_format_type type); + +/*! + * \brief Add all known formats to the capabilities structure using default format attribute. */ +void ast_format_cap_add_all(struct ast_format_cap *cap); + +/*! + * \brief Append the formats in src to dst + */ +void ast_format_cap_append(struct ast_format_cap *dst, const struct ast_format_cap *src); + +/*! + * \brief Copy all items in src to dst. + * \note any items in dst will be removed before copying + */ +void ast_format_cap_copy(struct ast_format_cap *dst, const struct ast_format_cap *src); + +/*! + * \brief create a deep copy of an ast_format_cap structure + * + * \retval cap on success + * \retval NULL on failure + */ +struct ast_format_cap *ast_format_cap_dup(const struct ast_format_cap *src); + +/*! + * \brief determine if a capabilities structure is empty or not + * + * \retval 1, true is empty + * \retval 0, false, not empty + */ +int ast_format_cap_is_empty(const struct ast_format_cap *cap); + +/*! + * \brief Remove format capability from capability structure. + * + * \Note format must match Exactly to format in ast_format_cap object in order + * to be removed. + * + * \retval 0, remove was successful + * \retval -1, remove failed. Could not find format to remove + */ +int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format); + +/*! + * \brief Remove all format capabilities from capability + * structure for a specific format id. + * + * \Note This will remove _ALL_ formats matching the format id from the + * capabilities structure. + * + * \retval 0, remove was successful + * \retval -1, remove failed. Could not find formats to remove + */ +int ast_format_cap_remove_byid(struct ast_format_cap *cap, enum ast_format_id id); + +/*! + * \brief Remove all formats matching a specific format type. + */ +void ast_format_cap_remove_bytype(struct ast_format_cap *cap, enum ast_format_type type); + +/*! + * \brief Remove all format capabilities from capability structure + */ +void ast_format_cap_remove_all(struct ast_format_cap *cap); + +/*! + * \brief Remove all previous formats and set a single new format. + */ +void ast_format_cap_set(struct ast_format_cap *cap, 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. + */ +int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format); + +/*! + * \brief is cap1 identical to cap2 + * + * 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. + * + * \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. + * + * \retval !NULL success, joint capabilties structure with _NO_ locking enabled. + * \retval NULL failure + */ +struct ast_format_cap *ast_format_cap_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2); + +/*! + * \brief Get joint capability structure, copy into result capabilities structure + * + * \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 Find out if capability structures have any joint capabilities without + * returning those capabilities. + * + * \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 + * + * \retval !NULL success, new capabilities structure with _NO_ locking enabled on the new structure. + * \retval NULL failure + */ +struct ast_format_cap *ast_format_cap_get_type(const struct ast_format_cap *cap, enum ast_format_type ftype); + +/*! + * \brief Find out if the capabilities structure has any formats + * of a specific type. + * + * \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); + +/*! + * \brief ast_format_cap to old bitfield format represenatation + * + * \note This is only to be used for IAX2 compatibility + * + * \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); + +#endif /* _AST_FORMATCAP_H */ diff --git a/include/asterisk/format_pref.h b/include/asterisk/format_pref.h new file mode 100644 index 000000000..73a0bdc45 --- /dev/null +++ b/include/asterisk/format_pref.h @@ -0,0 +1,114 @@ +/* + * 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. */ + char 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 preference structure to get the codec out of + * \param index to retrieve from + * \param retult 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 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 0d8fc0b22..fc7c1a07b 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -31,15 +31,11 @@ extern "C" { #include <sys/time.h> -#include "asterisk/frame_defs.h" +#include "asterisk/format_pref.h" +#include "asterisk/format.h" #include "asterisk/endian.h" #include "asterisk/linkedlists.h" -struct ast_codec_pref { - char order[sizeof(format_t) * 8]; - char framing[sizeof(format_t) * 8]; -}; - /*! * \page Def_Frame AST Multimedia and signalling frames * \section Def_AstFrame What is an ast_frame ? @@ -134,7 +130,7 @@ enum { union ast_frame_subclass { int integer; - format_t codec; + struct ast_format format; }; /*! \brief Data structure associated with a single frame of data @@ -237,78 +233,6 @@ extern struct ast_frame ast_null_frame; /*! Reject link request */ #define AST_HTML_LINKREJECT 20 -/* Data formats for capabilities and frames alike */ -/*! G.723.1 compression */ -#define AST_FORMAT_G723_1 (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_SLINEAR (1ULL << 6) -/*! LPC10, 180 samples/frame */ -#define AST_FORMAT_LPC10 (1ULL << 7) -/*! G.729A audio */ -#define AST_FORMAT_G729A (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_SLINEAR16 (1ULL << 15) -/*! Maximum audio mask */ -#define AST_FORMAT_AUDIO_MASK 0xFFFF0000FFFFULL -/*! JPEG Images */ -#define AST_FORMAT_JPEG (1ULL << 16) -/*! PNG Images */ -#define AST_FORMAT_PNG (1ULL << 17) -/*! H.261 Video */ -#define AST_FORMAT_H261 (1ULL << 18) -/*! H.263 Video */ -#define AST_FORMAT_H263 (1ULL << 19) -/*! H.263+ Video */ -#define AST_FORMAT_H263_PLUS (1ULL << 20) -/*! H.264 Video */ -#define AST_FORMAT_H264 (1ULL << 21) -/*! MPEG4 Video */ -#define AST_FORMAT_MP4_VIDEO (1ULL << 22) -#define AST_FORMAT_VIDEO_MASK ((((1ULL << 25)-1) & ~(AST_FORMAT_AUDIO_MASK)) | 0x7FFF000000000000ULL) -/*! T.140 RED Text format RFC 4103 */ -#define AST_FORMAT_T140RED (1ULL << 26) -/*! T.140 Text format - ITU T.140, RFC 4103 */ -#define AST_FORMAT_T140 (1ULL << 27) -/*! Maximum text mask */ -#define AST_FORMAT_MAX_TEXT (1ULL << 28) -#define AST_FORMAT_TEXT_MASK (((1ULL << 30)-1) & ~(AST_FORMAT_AUDIO_MASK) & ~(AST_FORMAT_VIDEO_MASK)) -/*! G.719 (64 kbps assumed) */ -#define AST_FORMAT_G719 (1ULL << 32) -/*! SpeeX Wideband (16kHz) Free Compression */ -#define AST_FORMAT_SPEEX16 (1ULL << 33) -/*! Raw mu-law data (G.711) */ -#define AST_FORMAT_TESTLAW (1ULL << 47) -/*! Reserved bit - do not use - * \warning We use this bit internally for iteration. Additionally, using this - * bit will severely break the implementation of codec prefs within IAX2, as we - * rely on the equivalence of UTF-8 and ASCII. The codec represented by this - * bit should use the first two-byte encoding of UTF-8, which is not presently - * accounted for. Hence, we reserve this bit as unused. - */ -#define AST_FORMAT_RESERVED (1ULL << 63) - enum ast_control_frame_type { AST_CONTROL_HANGUP = 1, /*!< Other end has hungup */ AST_CONTROL_RING = 2, /*!< Local ring */ @@ -505,7 +429,7 @@ struct ast_option_header { /*! \brief Definition of supported media formats (codecs) */ struct ast_format_list { - format_t bits; /*!< bitmask value */ + enum ast_format_id id; /*!< The format unique id */ char *name; /*!< short name */ int samplespersecond; /*!< Number of samples per second (8000/16000) */ char *desc; /*!< Description */ @@ -573,12 +497,18 @@ 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); /*! \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. */ -char* ast_getformatname(format_t format); +char* ast_getformatname(struct ast_format *format); /*! \brief Get the names of a set of formats * \param buf a buffer for the output string @@ -588,21 +518,22 @@ char* ast_getformatname(format_t 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. */ -char* ast_getformatname_multiple(char *buf, size_t size, format_t format); +char* ast_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *cap); /*! * \brief Gets a format from a name. * \param name string of format - * \return This returns the form of the format in binary on success, 0 on error. + * \param format structure to return the format in. + * \return This returns the format pointer given to it on success and NULL on failure */ -format_t ast_getformatbyname(const char *name); +struct ast_format *ast_getformatbyname(const char *name, struct ast_format *format); /*! \brief Get a name from a format * Gets a name from a format - * \param codec codec number (1,2,4,8,16,etc.) + * \param format to get name of * \return This returns a static string identifying the format on success, 0 on error. */ -char *ast_codec2str(format_t codec); +char *ast_codec2str(struct ast_format *format); /*! \name AST_Smoother */ @@ -654,91 +585,20 @@ const struct ast_format_list *ast_get_format_list_index(int index); const struct ast_format_list *ast_get_format_list(size_t *size); void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix); -/*! \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. - * \arg \ref AudioCodecPref -*/ -format_t ast_codec_pref_index(struct ast_codec_pref *pref, int index); - -/*! \brief Remove audio a codec from a preference list */ -void ast_codec_pref_remove(struct ast_codec_pref *pref, format_t format); - -/*! \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, format_t 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, format_t format, int only_if_existing); - -/*! \brief Select the best audio format according to preference list from supplied options. - If "find_best" is non-zero then if nothing is found, the "Best" format of - the format list is selected, otherwise 0 is returned. */ -format_t ast_codec_choose(struct ast_codec_pref *pref, format_t formats, int find_best); - -/*! \brief Set packet size for codec -*/ -int ast_codec_pref_setsize(struct ast_codec_pref *pref, format_t format, int framems); - -/*! \brief Get packet size for codec -*/ -struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, format_t format); - -/*! \brief Parse an "allow" or "deny" line in a channel or device configuration - and update the capabilities mask 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, format_t *mask, const char *list, int allowing); - -/*! \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); - /*! \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(format_t format, int samples); +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(format_t format) +static inline int ast_codec_interp_len(struct ast_format *format) { - return (format == AST_FORMAT_ILBC) ? 30 : 20; + return (format->id == AST_FORMAT_ILBC) ? 30 : 20; } /*! @@ -763,9 +623,9 @@ int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2); /*! * \brief Get the sample rate for a given format. */ -static force_inline int ast_format_rate(format_t format) +static force_inline int ast_format_rate(struct ast_format *format) { - switch (format) { + switch (format->id) { case AST_FORMAT_G722: case AST_FORMAT_SLINEAR16: case AST_FORMAT_SIREN7: diff --git a/include/asterisk/frame_defs.h b/include/asterisk/frame_defs.h index 829572d19..e69de29bb 100644 --- a/include/asterisk/frame_defs.h +++ b/include/asterisk/frame_defs.h @@ -1,38 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 1999 - 2009, 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_FRAME_DEFS_H -#define _ASTERISK_FRAME_DEFS_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -typedef int64_t format_t; - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_FRAME_DEFS_H */ diff --git a/include/asterisk/image.h b/include/asterisk/image.h index a3e2e015e..302f09e85 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 '|' ) */ - int 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 */ @@ -57,12 +57,12 @@ int ast_send_image(struct ast_channel *chan, const char *filename); * \brief Make an image * \param filename filename of image to prepare * \param preflang preferred language to get the image...? - * \param format the format of the file + * \param format the format of the file, NULL for any image format * Make an image from a filename ??? No estoy positivo * \retval an ast_frame on success * \retval NULL on failure */ -struct ast_frame *ast_read_image(const char *filename, const char *preflang, int format); +struct ast_frame *ast_read_image(const char *filename, const char *preflang, struct ast_format *format); /*! * \brief Register image format diff --git a/include/asterisk/mod_format.h b/include/asterisk/mod_format.h index 08ee4cc42..ff3ab7bbf 100644 --- a/include/asterisk/mod_format.h +++ b/include/asterisk/mod_format.h @@ -37,14 +37,14 @@ extern "C" { * Not all are necessary, the support routine implement default * values for some of them. * A handler typically fills a structure initializing the desired - * fields, and then calls ast_format_register() with the (readonly) + * fields, and then calls ast_format_def_register() with the (readonly) * structure as an argument. */ -struct ast_format { +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) */ - format_t format; /*!< Format of frames it uses/provides (one only) */ + 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. @@ -76,7 +76,7 @@ struct ast_format { void (*close)(struct ast_filestream *); char * (*getcomment)(struct ast_filestream *); /*!< Retrieve file comment */ - AST_LIST_ENTRY(ast_format) list; /*!< Link */ + AST_LIST_ENTRY(ast_format_def) list; /*!< Link */ /*! * If the handler needs a buffer (for read, typically) @@ -99,7 +99,7 @@ struct ast_format { */ struct ast_filestream { /*! Everybody reserves a block of AST_RESERVED_POINTERS pointers for us */ - struct ast_format *fmt; /* need to write to the lock and usecnt */ + struct ast_format_def *fmt; /* need to write to the lock and usecnt */ int flags; mode_t mode; char *open_filename; @@ -110,7 +110,7 @@ struct ast_filestream { /*! Transparently translate from another format -- just once */ struct ast_trans_pvt *trans; struct ast_tranlator_pvt *tr; - int lastwriteformat; + struct ast_format lastwriteformat; int lasttimeout; struct ast_channel *owner; FILE *f; @@ -127,8 +127,8 @@ struct ast_filestream { * \retval 0 on success * \retval -1 on failure */ -int __ast_format_register(const struct ast_format *f, struct ast_module *mod); -#define ast_format_register(f) __ast_format_register(f, ast_module_info->self) +int __ast_format_def_register(const struct ast_format_def *f, struct ast_module *mod); +#define ast_format_def_register(f) __ast_format_def_register(f, ast_module_info->self) /*! * \brief Unregisters a file format @@ -137,7 +137,7 @@ int __ast_format_register(const struct ast_format *f, struct ast_module *mod); * \retval 0 on success * \retval -1 on failure to unregister */ -int ast_format_unregister(const char *name); +int ast_format_def_unregister(const char *name); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index e80a303f6..429e60537 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -30,7 +30,7 @@ #include "asterisk/hashtab.h" #include "asterisk/stringfields.h" #include "asterisk/xmldoc.h" -#include "asterisk/frame_defs.h" +#include "asterisk/format.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -887,11 +887,11 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex /*! Synchronously or asynchronously make an outbound call and send it to a particular extension */ -int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); +int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); /*! Synchronously or asynchronously make an outbound call and send it to a particular application with given extension */ -int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); +int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel); /*! * \brief Evaluate a condition diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h index cd9179be1..f13538321 100644 --- a/include/asterisk/rtp_engine.h +++ b/include/asterisk/rtp_engine.h @@ -227,8 +227,12 @@ enum ast_rtp_instance_stat { struct ast_rtp_payload_type { /*! Is this an Asterisk value */ int asterisk_format; - /*! Actual internal value of the payload */ - format_t code; + /*! If asterisk_format is set, this is the internal + * asterisk format represented by the payload */ + struct ast_format format; + /*! Actual internal RTP specific value of the payload */ + int rtp_code; + }; /*! Structure that represents statistics from an RTP instance */ @@ -335,8 +339,8 @@ struct ast_rtp_engine { void *(*extended_prop_get)(struct ast_rtp_instance *instance, int property); /*! Callback for setting an RTP property */ void (*prop_set)(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value); - /*! Callback for setting a payload */ - void (*payload_set)(struct ast_rtp_instance *instance, int payload, int astformat, format_t format); + /*! 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 */ @@ -360,9 +364,9 @@ struct ast_rtp_engine { /*! Callback to locally bridge two RTP instances */ int (*local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1); /*! Callback to set the read format */ - int (*set_read_format)(struct ast_rtp_instance *instance, format_t format); + int (*set_read_format)(struct ast_rtp_instance *instance, struct ast_format *format); /*! Callback to set the write format */ - int (*set_write_format)(struct ast_rtp_instance *instance, format_t format); + int (*set_write_format)(struct ast_rtp_instance *instance, struct ast_format *format); /*! Callback to make two instances compatible */ int (*make_compatible)(struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1); /*! Callback to see if two instances are compatible with DTMF */ @@ -371,8 +375,8 @@ struct ast_rtp_engine { int (*activate)(struct ast_rtp_instance *instance); /*! Callback to request that the RTP engine send a STUN BIND request */ void (*stun_request)(struct ast_rtp_instance *instance, struct ast_sockaddr *suggestion, const char *username); - /*! Callback to get the transcodeable formats supported */ - int (*available_formats)(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk); + /*! Callback to get the transcodeable formats supported. result returned in ast_format_cap *result */ + void (*available_formats)(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result); /*! Linked list information */ AST_RWLIST_ENTRY(ast_rtp_engine) entry; }; @@ -407,9 +411,9 @@ struct ast_rtp_glue { */ enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance); /*! Callback for updating the destination that the remote side should send RTP to */ - int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active); - /*! Callback for retrieving codecs that the channel can do */ - format_t (*get_codec)(struct ast_channel *chan); + int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active); + /*! Callback for retrieving codecs that the channel can do. Result returned in result_cap*/ + void (*get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap); /*! Linked list information */ AST_RWLIST_ENTRY(ast_rtp_glue) entry; }; @@ -1046,27 +1050,29 @@ struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs /*! * \brief Get the sample rate associated with known RTP payload types * - * \param asterisk_format True if the value in the 'code' parameter is an AST_FORMAT value - * \param code Format code, either from AST_FORMAT list or from AST_RTP list + * \param asterisk_format True if the value in format is to be used. + * \param An asterisk format + * \param code from AST_RTP list * * \return the sample rate if the format was found, zero if it was not found * * \since 1.8 */ -unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code); +unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, struct ast_format *format, int code); /*! * \brief Retrieve all formats that were found * * \param codecs Codecs structure to look in - * \param astformats An integer to put the Asterisk formats in + * \param astformats A capabilities structure to put the Asterisk formats in. * \param nonastformats An integer to put the non-Asterisk formats in * * Example usage: * * \code - * int astformats, nonastformats; - * ast_rtp_codecs_payload_Formats(&codecs, &astformats, &nonastformats); + * struct ast_format_cap *astformats = ast_format_cap_alloc_nolock() + * int nonastformats; + * ast_rtp_codecs_payload_formats(&codecs, &astformats, &nonastformats); * \endcode * * This retrieves all the formats known about in the codecs structure and puts the Asterisk ones in the integer @@ -1074,13 +1080,14 @@ unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code); * * \since 1.8 */ -void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *astformats, int *nonastformats); +void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats); /*! * \brief Retrieve a payload based on whether it is an Asterisk format and the code * * \param codecs Codecs structure to look in - * \param asterisk_format Non-zero if the given code is an Asterisk format value + * \param asterisk_format Non-zero if the given Asterisk format is present + * \param format Asterisk format to look for * \param code The format to look for * * \retval Numerical payload @@ -1088,20 +1095,21 @@ void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *ast * Example usage: * * \code - * int payload = ast_rtp_codecs_payload_code(&codecs, 1, AST_FORMAT_ULAW); + * int payload = ast_rtp_codecs_payload_code(&codecs, 1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0); * \endcode * * This looks for the numerical payload for ULAW in the codecs structure. * * \since 1.8 */ -int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code); +int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code); /*! * \brief Retrieve mime subtype information on a payload * - * \param asterisk_format Non-zero if the given code is an Asterisk format value - * \param code Format to look up + * \param asterisk_format Non-zero to look up using Asterisk format + * \param format Asterisk format to look up + * \param code RTP code to look up * \param options Additional options that may change the result * * \retval Mime subtype success @@ -1110,21 +1118,22 @@ int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asteris * Example usage: * * \code - * const char *subtype = ast_rtp_lookup_mime_subtype2(1, AST_FORMAT_ULAW, 0); + * const char *subtype = ast_rtp_lookup_mime_subtype2(1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0, 0); * \endcode * * This looks up the mime subtype for the ULAW format. * * \since 1.8 */ -const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options); +const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_format *format, int code, enum ast_rtp_options options); /*! * \brief Convert formats into a string and put them into a buffer * * \param buf Buffer to put the mime output into - * \param capability Formats that we are looking up - * \param asterisk_format Non-zero if the given capability are Asterisk format capabilities + * \param ast_format_capability Asterisk Formats we are looking up. + * \param rtp_capability RTP codes that we are looking up + * \param asterisk_format Non-zero if the ast_format_capability structure is to be used, 0 if rtp_capability is to be used * \param options Additional options that may change the result * * \retval non-NULL success @@ -1134,14 +1143,19 @@ const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format * * \code * char buf[256] = ""; - * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), AST_FORMAT_ULAW | AST_FORMAT_ALAW, 1, 0); + * 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)); + * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), cap, 0, 1, 0); + * ast_format_cap_destroy(cap); * \endcode * * This returns the mime values for ULAW and ALAW in the buffer pointed to by buf. * * \since 1.8 */ -char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, const format_t capability, const int asterisk_format, enum ast_rtp_options options); +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 @@ -1535,14 +1549,15 @@ char *ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_r * Example usage: * * \code - * ast_rtp_instance_set_read_format(instance, AST_FORMAT_ULAW); + * struct ast_format tmp_fmt; + * ast_rtp_instance_set_read_format(instance, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0)); * \endcode * * This requests that the RTP engine provide audio frames in the ULAW format. * * \since 1.8 */ -int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, format_t format); +int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format); /*! * \brief Tell underlying RTP engine that audio frames will be provided in a specific format @@ -1556,14 +1571,15 @@ int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, format_t * Example usage: * * \code - * ast_rtp_instance_set_write_format(instance, AST_FORMAT_ULAW); + * struct ast_format tmp_fmt; + * ast_rtp_instance_set_write_format(instance, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0)); * \endcode * * This tells the underlying RTP engine that audio frames will be provided to it in ULAW format. * * \since 1.8 */ -int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, format_t format); +int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format); /*! * \brief Request that the underlying RTP engine make two RTP instances compatible with eachother @@ -1592,20 +1608,19 @@ int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_in * \param instance The RTP instance * \param to_endpoint Formats being sent/received towards the endpoint * \param to_asterisk Formats being sent/received towards Asterisk - * - * \retval supported formats + * \param result capabilities structure to store and return supported formats in. * * Example usage: * * \code - * ast_rtp_instance_available_formats(instance, AST_FORMAT_ULAW, AST_FORMAT_SLINEAR); + * ast_rtp_instance_available_formats(instance, to_capabilities, from_capabilities, result_capabilities); * \endcode * * This sees if it is possible to have ulaw communicated to the endpoint but signed linear received into Asterisk. * * \since 1.8 */ -format_t ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk); +void ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result); /*! * \brief Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance diff --git a/include/asterisk/slin.h b/include/asterisk/slin.h index 7abfe7fd8..ab7d843ab 100644 --- a/include/asterisk/slin.h +++ b/include/asterisk/slin.h @@ -62,7 +62,6 @@ static inline struct ast_frame *slin8_sample(void) { static struct ast_frame f = { .frametype = AST_FRAME_VOICE, - .subclass.codec = AST_FORMAT_SLINEAR, .datalen = sizeof(ex_slin8) * 2, .samples = ARRAY_LEN(ex_slin8), .mallocd = 0, @@ -71,6 +70,7 @@ static inline struct ast_frame *slin8_sample(void) .data.ptr = ex_slin8, }; + ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0); return &f; } @@ -78,7 +78,6 @@ static inline struct ast_frame *slin16_sample(void) { static struct ast_frame f = { .frametype = AST_FRAME_VOICE, - .subclass.codec = AST_FORMAT_SLINEAR16, .datalen = sizeof(ex_slin16) * 2, .samples = ARRAY_LEN(ex_slin16), .mallocd = 0, @@ -87,5 +86,6 @@ static inline struct ast_frame *slin16_sample(void) .data.ptr = ex_slin16, }; + ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0); return &f; } diff --git a/include/asterisk/slinfactory.h b/include/asterisk/slinfactory.h index 78d432193..003c6ac28 100644 --- a/include/asterisk/slinfactory.h +++ b/include/asterisk/slinfactory.h @@ -24,6 +24,8 @@ #ifndef _ASTERISK_SLINFACTORY_H #define _ASTERISK_SLINFACTORY_H +#include "asterisk/format.h" + #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -37,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 */ - format_t format; /*!< Current format the translation path is converting from */ - format_t 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 */ }; /*! diff --git a/include/asterisk/speech.h b/include/asterisk/speech.h index cb167d5b5..5397d8aaa 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 */ - int format; + struct ast_format format; /*! Data for speech engine */ void *data; /*! Cached results */ @@ -74,7 +74,7 @@ struct ast_speech_engine { /*! Name of speech engine */ char *name; /*! Set up the speech structure within the engine */ - int (*create)(struct ast_speech *speech, int format); + int (*create)(struct ast_speech *speech, struct ast_format *format); /*! Destroy any data set on the speech structure by the engine */ int (*destroy)(struct ast_speech *speech); /*! Load a local grammar on the speech structure */ @@ -98,7 +98,7 @@ struct ast_speech_engine { /*! Try to get results */ struct ast_speech_result *(*get)(struct ast_speech *speech); /*! Accepted formats by the engine */ - int formats; + struct ast_format_cap *formats; AST_LIST_ENTRY(ast_speech_engine) list; }; @@ -131,7 +131,7 @@ int ast_speech_results_free(struct ast_speech_result *result); /*! \brief Indicate to the speech engine that audio is now going to start being written */ void ast_speech_start(struct ast_speech *speech); /*! \brief Create a new speech structure */ -struct ast_speech *ast_speech_new(const char *engine_name, int formats); +struct ast_speech *ast_speech_new(const char *engine_name, const struct ast_format_cap *formats); /*! \brief Destroy a speech structure */ int ast_speech_destroy(struct ast_speech *speech); /*! \brief Write audio to the speech engine */ diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h index 821463bf1..7e73cd1b1 100644 --- a/include/asterisk/translate.h +++ b/include/asterisk/translate.h @@ -24,9 +24,6 @@ #ifndef _ASTERISK_TRANSLATE_H #define _ASTERISK_TRANSLATE_H -#define MAX_AUDIO_FORMAT 47 /* Do not include video here */ -#define MAX_FORMAT 64 /* Do include video here */ - #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -35,11 +32,78 @@ extern "C" { #include "asterisk/frame.h" #include "asterisk/plc.h" #include "asterisk/linkedlists.h" -// XXX #include "asterisk/module.h" #endif struct ast_trans_pvt; /* declared below */ +/*! + * \brief Translator Cost Table definition. + * + * \note The defined values in this table must be used to set + * the translator's table_cost value. + * + * \note The cost value of the first two values must always add + * up to be greater than the largest value defined in this table. + * This is done to guarantee a direct translation will always + * have precedence over a multi step translation. + * + * \details This table is built in a way that allows translation + * paths to be built that guarantee the best possible balance + * between performance and quality. With this table direct + * translation paths between two formats will always take precedence + * over multi step paths, lossless intermediate steps will always + * be chosen over lossy intermediate steps, and preservation of + * sample rate across the translation will always have precedence + * over a path that involves any re-sampling. + */ +enum ast_trans_cost_table { + + /* Lossless Source Translation Costs */ + + /*! [lossless -> lossless] original sampling */ + AST_TRANS_COST_LL_LL_ORIGSAMP = 400000, + /*! [lossless -> lossy] original sampling */ + AST_TRANS_COST_LL_LY_ORIGSAMP = 600000, + + /*! [lossless -> lossless] up sample */ + AST_TRANS_COST_LL_LL_UPSAMP = 800000, + /*! [lossless -> lossy] up sample */ + AST_TRANS_COST_LL_LY_UPSAMP = 825000, + + /*! [lossless -> lossless] down sample */ + AST_TRANS_COST_LL_LL_DOWNSAMP = 850000, + /*! [lossless -> lossy] down sample */ + AST_TRANS_COST_LL_LY_DOWNSAMP = 875000, + + /*! [lossless -> unknown] unknown. + * This value is for a lossless source translation + * with an unknown destination and or sample rate conversion. */ + AST_TRANS_COST_LL_UNKNOWN = 885000, + + /* Lossy Source Translation Costs */ + + /*! [lossy -> lossless] original sampling */ + AST_TRANS_COST_LY_LL_ORIGSAMP = 900000, + /*! [lossy -> lossy] original sampling */ + AST_TRANS_COST_LY_LY_ORIGSAMP = 915000, + + /*! [lossy -> lossless] up sample */ + AST_TRANS_COST_LY_LL_UPSAMP = 930000, + /*! [lossy -> lossy] up sample */ + AST_TRANS_COST_LY_LY_UPSAMP = 945000, + + /*! [lossy -> lossless] down sample */ + AST_TRANS_COST_LY_LL_DOWNSAMP = 960000, + /*! [lossy -> lossy] down sample */ + AST_TRANS_COST_LY_LY_DOWNSAMP = 975000, + + /*! [lossy -> unknown] unknown. + * This value is for a lossy source translation + * with an unknown destination and or sample rate conversion. */ + AST_TRANS_COST_LY_UNKNOWN = 985000, + +}; + /*! \brief * Descriptor of a translator. * @@ -70,10 +134,14 @@ struct ast_trans_pvt; /* declared below */ */ struct ast_translator { const char name[80]; /*!< Name of translator */ - format_t srcfmt; /*!< Source format (note: bit position, - * converted to index during registration) */ - format_t dstfmt; /*!< Destination format (note: bit position, - * converted to index during registration) */ + struct ast_format src_format; /*!< Source format */ + struct ast_format dst_format; /*!< Destination format */ + + int table_cost; /*!< Cost value associated with this translator based + * on translation cost table. */ + int comp_cost; /*!< Cost value associated with this translator based + * on computation time. This cost value is computed based + * on the time required to translate sample data. */ int (*newpvt)(struct ast_trans_pvt *); /*!< initialize private data * associated with the translator */ @@ -109,8 +177,9 @@ struct ast_translator { struct ast_module *module; /*!< opaque reference to the parent module */ - int cost; /*!< Cost in milliseconds for encoding/decoding 1 second of sound */ int active; /*!< Whether this translator should be used or not */ + int src_fmt_index; /*!< index of the source format in the matrix table */ + int dst_fmt_index; /*!< index of the destination format in the matrix table */ AST_LIST_ENTRY(ast_translator) list; /*!< link field */ }; @@ -199,11 +268,20 @@ void ast_translator_deactivate(struct ast_translator *t); * \brief Chooses the best translation path * * Given a list of sources, and a designed destination format, which should - * I choose? - * \return Returns 0 on success, -1 if no path could be found. - * \note Modifies dests and srcs in place + * I choose? + * + * \param destination capabilities + * \param source capabilities + * \param destination format chosen out of destination capabilities + * \param source format chosen out of source capabilities + * \return Returns 0 on success, -1 if no path could be found. + * + * \note dst_cap and src_cap are not mondified. */ -format_t ast_translator_best_choice(format_t *dsts, format_t *srcs); +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); /*! * \brief Builds a translator path @@ -212,7 +290,7 @@ format_t ast_translator_best_choice(format_t *dsts, format_t *srcs); * \param source source format * \return ast_trans_pvt on success, NULL on failure * */ -struct ast_trans_pvt *ast_translator_build_path(format_t dest, format_t source); +struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dest, struct ast_format *source); /*! * \brief Frees a translator path @@ -238,12 +316,14 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, i * \param src source format * \return the number of translation steps required, or -1 if no path is available */ -unsigned int ast_translate_path_steps(format_t dest, format_t src); +unsigned int ast_translate_path_steps(struct ast_format *dest, struct ast_format *src); /*! - * \brief Mask off unavailable formats from a format bitmask + * \brief Find available formats * \param dest possible destination formats * \param src source formats + * \param result capabilities structure to store available formats in + * * \return the destination formats that are available in the source or translatable * * The result will include all formats from 'dest' that are either present @@ -252,7 +332,7 @@ unsigned int ast_translate_path_steps(format_t dest, format_t src); * \note Only a single audio format and a single video format can be * present in 'src', or the function will produce unexpected results. */ -format_t ast_translate_available_formats(format_t dest, format_t src); +void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result); /*! * \brief Puts a string representation of the translation path into outbuf @@ -262,6 +342,13 @@ format_t ast_translate_available_formats(format_t dest, format_t src); */ const char *ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str); +/*! + * \brief Initialize the translation matrix and index to format conversion table. + * \retval 0 on success + * \retval -1 on failure + */ +int ast_translate_init(void); + #if defined(__cplusplus) || defined(c_plusplus) } #endif |