Qt/C++音视频开发67-保存裸流加入sps/pps信息/转码保存/拉流推流
在h264流中,有两种NALU极其的重要,序列参数集(SequenceParamaterSet,SPS)和图像参数集(PictureParamaterSet,PPS),SPS中的信息至关重要,记录了编码的prfile、level、图像宽高等,如果其中的数据丢失或出现错误,那么解码过程很可能会失败。每一帧编码后数据所依赖的参数保存于PPS中。一般情况SPS和PPS的NALUnit通常位于整个码流的起始位置。封装文件一般进保存一次,位于文件头部,sps/sps再整个解码过程中复用,不发生变化。然而对于实时流,通常是从流中间开始解码,因此需要在每个I帧前添加SPS和PPS;如果编码器在编码过程中改变了码流参数(如分辨率),需要重新调整SPS和PPS数据。
ffmpeg中SPS、PPS数据从输入流中解析时,位于AVFormatContext-streams[video_index]-codecpar-extradata中。编码时,sps/pps数据存放于编码器上下文AVCodecContext-extradata中,但是该对象通常是空指针,还需要进行额外设置。通常我们编码保存裸流时,仅第一个I帧前有SPS/PPS数据。但是,如果需要做实时流传输,必须要在每一个I帧前添加SPS和PPS。其中SPS和PPS分别是14/5个字节。
有两种方法可以加上sps/pps,一种是自己判断并主动加上,一种是用ffmpeg自带的bsf相关函数,推荐使用bsf相关函数处理,非常准确而且性能高。一开始我也以为很难,其实非常简单,总结就是三步走,初始化,不断写入,关闭释放。
添加sps/pps大致步骤:
初始化AVBSFContext,av_bsf_alloc/avcodec_parameters_copy/av_bsf_init。
写入数据av_bsf_s_packet/av_bsf_receive_packet。
关闭释放av_bsf_free。
二、效果图三、体验地址国内站点:
国际站点:
个人作品:
体验地址::01jf文件名:bin_video_demo。
四、功能特点4.1.基础功能支持本地摄像头设备和本地桌面采集,支持多设备和多屏幕。
文件可以指定播放位置、调节音量大小、设置静音状态等。
支持倍速播放文件,可选0.5倍、1.0倍、2.5倍、5.0倍等速度,相当于慢放和快放。
支持开始播放、停止播放、暂停播放、继续播放。
支持抓拍截图,可指定文件路径,可选抓拍完成是否自动显示预览。
支持录像存储,手动开始录像、停止录像,部分内核支持暂停录像后继续录像,跳过不需要录像的部分。
支持无感知切换循环播放、自动重连等机制。
多线程处理,一个解码一个线程,不卡主界面。
4.2.特色功能同时支持多种解码内核,包括qmedia内核(Qt4/Qt5/Qt6)、ffmpeg内核(ffmpeg2/ffmpeg3/ffmpeg4/ffmpeg5/ffmpeg6)、vlc内核(vlc2/vlc3)、mpv内核(mpv1/mp2)、mdk内核、海康sdk、easyplayer内核等。
非常完善的多重基类设计,新增一种解码内核只需要实现极少的代码量,就可以应用整套机制,极易拓展。
支持多种硬件加速类型,ffmpeg可选dxva2、d3d11va等,vlc可选any、dxva2、d3d11va,mpv可选auto、dxva2、d3d11va,mdk可选dxva2、d3d11va、cuda、mft等。不同的系统环境有不同的类型选择,比如linux系统有vaapi、vdpau,macos系统有videotoolbox。
解码线程和显示窗体分离,可指定任意解码内核挂载到任意显示窗体,动态切换。
本地摄像头设备支持指定设备名称、分辨率、帧率进行播放。
本地桌面采集支持设定采集区域、偏移值、指定桌面索引、帧率、多个桌面同时采集等。还支持指定窗口标题采集固定窗口。
支持逐帧播放,提供上一帧/下一帧函数接口,可以逐帧查阅采集到的图像。
音频文件自动提取专辑信息比如标题、艺术家、专辑、专辑封面,自动显示专辑封面。