第三部分 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功能。
第三部分 overlay 学习的更多相关文章
- C#中的线程三 (结合ProgressBar学习Control.BeginInvoke)
C#中的线程三(结合ProgressBar学习Control.BeginInvoke) 本篇继上篇转载的关于Control.BeginInvoke的论述之后,再结合一个实例来说明Cotrol.Begi ...
- 三、Android学习第三天——Activity的布局初步介绍(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 三.Android学习第三天——Activity的布局初步介绍 今天总结下 ...
- JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB
JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...
- 精通ASP.Net MVC 3 框架(第三版)学习笔记
精通ASP.Net MVC 3 框架(第三版)学习笔记 代码才是王道. http://pan.baidu.com/s/1pJyL1cn
- JavaWeb学习总结(三)——Tomcat服务器学习和使用
收藏 JavaWeb学习总结(三)——Tomcat服务器学习和使用 http://www.cnblogs.com/xdp-gacl/p/3744053.html
- JavaScript高级程序设计(第三版)学习,第一次总结
Array类型 var arr = []; arr.length; //返回数组元素个数 改变length可以动态改变数组大小 检测数组 instanceof可以检测某个对象是否是数组,限制:只能是一 ...
- DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D
本文从哈利_创.转载请注明出处.有问题欢迎联系本人! 邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...
- 第三周java学习总结
学号 20175206 <Java程序设计>第三周学习总结 教材学习内容总结 本周为第四章的学习,分为以下几个方面: 1.包与代码组织 2.String类 3.对象创建 4.包装类 经过代 ...
- 2018年-2019年第二学期第三周C#学习个人总结
在第三周,我们又开始了C#的进一步学习,学习的范围是从4.8static关键字到4.11对象初始化器.在4.8static关键字我学到了静态字段,静态属性,静态方法,静态类,静态构造方法单例模式,嵌套 ...
随机推荐
- 浏览器的visibilitychange 事件ie10以下不兼容
方法1, <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- Describe the difference between repeater, bridge and router.
中继器,路由器,网桥,网关的区别. 路由器:网络层设备,实现复杂的路径选择,控制IP包从源到目的地的路径:根据IP地址进行选路和转发IP数据包 中继器:物理层设备,物理信号的重新生成,对信号进行整形和 ...
- C# 返回json结果集,js日期格式化
asp.net mvc返回json结果集 return Json(new { total = totalCount, rows = result }, JsonRequestBehavior.Allo ...
- 2015-4-2的阿里巴巴笔试题:乱序的序列保序输出(bit数组实现hash)
分布式系统中的RPC请求经常出现乱序的情况.写一个算法来将一个乱序的序列保序输出.例如,假设起始序号是1,对于(1, 2, 5, 8, 10, 4, 3, 6, 9, 7)这个序列,输出是:123, ...
- Web前端框架学习成本比较及学习方法
就项目中自己用过的前端框架的学习成本比较与学习心得分享 刚工作时间不长只用过这几个框架下面是难易程度比较: 不论哪个web前端框架, 究其本质都是把页面的数据传递给后台服务器语言(如java)进行处理 ...
- 有关hadoop分布式配置详解
linux配置ssh无密码登录 配置ssh无密码登录,先要安装openssh,如下: yum install openssh-clients 准备两台linux服务器或虚拟机,设置两台linux的ho ...
- java程序练习:x进制转Y进制
/*X进制到Y进制转换*/ /*Step1.提示用户输入数据的进制X *Step2.接收用户输入的数据,保存到X * Scanner方法 *Step3.接收用户输入X进制的数据,保存到num *Ste ...
- C# SqlConnection
public static ArrayList Connect(string connectionString, string commandText) { ArrayList retValList ...
- MVC中的@Html.DisplayFor等方法如何控制日期的显示格式(转) - Rising
在Sql Server2005中,如果将某字段定义成日期 时间 类型DateTime,那么在视图中会默认显示成年月日时分秒的方式(如 2013/8/6 13:37:33) 如果只想显示成年 ...
- 团体程序设计天梯赛-练习集L1-007. 念数字
L1-007. 念数字 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 翁恺 输入一个整数,输出每个数字对应的拼音.当整数为负数时,先 ...