ghy
Alejandro Acuña
2025-03-12 26319e4c5bfbee722c15b8e7ccca9b6127bb1cb8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// RTPPacket.cpp: implementation of the RTPPacket class.
//
//////////////////////////////////////////////////////////////////////
 
#include "RTPPacket.h"
#include "Exception.h"
#include "TraceUser.h"
 
RTPPacket *
RTPPacket::CreateRTPPacket(char *buffer, int len, Tracer *tracer)
{
    int returnCode = 0;
    RTPPacket *rtpPacket = NULL;
 
    // make a copy of the class variables so that we can fill them in to test
    // for the validity of the packet before we create the RTPPacket structure
    bool            headerExtension;
    unsigned char   contributorCount;
    bool            marker;
    unsigned char   payloadType;
    unsigned short  seqNo;
    unsigned long   timestamp;
    unsigned long   ssrc;
    unsigned long   dataLen;
    char            *rtpData;
    unsigned char   version;
    unsigned long   headerLength;
 
    char            *packetPtr;
    unsigned long   totalLength;
    unsigned long   numPadding;
 
    try
    {
        if (len < 12)
        {
            throw Exception(-10, "invalid RTP packet : len = %d bytes", len);
        }
        packetPtr           = buffer;
        totalLength         = len;
        numPadding          = packetPtr[0] & 0x20 ? packetPtr[totalLength - 1] : 0;
 
        headerExtension     = (packetPtr[0] & 0x10) != 0;
        if (headerExtension)
        {
            throw Exception(-20, "header extension not supported");
        }
 
        contributorCount    = packetPtr[0] & 0x0f;
        marker              = (packetPtr[1] & 0x80) != 0;
        payloadType         = packetPtr[1] & 0x7f;
        seqNo               = ntohs(*((short *)(packetPtr + 2)));
        timestamp           = ntohl(*((unsigned long *)(packetPtr + 4)));
        ssrc                = ntohl(*((unsigned long *)(packetPtr + 8)));
 
        version             = (packetPtr[0] & 0xc0) >> 6;
        if (version != 2)
        {
            throw Exception(-30, "invalid RTP version %d", version);
        }
 
        headerLength        = 12 + 4 * contributorCount;
        if (totalLength < headerLength)
        {
            throw Exception(-40, "totalLength (%d) < headerLength (%d) ! contributor count = %d", totalLength, headerLength, contributorCount);
        }
 
        if (totalLength < (headerLength + numPadding))
        {
            throw Exception(-50, "totalLength (%d) < headerLength (%d) + numPadding (%d)", totalLength, headerLength, numPadding);
        }
        dataLen             = totalLength - headerLength - numPadding;
        rtpData             = packetPtr + headerLength;
 
        // now that all checks have been made, we will create and return the RTP packet
        rtpPacket = new RTPPacket(buffer, len);
    }
    catch (Exception exception)
    {
        tracer->tracef(ERR, "RTPPacket::CreateRTPPacket : error %d : %s\n", exception.ErrorCode(), exception.ErrorMessage());
        if (rtpPacket)
        {
            delete rtpPacket;
        }
        rtpPacket = NULL;
    }
    return rtpPacket;
}
 
RTPPacket *
RTPPacket::CloneHeader()
{
    RTPPacket *newHeader = new RTPPacket(this->packetPtr, this->headerLength);
    if (newHeader)
    {
        newHeader->packetPtr = NULL;
        newHeader->rtpData = NULL;
    }
    return newHeader;
}