Home | History | Annotate | Download | only in src
      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