• 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 "aac_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 SDPAACMediaInfoParser::parseMediaInfo(const char *buff,
24                                       const int index,
25                                       SDPInfo *sdp,
26                                       payloadVector payload_vec,
27                                       bool isSipSdp,
28                                       int alt_id,
29                                       bool alt_def_id)
30 {
31     const char *current_start = buff; //Pointer to the beginning of the media text
32     const char *end = buff + index;   //Pointer to the end of the media text
33     const char *line_start_ptr, *line_end_ptr;
34     int decLength = 0;
35     int fmtp_cnt = 0;
36     SDPAllocDestructDealloc<uint8> SDP_alloc;
37 
38     while (get_next_line(current_start, end,
39                          line_start_ptr, line_end_ptr))
40     {
41         if ((!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))) && (alt_def_id == false))
42         {
43             line_start_ptr += oscl_strlen("a=alt:");
44             for (; *line_start_ptr != ':'; line_start_ptr++);
45             line_start_ptr = line_start_ptr + 1;
46         }
47 
48         if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:")))
49         {
50 
51             const char *tmp_start_line, *tmp_end_line;
52 
53             fmtp_cnt++;
54 
55             tmp_start_line = line_start_ptr + oscl_strlen("a=fmtp:");
56             tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
57             if (tmp_start_line >= line_end_ptr)
58             {
59                 break;
60             }
61             tmp_end_line = skip_to_whitespace(tmp_start_line, line_end_ptr);
62             if (tmp_end_line < tmp_start_line)
63             {
64                 break;
65             }
66             tmp_start_line = tmp_end_line + 1;
67             tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
68             if (tmp_start_line >= line_end_ptr)
69             {
70                 break;
71             }
72             int ii = 0;
73             const char *temp = tmp_start_line;
74             for (ii = 0; ii < (line_end_ptr - tmp_start_line) ; ii++)
75             {
76                 if ((tmp_start_line[ii] == ';') || (ii == (line_end_ptr - tmp_start_line - 1)))
77                 {
78                     tmp_end_line = tmp_start_line + ii;
79                     if ((line_end_ptr - tmp_start_line - 1) == ii)
80                     {
81                         tmp_end_line++;
82                     }
83 
84                     if (!oscl_strncmp(temp, "config=", oscl_strlen("config=")))
85                     {
86                         uint32 currentLength;
87                         temp += oscl_strlen("config=");
88                         temp = skip_whitespace(temp, line_end_ptr);
89                         if (temp >= line_end_ptr)
90                         {
91                             PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - no data in config= field"));
92                             return SDP_BAD_MEDIA_FMTP;
93                         }
94                         currentLength = (int)(tmp_end_line - temp) / 2;
95 
96                         if (decLength < (int) currentLength)
97 
98                             decLength = currentLength;
99                     }
100                     if (tmp_end_line != line_end_ptr) temp = tmp_end_line + 1;
101                     temp = skip_whitespace(temp, line_end_ptr);
102                     if (temp >= line_end_ptr)
103                     {
104                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - Format in a=fmtp line is incorrect"));
105                         return SDP_BAD_MEDIA_FMTP;
106                     }
107                 }
108             }
109         }
110         current_start = line_end_ptr + 1;
111     }
112 
113     if (fmtp_cnt == 0)  // a=fmtp field not found
114     {
115         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp field not found"));
116         return SDP_FAILURE_NO_FMTP_FIELD;
117     }
118 
119     bool altMedia = false;
120     if (!alt_id || (alt_def_id == true))
121         altMedia = false;
122     else
123         altMedia = true;
124 
125     //Allocate media info class here
126     void *memory = sdp->alloc(sizeof(aac_mediaInfo), altMedia);
127     if (NULL == memory)
128     {
129         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - unable to allocate memory to media parser"));
130         return SDP_NO_MEMORY;
131     }
132     else
133     {
134         aac_mediaInfo *aacA = OSCL_PLACEMENT_NEW(memory, aac_mediaInfo());
135 
136         aacA->setMediaInfoID(sdp->getMediaObjectIndex());
137 
138         // Allocate memory to the payload specific objects
139         for (uint32 ii = 0; ii < payload_vec.size(); ii++)
140         {
141             void* mem = aacA->alloc(sizeof(AacPayloadSpecificInfoType));
142             if (mem == NULL)
143             {
144                 return SDP_NO_MEMORY;
145             }
146             else
147             {
148                 OSCL_PLACEMENT_NEW(mem, AacPayloadSpecificInfoType(payload_vec[ii]));
149             }
150         }
151 
152 
153         if (alt_id && !alt_def_id)
154         {
155             sdp->copyFmDefMedia(aacA);
156             aacA->resetAlternateTrackId();
157             aacA->resetDependentTrackId();
158         }
159 
160         SDP_ERROR_CODE status = baseMediaInfoParser(buff, aacA, index, alt_id, alt_def_id, isSipSdp);
161         if (status != SDP_SUCCESS)
162         {
163             return status;
164         }
165 
166 
167         current_start = buff;
168 
169         while (get_next_line(current_start, end,
170                              line_start_ptr, line_end_ptr))
171         {
172             switch (*line_start_ptr)
173             {
174                 case 'a':
175                 {
176                     const char *sptr;
177                     if ((!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))) && (alt_def_id == false))
178                     {
179                         line_start_ptr += oscl_strlen("a=alt:");
180                         for (; *line_start_ptr != ':'; line_start_ptr++);
181                         line_start_ptr = line_start_ptr + 1;
182                     }
183                     if (!oscl_strncmp(line_start_ptr, "a=lang:", oscl_strlen("a=lang:")))
184                     {
185                         sptr = line_start_ptr + oscl_strlen("a=lang:");
186                         sptr = skip_whitespace(sptr, line_end_ptr);
187                         if (sptr >= line_end_ptr)
188                         {
189                             PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=lang field incorrect"));
190                             return SDP_BAD_MEDIA_LANG_FIELD;
191                         }
192                         OsclMemoryFragment memFrag;
193                         memFrag.ptr = (void*)sptr;
194                         memFrag.len = (line_end_ptr - sptr);
195 
196                         ((aac_mediaInfo*)aacA)->setLang(memFrag);
197                     }
198                     if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:")))
199                     {
200                         const char *tmp_start_line, *tmp_end_line;
201                         tmp_start_line = line_start_ptr + oscl_strlen("a=fmtp:");
202                         tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
203                         if (tmp_start_line >= line_end_ptr)
204                         {
205                             break;
206                         }
207                         tmp_end_line = skip_to_whitespace(tmp_start_line, line_end_ptr);
208                         if (tmp_end_line < tmp_start_line)
209                         {
210                             break;
211                         }
212                         uint32 payloadNumber;
213                         if (PV_atoi(tmp_start_line, 'd', (tmp_end_line - tmp_start_line), payloadNumber) == false)
214                         {
215                             PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp field format is incorrect"));
216                             return SDP_BAD_MEDIA_FMTP;
217                         }
218                         else
219                         {
220                             int p;
221                             if (!aacA->lookupPayloadNumber(payloadNumber, p))
222                             {
223                                 fmtp_cnt--;
224                                 break;
225                             }
226                         }
227                         // payloadNumber is present in the mediaInfo. get the payload
228                         // Specific pointer corresponding to this payload
229                         AacPayloadSpecificInfoType* payloadPtr =
230                             (AacPayloadSpecificInfoType*)aacA->getPayloadSpecificInfoTypePtr(payloadNumber);
231 
232                         PVMF_SDP_PARSER_LOGINFO((0, "SDPAacMediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNumber));
233 
234                         tmp_start_line = tmp_end_line + 1;
235                         tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr);
236                         if (tmp_start_line >= line_end_ptr)
237                         {
238                             break;
239                         }
240                         int ii = 0;
241                         const char *temp = tmp_start_line;
242                         for (ii = 0; ii < (line_end_ptr - tmp_start_line) ; ii++)
243                         {
244                             if ((tmp_start_line[ii] == ';') || (ii == (line_end_ptr - tmp_start_line - 1)))
245                             {
246                                 tmp_end_line = tmp_start_line + ii;
247                                 if (ii == (line_end_ptr - tmp_start_line - 1))
248                                 {
249                                     tmp_end_line += 1;
250                                 }
251 
252                                 if (!oscl_strncmp(temp, "config=", oscl_strlen("config=")))
253                                 {
254 
255                                     uint8 *mptr = SDP_alloc.allocate(decLength);
256                                     OsclRefCounterSA< SDPAllocDestructDealloc<uint8> > *refcnt = new OsclRefCounterSA< SDPAllocDestructDealloc<uint8> >(mptr);
257                                     OsclSharedPtr<uint8> decInfo(mptr, refcnt);
258 
259                                     temp += oscl_strlen("config=");
260                                     temp = skip_whitespace(temp, line_end_ptr);
261                                     if (temp >= line_end_ptr)
262                                     {
263                                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp field format is incorrect for config= field"));
264                                         return SDP_BAD_MEDIA_FMTP;
265                                     }
266                                     decLength = (int)(tmp_end_line - temp) / 2;
267                                     int idx = 0;
268                                     for (idx = 0; idx < decLength; idx++)
269                                     {
270                                         uint32 val;
271                                         if (PV_atoi((temp + 2*idx), 'x', 2, val) == false)
272                                         {
273                                             PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp field format is incorrect for config= field"));
274                                             return SDP_BAD_MEDIA_FMTP;
275                                         }
276 
277                                         *(decInfo + idx) = (uint8) val;
278                                     }
279 
280                                     if (payloadPtr)
281                                     {
282                                         payloadPtr->setDecoderSpecificInfo(decInfo);
283                                         payloadPtr->setDecoderSpecificInfoSize(decLength);
284                                     }
285                                     else
286                                     {
287                                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp field format is incorrect for payload"));
288                                         return SDP_PAYLOAD_MISMATCH;
289                                     }
290                                 }
291 
292                                 // add code for cpresent flag
293                                 if (!oscl_strncmp(temp, "cpresent=", oscl_strlen("cpresent=")))
294                                 {
295                                     temp += oscl_strlen("cpresent=");
296                                     temp = skip_whitespace(temp, line_end_ptr);
297                                     if (temp > line_end_ptr)
298                                     {
299                                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp format is incorrect for cpresent= field"));
300                                         return SDP_BAD_MEDIA_FMTP;
301                                     }
302                                     uint32 cpresent; //Assuming that the possible values are either 0 or 1
303                                     if (PV_atoi(temp, 'd', tmp_end_line - temp, cpresent) == true)
304                                     {
305                                         if (payloadPtr)
306                                             payloadPtr->setcpresent(cpresent ? true : false);
307                                         else
308                                             return SDP_PAYLOAD_MISMATCH;
309                                     }
310                                 }
311                                 if (!oscl_strncmp(temp, "SBR-enabled=", oscl_strlen("SBR-enabled=")))
312                                 {
313                                     temp += oscl_strlen("SBR-enabled=");
314                                     temp = skip_whitespace(temp, line_end_ptr);
315                                     if (temp > line_end_ptr)
316                                     {
317                                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp format is incorrect for SBR-enabled= field"));
318                                         return SDP_BAD_MEDIA_FORMAT;
319                                     }
320                                     uint32 sbrEn; //Assuming that the possible values are either 0 or 1
321                                     if (PV_atoi(temp, 'd', tmp_end_line - temp, sbrEn) == true)
322                                     {
323                                         if (payloadPtr)
324                                             payloadPtr->setAACplusSBRenabled(sbrEn ? true : false);
325                                         else
326                                             return SDP_PAYLOAD_MISMATCH;
327                                     }
328                                 }
329 
330 
331                                 if (!oscl_strncmp(temp, "decode_buf=", oscl_strlen("decode_buf=")))
332                                 {
333                                     temp += oscl_strlen("decode_buf=");
334                                     temp = skip_whitespace(temp, tmp_end_line);
335                                     if (temp > tmp_end_line)
336                                     {
337                                         PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp format is incorrect for decode_buf= field"));
338                                         return SDP_BAD_MEDIA_FORMAT;
339                                     }
340                                     uint32 dec;
341                                     if (PV_atoi(temp, 'd', tmp_end_line - temp, dec) == true)
342                                     {
343                                         if (payloadPtr)
344                                             payloadPtr->setMaxBufferSize(dec);
345                                         else
346                                             return SDP_PAYLOAD_MISMATCH;
347                                     }
348                                 }
349 
350                                 if (tmp_end_line != line_end_ptr) temp = tmp_end_line + 1;
351                                 temp = skip_whitespace(temp, line_end_ptr);
352                                 if (temp >= line_end_ptr)
353                                 {
354                                     PVMF_SDP_PARSER_LOGERROR((0, "SDPAACMediaInfoParser::parseMediaInfo - a=fmtp format is bad"));
355                                     return SDP_BAD_MEDIA_FORMAT;
356                                 }
357                             }
358                         }
359                     }
360                 }
361                 break;
362                 default:
363                     break;
364             }
365             current_start = line_end_ptr;
366         }
367 
368 
369         sessionDescription *session = sdp->getSessionInfo();
370 
371         const char *altGroupBW = session->getAltGroupBW();
372         int length = session->getAltGroupBWLength();
373 
374         if (length > 0)
375         {
376             status = setDependentMediaId(altGroupBW, length, aacA, alt_id);
377             if (status != SDP_SUCCESS)
378                 return SDP_BAD_MEDIA_ALT_ID;
379         }
380 
381         const char *altGroupLANG = session->getAltGroupLANG();
382         length = session->getAltGroupLANGLength();
383 
384         if (length > 0)
385         {
386             status = setDependentMediaId(altGroupLANG, length, aacA, alt_id);
387             if (status != SDP_SUCCESS)
388                 return SDP_BAD_MEDIA_ALT_ID;
389         }
390 
391         if (aacA->getCFieldStatus() || session->getCFieldStatus())
392         {
393             //if sample rate is zero override with defaults
394             Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector =
395                 aacA->getPayloadSpecificInfoVector();
396             for (int ii = 0; ii < (int)payloadSpecificInfoVector.size(); ii++)
397             {
398                 if (payloadSpecificInfoVector[ii]->getSampleRate() == 0)
399                 {
400                     payloadSpecificInfoVector[ii]->sampleRate =
401                         PVMF_SDP_DEFAULT_LATM_SAMPLE_RATE;
402                 }
403             }
404             return SDP_SUCCESS;
405         }
406         else
407         {
408             return SDP_FAILURE_NO_C_FIELD;
409         }
410     }
411 }
412 
413