在Android上,預設的多媒體框架(multimedia framework)是OpenCORE。 OpenCORE的優點是兼顧了跨平台的移植性,而且已經過多方驗證,所以相對來說較為穩定;但是其缺點是過於龐大複雜,需要耗費相當多的時間去維護。從 Android 2.0開始,Google引進了架構稍為簡潔的Stagefright,並且有逐漸取代OpenCORE的趨勢 (註1)。

[圖1] Stagefright在Android多媒體架構中的位置。

[圖2] Stagefright所涵蓋的模組 (註2)。
以下我們就先來看看Stagefright是如何播放一個影片檔。

Stagefright在Android中是以shared library的形式存在(libstagefright.so),其中的module -- AwesomePlayer可用來播放video/audio (註3)。AwesomePlayer提供許多API,可以讓上層的應用程式(Java/JNI)來呼叫,我們以一個簡單的程式來說明video playback的流程。

在Java中,若要播放一個影片檔,我們會這樣寫:

MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE); ...... (1)
mp.prepare(); ........................ (2)、(3)
mp.start(); .......................... (4)

在Stagefright中,則會看到相對應的處理;

(1) 將檔案的絕對路徑指定給mUri

status_t AwesomePlayer::setDataSource(const char* uri, ...)
{
  return setDataSource_l(uri, ...);
}

status_t AwesomePlayer::setDataSource_l(const char* uri, ...)
{
  mUri = uri;
}

(2) 啟動mQueue,作為event handler

status_t AwesomePlayer::prepare()
{
  return prepare_l();
}

status_t AwesomePlayer::prepare_l()
{
  prepareAsync_l();

while (mFlags & PREPARING)
  {
    mPreparedCondition.wait(mLock);
  }
}

status_t AwesomePlayer::prepareAsync_l()
{
  mQueue.start();

mFlags |= PREPARING;
  mAsyncPrepareEvent = new AwesomeEvent(
                             this
                             &AwesomePlayer::onPrepareAsyncEvent);
  mQueue.postEvent(mAsyncPrepareEvent);
}

(3) onPrepareAsyncEvent被觸發

void AwesomePlayer::onPrepareAsyncEvent()
{
  finishSetDataSource_l();

initVideoDecoder(); ...... (3.3)
  initAudioDecoder();
}

status_t AwesomePlayer::finishSetDataSource_l()
{
  dataSource = DataSource::CreateFromURI(mUri.string(), ...);
  sp<MediaExtractor> extractor =
                     MediaExtractor::Create(dataSource); ..... (3.1)

return setDataSource_l(extractor); ......................... (3.2)
}

(3.1) 解析mUri所指定的檔案,並且根據其header來選擇對應的extractor

sp<MediaExtractor> MediaExtractor::Create(const sp<DataSource> &source, ...)
{
  source->sniff(&tmp, ...);
  mime = tmp.string();

if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
  {
    return new MPEG4Extractor(source);
  }
  else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG))
  {
    return new MP3Extractor(source);
  }
  else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
  {
    return new AMRExtractor(source);
  }
}

(3.2) 使用extractor對檔案做A/V的分離 (mVideoTrack/mAudioTrack)

status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor)
{
  for (size_t i = 0; i < extractor->countTracks(); ++i)
  {
    sp<MetaData> meta = extractor->getTrackMetaData(i);

CHECK(meta->findCString(kKeyMIMEType, &mime));

if (!haveVideo && !strncasecmp(mime, "video/", 6))
    {
      setVideoSource(extractor->getTrack(i));
      haveVideo = true;
    }
    else if (!haveAudio && !strncasecmp(mime, "audio/", 6))
    {
      setAudioSource(extractor->getTrack(i));
      haveAudio = true;
    }
  }
}

void AwesomePlayer::setVideoSource(sp<MediaSource> source)
{
  mVideoTrack = source;
}

(3.3) 根據mVideoTrack中的編碼類型來選擇video decoder (mVideoSource)

status_t AwesomePlayer::initVideoDecoder()
{
  mVideoSource = OMXCodec::Create(mClient.interface(),
                                  mVideoTrack->getFormat(),
                                  false,
                                  mVideoTrack);
}


(4) 將mVideoEvent放入mQueue中,開始解碼播放,並交由mVideoRenderer來畫出

status_t AwesomePlayer::play()
{
  return play_l();
}

status_t AwesomePlayer::play_l()
{
  postVideoEvent_l();
}

void AwesomePlayer::postVideoEvent_l(int64_t delayUs)
{
  mQueue.postEventWithDelay(mVideoEvent, delayUs);
}

void AwesomePlayer::onVideoEvent()
{
  mVideoSource->read(&mVideoBuffer, &options);
  [Check Timestamp]
  mVideoRenderer->render(mVideoBuffer);

postVideoEvent_l();
}


stagefright框架(一)Video Playback的流程的更多相关文章

  1. stagefright框架(三)-选择Video Decode

    在<Stagefright (1) – Video Playback的流程>中,我们并没有详述Stagefright是如何根据影片档的类型来选择适合的video decoder,现在,就让 ...

  2. stagefright框架(六)-Audio Playback的流程

    到目前为止,我们都只着重在video处理的部分,对于audio却只字未提.这篇文章将会开始audio处理的流程. Stagefright中关于audio的部分是交由AudioPlayer来处理,它是在 ...

  3. StageFright框架流程解读

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

  4. stagefright框架(七)-Audio和Video的同步

    讲完了audio和video的处理流程,接下来要看的是audio和video同步化(synchronization)的问题.OpenCORE的做法是设置一个主clock,而audio和video就分别 ...

  5. Android Multimedia框架总结(八)Stagefright框架之AwesomePlayer及数据解析器

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52503057 前言:前面一篇分析了medi ...

  6. Android Multimedia框架总结(十)Stagefright框架之音视频输出过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012 前言:上篇文中最后 ...

  7. Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52532085 不知不觉到第九篇了,感觉还有 ...

  8. 微信公众帐号开发。大家是用框架还是自己写的流程。现在遇到若干问题。请教各路大仙 - V2EX

    微信公众帐号开发.大家是用框架还是自己写的流程.现在遇到若干问题.请教各路大仙 - V2EX 微信公众帐号开发.大家是用框架还是自己写的流程.现在遇到若干问题.请教各路大仙

  9. Maven SSH三大框架整合的加载流程

    <Maven精品教程视频\day02视频\03ssh配置文件加载过程.avi;> 此课程中讲 SSH三大框架整合的加载流程,还可以,初步接触的朋友可以听一听. < \day02视频\ ...

随机推荐

  1. vue 单页面应用实战

    1. 为什么要 SPA? SPA: 就是俗称的单页应用(Single Page Web Application). 在移动端,特别是 hybrid 方式的H5应用中,性能问题一直是痛点. 使用 SPA ...

  2. servlet乱码以及解决

    //  浏览器提交的数据是000110011(码表中对应的<编码> )等东西. // 浏览器以什么<码表>打开浏览器(而空中浏览器使用的编码是:<meta http-eq ...

  3. Apache 2.4.7在CentOS6.4中安装配置反向代理解决单外网IP对应多个内网主机的方法实践

    欢迎转载,转载时请保留全文及出处. Apache 2.4.7在CentOS6.4中安装配置反向代理解决单外网IP对应多个内网主机的方法实践 Apache安装 下载源程序(http://httpd.ap ...

  4. weblogic开机启动脚本

    1.在/home/bea/startBeaAll目录内创建一个startBeaAll.sh文件,加入如下内容(把相应目录与命令修改即可,红字部分为修改地方): #!/bin/sh echo " ...

  5. html验证码

    一.原理 1.在webservice服务端,新建一个Bitmap对象,将验证码字符串.干扰线和干扰点绘制到此Bitmap上——>转换为字节数组——>Base64字符串 2.<img ...

  6. 高性能PHP日志插件--Seaslog

    日志系统作为记录系统运行的信息,包括 用户输入,安全日志等,日志系统是不能影响用户的使用. 为什么需要记录日志? 既然日志系统增加了整个系统的开销,为什么我还需要它,这是因为日志能帮我们记录运行的很多 ...

  7. slave延迟原因及优化方法

    转载叶总:http://imysql.com/2015/04/12/mysql-optimization-case-howto-resolve-slave-delay.shtml 一般而言,slave ...

  8. 【HTML5】在head 设置 meta 能更方便开发

    <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initi ...

  9. nopCommerce 3.3正式发布及新增功能改进

    nopCommerce是一套优秀开源且基于Asp.net MVC的开源商城系统,nopCommerce 3.x经历长时间多个版本重构优化改进,目前已经趋于完善与成熟! nopCommerce 3.3正 ...

  10. php二分查找

    // 递归版本 function bin_sch($arr,$low,$high,$val) { if($low<$high){ $mid = intval(($low+$high)/2); i ...