| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| /* */ |
| /* ===================================================================== */ |
| /* File: h263MediaInfoParser.cpp */ |
| /* Description: */ |
| /* */ |
| /* */ |
| /* Rev: */ |
| /* Created: 05/24/01 */ |
| /* ===================================================================== */ |
| /* */ |
| /* Revision History: */ |
| /* */ |
| /* Rev: */ |
| /* Date: */ |
| /* Description: */ |
| /* */ |
| /* //////////////////////////////////////////////////////////////////////// */ |
| |
| #include "h263_media_info_parser.h" |
| #include "oscl_string_utils.h" |
| #include "oscl_string_containers.h" |
| |
| /* ======================================================================== */ |
| /* Function : parsePayload(char *buff, mediaInfo* h263V,int index) */ |
| /* Date : 05/24/2001 */ |
| /* Purpose : Parses H263 text and fills out the h263 media structure */ |
| /* In/out : */ |
| /* Return : */ |
| /* Modified : */ |
| /* ======================================================================== */ |
| SDP_ERROR_CODE |
| SDPH263MediaInfoParser::parseMediaInfo(const char *buff, const int index, SDPInfo *sdp, payloadVector payload_vec, bool isSipSdp, int alt_id, bool alt_def_id) |
| { |
| |
| const char *current_start = buff; //Pointer to the beginning of the media text |
| const char *end = buff + index; //Pointer to the end of the media text |
| const char *line_start_ptr, *line_end_ptr; |
| bool framesize_found_in_fmtp = false; |
| bool framesize_found = false; |
| int fmtp_cnt = 0; |
| |
| bool altMedia = false; |
| if (!alt_id || (alt_def_id == true)) |
| altMedia = false; |
| else |
| altMedia = true; |
| |
| void *memory = sdp->alloc(sizeof(h263_mediaInfo), altMedia); |
| if (NULL == memory) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Memory allocation failure")); |
| return SDP_NO_MEMORY; |
| } |
| else |
| { |
| h263_mediaInfo *h263V = OSCL_PLACEMENT_NEW(memory, h263_mediaInfo()); |
| |
| h263V->setMediaInfoID(sdp->getMediaObjectIndex()); |
| |
| // Allocate memory to the payload specific objects |
| for (uint32 ii = 0; ii < payload_vec.size(); ii++) |
| { |
| void* mem = h263V->alloc(sizeof(H263PayloadSpecificInfoType)); |
| if (mem == NULL) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Memory allocation failure")); |
| return SDP_NO_MEMORY; |
| } |
| else |
| { |
| H263PayloadSpecificInfoType* h263Payload = OSCL_PLACEMENT_NEW(mem, H263PayloadSpecificInfoType(payload_vec[ii])); |
| (void) h263Payload; |
| } |
| } |
| |
| |
| if (alt_id && !alt_def_id) |
| { |
| sdp->copyFmDefMedia(h263V); |
| //empty alternate & default track ID vectors. |
| h263V->resetAlternateTrackId(); |
| h263V->resetDependentTrackId(); |
| |
| } |
| |
| SDP_ERROR_CODE status = baseMediaInfoParser(buff, h263V, index, alt_id, alt_def_id, isSipSdp); |
| if (status != SDP_SUCCESS) |
| { |
| return status; |
| } |
| |
| while (get_next_line(current_start, end, |
| line_start_ptr, line_end_ptr)) |
| { |
| switch (*line_start_ptr) |
| { |
| case 'a': |
| { |
| if ((!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))) && (alt_def_id == false)) |
| { |
| line_start_ptr += oscl_strlen("a=alt:"); |
| for (; *line_start_ptr != ':'; line_start_ptr++); |
| line_start_ptr = line_start_ptr + 1; |
| } |
| if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:"))) |
| { |
| const char *tmp_start_line, *tmp_end_line; |
| |
| fmtp_cnt++ ; |
| |
| tmp_start_line = line_start_ptr + oscl_strlen("a=fmtp:"); |
| tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr); |
| if (tmp_start_line >= line_end_ptr) |
| { |
| break; |
| } |
| tmp_end_line = skip_to_whitespace(tmp_start_line, line_end_ptr); |
| if (tmp_end_line < tmp_start_line) |
| { |
| break; |
| } |
| uint32 payloadNumber; |
| if (PV_atoi(tmp_start_line, 'd', tmp_end_line - tmp_start_line, payloadNumber) == false) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad payload number")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| else |
| { |
| int p; |
| if (!h263V->lookupPayloadNumber(payloadNumber, p)) |
| { |
| fmtp_cnt--; |
| break; |
| } |
| } |
| |
| // payloadNumber is present in the mediaInfo. get the payload |
| // Specific pointer corresponding to this payload |
| H263PayloadSpecificInfoType* payloadPtr = |
| (H263PayloadSpecificInfoType*)h263V->getPayloadSpecificInfoTypePtr(payloadNumber); |
| if (payloadPtr == NULL) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Unable to find payload pointer for payload")); |
| return SDP_PAYLOAD_MISMATCH; |
| } |
| |
| PVMF_SDP_PARSER_LOGINFO((0, "SDPH263MediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNumber)); |
| |
| tmp_start_line = tmp_end_line + 1; |
| tmp_start_line = skip_whitespace(tmp_start_line, line_end_ptr); |
| if (tmp_start_line >= line_end_ptr) |
| { |
| break; |
| } |
| int ii = 0; |
| const char *temp = tmp_start_line; |
| for (ii = 0; ii < (line_end_ptr - tmp_start_line); ii++) |
| { |
| if ((tmp_start_line[ii] == ';') || (ii == (line_end_ptr - tmp_start_line) - 1)) |
| { |
| tmp_end_line = tmp_start_line + ii; |
| if (ii == (line_end_ptr - tmp_start_line) - 1) |
| { |
| tmp_end_line += 1; |
| } |
| if (!oscl_strncmp(temp, "profile=", oscl_strlen("profile="))) |
| { |
| temp += oscl_strlen("profile="); |
| temp = skip_whitespace(temp, tmp_end_line); |
| if (temp > tmp_end_line) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad profile= field")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| uint32 cp; |
| if (PV_atoi(temp, 'd', (tmp_end_line - temp), cp) == true) |
| payloadPtr->setCodecProfile(cp); |
| } |
| if (!oscl_strncmp(temp, "level=", oscl_strlen("level="))) |
| { |
| temp += oscl_strlen("level="); |
| temp = skip_whitespace(temp, tmp_end_line); |
| if (temp > tmp_end_line) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad level= field")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| uint32 cl; |
| if (PV_atoi(temp, 'd', (tmp_end_line - temp), cl) == true) |
| payloadPtr->setCodecLevel(cl); |
| } |
| if (!oscl_strncmp(temp, "framesize=", oscl_strlen("framesize="))) |
| { |
| framesize_found_in_fmtp = true; |
| temp += oscl_strlen("framesize="); |
| temp = skip_whitespace(temp, tmp_end_line); |
| if (temp > tmp_end_line) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad framesize= field")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| const char *end = NULL; |
| int idx = 0; |
| for (idx = 0; idx < (tmp_end_line - temp); idx++) |
| { |
| if (temp[idx] == '-') |
| { |
| end = temp + idx; |
| } |
| } |
| if (end == NULL) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - frame width missing")); |
| return SDP_MISSING_MEDIA_DESCRIPTION; |
| } |
| uint32 width; |
| if (PV_atoi(temp, 'd', (end - temp), width) == true) |
| { |
| payloadPtr->setFrameWidth(width); |
| } |
| temp = end + 1; |
| temp = skip_whitespace(temp, tmp_end_line); |
| if (temp > tmp_end_line) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - frame height missing")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| uint32 height; |
| if (PV_atoi(temp, 'd', (tmp_end_line - temp), height) == true) |
| { |
| payloadPtr->setFrameHeight(height); |
| } |
| } |
| if (!oscl_strncmp(temp, "decode_buf=", oscl_strlen("decode_buf="))) |
| { |
| temp += oscl_strlen("decode_buf="); |
| temp = skip_whitespace(temp, tmp_end_line); |
| if (temp > tmp_end_line) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad decode_buf= field")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| uint32 decode_buf; |
| if (PV_atoi(temp, 'd', (tmp_end_line - temp), decode_buf) == true) |
| payloadPtr->setMaxBufferSize(decode_buf); |
| } |
| if (tmp_end_line != line_end_ptr) temp = tmp_end_line + 1; |
| temp = skip_whitespace(temp, line_end_ptr); |
| if (temp >= line_end_ptr) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=fmtp line format")); |
| return SDP_BAD_MEDIA_FMTP; |
| } |
| } |
| } |
| } // end a=fmtp |
| StrPtrLen fmsize("a=framesize:"); |
| if (!oscl_strncmp(line_start_ptr, fmsize.c_str(), fmsize.length())) |
| { |
| uint32 width, height; |
| const char *sptr = line_start_ptr + fmsize.length(); |
| const char *eptr = skip_to_whitespace(sptr, line_end_ptr); |
| |
| if (sptr > eptr) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format")); |
| return SDP_BAD_MEDIA_FRAMESIZE; |
| } |
| uint32 payloadNo; |
| if (PV_atoi(sptr, 'd', (eptr - sptr), payloadNo)) |
| { |
| int p; |
| if (!h263V->lookupPayloadNumber(payloadNo, p)) |
| break; |
| } |
| else |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - bad payload number")); |
| return SDP_BAD_MEDIA_FRAMESIZE; |
| } |
| |
| framesize_found = true; |
| |
| // payloadNumber is present in the mediaInfo. get the payload |
| // Specific pointer corresponding to this payload |
| H263PayloadSpecificInfoType* payloadPtr2 = |
| (H263PayloadSpecificInfoType*)h263V->getPayloadSpecificInfoTypePtr(payloadNo); |
| if (payloadPtr2 == NULL) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize - unable to find payload pointer for the payload")); |
| return SDP_PAYLOAD_MISMATCH; |
| } |
| |
| PVMF_SDP_PARSER_LOGINFO((0, "SDPH263MediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNo)); |
| |
| sptr = eptr; |
| sptr = skip_whitespace(sptr , line_end_ptr); |
| |
| for (;*eptr != '-' ; ++eptr); |
| |
| if (!PV_atoi(sptr, 'd', eptr - sptr, width)) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - bad width factor")); |
| return SDP_BAD_MEDIA_FRAMESIZE ; |
| } |
| |
| eptr = eptr + 1; |
| sptr = eptr; |
| if (sptr > line_end_ptr) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format")); |
| return SDP_BAD_MEDIA_FRAMESIZE; |
| } |
| eptr = skip_to_whitespace(sptr, line_end_ptr); |
| if (!PV_atoi(sptr, 'd', eptr - sptr, height)) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - Bad height factor")); |
| return SDP_BAD_MEDIA_FRAMESIZE; |
| } |
| if (framesize_found_in_fmtp) |
| { |
| if ((int)width != payloadPtr2->getFrameWidth() || (int)height != payloadPtr2->getFrameHeight()) |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - Bad a=framesize line format - frame width & height mis match")); |
| return SDP_BAD_MEDIA_FRAMESIZE; |
| } |
| |
| } |
| else |
| { |
| payloadPtr2->setFrameWidth(width); |
| payloadPtr2->setFrameHeight(height); |
| } |
| } |
| |
| } |
| break; |
| default: |
| { |
| } |
| break; |
| } |
| current_start = line_end_ptr; |
| } |
| |
| sessionDescription *session = sdp->getSessionInfo(); |
| |
| const char *altGroupBW = session->getAltGroupBW(); |
| int length = session->getAltGroupBWLength(); |
| |
| if (length > 0) |
| { |
| status = setDependentMediaId(altGroupBW, length, h263V, alt_id); |
| if (status != SDP_SUCCESS) |
| return SDP_BAD_MEDIA_ALT_ID; |
| } |
| |
| const char *altGroupLANG = session->getAltGroupLANG(); |
| length = session->getAltGroupLANGLength(); |
| |
| if (length > 0) |
| { |
| status = setDependentMediaId(altGroupLANG, length, h263V, alt_id); |
| if (status != SDP_SUCCESS) |
| return SDP_BAD_MEDIA_ALT_ID; |
| } |
| |
| if ((h263V->getCFieldStatus() || session->getCFieldStatus())) |
| { |
| //if sample rate is zero override with defaults |
| Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector = |
| h263V->getPayloadSpecificInfoVector(); |
| for (int ii = 0; ii < (int)payloadSpecificInfoVector.size();ii++) |
| { |
| if (payloadSpecificInfoVector[ii]->getSampleRate() == 0) |
| { |
| payloadSpecificInfoVector[ii]->sampleRate = |
| PVMF_SDP_DEFAULT_H263_SAMPLE_RATE; |
| } |
| } |
| return SDP_SUCCESS; |
| } |
| else |
| { |
| PVMF_SDP_PARSER_LOGERROR((0, "SDPH263MediaInfoParser::parseMediaInfo - no c field")); |
| return SDP_FAILURE_NO_C_FIELD; |
| } |
| } |
| |
| |
| } |