前言

FFmpeg的avformat_open_input函数和av_read_frame函数默认是阻塞的,意味着如果RTSP服务器不在线的情况下,ffplay工具会一直在avformat_open_input函数内部不断尝试连接服务器。

ffplay退出阻塞的机制

decode_interrupt_cb函数主要是为了允许用户中断退出

当用户按下键盘的q,abort_request将会赋值为1,在上述两个函数中,退出循环

static int decode_interrupt_cb(void *ctx)
{
          
          
    VideoState *is = ctx;
    return is->abort_request;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
ic->interrupt_callback.callback = decode_interrupt_cb;
    ic->interrupt_callback.opaque = is;
  • 1.
  • 2.

连接超时

代码堆栈

ffplayd.exe!decode_interrupt_cb(void * ctx)2713	C
 	ffplayd.exe!ff_check_interrupt(AVIOInterruptCB * cb)667	C
 	ffplayd.exe!ff_poll_interrupt(pollfd * p, unsigned long nfds, int timeout, AVIOInterruptCB * cb)166	C
 	ffplayd.exe!ff_connect_parallel(addrinfo * addrs, int timeout_ms_per_address, int parallel, URLContext * h, int * fd, void(*)(void *, int) customize_fd, void * customize_ctx)461	C
 	ffplayd.exe!tcp_open(URLContext * h, const char * uri, int flags)198	C
 	ffplayd.exe!ffurl_connect(URLContext * uc, AVDictionary * * options)205	C
 	ffplayd.exe!ffurl_open_whitelist(URLContext * * puc, const char * filename, int flags, const AVIOInterruptCB * int_cb, AVDictionary * * options, const char * whitelist, const char * blacklist, URLContext * parent)345	C
 	ffplayd.exe!ff_rtsp_connect(AVFormatContext * s)1841	C
 	ffplayd.exe!rtsp_read_header(AVFormatContext * s)726	C
>	ffplayd.exe!avformat_open_input(AVFormatContext * * ps, const char * filename, AVInputFormat * fmt, AVDictionary * * options)631	C
 	ffplayd.exe!read_thread(void * arg)2780	C
 	ffplayd.exe!SDL_RunThread(void * data)283	C
 	ffplayd.exe!RunThread(void * data)91	C
 	ffplayd.exe!RunThreadViaBeginThreadEx(void * data)106	C
 	ucrtbased.dll!00007ffbf3f14fb8()	未知
 	ucrtbased.dll!00007ffbf3f14bf1()	未知
 	kernel32.dll!00007ffc6c1e7c24()	未知
 	ntdll.dll!00007ff