ffmpeg中的超时控制

在FFmpeg库中,很多函数没有直接的参数可以设置超时。

那么有哪些函数可以通过设置 AVFormatContext 的 interrupt_callback 来实现超时控制?

  • avformat_open_input: 打开输入文件或流。这个函数会阻塞,尤其是在网络流的情况下,可能会因为等待服务器响应而长时间阻塞。

  • avformat_find_stream_info: 读取流信息。这个函数会尝试读取更多的数据来获得流的详细信息,如果数据源响应缓慢,也会阻塞。

  • av_read_frame: 读取数据包。这个函数会读取下一帧的数据包,如果数据源响应缓慢或者网络连接不稳定,也会阻塞。

  • avio_read: 从输入缓冲区读取数据,这个函数也会阻塞。

  • avio_open: 打开文件或网络资源以进行读取或写入的函数。

  • av_seek_frame 或 **avformat_seek_file**用于在媒体流中进行跳转操作

  • 等等

总之在打开、关闭、读写网络流的时候都有可能遇到阻塞的问题。

以**avformat_find_stream_info函数为例,函数的调用关系如下:**

复制代码
avformat_find_stream_info
	read_frame_internal
		ff_read_packet
			s->iformat->read_packet
				read_packet(rpsp.c)
					ff_sdp_demuxer.read_packet = ff_rtsp_fetch_packet
						ff_rtsp_fetch_packet
							read_packet
								ff_rtsp_tcp_read_packet
									ff_rtsp_read_reply
										ffurl_read_complete
											retry_transfer_wrapper
												ff_check_interrupt

ff_check_interrupt函数用于检测中断回调函数是否应该触发中断操作。

调用ff_check_interrupt函数的函数包括:

复制代码
async_check_interrupt in async.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
retry_transfer_wrapper in avio.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
get_current_fragment in dashdec.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
read_data in dashdec.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
reopen_demux_for_component in dashdec.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
dash_read_packet in dashdec.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
failing_write_packet in fifo_test.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
read_data in hls.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
read_data in hls.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
read_data in hls.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
hls_read in hlsproto.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
hls_read in hlsproto.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
libsrt_network_wait_fd_timeout in libsrt.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
libsrt_listen_connect in libsrt.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
ff_network_wait_fd_timeout in network.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
ff_network_sleep_interruptible in network.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
ff_poll_interrupt in network.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
ff_listen_connect in network.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
start_connect_attempt in network.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
rtp_read in rtpproto.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 
udp_read_packet in rtsp.c (ffmpeg\ffmpeg-4.1.4\libavformat) : 

以上函数被进一步调用的关系如下:

复制代码
retry_transfer_wrapper
	ffurl_read
		wrapped_url_read
		io_read_packet
		cache_read
		concat_read
		crypto_read
		ftp_getc
		ftp_read
		ftp_read_dir
		gopher_read
		hls_read
		http_getc
		http_buf_read
		http_shutdown
		rtmpe_read
		rtmp_http_send_cmd
		rtmp_http_read
		rtmp_http_open
		ff_rtmp_packet_read
		ff_rtmp_packet_read_internal
		rtmp_write
		udp_read_packet
		rtp_read_header
		sap_read_header
		sap_fetch_packet
		srtp_read
		subfile_read
		gnutls_url_pull
		tls_read_callback
		mbedtls_recv
		url_bio_bread
		tls_client_handshake_loop
		tls_read
		tls_read_cb
	ffurl_read_complete
		get_chunk_header
		read_data_packet
		get_http_header_data
		get_tcp_server_response
		rtmp_packet_read_one_chunk
		rtmp_calc_swfhash
		rtmp_handshake
		rtmp_receive_hs_packet
		rtmp_server_handshake
		ff_rtsp_skip_packet
		ff_rtsp_read_reply
		read_line
		rtsp_read_announce
		ff_rtsp_tcp_read_packet
	ffurl_write
		io_write_packet
		crypto_write
		crypto_close
		ftp_send_command
		ftp_write
		gopher_write
		http_write_reply
		http_connect
		http_write
		ff_rtmp_packet_write
		ff_rtp_check_and_send_back_rr
		ff_rtp_send_punch_packets
		ff_rtp_send_rtcp_feedback
		ff_rtsp_read_reply
		ff_rtsp_tcp_write_packet
		gnutls_url_push
		http_proxy_open
		http_proxy_write
		http_shutdown
		icecast_write
		ism_write
		mbedtls_send
		md5_close
		prompeg_write_fec
		rtmp_handshake
		rtmp_send_hs_packet
		rtmp_server_handshake
		rtmpe_write
		rtp_write
		rtsp_send_cmd_with_content_async
		rtsp_send_reply
		sap_write_close
		sap_write_packet
		send_command_packet
		srtp_write
		tee_write
		tls_client_handshake
		tls_client_handshake_loop
		tls_shutdown_client
		tls_write
		tls_write_callback
		tls_write_cb
		url_bio_bwrite
		
async_check_interrupt
	async_buffer_task
	async_open
	async_read_internal
	async_seek
	
ff_listen_connect
	sctp_open
	unix_open
	
ff_network_sleep_interruptible
	http_read_stream
	
ff_network_wait_fd_timeout
	tcp_read
	tcp_write
	
ff_poll_interrupt
	ff_listen_connect
	ff_connect_parallel
	
get_current_fragment
	read_data
	
libsrt_listen_connect
	libsrt_setup
	
libsrt_network_wait_fd_timeout
	libsrt_listen
	libsrt_listen_connect
	libsrt_read
	libsrt_write
	
read_data
	hls_read_header
	pulse_read_packet
	reopen_demux_for_component
	tls_client_handshake_loop
	
reopen_demux_for_component
	open_demux_for_component
	recheck_discard_flags
	dash_read_packet
	dash_seek
	
start_connect_attempt
	ff_connect_parallel
	
udp_read_packet
	read_packet

dash_read_packet
	AVInputFormat ff_dash_demuxer = {
   .name           = "dash",
   .long_name      = NULL_IF_CONFIG_SMALL("Dynamic Adaptive Streaming over HTTP"),
   .priv_class     = &dash_class,
   .priv_data_size = sizeof(DASHContext),
   .read_probe     = dash_probe,
   .read_header    = dash_read_header,
   .read_packet    = dash_read_packet,
   .read_close     = dash_close,
   .read_seek      = dash_read_seek,
   .flags          = AVFMT_NO_BYTE_SEEK,
	};

failing_write_packet
	AVOutputFormat ff_fifo_test_muxer = {
   .name           = "fifo_test",
   .long_name      = NULL_IF_CONFIG_SMALL("Fifo test muxer"),
   .priv_data_size = sizeof(FailingMuxerContext),
   .write_header   = failing_write_header,
   .write_packet   = failing_write_packet,
   .write_trailer  = failing_write_trailer,
   .deinit         = failing_deinit,
   .priv_class     = &failing_muxer_class,
   .flags          = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
	};
		
hls_read
	const URLProtocol ff_hls_protocol = {
   .name           = "hls",
   .url_open       = hls_open,
   .url_read       = hls_read,
   .url_close      = hls_close,
   .flags          = URL_PROTOCOL_FLAG_NESTED_SCHEME,
   .priv_data_size = sizeof(HLSContext),
	};

rtp_read
	const URLProtocol ff_rtp_protocol = {
   .name                      = "rtp",
   .url_open                  = rtp_open,
   .url_read                  = rtp_read,
   .url_write                 = rtp_write,
   .url_close                 = rtp_close,
   .url_get_file_handle       = rtp_get_file_handle,
   .url_get_multi_file_handle = rtp_get_multi_file_handle,
   .priv_data_size            = sizeof(RTPContext),
   .flags                     = URL_PROTOCOL_FLAG_NETWORK,
   .priv_data_class           = &rtp_class,
	};
相关推荐
dwp11471706071 天前
在Windows上基于MSYS2 UCRT64工具链编译ffmpeg源码
windows·ffmpeg
专业开发者1 天前
开发者可从蓝牙 ® 低功耗音频(Bluetooth® LE Audio)中获得的 4 大功能
物联网·ffmpeg·音视频
dwp11471706071 天前
在Windows上基于MSYS2 MSVC工具链编译ffmpeg源码
windows·ffmpeg
筏.k2 天前
FFmpeg 视频解码入门:H264 软解码器简单示例
ffmpeg·音视频
hk11242 天前
【音视频/边缘计算】2025年度H.265/HEVC高并发解码与画质修复(Super-Resolution)基准测试报告(含沙丘/失控玩家核心样本)
ffmpeg·边缘计算·音视频开发·h.265·测试数据集
筏.k2 天前
FFmpeg 视频解码进阶:H264_CUVID 硬解码器简单示例
ffmpeg·音视频
auspicious航3 天前
数据库同步技术演进:从备份转储到实时CDC的DBA实战指南
数据库·ffmpeg·dba
小馬佩德罗4 天前
如何将x264 x265的动态库编译入Linux系统中的FFmpeg源码 - x264库编译
linux·ffmpeg·x264
Black蜡笔小新4 天前
视频融合平台EasyCVR融合无线监控,打造智能高效安防解决方案
ffmpeg·音视频
jianghusanren34 天前
【无标题】
ffmpeg