avformat_open_input打开不存在的rtsp阻塞

网上很多文章,说到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

#ifdef __cplusplus
extern "C" {
#endif

#include <libavformat/avformat.h>
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
#include <libavutil/time.h>
#ifdef __cplusplus
}
#endif

...
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;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值