简体   繁体   English

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

[英]Live555 - Proper client shutdown with watchVariable

I am currently facing an issue with live555. 我目前遇到live555问题。

I wrote a windows DLL for my project , this DLL expose a very simple API to start an RTSP client with ease. 我为项目编写了一个Windows DLL,该DLL公开了一个非常简单的API,可轻松启动RTSP客户端。 A unity program loads the DLL and then uses the API to receive the frames. 统一程序加载DLL,然后使用API​​接收帧。

the two main functions exposed are : 公开的两个主要功能是:

bool startRTSP(bool isTCP);
bool stopRTSP();

Due to the nature of the Live555 library , i cannot start the RTSP in the unity thread. 由于Live555库的性质,我无法在统一线程中启动RTSP。 So i created a new thread when startRTSP is called , and with some callbacks the frames are sent to unity. 因此,当调用startRTSP时,我创建了一个新线程,并通过一些回调将帧发送到统一状态。

However , to be able to stop the RTSP from an external thread (the unity thread calling stopRTSP) i am using the eventLoopWatchVariable. 但是,为了能够从外部线程(调用stopRTSP的统一线程)停止RTSP,我正在使用eventLoopWatchVariable。 For example this is how the RTSP event loop is started : 例如,这是RTSP事件循环的启动方式:

env->taskScheduler().doEventLoop(&eventLoopWatchVariable);

When the stop function is called , the eventLoopWatchVariable is set to 1 from the unity thread. 调用stop函数时,从统一线程将eventLoopWatchVariable设置为1。 Shutting down the event Loop. 关闭事件循环。

Right after this event loop exit the cleanup functions are called : 在此事件循环退出后,立即调用清理函数:

delete scheduler;
env->reclaim();

I was expecting thoose function to go through the RTSP client and shutting them down. 我期望thoose函数能够通过RTSP客户端并关闭它们。 (Sending the TEARDOWN command to the server for example) (例如,将TEARDOWN命令发送到服务器)

But they clearly don't , and the clients are never destroyed ! 但是他们显然没有,客户也永远不会被摧毁!

I am suspecting it to cause a reconexion issue to the same stream. 我怀疑它会在同一数据流中引起重新发送问题。 (the SETUP , DESCRIBE and PLAY command are sent and the responses are received , but no data is coming) Using VLC or mplayer i can see that the server is still streaming so this is not a server issue. (发送SETUP,DESCRIBE和PLAY命令并接收到响应,但没有数据传入)使用VLC或mplayer,我可以看到服务器仍在流式传输,因此这不是服务器问题。

How can i ask live555 to close the RTSPClient and their subsessions when the eventLoopWatchVariable is set to 1 ? 当eventLoopWatchVariable设置为1时,我如何要求live555关闭RTSPClient及其子会话?

I cannot send the TEARDOWN command to the server if the eventLoop is not running anymore. 如果eventLoop不再运行,则无法将TEARDOWN命令发送到服务器。 So i am a bit lost right now about the best way to do it . 所以现在我对最佳方法的做法有些迷茫。

If anyone has an idea about it , i would love to hear it ! 如果有人对此有想法,我很想听听!

Thanks in advance. 提前致谢。

I cannot send the TEARDOWN command to the server if the eventLoop is not running anymore. 如果eventLoop不再运行,则无法将TEARDOWN命令发送到服务器。

This is inexact, the mainloop is needed to receive messages not to send messages. 这是不精确的,需要mainloop接收消息而不是发送消息。

In order to close properly the RTSP client connection after the mainloop and before releasing the environment, you could proceed like this : 为了在主循环之后和释放环境之前正确关闭RTSP客户端连接,您可以像这样进行操作:

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

You can also wait for TEARDOWN answer, giving a callback to sendTeardownCommand and running again doEventLoop. 您还可以等待TEARDOWN答案,给sendTeardownCommand回调,然后再次运行doEventLoop。

Here is the correct way to fully shutdown an rtsp client. 这是完全关闭rtsp客户端的正确方法。 This answer assumes you are using the following program as the base for your rtsp client: testProgs/testRTSPClient.cpp (bundled with live555). 该答案假定您使用以下程序作为rtsp客户端的基础:testProgs / testRTSPClient.cpp(与live555捆绑在一起)。

Firstly modify openURL() to some how return "RTSPClient* rtspClient" back to the caller. 首先,将openURL()修改为将“ RTSPClient * rtspClient”返回给调用方的方式。 Then use this example (continuing from main() inside of testRTSPClient.cpp): 然后使用以下示例(从testRTSPClient.cpp内部的main()继续):

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM