2.4 Stagefright中添加组件-RTSP(Android2.2)

  (Android2.2) 本节以在Stagefright中实现Rtsp流播放功能为例,介绍在Stagefright中添加功能组件的完整设计和过程。
  手机终端的流媒体播放通常包括两种,一种是基于Http协议,一种则是基于RTSP协议。Http说白了就是下载播放,其过程就是建立http连接,通过udp把点播的视频文件下载到本地。通常文件的格式为mp4,当然也可以有其他的格式,数据到了本地,其播放就和磁盘上的文件播放没任何区别。这种类型比较简单,无实时概念,也不需要考虑时间戳等问题。
  Rtsp(实时流协议)目前在网络实时播放及某些视频点播系统中有着十分广泛的应用。它是严格的客户端服务器模式,流的解析处理工作是在服务器端做的,Client收到的是Es数据,对ES数据解码并播放,Rtsp协议的一般工作流程如下:
  RTSP常用的命令有(由C端发起): 命令 描述 OPTIONS 询问S有哪些方法可用 DESCRIBE 要求得到S提供的媒体初始化描述信息,S回应媒体初始化描述信息,通常采用SDP协议描述。 SETUP 设置会话的属性,以及传输模式,告诉S建立会话。 PLAY C请求播放 PAUSE C请求暂停播放 TEARDOWN C请求关闭会话 服务器支持哪些命令通常采用OPTIONS就可以获取到,像PAUSE这样的命令有的服务器是不支持的,例如一些直播的电视台节目,是不需要支持PAUSE的。对于IPTV的模式来书,支持文件的点播,这样不但可以支持PAUSE/RESUME这样的请求,有的也会支持快进快退的操作,全在于服务器。
  回到我们的需求,整个过程大致可分为4个阶段。
  1. DESCRIBE
  C端根据URL可以得到服务端的IP地址和端口等信息,也就得到了和S端通话的权利。通过TCP的连接,向S端发送DESCRIBE的命令,也就是告诉服务器,我对xx目标(文件)感兴趣,需要你告诉我一些详细信息。这时候服务端会解析并把一些流播放必须的信息例如视频的编码格式,图像Size,音频的的编码格式,Sample Rate,Channels等信息,都写成SDP的格式,同时发送个C端。C端得到这些必备的信息,就可以去启动解码器,准备解码。 TEARDOWN … … Send ES data Reply OK PLAY Reply OK SETUP A/V Track Reply SDP DESCRIBE Client Server Reply OK 2.SETUP C端知道了当前的流有几个Track,就分别去告诉S端,我要建立几个Track,并分别的告诉S端我这边接收数据的端口号,通常会建立一个Video Track和一个Audio Track,单独的音频广播台则只会建立以个Audio Track.
  3 PLAY
  C端已经做好准备,可以开始播放,则发送Play指令告诉S端咱们开始吧。S端收到指令,并回复OK,就开始一个包一个包的吧ES流数据发送给C端相应的端口。C则等待接收数据并解码播放。
  4 TEARDOWN
  C端打算停止,则主动发送TEARDOWN告诉S端不玩了,咱们拜拜吧。S端发送OK,整个会话就算完成。
  Android2.2的Stagefright支持了http这种简单的流播放,而并不支持RTSP协议,在2.2版本OpenCore只完成很小一部分功能,就是RTSP。如果这个功能Stagefright也都具备了,那就完全可以把Opencore一脚踢开了。我们下面就来帮Stagefright实现这个功能。
  首先来熟悉一下Http的功能框架: Prefetcher VTrack ATrack Awesomeplayer Extractor(MP4) CacheDataSource HttpDataSource HttpStream 框架非常简单,如果把Extractor之下都看成是Filesource的话,其和普通文件播放也就差在于多了个Prefetcher,然后就是这个prefetcher让我觉得在其上扩展十分容易,Code都是可以复用的,看下RTSP的设计框架。 VRingBuff RTSPDataSource librtsp RTSPExtractor ARingBuff Awesomeplayer VTrack ATrack Prefetcher 使用RTSP当我们收到数据的时候已经是按不同的Track分好的了,所以我们应该按不同的Track来存储数据,这时候Ringbuffer就是最有效率和最省内存的方式了。由其可以替代CacheDataSource。
  RTSPDataSource继承DataSource,完成了DataSource的基本功能,实际上也就是实现几个必须的接口,例如getSize,readAt 等。因RTSP的特殊情况,我扩展了一个
  readAt:
  virtual ssize_t readAt(int trackID, void *data, int64_t *timestamp , int timeout) = 0;
  原因有3:
  1. RTSP的timestamp是要跟着packet走的。
  2. 读数据需要分不同的Track。
  3. 网络流数据的读取必须有timeout的机制,否则一旦在网络不好的条件下很有可能被block住。
  RTSPExtractor负责Track的管理,为player提供逻辑上清晰简单的(Video或Audio)数据源(MediaSource)。同时它需要完成MetaData的填写,使得player有足够的信息来启动各个模块。
  Rtsp解码器所需要的所有信息都由SDP来描述,也就是在DESCRIBE阶段得到content
  内容,这个content逻辑上应该由Extractor来解析,但考虑到本身RTSP lib中有sdp解析的功能,而且实际有意义的信息并不多,因此采用另一种方式,DataSouce中再增加一个Track用来传递SDP信息,实际上传递的就是一个解析出来的结构体。
  Prefecher是这样一个组件,它内部会启动一个线程,用来预存一定量的数据,它是一堆MediaBuffer的堆积。它的存在对于流数据的播放时必要的,以前它单为http设计,实际我们所有的流播放都可以使用这个机制。同时它包含一个实现MediaSource的PrefechedSource,实现和应用的数据接入,同时提供了其他接口用来获取其缓冲数据时间相关属性。
  以上基本组件完成了RTSP的整个框架,细节不多说。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值