1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rtp_packet.h"
17 #include <arpa/inet.h>
18 #include <cstdlib>
19 
20 namespace OHOS {
21 namespace Sharing {
22 #define AV_RB16(x) ((((const uint8_t *)(x))[0] << 8) | ((const uint8_t *)(x))[1])
23 
GetCsrcSize() const24 size_t RtpHeader::GetCsrcSize() const
25 {
26     return csrc_ << 2; // 2:byte offset
27 }
28 
GetCsrcData()29 uint8_t *RtpHeader::GetCsrcData()
30 {
31     if (!csrc_) {
32         return nullptr;
33     }
34 
35     return &payload_;
36 }
37 
GetExtSize(size_t rtp_size) const38 size_t RtpHeader::GetExtSize(size_t rtp_size) const
39 {
40     if (!ext_) {
41         return 0;
42     }
43     if (RtpPacket::RTP_HEADER_SIZE + GetCsrcSize() + 4 > rtp_size) { // 4:byte offset
44         return 0;
45     }
46 
47     auto ext_ptr = &payload_ + GetCsrcSize();
48     return AV_RB16(ext_ptr + 2) << 2; // 2:byte offset
49 }
50 
GetExtReserved(size_t rtp_size) const51 uint16_t RtpHeader::GetExtReserved(size_t rtp_size) const
52 {
53     if (!ext_) {
54         return 0;
55     }
56     if (RtpPacket::RTP_HEADER_SIZE + GetCsrcSize() + 2 > rtp_size) { // 2:byte offset
57         return 0;
58     }
59 
60     auto ext_ptr = &payload_ + GetCsrcSize();
61     return AV_RB16(ext_ptr);
62 }
63 
GetExtData(size_t rtp_size)64 uint8_t *RtpHeader::GetExtData(size_t rtp_size)
65 {
66     if (!ext_) {
67         return nullptr;
68     }
69     auto ext_ptr = &payload_ + GetCsrcSize();
70 
71     return ext_ptr + 4; // 4:byte offset
72 }
73 
GetPayloadOffset(size_t rtp_size) const74 size_t RtpHeader::GetPayloadOffset(size_t rtp_size) const
75 {
76     return GetCsrcSize() + (ext_ ? (4 + GetExtSize(rtp_size)) : 0); // 4:byte offset
77 }
78 
GetPayloadData(size_t rtp_size)79 uint8_t *RtpHeader::GetPayloadData(size_t rtp_size)
80 {
81     return &payload_ + GetPayloadOffset(rtp_size);
82 }
83 
GetPaddingSize(size_t rtp_size) const84 size_t RtpHeader::GetPaddingSize(size_t rtp_size) const
85 {
86     if (!padding_) {
87         return 0;
88     }
89     auto end = (uint8_t *)this + rtp_size - 1;
90     if (*end + RtpPacket::RTP_HEADER_SIZE > rtp_size) {
91         return 0;
92     }
93     return *end;
94 }
95 
GetPayloadSize(size_t rtp_size) const96 size_t RtpHeader::GetPayloadSize(size_t rtp_size) const
97 {
98     auto invalid_size = GetPayloadOffset(rtp_size) + GetPaddingSize(rtp_size);
99     if (invalid_size + RtpPacket::RTP_HEADER_SIZE >= rtp_size) {
100         return 0;
101     }
102 
103     return rtp_size - invalid_size - RtpPacket::RTP_HEADER_SIZE;
104 }
105 
GetHeader()106 RtpHeader *RtpPacket::GetHeader()
107 {
108     return (RtpHeader *)Data();
109 }
110 
GetSeq()111 uint16_t RtpPacket::GetSeq()
112 {
113     return ntohs(GetHeader()->seq_);
114 }
115 
GetStamp()116 uint32_t RtpPacket::GetStamp()
117 {
118     return ntohl(GetHeader()->stamp_);
119 }
120 
GetStampMS()121 uint32_t RtpPacket::GetStampMS()
122 {
123     return GetStamp() * uint64_t(1000) / sampleRate_; // 1000:unit
124 }
125 
GetSSRC()126 uint32_t RtpPacket::GetSSRC()
127 {
128     return ntohl(GetHeader()->ssrc_);
129 }
130 
GetPayload()131 uint8_t *RtpPacket::GetPayload()
132 {
133     return GetHeader()->GetPayloadData(Size());
134 }
135 
GetPayloadSize()136 size_t RtpPacket::GetPayloadSize()
137 {
138     return GetHeader()->GetPayloadSize(Size());
139 }
140 } // namespace Sharing
141 } // namespace OHOS