android 如何编译overlay

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 如何编译overlay相关的知识,希望对你有一定的参考价值。

参考技术A android
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功能。本回答被提问者和网友采纳

以上是关于android 如何编译overlay的主要内容,如果未能解决你的问题,请参考以下文章

如何定制android源码的编译选项

编译 Android 时如何指定输出目录?

如何编译Android的kernel

如何反编译android应用并重新打包

如何反编译android应用并重新打包

android编译的时候 是如何配置默认显示横竖屏