-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnative-lib.cpp
More file actions
379 lines (326 loc) · 11.6 KB
/
native-lib.cpp
File metadata and controls
379 lines (326 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
/*******************************************************************************
** **
** Jiedi(China nanjing)Ltd. **
** 创建:夏曹俊,此代码可用作为学习参考 **
*******************************************************************************/
/*****************************FILE INFOMATION***********************************
**
** Project : FFmpeg
** Description : FFMPEG项目创建示例
** Contact : [email protected]
** 博客 : http://blog.csdn.net/jiedichina
** 视频课程 : 网易云课堂 http://study.163.com/u/xiacaojun
腾讯课堂 https://jiedi.ke.qq.com/
csdn学院 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=961
** 51cto学院 http://edu.51cto.com/lecturer/index/user_id-12016059.html
** 下载最新的ffmpeg版本 ffmpeg.club
**
** 安卓流媒体播放器 课程群 :23304930 加入群下载代码和交流
** 微信公众号 : jiedi2007
** 头条号 : 夏曹俊
**
*******************************************************************************/
//!!!!!!!!! 加群23304930下载代码和交流
#include <jni.h>
#include <string>
#include <android/log.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_WARN,"testff",__VA_ARGS__)
//顶点着色器glsl
#define GET_STR(x) #x
static const char *vertexShader = GET_STR(
attribute vec4 aPosition; //顶点坐标
attribute vec2 aTexCoord; //材质顶点坐标
varying vec2 vTexCoord; //输出的材质坐标
void main(){
vTexCoord = vec2(aTexCoord.x,1.0-aTexCoord.y);
gl_Position = aPosition;
}
);
//片元着色器,软解码和部分x86硬解码
static const char *fragYUV420P = GET_STR(
precision mediump float; //精度
varying vec2 vTexCoord; //顶点着色器传递的坐标
uniform sampler2D yTexture; //输入的材质(不透明灰度,单像素)
uniform sampler2D uTexture;
uniform sampler2D vTexture;
void main(){
vec3 yuv;
vec3 rgb;
yuv.r = texture2D(yTexture,vTexCoord).r;
yuv.g = texture2D(uTexture,vTexCoord).r - 0.5;
yuv.b = texture2D(vTexture,vTexCoord).r - 0.5;
rgb = mat3(1.0, 1.0, 1.0,
0.0,-0.39465,2.03211,
1.13983,-0.58060,0.0)*yuv;
//输出像素颜色
gl_FragColor = vec4(rgb,1.0);
}
);
GLint InitShader(const char *code,GLint type)
{
//创建shader
GLint sh = glCreateShader(type);
if(sh == 0)
{
LOGD("glCreateShader %d failed!",type);
return 0;
} else {
LOGD("glCreateShader %d success!",type);
}
//加载shader
glShaderSource(sh,
1, //shader数量
&code, //shader代码
0); //代码长度
//编译shader
glCompileShader(sh);
//获取编译情况
GLint status;
glGetShaderiv(sh,GL_COMPILE_STATUS,&status);
if(status == 0)
{
LOGD("glCompileShader failed!");
return 0;
}
LOGD("glCompileShader success!");
return sh;
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_aplay_testopengles_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_aplay_testopengles_XPlay_Open(JNIEnv *env, jobject instance, jstring url_, jobject surface) {
const char *url = env->GetStringUTFChars(url_, 0);
LOGD("open url is %s",url);
FILE *fp = fopen(url,"rb");
if(!fp)
{
LOGD("open file %s failed!",url);
return;
} else {
LOGD("open file %s success!",url);
}
//1 获取原始窗口
ANativeWindow *nwin = ANativeWindow_fromSurface(env,surface);
////////////////////
///EGL
//1 EGL display创建和初始化
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if(display == EGL_NO_DISPLAY)
{
LOGD("eglGetDisplay failed!");
return;
} else {
LOGD("eglGetDisplay success!");
}
// 初始化
if(EGL_TRUE != eglInitialize(display,0,0))
{
LOGD("eglInitialize failed!");
return;
} else {
LOGD("eglInitialize success!");
}
//2 surface
//2-1 surface窗口配置
//输出配置
EGLConfig config;
EGLint configNum;
EGLint configSpec[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE
};
if(EGL_TRUE != eglChooseConfig(display,configSpec,&config,1,&configNum))
{
LOGD("eglChooseConfig failed!");
return;
}
//创建surface
EGLSurface winsurface = eglCreateWindowSurface(display,config,nwin,0);
if(winsurface == EGL_NO_SURFACE)
{
LOGD("eglCreateWindowSurface failed!");
return;
} else {
LOGD("eglCreateWindowSurface success!");
}
//3 context 创建关联的上下文
const EGLint ctxAttr[] = {
EGL_CONTEXT_CLIENT_VERSION,2,EGL_NONE
};
EGLContext context = eglCreateContext(display,config,EGL_NO_CONTEXT,ctxAttr);
if(context == EGL_NO_CONTEXT)
{
LOGD("eglCreateContext failed!");
return;
} else {
LOGD("eglCreateContext success!");
}
if(EGL_TRUE != eglMakeCurrent(display,winsurface,winsurface,context))
{
LOGD("eglMakeCurrent failed!");
return;
} else {
LOGD("eglMakeCurrent success!");
}
LOGD("EGL Init Success!");
//顶点和片元shader初始化
//顶点shader初始化
GLint vsh = InitShader(vertexShader,GL_VERTEX_SHADER);
//片元yuv420 shader初始化
GLint fsh = InitShader(fragYUV420P,GL_FRAGMENT_SHADER);
/////////////////////////////////////////////////////////////
//创建渲染程序
GLint program = glCreateProgram();
if(program == 0)
{
LOGD("glCreateProgram failed!");
return;
} else {
LOGD("glCreateProgram success!");
}
//渲染程序中加入着色器代码
glAttachShader(program,vsh);
glAttachShader(program,fsh);
//链接程序
glLinkProgram(program);
GLint status = 0;
glGetProgramiv(program,GL_LINK_STATUS,&status);
if(status != GL_TRUE)
{
LOGD("glLinkProgram failed!");
return;
}
glUseProgram(program);
LOGD("glLinkProgram success!");
/////////////////////////////////////////////////////////////
//加入三维顶点数据 两个三角形组成正方形
static float vers[] = {
1.0f,-1.0f,0.0f,
-1.0f,-1.0f,0.0f,
1.0f,1.0f,0.0f,
-1.0f,1.0f,0.0f,
};
GLuint apos = (GLuint)glGetAttribLocation(program,"aPosition");
glEnableVertexAttribArray(apos);
//传递顶点
glVertexAttribPointer(apos,3,GL_FLOAT,GL_FALSE,12,vers);
//加入材质坐标数据
static float txts[] = {
1.0f,0.0f , //右下
0.0f,0.0f,
1.0f,1.0f,
0.0,1.0
};
GLuint atex = (GLuint)glGetAttribLocation(program,"aTexCoord");
glEnableVertexAttribArray(atex);
glVertexAttribPointer(atex,2,GL_FLOAT,GL_FALSE,8,txts);
int width = 424;
int height = 240;
//材质纹理初始化
//设置纹理层
glUniform1i( glGetUniformLocation(program,"yTexture"),0); //对于纹理第1层
glUniform1i( glGetUniformLocation(program,"uTexture"),1); //对于纹理第2层
glUniform1i( glGetUniformLocation(program,"vTexture"),2); //对于纹理第3层
//创建opengl纹理
GLuint texts[3] = {0};
//创建三个纹理
glGenTextures(3,texts);
//设置纹理属性
glBindTexture(GL_TEXTURE_2D,texts[0]);
//缩小的过滤器
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//设置纹理的格式和大小
glTexImage2D(GL_TEXTURE_2D,
0, //细节基本 0默认
GL_LUMINANCE,//gpu内部格式 亮度,灰度图
width,height, //拉升到全屏
0, //边框
GL_LUMINANCE,//数据的像素格式 亮度,灰度图 要与上面一致
GL_UNSIGNED_BYTE, //像素的数据类型
NULL //纹理的数据
);
//设置纹理属性
glBindTexture(GL_TEXTURE_2D,texts[1]);
//缩小的过滤器
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//设置纹理的格式和大小
glTexImage2D(GL_TEXTURE_2D,
0, //细节基本 0默认
GL_LUMINANCE,//gpu内部格式 亮度,灰度图
width/2,height/2, //拉升到全屏
0, //边框
GL_LUMINANCE,//数据的像素格式 亮度,灰度图 要与上面一致
GL_UNSIGNED_BYTE, //像素的数据类型
NULL //纹理的数据
);
//设置纹理属性
glBindTexture(GL_TEXTURE_2D,texts[2]);
//缩小的过滤器
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//设置纹理的格式和大小
glTexImage2D(GL_TEXTURE_2D,
0, //细节基本 0默认
GL_LUMINANCE,//gpu内部格式 亮度,灰度图
width/2,height/2, //拉升到全屏
0, //边框
GL_LUMINANCE,//数据的像素格式 亮度,灰度图 要与上面一致
GL_UNSIGNED_BYTE, //像素的数据类型
NULL //纹理的数据
);
//////////////////////////////////////////////////////
////纹理的修改和显示
unsigned char *buf[3] = {0};
buf[0] = new unsigned char[width*height];
buf[1] = new unsigned char[width*height/4];
buf[2] = new unsigned char[width*height/4];
for(int i = 0; i<10000;i++)
{
//memset(buf[0],i,width*height);
// memset(buf[1],i,width*height/4);
//memset(buf[2],i,width*height/4);
//420p yyyyyyyy uu vv
if(feof(fp) == 0)
{
//yyyyyyyy
fread(buf[0],1,width*height,fp);
fread(buf[1],1,width*height/4,fp);
fread(buf[2],1,width*height/4,fp);
}
//激活第1层纹理,绑定到创建的opengl纹理
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texts[0]);
//替换纹理内容
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,GL_LUMINANCE,GL_UNSIGNED_BYTE,buf[0]);
//激活第2层纹理,绑定到创建的opengl纹理
glActiveTexture(GL_TEXTURE0+1);
glBindTexture(GL_TEXTURE_2D,texts[1]);
//替换纹理内容
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width/2,height/2,GL_LUMINANCE,GL_UNSIGNED_BYTE,buf[1]);
//激活第2层纹理,绑定到创建的opengl纹理
glActiveTexture(GL_TEXTURE0+2);
glBindTexture(GL_TEXTURE_2D,texts[2]);
//替换纹理内容
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width/2,height/2,GL_LUMINANCE,GL_UNSIGNED_BYTE,buf[2]);
//三维绘制
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
//窗口显示
eglSwapBuffers(display,winsurface);
}
env->ReleaseStringUTFChars(url_, url);
}