Asterisk RTP引擎

        Asterisk内核(下面就简称内核)提供了一系列RTP相关的API函数。在使用不同的RTP栈时,这些API为RTP使用模块提供一种统一的访问方式。这些API封装之后,任何使用RTP的模块,都感觉不到底层栈的差异。对于使用模块来说,每个RTP栈的行为都是一样的。

        内核把一个RTP session称作一个RTP实例,一个实例由几部分组成:编解码(codec)信息、RTP引擎、RTP属性信息、地址信息。可以通过引擎名明确指定所使用的RTP栈,如果没有指定,会使用缺省的栈。调用方可以提供RTP所使用的地址,但底层RTP引擎可能会根据自身的配置,选择一个适当的地址。

        RTP引擎(通常是以属于resource分类的模块),是介于内核和RTP栈之间的一层。内核提供一系列的回调接口来完成不同的事务(比如说音频输出),而RTP引擎则需要适配这些接口,即对RTP栈进行封装。

Glue是一个RTP实例和一个信道(channel)间绑定的内容。在执行远端桥接或本地桥接时,或者通道驱动需要通知远端改变RTP流的目的地时,它用来检索RTP实例。

        RTP实例的统计数据,可以通调用ast_rtp_instance_get_stats这个API来检索。这要求使用中的RTP引擎填充一个数据结构,以携带所请求的统计项值。没有要求一个RTP引擎必须支持所有的统计项。

        调用方可以改变RTP引擎和引核的行为,这需要设置RTP属性。比如说:有一个叫AST_RTP_PROPERTY_NAT的属性,它用来告诉RTP引擎:如果支持对称RTP就启用它。内核并不要求一个RTP引擎必须支持所有的属性。

         编解码信息存储在一个独立的数据结构中,它拥有自己的一套API,用于添加、删除或信息检索。使用它们的模块,在RTP实例创建之后调用这些API,这样,载荷信息对RTP引擎来说就是可见的。

 

数据结构

ast_rtp_instance,描述RTPSession的数据结构。

00048 /*! Structure that represents an RTP session (instance) */
00049 struct ast_rtp_instance {
00050    /*! Engine that is handling this RTP instance */
00051    struct ast_rtp_engine *engine;
00052    /*! Data unique to the RTP engine */
00053    void *data;
00054    /*! RTP properties that have been set and their value */
00055    int properties[AST_RTP_PROPERTY_MAX];
00056    /*! Address that we are expecting RTP to come in to */
00057    struct ast_sockaddr local_address;
           ........
 };

 

 

ast_rtp_mime_type,在rtp_engine.c中,直接定义了一个数组,描述MIME媒体类型

00086 /*! The following array defines the MIME Media type (and subtype) for each
00087    of our codecs, or RTP-specific data type. */
00088 static struct ast_rtp_mime_type {
00089    struct ast_rtp_payload_type payload_type;
00090    char *type;
00091    char *subtype;
00092    unsigned int sample_rate;
00093 } ast_rtp_mime_types[]; 

 

 

        ast_rtp_engine 描述具体RTP栈的数据结构,提供了内核与RTP栈交互的一系列接口定义。具体的RTP引擎实现,都要实例化里面的内容。

00313 /*! Structure that represents an RTP stack (engine) */
00314 struct ast_rtp_engine {
00315    /*! Name of the RTP engine, used when explicitly requested */
00316    const char *name;
00317    /*! Module this RTP engine came from, used for reference counting */
00318    struct ast_module *mod;
00319    /*! Callback for setting up a new RTP instance */
00320    int (*new)(struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *sa, void *data);
00321    /*! Callback for destroying an RTP instance */
00322    int (*destroy)(struct ast_rtp_instance *instance);
00323    /*! Callback for writing out a frame */
00324    int (*write)(struct ast_rtp_instance *instance, struct ast_frame *frame);
00325    /*! Callback for stopping the RTP instance */
00326    void (*stop)(struct ast_rtp_instance *instance);
          .......
};

 

 

        ast_rtp_glue,描述RTP实例和具体信道间绑定的数据内容、内核与RTP使用模块间的接口定义,用到RTP的外围模块,都需要自己实现相关的接口:

00396 /*! Structure that represents the glue that binds an RTP instance to a channel */
00397 struct ast_rtp_glue {
00398    /*! Name of the channel driver that this glue is responsible for */
00399    const char *type;
00400    /*! Module that the RTP glue came from */
00401    struct ast_module *mod;
00402    /*!
00403     * \brief Callback for retrieving the RTP instance carrying audio
00404     * \note This function increases the reference count on the returned RTP instance.
00405     */
00406    enum ast_rtp_glue_result (*get_rtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
00407    /*!
00408     * \brief Callback for retrieving the RTP instance carrying video
00409     * \note This function increases the reference count on the returned RTP instance.
00410     */
00411    enum ast_rtp_glue_result (*get_vrtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
00412    /*!
00413     * \brief Callback for retrieving the RTP instance carrying text
00414     * \note This function increases the reference count on the returned RTP instance.
00415     */
00416    enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
00417    /*! Callback for updating the destination that the remote side should send RTP to */
00418    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);
00419    /*! Callback for retrieving codecs that the channel can do.  Result returned in result_cap*/
00420    void (*get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap);
00421    /*! Linked list information */
00422    AST_RWLIST_ENTRY(ast_rtp_glue) entry;
00423 };

 

 

        内核定义了两个链表,用来管理RTPengine和RTP glue

00080 /*! List of RTP engines that are currently registered */
00081 static AST_RWLIST_HEAD_STATIC(engines, ast_rtp_engine);
00082 
00083 /*! List of RTP glues */
00084 static AST_RWLIST_HEAD_STATIC(glues, ast_rtp_glue);

 

        内核提供了一个抽象的管理和调用接口,具体的RTP应用模块,与内核API交互,内核再通过ast_rtp_engine里定义的接口与FTP栈交互,如果要引入新的RTP栈,就要实现栈与内核间的一个引擎模块,实现这些接口的封装。1.8版本中,asterisk实现两个引擎模块:res_rtp_asterisk和res_rtp_multicast模块。

你可能感兴趣的:(数据结构,struct,callback,reference,引擎,structure)