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模組。