赞
踩
最近的流媒体项目中,在拉车辆流的过程中,发现调用ffmpeg avcodec_send_packet
和avcodec_receive_frame
时总是不能做到送入1包,立刻吐出对应pts的一帧,总是有缓存2-3帧的问题。对于普通的播放器已经足够,但是平行驾驶要求的极低延时就无法做到了。因为传输的h264流完全是只有IP帧,并没有依赖后向的B帧。所以开始调查问题解决办法。
1 首先尝试一些低延时参数,无效
AVDictionary *avdic=NULL;
av_dict_set(&avdic, "rtsp_transport", "tcp", 1);
av_dict_set(&avdic, "muxdelay", "0", 0);
av_dict_set(&avdic, "fflags", "nobuffer", 0);
av_dict_set(&avdic, "tune", "zerolatency", 0);
av_dict_set(&avdic, "max_delay", "0", 0);
av_dict_set(&avdic, "preset", "superfast", 0);
av_dict_set(&avdic, "packet-buffering", "0", 0);
2 查看官网发现有送入flush包的说法,用于刷新解码器,但是只是用于seek操作
https://ffmpeg.org/doxygen/4.0/group__lavc__encdec.html
3 开始dump ffmepg和webrtc两端的流,终于发现端倪
dump类工具
#include <fstream> class H264Dump { public: //static H264Dump &Instance(); H264Dump(); ~H264Dump(); //void inputFrame(const H264Frame::Ptr &frame); void inputPkt(const char* data, int size); static int i; std::ofstream out; // std::mutex frame_list_mutex; // std::list<std::string> frame_list; }; int H264Dump::i = 0; H264Dump::H264Dump() { std::string _ = "player_11_5_" + std::to_string(++H264Dump::i) + ".h264"; out = std::ofstream( _ , std::ios_base::out | std::ios::trunc | std::ios::binary); } H264Dump::~H264Dump() { out.close(); } void H264Dump::inputPkt(const char* data, int size) { out.write(data, size); out.flush(); } _ffmpeg_dump_h264.inputPkt((char*)packet->data, packet->size);
相同的文件,webrtc在收端,接到的流和原文件有一些小小的差异。在每个I帧(5)pps帧(8)之前,即**sps帧(7)**有一些不同,影响到了解码器能否立刻输出的情况!
H264码流中SPS PPS详解
vui参数的提问
H264裸流分析中,能获取哪些信息?
BSAnalyzer工具分析dump下的流
可以看到主要的不同就是在于num_reorder_frames
和max_dec_frame_buffering
的设置,webrtc是01,而我们的是22对于IPPP这种时不要缓存或者重排的,修改编码器后,果然解决了。
能正常拉到的流不一定就没问题,要仔细分析sps,pps等参数!
framerate=(time_scale/num_unit_in_tick)/2;
(pic_width_in_mbs_minus1+1 )*16 = 宽
(pic_height_in_map_units_minus1+1)*16 = 高
00 00 00 01 27 SPS
00 00 00 01 28 PPS
00 00 00 01 65(25) I帧
00 00 00 01 41 P帧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。