简体   繁体   中英

Live555 - Proper client shutdown with watchVariable

I am currently facing an issue with live555.

I wrote a windows DLL for my project , this DLL expose a very simple API to start an RTSP client with ease. A unity program loads the DLL and then uses the API to receive the frames.

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. So i created a new thread when startRTSP is called , and with some callbacks the frames are sent to unity.

However , to be able to stop the RTSP from an external thread (the unity thread calling stopRTSP) i am using the eventLoopWatchVariable. For example this is how the RTSP event loop is started :

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

When the stop function is called , the eventLoopWatchVariable is set to 1 from the unity thread. 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. (Sending the TEARDOWN command to the server for example)

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.

How can i ask live555 to close the RTSPClient and their subsessions when the eventLoopWatchVariable is set to 1 ?

I cannot send the TEARDOWN command to the server if the eventLoop is not running anymore. 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.

This is inexact, the mainloop is needed to receive messages not to send messages.

In order to close properly the RTSP client connection after the mainloop and before releasing the environment, you could proceed like this :

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

Here is the correct way to fully shutdown an rtsp client. This answer assumes you are using the following program as the base for your rtsp client: testProgs/testRTSPClient.cpp (bundled with live555).

Firstly modify openURL() to some how return "RTSPClient* rtspClient" back to the caller. Then use this example (continuing from main() inside of testRTSPClient.cpp):

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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