最近使用ffmpeg来做一个rtsp的客户端,这过程也遇到不少问题,不过相应都比较好,一路走下来.不过到项目结尾时,且遇到一个比较纠结的问题.那就是客户端在使用的过程中,把rtsp服务器的网断了.这时客户端会卡死.无法操作.尝试了各种线程的处理,还不行.最后追踪代码来到av_read_frame这个函数.问题就出现在它身上了.当服务器断网后,这个函数会一直没有返回,且整个线程也停在那里了.
难道就没有连接超时的判断.
原来要想实现连接超时的判断,得用回调函数.网上有两种设置方法.不过我这边只有这种是有效的.
直接上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
AVCodec *pCodec; // Register all formats and codecs
av_register_all();
avcodec_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
pFormatCtx->interrupt_callback.callback = interrupt_cb;--------注册回调函数
pFormatCtx->interrupt_callback.opaque = pFormatCtx;
AVDictionary* options = NULL;
av_dict_set(&options, "rtsp_transport" , "tcp" , 0);
// ret = avformat_open_input(&pFormatCtx, cFullPath, 0, &options);
//avformat_network_init();
// Open video file
if (avformat_open_input(&pFormatCtx, [url cStringUsingEncoding:NSASCIIStringEncoding], 0, &options) != 0) {
av_log(NULL, AV_LOG_ERROR, "Couldn't open file\n" );
goto initError;
}
|
再另外定义一下函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
static int interrupt_cb( void *ctx)
{ // do something
NSLog(@ "%d" ,time_out);
time_out++;
if (time_out > 40) {
NSLog(@ "------%d" , firsttimeplay);
time_out=0;
if (firsttimeplay) {
firsttimeplay=0;
NSLog(@ "++++++++" );
return 1; //这个就是超时的返回
}
}
return 0;
} |
这样,回调函数就会一直在后台运行着,然后就可以在上面加一些逻辑让超时返回1了,返回1,系统就自动结束,把主动权交回给主线程,这样用户就可以再操作ui了,卡死的问题ok