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:
parent
3a742f1f14
commit
adddf3e4e7
54
rtcp.c
54
rtcp.c
@ -29,12 +29,60 @@ int cSatipRtcp::GetFd(void)
|
||||
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)
|
||||
{
|
||||
//debug("cSatipRtcp::%s(%d)", __FUNCTION__, fdP);
|
||||
if (bufferM) {
|
||||
int length = ReadApplication(bufferM, bufferLenM);
|
||||
if (length > 0)
|
||||
tunerM->ParseReceptionParameters(bufferM, length);
|
||||
int length = Read(bufferM, bufferLenM);
|
||||
if (length > 0) {
|
||||
int offset = GetApplicationOffset(&length);
|
||||
if (offset >= 0)
|
||||
tunerM->ParseReceptionParameters(bufferM + offset, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
rtcp.h
1
rtcp.h
@ -19,6 +19,7 @@ private:
|
||||
cSatipTunerIf *tunerM;
|
||||
unsigned int bufferLenM;
|
||||
unsigned char *bufferM;
|
||||
int GetApplicationOffset(int *lenghtP);
|
||||
|
||||
protected:
|
||||
virtual int GetFd(void);
|
||||
|
82
rtp.c
82
rtp.c
@ -11,7 +11,10 @@
|
||||
cSatipRtp::cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP)
|
||||
: deviceM(&deviceP),
|
||||
bufferLenM(bufferLenP),
|
||||
bufferM(MALLOC(unsigned char, bufferLenM))
|
||||
bufferM(MALLOC(unsigned char, bufferLenM)),
|
||||
lastErrorReportM(0),
|
||||
packetErrorsM(0),
|
||||
sequenceNumberM(-1)
|
||||
{
|
||||
if (bufferM)
|
||||
memset(bufferM, 0, bufferLenM);
|
||||
@ -29,12 +32,83 @@ int cSatipRtp::GetFd(void)
|
||||
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)
|
||||
{
|
||||
//debug("cSatipRtp::%s(%d)", __FUNCTION__, fdP);
|
||||
if (bufferM) {
|
||||
int length = ReadVideo(bufferM, min(deviceM->CheckData(), bufferLenM));
|
||||
if (length > 0)
|
||||
deviceM->WriteData(bufferM, length);
|
||||
int length = Read(bufferM, min(deviceM->CheckData(), bufferLenM));
|
||||
if (length > 0) {
|
||||
int headerlen = GetHeaderLenght(length);
|
||||
if ((headerlen >= 0) && (headerlen < length))
|
||||
deviceM->WriteData(bufferM + headerlen, length - headerlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
rtp.h
8
rtp.h
@ -15,9 +15,16 @@
|
||||
|
||||
class cSatipRtp : public cSatipSocket, public cSatipPollerIf {
|
||||
private:
|
||||
enum {
|
||||
eReportIntervalS = 300 // in seconds
|
||||
};
|
||||
cSatipDeviceIf *deviceM;
|
||||
unsigned int bufferLenM;
|
||||
unsigned char *bufferM;
|
||||
time_t lastErrorReportM;
|
||||
int packetErrorsM;
|
||||
int sequenceNumberM;
|
||||
int GetHeaderLenght(int lengthP);
|
||||
|
||||
protected:
|
||||
virtual int GetFd(void);
|
||||
@ -26,6 +33,7 @@ protected:
|
||||
public:
|
||||
cSatipRtp(cSatipDeviceIf &deviceP, unsigned int bufferLenP);
|
||||
virtual ~cSatipRtp();
|
||||
virtual void Close(void);
|
||||
};
|
||||
|
||||
#endif /* __SATIP_RTP_H_ */
|
||||
|
109
socket.c
109
socket.c
@ -20,10 +20,7 @@
|
||||
|
||||
cSatipSocket::cSatipSocket()
|
||||
: socketPortM(0),
|
||||
socketDescM(-1),
|
||||
lastErrorReportM(0),
|
||||
packetErrorsM(0),
|
||||
sequenceNumberM(-1)
|
||||
socketDescM(-1)
|
||||
{
|
||||
debug("cSatipSocket::%s()", __FUNCTION__);
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
@ -75,14 +72,8 @@ void cSatipSocket::Close(void)
|
||||
close(socketDescM);
|
||||
socketDescM = -1;
|
||||
socketPortM = 0;
|
||||
sequenceNumberM = -1;
|
||||
memset(&sockAddrM, 0, sizeof(sockAddrM));
|
||||
}
|
||||
if (packetErrorsM) {
|
||||
info("detected %d RTP packet errors", packetErrorsM);
|
||||
packetErrorsM = 0;
|
||||
lastErrorReportM = time(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool cSatipSocket::Flush(void)
|
||||
@ -141,104 +132,6 @@ int cSatipSocket::Read(unsigned char *bufferAddrP, unsigned int bufferLenP)
|
||||
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)
|
||||
{
|
||||
|
12
socket.h
12
socket.h
@ -12,28 +12,20 @@
|
||||
|
||||
class cSatipSocket {
|
||||
private:
|
||||
enum {
|
||||
eReportIntervalS = 300 // in seconds
|
||||
};
|
||||
int socketPortM;
|
||||
int socketDescM;
|
||||
struct sockaddr_in sockAddrM;
|
||||
time_t lastErrorReportM;
|
||||
int packetErrorsM;
|
||||
int sequenceNumberM;
|
||||
|
||||
public:
|
||||
cSatipSocket();
|
||||
~cSatipSocket();
|
||||
virtual ~cSatipSocket();
|
||||
bool Open(const int portP = 0);
|
||||
void Close(void);
|
||||
virtual void Close(void);
|
||||
int Fd(void) { return socketDescM; }
|
||||
int Port(void) { return socketPortM; }
|
||||
bool IsOpen(void) { return (socketDescM >= 0); }
|
||||
bool Flush(void);
|
||||
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);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user