`
java-admin
  • 浏览: 1365122 次
  • 性别: Icon_minigender_1
  • 来自: 陕西.西安
社区版块
存档分类
最新评论

Android Overlay学习 一

阅读更多

前文仅了解了overlay HAL的架构,下面继续看看系统层是如何调用Overlay模块。

1、 测试代码

frameworks/base/libs/surfaceflinger/tests/overlays/overlays.cpp提供了一个简单的overlay调用流程,可惜这个测试程序有错误,
    在sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240, PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);
这句话编译不过去,错误在Surface的申请,和overlay无关。

我们来看看这段代码:

int main(int argc, char** argv)
{
    // set up the thread-pool 建立线程池
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // create a client to surfaceflinger 创建一个SurfaceFlinger client
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
   
    // create pushbuffer surface 创建一个surface,最后那个参数是类型?
    sp<Surface> surface = client->createSurface(getpid(), 0, 320, 240,
            PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);

    // get to the isurface 取得isurface接口
    sp<ISurface> isurface = Test::getISurface(surface);
    printf("isurface = %p\n", isurface.get());
   
    // now request an overlay 创建一个overlay
    sp<OverlayRef> ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);
    sp<Overlay> overlay = new Overlay(ref);
   
    /*
     * here we can use the overlay API 创建好overlay后,即可使用overlay的API,这些都对应到overlay HAL的具体实现
     */
   
    overlay_buffer_t buffer;
    overlay->dequeueBuffer(&buffer);
    printf("buffer = %p\n", buffer);
   
    void* address = overlay->getBufferAddress(buffer);
    printf("address = %p\n", address);

    overlay->queueBuffer(buffer);//最重要的操作就是通过queueBuffer将buffer列队

    return 0;
}

2、Android系统创建中Overlay(调用createOverlay)

1)摄像头相关 CameraService.cpp (frameworks\base\camera\libcameraservice)
setPreviewDisplay()、startPreviewMode()
|
setOverlay()
|
creatOverlay()

2)界面相关 ISurface.cpp (frameworks\base\libs\ui)
LayerBaseClient::Surface::onTransact() <--该函数位于LayerBase.cpp,好像是用于ibind进程通讯的函数
|
BnSurface::onTransact() //有5种方式,只有确定有overlay硬件支持时才会调用case CREATE_OVERLAY
|
... ...
switch(code) {
        case REQUEST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            int bufferIdx = data.readInt32();
            int usage = data.readInt32();
            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
            return GraphicBuffer::writeToParcel(reply, buffer.get());
        }
        case REGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            BufferHeap buffer;
            buffer.w = data.readInt32();
            buffer.h = data.readInt32();
            buffer.hor_stride = data.readInt32();
            buffer.ver_stride= data.readInt32();
            buffer.format = data.readInt32();
            buffer.transform = data.readInt32();
            buffer.flags = data.readInt32();
            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
            status_t err = registerBuffers(buffer);
            reply->writeInt32(err);
            return NO_ERROR;
        } break;
        case UNREGISTER_BUFFERS: {
            CHECK_INTERFACE(ISurface, data, reply);
            unregisterBuffers();
            return NO_ERROR;
        } break;
        case POST_BUFFER: {
            CHECK_INTERFACE(ISurface, data, reply);
            ssize_t offset = data.readInt32();
            postBuffer(offset);
            return NO_ERROR;
        } break;
        case CREATE_OVERLAY: {
            CHECK_INTERFACE(ISurface, data, reply);
            int w = data.readInt32();
            int h = data.readInt32();
            int f = data.readInt32();
            sp<OverlayRef> o = createOverlay(w, h, f);
            return OverlayRef::writeToParcel(reply, o);
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
... ...


3)LayerBuffer.cpp (frameworks\base\libs\surfaceflinger) 这儿其实是createOverlay的实现
sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format)
|
sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f)
|
sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f); //通过OverlaySource来创建overlay

LayerBuffer::OverlaySource::OverlaySource()//该函数调用了Overlay HAL的API createOverlay
{
    overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();//get HAL
    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);//HAL API

    // enable dithering...
    overlay_dev->setParameter(overlay_dev, overlay, OVERLAY_DITHER, OVERLAY_ENABLE);
//设置参数,初始化OverlayRef类,OverlayRef的构造函数在Overlay.cpp中
    mOverlay = overlay;
    mWidth = overlay->w;
    mHeight = overlay->h;
    mFormat = overlay->format;
    mWidthStride = overlay->w_stride;
    mHeightStride = overlay->h_stride;
    mInitialized = false;
... ...
    *overlayRef = new OverlayRef(mOverlayHandle, channel,mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
}

3、Overlay HAL模块管理
Overlay.cpp (frameworks\base\libs\ui)负责管理overlay HAL,并对HAL的API进行封装

1)打开Overlay HAL模块
Overlay::Overlay(const sp<OverlayRef>& overlayRef)
    : mOverlayRef(overlayRef), mOverlayData(0), mStatus(NO_INIT)
{
    mOverlayData = NULL;
    hw_module_t const* module;
    if (overlayRef != 0) {
        if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
            if (overlay_data_open(module, &mOverlayData) == NO_ERROR) {
                mStatus = mOverlayData->initialize(mOverlayData,
                        overlayRef->mOverlayHandle);
            }
        }
    }
}

2)Overlay HAL的初始化
参考上一段,overlayRef = new OverlayRef(mOverlayHandle, channel,mWidth, mHeight, mFormat, mWidthStride, mHeightStride);

构造函数位于Overlay.cpp
OverlayRef::OverlayRef(overlay_handle_t handle, const sp<IOverlay>& channel,
         uint32_t w, uint32_t h, int32_t f, uint32_t ws, uint32_t hs)
    : mOverlayHandle(handle), mOverlayChannel(channel),
    mWidth(w), mHeight(h), mFormat(f), mWidthStride(ws), mHeightStride(hs),
    mOwnHandle(false)
{
}

3)封装了很多的API,但是没有查到那儿有调用,看来还需要大改框架才能真正将overlay利用起来
比如TI自己写的opencore函数中到时有用到,主要负责视频输出。
Android_surface_output_omap34xx.cpp (hardware\ti\omap3\libopencorehw)

 

4、总结
Overlay的输出对象有两种,一种是视频(主要是YUV格式,调用系统的V4L2),另外一个是ISurface的一些图像数据(RGB格式,直接写framebuffer)
从代码实现角度看,目前Android系统默认并没有使用Overlay功能,虽然提供了Skeleton的Overlay HAL,并对其进行封装,但是上层几乎没有调用到封装的API。
如果要用好Overlay HAL,需要大量修改上层框架,这对视屏播放可能比较重要,可参考TI的Android_surface_output_omap34xx.cpp。
此外Surface实现的Overlay功能和Copybit的功能有部分重复,从TI的代码看主要是实现V4L2的Overlay功能。

 

 

分享到:
评论
1 楼 ishelf 2010-11-19  
bs你这种人,转载文章请注明!文章出处http://hi.baidu.com/aokikyon/blog/item/6e4e622c4fdaaae18a1399d4.html。自己看时间

相关推荐

    Android google Map地图学习

    此资料包含 Android学习笔记 - 地图.doc 通过地名获得经纬度并标识在地图上.doc 点中overlay弹出带尾巴的气泡的实现.doc 传递坐标到Google地图.doc android map.doc Android地图和定位学习总结 .doc 希望对大家有...

    android系统原理及开发要点详解

     嵌入式Linux系统学习者:将Android作为一个集Linux核心和应用层程序于一体的系统进行学习,并可以利用Android的仿真环境运行和调试程序。  读者在学习本书的过程中,应尽量对照本书的框图和手头的Android源代码,...

    Android高级编程--源代码

    作为使用androidsdk构建这些应用程序的实用指南书籍,《android高级编程》从始至终穿插了一系列示例项目,每个项目都引入android的新功能和新技术,以助您达到最圆满的学习效果。书中介绍android的所有基本功能,并...

    [Android.UI基础教程].Jason.Ostrander.扫描版.pdf

    [Android.UI基础教程].Jason.Ostrander.扫描版,关于android的UI设计方面的知识,学习过程的经典书

    android系统原理及开发要点详解_韩超_梁泉 4

     嵌入式Linux系统学习者:将Android作为一个集Linux核心和应用层程序于一体的系统进行学习,并可以利用Android的仿真环境运行和调试程序。  读者在学习本书的过程中,应尽量对照本书的框图和手头的Android源代码,...

    《Android高级编程》

    作为使用AndroidSDK构建这些应用程序的实用指南书籍,《Android高级编程》从始至终穿插了一系列示例项目,每个项目都引入Android的新功能和新技术,以助您达到最圆满的学习效果。书中介绍Android的所有基本功能,并...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part1

    本书适合Android研发人员及Android爱好者学习,也可以作为相关培训学校和大专院校相关专业的教学用书。 全书压缩打包成3部分,这是第1部分。 目录: 第1章 Android底层开发基础 1 1.1 什么是驱动 1 ...

    android系统原理及开发要点详解_韩超_梁泉 1

     嵌入式Linux系统学习者:将Android作为一个集Linux核心和应用层程序于一体的系统进行学习,并可以利用Android的仿真环境运行和调试程序。  读者在学习本书的过程中,应尽量对照本书的框图和手头的Android源代码,...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part3

    本书适合Android研发人员及Android爱好者学习,也可以作为相关培训学校和大专院校相关专业的教学用书。 全书压缩打包成3部分,这是第3部分。 目录: 第1章 Android底层开发基础 1 1.1 什么是驱动 1 ...

    一本android的好书beginning android 2 和 源码

    这是一本学习android的好书,我浏览了,是老外著的,高清晰的pdf。为了方便大家学习android,我将本书所附的源码一块打包了。方便了不少,如果觉得好就顶一下吧,大家共同进步。 另外一本pro android 的下载地址: ...

    ffmpeg-水印(第一章资源)-android环境调用ffmpeg的demo

    ffmpeg-水印(第一章资源)-android环境调用ffmpeg的demo(适合学习) "snprintf(filter_args, sizeof(filter_args), "movie=%s[wm];[in][wm]overlay=5:5[out]", logoPath);"解说: [in]表示 初始化滤镜的 inputs-&gt;...

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part2

    本书适合Android研发人员及Android爱好者学习,也可以作为相关培训学校和大专院校相关专业的教学用书。 全书压缩打包成3部分,这是第2部分。 目录: 第1章 Android底层开发基础 1 1.1 什么是驱动 1 ...

    learning_gradle_android:学习如何构建启用 gradle 的 android 项目

    learning_gradle_android 学习如何构建启用 gradle 的 android 项目01_basic:将简单的 eclpise 项目转换为启用 gradle 的项目02_dependency:支持库项目03_sign:支持apk签名机制04_proguard:在gradle中使用...

    安卓SlidingMenu各种菜单侧滑菜单相关-OverlayMenuAndroid覆盖菜单.rar

    Overlay Menu Android覆盖菜单.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

    RaspberryPi:站在树莓派上的可持续逻辑

    自述文件 个人认为,树莓派应该算是现有的开源硬件里...利用Overlay加载AT24C02 I2C驱动,通过i2c-tools获取数据 0017 通过Python3 Flask / websocket作为服务端,使用GPIO控制网页背景 0016 通过Python3 Flask作为HTT

Global site tag (gtag.js) - Google Analytics