一、播放视频说明

  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代码:

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import android.view.SurfaceHolder;

public class XPlay extends GLSurfaceView implements Runnable,SurfaceHolder.Callback {

    public XPlay(Context context, AttributeSet attrs) {
        super( context,attrs );
    }

    @Override
    public void run() {
        //在线程中进行显示,不阻碍
        Open("/sdcard/1080.mp4",getHolder().getSurface());
    }
    @Override
    public void surfaceCreated(SurfaceHolder var1){
        new Thread( this ).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder var1, int var2, int var3, int var4){

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder var1){

    }
    public native void Open(String url,Object surface);
}
View Code

相关文章: