1 /*
2 * The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) implementation with additional features.
3 * Copyright (C) 2017 Belledonne Communications SARL
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #include "ortp/ortp.h"
21 #include <bctoolbox/port.h>
22
23
rtp_profile_get_payload_number_from_mime(RtpProfile * profile,const char * mime)24 int rtp_profile_get_payload_number_from_mime(RtpProfile *profile, const char *mime)
25 {
26 return rtp_profile_get_payload_number_from_mime_and_flag(profile, mime, -1);
27 }
28
rtp_profile_get_payload_number_from_mime_and_flag(RtpProfile * profile,const char * mime,int flag)29 int rtp_profile_get_payload_number_from_mime_and_flag(RtpProfile *profile, const char *mime, int flag)
30 {
31 PayloadType *pt;
32 int i;
33 for (i = 0; i < RTP_PROFILE_MAX_PAYLOADS; i++) {
34 pt = rtp_profile_get_payload(profile, i);
35 if (pt != NULL) {
36 if (strcasecmp(pt->mime_type, mime) == 0) {
37 if (flag < 0 || pt->flags & flag) {
38 return i;
39 }
40 }
41 }
42 }
43 return -1;
44 }
45
rtp_profile_find_payload_number(RtpProfile * profile,const char * mime,int rate,int channels)46 int rtp_profile_find_payload_number(RtpProfile*profile,const char *mime,int rate,int channels)
47 {
48 int i;
49 PayloadType *pt;
50 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
51 {
52 pt=rtp_profile_get_payload(profile,i);
53 if (pt!=NULL)
54 {
55 if (strcasecmp(pt->mime_type,mime)==0 &&
56 pt->clock_rate==rate &&
57 (pt->channels==channels || channels<=0 || pt->channels<=0)) {
58 /*we don't look at channels if it is undefined
59 ie a negative or zero value*/
60 return i;
61 }
62 }
63 }
64 return -1;
65 }
66
rtp_profile_get_payload_number_from_rtpmap(RtpProfile * profile,const char * rtpmap)67 int rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile,const char *rtpmap)
68 {
69 int clock_rate, channels, ret;
70 char* subtype = ortp_strdup( rtpmap );
71 char* rate_str = NULL;
72 char* chan_str = NULL;
73
74 /* find the slash after the subtype */
75 rate_str = strchr(subtype, '/');
76 if (rate_str && strlen(rate_str)>1) {
77 *rate_str = 0;
78 rate_str++;
79
80 /* Look for another slash */
81 chan_str = strchr(rate_str, '/');
82 if (chan_str && strlen(chan_str)>1) {
83 *chan_str = 0;
84 chan_str++;
85 } else {
86 chan_str = NULL;
87 }
88 } else {
89 rate_str = NULL;
90 }
91
92 // Use default clock rate if none given
93 if (rate_str) clock_rate = atoi(rate_str);
94 else clock_rate = 8000;
95
96 // Use default number of channels if none given
97 if (chan_str) channels = atoi(chan_str);
98 else channels = -1;
99
100 //printf("Searching for payload %s at freq %i with %i channels\n",subtype,clock_rate,ch1annels);
101 ret=rtp_profile_find_payload_number(profile,subtype,clock_rate,channels);
102 ortp_free(subtype);
103 return ret;
104 }
105
rtp_profile_find_payload(RtpProfile * prof,const char * mime,int rate,int channels)106 PayloadType * rtp_profile_find_payload(RtpProfile *prof,const char *mime,int rate,int channels)
107 {
108 int i;
109 i=rtp_profile_find_payload_number(prof,mime,rate,channels);
110 if (i>=0) return rtp_profile_get_payload(prof,i);
111 return NULL;
112 }
113
114
rtp_profile_get_payload_from_mime(RtpProfile * profile,const char * mime)115 PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime)
116 {
117 int pt;
118 pt=rtp_profile_get_payload_number_from_mime(profile,mime);
119 if (pt==-1) return NULL;
120 else return rtp_profile_get_payload(profile,pt);
121 }
122
123
rtp_profile_get_payload_from_rtpmap(RtpProfile * profile,const char * rtpmap)124 PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap)
125 {
126 int pt = rtp_profile_get_payload_number_from_rtpmap(profile,rtpmap);
127 if (pt==-1) return NULL;
128 else return rtp_profile_get_payload(profile,pt);
129 }
130
rtp_profile_move_payload(RtpProfile * prof,int oldpos,int newpos)131 int rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos){
132 if (oldpos<0 || oldpos>=RTP_PROFILE_MAX_PAYLOADS) {
133 ortp_error("Bad old pos index %i",oldpos);
134 return -1;
135 }
136 if (newpos<0 || newpos>=RTP_PROFILE_MAX_PAYLOADS) {
137 ortp_error("Bad new pos index %i",newpos);
138 return -1;
139 }
140 prof->payload[newpos]=prof->payload[oldpos];
141 prof->payload[oldpos]=NULL;
142 return 0;
143 }
144
rtp_profile_new(const char * name)145 RtpProfile * rtp_profile_new(const char *name)
146 {
147 RtpProfile *prof=(RtpProfile*)ortp_new0(RtpProfile,1);
148 rtp_profile_set_name(prof,name);
149 return prof;
150 }
151
152 /**
153 * Assign payload type number index to payload type desribed in pt for the RTP profile profile.
154 * @param profile a RTP profile
155 * @param idx the payload type number
156 * @param pt the payload type description
157 *
158 **/
rtp_profile_set_payload(RtpProfile * profile,int idx,PayloadType * pt)159 void rtp_profile_set_payload(RtpProfile *profile, int idx, PayloadType *pt){
160 if (idx<0 || idx>=RTP_PROFILE_MAX_PAYLOADS) {
161 ortp_error("Bad index %i",idx);
162 return;
163 }
164 profile->payload[idx]=pt;
165 }
166
167 /**
168 * Initialize the profile to the empty profile (all payload type are unassigned).
169 *@param profile a RTP profile
170 *
171 **/
rtp_profile_clear_all(RtpProfile * profile)172 void rtp_profile_clear_all(RtpProfile *profile){
173 int i;
174 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
175 profile->payload[i]=0;
176 }
177 }
178
179
180 /**
181 * Set a name to the rtp profile. (This is not required)
182 * @param profile a rtp profile object
183 * @param name a string
184 *
185 **/
rtp_profile_set_name(RtpProfile * profile,const char * name)186 void rtp_profile_set_name(RtpProfile *profile, const char *name){
187 if (profile->name!=NULL) ortp_free(profile->name);
188 profile->name=ortp_strdup(name);
189 }
190
191 /* ! payload are not cloned*/
rtp_profile_clone(RtpProfile * prof)192 RtpProfile * rtp_profile_clone(RtpProfile *prof)
193 {
194 int i;
195 PayloadType *pt;
196 RtpProfile *newprof=rtp_profile_new(prof->name);
197 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
198 pt=rtp_profile_get_payload(prof,i);
199 if (pt!=NULL){
200 rtp_profile_set_payload(newprof,i,pt);
201 }
202 }
203 return newprof;
204 }
205
206
207 /*clone a profile and its payloads */
rtp_profile_clone_full(RtpProfile * prof)208 RtpProfile * rtp_profile_clone_full(RtpProfile *prof)
209 {
210 int i;
211 PayloadType *pt;
212 RtpProfile *newprof=rtp_profile_new(prof->name);
213 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
214 pt=rtp_profile_get_payload(prof,i);
215 if (pt!=NULL){
216 rtp_profile_set_payload(newprof,i,payload_type_clone(pt));
217 }
218 }
219 return newprof;
220 }
221
rtp_profile_destroy(RtpProfile * prof)222 void rtp_profile_destroy(RtpProfile *prof)
223 {
224 int i;
225 PayloadType *payload;
226 if (prof->name) {
227 ortp_free(prof->name);
228 prof->name = NULL;
229 }
230 for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
231 {
232 payload=rtp_profile_get_payload(prof,i);
233 if (payload!=NULL && (payload->flags & PAYLOAD_TYPE_ALLOCATED))
234 payload_type_destroy(payload);
235 }
236 ortp_free(prof);
237 }
238