blob: 0eb0dfb8c95eeaad45645ed344eaa2a041d0a251 [file] [log] [blame]
/* ------------------------------------------------------------------
* 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;
}
}
}