Android多媒体开发(3)——Video Rendering

AwesomePlayer::onVideoEvent()除了通过OMXCodec::read()取得解码后的数据外,还必须将这些数据(mVideoBuffer)传给video renderer, 以便渲染到屏幕上去。

1.要将mVideoBuffer中的数据画出来之前,必须先创建mVideoRenderer的实例。

void AwesomePlayer::onVideoEvent()
{  
    ...  
    if (mVideoRenderer == NULL)  
    {    
        initRenderer_l();  
    }  
    ...
}

void AwesomePlayer::initRenderer_l()
{  
    if (!strncmp("OMX.", component, 4))  
    {    
        mVideoRenderer = new AwesomeRemoteRenderer(
                mClient.interface()->createRenderer(
                                     mISurface, 
                                     component, 
                                     ...));  .......... (2)  
    }  
    else  
    {    
        mVideoRenderer = new AwesomeLocalRenderer(
                                     ...,
                                     component, 
                                     mISurface); ............................ (3)  
    }
}

2.如果video decoder是OMX component,则创建一个AwesomeRemoteRenderer作为mVideoRenderer。

从上面的程序来看,AwesomeRemoteRenderer的本质是由OMX::createRenderer所创建的。createRenderer会先创建一个hardware renderer -- SharedVideoRenderer (libstagefrighthw.so);若失败,则创建software renderer -- SoftwareRenderer (surface)。

sp<IOMXRenderer> OMX::createRenderer(...)
{  
    VideoRenderer *impl = NULL;  
    libHandle = dlopen("libstagefrighthw.so", RTLD_NOW);  
    if (libHandle)  
    {    
        CreateRendererFunc func = dlsym(libHandle, ...);    
        impl = (*func)(...); <----------------- Hardware Renderer  
    }  
    if (!impl)  
    {    
        impl = new SoftwareRenderer(...); <---- Software Renderer  
    }
}

3.如果video decoder是software component,则创建一个AwesomeLocalRenderer作为mVideoRenderer。

AwesomeLocalRenderer的constructor会调用本身的init函数,其所做的事和OMX::createRenderer一模一样。

void AwesomeLocalRenderer::init(...)
{  
    mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);  
    if (mLibHandle)  
    {    
        CreateRendererFunc func = dlsym(...);    
        mTarget = (*func)(...); <---------------- Hardware Renderer  
    }  
    if (mTarget == NULL)  
    {    
        mTarget = new SoftwareRenderer(...); <--- Software Renderer  
    }
}
AwesomeRenderer

4.mVideoRenderer一旦创建就可以开始将解码后的数据传给它。

void AwesomePlayer::onVideoEvent()
{  
    if (!mVideoBuffer)  
    {    
        mVideoSource->read(&mVideoBuffer, ...);  
    }  
    [Check Timestamp]  
    if (mVideoRenderer == NULL)  
    {    
        initRenderer_l();  
    }  
    mVideoRenderer->render(mVideoBuffer); <----- Render Data
}

AwesomePlayer流程图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本篇文章是基于谷歌有关Graphic的一篇概览文章的翻译:http://source.android.com/de...
    lee_3do阅读 11,977评论 2 21
  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 10,256评论 0 3
  • 原文:https://developer.android.com/reference/android/media/...
    thebestofrocky阅读 11,301评论 0 6
  • 随着互联网技术的飞速发展,移动端播放视频的需求如日中天,由此也催生了一批开源/闭源的播放器,但是无论这个播放器功能...
    金山视频云阅读 46,668评论 28 170
  • 内需 做刚需的事情 注意力 的大坑 1.莫名其妙的凑热闹 2.火急火燎的随大流 3.操碎别人的心 我中招操碎别人的...
    骑脚踏车的骑士小姐阅读 1,846评论 0 0