先放demo源码地址:https://github.com/xxxzhou/aoce 06_mediaplayer

  效果图:

  

  主要几个点:

  • 用ffmpeg打开rtmp流。
  • 使用vulkan Compute shader处理yuv420P/yuv422P数据格式成rgba.
  • 初始化android surface为vulkan的交换链,把如上结果复制到交换链上显示。
  • 如果是opengles surface,如何不通过CPU直接把数据从vulkan复制到opengles里。

  这个demo主要是为了验证用vulkan做GPGPU处理后,能输出到vulkan/opengles纹理,后续有可能的话,明年下半年业余时间在这项目用vulkan Compute shader移植GPUImage学习下,设计的运行平台是window/android,你可以在window平台用vscode(安装相应cmake/C++插件)运行查看调试过程,也可以用android studio打开里面的android文件夹,运行06_mediaplayer查看对应如上效果。  

集成ffmpeg

  window平台自己编译后放入aoce/thirdparty/ffmpeg/x64中,android 我直接用的这位同学编译好的https://github.com/xufuji456/FFmpegAndroid,你也可以在https://github.com/xxxzhou/aoce_thirdparty下载我整理好的。

  如下目录放置就好。

  

  cmake里填写好相关window/android平台逻辑以后,你可以选择在window端直接用vscode,也可以用MVS打开cmake生成的sln文件,用android studio打开android文件夹,自动Sync gradle引用cmake并编译好相关C++项目。

  相应ffmpeg播放器FMediaPlayer的实现我参照了android下的MediaPlayer的接口设计,主要是prepare这个接口让我意识到我在oeip不合理的地方,按照android下的MediaPlayer的接口重新实现了下ffmpeg里播放实现,现在只是简单走了下流程,后期还需要设计各个状态的转化。

用vulkan的Compute shader做GPGPU计算

  这个是我在 Vulkan在Android使用Compute shader 就准备做的事,设想是用有序无环图来构建GPU计算流程,这个demo也算是简单验证下这个流程,后续会验证设计的多输入输出部分,如下构建。  

    // 生成一张执行图
vkGraph = AoceManager::Get().getPipeGraphFactory(gpuType)->createGraph();
auto *layerFactory = AoceManager::Get().getLayerFactory(gpuType);
inputLayer = layerFactory->crateInput();
outputLayer = layerFactory->createOutput();
// 输出GPU数据
outputLayer->updateParamet({false, true});
yuv2rgbLayer = layerFactory->createYUV2RGBA();
// 生成图
vkGraph->addNode(inputLayer)->addNode(yuv2rgbLayer)->addNode(outputLayer);

  其中yuv2rgbLayer现在完成了nv12/yuv420P/yuy422P/yuyvI这些常见格式的解析,贴一段yuv420P的代码,CS代码需要配合线程组的划分来看,大家可以在github查看完整流程,YUV转换的代码主要注意尽量不要多个线程同时读或者写某个地址就好。  

void yuv420p(){
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
ivec2 size = imageSize(outTex);
if(uv.x >= size.x/2 || uv.y >= size.y/2){
return;
}
ivec2 nuv = u12u2(u22u1(uv.xy, size.x/2), size.x);
ivec2 uindex = nuv + ivec2(0,size.y);
ivec2 vindex = nuv + ivec2(0,size.y*5/4); float y1 = imageLoad(inTex,ivec2(uv.x*2,uv.y*2)).r;
float y2 = imageLoad(inTex,ivec2(uv.x*2+1,uv.y*2)).r;
float y3 = imageLoad(inTex,ivec2(uv.x*2,uv.y*2+1)).r;
float y4 = imageLoad(inTex,ivec2(uv.x*2+1,uv.y*2+1)).r;
float u = imageLoad(inTex,uindex.xy).r -0.5f;
float v = imageLoad(inTex,vindex.xy).r -0.5f; vec4 rgba1 = yuv2Rgb(y1,u,v,1.f);
vec4 rgba2 = yuv2Rgb(y2,u,v,1.f);
vec4 rgba3 = yuv2Rgb(y3,u,v,1.f);
vec4 rgba4 = yuv2Rgb(y4,u,v,1.f); imageStore(outTex, ivec2(uv.x*2,uv.y*2),rgba1);
imageStore(outTex, ivec2(uv.x*2+1,uv.y*2),rgba2);
imageStore(outTex, ivec2(uv.x*2,uv.y*2+1),rgba3);
imageStore(outTex, ivec2(uv.x*2+1,uv.y*2+1),rgba4);
}

用vulkan显示

  Vulkan在Android使用Compute shader 里面,我使用native window完成vulkan展示与显示,但是很多时候,窗口并不是特定的,这个项目的设计目标之一也是无窗口使用Vulkan的Compute shader完成图像处理,后续高效支持对接android UI/UE4/Unity3d/window UI SDK都方便。

  在这,我们需要查看运行结果,在这我们换种方式,不用native window,不然方便的android UI都不能用了,在native window的实现方式中,我们知道vulkan 交换链只需要ANativeWindow,相应的UI消息循环显示图像处理结果过程我们并不需要,通过查看 android图形框架指明了surface对应的C++类就是ANativeWindow,这样我们可以直接使用surface来完成vulkan 图像呈现工程,相关实现可以看vulkan模块下的vulkanwindow里的initsurface实现。

  其中这个demo的window/andorid刷新部分有些不同,window利用本身主线程的窗口空闲时间,把ffmpeg解码线程上的数据经vulkan处理后复制到交换链当前显示图像中,而android本身的Surface没有找到GLSurfaceView.Renderer类似的onDrawFrame时机,所以在android vulkan中,处理与复制呈现给交换链全在ffmpeg解码线程上,不过android 下面的opengles显示又和window一样,主线程直接复制呈现,而ffmpeg解码线程用vulkan处理。

opengles显示

  本来我想着用vulkan处理了,就能放弃opengl相关,但是至少现在还不现实,android端本身图像APP,以及对应android上的UE4/Unity3D,opengl es可能是更成熟的选择。

  如何把vulkan的计算结果直接复制给opengles,通过文档 android文档AHardwareBuffer 其中有句话AHardwareBuffers可以绑定到EGL/OpenGL和Vulkan原语,通过相应提示用法VK_ANDROID_external_memory_android_hardware_buffer扩展/eglGetNativeClientBufferANDROID,我们继续搜索,查找到 google vulkantest这里有段源码,详细说明了如何把vulkan里的vkImage绑定到AHardwareBuffer上,opengles部分根据eglGetNativeClientBufferANDROID查找到如何把AHardwareBuffer绑定到对应的opengles纹理上,这样我们通过vkImage-AHardwareBuffer-opengl texture的绑定,对应其封装在aoce_vulkan模块的hardwareImage类中。

  AHardwareBuffer后续还可以继续挖,android原生平台提供的多媒体相关的SDK如摄像机,MediaPlay等都有AHardwareBuffer的身影,后续可以尝试直接把相关绑定到vulkan加快运算。

  本人android开发并不熟悉,欢迎大家指正其中错误的地方。

android下vulkan与opengles纹理互通的更多相关文章

  1. 在Android用vulkan完成蓝绿幕扣像

    效果图(1080P处理) 因为摄像头开启自动曝光,画面变动时,亮度变化导致扣像在转动时如上. 源码地址vulkan_extratest 这个demo主要测试二点,一是测试ndk camera集成效果, ...

  2. android ndk调用OpenGL 实现纹理贴图Texture

    android ndk调用OpenGL 实现纹理贴图Texture 时间 2014-06-25 05:24:39  CSDN博客 原文  http://blog.csdn.net/chrisfxs/a ...

  3. Android下/data/data/<package_name>/files读写权限

    今天将更新模块拿到android上面测试的时候,发现在创建writablepath.."upd/"目录的时候出现Permission Denied提示BTW:我使用的是lfs来创建 ...

  4. Android下Cocos2d创建HelloWorld工程

    最近在搭建Cocos2d的环境,结果各种问题,两人弄了一天才能搞好一个环境-! -_-!! 避免大家也可能会遇到我这种情况,所以写一个随笔,让大家也了解下如何搭建吧- 1.环境安装准备 下载 tadp ...

  5. Android下读取logcat的信息

    有时我们需要在程序执行进程中遇到一些异常,需要收集一logcat的信息,android下就可以使用以下方法获取: private static String getLogcatInfo(){ Stri ...

  6. Android下OpenCV的环境搭建

    目录(?)[-] 前言 系统环境 相关工具 Android ADT环境搭建 Android SDK环境变量的配置 Android NDK的安装与配置 OpenCV for Android 环境搭建 基 ...

  7. Android下添加新的自定义键值和按键处理流程

            Android下添加新的自定义键值和按键处理流程     说出来不怕大家笑话,我写这篇博客的原因在于前几天去一个小公司面试Android系统工程师,然后在面试的时候对方的技术总监问了我 ...

  8. Android下的数据储存方式(三)

      Android下最好的数据储存方式:关系型数据库sqlite.   数据库的创建:使用SqliteOpenHelper类 结合SqliteOpenHelper类和SQLiteDatabase类的帮 ...

  9. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

随机推荐

  1. 【应用服务 App Service】NodeJS +Egg 发布到App Service时遇见 [ERR_SYSTEM_ERROR]: A system error occurred:uv_os_get_passwd returned ENOENT(no such file or directory)

    问题情形 本地NodeJS应用使用Egg脚手架构建,本地运行测试完全没有问题,发布后App Service后不能运行.通过登录到kudu后(https://<your web site>. ...

  2. MySQL数据库基础-1

    数据库原理 数据时代 信息创造价值 -结构化数据 关系完整,密切 -非结构化数据 数据散乱,相互关系不大 -半结构化数据 XML HTML 也不是完全没有结构,也不是特别规矩 MySQL适合管理结构化 ...

  3. Linux 发行版本简介

    1991年的10月5日Linus Benedict Torvalds在comp.os.minix 新闻组上发布消息,正式向外宣布他自行编写的完全自由免费的内核诞生(Freeminix-like ker ...

  4. centos使用上一条命令的快捷键

    使用上一条的最后一个参数 有时需要连续多个命令操作一个路径很长的文件: cat /usr/share/doc/centos-release/GPL 下一个命令可能还要使用这个路径,即使有命令补全也会很 ...

  5. android自带下拉刷新SwipeRefreshLayout

    也是一个布局容器,只有一个子组件,类似scrollView <?xml version="1.0" encoding="utf-8"?> <a ...

  6. Graph-to-ID task

    首先图像是一个二维的结构,CNN提取图片的特征,但是是local的,通过kenel的形式,不断的图上移动,通过卷积的形式, 无论移动到哪个位置,内部的结构都是不变的,这就是参数共享. 这个所说的图像显 ...

  7. 开源项目bootdo的实战开发笔记

    开源项目bootdo 源码地址:https://github.com/lcg0124/bootdo 技术选型 1.后端 核心框架:Spring Boot 安全框架:Apache Shiro 模板引擎: ...

  8. Java中的微信支付(2):API V3 微信平台证书的获取与刷新

    1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...

  9. 【转】not found while looking for property错误

    原址:http://blog.csdn.net/y3wegy/article/details/7840813 最近在研究Hibernate.过程当中碰到了很多问题啊!其中一个就是not found w ...

  10. error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“

    python3 是用 VC++ 14 编译的, python27 是 VC++ 9 编译的, 安装 python3 的包需要编译的也是要 VC++ 14 以上支持的. 可以下载安装这个: 链接:htt ...