视频framework学习总结

本文主要介绍了Android平台上的本地视频播放与流媒体播放的实现原理。本地视频播放涉及MediaPlayer的setDataSource、prepareAsync和start方法,通过NuPlayer框架进行解码。流媒体播放则涉及到RTP、RTCP、RTSP协议,通过RTSPSource与服务器交互获取SDP文件,建立RTP和RTCP数据链接。文章详细解析了数据传输和解码的过程,包括MediaExtractor、MediaCodec与OpenMAX之间的交互。
摘要由CSDN通过智能技术生成

1 前言
视频学习这里总结两部分,分别为本地视频播放以及基于RTSP的流媒体播放(还有基于HLS的流媒体播放,暂时没有深入了解)。本地视频就是用户下载的视频文件播放,而流媒体就是用户基于网络在线播放的视频,可以分为点播和直播两种。
2 本地视频播放
要实现播放一个视频文件,只要调用以下三个函数即可:setDataSource、prepareAsync
监听到prepareAsync 完成的消息后再调用start的方法。这里以Y5II(MTK6735芯片)代码为基础来分析。
当java层代码调用setDataSource方法时候,会通过JNI调用到MediaPlayer的setDataSource(int fd, int64_t offset, int64_t length)方法。代码如下:

在这里会通过binder获取到一个MediaPlayerService的对象service。然后通过create的方创建一个Client的对象,而Client就是IMediaPlayer的binder机制的服务端的实现,所以service创建的IMediaPlayer对象就是Client的对象,然后可以通过Bn端的Client对象调用setDataSource生成相应的player。

在setDataSource的方法中会通过MediaPlayerFactory获取playerType,在getDefaultPlayerType()方法中默认返回的是NU_PLAYER的类型。然后在setDataSource_pre()的方法中会调用createPlayer()的方法,最终调用到MediaPlayerFactory::createPlayer(playerType, this, notify);方法。这里会根据注册的Factory来生成对应的player,根据NU_PLAYER的类型,调用到NuPlayerFactory的createPlayer()方法。

这里返回的是一个NuPlayerDriver的对象,在NuPlayerDriver的构造函数中会为Looper注册相关的hander,并且生成了一个HwNuPlayer的对象,而这个对象是继承NuPlayer的。所以这里最终调用的是NuPlayer的框架。
在MediaPlayerService的Client类中的setDataSource()方法里面通过setDataSource_post(p, p->setDataSource(fd, offset, length));调用到了NuPlayer的setDataSourceAsync()方法。

这里会定义两个AMessage对象,其中kWhatSetDataSource是通知NuPlayerDriver已经完成了设置操作,而kWhatSourceNotify是传递给GenericSource对象的,GenericSource是专门处理本地视频的对象。
当java层代码调用setDataSource之后,会调用prepareAsync的方法。这里会通过JNI调用到MediaPlayer的prepareAsync()方法,接着调用到prepareAsync_l()的方法。

这里会调用到mPlayer的prepareAsync()的方法,而这个mPlayer就是setDataSource()方法里面生成的Client的对象。

这里会调用的是NuPlayer的prepareAsync()方法。

Post了一个消息,看看这个消息具体做了什么?

抛弃掉MTK的宏定义的内容,其实调用的是mSource的方法,这个mSource针对本地视频对应的是GenericSource。

这里注册相关Looper,并且post了一个kWhatPrepareAsync的消息。在GenericSource的消息接收后会执行到onPrepareAsync()的方法。

这里省略了部分代码,只保留了重要部分的代码。刚开始mDataSource是空的,所以会生成一个mDataSource的对象,这里会打开本地文件,赋值文件句柄给mFd的对象。接着会执行initFromDataSource()的方法,这个方法主要是生成相应的MediaExtractor,并获取相关的音视频文件,这里也只是保留了重要部分的代码。

首选检测mDataSource是否为空,不为空的话,会调用MediaExtractor的create方法,生成相应的extractor。

在Create方法里面会根据mDataSource里面注册的RegisterSniffer_l()方法来判断当前文件是属于那种媒体文件,然后

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值