• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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