FFmpeg长时间无响应的解决方法

FFmpeg长时间无响应的解决方法

需要解决的问题

1、FFmpeg去连接的时候相机不在线导致avformat_open_input等函数一直死等,造成程序卡死

2、av_read_frame的过程中相机断开连接导致读取码流一直死等

解决方法

打开流媒体之前注册FFmpeg回调函数

AVFormatContext *m_pRtspFmt = avformat_alloc_context();

 m_pRtspFmt->interrupt_callback.callback = AVInterruptCallBackFun;
 m_pRtspFmt->interrupt_callback.opaque = this;

回调函数类型为:

typedef struct AVIOInterruptCB {int (*callback)(void*);void *opaque;} AVIOInterruptCB;

回调函数中返回1则代表ffmpeg结束阻塞可以将操纵权交给用户线程并返回错误码

回调函数中返回0则代表ffmpeg继续阻塞直到ffmpeg正常工作为止

所以要退出死等则需要返回1

伪代码如下:

//相机连接类
class CIPCamera
{
public:
	CIPCamera();
	   ~CIPCamera();
	  //AVReadFrame超时回调函数
	static  int  AVInterruptCallBackFun(void   *ctx);
	//读取rtsp码流线程
	static DWORD WINAPI  ReadStreamThread(LPVOID param);
	//心跳监控线程--监控线程是否死掉
	static DWORD WINAPI MonitorThread(LPVOID param);
};

int CIPCamera::AVInterruptCallBackFun(void *param)
{
	CIPCamera *pCamera = (CIPCamera*)param;
	if (NULL == pCamera) return 0;

	if (pCamera->m_bQuitFFmpegBlock)
	{
		//通知FFMpeg可以从阻塞工作线程中释放操作
		return 1;
	}
	else
	{
		//通知FFMpeg继续阻塞工作
		return 0;
	}
}
//连接相机 读取rtsp码流线程
DWORD WINAPI CIPCamera::ReadStreamThread(LPVOID param)
{
	CIPCamera *pCapture = (CIPCamera*)param;

	if (NULL == pCapture) return -1;

	pCapture->ConnectCamera();
	while (pCapture->m_bWorkOK)
	{
		//FFmpeg读取码流
		pCapture->ReadStream();
		//发送心跳
		pCapture->HeartBeat();
		Sleep(1);
	}
	return TRUE;
}
//监控线程
DWORD WINAPI CIPCamera::MonitorThread(LPVOID param)
{
	CIPCamera *pCamera = (CIPCamera*)param;
	if (NULL == pCamera) return -1;

	while (pCamera->m_bReWork)
	{
		//如果心跳超时
		if ( OK != pCamera->GetState(&nTimeOut);)
		{
			//则通知ffmpeg返回
			pCamera->m_bWorkOK = FALSE;
			pCamera->m_bQuitFFmpegBlock = TRUE;
		}
		else
		{
			//ffmpeg继续工作
			pCamera->m_bWorkOK = TRUE;
		}
		Sleep(100);
	}

	return 0;
}
时间: 2024-08-05 12:55:33

FFmpeg长时间无响应的解决方法的相关文章

Android ListView的item点击无响应的解决方法

如果listitem里面包括button或者checkbox等控件,默认情况下listitem会失去焦点,导致无法响应item的事件,最常用的解决办法 是在listitem的布局文件中设置descendantFocusability属性. item的布局文件: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.andro

Endnote 导入enw文件无响应及解决方法

Endonote 导入enw文件无响应及解决方法 今天在修改硕士毕业论文的时候发现,有些文献是在endnote上在线所搜不到的,必须自行在pubmed上搜到后,下载保存为.enw文件.但是通过在endnote上导入.ENW文件却发现没有反应不会出现新导入组,如下图 ,但导入后没有出现imported References 组 解决方法 直接双击.enw文件后解决问题,.enw文件可被导入(导入后左侧栏随即出现imported References 组). 原文地址:https://www.cnb

JVM 调优 —— GC 长时间停顿问题及解决方法

零. 简介 垃圾收集器长时间停顿,表现在 Web 页面上可能是页面响应码 500 之类的服务器错误问题,如果是个支付过程可能会导致支付失败,将造成公司的直接经济损失,程序员要尽量避免或者说减少此类情况发生. 一. 并发模式失败(concurrent mode failure) 并发模式失败日志: 2016-02-21T13:53:07.974+0800: 171467.254: [GC [1 CMS-initial-mark: 1436199K(1560576K)] 1512927K(25043

eclipse插件Maven添加依赖查询无结果的解决方法(Select Dependency doesn&#39;t work)

在eclipse中用过maven的可能都遇到过这种情况,我以前一直在search.maven里面搜索,然后添加pom信息. 今天在网上搜索时,找到了一个解决方法,在这里分享一下. 第一步,在preferences里面选择maven,选中"Download repository index updates on startup" 第二步,打开Maven仓库 第三步,在全局仓库上右键选择"Full Index Enabled" 选择之后,maven会下载一个近百兆的索引

Windows 8.1/10 升级补丁导致Windows资源管理器停止响应的解决方法

前言 我自己的操作系统是Windows 8.1(现在为Windows 10),微软在2015年03月11日推送了新的更新补丁,重新启动计算机后发现Windows资源管理器频繁卡顿假死导致不停重启,资源管理器CPU会异常升高,使得Windows资源管理器停止响应.这个问题困扰了我大半个月时间,差点就直接怒降Windows 7或者提前入坑Windows 10预览版(也有各种地雷Bug在等你来踩),现在终于找到了解决方法,分享给大家以供参考. 微软这次的升级补丁测试得可真到位 更新历史 2015年05

svn查看日志(show log)显示时间为1970的解决方法

问题: 在修改文件后show log无法显示日志,上面的时间会自动在2016年和1970年间跳,而且设置不了时间.解决方法:1.编辑svnserve.conf,设置“anon-access=none” 2.在authz中添加 [/]* = r 3,清理svn的cache 即可 svn查看日志(show log)显示时间为1970的解决方法,布布扣,bubuko.com

WPF:鼠标长时间无操作,窗口隐藏

//设置鼠标长时间无操作计时器 private System.Timers.Timer MouseTimerTick = new System.Timers.Timer(10000); private void Window_Activated(object sender, EventArgs e) { this.Dispatcher.Invoke(new Action(() => { //显示 })); MouseTimerTick.Stop(); } private void Window_

VirtualBox虚拟机内的系统时间无法调整的解决方法

VirtualBox虚拟机内的系统时间无法调整的解决方法 因试用某软件要求将系统时间设置在特定的日期,利用windows自带的调整日期/时间功能进行设置,发现过几秒钟就又恢复到和主机相同的时间了,即使把Internet时间服务器同步禁用了也是这样. 上网搜索终于找到解决方案了. 1. 先到管理工具->服务,将“windows time”服务停止并设为手动启动. 2. 打开虚拟机内的注册表,找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service

wxpython 拖动界面时进入假死状态(未响应)解决方法

场景:在一个事件中调用一个函数,但是这个函数执行的时间非常的长,此过程中拖动界面的时候会使得界面进入未响应状态,直到函数执行完才可以ok 解决方法: 在调用函数的时候使用多线程调用 import threading thread_obj = threading(func, arg=(para1,)) thread_obj.start()