网上很多文章,说到avformat_open_input阻塞,就设置一下
av_dict_set(&avdic, "stimeout ", "300000", 0);
ffmpeg源码rtsp.c有这样一段定义
{ "timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
{ "stimeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
按照正常的说法,应该没问题,但就是不行,设置了还是会一直阻塞。
不管那么多,下面是正解,需要设置一下回调函数。部分关键代码
// C++ Header
extern "C" {
}
...
class CFfmpegCapture
{
private:
static int decode_interrupt_cb(void *ctx);
//
int64_t m_nStartOpenTS = 0;
}
//c++ body
int CFfmpegCapture::decode_interrupt_cb(void *ctx)
{
CFfmpegCapture *pThis = (CFfmpegCapture*)ctx;
//microseconds 微秒
int64_t nDurTime = av_gettime() - pThis->m_nStartOpenTS;
if (nDurTime > 3000000 && pThis->m_nStartOpenTS>0)
{
return 1;
}
return 0;
}
int CFfmpegCapture::StartCapture(const char *pUrl)
{
AVDictionary* avdic = NULL;
av_dict_set(&avdic, "rtsp_transport", "tcp", 0);
//set timeout (in microseconds) of socket TCP I/O operations
av_dict_set(&avdic, "stimeout ", "300000", 0);
//set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)
//av_dict_set(&avdic, "timeout ", "2", 0);
m_pFmtCtx->interrupt_callback.callback = decode_interrupt_cb;
m_pFmtCtx->interrupt_callback.opaque = (void*)this;
m_nStartOpenTS = av_gettime();
int ret = -1;
ret = avformat_open_input(&m_pFmtCtx, pUrl, nullptr, &avdic);
if (ret != 0) {
return -1;
}
//成功open以后,置0
m_nStartOpenTS = 0;
}
回调函数返回1表示不在阻塞( If the callback returns 1, the blocking operation will be aborted.)
ffmpeg-》avio.h文件描述:
/**
* Callback for checking whether to abort blocking functions.
* AVERROR_EXIT is returned in this case by the interrupted
* function. During blocking operations, callback is called with
* opaque as parameter. If the callback returns 1, the
* blocking operation will be aborted.
*
* No members can be added to this struct without a major bump, if
* new elements have been added after this struct in AVFormatContext
* or AVIOContext.
*/
typedef struct AVIOInterruptCB {
int (*callback)(void*);
void *opaque;
} AVIOInterruptCB;
//其实ffmpeg从4.0开始不用stimeout,用的listen_timeout等待网络超时,不然会一直超时下去。
AVDictionary* options = nullptr;
//实时播放使用udp,减小带宽并防止断线
av_dict_set(&options, "rtsp_transport", "udp", 0);
//等待3秒超时
av_dict_set(&options, "listen_timeout", "3", 0);
分类:
ffmpeg、ffplay
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2018-04-12 安装包制作工具 SetupFactory使用1 详解
2016-04-12 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)
2016-04-12 嵌入式 H264中的SPS、PPS提取与作用
2016-04-12 嵌入式 H264参数语法文档: SPS、PPS、IDR以及NALU编码规律
2016-04-12 嵌入式 使用mp4v2将H264+AAC合成mp4文件
2016-04-12 嵌入式 H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
2016-04-12 嵌入式 H264视频通过RTMP直播