项目目录

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -UNDEBUG")add_library(native-media-jni SHAREDandroid_fopen.cnative-media-jni.c)# Include libraries needed for native-media-jni lib
target_link_libraries(native-media-jniandroidlogOpenMAXAL)

链接了OpenMaxAL的库。

android_fopen.c

return funopen(asset, android_read, android_write, android_seek, android_close);
 The calling conventions of  readfn, writefn, seekfn and closefn must matchthose, respectively, of read(2), write(2),    lseek(2), and close(2) withthe single   exception that they are passed the cookie argument specifiedto  funopen() in place of the traditional file descriptor argument.

MySurfaceView.java

1)定义GLsurface的渲染器

class MyRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener 

2)构造方法

分配本地Direct buffer,可以减少内存的复制。

那么为什么创建DirectByteBuffer比HeapByteBuffer性能差却还使用DirectByteBuffer呢?

答:创建DirectByteBuffer的确不如HeapByteBuffer快,但是本地IO(从操作系统本地获取数据,比如FileChannel、SocketChannel网络数据)时,使用DirectByteBuffer比HeapByteBuffer少复制一次(java堆内存复制到操作系统内存,具体请继续看)
————————————————
版权声明:本文为CSDN博主「我叫周利东」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36951116/article/details/87185240

public MyRenderer() {mVertices = ByteBuffer.allocateDirect(mVerticesData.length* FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();mVertices.put(mVerticesData).position(0);Matrix.setIdentityM(mSTMatrix, 0);Matrix.setIdentityM(mMMatrix, 0);Matrix.rotateM(mMMatrix, 0, 20, 0, 1, 0);
}

3)onSurfaceCreated方法

public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
/* Set up alpha blending and an Android background color */
GLES20.glEnable(GLES20.GL_BLEND);//启动混合,实现半透明的效果
/*
GL_ONE:      表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。
GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子。
GL_DST_ALPHA:表示使用目标颜色的alpha值来作为因子。
GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子(1-alpha)。
GL_ONE_MINUS_DST_ALPHA:表示用1.0减去目标颜色的alpha值来作为因子。
除 此以外,还有GL_SRC_COLOR(把源颜色的四个分量分别作为因子的四个分量)、GL_ONE_MINUS_SRC_COLOR、 GL_DST_COLOR、GL_ONE_MINUS_DST_COL
*/
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//改变背景颜色
GLES20.glClearColor(0.643f, 0.776f, 0.223f, 1.0f);

//创建着色器的程序

{

//首先,加载定点着色器

{

private int loadShader(int shaderType, String source) {int shader = GLES20.glCreateShader(shaderType);if (shader != 0) {
//加载着色器程序GLES20.glShaderSource(shader, source);
//编译着色器GLES20.glCompileShader(shader);int[] compiled = new int[1];GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e(TAG, "Could not compile shader " + shaderType + ":");Log.e(TAG, GLES20.glGetShaderInfoLog(shader));GLES20.glDeleteShader(shader);shader = 0;}}return shader;
}

}

int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {return 0;
}
//然后,加载片元着色器
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {return 0;
}

//创建程序

int program = GLES20.glCreateProgram();
if (program != 0) {
//程序绑定,定点着色器GLES20.glAttachShader(program, vertexShader);checkGlError("glAttachShader");
//绑定片元这着色器GLES20.glAttachShader(program, pixelShader);checkGlError("glAttachShader");
//连接GLES20.glLinkProgram(program);int[] linkStatus = new int[1];GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);if (linkStatus[0] != GLES20.GL_TRUE) {Log.e(TAG, "Could not link program: ");Log.e(TAG, GLES20.glGetProgramInfoLog(program));GLES20.glDeleteProgram(program);program = 0;}
}

}

mProgram = createProgram(mVertexShader, mFragmentShader); if (mProgram == 0) { return; }

//获取定点位置

maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
checkGlError("glGetAttribLocation aPosition");
if (maPositionHandle == -1) {throw new RuntimeException("Could not get attrib location for aPosition");
}

//获取纹理坐标

maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
checkGlError("glGetAttribLocation aTextureCoord");
if (maTextureHandle == -1) {throw new RuntimeException("Could not get attrib location for aTextureCoord");
}

分别获取相应的矩阵

muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
int[] textures = new int[1];
// glGenTextures函数根据纹理参数返回n个纹理索引
GLES20.glGenTextures(1, textures, 0);mTextureID = textures[0];
//纹理进行绑定
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
checkGlError("glBindTexture mTextureID");

//设置纹理放大缩小和边界的方式

GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);

创建了一个surface

mSurface = new SurfaceTexture(mTextureID);
mSurface.setOnFrameAvailableListener(this);
/*
void setLookAtM (float[] rm , int rmOffset ,float eyeX , float eyeY , float eyeZ , float centerX,float centerY , float centerZ , float upX , float upY , float upZ )在世界坐标系下,设置眼镜观察点的位置,设置视图中心的位置,设置某个坐标轴方向为屏幕竖直向上的向量(不清楚可见第3节)。
参数rm是待设定的矩阵数组,它应为4×4的矩阵,即大小为16的数组;参数rmOffset为启用数组的偏移量,一般设为0;参数eyeX,eyeY和eyeZ为人眼在世界坐标系的位置。参数centerX,centerY和centerZ为模型中心在世界坐标系中的位置;eyeX,eyeY和eyeZ所确定的点与centerX,centerY和centerZ所确定的点构成了视线;参数upX,upY和upZ决定哪个坐标轴竖直向上,且该向量与视线是垂直的,可理解为人正常平视物体时,头顶所指方向为竖直向上向量,视线此刻与该向量垂直的
————————————————
版权声明:本文为CSDN博主「lyzirving」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lyzirving/article/details/79022445
*/Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);synchronized(this) {updateSurface = false;
}

4) 定点和片元着色器

private final String mVertexShader ="uniform mat4 uMVPMatrix;\n" +"uniform mat4 uSTMatrix;\n" +"attribute vec4 aPosition;\n" +"attribute vec4 aTextureCoord;\n" +"varying vec2 vTextureCoord;\n" +"void main() {\n" +"  gl_Position = uMVPMatrix * aPosition;\n" +"  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +"}\n";private final String mFragmentShader ="#extension GL_OES_EGL_image_external : require\n" +"precision mediump float;\n" +"varying vec2 vTextureCoord;\n" +"uniform samplerExternalOES sTexture;\n" +"void main() {\n" +"  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +"}\n";

5)当onFrameAvaliable时,进行onDrawFrame

public void onDrawFrame(GL10 glUnused)

//更新texImagehttps://blog.csdn.net/lyzirving/article/details/79051437

synchronized(this) {if (updateSurface) {mSurface.updateTexImage();
//获取纹理坐标mSurface.getTransformMatrix(mSTMatrix);updateSurface = false;}
}

GLES会情况深度缓冲

GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
mVertices.position(VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,VERTICES_DATA_STRIDE_BYTES, mVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");mVertices.position(VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,VERTICES_DATA_STRIDE_BYTES, mVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);//矩形渲染
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
checkGlError("glDrawArrays");

Android-NDK:native-media相关推荐

  1. Mastering Android NDK Build System - Part 1: Techniques with ndk-build

    This article is not a "Hello world!"-type tutorial for NDK. Although I will still provide ...

  2. android stl,Android NDK中的c++ STL

    田海立@CSDN 2020-11-25 Android NDK(Native Development Kit)提供了一套基于c/c++开发Android应用的工具.基于c/c++开发需要STL (St ...

  3. Android NDK之JNI陷阱

        背景: 最近一个月一直在做移植库的工作,将c代码到share library移植到Android平台.这就涉及到Android NDK(native develop kit)内容.这里只想记录 ...

  4. android ndk 编译c++11,Android NDK中的c++ STL

    田海立@CSDN 2020-11-25 Android NDK(Native Development Kit)提供了一套基于c/c++开发Android应用的工具.基于c/c++开发需要STL (St ...

  5. 【学习Android NDK开发】Java通过JNI调用native方法

    参考:Android NDK,sample/hello-jni示例项目 系统环境:Ubuntu 12.04 LTS 32-bit 1.准备工作 打开Eclipse,新建Android项目: Appli ...

  6. Android app native代码性能分析

    分析我们app中native层的C/C++代码性能,能够方便我们找出其中的性能瓶颈,并在稍后做有针对性的优化. 下载android-ndk-profiler 工欲善其事,必先利其器,我们先要有良好的工 ...

  7. 使用LeakTracer检测android NDK C/C++代码中的memory leak

    Memory issue是C/C++开发中比较常遇到,经常带给人比较大困扰,debug起来又常常让人无从下手的一类问题,memory issue主要又分为memory leak,野指针,及其它非法访问 ...

  8. 音频之Android NDK读写声卡

    通过Android NDK读写声卡通过 AudioRecord和AudioTrack两个类实现. AudioTrack:负责声音数据的输出 AudioRecord:负责声音数据的采集 相关头文件位置 ...

  9. Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg

    ###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便,所以接下来主要操作在Linux环境下进行.但是对于Android NDK 开发新手来说,自己电脑配置Ubuntu Linux ...

  10. Android NDK开发之旅31 FFmpeg音频解码

    ###前言 #####基于Android NDK开发之旅30--FFmpeg视频播放这篇文章,我们已经学会视频解码基本过程.这篇文章就对音频解码进行分析. #####音频解码和视频解码的套路基本是一样 ...

最新文章

  1. 摘要: Nginx 网络多并发请求的TCP网络参数做简单说明。
  2. (流式、lambda、触发器)实时处理大比拼 - 物联网(IoT)\金融,时序处理最佳实践
  3. 部署 instance 到 OVS vlan100 - 每天5分钟玩转 OpenStack(138)
  4. python 搭建登陆系统_Django 搭建CMDB系统完整[1](用户登录)
  5. matlab生产计划问题,基于MATLAB的生产计划最优化系统设计
  6. stm32 IOT_基于STM32平台的cubeMX和HAL库详解
  7. kafka topic常用命令
  8. gsp计算机管理系的功能,药博士医药企业GSP管理系统功能介绍
  9. wstring 截取_StringUtils截取字符substringBefore等方法使用
  10. ARC106——E - Medals
  11. 前端学习(1032):jquery插件-瀑布流
  12. 排序第一天,回忆关键字
  13. Silverlight 2.0的了解
  14. c语言编程洛谷评测得零分,洛谷试炼场题解记录——洛谷的第一个任务
  15. iOS 咻一咻,雷达,搜索动画,radarView
  16. RIM任松伟:黑莓引领企业移动化主题演讲
  17. 使用Aspose组件将WORD、PDF、PPT转为图片
  18. dbeaver连接gaussdb
  19. python爬虫 关于加速乐(_jsl)
  20. 分布式系统理论基础 - CAP

热门文章

  1. 子域名查询DNS记录查询
  2. C语言中能运算符重载吗,C++语言中什么运算符不能重载
  3. 【数据结构与算法】之深入解析“格雷编码”的求解思路与算法示例
  4. iOS之深入解析静态库和动态库
  5. 94. Binary Tree Inorder Traversal 二叉树的中序遍历
  6. 2017第八届蓝桥杯C/C++ B组省赛 —— 第一题:购物单
  7. 2018年第九届蓝桥杯 - 省赛 - C/C++大学A组 - A. 分数
  8. 大数据WEB阶段(十一)Ajax、URL编码
  9. ubuntu16.04中成功安装ROS后,小海龟示例
  10. 【Tools】Bandicam安装和卸载