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();
|
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
1
rtcp.h
@ -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
82
rtp.c
@ -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
8
rtp.h
@ -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
109
socket.c
@ -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)
|
||||||
{
|
{
|
||||||
|
12
socket.h
12
socket.h
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user