视频实时OpenGL渲染并保存渲染结果合成MP4
2017-08-29 16:14
2775 查看
这是一个能实时播放多个视频、图片在一个GL容器里的控件,通过这个控件,可以在一个view中绘制固定坐标、自由随机滚动的视频和图片,然后从该view中截取数据帧,实时保存成YUV格式的文件,最后合成MP4。
一、OpenGL 渲染视频模块
1.结构简介a. GLEngine是一个全局控制GL绘制各个子view的类,结构图如下:
b.Java层封装后的View控件结构如下:
GLEngine直接提供接口给上层调用,通过该对象实现创建、绘制、释放子view,和获取GL绘制结果,以及释放整个GL。 MyGLView是对底层的封装,提供方法给Android直接使用。
2.工作原理
底层GLEngine实例化后,会返回一个long型的对象句柄给上层的MyGLView,MyGLView对象就可以通过该句柄实现对底层GLEngine的引用。 MyGLView对象通过addStaticView()、addScrollView()方法调用底层对应的createStaticView()、createScrollView()函数,拿到子view long型的句柄,然提供给使用MyGLView的开发者保存下来,开发者就可以通过这些子view的句柄来绘制GL里面的各个子view。
二、视频编解码模块
结构简介a. GetRgbFremer
MP4解码器,能从MP4文件中取出RGB帧,类结构图如下:
b.RgbToYuv420P
对RGB帧转换成YUV420P帧的转换,并保存为文件,结构图如下:
c.H264Encoder
能把YUV编码成H264,结构图如下:
d.Mp4Muxer
视频复合器,能把AAC音频流和H264视频流合成MP4,结构图如下:
三、视频编解码和OpenGL渲染整合使用指南
首选创建多个线程解码多个视频,获取到的帧数据缓存起来。
/** * 解码线程1 */ private FFGetRgbFramer mFFGetRgbFramer = new FFGetRgbFramer(mInMp4Path, mVideoWidth1, mVideoHeight1); private byte[] mVideoData1; private void decodeThread1() { new Thread(new Runnable() { @Override public void run() { while (mRun) { if (mVideoData1 == null) { mVideoData1 = mFFGetRgbFramer.getNextRgbFrame(); if (mVideoData1 == null) { break; } } } } }).start(); } …… ……
在SurfaceView的Renderer下的回调onSurfaceChanged下初始化MyGLView,并添加子view,拿到句柄保存下来,在回调onDrawFrame下把调用MyGLView对象的drawFrame()方法,并且把要绘制的子view对应的句柄和RGB帧数据传进去,该方法返回获取到的GL绘制结果,然后使用FFRgbToYuv420p保存成YUV文件,以备后续合成MP4使用。例如:
GLSurfaceView.Renderer mRenderer = new GLSurfaceView.Renderer() { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { mGLView.initGL(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { mGLView.onChangeGL(width,height); mStaticHandle1 = mGLView.addStaticView(0, 0, mVideoWidth1, mVideoHeight1, width, height); …… …… mHandles.clear(); mHandles.add(mStaticHandle1); mHandles.add(mStaticHandle2); …… } @Override public void onDrawFrame(GL10 gl) { if (mVideoData1 != null && mVideoData2 != null) { List<byte[]> byteList = new ArrayList<>(); byteList.add(mVideoData1); …… mVideoData1 = null; …… byte[] rgbResultByte = mGLView.drawFrame(mHandles,byteList); if (rgbResultByte != null) { mFFRgbToYuv420p.pushRgbData(rgbResultByte); } } } };
最后再分别利用H264Encoder、Mp4Muxer合成MP4。
OpenGL实现部分源码地址:https://github.com/hondameng/OpenGLES2Test
相关文章推荐
- [置顶] 基于iOS的网络音视频实时传输系统(六)- AudioQueue播放音频,OpenGL渲染显示图像
- 发布一小段代码: 图象读取代码(OpenGL纹理的加载以及渲染结果的保存)
- GPUImage中是如果保存OpenGL渲染后的视频的
- 基于FFmpeg 和 OpenGL 的音视频合成+过渡特效【C++】
- Android: MediaCodec视频文件硬件解码,高效率得到YUV格式帧,快速保存JPEG图片(不使用OpenGL)
- DirecrShow 实时采集桌面并进行H264和AAC编码后封装成MP4保存
- opencv 2.4.6 摄像头实时保存视频
- opencv 、directshow捕获摄像头,实时播放,编码,保存视频,保存单帧
- 利用opengl将3ds文件导入场景并显示,然后保存这个场景为bmp格式图像,其结果与显示不同,问题出在哪儿了
- [置顶] OpenGL ES总结(四)OpenGL 渲染视频画面
- 使用opencv从mp4视频中抽帧并保存
- opengl 如何渲染视频流.
- ffmpeg视频按帧截取图片和ffmpeg将图片合成mp4视频
- OpenCV摄像头获取视频并实时保存每帧图片
- Android OpenGL渲染双视频
- 利用Qt + OpenGL 渲染 YUV数据,播放视频 mac版
- javacpp-opencv图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作
- 用jni实现基于opengl的yuv格式的视频渲染
- [算法]iOS 视频添加水印,合成视频两种方案(整体渲染和分割渲染)
- OpenCV入门七:OpenCV打开视频文件,并对其中的每一帧图像进行Canny算子边缘化提取,并将结果保存为视频文件