std::string SniffingNetworkFlow(uint8_t* pbuf, int nbufsize, double* dTime)
{
av_register_all();
AVIOContext *pb = NULL;
AVInputFormat* piFmt = NULL;
std::string str = "";
pb = avio_alloc_context(pbuf, nbufsize, 0, NULL, NULL, NULL, NULL);
if (av_probe_input_buffer(pb, &piFmt, "", NULL, 0, 0) < 0)//探测从内存中获取到的媒体流的格式
{
fprintf(stderr, "probe format failed\n");
avio_context_free(&pb);
return str;
}
else
{
fprintf(stdout, "format:%s[%s]\n", piFmt->name, piFmt->long_name);
str = piFmt->name;
//return str;
}
AVFormatContext *pFormatCtx;
//打开视频流并显示
pFormatCtx = avformat_alloc_context();
pFormatCtx->pb = pb;
if (avformat_open_input(&pFormatCtx, "", piFmt, NULL) != 0) //iformat,priv_data赋值,pb, nbstreams,streams为null
{
printf("Couldn't open input stream.(无法打开输入流)\n");
avformat_close_input(&pFormatCtx);
avio_context_free(&pb);
return str;
}
if (avformat_find_stream_info(pFormatCtx, NULL)<0)//nbstreams,streams赋值, pb还是为null
{
printf("Couldn't find stream information.(无法获取流信息)\n");
avformat_close_input(&pFormatCtx);
avio_context_free(&pb);
return str;
}
av_dump_format(pFormatCtx, 0, "", 0);
int videoindex = -1;
for (int i = 0; i < pFormatCtx->nb_streams; i++) //一般情况下,一个媒体只有两个流,视频和音频流即streams[0],stream[1]
{
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{//找到视频流
videoindex = i;//在nb_streams视频流的索引
break;
}
}
if (videoindex < 0)
{
printf("Didn't find a video stream.(没有找到视频流)\n");
avformat_close_input(&pFormatCtx);
avio_context_free(&pb);
return "";
}
AVStream* pStream = pFormatCtx->streams[videoindex];
if (pStream->codecpar->width == 0 || pStream->codecpar->height == 0)
{
*dTime = 0;
avformat_close_input(&pFormatCtx);
avio_context_free(&pb);
return "";
}
//ceil向上,floor向下
if (pStream->avg_frame_rate.den == 0 || pStream->avg_frame_rate.num == 0)
*dTime = 0.04;
else
{
double fps = floor(av_q2d(pStream->avg_frame_rate));
*dTime = (1.00 / fps);
}
avformat_close_input(&pFormatCtx);
avio_context_free(&pb);
return str;
}
码流最少包含一帧完整数据,不然帧率无法获得,读文件最好读2M