由于网络环境不稳定,在实际的录像过程中常常会将录制的文件保存为多个视频文件,后期就需要更多的资源来进行视频合并,并且增加了额外的时间开销。为了解决这个问题,同时考虑到时间的开销以及资源占用率最小,就想出了这样的一个办法,在断网时,av_read_frame()会在达到超时后,返回一个负值,由于同一个摄像机里面的参数都一致,可以沿用前面设置的参数,后面只需要再次打开流,不停的检查是否能连通,连通后将对应的视频流和音频流写入到对应的位置中。
在检测流是否连通过程中,需要不断的对avformatcontext分配内存,为了避免内存溢出,需要分配一次,就释放一次。测试发现,当调用avformat_open_input()失败时,下一次分配内存时,并没有增加额外的内存开销,因此就不需要担心内存溢出的情况。
测试代码如下:
#include<iostream>
#include<thread>
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libavutil/avstring.h>
#include <libavutil/pixfmt.h>
#include <libavutil/samplefmt.h>
#include <libavutil/channel_layout.h>
#include "MP4Encoder.h"
#include<malloc.h>
#include<Windows.h>
}
using namespace std;
bool state=false;
AVFormatContext *ifmt=NULL;
/*
返回 -1失败,0成功
*/
int InitInputRtspStream(const char* url,AVFormatContext *ic)
{
AVDictionary* options = NULL;
av_dict_set(&options,"rtsp_transport", "tcp", 0);
av_dict_set(&options,"stimeout","5000000",0);
if(avformat_open_input(&ic,url,NULL,&options)!=0)
return -1;
if(avformat_find_stream_info(ic,NULL)<0)
return -1;
//显示输入流信息
printf("-----------rtsp流输入信息--------------\n");
av_dump_format(ic, 0, url,0);
printf("---------------------------------------\n");
printf("\n");
return 0;
}
void test()
{
int ret=-1;
int i=0;
while(!state)
{
i++;
av_register_all();
avformat_network_init();
ifmt=avformat_alloc_context();
printf("---第%d次 分配地址%0x 内存大小:%d\n",i,ifmt,sizeof(*ifmt));
ret=InitInputRtspStream("rtsp://admin:admin@192.168.10.114:554",ifmt);
if(ret>=0)
{
avformat_close_input(&ifmt);
}
printf("***第%d次 分配地址%0x 内存大小:%d\n",i,ifmt,sizeof(*ifmt));
}
}
void main()
{
state=false;
thread task(test);
task.detach();
printf("输入按键停止\n");
getchar();
state=true;
printf("退出程序\n");
getchar();
}
测试结果