一、播放视频说明
1、两种方式播放视频
①shader播放YUV,后面再介绍。
②RGB直接显示数据,简单。性能差,用到FFmpeg的格式转换,没有shader效率高。本文介绍这个方式。
2.GLSurfaceView原理(双缓冲机制):
SurfaceHolder: getHolder().getSurface();
得到Surface,取出其中缓冲地址,写入RGB数据。
3.新建一个java的XPlay组件,继承与GLSurfaceView,并在xml中进行布局编写。
4.调用native函数:public native void Open(String url,Object surface);
5.在C++中进行取出缓冲地址,将数据放到缓冲并发送出去进行显示。
二、函数说明
1、需要的头文件
#include <android/native_window.h>
#include <android/native_window_jni.h>
2.函数说明
ANativeWindow *nwin = ANativeWindow_fromSurface(env,surface);//env为JNIEnv *env ,surface为java传过来的jobject surface 生成一个原始的窗口类
ANativeWindow_setBuffersGeometry(nwin,outWidth,outHeight,WINDOW_FORMAT_RGBA_8888); // 对原始的窗口类设置,设置宽高格式,不是surface的宽高,设置nativewindow的buff,可自动拉伸
ANativeWindow_Buffer wbuf;
//双缓冲
ANativeWindow_lock(nwin,&wbuf,0); //加锁、获取nwin的缓冲到wbuf中,
uint8_t *dst = (uint8_t*)wbuf.bits; //缓冲地址,跟显卡交互的, 地址是:内存地址
memcpy(dst,rgb,outWidth*outHeight*4); // 复制rgb到地址中,宽*高*4 ,rgb为像素转换完成的数据
ANativeWindow_unlockAndPost(nwin); //解锁并post出去
代码说明:
1.新建XPlay
2.在布局文件layout中加入Xplay
3.C++代码
layout的XML:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="aplay.testffmpeg.MainActivity"> <XPlay android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
Xplay代码: