视频学习笔记:Android ffmpeg解码多路h264视频并显示
来源:互联网 发布:淘宝集市店 编辑:程序博客网 时间:2024/06/06 09:33
背景
Android设备上使用ffmpeg解码多路h264视频,抽取了一个简单demo方便日后参考,在此记录一下。demo中主要涉及以下功能:
1.ffmpeg解码h264视频为yuv帧
2.使用ffmpeg将yuv帧转换为可以在画布上渲染的rgb帧
3.将android的SurfaceView类传入jni层并使用rgb帧进行渲染
4.使用Java类包装c++类,多线程解码多路视频
5.集成了OpenCV相关功能,在本例中可以使用相关api保存arg帧
其中解码部分代码参考了雷神博客的相关文章,并已经在项目中多处使用,surfaceview渲染部分参考了ijkplayer中的相关源码。项目地址如下,具体功能可以参考源码。
项目地址:https://git.oschina.net/vonchenchen/android_ffmpge_muti_decode.git
下面简单介绍一下工程的主要内容
功能实现
总体功能
首先需要使用ndk编译ffmpeg源码,这部分网上已经有比较多的介绍,在此不再赘述,编译好的文件已经在工程中可以直接使用。加载ffmpeg动态链接库的命令在Android.mk中,内容如下:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
也就是直接将其copy到jniLibs文件的对应目录即可。
decoder.cpp文件负责具体调用ffmpeg的功能进行解码。之前的项目中一直使用这个类,直接定义一个变量并调用相关解码方法。对于解码多路视频,如果直接在jni文件中定义多个对象则显得比较啰嗦,如果能使用java类包装一下decode类,需要一个decode类就new一个对应的java类,不需要时让java回收,这是比较理想的,对此专门学习了一下这种实现,原理见这里的另外一篇博客http://blog.csdn.net/lidec/article/details/72872037。
当我们解码完毕后,需要把rgb帧渲染到画布上,这个过程参考了ijkplayer的实现,将surface作为一个参数传入jni层,拿到surface的缓冲区后将生成的rgb数据直接copy到这个缓冲区即可完成显示。相关ndk的api可以参考ndk文档,链接https://developer.android.com/ndk/reference/group___native_activity.html。这里注意,在编译时,LOCAL_LDLIBS中需要加入-ljnigraphics -landroid两个库。
解码与显示
这个类参考了雷神的博客,使用c++简单封装了一下。主干功能如下
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
这里简单进行介绍,传入h264视频buffer后利用av_parser_parse2解析出h264头在当前buffer中的偏移量,然后使用avcodec_decode_video2函数进行解码,最后得到一个AVFrame帧,这个帧就是h264流中的yuv帧。拿到这个帧和其他相关信息后,我们将这些内容传递给handle_data这个函数指针,由外面传入的handle_data函数处理生成的yuv帧。
帧处理回调在com_vonchenchen_android_video_demos_codec_CodecWrapper.cpp中实现,这个函数主要完成将yuv数据使用ffmpeg转换为rgb帧,并且获取surface的缓冲区,将rgb拷贝到这段缓冲区中。具体实现如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
yuv转rgb
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
总结
本文简单介绍了Android ffmpeg解码多路h264视频并显示的流程并附有完整示例,希望能够给有相关需求并且还在探索的同学一个参考,也希望大家多多指正,一起进步。
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 基于ffmpeg解码h264视频
- FFMPEG学习----解码视频
- 视频编解码学习之路(H264)
- ffmpeg 接收解码rtp h264视频流
- ffmpeg 接收解码rtp h264视频流
- FFMpeg视频解码+OpenCV显示
- FFmpeg 视频解码,窗口显示
- FFmpeg 视频解码,窗口显示
- 视频编解码学习(2):H264学习笔记
- FFmpeg学习1:视频解码
- 学习FFmpeg API -解码视频
- FFmpeg学习1:视频解码
- <五> S5PV210 H264视频解码后显示
- rtsp获取视频帧 ffmpeg解码h264数据 D3D显示yv12数据
- ffmpeg如何从内存读取h264音视频流进行解码显示
- [ffmpeg]如何同时解码多路视频
- react安装和使用--webpack
- sqlserver函数
- Oracle in exists
- 58 同城 iOS 客户端 Hybrid 框架探索
- java 实现http响应
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 基于注解的Spring整合SpringMVC开发流程?
- 链表——Java实现
- java-访问修饰符
- ngixn如何控制多进程连接的平衡
- 图解集合3:CopyOnWriteArrayList
- hibernate中merge的使用以及与update的区别
- ACM一些常用小技巧(博客收集+总结)
- hibernate一对一外键映射