stagefright使用surfaceflinger buffer 的分析

之前学习了surfaceflinger和stagefright 两大模块,
这两大模块之间联系最大的地方,就是surfaceflinger 管理显示buffer,然后stagefright 如何用这个buffer
这里总结一下这一块自己学习的知识点
平台samsung exynos ,android 4.4

实际上本文想研究的就是三个问题:
(1)如何获取显示buffer,并且怎么把它告诉给OMX
(2)解码的时候,OMX如何把这个buffer告诉给解码器,作为视频数据输出的buffer
(3)有了buffer了,buffer里面有了数据了,如何显示出来
下面对这三点分开讨论

本文参考了大牛 http://blog.youkuaiyun.com/gzzaigcn/article/category/2135451 的一些分析。
在此文章基础上做了扩展。感谢前人的肩膀。

一,如何申请显示output buffer,以及如何设置给OMX来使用

1.来看解码输出缓存在surfaceflinger下的缓存申请:
status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {  
 if (mNativeWindow != NULL && portIndex == kPortIndexOutput)
 {  
 return allocateOutputBuffersFromNativeWindow();//使用surface渲染,为输出分配图形缓存GraphicBuffer  
}  
可以看到当申请的是NativeWindow形式的buffer,这说明了输出的buffer是需要去直接完成render的,所以输出缓存区要从本地窗口buffer进行申请:

2.allocateOutputBuffersFromNativeWindow的实现

SurfaceFlinger架构下的Buffer申请机制可以看前面提到的博文,  
先贴代码,已经去除一些细枝末节的代码:
status_t OMXCodec::allocateOutputBuffersFromNativeWindow()
{
    status_t err = mOMX->getParameter(
            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
    if (err != OK) {
        CODEC_LOGE("getParameter failed: %d", err);
        return err;
    }
    err = native_window_set_buffers_geometry(
            mNativeWindow.get(),
            def.format.video.nFrameWidth,
            def.format.video.nFrameHeight,
            def.format.video.eColorFormat);
    // Set up the native window.
    OMX_U32 usage = 0;
    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
    ALOGV("native_window_set_usage usage=0x%lx", usage);
    err = native_window_set_usage(
            mNativeWindow.get(), usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
    if (err != 0) {
        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
        return err;
    }
    err = native_window_set_buffer_count(
            mNativeWindow.get(), def.nBufferCountActual);
    if (err != 0) {
        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
                -err);
        return err;
}
    // Dequeue buffers and send them to OMX
    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
        ANativeWindowBuffer* buf;
        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
        if (err != 0) {
            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
            break;
        }
        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
        BufferInfo info;
        info.mData = NULL;
        info.mSize = def.nBufferSize;
        info.mStatus = OWNED_BY_US;
        info.mMem = NULL;
        info.mMediaBuffer = new MediaBuffer(graphicBuffer);
        info.mMediaBuffer->setObserver(this);
        mPortBuffers[kPortIndexOutput].push(info);
        IOMX::buffer_id bufferId;
        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
                &bufferId);
        if (err != 0) {
            CODEC_LOGE("registering GraphicBuffer with OMX IL compo
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值