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,
	};
相关推荐
daqinzl4 小时前
node.js @ffmpeg-installer/ffmpeg 桌面推流
ffmpeg·node.js·installe·桌面推流
sunrise_ccx4 小时前
避坑ffmpeg直接获取视频fps不准确
ffmpeg·音视频
oushaojun24 小时前
win10中使用ffmpeg的filter滤镜
ffmpeg·filter
lindsayshuo4 小时前
香橙派--安装RKMPP、x264、libdrm、FFmpeg(支持rkmpp)以及opencv(支持带rkmpp的ffmpeg)(适用于RK3588平台)
人工智能·opencv·ffmpeg
海天鹰15 小时前
ffmpeg区域颜色覆盖
ffmpeg
@Crazy Snail1 天前
C# Winform--ffmpeg图片合成视频以及参数设置
开发语言·ffmpeg·c#
runing_an_min1 天前
ffmpeg 视频滤镜:高斯模糊-gblur
ffmpeg·音视频·高斯模糊·gblur
disgare1 天前
FFmpegFrameRecorder 切分视频文件时结束条件设置不当导致切分后的文件过短问题
ffmpeg
Tech Synapse1 天前
Java中使用FFmpeg拉取RTSP流
java·开发语言·ffmpeg
oushaojun21 天前
ubuntu中使用ffmpeg和nginx推http hls视频流
nginx·ubuntu·ffmpeg·hls