1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "h263_media_info_parser.h"
19 #include "oscl_string_utils.h"
20 #include "oscl_string_containers.h"
21
22 SDP_ERROR_CODE
parseMediaInfo(const char * buff,const int index,SDPInfo * sdp,payloadVector payload_vec,bool isSipSdp,int alt_id,bool alt_def_id)23 SDPH263MediaInfoParser::parseMediaInfo(const char *buff, const int index, SDPInfo *sdp, payloadVector payload_vec, bool isSipSdp, int alt_id, bool alt_def_id)
24 {
25
26 const char *current_start = buff; //Pointer to the beginning of the media text
27 const char *end = buff + index; //Pointer to the end of the media text
28 const char *line_start_ptr, *line_end_ptr;
29 bool framesize_found_in_fmtp = false;
30 bool framesize_found = false;
31 int fmtp_cnt = 0;
32
33 bool altMedia = false;
34 if (!alt_id || (alt_def_id == true))
35 altMedia = false;
36 else
37 altMedia = true;
38
39 void *memory = sdp->alloc(sizeof(h263_mediaInfo), altMedia);
40 if (NULL == memory)
41 {
42 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Memory allocation failure"));
43 return SDP_NO_MEMORY;
44 }
45 else
46 {
47 h263_mediaInfo *h263V = OSCL_PLACEMENT_NEW(memory, h263_mediaInfo());
48
49 h263V->setMediaInfoID(sdp->getMediaObjectIndex());
50
51 // Allocate memory to the payload specific objects
52 for (uint32 ii = 0; ii < payload_vec.size(); ii++)
53 {
54 void* mem = h263V->alloc(sizeof(H263PayloadSpecificInfoType));
55 if (mem == NULL)
56 {
57 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Memory allocation failure"));
58 return SDP_NO_MEMORY;
59 }
60 else
61 {
62 H263PayloadSpecificInfoType* h263Payload = OSCL_PLACEMENT_NEW(mem, H263PayloadSpecificInfoType(payload_vec[ii]));
63 (void) h263Payload;
64 }
65 }
66
67
68 if (alt_id && !alt_def_id)
69 {
70 sdp->copyFmDefMedia(h263V);
71 //empty alternate & default track ID vectors.
72 h263V->resetAlternateTrackId();
73 h263V->resetDependentTrackId();
74
75 }
76
77 SDP_ERROR_CODE status = baseMediaInfoParser(buff, h263V, index, alt_id, alt_def_id, isSipSdp);
78 if (status != SDP_SUCCESS)
79 {
80 return status;
81 }
82
83 while (get_next_line(current_start, end,
84 line_start_ptr, line_end_ptr))
85 {
86 switch (*line_start_ptr)
87 {
88 case 'a':
89 {
90 if ((!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))) && (alt_def_id == false))
91 {
92 line_start_ptr += oscl_strlen("a=alt:");
93 for (; *line_start_ptr != ':'; line_start_ptr++);
94 line_start_ptr = line_start_ptr + 1;
95 }
96 if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:")))
97 {
98 const char *tmp_start_line, *tmp_end_line;
99
100 fmtp_cnt++ ;
101
102 tmp_start_line = line_start_ptr + oscl_strlen("a=fmtp:");
103 tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
104 if (tmp_start_line >= line_end_ptr)
105 {
106 break;
107 }
108 tmp_end_line = skip_to_whitespace(tmp_start_line, line_end_ptr);
109 if (tmp_end_line < tmp_start_line)
110 {
111 break;
112 }
113 uint32 payloadNumber;
114 if (PV_atoi(tmp_start_line, 'd', tmp_end_line - tmp_start_line, payloadNumber) == false)
115 {
116 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad payload number"));
117 return SDP_BAD_MEDIA_FMTP;
118 }
119 else
120 {
121 int p;
122 if (!h263V->lookupPayloadNumber(payloadNumber, p))
123 {
124 fmtp_cnt--;
125 break;
126 }
127 }
128
129 // payloadNumber is present in the mediaInfo. get the payload
130 // Specific pointer corresponding to this payload
131 H263PayloadSpecificInfoType* payloadPtr =
132 (H263PayloadSpecificInfoType*)h263V->getPayloadSpecificInfoTypePtr(payloadNumber);
133 if (payloadPtr == NULL)
134 {
135 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Unable to find payload pointer for payload"));
136 return SDP_PAYLOAD_MISMATCH;
137 }
138
139 PVMF_SDP_PARSER_LOGINFO((0, "SDPH263MediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNumber));
140
141 tmp_start_line = tmp_end_line + 1;
142 tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
143 if (tmp_start_line >= line_end_ptr)
144 {
145 break;
146 }
147 int ii = 0;
148 const char *temp = tmp_start_line;
149 for (ii = 0; ii < (line_end_ptr - tmp_start_line); ii++)
150 {
151 if ((tmp_start_line[ii] == ';') || (ii == (line_end_ptr - tmp_start_line) - 1))
152 {
153 tmp_end_line = tmp_start_line + ii;
154 if (ii == (line_end_ptr - tmp_start_line) - 1)
155 {
156 tmp_end_line += 1;
157 }
158 if (!oscl_strncmp(temp, "profile=", oscl_strlen("profile=")))
159 {
160 temp += oscl_strlen("profile=");
161 temp = skip_whitespace(temp, tmp_end_line);
162 if (temp > tmp_end_line)
163 {
164 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad profile= field"));
165 return SDP_BAD_MEDIA_FMTP;
166 }
167 uint32 cp;
168 if (PV_atoi(temp, 'd', (tmp_end_line - temp), cp) == true)
169 payloadPtr->setCodecProfile(cp);
170 }
171 if (!oscl_strncmp(temp, "level=", oscl_strlen("level=")))
172 {
173 temp += oscl_strlen("level=");
174 temp = skip_whitespace(temp, tmp_end_line);
175 if (temp > tmp_end_line)
176 {
177 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad level= field"));
178 return SDP_BAD_MEDIA_FMTP;
179 }
180 uint32 cl;
181 if (PV_atoi(temp, 'd', (tmp_end_line - temp), cl) == true)
182 payloadPtr->setCodecLevel(cl);
183 }
184 if (!oscl_strncmp(temp, "framesize=", oscl_strlen("framesize=")))
185 {
186 framesize_found_in_fmtp = true;
187 temp += oscl_strlen("framesize=");
188 temp = skip_whitespace(temp, tmp_end_line);
189 if (temp > tmp_end_line)
190 {
191 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad framesize= field"));
192 return SDP_BAD_MEDIA_FMTP;
193 }
194 const char *end = NULL;
195 int idx = 0;
196 for (idx = 0; idx < (tmp_end_line - temp); idx++)
197 {
198 if (temp[idx] == '-')
199 {
200 end = temp + idx;
201 }
202 }
203 if (end == NULL)
204 {
205 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - frame width missing"));
206 return SDP_MISSING_MEDIA_DESCRIPTION;
207 }
208 uint32 width;
209 if (PV_atoi(temp, 'd', (end - temp), width) == true)
210 {
211 payloadPtr->setFrameWidth(width);
212 }
213 temp = end + 1;
214 temp = skip_whitespace(temp, tmp_end_line);
215 if (temp > tmp_end_line)
216 {
217 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - frame height missing"));
218 return SDP_BAD_MEDIA_FMTP;
219 }
220 uint32 height;
221 if (PV_atoi(temp, 'd', (tmp_end_line - temp), height) == true)
222 {
223 payloadPtr->setFrameHeight(height);
224 }
225 }
226 if (!oscl_strncmp(temp, "decode_buf=", oscl_strlen("decode_buf=")))
227 {
228 temp += oscl_strlen("decode_buf=");
229 temp = skip_whitespace(temp, tmp_end_line);
230 if (temp > tmp_end_line)
231 {
232 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad decode_buf= field"));
233 return SDP_BAD_MEDIA_FMTP;
234 }
235 uint32 decode_buf;
236 if (PV_atoi(temp, 'd', (tmp_end_line - temp), decode_buf) == true)
237 payloadPtr->setMaxBufferSize(decode_buf);
238 }
239 if (tmp_end_line != line_end_ptr) temp = tmp_end_line + 1;
240 temp = skip_whitespace(temp, line_end_ptr);
241 if (temp >= line_end_ptr)
242 {
243 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format"));
244 return SDP_BAD_MEDIA_FMTP;
245 }
246 }
247 }
248 } // end a=fmtp
249 StrPtrLen fmsize("a=framesize:");
250 if (!oscl_strncmp(line_start_ptr, fmsize.c_str(), fmsize.length()))
251 {
252 uint32 width, height;
253 const char *sptr = line_start_ptr + fmsize.length();
254 const char *eptr = skip_to_whitespace(sptr, line_end_ptr);
255
256 if (sptr > eptr)
257 {
258 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format"));
259 return SDP_BAD_MEDIA_FRAMESIZE;
260 }
261 uint32 payloadNo;
262 if (PV_atoi(sptr, 'd', (eptr - sptr), payloadNo))
263 {
264 int p;
265 if (!h263V->lookupPayloadNumber(payloadNo, p))
266 break;
267 }
268 else
269 {
270 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - bad payload number"));
271 return SDP_BAD_MEDIA_FRAMESIZE;
272 }
273
274 framesize_found = true;
275
276 // payloadNumber is present in the mediaInfo. get the payload
277 // Specific pointer corresponding to this payload
278 H263PayloadSpecificInfoType* payloadPtr2 =
279 (H263PayloadSpecificInfoType*)h263V->getPayloadSpecificInfoTypePtr(payloadNo);
280 if (payloadPtr2 == NULL)
281 {
282 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize - unable to find payload pointer for the payload"));
283 return SDP_PAYLOAD_MISMATCH;
284 }
285
286 PVMF_SDP_PARSER_LOGINFO((0, "SDPH263MediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNo));
287
288 sptr = eptr;
289 sptr = skip_whitespace(sptr , line_end_ptr);
290
291 for (; *eptr != '-' ; ++eptr);
292
293 if (!PV_atoi(sptr, 'd', eptr - sptr, width))
294 {
295 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - bad width factor"));
296 return SDP_BAD_MEDIA_FRAMESIZE ;
297 }
298
299 eptr = eptr + 1;
300 sptr = eptr;
301 if (sptr > line_end_ptr)
302 {
303 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format"));
304 return SDP_BAD_MEDIA_FRAMESIZE;
305 }
306 eptr = skip_to_whitespace(sptr, line_end_ptr);
307 if (!PV_atoi(sptr, 'd', eptr - sptr, height))
308 {
309 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - Bad height factor"));
310 return SDP_BAD_MEDIA_FRAMESIZE;
311 }
312 if (framesize_found_in_fmtp)
313 {
314 if ((int)width != payloadPtr2->getFrameWidth() || (int)height != payloadPtr2->getFrameHeight())
315 {
316 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - frame width & height mis match"));
317 return SDP_BAD_MEDIA_FRAMESIZE;
318 }
319
320 }
321 else
322 {
323 payloadPtr2->setFrameWidth(width);
324 payloadPtr2->setFrameHeight(height);
325 }
326 }
327
328 }
329 break;
330 default:
331 {
332 }
333 break;
334 }
335 current_start = line_end_ptr;
336 }
337
338 sessionDescription *session = sdp->getSessionInfo();
339
340 const char *altGroupBW = session->getAltGroupBW();
341 int length = session->getAltGroupBWLength();
342
343 if (length > 0)
344 {
345 status = setDependentMediaId(altGroupBW, length, h263V, alt_id);
346 if (status != SDP_SUCCESS)
347 return SDP_BAD_MEDIA_ALT_ID;
348 }
349
350 const char *altGroupLANG = session->getAltGroupLANG();
351 length = session->getAltGroupLANGLength();
352
353 if (length > 0)
354 {
355 status = setDependentMediaId(altGroupLANG, length, h263V, alt_id);
356 if (status != SDP_SUCCESS)
357 return SDP_BAD_MEDIA_ALT_ID;
358 }
359
360 if ((h263V->getCFieldStatus() || session->getCFieldStatus()))
361 {
362 //if sample rate is zero override with defaults
363 Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector =
364 h263V->getPayloadSpecificInfoVector();
365 for (int ii = 0; ii < (int)payloadSpecificInfoVector.size(); ii++)
366 {
367 if (payloadSpecificInfoVector[ii]->getSampleRate() == 0)
368 {
369 payloadSpecificInfoVector[ii]->sampleRate =
370 PVMF_SDP_DEFAULT_H263_SAMPLE_RATE;
371 }
372 }
373 return SDP_SUCCESS;
374 }
375 else
376 {
377 PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - no c field"));
378 return SDP_FAILURE_NO_C_FIELD;
379 }
380 }
381
382
383 }
384