MediaCodec解码到GLSurfaceView

    private void createCodecFromGL(){
        mRtmpView = (RTMPDisplayView2)findViewById(R.id.view_preview);
        mRtmpView.init();
        new Thread(){
            @Override
            public void run() {
                super.run();
                synchronized (mRtmpView.sSync){
                    try {
                        mRtmpView.sSync.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Surface mSurface = mRtmpView.getSurface();
                mRtmpView.mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {     //TODO move to decode chread.
                    @Override
                    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
                        Log.i(TAG, "onFrameAvailable");
                        mRtmpView.requestRender();
                    }
                });
                mVideoDecoder.init(mSurface);
                mVideoDecoder.start();
            }
        }.start();
    }

编码器初始化:


            mDecoder = MediaCodec.createDecoderByType(VIDEO_TYPE);
            MediaFormat format = MediaFormat.createVideoFormat(VIDEO_TYPE, 1540, 1280); 
            format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1540 * 1280);
            format.setInteger("durationUs", 63446722); 
            mDecoder.start();

解码线程不贴了。GLSurfaceView的初始化,注意设置为dirty模式:

        setEGLContextClientVersion(2);
        setPreserveEGLContextOnPause(true);
        render = new ViewRenderer();
        setRenderer(render);
        setRenderMode(RENDERMODE_WHEN_DIRTY); 

在GLThread初始化中创建SurfaceTexture和Surface:

        @Override
        public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
            Log.i(TAG,"onSurfaceCreated");
            mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
            if (mProgram == 0) {
                throw new RuntimeException("failed creating program");
            }
            maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
            maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
            muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
            muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
            int[] textures = new int[1];
            GLES20.glGenTextures(1, textures, 0);
            mTextureID = textures[0];
            GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
            checkGlError("glBindTexture mTextureID");

            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                    GLES20.GL_NEAREST);
            GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                    GLES20.GL_LINEAR);
            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
                    GLES20.GL_CLAMP_TO_EDGE);
            GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
                    GLES20.GL_CLAMP_TO_EDGE);
            checkGlError("glTexParameter");
            mSurfaceTexture = new SurfaceTexture(mTextureID);//注意这里
            mSurface = new Surface(mSurfaceTexture);
            synchronized (sSync){
                sSync.notifyAll();
            }
        }
                @Override
        public void onDrawFrame(GL10 gl10) {
            mSurfaceTexture.getTransformMatrix(mSTMatrix);
            mSurfaceTexture.updateTexImage();
            //draw more...
            }

那个线程锁是因为GL线程要等Activity OnResume生命周期走完才会创建。而SurfaceTexture的监听又需要独立于GL线程。所以开头创建一个线程。
最后贴一下示例Shader:

        private static final String VERTEX_SHADER =
                "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 static final String FRAGMENT_SHADER =
                "#extension GL_OES_EGL_image_external : require\n" +
                        "precision mediump float;\n" +      // highp here doesn't seem to matter
                        "varying vec2 vTextureCoord;\n" +
                        "uniform samplerExternalOES sTexture;\n" +
                        "void main() {\n" +
                        "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
                        "}\n";

你可能感兴趣的:(CV,GL)