分享

EMIPLIB的使用及扩展(二)

 lance library 2012-02-24

2. EMIPLIB的消息机制

EMIPLIB组件对象间,采用消息(Message)驱动机制实现数据的交流与互通。换句话说,组件间数据的交互,只能依靠消息的传递实现。

依据本节第一部分描述的“EMIPLIB的功能模块划分”,将组件分为不同功能类别,对应的,也将消息划分为不同种类,只有相同或者相近功能的组件间才共享同一定义的消息。具体的系统消息结构见下图所示:

 

 

 

EMIPLIB消息结构图

所有消息均继承自基类MIPMessage,用以定义消息类的基本结构。每个消息必须带有两个关键属性:Type(类型)和Subtype(子类型)。其中Type字段已在MIPMessage中定义,用以标识该消息所属功能模块,Subtype则留给继承类以细分消息类别。大致如下所示(◆表示Subtype):

(1)   MIPMESSAGE_TYPE_SYSTEM:系统消息,对应上图所示的MIPSystemMessage类。

u  MIPSYSTEMMESSAGE_TYPE_WAITTIME:有组件链下发给系统的第一个组件(一般为定时器),表示延时设定时间后再触发下一组件。

u  MIPSYSTEMMESSAGE_TYPE_ISTIME:触发下一组件的消息子类型。

(2)   MIPMESSAGE_TYPE_AUDIO_RAW

对应MIPRawFloatAudioMessage类:

u  MIPRAWAUDIOMESSAGE_TYPE_FLOAT 

对应MIPRawU8AudioMessage类:            

u  MIPRAWAUDIOMESSAGE_TYPE_U8

对应MIPRaw16bitAudioMessage类:                   

u  MIPRAWAUDIOMESSAGE_TYPE_U16LE                   

u  MIPRAWAUDIOMESSAGE_TYPE_U16BE

u  MIPRAWAUDIOMESSAGE_TYPE_S16LE               

u  MIPRAWAUDIOMESSAGE_TYPE_S16BE                   

u  MIPRAWAUDIOMESSAGE_TYPE_S16                 

MIPRAWAUDIOMESSAGE_TYPE_U16

(3)   MIPMESSAGE_TYPE_AUDIO_ENCODED:对应MIPEncodedAudioMessage类,通过在该类中定义如下子类型(并未分别为每个子类型单独实现类)

u  MIPENCODEDAUDIOMESSAGE_TYPE_SPEEX

u  MIPENCODEDAUDIOMESSAGE_TYPE_ULAW

u  MIPENCODEDAUDIOMESSAGE_TYPE_ALAW

u  MIPENCODEDAUDIOMESSAGE_TYPE_GSM

u  MIPENCODEDAUDIOMESSAGE_TYPE_LPC

u  MIPENCODEDAUDIOMESSAGE_TYPE_SILK

(4)   MIPMESSAGE_TYPE_VIDEO_RAW:实现继承自MIPVideoMessage

对应MIPRawYUV420PVideoMessage类:

u  MIPRAWVIDEOMESSAGE_TYPE_YUV420P

对应MIPRawYUYVVideoMessage类:

u  MIPRAWVIDEOMESSAGE_TYPE_YUYV

对应MIPRawRGBVideoMessage

u  MIPRAWVIDEOMESSAGE_TYPE_RGB24

u  MIPRAWVIDEOMESSAGE_TYPE_RGB32

(5)   MIPMESSAGE_TYPE_VIDEO_ENCODED:对应MIPEncodedVideoMessage

u  MIPENCODEDVIDEOMESSAGE_TYPE_H263P

u  MIPENCODEDVIDEOMESSAGE_TYPE_JPEG

(6)   MIPMESSAGE_TYPE_RTP

u  MIPRTPMESSAGE_TYPE_SEND:对应MIPRTPSendMessage类。

u  MIPRTPMESSAGE_TYPE_RECEIVE:对应MIPRTPReceiveMessage类。

(7)   MIPMESSAGE_TYPE_ALL:特别的,用于消息过滤机制,表示此组件接受任何形式的消息。

注:为了实现的方面,EMIPLIBRAW Audio/Video(原始数据流)所定义的子类型采用部分合并的方式,将结构类似的子类型重用,异构的子类型则分别实现。为Encoded Audio/Video(编码数据流)所定义的子类型由于结构一致,重用一个实现类即可。

3.   EMIPLIB的RTP打包、解包机制

EMIPLIBRTP打包与解包机制并没有采用相同的可逆设计,还挺有意思的,故此处提出来专门说明。

(1)  RTP打包机制

上文已经说明,EMIPLIB的基本单位是组件(Component),整个流程的实现,是基于一条Component Chain将组件串起来。因此,RTP打包模块也是按照此思路完成。

RTP部分的组件链如下图所示:

 

输出RTP码流的组件链连接图

下面针对上图RTP部分简要说明。

u  按照编码格式打包为对应RTP包:通过定义RTP编码的基类MIPRTPEncoder(继承自MIPComponent,作为组件实现) ,不同编码格式可以有自己的实现方案,但均需继承此基类并以此来描述自己所提供的服务 。下图所示为基类与继承类间的关系。

 

 

 

RTP打包模块结构图

值得一提的是,MIPRTPH263Encoder作为H.263+RFC实现,而MIPRTPVIdeoEncoder则作为H.263+YUV420P的内部实现方案,不能在有外部RTP依赖关系的系统环境中使用。之所以将YUV420P作为内部实现,推测是因为RFC中并未定义未被压缩的原始码流的RTP实现方案。

u  RTP统一配置与报文发送:由MIPRTPComponent类整合JRTPLIB实现。MIPRTPComponent类可以实现RTP报文的发送与接收。通过设置RTPSession参数,统一配置外发RTP报文的IP地址及端口号、时间戳、收发方缓存、最大报文长度等基本参数。

(2)  RTP解包机制

RTP的解包机制则有所不同。

u  RTP报文接收:仍然使用发包处所使用的MIPRTPComponent实现,但配置信息通过SIP交互的初始化信息自动下发。

 

RTP码流接收的组件链结构图

u  按照格式解包:并不是类似Encoder的方式,通过继承MIPRTPVIdeoEncoder父类的方式实现。而是格外的定义了非组件形式的MIPRTPPacketDecoder纯虚类,统一描述不同负载形式的RTP报文解码所需要提供的服务。每种具体格式的报文解包实现都需要继承这个纯虚类。

当接收方处理多种负载类型的RTP报文时,由MIPRTPVIdeoDecoder作为全局控制中心,将报文发送到对应解码实现中。这样做的好处是,系统可以同时处理多种格式的RTP报文且不会冲突。

解包模块结构图

MIPRTPVIdeoDecoder中负载类型与RTP解码实现类的映射关系通过一个数组来实现。根据系统当前所需要的解码组件动态加载。在RTPRFC文献中,某些数据格式类型绑定确定的负载类型编号,有些则可以通过临时的动态绑定操作,将某个预留的负载类型编号绑定某个特定实现。具体的实现是通过RTP传输前的SIP报文携带的SDP包体信息完成交互的。

 

?8接收RTP时组件关系图

1.1.3.4 EMIPLIB的扩展应用

当然,EMIPLIB仅仅是流媒体系统的框架,其中有许多功能尚未实现,需要开发者根据自己的需要添加,比如:

(1)  针对H.264MPEG4编码的RTP报文打包;

(2)  前端回送的码流打包为容器格式保存;

(3)  与其他SIP应用程序的交互(初始化、暂停、回放等等)

EMIPLIB的可扩展性良好,在理解上述架构的基础上,可以方便的添加组件实现。(1)(2)已经的源代码我已经写好了,(3)还在写,但开发难度不大,等我有空再注释下,传上来 嘿嘿~

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多