stagefright简介

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、StageFright介绍

Android froyo版本多媒体引擎做了变动,新添加了stagefright框架,并且默认情况android 选择stagefright,并没有完全抛弃opencore,主要是做了一个OMX层,仅仅是对opencore 的omx-component部分做了引用。stagefright是在MediaPlayerService这一层加入的,和opencore是并列的。Stagefright在Android中是以shared library的形式存在(libstagefright.so),其中的module -- AwesomePlayer可用来播放video/audio。AwesomePlayer提供许多API,可以让上层的应用程序(Java/JNI)来调用。

2、StageFright数据流封装

2.1》由数据源DataSource生成MediaExtractor。通过MediaExtractor::Create(dataSource)来实现。Create方法通过两步来生成相应的MediaExtractor(MediaExtractor.cpp):通过dataSource-λ>sniff来探测数据类型

生成相应的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);

}

2.2》把音视频轨道分离,生成mVideoTrack和mAudioTrack两个MediaSource。代码如下(AwesomePlayer.cpp):

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;

}

2.3》得到的这两个MediaSource,只具有parser功能,没有decode功能。还需要对这两个MediaSource做进一步的包装,获取了两个MediaSource(具有parse和decode功能):mVideoSource = OMXCodec::Create(

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

false, // createEncoder

mVideoTrack,

NULL, flags);

mAudioSource = OMXCodec::Create(

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

false, // createEncoder

mAudioTrack);

当调用MediaSource.start()方法后,它的内部就会开始从数据源获取数据并解析,等到缓冲区满后便停止。在AwesomePlayer里就可以调用MediaSource的read方法读取解码后的数据。

对于mVideoSource来说,读取的数据:mVideoSource-ν>read(&mVideoBuffer, &options)交给显示模块进行渲染,mVideoRenderer->render(mVideoBuffer);

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

3、StageFright的Decode

经过“数据流的封装”得到的两个MediaSource,其实是两个OMXCodec。AwesomePlayer 和mAudioPlayer都是从MediaSource中得到数据进行播放。AwesomePlayer得到的是最终需要渲染的原始视频数据,而mAudioPlayer读取的是最终需要播放的原始音频数据。也就是说,从OMXCodec中读到的数据已经是原始数据了。

OMXCodec是怎么把数据源经过parse、decode两步以后转化成原始数据的。从OMXCodec::Create这个构造方法开始,它的参数:

IOMXν &omx指的是一个OMXNodeInstance对象的实例。

MetaDataν&meta这个参数由MediaSource.getFormat获取得到。这个对象的主要成员就是一个KeyedVector mItems,里面存放了一些代表MediaSource格式信息的名值对。

bool createEncoder指明这个OMXCodec是编码还是解码。ν

MediaSource &source是一个MediaExtractor。ν

char *matchComponentName指定一种Codec用于生成这个OMXCodec。ν

先使用findMatchingCodecs寻找对应的Codec,找到以后为当前IOMX分配节点并注册事件监听器:omx->allocateNode(componentName, observer, &node)。最后,把IOMX封装进一个OMXCodec:

sp codec = new OMXCodec(

omx, node, quirks,

createEncoder, mime, componentName,

source);

这样就得到了OMXCodec。

AwesomePlayer中得到这个OMXCodec后,首先调用mVideoSource->start()进行初始化。OMXCodec初始化主要是做两件事:

向OpenMAX发送开始命令。mOMX-ν>sendCommand(mNode, OMX_CommandStateSet, OMX_StateIdle)

调用allocateBuffers()分配两个缓冲区,存放在Vectorν mPortBuffers[2]中,分别用于输入和输出。

相关文档
最新文档