分享

Android-StageFright之decode

 Kevin之泊心亭 2011-12-22

Android-StageFright之decode

上一篇“数据流的封装“中, 最后得到的两个MediaSource其实是两个OMXCodec。AwesomePlayer和mAudioPlayer都是从MediaSource 中得到数据进行播放的。AwesomePlayer得到的是最终需要渲染的原始视频数据,而mAudioPlayer读取的是最终需要播放的原始音频数 据。也就是说,从OMXCodec中读到的数据已经是原始数据了。下面分析一下OMXCodec是怎么把数据源经过parse、decode两步以后转化 成原始数据的。

从OMXCodec::Create这个构造方法开始,先看一下它的参数:

IOMX &omx

经过层层追踪,跨过OpenBinder机制,我们发现它是其实是一个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:

1
2
3
4
5
6
7
sp<OMXCodec> codec = new OMXCodec(
 
                    omx, node, quirks,
 
                    createEncoder, mime, componentName,
 
                    source);

这样就得到了OMXCodec。

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

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

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

AwesomePlayer开始播放后,通过mVideoSource->read(&mVideoBuffer, &options)读取数据。

mVideoSource->read(&mVideoBuffer, &options)具体是调用OMXCodec.read来读取数据。而OMXCodec.read主要分两步来实现数据的读取:

1、通过调用drainInputBuffers()对mPortBuffers[kPortIndexInput]进行填充,这一步完成parse。由OpenMAX从数据源把demux后的数据读取到输入缓冲区,作为OpenMAX的输入。

2、通过fillOutputBuffers()对mPortBuffers[kPortIndexOutput]进行填充,这一步完成decode。由OpenMAX对输入缓冲区中的数据进行解码,然后把解码后可以显示的视频数据输出到输出缓冲区。

AwesomePlayer通过mVideoRenderer->render(mVideoBuffer)对经过parse和decode 处理的数据进行渲染。一个mVideoRenderer其实就是一个包装了IOMXRenderer的AwesomeRemoteRenderer:

1
2
3
4
5
6
7
8
9
10
11
12
13
mVideoRenderer = new AwesomeRemoteRenderer(
 
                mClient.interface()->createRenderer(
 
                        mISurface, component,
 
                        (OMX_COLOR_FORMATTYPE)format,
 
                        decodedWidth, decodedHeight,
 
                        mVideoWidth, mVideoHeight,
 
                        rotationDegrees));

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约