FFmpeg n4.0.6获取RTSP流后无法读取time_base问题咨询
问题原因及解决方案
核心问题分析
你遇到的time_base读取为0/0的情况,主要有两个原因:
1. 流遍历逻辑错误
你的循环代码中,只要遇到非视频流就直接return -1,这会导致如果RTSP流包含音频流或其他辅助流时,程序会提前终止。虽然当前测试的流只有视频流,程序执行到了av_dump_format,但这个逻辑本身是错误的,会影响多流场景的兼容性。
2. FFmpeg旧版本的RTSP流time_base初始化特性
在FFmpeg n4.0.6版本中,部分RTSP流的stream->time_base并不会在avformat_find_stream_info执行完成后立即被填充。这是因为有些设备的SDP协议只提供了基础的码流信息(如分辨率、帧率),而精确的time_base需要从实际读取的RTP数据包或码流元数据中推导,avformat_find_stream_info无法完成这一步骤。
修正后的代码示例
修正流遍历逻辑
首先调整流遍历代码,正确找到视频流而不提前退出:
// 查找视频流索引 int videoindex = -1; for (int i = 0; i < pFormatCtx->nb_streams; i++) { printf("i: %d\n", i); if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoindex = i; printf("找到视频流,索引:%d\n", videoindex); } } // 未找到视频流才退出 if (videoindex == -1) { printf("未找到视频流.\n"); return -1; }
读取数据包后获取正确的time_base
添加读取数据包的逻辑,在读取至少一个视频数据包后,FFmpeg会自动填充time_base:
// 初始化AVPacket av_packet = av_packet_alloc(); if (!av_packet) { printf("AVPacket分配失败\n"); return -1; } // 读取一个数据包 if (av_read_frame(pFormatCtx, av_packet) == 0) { if (av_packet->stream_index == videoindex) { AVRational time_base = pFormatCtx->streams[videoindex]->time_base; printf("读取数据包后的time_base: %d/%d\n", time_base.num, time_base.den); } av_packet_unref(av_packet); }
额外说明
从av_dump_format的输出可以看到,流的tbn值为90k,这对应time_base为1/90000,这是RTSP流常用的时间基准。读取数据包后,你就能获取到这个正确的值。
内容的提问来源于stack exchange,提问作者何西西
相关产品推荐
相关产品推荐

