Stagefright缓存机制PPT学习课件_第1页
Stagefright缓存机制PPT学习课件_第2页
Stagefright缓存机制PPT学习课件_第3页
Stagefright缓存机制PPT学习课件_第4页
Stagefright缓存机制PPT学习课件_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Stagefright缓冲机制android2.3.3,一、AndroidBinder机制,二、SetDataSource过程,三、prepare过程,四、缓冲读取过程,1,AndroidBinder机制,Proxy进程的MediaPlayer到Native进程上的AwesomePlayer,Proxy进程,Native进程,2,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信setDataSource操作,Proxy进程端,获得BpMediaPlayerService后通过ProxyBinder通信,在data中写入uri,3,AndroidBinder机制,获得与Native进程上AwesomePlayer通信的BpMediaPlayerService对象,先要获取BpMediaPlayerService类型的mediaPlayerService对象,这是工作在Proxy进程上的,setDataSource操作通过这个对象与Native进程上的BnMediaPlayerService类型对象进行通信。事实上,获得MediaPlayerService的过程也需要IPC从Native进程上获得,在checkService函数中有此过程,此处略,4,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信setDataSource操作,Native进程端,在Native进程端处理数据的为MediaPlayerService的对象,5,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信setDataSource操作,Native进程端,Native端:setDataSource时先建立处理流媒体对应的Player对象,通过Client建立StagefrightPlayer对象,其中包含AwesomePlayer类型的成员属性mPlayer,6,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信setDataSource操作,Native进程端,7,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信prepare,start,stop等操作,Proxy进程上通过IPC发送处理的请求,8,AndroidBinder机制,Proxy进程与Native进程上的AwesomePlayer通信prepare,start,stop等操作,Native进程端处理相应的请求并通过Client-StagefrightPlayer-AwesomePlayer执行最终的操作,大致过程同上,9,SetDataSource过程,传入的只是一个URL和在构成Request时需要的HTTPHeader只在局部变量中保存即可reset_l只是一个复位局部变量的函数,10,prepare过程,AwesomePlayer内部mQueue(TimedEventQueue)是一个事件队列mQueue单独有自己的线程(pthread)随时监视队列是否为空通过异步的方式处理从Proxy进程传入Native进程上的事件通过onPrepareAsyncEvent方法来响应prepare事件,11,prepare过程TimedEventQueue的一点说明,TimedEventQueue在插入队列时是按照事件等待响应时间排序插入的等待时间越长的会越往后插入队列,三个方法分别加入队列头,尾和按等待时间,3.Fire触发事件-AwesomeEvent,12,prepare过程onPrepareAsyncEvent处理prepare事件,根据mUri的信息设置并绑定好对应的音视频源初始化视频,音频解码器发送继续缓冲事件检查是否需要继续缓冲数据,13,prepare过程onPrepareAsyncEvent处理finishSetDataSource,14,检查setDataSource时保存的mUri属性前几个字符如果是以httplive:/开头则开始httplivestreaming的处理,3.当真正开始与服务器进行连接时需要把头改成http:/才行建立LiveSource对象,此时就与服务器第一次连接,并得到.m3u8文件根据LiveSource对象建立视频的数据缓冲对象NuCachedSource2根据缓冲得到的数据进行分析并开始分离音视频,prepare过程onPrepareAsyncEvent处理finishSetDataSource,15,prepare过程建立liveSource对象,16,prepare过程建立liveSource对象,fetchM3U与服务器连接,首先需要根据传入的host/port连接服务器与服务器连接后发送Request请求,17,prepare过程建立liveSource对象,fetchM3U与服务器连接,18,prepare过程建立liveSource对象,fetchM3U向服务器发送请求,在NuHTTPDataSource的connect中,通过HTTPStream属性connect服务器成功后发送Request,19,prepare过程建立liveSource对象,fetchM3U向服务器发送请求,把mOffset属性更新成用户新定义的传入的offset,然后在Request的Range域中写好新的offset值发送给服务器这样以后从服务器读到的流数据就是用户调整播放时间后需要的数据了,这个Request是在服务器端进行相应的调整Range域的含义:bytes=a-b表示需要从服务器下载从第a字节到第b字节的数据,如果写成bytes=a-则表示从第a字节到结束在发送数据的if语句中通过|或的方式也顺带进行了mHTTP.receive_header接收服务器发回的Response相应完成一次握,20,prepare过程建立liveSource对象,fetchM3U处理接收响应,21,prepare过程建立liveSource对象,fetchM3U处理接收响应,22,prepare过程建立liveSource对象,fetchM3U处理接收响应,无论是否使用Range属性都在此处获得整个流媒体文件的大小可以通过getSize()获取到,23,prepare过程建立liveSource对象,24,prepare过程建立liveSource对象,fetchM3U读取数据readAt,只有当用户进行了跳进,即传入的offset与内部记录的播放mOffset不一致时才从新尝试连接服务器,这样可以在Range域中调整,让服务器能够传来跳进后的新offset的数据,如果是连续播放则不必再连接服务器,此时读取的就是index.m3u8文件,把文件内容都缓存到之间新new出来的ABuffer对象中,25,prepare过程建立liveSource对象,fetchM3U读取.m3u8数据,下载index.m3u8的过程应该是一个原子过程,需要尽量能够得到完整的文件,而且HTTPStream对象在connect服务器后也把socket设置成阻塞类型,26,prepare过程建立liveSource对象,fetchM3U返回结果,fetchM3U把index.m3u8文件缓冲到buffer对象上后就直接把指针给了out参数,接之前loadPlayList的序列图,在完成fetchM3U之后构建M3UParser对.m3u8文件进行解析,27,prepare过程建立liveSource对象,解析m3u8文件,第一行必须是标准m3u8行头:,mMeta类型为AMessage,内部的Item就是K/Vtuple,其中Item的u部分是联合体,通过mType决定如何具体解读u,获取每个分片的播放长度,以秒计算并保存到mMeta中,例如15秒一个分片,28,prepare过程建立liveSource对象,解析m3u8文件,如果媒体分片很多.ts文件的索引可能包含在不同的.m3u8文件中按照sequence_number来顺序访问所有的.m3u8文件从而顺序索引到所有的.ts文件,行末,完成解析,并设置标记位退出while循环,29,prepare过程建立liveSource对象,解析m3u8文件,具体分片信息,分片时长Key=“duration”,指向下一个URI流的信息稍后说明,30,prepare过程建立liveSource对象,解析m3u8文件,这是可变带宽的.m3u8文件,此时设置mIsVariantPlaylist属性为true,这样其他所有对该m3u8文件中,非#EXT-X-STREAM-INF行的检测都略过,需要继续进行连接,获得非mIsVariantPlaylist的播放列表为止,例如:,31,prepare过程建立liveSource对象,解析m3u8文件,处理variantPlayList的大致过程:,1.如果#行是可变播放列表则剩下对#行的检查只检查#EXT-X-STREAM-INF行在parseStreamInf中获取这个stream的带宽值并保存到itemMeta中K/V=“bandwidth”,value,下面是parseStreamInf中关键位置的处理,32,prepare过程建立liveSource对象,解析m3u8文件,处理variantPlayList的大致过程:,2.读取下一行URI具体内容并根据之前获得此.m3u8的URI一起拼接成新的URI这个新的URI对应之前的带宽值,MakeURL判断BaseURI是否为绝对路径以http:/开头,不是则在最后一个/后加上line的内容,M3UParser.mItems保存着#行中需要继续构造URI获取数据的项目包括获取不同带宽的.m3u8文件的URI即#EXT-X-STREAM-INF(key=“bandwidth”)还有获取具体编码数据.ts文件的URI即#EXTINF(“key=duration”)在完成m3u8的parse后要检查mItems继续尝试连接服务器获取数据,M3UParser.mMeta保存着#行中不需要再继续构造URI的项目包括#EXT-X-TARGETDURATION就是一个固定值,33,prepare过程建立liveSource对象,解析m3u8文件,处理variantPlayList的大致过程:,3.读取完.m3u8文件直到#EXT-X-ENDLIST保存所有#EXT-X-STREAM-INF的bandwidth属性并拼接保存住对应的URI,4.完成m3u8的parse过程回到LiveSource.loadPlayList检查m3u8是否为variantPlayList类型的播放列表如果是则遍历获得所有的带宽值,都保存到mBandwidthItems:Vector中按照升序排列,34,prepare过程建立liveSource对象,解析m3u8文件,处理variantPlayList的大致过程:,5.尝试用最高带宽播放媒体,而最低带宽只要始终处于available状态即可,6.根据新的URI再次连接服务器获取.m3u8文件,如果这次还是variantPlayList就是错误的返回false正常情况,此时就获得了媒体分片索引的.m3u8文件了,内部都是.ts分片的uri,35,prepare过程onPrepareAsyncEvent处理finishSetDataSource,36,prepare过程建立NuCachedSource2对象,在NuCachedSource2内部也有自己的Looper,也是一个事件队列监视线程整个从服务器上fetch数据到缓存的过程就是通过post事件来驱动的NuCachedSource2:onMessageReceived(constsp&msg)处理具体的消息kWhatFetchMore用于缓冲数据,并保存到PageCache上,37,prepare过程建立NuCachedSource2对象,在NuCachedSource2类内与缓冲Cache有关的几个属性和类,38,prepare过程建立NuCachedSource2对象,从服务器缓存数据,整个android源码普遍使用sp智能指针,mTarget就是指向NuCachedSource2构造函数里this指针,39,prepare过程建立NuCachedSource2对象,从服务器缓存数据,gLooperRoster中维护着很多系统中类似的事件监视线程,构造AMessage对象时有mReflector-id用于区分找到目标Looper,从而可以post到目标Looper上,40,prepare过程建立NuCachedSource2对象,从服务器缓存数据,41,prepare过程建立NuCachedSource2对象,从服务器缓存数据,42,prepare过程建立NuCachedSource2对象,从服务器缓存数据,43,prepare过程建立NuCachedSource2对象,从服务器缓存数据,向事件队列插入消息时要检查插入的是否是队列中的第一个消息因为在监视线程中,如果判断当前队列为空则进入等待状态所以此处如果是第一个消息则发送信号量触发监视线程继续运行,44,prepare过程建立NuCachedSource2对象,从服务器缓存数据,说明:如果队列头是加了等待锁的事件(3.),可能的一种情况就是缓冲区内数据跟不上播放,此时需要等待缓冲,而缓冲的fetchMore事件也是在这个监视线程上工作的,但是fetchMore事件等待时间为0,所以在插入fetchMore事件时会排到队列头,从而先响应fetchMore事件,这样就在达到等待时继续缓冲数据的目的,当等待锁到时开始被响应时,缓冲区内也有一定数据可读了,45,prepare过程建立NuCachedSource2对象,从服务器缓存数据,46,prepare过程建立NuCachedSource2对象,从服务器缓存数据,整个HTTPLiveStreaming从服务器缓冲数据的过程大致如下:1.与服务器建立连接后获得媒体文件的大小,此时offset为02.与服务器通信的socket是阻塞类型如果无法recv到数据30秒后会收到系统INTER中断信号跳出recv函数继续事件监听线程函数的执行3.在客户端有一个事件监听线程始终在后台工作只要PageCache内缓冲的数据量没有达到上限5M就会尝试从服务器端获取数据4.接受的数据按照64k一页的方式按照顺序存储到PageCache中这样通过offset能够在PageCache中Seek需要的数据5.如果缓冲区到达缓冲上限,则fetchMore事件将被拖后执行,排在队列尾一段时间后,如果等待时间delayUs到达,才再继续从服务器获取数据6.当用户需要的数据块offset,offset+size不在缓冲区上时则会重新刷新缓冲区,此时就会继续缓冲新数据,47,从NuCachedSource2的缓冲中读取数据,缓冲命中的情况,readAt中的参数void*data是上层解码器的解码缓存,此处还是用memcpy的方式返回数据给上层,没有使用直接传指针可能是考虑到

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论