抽取视频数据
- 抽取视频数据需要掌握的基本概念
- Start code
1.抽取视频数据的本质
本质: 多媒体中的视频数据是压缩(编码)后的Frame数据,压缩后的视频帧我们称之为 packet,简单起见我们将其称之为视频帧。抽取操作即抽取的是
视频帧序列。
2.抽取方案
方式1: 每一帧加上帧的length
读物第一帧的时候读取帧的长度,紧接着第二帧的长度,第二帧;第三帧的长度,第三帧;以此类推;
方式2: 每一帧前面加上关键字-称之为特征吗,start code,可以想像成栅栏,有点类似迭代器的概念
即遇到start code 代表当前帧开始,前面的帧结束。start code 是为了区分帧与帧之间的间隔。
start code 作用的直观感受,即当播放器播放h264数据时,是根据start code 将不同帧区分出来进行播放
3.某些基本概念
SPS/PPS (暂时不做介绍,可以去网上搜)
作用,解码的视频参数,入视频帧的宽,高(视频分辨率),fps(帧率),其他的参数都存放在SPS,PPS 中
需要说明的是,普通视频文件只需要有一个SPS/PPS 就可以了,获取到SPS & PPS后,每次解码都获取到相同的分辨率,相同帧率
在个别异常情况,如直播流视频帧的分辨率发生变化(切换分辨率),实际中不止存放一份SPS/PPS,当分辨率发生变化时,都需要update SPS/PPS,当解码器拿到变化的
SPS/PPS ,就可以重新解码了。
如何解决上述问题,如果 SPS/PPS 丢失了怎么办? 对应解决方案:在每个关键帧的前面都会增加SPS/PPS数据包,当数据包丢失之后,后面再接受到新的关键
帧包,可以正常解码下去,否则产生花屏。
如果每次都传输 SPS/PPS 是否会增加网络负担;SPS/PPS 一般在 1-19 个字节内,网络无负担
另外每个关键帧前面需要有 SPS/PPS 数据,非关键帧不需要有 SPS/PPS, 关键帧有了这个数据 编解码器才知道视频参数有没有发生变化,有变化,
编解码器需要重新初始化,没有变化,则不需要做。
ffmpeg 如何获取 SPS/PPS
通过codec-extradata 获取,SPS/PPS 不与数据包 packet 存储在一起,而是放在编码器的扩展数据中存储 codec-extradata
4.实战抽取多媒体视频文件中的h264数据
extr_video_gop 代码中对应每一行都有对应注释,可以仔细过一遍
5.编译 & 运行
1. 编译
clang -g -o extr_video_gop extr_video_gop.c `pkg-config --libs libavutil libavformat`
2. 运行
./extr_video_gop data/left.mp4
3. 待完成(存储至文件的操作后续更改为网络传输数据至后端业务服务器)
6.运行效果
6.1 采用python + ffmpeg cmd 实现 的获取gop 的操作结果如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/c8b5f4ea9a05126d89d3461ce2f3edb1.png)
python + ffmpeg cmd 效果
6.2 c代码实现 ffmpeg 获取gop h264 效果代码
![](https://i-blog.csdnimg.cn/blog_migrate/9320265f11d8da087279531fbe376d4d.png)
c代码实现 ffmpeg 获取gop h264数据
可以看到效果是对齐的。