1
0
mirror of https://github.com/rofafor/vdr-plugin-satip.git synced 2023-10-10 13:37:42 +02:00

Moved ReadVideo/Application() from cSatipSocket into cSatipRtp/cStatipRtcp classes and get rid of unnecessary memcpy.

The original patch is polished and tweaked by Rolf Ahrenberg.
This commit is contained in:
nafets227 2014-11-16 09:31:34 +01:00 committed by Rolf Ahrenberg
parent 3a742f1f14
commit adddf3e4e7
6 changed files with 141 additions and 125 deletions

54
rtcp.c
View File

@ -29,12 +29,60 @@ int cSatipRtcp::GetFd(void)
return Fd(); return Fd();
} }
int cSatipRtcp::GetApplicationOffset(int *lengthP)
{
//debug("cSatipRtcp::%s()", __FUNCTION__);
if (!lengthP)
return -1;
int offset = 0;
int total = *lengthP;
while (total > 0) {
// Version
unsigned int v = (bufferM[offset] >> 6) & 0x03;
// Padding
//unsigned int p = (bufferM[offset] >> 5) & 0x01;
// Subtype
//unsigned int st = bufferM[offset] & 0x1F;
// Payload type
unsigned int pt = bufferM[offset + 1] & 0xFF;
// Lenght
unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF);
// Convert it to bytes
length = (length + 1) * 4;
// V=2, APP = 204
if ((v == 2) && (pt == 204)) {
// SSCR/CSCR
//unsigned int ssrc = ((bufferM[offset + 4] & 0xFF) << 24) | ((bufferM[offset + 5] & 0xFF) << 16) |
// ((bufferM[offset + 6] & 0xFF) << 8) | (bufferM[offset + 7] & 0xFF);
// Name
if ((bufferM[offset + 8] == 'S') && (bufferM[offset + 9] == 'E') &&
(bufferM[offset + 10] == 'S') && (bufferM[offset + 11] == '1')) {
// Identifier
//unsigned int id = ((bufferM[offset + 12] & 0xFF) << 8) | (bufferM[offset + 13] & 0xFF);
// String length
int string_length = ((bufferM[offset + 14] & 0xFF) << 8) | (bufferM[offset + 15] & 0xFF);
if (string_length > 0) {
*lengthP = string_length;
return (offset + 16);
}
}
}
offset += length;
total -= length;
}
*lengthP = 0;
return -1;
}
void cSatipRtcp::Action(int fdP) void cSatipRtcp::Action(int fdP)
{ {
//debug("cSatipRtcp::%s(%d)", __FUNCTION__, fdP); //debug("cSatipRtcp::%s(%d)", __FUNCTION__, fdP);
if (bufferM) { if (bufferM) {
int length = ReadApplication(bufferM, bufferLenM); int length = Read(bufferM, bufferLenM);
if (length > 0) if (length > 0) {
tunerM->ParseReceptionParameters(bufferM, length); int offset = GetApplicationOffset(&length);
if (offset >= 0)
tunerM->ParseReceptionParameters(bufferM + offset, length);
}
} }
} }

1
rtcp.h
View File

@ -19,6 +19,7 @@ private:
cSatipTunerIf *tunerM; cSatipTunerIf *tunerM;
unsigned int bufferLenM; unsigned int bufferLenM;
unsigned char *bufferM; unsigned char *bufferM;
int GetApplicationOffset(int *lenghtP);
protected: protected:
virtual int GetFd(void); virtual int GetFd(void);

82
rtp.c
View File

@ -11,7 +11,10 @@
cSatipRtp::cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP) cSatipRtp::cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP)
: deviceM(&deviceP), : deviceM(&deviceP),
bufferLenM(bufferLenP), bufferLenM(bufferLenP),
bufferM(MALLOC(unsigned char, bufferLenM)) bufferM(MALLOC(unsigned char, bufferLenM)),
lastErrorReportM(0),
packetErrorsM(0),
sequenceNumberM(-1)
{ {
if (bufferM) if (bufferM)
memset(bufferM, 0, bufferLenM); memset(bufferM, 0, bufferLenM);
@ -29,12 +32,83 @@ int cSatipRtp::GetFd(void)
return Fd(); return Fd();
} }
void cSatipRtp::Close(void)
{
debug("cSatipRtp::%s(%d)", __FUNCTION__, GetFd());
cSatipSocket::Close();
sequenceNumberM = -1;
if (packetErrorsM) {
info("Detected %d RTP packet errors", packetErrorsM);
packetErrorsM = 0;
lastErrorReportM = time(NULL);
}
}
int cSatipRtp::GetHeaderLenght(int lengthP)
{
//debug("cSatipRtp::%s()", __FUNCTION__);
unsigned int headerlen = 0;
if (lengthP > 0) {
if (bufferM[0] == TS_SYNC_BYTE)
return headerlen;
else if (lengthP > 3) {
// http://tools.ietf.org/html/rfc3550
// http://tools.ietf.org/html/rfc2250
// Version
unsigned int v = (bufferM[0] >> 6) & 0x03;
// Extension bit
unsigned int x = (bufferM[0] >> 4) & 0x01;
// CSCR count
unsigned int cc = bufferM[0] & 0x0F;
// Payload type: MPEG2 TS = 33
//unsigned int pt = bufferAddrP[1] & 0x7F;
// Sequence number
int seq = ((bufferM[2] & 0xFF) << 8) | (bufferM[3] & 0xFF);
if ((((sequenceNumberM + 1) % 0xFFFF) == 0) && (seq == 0xFFFF))
sequenceNumberM = -1;
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
packetErrorsM++;
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
info("Detected %d RTP packet errors", packetErrorsM);
packetErrorsM = 0;
lastErrorReportM = time(NULL);
}
sequenceNumberM = seq;
}
else
sequenceNumberM = seq;
// Header lenght
headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
// Check if extension
if (x) {
// Extension header length
unsigned int ehl = (((bufferM[headerlen + 2] & 0xFF) << 8) | (bufferM[headerlen + 3] & 0xFF));
// Update header length
headerlen += (ehl + 1) * (unsigned int)sizeof(uint32_t);
}
// Check that rtp is version 2 and payload contains multiple of TS packet data
if ((v != 2) || (((lengthP - headerlen) % TS_SIZE) != 0) || (bufferM[headerlen] != TS_SYNC_BYTE)) {
debug("cSatipRtp::%s(%d): Received incorrect RTP packet", __FUNCTION__, lengthP);
headerlen = -1;
}
}
}
return headerlen;
}
void cSatipRtp::Action(int fdP) void cSatipRtp::Action(int fdP)
{ {
//debug("cSatipRtp::%s(%d)", __FUNCTION__, fdP); //debug("cSatipRtp::%s(%d)", __FUNCTION__, fdP);
if (bufferM) { if (bufferM) {
int length = ReadVideo(bufferM, min(deviceM->CheckData(), bufferLenM)); int length = Read(bufferM, min(deviceM->CheckData(), bufferLenM));
if (length > 0) if (length > 0) {
deviceM->WriteData(bufferM, length); int headerlen = GetHeaderLenght(length);
if ((headerlen >= 0) && (headerlen < length))
deviceM->WriteData(bufferM + headerlen, length - headerlen);
}
} }
} }

8
rtp.h
View File

@ -15,9 +15,16 @@
class cSatipRtp : public cSatipSocket, public cSatipPollerIf { class cSatipRtp : public cSatipSocket, public cSatipPollerIf {
private: private:
enum {
eReportIntervalS = 300 // in seconds
};
cSatipDeviceIf *deviceM; cSatipDeviceIf *deviceM;
unsigned int bufferLenM; unsigned int bufferLenM;
unsigned char *bufferM; unsigned char *bufferM;
time_t lastErrorReportM;
int packetErrorsM;
int sequenceNumberM;
int GetHeaderLenght(int lengthP);
protected: protected:
virtual int GetFd(void); virtual int GetFd(void);
@ -26,6 +33,7 @@ protected:
public: public:
cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP); cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP);
virtual ~cSatipRtp(); virtual ~cSatipRtp();
virtual void Close(void);
}; };
#endif /* __SATIP_RTP_H_ */ #endif /* __SATIP_RTP_H_ */

109
socket.c
View File

@ -20,10 +20,7 @@
cSatipSocket::cSatipSocket() cSatipSocket::cSatipSocket()
: socketPortM(0), : socketPortM(0),
socketDescM(-1), socketDescM(-1)
lastErrorReportM(0),
packetErrorsM(0),
sequenceNumberM(-1)
{ {
debug("cSatipSocket::%s()", __FUNCTION__); debug("cSatipSocket::%s()", __FUNCTION__);
memset(&sockAddrM, 0, sizeof(sockAddrM)); memset(&sockAddrM, 0, sizeof(sockAddrM));
@ -75,14 +72,8 @@ void cSatipSocket::Close(void)
close(socketDescM); close(socketDescM);
socketDescM = -1; socketDescM = -1;
socketPortM = 0; socketPortM = 0;
sequenceNumberM = -1;
memset(&sockAddrM, 0, sizeof(sockAddrM)); memset(&sockAddrM, 0, sizeof(sockAddrM));
} }
if (packetErrorsM) {
info("detected %d RTP packet errors", packetErrorsM);
packetErrorsM = 0;
lastErrorReportM = time(NULL);
}
} }
bool cSatipSocket::Flush(void) bool cSatipSocket::Flush(void)
@ -141,104 +132,6 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
return 0; return 0;
} }
int cSatipSocket::ReadVideo(unsigned char *bufferAddrP, unsigned int bufferLenP)
{
//debug("cSatipSocket::%s()", __FUNCTION__);
int len = Read(bufferAddrP, bufferLenP);
if (len > 0) {
if (bufferAddrP[0] == TS_SYNC_BYTE)
return len;
else if (len > 3) {
// http://tools.ietf.org/html/rfc3550
// http://tools.ietf.org/html/rfc2250
// Version
unsigned int v = (bufferAddrP[0] >> 6) & 0x03;
// Extension bit
unsigned int x = (bufferAddrP[0] >> 4) & 0x01;
// CSCR count
unsigned int cc = bufferAddrP[0] & 0x0F;
// Payload type: MPEG2 TS = 33
//unsigned int pt = bufferAddrP[1] & 0x7F;
// Sequence number
int seq = ((bufferAddrP[2] & 0xFF) << 8) | (bufferAddrP[3] & 0xFF);
if ((((sequenceNumberM + 1) % 0xFFFF) == 0) && (seq == 0xFFFF))
sequenceNumberM = -1;
else if ((sequenceNumberM >= 0) && (((sequenceNumberM + 1) % 0xFFFF) != seq)) {
packetErrorsM++;
if (time(NULL) - lastErrorReportM > eReportIntervalS) {
info("detected %d RTP packet errors", packetErrorsM);
packetErrorsM = 0;
lastErrorReportM = time(NULL);
}
sequenceNumberM = seq;
}
else
sequenceNumberM = seq;
// Header lenght
unsigned int headerlen = (3 + cc) * (unsigned int)sizeof(uint32_t);
// Check if extension
if (x) {
// Extension header length
unsigned int ehl = (((bufferAddrP[headerlen + 2] & 0xFF) << 8) |
(bufferAddrP[headerlen + 3] & 0xFF));
// Update header length
headerlen += (ehl + 1) * (unsigned int)sizeof(uint32_t);
}
// Check that rtp is version 2 and payload contains multiple of TS packet data
if ((v == 2) && (((len - headerlen) % TS_SIZE) == 0) &&
(bufferAddrP[headerlen] == TS_SYNC_BYTE)) {
// Set argument point to payload in read buffer
memmove(bufferAddrP, &bufferAddrP[headerlen], (len - headerlen));
return (len - headerlen);
}
}
}
return 0;
}
int cSatipSocket::ReadApplication(unsigned char *bufferAddrP, unsigned int bufferLenP)
{
//debug("cSatipSocket::%s()", __FUNCTION__);
int len = Read(bufferAddrP, bufferLenP);
int offset = 0;
while (len > 0) {
// Version
unsigned int v = (bufferAddrP[offset] >> 6) & 0x03;
// Padding
//unsigned int p = (bufferAddrP[offset] >> 5) & 0x01;
// Subtype
//unsigned int st = bufferAddrP[offset] & 0x1F;
// Payload type
unsigned int pt = bufferAddrP[offset + 1] & 0xFF;
// Lenght
unsigned int length = ((bufferAddrP[offset + 2] & 0xFF) << 8) | (bufferAddrP[offset + 3] & 0xFF);
// Convert it to bytes
length = (length + 1) * 4;
// V=2, APP = 204
if ((v == 2) && (pt == 204)) {
// SSCR/CSCR
//unsigned int ssrc = ((bufferAddrP[offset + 4] & 0xFF) << 24) | ((bufferAddrP[offset + 5] & 0xFF) << 16) |
// ((bufferAddrP[offset + 6] & 0xFF) << 8) | (bufferAddrP[offset + 7] & 0xFF);
// Name
if ((bufferAddrP[offset + 8] == 'S') && (bufferAddrP[offset + 9] == 'E') &&
(bufferAddrP[offset + 10] == 'S') && (bufferAddrP[offset + 11] == '1')) {
// Identifier
//unsigned int id = ((bufferAddrP[offset + 12] & 0xFF) << 8) | (bufferAddrP[offset + 13] & 0xFF);
// String length
int string_length = ((bufferAddrP[offset + 14] & 0xFF) << 8) | (bufferAddrP[offset + 15] & 0xFF);
if (string_length > 0) {
// Set argument point to payload in read buffer
memmove(bufferAddrP, &bufferAddrP[offset + 16], string_length);
bufferAddrP[string_length] = 0;
return string_length;
}
}
}
offset += length;
len -= length;
}
return 0;
}
bool cSatipSocket::Write(const char *addrP, const unsigned char *bufferAddrP, unsigned int bufferLenP) bool cSatipSocket::Write(const char *addrP, const unsigned char *bufferAddrP, unsigned int bufferLenP)
{ {

View File

@ -12,28 +12,20 @@
class cSatipSocket { class cSatipSocket {
private: private:
enum {
eReportIntervalS = 300 // in seconds
};
int socketPortM; int socketPortM;
int socketDescM; int socketDescM;
struct sockaddr_in sockAddrM; struct sockaddr_in sockAddrM;
time_t lastErrorReportM;
int packetErrorsM;
int sequenceNumberM;
public: public:
cSatipSocket(); cSatipSocket();
~cSatipSocket(); virtual ~cSatipSocket();
bool Open(const int portP = 0); bool Open(const int portP = 0);
void Close(void); virtual void Close(void);
int Fd(void) { return socketDescM; } int Fd(void) { return socketDescM; }
int Port(void) { return socketPortM; } int Port(void) { return socketPortM; }
bool IsOpen(void) { return (socketDescM >= 0); } bool IsOpen(void) { return (socketDescM >= 0); }
bool Flush(void); bool Flush(void);
int Read(unsigned char *bufferAddrP, unsigned int bufferLenP); int Read(unsigned char *bufferAddrP, unsigned int bufferLenP);
int ReadVideo(unsigned char *bufferAddrP, unsigned int bufferLenP);
int ReadApplication(unsigned char *bufferAddrP, unsigned int bufferLenP);
bool Write(const char *addrP, const unsigned char *bufferAddrP, unsigned int bufferLenP); bool Write(const char *addrP, const unsigned char *bufferAddrP, unsigned int bufferLenP);
}; };