Feature #2016 » rtsp-server.diff
| server/Makefile | ||
|---|---|---|
|
server.o component.o connection.o \
|
||
|
componentVTP.o connectionVTP.o \
|
||
|
componentHTTP.o connectionHTTP.o menuHTTP.o \
|
||
|
componentRTSP.o connectionRTSP.o \
|
||
|
componentIGMP.o connectionIGMP.o \
|
||
|
streamer.o livestreamer.o livefilter.o recstreamer.o recplayer.o \
|
||
|
menu.o suspend.o setup.o
|
||
| server/server.c | ||
|---|---|---|
|
#include "server/server.h"
|
||
|
#include "server/componentVTP.h"
|
||
|
#include "server/componentHTTP.h"
|
||
|
#include "server/componentRTSP.h"
|
||
|
#include "server/componentIGMP.h"
|
||
|
#include "server/setup.h"
|
||
| ... | ... | |
|
Start();
|
||
|
}
|
||
|
cStreamdevServer::~cStreamdevServer()
|
||
|
cStreamdevServer::~cStreamdevServer()
|
||
|
{
|
||
|
Stop();
|
||
|
}
|
||
|
void cStreamdevServer::Initialize(void)
|
||
|
void cStreamdevServer::Initialize(void)
|
||
|
{
|
||
|
if (m_Instance == NULL) {
|
||
|
if (StreamdevServerSetup.StartVTPServer) Register(new cComponentVTP);
|
||
|
if (StreamdevServerSetup.StartHTTPServer) Register(new cComponentHTTP);
|
||
|
if (StreamdevServerSetup.StartRTSPServer) Register(new cComponentRTSP);
|
||
|
if (StreamdevServerSetup.StartIGMPServer) {
|
||
|
if (strcmp(StreamdevServerSetup.IGMPBindIP, "0.0.0.0") == 0)
|
||
|
esyslog("streamdev-server: Not starting IGMP. IGMP must be bound to a local IP");
|
||
| server/setup.c | ||
|---|---|---|
|
HTTPServerPort = 3000;
|
||
|
HTTPPriority = 0;
|
||
|
HTTPStreamType = stTS;
|
||
|
StartRTSPServer = true;
|
||
|
RTSPServerPort = 554;
|
||
|
RTSPPriority = 0;
|
||
|
StartIGMPServer = false;
|
||
|
IGMPClientPort = 1234;
|
||
|
IGMPPriority = 0;
|
||
| ... | ... | |
|
AllowSuspend = false;
|
||
|
strcpy(VTPBindIP, "0.0.0.0");
|
||
|
strcpy(HTTPBindIP, "0.0.0.0");
|
||
|
strcpy(RTSPBindIP, "0.0.0.0");
|
||
|
strcpy(IGMPBindIP, "0.0.0.0");
|
||
|
}
|
||
| ... | ... | |
|
else if (strcmp(Name, "HTTPPriority") == 0) HTTPPriority = atoi(Value);
|
||
|
else if (strcmp(Name, "HTTPStreamType") == 0) HTTPStreamType = atoi(Value);
|
||
|
else if (strcmp(Name, "HTTPBindIP") == 0) strcpy(HTTPBindIP, Value);
|
||
|
else if (strcmp(Name, "StartRTSPServer") == 0) StartRTSPServer = atoi(Value);
|
||
|
else if (strcmp(Name, "RTSPServerPort") == 0) RTSPServerPort = atoi(Value);
|
||
|
else if (strcmp(Name, "RTSPPriority") == 0) RTSPPriority = atoi(Value);
|
||
|
else if (strcmp(Name, "RTSPBindIP") == 0) strcpy(RTSPBindIP, Value);
|
||
|
else if (strcmp(Name, "StartIGMPServer") == 0) StartIGMPServer = atoi(Value);
|
||
|
else if (strcmp(Name, "IGMPClientPort") == 0) IGMPClientPort = atoi(Value);
|
||
|
else if (strcmp(Name, "IGMPPriority") == 0) IGMPPriority = atoi(Value);
|
||
| ... | ... | |
|
Add(new cMenuEditIntItem (tr("Priority"), &m_NewSetup.HTTPPriority, MINPRIORITY, MAXPRIORITY));
|
||
|
Add(new cMenuEditStraItem(tr("HTTP Streamtype"), &m_NewSetup.HTTPStreamType, st_Count - 1, StreamTypes));
|
||
|
AddCategory (tr("RTSP Server"));
|
||
|
Add(new cMenuEditBoolItem(tr("Start RTSP Server"), &m_NewSetup.StartRTSPServer));
|
||
|
Add(new cMenuEditIntItem (tr("RTSP Server Port"), &m_NewSetup.RTSPServerPort, 0, 65535));
|
||
|
Add(new cMenuEditIpItem (tr("Bind to IP"), m_NewSetup.RTSPBindIP));
|
||
|
Add(new cMenuEditIntItem (tr("Priority"), &m_NewSetup.RTSPPriority, MINPRIORITY, MAXPRIORITY));
|
||
|
AddCategory (tr("Multicast Streaming Server"));
|
||
|
Add(new cMenuEditBoolItem(tr("Start IGMP Server"), &m_NewSetup.StartIGMPServer));
|
||
|
Add(new cMenuEditIntItem (tr("Multicast Client Port"), &m_NewSetup.IGMPClientPort, 0, 65535));
|
||
| ... | ... | |
|
|| m_NewSetup.StartHTTPServer != StreamdevServerSetup.StartHTTPServer
|
||
|
|| m_NewSetup.HTTPServerPort != StreamdevServerSetup.HTTPServerPort
|
||
|
|| strcmp(m_NewSetup.HTTPBindIP, StreamdevServerSetup.HTTPBindIP) != 0
|
||
|
|| m_NewSetup.StartRTSPServer != StreamdevServerSetup.StartRTSPServer
|
||
|
|| m_NewSetup.RTSPServerPort != StreamdevServerSetup.RTSPServerPort
|
||
|
|| strcmp(m_NewSetup.RTSPBindIP, StreamdevServerSetup.RTSPBindIP) != 0
|
||
|
|| m_NewSetup.StartIGMPServer != StreamdevServerSetup.StartIGMPServer
|
||
|
|| m_NewSetup.IGMPClientPort != StreamdevServerSetup.IGMPClientPort
|
||
|
|| strcmp(m_NewSetup.IGMPBindIP, StreamdevServerSetup.IGMPBindIP) != 0) {
|
||
|
restart = true;
|
||
|
cStreamdevServer::Destruct();
|
||
|
}
|
||
|
|
||
|
SetupStore("HideMenuEntry", m_NewSetup.HideMenuEntry);
|
||
|
SetupStore("MaxClients", m_NewSetup.MaxClients);
|
||
|
SetupStore("StartSuspended", m_NewSetup.StartSuspended);
|
||
| ... | ... | |
|
SetupStore("HTTPBindIP", m_NewSetup.HTTPBindIP);
|
||
|
SetupStore("HTTPPriority", m_NewSetup.HTTPPriority);
|
||
|
SetupStore("HTTPStreamType", m_NewSetup.HTTPStreamType);
|
||
|
SetupStore("RTSPServerPort", m_NewSetup.RTSPServerPort);
|
||
|
SetupStore("RTSPBindIP", m_NewSetup.RTSPBindIP);
|
||
|
SetupStore("RTSPPriority", m_NewSetup.RTSPPriority);
|
||
|
SetupStore("StartIGMPServer", m_NewSetup.StartIGMPServer);
|
||
|
SetupStore("IGMPClientPort", m_NewSetup.IGMPClientPort);
|
||
|
SetupStore("IGMPBindIP", m_NewSetup.IGMPBindIP);
|
||
| server/setup.h | ||
|---|---|---|
|
int HTTPPriority;
|
||
|
int HTTPStreamType;
|
||
|
char HTTPBindIP[20];
|
||
|
int StartRTSPServer;
|
||
|
int RTSPServerPort;
|
||
|
int RTSPPriority;
|
||
|
char RTSPBindIP[20];
|
||
|
int StartIGMPServer;
|
||
|
int IGMPClientPort;
|
||
|
int IGMPPriority;
|
||
| server/streamer.c | ||
|---|---|---|
|
// --- cStreamdevWriter -------------------------------------------------------
|
||
|
cStreamdevWriter::cStreamdevWriter(cTBSocket *Socket,
|
||
|
cStreamdevWriter::cStreamdevWriter(cTBSocket *Socket,
|
||
|
cStreamdevStreamer *Streamer):
|
||
|
cThread("streamdev-writer"),
|
||
|
m_Streamer(Streamer),
|
||
|
m_Socket(Socket)
|
||
|
m_Socket(Socket),
|
||
|
m_StreamEncapsulation(seRAW)
|
||
|
{
|
||
|
}
|
||
| ... | ... | |
|
Dprintf("Writer start\n");
|
||
|
int max = 0;
|
||
|
uchar *block = NULL;
|
||
|
uchar rtpbuf[(7*TS_SIZE)+12]; // 7 TS packets + RTP header size (12 bytes)
|
||
|
ushort sequence_number = 0;
|
||
|
ulong tstamp = 0;
|
||
|
ulong ssrc = 0;
|
||
|
int count, offset = 0;
|
||
|
int timeout = 0;
|
||
| ... | ... | |
|
if (sel.CanWrite(*m_Socket)) {
|
||
|
int written;
|
||
|
int pkgsize = count;
|
||
|
// SOCK_DGRAM indicates multicast
|
||
|
// SOCK_DGRAM indicates unicast/multicast RTP or TS-in-UDP
|
||
|
if (m_Socket->Type() == SOCK_DGRAM) {
|
||
|
// don't fragment multicast packets
|
||
|
// max. payload on standard local ethernet is 1416 to 1456 bytes
|
||
| ... | ... | |
|
pkgsize = 7 * TS_SIZE;
|
||
|
else
|
||
|
pkgsize -= pkgsize % TS_SIZE;
|
||
|
// Check if this should be an RTP stream and not a raw TS-in-UDP stream
|
||
|
if (m_StreamEncapsulation == seRTP) {
|
||
|
// Set RTP header
|
||
|
rtpbuf[0] = 0x02; //RTP version 2, no padding, no extension header, CSRC Count = 0
|
||
|
rtpbuf[1] = 0x20; // RTP payload type 32, no marker
|
||
|
rtpbuf[2] = sequence_number & 0x00FF;
|
||
|
rtpbuf[3] = (sequence_number & 0xFF00) >>8;
|
||
|
rtpbuf[4] = tstamp & 0x000000FF;
|
||
|
rtpbuf[5] = (tstamp & 0x0000FF00) >>8;
|
||
|
rtpbuf[6] = (tstamp & 0x00FF0000) >>16;
|
||
|
rtpbuf[7] = (tstamp & 0xFF000000) >>24;
|
||
|
rtpbuf[8] = ssrc & 0x000000FF;
|
||
|
rtpbuf[9] = (ssrc & 0x0000FF00) >>8;
|
||
|
rtpbuf[10] = (ssrc & 0x00FF0000) >>16;
|
||
|
rtpbuf[11] = (ssrc & 0xFF000000) >>24;
|
||
|
memcpy(&rtpbuf[12], block + offset, pkgsize);
|
||
|
if ((written = m_Socket->Write(&rtpbuf[0], pkgsize+12)) == -1) {
|
||
|
esyslog("ERROR: streamdev-server: couldn't send %d bytes: %m", pkgsize);
|
||
|
break;
|
||
|
}
|
||
|
// Remove size of RTP header again
|
||
|
if (written > 12 )
|
||
|
written -= 12;
|
||
|
}
|
||
|
else
|
||
|
if ((written = m_Socket->Write(block + offset, pkgsize)) == -1) {
|
||
|
esyslog("ERROR: streamdev-server: couldn't send %d bytes: %m", pkgsize);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if ((written = m_Socket->Write(block + offset, pkgsize)) == -1) {
|
||
|
esyslog("ERROR: streamdev-server: couldn't send %d bytes: %m", pkgsize);
|
||
|
break;
|
||
|
else {
|
||
|
if ((written = m_Socket->Write(block + offset, pkgsize)) == -1) {
|
||
|
esyslog("ERROR: streamdev-server: couldn't send %d bytes: %m", pkgsize);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// statistics
|
||
| ... | ... | |
|
Dprintf("Max. Transmit Blocksize was: %d\n", max);
|
||
|
}
|
||
|
void cStreamdevWriter::SetStreamEncapsulationType(eStreamEncapsulation StreamEncapsulation)
|
||
|
{
|
||
|
m_StreamEncapsulation = StreamEncapsulation;
|
||
|
}
|
||
|
// --- cRemuxDummy ------------------------------------------------------------
|
||
|
class cRemuxDummy: public Streamdev::cTSRemux {
|
||
| server/streamer.h | ||
|---|---|---|
|
#define WRITERBUFSIZE (20000 * TS_SIZE)
|
||
|
enum eStreamEncapsulation{
|
||
|
seRAW,
|
||
|
seRTP
|
||
|
};
|
||
|
// --- cStreamdevBuffer -------------------------------------------------------
|
||
|
class cStreamdevBuffer: public cRingBufferLinear {
|
||
| ... | ... | |
|
private:
|
||
|
cStreamdevStreamer *m_Streamer;
|
||
|
cTBSocket *m_Socket;
|
||
|
eStreamEncapsulation m_StreamEncapsulation;
|
||
|
protected:
|
||
|
virtual void Action(void);
|
||
| ... | ... | |
|
public:
|
||
|
cStreamdevWriter(cTBSocket *Socket, cStreamdevStreamer *Streamer);
|
||
|
virtual ~cStreamdevWriter();
|
||
|
void SetStreamEncapsulationType(eStreamEncapsulation StreamEncapsulation);
|
||
|
};
|
||
|
// --- cStreamdevStreamer -----------------------------------------------------
|
||
- « Previous
- 1
- …
- 3
- 4
- 5
- Next »