首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Live555 -使用watchVariable正确关闭客户端

Live555 -使用watchVariable正确关闭客户端
EN

Stack Overflow用户
提问于 2016-10-16 00:25:38
回答 2查看 1.8K关注 0票数 4

我现在正面临着一个live555的问题。

我为我的项目写了一个windows动态链接库,这个动态链接库公开了一个非常简单的API来轻松启动RTSP客户端。unity程序加载DLL,然后使用API接收帧。

公开的两个主要函数是:

代码语言:javascript
复制
bool startRTSP(bool isTCP);
bool stopRTSP();

由于Live555库的性质,我不能在unity线程中启动RTSP。因此,我在调用startRTSP时创建了一个新线程,并通过一些回调将帧发送到unity。

但是,为了能够从外部线程( unity线程调用stopRTSP)停止RTSP,我使用了eventLoopWatchVariable。例如,RTSP事件循环的启动方式如下:

代码语言:javascript
复制
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

当调用停止函数时,从unity线程将eventLoopWatchVariable设置为1。正在关闭事件循环。

在此事件循环退出后,将立即调用清理函数:

代码语言:javascript
复制
delete scheduler;
env->reclaim();

我期望thoose函数通过RTSP客户端并关闭它们。(例如向服务器发送TEARDOWN命令)

但它们显然不会,而且客户端永远不会被破坏!

我怀疑它会导致同一个流的重新连接问题。( SETUP、DESCRIBE和PLAY命令已发送,响应已收到,但没有数据)使用VLC或mplayer我可以看到服务器仍在流式传输,因此这不是服务器问题。

当RTSPClient设置为1时,我如何请求live555关闭eventLoopWatchVariable及其子会话?

如果eventLoop不再运行,我无法向服务器发送TEARDOWN命令。所以我现在对最好的方法有点迷茫。

如果有人对此有什么想法,我很想听听!

提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2016-11-30 04:48:23

如果eventLoop不再运行,

I将无法向服务器发送TEARDOWN命令。

这是不准确的,主循环需要接收消息而不是发送消息。

为了在主循环之后释放环境之前正确关闭RTSP客户端连接,您可以执行以下操作:

代码语言:javascript
复制
// wait for stop event
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

// send tear TEARDOWN
client->sendTeardownCommand(session, NULL);

// close subsession & session
Medium::close(session);

// close RTSP client
Medium::close(client);

// free environment & scheduler
env->reclaim();
delete scheduler;

您也可以等待TEARDOWN应答,回调sendTeardownCommand并再次运行doEventLoop。

票数 2
EN

Stack Overflow用户

发布于 2019-02-20 03:46:01

下面是完全关闭rtsp客户端的正确方法。这个答案假设您使用以下程序作为rtsp客户机的基础: testProgs/testRTSPClient.cpp (与live555捆绑在一起)。

首先修改openURL(),看看如何将"RTSPClient* rtspClient“返回给调用者。然后使用这个例子(从testRTSPClient.cpp内部的main()继续):

代码语言:javascript
复制
RTSPClient* rtspClient = openURL(*env, argv[0], argv[1]);

// All subsequent activity takes place within the event loop:
env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

//... do whatever stuff you want to do in the background...

//start this code when you want to stop the rtsp client
eventLoopWatchVariable = 1;

//run this code for each rtspClient that exists
StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs;

rtspClient->sendTeardownCommand(*scs.session, NULL);

Medium::close(client->rtspClient);
//end code segment

env->reclaim();
env = NULL;
delete scheduler;
scheduler = NULL;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40061481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档