Skip to content

Commit 0119391

Browse files
committed
feature: 支持通过SDP拉RTP流
1 parent ee21dd1 commit 0119391

File tree

2 files changed

+95
-24
lines changed

2 files changed

+95
-24
lines changed

src/StreamPuller.cpp

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "MPEG2TransportStreamParser.hh" // internal header for PIDState_STREAM and StreamType
1111
#include "H264VideoStreamFramer.hh"
1212
#include "H265VideoStreamFramer.hh"
13+
#include "Base64.hh"
1314
#include "StreamSink.h"
1415

1516
#ifdef _DEBUG
@@ -170,6 +171,8 @@ void StreamPuller::start()
170171
exit = 0;
171172
if (protocol == CRP_RTSP)
172173
thread = std::thread(&StreamPuller::runRTSP, this);
174+
else if (protocol == CRP_SDP)
175+
thread = std::thread(&StreamPuller::runSDP, this);
173176
else if (protocol == CRP_RTP)
174177
thread = std::thread(&StreamPuller::runRTP, this);
175178
else if (protocol == CRP_HTTP)
@@ -199,11 +202,61 @@ void StreamPuller::runRTSP()
199202
delete scheduler;
200203
}
201204

205+
static bool parseSDP(const std::string& url, std::string& sdp)
206+
{
207+
static const std::regex regex(R"(([a-z\d\+]+):\/\/(.+))");
208+
std::smatch match;
209+
if (std::regex_match(url, match, regex))
210+
{
211+
std::string schema = match[1].str();
212+
sdp = match[2].str();
213+
if (schema == "sdp+base64")
214+
{
215+
unsigned dataSize = 0;
216+
unsigned char* data = base64Decode(sdp.c_str(), sdp.length(), dataSize, true);
217+
sdp = std::string((char*) data, dataSize);
218+
}
219+
else if (schema != "sdp")
220+
{
221+
sdp = "";
222+
return false;
223+
}
224+
return !sdp.empty();
225+
}
226+
return false;
227+
}
228+
229+
void StreamPuller::runSDP()
230+
{
231+
std::string sdp;
232+
if (!parseSDP(url, sdp))
233+
{
234+
fprintf(stderr, "Invalid SDP description: %s\n", url.c_str());
235+
callback.invokeSync(CRP_EV_ERROR, (void*) 0, userData);
236+
return;
237+
}
238+
239+
scheduler = BasicTaskScheduler::createNew();
240+
environment = BasicUsageEnvironment::createNew(*scheduler);
241+
rtspClient = NULL;
242+
session = NULL;
243+
demuxer = NULL;
244+
livenessCheckTask = NULL;
245+
246+
callback.invokeSync(CRP_EV_START, nullptr, userData);
247+
continueAfterDESCRIBE(NULL, 0, sdp.c_str());
248+
environment->taskScheduler().doEventLoop(&exit);
249+
250+
shutdownStream(NULL);
251+
delete scheduler;
252+
}
253+
202254
static bool parseRTPUrl(const std::string& url, std::string& host, int& port)
203255
{
204-
std::regex regex(R"(rtp://([^:]+):(\d+))");
256+
static const std::regex regex(R"(rtp://([^:]+):(\d+))");
205257
std::smatch match;
206-
if (std::regex_match(url, match, regex)) {
258+
if (std::regex_match(url, match, regex))
259+
{
207260
host = match[1].str();
208261
port = std::stoi(match[2].str());
209262
return true;
@@ -420,7 +473,7 @@ void StreamPuller::runHTTP()
420473

421474
void StreamPuller::shutdownStream(RTSPClient* rtspClient)
422475
{
423-
UsageEnvironment& env = rtspClient->envir();
476+
UsageEnvironment& env = *environment;
424477

425478
if (session != NULL)
426479
{
@@ -442,7 +495,7 @@ void StreamPuller::shutdownStream(RTSPClient* rtspClient)
442495
}
443496
}
444497

445-
if (someSubsessionsWereActive)
498+
if (rtspClient != NULL && someSubsessionsWereActive)
446499
{
447500
rtspClient->sendTeardownCommand(*session, NULL);
448501
}
@@ -453,9 +506,9 @@ void StreamPuller::shutdownStream(RTSPClient* rtspClient)
453506
this->rtspClient = NULL;
454507
}
455508

456-
void StreamPuller::continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString)
509+
void StreamPuller::continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, const char* resultString)
457510
{
458-
UsageEnvironment& env = rtspClient->envir();
511+
UsageEnvironment& env = *environment;
459512

460513
if (resultCode != 0)
461514
{
@@ -490,7 +543,7 @@ void StreamPuller::continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode,
490543

491544
void StreamPuller::continueAfterSETUP(RTSPClient* rtspClient, int resultCode, char* resultString)
492545
{
493-
UsageEnvironment& env = rtspClient->envir();
546+
UsageEnvironment& env = *environment;
494547
const char* mediumName;
495548
const char* codecName;
496549

@@ -630,22 +683,22 @@ void StreamPuller::continueAfterSETUP(RTSPClient* rtspClient, int resultCode, ch
630683
goto end;
631684
}
632685

633-
subsession->miscPtr = rtspClient;
686+
subsession->miscPtr = this;
634687
if (subsession->sink != NULL)
635688
{
636689
env << "Created a " << mediumName << " data sink for the subsession\n";
637690
subsession->sink->startPlaying(*(subsession->readSource()), [](void* clientData)
638691
{
639692
MediaSubsession* subsession = (MediaSubsession*) clientData;
640-
((OurRTSPClient*) subsession->miscPtr)->parent->subsessionAfterPlaying(subsession);
693+
((StreamPuller*) subsession->miscPtr)->subsessionAfterPlaying(subsession);
641694
}, subsession);
642695
}
643696
if (subsession->rtcpInstance() != NULL)
644697
{
645698
subsession->rtcpInstance()->setByeWithReasonHandler([](void* clientData, char const* reason)
646699
{
647700
MediaSubsession* subsession = (MediaSubsession*) clientData;
648-
((OurRTSPClient*) subsession->miscPtr)->parent->subsessionByeHandler(subsession, reason);
701+
((StreamPuller*) subsession->miscPtr)->subsessionByeHandler(subsession, reason);
649702
delete[] reason;
650703
}, subsession);
651704
}
@@ -656,7 +709,7 @@ void StreamPuller::continueAfterSETUP(RTSPClient* rtspClient, int resultCode, ch
656709

657710
void StreamPuller::continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString)
658711
{
659-
UsageEnvironment& env = rtspClient->envir();
712+
UsageEnvironment& env = *environment;
660713

661714
if (resultCode != 0)
662715
{
@@ -676,7 +729,7 @@ void StreamPuller::continueAfterPLAY(RTSPClient* rtspClient, int resultCode, cha
676729

677730
void StreamPuller::setupNextSubsession(RTSPClient* rtspClient)
678731
{
679-
UsageEnvironment& env = rtspClient->envir();
732+
UsageEnvironment& env = *environment;
680733

681734
subsession = iter->next();
682735
if (subsession != NULL)
@@ -695,20 +748,34 @@ void StreamPuller::setupNextSubsession(RTSPClient* rtspClient)
695748
else
696749
env << "client ports " << subsession->clientPortNum() << "-" << subsession->clientPortNum() + 1;
697750
env << ")\n";
698-
rtspClient->sendSetupCommand(*subsession, [](RTSPClient * rtspClient, int resultCode, char* resultString)
699-
{
700-
((OurRTSPClient*) rtspClient)->parent->continueAfterSETUP(rtspClient, resultCode, resultString);
701-
delete[] resultString;
702-
}, False, option.transport == CRP_TCP);
751+
if (rtspClient != NULL)
752+
{
753+
rtspClient->sendSetupCommand(*subsession, [](RTSPClient* rtspClient, int resultCode, char* resultString)
754+
{
755+
((OurRTSPClient*) rtspClient)->parent->continueAfterSETUP(rtspClient, resultCode, resultString);
756+
delete[] resultString;
757+
}, False, option.transport == CRP_TCP);
758+
}
759+
else
760+
{
761+
continueAfterSETUP(NULL, 0, NULL);
762+
}
703763
}
704764
return;
705765
}
706766

707-
rtspClient->sendPlayCommand(*session, [](RTSPClient * rtspClient, int resultCode, char* resultString)
708-
{
709-
((OurRTSPClient*) rtspClient)->parent->continueAfterPLAY(rtspClient, resultCode, resultString);
710-
delete[] resultString;
711-
});
767+
if (rtspClient != NULL)
768+
{
769+
rtspClient->sendPlayCommand(*session, [](RTSPClient* rtspClient, int resultCode, char* resultString)
770+
{
771+
((OurRTSPClient*) rtspClient)->parent->continueAfterPLAY(rtspClient, resultCode, resultString);
772+
delete[] resultString;
773+
});
774+
}
775+
else
776+
{
777+
continueAfterPLAY(NULL, 0, NULL);
778+
}
712779
}
713780

714781
void StreamPuller::subsessionAfterPlaying(MediaSubsession* subsession)
@@ -730,7 +797,7 @@ void StreamPuller::subsessionAfterPlaying(MediaSubsession* subsession)
730797

731798
void StreamPuller::subsessionByeHandler(MediaSubsession* subsession, char const* reason)
732799
{
733-
UsageEnvironment& env = rtspClient->envir();
800+
UsageEnvironment& env = *environment;
734801

735802
env << "Received RTCP \"BYE\"";
736803
if (reason != NULL)
@@ -817,6 +884,8 @@ StreamPuller::Protocol StreamPuller::parseUrl(const std::string& url)
817884
{
818885
if (url.starts_with("rtsp"))
819886
return CRP_RTSP;
887+
else if (url.starts_with("sdp"))
888+
return CRP_SDP;
820889
else if (url.starts_with("rtp"))
821890
return CRP_RTP;
822891
else if (url.starts_with("http"))

src/StreamPuller.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class StreamPuller
2222
{
2323
CRP_UNKNOWN,
2424
CRP_RTSP,
25+
CRP_SDP,
2526
CRP_RTP,
2627
CRP_HTTP,
2728
};
@@ -37,10 +38,11 @@ class StreamPuller
3738
private:
3839
void start();
3940
void runRTSP();
41+
void runSDP();
4042
void runRTP();
4143
void runHTTP();
4244
void shutdownStream(RTSPClient* rtspClient);
43-
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString);
45+
void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, const char* resultString);
4446
void continueAfterSETUP(RTSPClient* rtspClient, int resultCode, char* resultString);
4547
void continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString);
4648
void setupNextSubsession(RTSPClient* rtspClient);

0 commit comments

Comments
 (0)