一、前言
和音频存储类似,视频的存储也对应三种格式,视频最原始的数据是yuv(音频对应pcm),视频压缩后的数据是h264(音频对应aac),由于很多播放器或者早期的播放器不支持直接播放h264文件,所以需要用编码器编码成mp4格式,这块就需要用到ffmpeg里面一整套的编码流程,对yuv数据进行编码成MP4格式存储。
在经过对各种视频文件或者视频流保存的过程中,发现rtsp这类的视频流可以直接编码打包存储,不需要经过 avcodec_send_frame avcodec_receive_packet 这两个步骤对每个包编码,这样可以极大的降低CPU占用,猜测可能是rtsp视频流收到的数据包packet就已经是标准的h264裸流带了各种pps啥的。所以视频监控领域如果要同时存储16路32路视频,采用这个策略是最稳妥的,相当于一直写文件。很多人会觉得编码流程繁琐,其实只要静下心来,挨个测试,把流程搞懂,基本上都是水到渠成的事情。包括之前遇到的保存的文件鼠标右键属性中看不到分辨率等参数信息,原来是调用写入文件头 avformat_write_header 写入的时机不对,一定要在打开打开视频编码器 avcodec_open2 以及打开输出文件 avio_open 以后再写入。
编码保存的大致流程:
- 查找编码器 avcodec_find_encoder
- 创建编码器 avcodec_alloc_context3
- 设置编码器 pix_fmt/time_base/framerate/width/height
- 打开编码器 avcodec_open2
- 创建上下文 avformat_alloc_output_context2
- 创建输出流 avformat_new_