1. ffmpeg是音视频界的瑞士军刀:
- 它提供了从录制、编码、封装、推流到拉流、解封装、解码、滤镜、播放的完整解决方案。
- 它是跨平台的解决方案,一套代码适配Windows、Linux、Mac OS、iOS、Andriod。
- 它原生支持hls、dash、rtmp、rtsp、http、tcp等主流协议,并提供统一的扩展方式方便扩展自己的协议,比如tutk、webrtc等,目前已经有开源库metaRTC可通过扩展集成到ffmpeg中实现webrtc的推拉流。
- 它支持或插件支持所有封装格式的封装和解封装。
- 它支持或插件支持所有音视频编码格式的编码和解码。主要视频代表有H264、H265,主要音频代表有aac、opus。
- 它已经内置一百多种滤镜并提供方式可以添加自定义滤镜。也可以在这个地方添加OpenGL,支持自定义GPU管线。
- 它解码后的音视频数据可以通过SDL(对不同平台提供一套统一的接口,调用不同的底层API库)去渲染视频和播放音频。可以通过OpenGLES去渲染视频,OpenGLES是OpenGL的子集,所以OpenGLES也可以在PC端渲染。
2. ffplay实现原理
1. ffplay是ffmpeg官方提供的播放器
它基于ffmpeg的强大功能,结合SDL实现了从拉流、解协议、解封装、音频解码、视频解码、音频播放、视频播放的一体化功能。
2. 以下是ffplay整体播放流程图:
3. ffplay有5个主要线程:
- 解协议、解封装线程: read_thread
- 音频解码线程:audio_thread
- 音频播放线程:sdl_audio_callback
- 视频解码线程:video_thread
- 视频播放线程(主线程):video_refresh
以上各线程之间各司其职、通力合作、有任务处理任务、无任务休眠等待其他线程唤醒继续执行任务。
4. 以下是各线程执行结构体关系图:
1. read_thread
负责解协议、解封装、将AVPacket放入音频PacketQueue或视频PacketQueue:
2. audio_thread
负责将音频队列里的AVPacket解码成AVFrame,经过滤镜处理后放入音频FrameQueue:
1. decoder_decode_frame:
2. audio_thread:
3. sdl_audio_callback
音频播放回调线程:
1. synchronize_audio:
2. audio_decode_frame:
3. sdl_audio_callback:
3. video_thread
负责将视频队列里的AVPacket解码成AVFrame,经过滤镜处理后放入视频FrameQueue:
4. video_refresh
视频播放线程负责从pictq队列取AVFrame渲染到SDLWindow中:
3. 优势分析
- ffmpeg实际是一个音视频框架,如果想要自定义一个协议进行播放只要按照规则实现一套对应的协议即可实现ffmpeg对此协议的支持,可以参考metaRTC这个例子。
- ffmpeg有统一的编解码代码实现,使得切换编解码器简直不要太容易,只需要将此编解码器编译到ffmpeg库中,然后修改一下编解码器对应的ID即可实现底层编解码器的切换,比如H264升级到H265将大幅降低服务器存储空间及传输带宽的占用,对直播和录播场景将节约不可估量的成本。
- ffmpeg配合SDL、OpenGLES将实现全平台的视频播放及特效处理。