Skip to content

Commit dda93e4

Browse files
committed
Refactor: How Streams and Streamclient are handled and how data is send
1 parent b8852ac commit dda93e4

File tree

101 files changed

+1894
-2978
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1894
-2978
lines changed

Makefile

+4-9
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ SOURCES = Version.cpp \
6868
main.cpp \
6969
Satpi.cpp \
7070
Stream.cpp \
71-
StreamClient.cpp \
7271
StreamManager.cpp \
7372
StringConverter.cpp \
7473
TransportParamVector.cpp \
@@ -108,14 +107,10 @@ SOURCES = Version.cpp \
108107
mpegts/PMT.cpp \
109108
mpegts/SDT.cpp \
110109
mpegts/TableData.cpp \
111-
output/StreamThreadBase.cpp \
112-
output/StreamThreadHttp.cpp \
113-
output/StreamThreadRtcpBase.cpp \
114-
output/StreamThreadRtcp.cpp \
115-
output/StreamThreadRtcpTcp.cpp \
116-
output/StreamThreadRtp.cpp \
117-
output/StreamThreadRtpTcp.cpp \
118-
output/StreamThreadTSWriter.cpp \
110+
output/StreamClient.cpp \
111+
output/StreamClientOutputHttp.cpp \
112+
output/StreamClientOutputRtp.cpp \
113+
output/StreamClientOutputRtpTcp.cpp \
119114
socket/HttpcSocket.cpp \
120115
socket/TcpSocket.cpp \
121116
socket/SocketAttr.cpp \

SatPI.plantuml

+19-39
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,16 @@ class HttpcServer {
103103
processStreamingRequest(..)
104104
}
105105

106-
class StreamInterface #aaaaff {
107-
getInputDevice() = 0
108-
getStreamClient(..) = 0
109-
getDecryptDevice() = 0
110-
}
111-
112-
Stream --|> StreamInterface
113-
Stream *-- StreamClient : " _client[..] "
106+
Stream *-- output::StreamClient : " _streamClientVector[..] "
107+
Stream *-- mpegts::PacketBuffer : " _tsBuffer[..] "
114108
Stream *-- input::Device
115-
Stream *-- output::StreamThreadBase
116109
decrypt::dvbapi::Client ..* Stream : " _decrypt "
117110
class Stream #aaaaff {
118111
XMLSupport
119-
--
112+
** Thread DataReader**
113+
** Thread Monitor/RTCP**
114+
--
120115
enabled
121-
StreamingType (RSTP/RTP/HTTP/..)
122116
streamInUse
123117
--
124118
getFrontendDecryptInterface()
@@ -149,10 +143,10 @@ class StreamManager #aaaaff {
149143
getFrontendDecryptInterface(..)
150144
}
151145

152-
StreamClient *-- socket::SocketAttr : " _rtp "
153-
StreamClient *-- socket::SocketAttr : " _rtcp "
154-
StreamClient *.. socket::SocketClient : " _httpStream "
155-
class StreamClient #aaaaff {
146+
output::StreamClient *-- socket::SocketAttr : " _rtp "
147+
output::StreamClient *-- socket::SocketAttr : " _rtcp "
148+
output::StreamClient *.. socket::SocketClient : " _httpStream "
149+
class output::StreamClient #ccffff {
156150
Mutex _mutex
157151
--
158152
SocketClient *_httpStream
@@ -171,33 +165,19 @@ class mpegts::PMT #11ff11
171165
class mpegts::PCR #11ff11
172166
class mpegts::SDT #11ff11
173167

174-
output::StreamThreadBase *-- mpegts::PacketBuffer : " _tsBuffer[..] "
175-
output::StreamThreadBase *.. StreamInterface
176-
class output::StreamThreadBase #ccffff {
177-
** Thread **
178-
--
179-
}
180-
181-
class output::StreamThreadRtcp #ccffff
182-
class output::StreamThreadHttp #ccffff
183-
184-
output::StreamThreadRtcp --* output::StreamThreadRtp
185-
186-
output::StreamThreadRtp --|> output::StreamThreadBase
187-
class output::StreamThreadRtp #ccffff {
188-
cseq
189-
}
190-
191-
output::StreamThreadHttp --|> output::StreamThreadBase
192168

193-
class input::stream::Streamer #55ccff
194-
input::Device <|-- input::stream::Streamer
169+
class output::StreamClientOutputHttp #ccffff
170+
class output::StreamClientOutputRtp #ccffff
171+
class output::StreamClientOutputRtpTcp #ccffff
172+
output::StreamClientOutputHttp --|> output::StreamClient
173+
output::StreamClientOutputRtp --|> output::StreamClient
174+
output::StreamClientOutputRtpTcp --|> output::StreamClient
195175

196-
class input::file::TSReader #99cc11
197-
class TSReaderData #99cc11
176+
class input::childpipe::TSReader #99cc11
177+
class TSReaderData #99cc11
198178

199-
input::Device <|-- input::file::TSReader
200-
input::file::TSReader *-- TSReaderData
179+
input::Device <|-- input::childpipe::TSReader
180+
input::childpipe::TSReader *-- TSReaderData
201181

202182
TSReaderData --|> input::DeviceData
203183

SatPI.png

-51.2 KB
Loading

SatPI.svg

+1-1
Loading

src/Defs.h

+3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
#ifndef DEFS_H_INCLUDE
2121
#define DEFS_H_INCLUDE DEFS_H_INCLUDE
2222

23+
#include <memory>
2324
#include <string>
2425
#include <vector>
2526

2627
using StringVector = std::vector<std::string>;
2728

29+
using PacketPtr = std::unique_ptr<uint8_t[]>;
30+
2831
class TypeID {
2932
public:
3033
TypeID(int id) : _id(id) {}

src/HeaderVector.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
// =============================================================================
2727

2828
std::string HeaderVector::getFieldParameter(const std::string_view reqHeader) const {
29-
for (const std::string &header : _vector) {
29+
for (const std::string& header : _vector) {
3030
const auto b = header.find(reqHeader, 0);
3131
const auto e = header.find_first_not_of(reqHeader, b);
3232
if (b != std::string::npos && reqHeader.size() == e && header[e] == ':') {
@@ -43,7 +43,7 @@ std::string HeaderVector::getStringFieldParameter(std::string_view header,
4343
return std::string();
4444
}
4545
StringVector params = StringConverter::split(field, ";\r\n");
46-
for (const std::string &param : params) {
46+
for (const std::string& param : params) {
4747
const auto p = param.find(parameter, 0);
4848
if (p != std::string::npos) {
4949
StringVector r = StringConverter::split(param, "=");

src/HttpServer.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ bool HttpServer::methodPost(SocketClient &client) {
9292
getHtmlBodyWithContent(htmlBody, HTML_NO_RESPONSE, "", CONTENT_TYPE_HTML, 0, 0);
9393

9494
// send 'htmlBody' to client
95-
if (!client.sendData(htmlBody.c_str(), htmlBody.size(), 0)) {
95+
if (!client.sendData(htmlBody.data(), htmlBody.size(), 0)) {
9696
SI_LOG_ERROR("Send htmlBody failed");
9797
return false;
9898
}
@@ -147,7 +147,7 @@ bool HttpServer::methodGet(SocketClient &client, bool headOnly) {
147147
} else if (file == "STOP") {
148148
exitRequest = true;
149149
getHtmlBodyWithContent(htmlBody, HTML_NO_RESPONSE, "", CONTENT_TYPE_HTML, 0, 0);
150-
} else if ((docTypeSize = readFile(filePath.c_str(), docType))) {
150+
} else if ((docTypeSize = readFile(filePath.data(), docType))) {
151151
if (file.find(".xml") != std::string::npos) {
152152
// check if the request is the SAT>IP description xml then fill in the server version, UUID,
153153
// XSatipM3U, presentationURL and tuner string
@@ -160,7 +160,7 @@ bool HttpServer::methodGet(SocketClient &client, bool headOnly) {
160160
_bindIPAddress,
161161
std::to_string(_properties.getHttpPort()));
162162
const std::string modelName = StringConverter::stringFormat("SatPI Server (@#1)", _bindIPAddress);
163-
const std::string newDocType = StringConverter::stringFormat(docType.c_str(),
163+
const std::string newDocType = StringConverter::stringFormat(docType.data(),
164164
modelName, _properties.getUPnPVersion(), _properties.getUUID(), presentationURL,
165165
_streamManager.getXMLDeliveryString(), _properties.getXSatipM3U());
166166
docType = newDocType;
@@ -193,9 +193,9 @@ bool HttpServer::methodGet(SocketClient &client, bool headOnly) {
193193
continue;
194194
}
195195
if (line.find("rtsp://") != std::string::npos) {
196-
docType += StringConverter::stringFormat(line.c_str(), rtsp);
196+
docType += StringConverter::stringFormat(line.data(), rtsp);
197197
} else if (line.find("http://") != std::string::npos) {
198-
docType += StringConverter::stringFormat(line.c_str(), http);
198+
docType += StringConverter::stringFormat(line.data(), http);
199199
}
200200
}
201201
docTypeSize = docType.size();
@@ -209,21 +209,21 @@ bool HttpServer::methodGet(SocketClient &client, bool headOnly) {
209209
}
210210
} else {
211211
file = _properties.getWebPath() + "/" + "404.html";
212-
docTypeSize = readFile(file.c_str(), docType);
212+
docTypeSize = readFile(file.data(), docType);
213213
getHtmlBodyWithContent(htmlBody, HTML_NOT_FOUND, file, CONTENT_TYPE_HTML, docTypeSize, 0);
214214
}
215215
}
216216
}
217217
// send something?
218218
if (htmlBody.size() > 0) {
219219
// send 'htmlBody' to client
220-
if (!client.sendData(htmlBody.c_str(), htmlBody.size(), 0)) {
220+
if (!client.sendData(htmlBody.data(), htmlBody.size(), 0)) {
221221
SI_LOG_ERROR("Send htmlBody failed");
222222
return false;
223223
}
224224
// send 'docType' to client if needed
225225
if (!headOnly && docTypeSize > 0) {
226-
if (!client.sendData(docType.c_str(), docTypeSize, 0)) {
226+
if (!client.sendData(docType.data(), docTypeSize, 0)) {
227227
SI_LOG_ERROR("Send docType failed");
228228
return false;
229229
}

src/HttpcServer.cpp

+23-18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <Log.h>
2424
#include <Properties.h>
2525
#include <Stream.h>
26+
#include <output/StreamClient.h>
2627
#include <StreamManager.h>
2728
#include <StringConverter.h>
2829
#include <socket/SocketClient.h>
@@ -32,6 +33,8 @@
3233
#include <cstdlib>
3334
#include <fcntl.h>
3435

36+
extern const char* const satpi_version;
37+
3538
const char *HttpcServer::HTML_BODY_WITH_CONTENT =
3639
"@#1 @#2\r\n" \
3740
"Server: SatPI WebServer v0.1\r\n" \
@@ -82,8 +85,6 @@ HttpcServer::HttpcServer(
8285
_streamManager(streamManager),
8386
_bindIPAddress(bindIPAddress) {}
8487

85-
HttpcServer::~HttpcServer() {}
86-
8788
void HttpcServer::initialize(
8889
int port,
8990
bool nonblock) {
@@ -164,18 +165,23 @@ void HttpcServer::processStreamingRequest(SocketClient &client) {
164165
const std::string method = client.getMethod();
165166
std::string httpcReply;
166167
if (sessionID.empty() && method == "OPTIONS") {
167-
methodOptions("", cseq, httpcReply);
168+
static const char *RTSP_OPTIONS_OK =
169+
"RTSP/1.0 200 OK\r\n" \
170+
"Server: satpi/@#1\r\n" \
171+
"CSeq: @#2\r\n" \
172+
"Public: OPTIONS, DESCRIBE, SETUP, PLAY, TEARDOWN\r\n" \
173+
"\r\n";
174+
httpcReply = StringConverter::stringFormat(RTSP_OPTIONS_OK, satpi_version, cseq);
168175
} else if (sessionID.empty() && method == "DESCRIBE") {
169176
methodDescribe("", cseq, feIndex, httpcReply);
170177
} else {
171-
int clientID;
172-
SpStream stream = _streamManager.findStreamAndClientIDFor(client, clientID);
178+
const auto [stream, streamClient] = _streamManager.findStreamAndClientFor(client);
173179
if (stream != nullptr) {
174-
stream->processStreamingRequest(client, clientID);
180+
stream->processStreamingRequest(client, streamClient);
175181

176182
// Check the Method
177183
if (method == "GET") {
178-
stream->update(clientID);
184+
stream->update(streamClient);
179185
const std::string multicast = params.getParameter("multicast");
180186
if (multicast.empty()) {
181187
getHtmlBodyNoContent(httpcReply, HTML_OK, "", CONTENT_TYPE_VIDEO, 0);
@@ -185,27 +191,26 @@ void HttpcServer::processStreamingRequest(SocketClient &client) {
185191
httpcReply += content;
186192
}
187193
} else if (method == "SETUP") {
188-
methodSetup(*stream, clientID, httpcReply);
194+
httpcReply = streamClient->getSetupMethodReply(stream->getStreamID());
189195

190-
if (!stream->update(clientID)) {
196+
if (!stream->update(streamClient)) {
191197
// something wrong here... send 408 error
192198
getHtmlBodyNoContent(httpcReply, HTML_REQUEST_TIMEOUT, "", CONTENT_TYPE_VIDEO, cseq);
193-
stream->teardown(clientID);
199+
stream->teardown(streamClient);
194200
}
195201
} else if (method == "PLAY") {
196-
methodPlay(*stream, clientID, httpcReply);
202+
httpcReply = streamClient->getPlayMethodReply(stream->getStreamID(), _bindIPAddress);
197203

198-
if (!stream->update(clientID)) {
204+
if (!stream->update(streamClient)) {
199205
// something wrong here... send 408 error
200206
getHtmlBodyNoContent(httpcReply, HTML_REQUEST_TIMEOUT, "", CONTENT_TYPE_VIDEO, cseq);
201-
stream->teardown(clientID);
207+
stream->teardown(streamClient);
202208
}
203209
} else if (method == "TEARDOWN") {
204-
methodTeardown(sessionID, cseq, httpcReply);
205-
206-
stream->teardown(clientID);
210+
httpcReply = streamClient->getTeardownMethodReply();
211+
stream->teardown(streamClient);
207212
} else if (method == "OPTIONS") {
208-
methodOptions(sessionID, cseq, httpcReply);
213+
httpcReply = streamClient->getOptionsMethodReply();
209214
} else if (method == "DESCRIBE") {
210215
methodDescribe(sessionID, cseq, feIndex, httpcReply);
211216
} else {
@@ -221,7 +226,7 @@ void HttpcServer::processStreamingRequest(SocketClient &client) {
221226
}
222227
const unsigned long time = sw.getIntervalMS();
223228
SI_LOG_DEBUG("Send reply in @#1 ms\r\n@#2", time, httpcReply);
224-
if (!client.sendData(httpcReply.c_str(), httpcReply.size(), MSG_NOSIGNAL)) {
229+
if (!client.sendData(httpcReply.data(), httpcReply.size(), MSG_NOSIGNAL)) {
225230
SI_LOG_ERROR("Send Streaming reply failed");
226231
}
227232
}

src/HttpcServer.h

+3-13
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
FW_DECL_NS0(Stream);
2929
FW_DECL_NS0(StreamManager);
3030

31+
FW_DECL_SP_NS1(output, StreamClient);
32+
3133
/// HTTP Client Server
3234
class HttpcServer :
3335
public TcpSocket {
@@ -66,7 +68,7 @@ class HttpcServer :
6668
StreamManager &streamManager,
6769
const std::string &bindIPAddress);
6870

69-
virtual ~HttpcServer();
71+
virtual ~HttpcServer() = default;
7072

7173
/// Call this to initialize, setup and start this server
7274
virtual void initialize(
@@ -94,18 +96,6 @@ class HttpcServer :
9496
return false;
9597
}
9698

97-
/// RTSP Method
98-
virtual void methodSetup(const Stream &UNUSED(stream), int UNUSED(clientID), std::string &UNUSED(htmlBody)) {}
99-
100-
/// RTSP Method
101-
virtual void methodPlay(const Stream &UNUSED(stream), int UNUSED(clientID), std::string &UNUSED(htmlBody)) {}
102-
103-
/// RTSP Method
104-
virtual void methodTeardown(const std::string &UNUSED(sessionID), int UNUSED(cseq), std::string &UNUSED(htmlBody)) {}
105-
106-
/// RTSP Method
107-
virtual void methodOptions(const std::string &UNUSED(sessionID), int UNUSED(cseq), std::string &UNUSED(htmlBody)) {}
108-
10999
/// RTSP Method
110100
virtual void methodDescribe(const std::string &UNUSED(sessionID), int UNUSED(cseq), FeIndex UNUSED(index), std::string &UNUSED(htmlBody)) {}
111101

src/Log.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ static base::Mutex logMutex;
3737

3838
bool Log::_syslogOn = false;
3939
bool Log::_coutLog = true;
40+
bool Log::_logDebug = true;
41+
4042
Log::LogBuffer Log::_appLogBuffer;
4143

4244
void Log::openAppLog(const char *deamonName, const bool daemonize) {
@@ -64,6 +66,9 @@ void Log::log(const int priority, const std::string &msg) {
6466
if ((priority & MPEGTS_TABLES) == MPEGTS_TABLES) {
6567
return;
6668
}
69+
if (priority == LOG_DEBUG && !_logDebug) {
70+
return;
71+
}
6772
// set timestamp
6873
struct timespec timeStamp;
6974
struct tm result;
@@ -87,7 +92,7 @@ void Log::log(const int priority, const std::string &msg) {
8792

8893
// log to syslog
8994
if (_syslogOn) {
90-
syslog(priority, "%s", line.c_str());
95+
syslog(priority, "%s", line.data());
9196
}
9297

9398
#ifdef DEBUG
@@ -112,7 +117,7 @@ std::string Log::makeJSON() {
112117
{
113118
base::MutexLock lock(logMutex);
114119
if (!_appLogBuffer.empty()) {
115-
for (const LogElem &elem : _appLogBuffer) {
120+
for (const LogElem& elem : _appLogBuffer) {
116121
json.startObject();
117122
json.addValueString("timestamp", elem.timestamp);
118123
json.addValueString("msg", elem.msg);

0 commit comments

Comments
 (0)