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,
	};
相关推荐
无敌最俊朗@21 小时前
音视频播放的核心处理流程
ffmpeg
mortimer2 天前
搞懂FFmpeg中2个桀骜不驯的参数:CRF 与 Preset
ffmpeg·音视频开发·视频编码
2401_841495643 天前
Windows 系统中ffmpeg安装问题的彻底解决
windows·python·ffmpeg·bug·语音识别·下载·安装步骤
八月的雨季 最後的冰吻3 天前
FFmpeg --15-视频解码: AVIO内存输入模式分析
ffmpeg·音视频
aqi003 天前
FFmpeg开发笔记(八十八)基于Compose的国产电视直播开源框架MyTV
android·ffmpeg·音视频·直播·流媒体
present12273 天前
一段音频/视频分离成人声与伴奏,Windows + Anaconda 快速跑通 Spleeter(离线可用)
windows·职场和发展·ffmpeg·音视频·娱乐·媒体
fxshy4 天前
python使用ffmpeg对视频进行转码
python·ffmpeg·音视频
zhangzhangkeji4 天前
FFMPEG - 6:合并、提取音视频;截取、连接音视频,
ffmpeg·音视频
mortimer4 天前
FFmpeg 拼接视频-记录我踩过的坑
ffmpeg·音视频开发
aqi004 天前
FFmpeg开发笔记(八十七)采用Kotlin的手机开源播放器VLC-Android
android·ffmpeg·音视频·流媒体