在上一篇文章中,对FFmpeg的视频解码过程做了一个总结。由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结。
本文的总结分为以下两个部分:
- 数据读取,主要关注在解码过程中所用到的FFmpeg中的结构体。
- 解码过程中所调用的函数
在学习的过程主要参考的是dranger tutorial,所以跟着教程在本文的最后使用SDL2.0将解码后的数据输出到屏幕上。
数据的读取
一个多媒体文件包含有多个流(视频流 video stream,音频流 audio stream,字幕等);流是一种抽象的概念,表示一连串的数据元素;
流中的数据元素称为帧Frame。也就是说多媒体文件中,主要有两种数据:流Stream 及其数据元素 帧Frame,在FFmpeg自然有与这两种数据相对应的抽象:AVStream和AVPacket。
使用FFmpeg的解码,数据的传递过程可归纳如下:
1. 调用avformat_open_input
打开流,将信息填充到AVFormatContext
中
2. 调用av_read_frame
从流中读取数据帧到 AVPacket
,AVPacket
保存仍然是未解码的数据。
3. 调用avcodec_decode_video2
将AVPacket
的数据解码,并将解码后的数据填充到AVFrame
中,AVFrame
中保存的是解码后的原始数据。
上述过程可以使用下图表示:
结构体的存储空间的分配与释放
FFmpeg并没有垃圾回收机制,所分配的空间都需要自己维护。而由于视频处理过程中数据量是非常大,对于动态内存的使用更要谨慎。
本小节主要介绍解码过程使用到的结构体存储空间的分配与释放。
AVFormatContext 在FFmpeg中有很重要的作用,描述一个多媒体文件的构成及其基本信息,存放了视频编解码过程中的大部分信息。通常该结构体由
avformat_open_input
分配
存储空间,在最后调用avformat_input_close
关闭。