HPlay extends GLSurfaceView
public native void OpenBySurface(String url, Object surface);
//显示窗口初始化
ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env,surface);
//设置窗口buffer大小
ANativeWindow_setBuffersGeometry(nativeWindow,width,height,WINDOW_FORMAT_RGBA_8888);
ANativeWindow_Buffer windowsBuf;
//锁定窗口,然后等待绘制surface
ANativeWindow_lock(nativeWindow,&windowsBuf,0);
uint8_t *dst = (uint8_t*)wbuf.bits;
memcpy(dst,rgb,width*height*4);
//解锁窗口,并且绘制窗口
ANativeWindow_unlockAndPost(nativeWindow);
ANativeWindow *nwin = ANativeWindow_fromSurface(env, surface);
//1 获取原始窗口
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
//输出配置
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
};
//创建surface
EGLSurface winsurface = eglCreateWindowSurface(display, config, nwin, 0);
const EGLint ctxAttr[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
};
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxAttr);
//顶点shader初始化
GLint vsh = InitShader(vertexShader, GL_VERTEX_SHADER);
//片元yuv420 shader初始化
GLint fsh = InitShader(fragYUV420P, GL_FRAGMENT_SHADER);
//创建渲染程序
GLint program = glCreateProgram();
//渲染程序中加入着色器代码
glAttachShader(program, vsh);
glAttachShader(program, fsh);
//链接程序
glLinkProgram(program);
GLint status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
glUseProgram(program);
//加入三维顶点数据 两个三角形组成正方形
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);
//设置纹理层
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 //纹理的数据
);
......
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];
//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]);
//三维绘制
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//窗口显示
eglSwapBuffers(display, winsurface);
cmake
target_link_libraries(
...
OpenSLES
...)
SLObjectltf engineObject = NULL;//存放引擎对象
SLEngineltf engineEngine = NULL;//存放引擎接口
slCraeateEngine(&engineObject ,
0, //SLuint32 numOptions
NULL, //选择项目 默认参数const SLEngineOption *pEngineOption
0, //Sluint32 numInterface 支持接口的数量
NULL, //SLInterfaceID支持的接口
NULL) // 接口表示数值,是否支持,也是一个数组
//实例化引擎
(*engineObject)->Realize(engineObject,//对象
SL_BOOLEAN_FALSE);//SL_BOOLEAN_FALSE 是阻塞,true是立马返回
//获取接口
(*engineObject)->GetInterface(engineObject,//对应
SL_IID_ENGINE,//SL_IID_ENGINE接口类型 通过ID号获取接口
&engineEngine);
SLEngineltf engineEngine = NULL;//存放引擎接口
SLObjectltf outputMixObject= NULL;//存放引擎对象
(*engineEngine )->CreateOutputMix(engineEngine,&outMixObject,0,0,0);
//实例化引擎
(*outputMixObject)->Realize(outputMixObject,//对象
SL_BOOLEAN_FALSE);//SL_BOOLEAN_FALSE 是阻塞,true是立马返回
//获取接口
SLDataLocator_OutputMix outputMix = {
SL_DATALOCATOR_OUTPUTMIX,outputMixObject}
SDLDataSink audioSnk = {
&outputMix,NULL};
SLDataLocator_AndroidSimpleBufferQueue
android_queue = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,2};
SLDataFormat_OPCM pcm={
SL_DATAFORMAT_PCM,//播放pcm格式的数据
2, //2个声道
SL_SAMPLINGRATE_44_1,// 44100hz的频率
SL_PCMSAMPLEFORMAT_FIXED_16,//位数16位
SL_PCMSAMPLEFORMAT_FIXED_16,//
SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT,//立体声(前左前右)
SL_BYTEBORDER_LITTLEENDIAN//高位在前还是低位在前
}
SLDataSource slDataSource ={
&android_queue,&pcm};//缓存队列的配置信息
SLObjectltf pcmPlayerObject= NULL;//存放引擎对象
SLEngineltf pcmPlayerPlay= NULL;//存放引擎接口
const SLInterfaceID ids[1] {
SL_IID_BUFFERQUEUE};
const SLboolean req[1] = {
SL_BOOLEAN_TRUE};
(*pcmPlayerPlay)->CreateAudioPlay(pcmPlayerPlay,
&pcmPlayerObject,&slDataSource,
&audioSnk,1,ids,req);
//初始化播放器
(*pcmPlayerObject)->Realize(pcmPlayerObject,//对象
SL_BOOLEAN_FALSE);
//得到接口后调用,获取Player接口
(*pcmPlayerObject)->GetInterface(pcmPlayerObject,//对应
SL_IID_PLAY,//SL_IID_ENGINE接口类型 通过ID号获取接口
&pcmPlayerPlay);