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 "evrc_media_info_parser.h" 19 #include "oscl_string_utils.h" 20 #include "oscl_string_containers.h" 21 22 SDP_ERROR_CODE 23 SDPEVRCMediaInfoParser::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 int fmtp_cnt = 0; 30 31 bool altMedia = false; 32 if (!alt_id || (alt_def_id == true)) 33 altMedia = false; 34 else 35 altMedia = true; 36 37 void *memory = sdp->alloc(sizeof(evrc_mediaInfo), altMedia); 38 if (NULL == memory) 39 { 40 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Memory allocation failure")); 41 return SDP_NO_MEMORY; 42 } 43 else 44 { 45 evrc_mediaInfo *evrcA = OSCL_PLACEMENT_NEW(memory, evrc_mediaInfo()); 46 47 evrcA->setMediaInfoID(sdp->getMediaObjectIndex()); 48 49 // Allocate memory to the payload specific objects 50 for (uint32 ii = 0; ii < payload_vec.size(); ii++) 51 { 52 void* mem = evrcA->alloc(sizeof(EvrcPayloadSpecificInfoType)); 53 if (mem == NULL) 54 { 55 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Memory allocation failure")); 56 return SDP_NO_MEMORY; 57 } 58 else 59 { 60 EvrcPayloadSpecificInfoType* evrcPayload = OSCL_PLACEMENT_NEW(mem, EvrcPayloadSpecificInfoType(payload_vec[ii])); 61 (void) evrcPayload; 62 } 63 } 64 65 66 if (alt_id && !alt_def_id) 67 { 68 sdp->copyFmDefMedia(evrcA); 69 //empty alternate & default track ID vectors. 70 evrcA->resetAlternateTrackId(); 71 evrcA->resetDependentTrackId(); 72 } 73 74 SDP_ERROR_CODE status = baseMediaInfoParser(buff, evrcA, index, alt_id, alt_def_id, isSipSdp); 75 if (status != SDP_SUCCESS) 76 { 77 return status; 78 } 79 80 81 while (get_next_line(current_start, end, 82 line_start_ptr, line_end_ptr)) 83 { 84 switch (*line_start_ptr) 85 { 86 case 'a': 87 { 88 const char *sptr; 89 if ((!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))) && (alt_def_id == false)) 90 { 91 line_start_ptr += oscl_strlen("a=alt:"); 92 for (; *line_start_ptr != ':'; line_start_ptr++); 93 line_start_ptr = line_start_ptr + 1; 94 } 95 if (!oscl_strncmp(line_start_ptr, "a=lang:", oscl_strlen("a=lang:"))) 96 { 97 sptr = line_start_ptr + oscl_strlen("a=lang:"); 98 sptr = skip_whitespace(sptr, line_end_ptr); 99 if (sptr >= line_end_ptr) 100 { 101 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=lang line format")); 102 return SDP_BAD_MEDIA_LANG_FIELD; 103 } 104 OsclMemoryFragment memFrag; 105 memFrag.ptr = (void*)sptr; 106 memFrag.len = (line_end_ptr - sptr); 107 ((evrc_mediaInfo*)evrcA)->setLang(memFrag); 108 } 109 if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:"))) 110 { 111 const char *tmp_start_line, *tmp_end_line; 112 fmtp_cnt++ ; 113 114 tmp_start_line = line_start_ptr + oscl_strlen("a=fmtp:"); 115 tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr); 116 if (tmp_start_line >= line_end_ptr) 117 { 118 break; 119 } 120 tmp_end_line = skip_to_whitespace(tmp_start_line, line_end_ptr); 121 if (tmp_end_line < tmp_start_line) 122 { 123 break; 124 } 125 uint32 payloadNumber; 126 if (PV_atoi(tmp_start_line, 'd', tmp_end_line - tmp_start_line, payloadNumber) == false) 127 { 128 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - payload number incorrect")); 129 return SDP_BAD_MEDIA_FMTP; 130 } 131 else 132 { 133 int p; 134 if (!evrcA->lookupPayloadNumber(payloadNumber, p)) 135 { 136 fmtp_cnt--; 137 break; 138 } 139 } 140 141 // payloadNumber is present in the mediaInfo. get the payload 142 // Specific pointer corresponding to this payload 143 EvrcPayloadSpecificInfoType* payloadPtr = 144 (EvrcPayloadSpecificInfoType*)evrcA->getPayloadSpecificInfoTypePtr(payloadNumber); 145 if (payloadPtr == NULL) 146 { 147 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - payload pointer not found for payload")); 148 return SDP_PAYLOAD_MISMATCH; 149 } 150 151 PVMF_SDP_PARSER_LOGINFO((0, "SDPEvrcMediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNumber)); 152 153 tmp_start_line = tmp_end_line + 1; 154 tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr); 155 if (tmp_start_line >= line_end_ptr) 156 { 157 break; 158 } 159 const char *temp = tmp_start_line; 160 int ii = 0; 161 for (ii = 0; ii < (line_end_ptr - tmp_start_line); ii++) 162 { 163 if ((tmp_start_line[ii] == ';') || (ii == (line_end_ptr - tmp_start_line - 1))) 164 { 165 tmp_end_line = tmp_start_line + ii; 166 if (ii == (line_end_ptr - tmp_start_line - 1)) 167 { 168 tmp_end_line += 1; 169 } 170 if (!oscl_strncmp(temp, "maxframes=", oscl_strlen("maxframes="))) 171 { 172 temp += oscl_strlen("maxframes="); 173 temp = skip_whitespace(temp, tmp_end_line); 174 if (temp >= tmp_end_line) 175 { 176 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - maxframes= field incorrect")); 177 return SDP_BAD_MEDIA_FMTP; 178 } 179 uint32 maxFrames; 180 if (PV_atoi(temp, 'd', (tmp_end_line - temp), maxFrames) == true) 181 payloadPtr->setMaximumFrames(maxFrames); 182 } 183 if (!oscl_strncmp(temp, "maxbundles=", oscl_strlen("maxbundles="))) 184 { 185 temp += oscl_strlen("maxbundles="); 186 temp = skip_whitespace(temp, tmp_end_line); 187 if (temp >= tmp_end_line) 188 { 189 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - maxbundles= field incorrect")); 190 return SDP_BAD_MEDIA_FMTP; 191 } 192 uint32 maxBundles; 193 if (PV_atoi(temp, 'd', (tmp_end_line - temp), maxBundles) == true) 194 payloadPtr->setMaximumBundle(maxBundles); 195 } 196 if (!oscl_strncmp(temp, "ptime=", oscl_strlen("ptime="))) 197 { 198 temp += oscl_strlen("ptime="); 199 temp = skip_whitespace(temp, tmp_end_line); 200 if (temp >= tmp_end_line) 201 { 202 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad ptime= field")); 203 return SDP_BAD_MEDIA_FMTP; 204 } 205 uint32 ptime; 206 if (PV_atoi(temp, 'd', (tmp_end_line - temp), ptime) == true) 207 payloadPtr->setPacketTime(ptime); 208 } 209 if (!oscl_strncmp(temp, "decode_buf=", oscl_strlen("decode_buf="))) 210 { 211 temp += oscl_strlen("decode_buf="); 212 temp = skip_whitespace(temp, tmp_end_line); 213 if (temp >= tmp_end_line) 214 { 215 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad decode_buf= field")); 216 return SDP_BAD_MEDIA_FMTP; 217 } 218 uint32 decode_buf; 219 if (PV_atoi(temp, 'd', (tmp_end_line - temp), decode_buf) == true) 220 payloadPtr->setMaxBufferSize(decode_buf); 221 } 222 if (tmp_end_line != line_end_ptr) temp = tmp_end_line + 1; 223 temp = skip_whitespace(temp, line_end_ptr); 224 if (temp >= line_end_ptr) 225 { 226 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Bad a=fmtp line format")); 227 return SDP_BAD_MEDIA_FMTP; 228 } 229 } 230 } 231 } 232 } 233 break; 234 default: 235 { 236 } 237 break; 238 } 239 current_start = line_end_ptr; 240 } 241 242 243 sessionDescription *session = sdp->getSessionInfo(); 244 245 const char *altGroupBW = session->getAltGroupBW(); 246 int length = session->getAltGroupBWLength(); 247 248 if (length > 0) 249 { 250 status = setDependentMediaId(altGroupBW, length, evrcA, alt_id); 251 if (status != SDP_SUCCESS) 252 return SDP_BAD_MEDIA_ALT_ID; 253 } 254 255 const char *altGroupLANG = session->getAltGroupLANG(); 256 length = session->getAltGroupLANGLength(); 257 258 if (length > 0) 259 { 260 status = setDependentMediaId(altGroupLANG, length, evrcA, alt_id); 261 if (status != SDP_SUCCESS) 262 return SDP_BAD_MEDIA_ALT_ID; 263 } 264 265 if (fmtp_cnt != evrcA->getMediaPayloadNumberCount()) 266 { 267 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - Number of payloads present in m= segment does not match number of a=ftmp field count")); 268 return SDP_PAYLOAD_MISMATCH; 269 } 270 271 if (evrcA->getCFieldStatus() || session->getCFieldStatus()) 272 { 273 //if sample rate is zero override with defaults 274 Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector = 275 evrcA->getPayloadSpecificInfoVector(); 276 for (int ii = 0; ii < (int)payloadSpecificInfoVector.size(); ii++) 277 { 278 if (payloadSpecificInfoVector[ii]->getSampleRate() == 0) 279 { 280 payloadSpecificInfoVector[ii]->sampleRate = 281 PVMF_SDP_DEFAULT_EVRC_SAMPLE_RATE; 282 } 283 } 284 return SDP_SUCCESS; 285 } 286 else 287 { 288 PVMF_SDP_PARSER_LOGERROR((0, "SDPEVRCMediaInfoParser::parseMediaInfo - c field not present")); 289 return SDP_FAILURE_NO_C_FIELD; 290 } 291 292 } 293 294 295 } 296