最近有用到存内存中读取数据,通过ffmpeg推成rtmp流。
参考了雷神的两篇帖子
https://blog.csdn.net/leixiaohua1020/article/details/39803457
https://blog.csdn.net/leixiaohua1020/article/details/39759163
主要遇到如下几个问题比较头疼
1. avformat_write_header 返回-12
2. av_interleaved_write_frame返回-22
3. av_read_frame内存读取异常
由于看不到具体的ffmpeg日志,单单根据返回值无法分析原因,所以第一步是将ffmpeg日志显示出来
主要参考
https://blog.csdn.net/fireroll/article/details/80712138
,对ffmpeg日志进行设置。
对于问题1 avformat_write_header 返回-12 打印出来的ffmpeg显示
sample rate not set 或 dimensions not set
参考雷神帖子
https://blog.csdn.net/leixiaohua1020/article/details/44116215
case AVMEDIA_TYPE_AUDIO:
if (codec->sample_rate <= 0) {
av_log(s, AV_LOG_ERROR, “sample rate not set\n”);
ret = AVERROR(EINVAL);
goto fail;
}
if (!codec->block_align)
codec->block_align = codec->channels *
av_get_bits_per_sample(codec->codec_id) >> 3;
break;
case AVMEDIA_TYPE_VIDEO:
if ((codec->width <= 0 || codec->height <= 0) &&
!(of->flags & AVFMT_NODIMENSIONS)) {
av_log(s, AV_LOG_ERROR, “dimensions not set\n”);
ret = AVERROR(EINVAL);
goto fail;
}
大概问题定位,主要是流的信息不全,我比较蹩脚的方法就不停的去读,读到一个包含了width和height大于0的包,再去写头,一般能成功。
对于问题2 :av_interleaved_write_frame返回-22 同样的输出日志为
Application provided invalid, non monotonically increasing dts to muxer in stream 0: 59398246 >= 1270
大概意思是,新推的这个包的dts不能小于最后推成功那个包的dts, 于是我就把最后推成功的dts和pts都记录下来,当新包的dts或pts小于之前记录的时候,就自己在之前的基础上加40,重置dts和pts.
对于问题3 :偶尔会内存读取异常,要注意avpackage的释放问题
av_read_frame返回大于等于0时, avpackage需要人为释放
av_read_frame返回小于0时,avpackage会自动释放,或者说根本就没申请到内存空间。
av_interleaved_write_frame 调用完成后,函数会自动释放内存空间。
网络不稳定也会导致读不到正确的信息,导致崩溃。 记录下希望对后来者有帮助。