数据流的封装
一、

由数据源DataSource生成MediaExtractor。

通过MediaExtractor::Create(dataSource)来实现。Create方法通过两步来生成相应的MediaExtractor:

1、通过dataSource->sniff来探测数据类型

2、生成相应的Extractor:

 if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)

             || !strcasecmp(mime, "audio/mp4")) {

             return new MPEG4Extractor(source);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {

             return new MP3Extractor(source, meta);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)

             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {

             return new AMRExtractor(source);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WAV)) {

             return new WAVExtractor(source);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_OGG)) {

             return new OggExtractor(source);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MATROSKA)) {

             return new MatroskaExtractor(source);

             } else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {

             return new MPEG2TSExtractor(source);

             }

二、

接下来,通过以下代码把音视频轨道分离:

 if (!haveVideo && !strncasecmp(mime, "video/", )) {

             setVideoSource(extractor->getTrack(i));

             haveVideo = true;

             } else if (!haveAudio && !strncasecmp(mime, "audio/", )) {

             setAudioSource(extractor->getTrack(i));

             haveAudio = true;

生成mVideoTrack和mAudioTrack两个MediaSource。

三、

到目前为止我们得到的这两个MediaSource只具有parser功能,没有decode功能。还需要对这两个MediaSource做进一步的包装:

 mVideoSource = OMXCodec::Create(

             mClient.interface(), mVideoTrack->getFormat(),

             false, // createEncoder

             mVideoTrack,

             NULL, flags);

             mAudioSource = OMXCodec::Create(

             mClient.interface(), mAudioTrack->getFormat(),

             false, // createEncoder

             mAudioTrack);

这回又获取了两个MediaSource。它们具有parse和decode功能。当调用MediaSource.start()方法后,它的内部 就会开始从数据源获取数据并解析,等到缓冲区满后便停止。在AwesomePlayer里就可以调用MediaSource的read方法读取解码后的数 据。

对于mVideoSource来说:

读取的数据。

 mVideoSource->read(&mVideoBuffer, &options)

交给显示模块进行渲染。

 mVideoRenderer->render(mVideoBuffer);

对mAudioSource来说:

用mAudioPlayer对mAudioSource进行封装,然后由mAudioPlayer负责读取数据和播放控制。

AwesomePlayer流程
URI,FD

DataSource

MediaExtractor

|

mVideoTrack mAudioTrack//音视频数据流

mVideoSource mAudioSource//音视频解码器

| |

mVideoBuffer mAudioPlayer

上面示意了数据由源到最终解码后的流程。

1、设置DataSource,数据源可以两种URI和FD。URI可以http://,rtsp://等。FD是一个本地文件描述符,能过FD,可以找到对应的文件。

2、由DataSource生成MediaExtractor。通过sp extractor = MediaExtractor::Create(dataSource);来实现。 MediaExtractor::Create(dataSource)会根据不同的数据内容创建不同的数据读取对象。

3、通过调用setVideoSource由MediaExtractor分解生成音频数据流(mAudioTrack)和视频数据流(mVideoTrack)。

4、 onPrepareAsyncEvent()

如果DataSource是URL的话,根据地址获取数据,并开始缓冲,直到获取到mVideoTrack和mAudioTrack。

mVideoTrack和mAudioTrack通过调用initVideoDecoder()和initAudioDecoder()来生成mVideoSource和mAudioSource这两个音视频解码器。

然后调用postBufferingEvent_l()提交事件开启缓冲。数据缓冲的执行函数是onBufferingUpdate()。

缓冲区有足够的数据可以播放时,调用play_l()开始播放。play_l()中关键是调用了postVideoEvent_l(),提交了
mVideoEvent。这个事件执行时会调用函数onVideoEvent()。这个函数通过调用
mVideoSource->read(&mVideoBuffer,
&options)进行视频解码。音频解码通过mAudioPlayer实现。

视频解码器解码后通过mVideoSource->read读取一帧帧的数据,放到mVideoBuffer中,最后通过mVideoRenderer->render(mVideoBuffer)把视频数据发送到显示模块。

当需要暂停或停止时,调用cancelPlayerEvents来提交事件用来停止解码,还可以选择是否继续缓冲数据。

android stagefright基本流程总结的更多相关文章

  1. StageFright框架流程解读

    1.    StageFright介绍     Android froyo版本号多媒体引擎做了变动,新加入�了stagefright框架,而且默认情况android选择stagefright,并没有全 ...

  2. Android stagefright与opencore对比

      [转载至其它博客] http://blog.csdn.net/djy1992/article/details/9339917 1引言 Android froyo版本多媒体引擎做了变动,新添加了st ...

  3. Android WIFI 启动流程(TIP^^)

    前几天因为解决一堆Bug,没时间写.我不会每天都写,就是为了存档一些资料. 内容来源:工作中接触到的+高手博客+文档(Books)=自己理解 仅限参考^^ 此博客是上一个<<Android ...

  4. 【转】android 电池(二):android关机充电流程、充电画面显示

    关键词:android 电池关机充电 androidboot.mode charger关机充电 充电画面显示 平台信息:内核:linux2.6/linux3.0系统:android/android4. ...

  5. Android的开机流程

    Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) ...

  6. Android之 系统启动流程

    在前一篇文章"Android之 看“马达”如何贯通Android系统 (从硬件设计 --> 驱动 --> HAL --> JNI --> Framework --&g ...

  7. Android开发经验02:Android 项目开发流程

    Android开发完整流程:   一.用户需求分析 用户需求分析占据整个APP开发流程中最重要的一个环节.一款APP开发的成功与否很大程度都决定于此.这里所说的用户需求分析指的是基于用户的要求所进行的 ...

  8. android 电池(二):android关机充电流程、充电画面显示【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8498580 上一篇我们讲了锂电池的充放电的流程和电池的一些特性,这一节我们重点说一下a ...

  9. Android View 绘制流程(Draw) 完全解析

    前言 前几篇文章,笔者分别讲述了DecorView,measure,layout流程等,接下来将详细分析三大工作流程的最后一个流程——绘制流程.测量流程决定了View的大小,布局流程决定了View的位 ...

随机推荐

  1. nodejs 批处理运行 app.js

    1.直接执行run.bat文件         以下的内容为批处理文件run.bat中的内容,批处理命令中NODE_PATH为Node.js的安装路径. 使用express 生成的项目.app.js为 ...

  2. IOS总结_无需自己定义UITabbar也可改变UITabbarController的背景和点击和的颜色

    在application: application didFinishLaunchingWithOptions: launchOptions 增加以下代码就能够实现对tabbar的颜色的改动 //设定 ...

  3. arcengine 调用arctoolbox功能的举例 spatialJoin

    废话不多说,code是王道. 其中str1.str2两个参数是target路径.join路径 private void spatialJoin(Geoprocessor gp, string str1 ...

  4. NET基础课-- 类型基础(NET之美)

    1.类型:值类型  引用类型. 分类依据:类型在内存的分配方式.值类型在堆栈,引用类型在托管堆. 名词:栈--所有变量都会被分配在栈上,只不过值类型直接含有数据,引用类型含有一个指向托管堆对象的地址. ...

  5. photoshop动作面板批量处理图片边框技巧

    1,想给图片加上边框,在不改变图片大小的前提下,可以这样做:ctrl+a,全选图片,然后“编辑”-----“描边”,在跳出来的选项卡里面可以设置边框颜色,大小,位置,及混合模式, ,我们设置好了,就可 ...

  6. SQL日期形式转换

    在SQL Server中,有时存储在数据库中的日期格式和我们需要显示在页面上的格式不相同,我们需要转化成需要的格式. 特在此总结了一下常用的日期格式. --当前时间 SELECT GETDATE(); ...

  7. iOS-OC-基础-NSDictionary常用方法

    /*=============================NSDictionary(不可变字典)的使用=========================*/ //————————————————— ...

  8. iOS开发-单例模式的解读

    现在网上的有很多人写单例模式,一个很基本的东西但是版本也有很多,新人看了难免有些眼花缭乱的感觉.自己最新比较闲,也过来写一些自己的心得. 在往下看之前,我们要明白一点,那就是在什么情况下我们才要用到单 ...

  9. ORACLE SEQUENCE用法 (自增长)

    在oracle中sequence就是序号,每次取的时候它会自动增加.sequence与表没有关系. 1.Create Sequence     首先要有CREATE SEQUENCE或者CREATE ...

  10. shell中的数学运算

    shell中要进行数学运算通常有3中方法: expr命令 比如 expr 1 + 6就会返回7,使用expr的缺点就是碰到乘法运算,或者加括号(因为它们在shell中有其他意义),需要使用转义,比如: ...