今天测试ffmpeg推流rtmp的时候,发现视频帧推流特别耗时,
逐个api的获取时间后发现是
avcodec_send_frame耗时接近100ms
av_interleaved_write_frame/av_write_frame耗时60-500ms不等
1.
avcodec_send_frame
处理方法:
av_opt_set(vc->priv_data, "preset", "superfast", 0);
这样会加快avcodec_send_frame的速度,但是会影响清晰度
2.
av_interleaved_write_frame/av_write_frame 和 avcodec_send_frame
处理方法:
a.不设置vc->time_base = { 1,fps };也就是默认使用{1, 1000000},之后yuv数据的pts设置成从开始到现在的微秒级时间戳
b.或者设置vc->time_base = { 1,fps };之后继续设置yuv数据的pts;
yuv->pts = videoPts;
++videoPts;
方法1没必要,只要time_base和pts设置正确,avcodec_send_frame得到的packet就是一个很小的包,av_interleaved_write_frame往服务器推流的时候也只需要消耗很小的带宽
如果time_base和pts设置的不对,很容易导致计算错误,每一帧都以关键帧的形式产生,推流就会推整个关键帧的数据,导致耗时明显
AVCodecContext* vc=....
vc->bit_rate = 50 * 1024 * 8;//压缩后每秒视频的bit位大小 50kB//设置太小的话,其本就只能看马赛克了
vc->framerate = { fps,1 };
//画面组的大小,多少帧一个关键帧
vc->gop_size = 50;
vc->max_b_frames = 0;
注意关键帧的间隔,设置太大了会导致接收流的时候延迟严重,设置太小了会导致带宽压力(其实也不会太明显)