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; }
原文地址:http://blog.csdn.net/zhouyongku/article/details/44978817