/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 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.
 * -------------------------------------------------------------------
 */
#include "h264_media_info_parser.h"
#include "oscl_string_utils.h"
#include "oscl_string_containers.h"
#include "sdp_parsing_utils.h"

#define MIN_ENCODED_BYTES 4
#define AVC_NALTYPE_MASK 0x1F
#define AVC_NALTYPE_SPS 7
#define AVC_NALTYPE_PPS 8

SDP_ERROR_CODE
SDPH264MediaInfoParser::parseMediaInfo(const char *buff,
                                       const int index,
                                       SDPInfo *sdp,
                                       payloadVector payload_vec,
                                       bool isSipSdp,
                                       int alt_id,
                                       bool alt_def_id)
{
    //Pointer to the beginning of the media text
    const char *current_start = buff;
    //Pointer to the end of the media text
    const char *end = buff + index;
    const char *line_start_ptr, *line_end_ptr;
    int fmtp_cnt = 0;
    bool altMedia = false;

    if (!alt_id || (alt_def_id == true))
    {
        altMedia = false;
    }
    else
    {
        altMedia = true;
    }
    void *memory = sdp->alloc(sizeof(h264_mediaInfo), altMedia);
    if (NULL == memory)
    {
        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Memory allocation failure"));
        return SDP_NO_MEMORY;
    }
    else
    {
        h264_mediaInfo *h264V = OSCL_PLACEMENT_NEW(memory, h264_mediaInfo());

        h264V->setMediaInfoID(sdp->getMediaObjectIndex());

        // Allocate memory to the payload specific objects
        for (uint32 ii = 0; ii < payload_vec.size(); ii++)
        {
            void* mem = h264V->alloc(sizeof(H264PayloadSpecificInfoType));
            if (mem == NULL)
            {
                PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Memory allocation failure"));
                return SDP_NO_MEMORY;
            }
            else
            {
                H264PayloadSpecificInfoType* h264Payload = OSCL_PLACEMENT_NEW(mem, H264PayloadSpecificInfoType(payload_vec[ii]));
                (void) h264Payload;
            }
        }


        if (alt_id && !alt_def_id)
        {
            sdp->copyFmDefMedia(h264V);
            //empty alternate & default track ID vectors.
            h264V->resetAlternateTrackId();
            h264V->resetDependentTrackId();
        }

        SDP_ERROR_CODE status =
            baseMediaInfoParser(buff, h264V, 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, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad payload number"));
                            return SDP_BAD_MEDIA_FMTP;
                        }
                        else
                        {
                            int p;
                            if (!h264V->lookupPayloadNumber(payloadNumber, p))
                            {
                                fmtp_cnt--;
                                break;
                            }
                        }

                        // payloadNumber is present in the mediaInfo. get the payload
                        // Specific pointer corresponding to this payload
                        H264PayloadSpecificInfoType* payloadPtr =
                            (H264PayloadSpecificInfoType*)h264V->getPayloadSpecificInfoTypePtr(payloadNumber);
                        if (payloadPtr == NULL)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: Payload pointer not found for payload"));
                            return SDP_PAYLOAD_MISMATCH;
                        }

                        PVMF_SDP_PARSER_LOGINFO((0, "SDPH264MediaInfoParser::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-level-id=",
                                                  oscl_strlen("profile-level-id=")))
                                {
                                    temp += oscl_strlen("profile-level-id=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad profile-level-id: field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'x',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setProfileLevelID(val);
                                    }

                                }
                                if (!oscl_strncmp(temp,
                                                  "max-mbps=",
                                                  oscl_strlen("max-mbps=")))
                                {
                                    temp += oscl_strlen("max-mbps=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-mbps: field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxMbps(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "max-fs=",
                                                  oscl_strlen("max-fs=")))
                                {
                                    temp += oscl_strlen("max-fs=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-fs field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxFs(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "max-cpb=",
                                                  oscl_strlen("max-cpb=")))
                                {
                                    temp += oscl_strlen("max-cpb=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-cpb: field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxCpb(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "max-dpb=",
                                                  oscl_strlen("max-dpb=")))
                                {
                                    temp += oscl_strlen("max-dpb=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-dpb field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxDpb(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "max-br=",
                                                  oscl_strlen("max-br=")))
                                {
                                    temp += oscl_strlen("max-br=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-br field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxBr(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "redundant-pic-cap=",
                                                  oscl_strlen("redundant-pic-cap=")))
                                {
                                    temp += oscl_strlen("redundant-pic-cap=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad redundant-pic-cap field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setRedundantPicCap(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "sprop-parameter-sets=",
                                                  oscl_strlen("sprop-parameter-sets=")))
                                {
                                    temp += oscl_strlen("sprop-parameter-sets=");
                                    temp = skip_whitespace(temp, line_end_ptr);
                                    if (temp >= line_end_ptr)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad sprop-parameter-sets field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 parameterSetLength = (int)(tmp_end_line - temp);
                                    SDP_ERROR_CODE errCode =
                                        parseParameterSets(temp,
                                                           parameterSetLength,
                                                           h264V,
                                                           payloadNumber);

                                    if (errCode != SDP_SUCCESS)
                                    {
                                        return errCode;
                                    }

                                }
                                if (!oscl_strncmp(temp,
                                                  "packetization-mode=",
                                                  oscl_strlen("packetization-mode=")))
                                {
                                    temp += oscl_strlen("packetization-mode=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad packetization-mode field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setPacketizationMode(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "sprop-interleaving-depth=",
                                                  oscl_strlen("sprop-interleaving-depth=")))
                                {
                                    temp += oscl_strlen("sprop-interleaving-depth=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad sprop-interleaving-depth field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setSpropInterleavingDepth(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "deint-buf-cap=",
                                                  oscl_strlen("deint-buf-cap=")))
                                {
                                    temp += oscl_strlen("deint-buf-cap=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad deint-buf-cap field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setDeintBufCap(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "sprop-deint-buf-req=",
                                                  oscl_strlen("sprop-deint-buf-req=")))
                                {
                                    temp += oscl_strlen("sprop-deint-buf-req=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad sprop-deint-buf-req field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setSpropDeintBufReq(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "sprop-init-buf-time=",
                                                  oscl_strlen("sprop-init-buf-time=")))
                                {
                                    temp += oscl_strlen("sprop-init-buf-time=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad sprop-init-buf-time field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setSpropInitBufTime(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "sprop-max-don-diff=",
                                                  oscl_strlen("sprop-max-don-diff=")))
                                {
                                    temp += oscl_strlen("sprop-max-don-diff=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad sprop-max-don-diff field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setSpropMaxDonDiff(val);
                                    }
                                }
                                if (!oscl_strncmp(temp,
                                                  "max-rcmd-nalu-size=",
                                                  oscl_strlen("max-rcmd-nalu-size=")))
                                {
                                    temp += oscl_strlen("max-rcmd-nalu-size=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format - Bad max-rcmd-nalu-size field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 val;
                                    if (PV_atoi(temp,
                                                'd',
                                                (tmp_end_line - temp),
                                                val) == true)
                                    {
                                        payloadPtr->setMaxRcmdNaluSize(val);
                                    }
                                }
                                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, "SDPH264MediaInfoParser::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, "SDPH264MediaInfoParser::parseMediaInfo - Bad a=fmtp: line format"));
                                    return SDP_BAD_MEDIA_FMTP;
                                }
                            }
                        }
                    }// end a=fmtp
                }
                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, h264V, 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, h264V, alt_id);
            if (status != SDP_SUCCESS)
                return SDP_BAD_MEDIA_ALT_ID;
        }

        if ((fmtp_cnt == h264V->getMediaPayloadNumberCount()) &&
                (h264V->getCFieldStatus() || session->getCFieldStatus()))

            return SDP_SUCCESS;
        else
        {
            PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseMediaInfo - no c field present"));
            return SDP_FAILURE_NO_C_FIELD;
        }

    }


}

SDP_ERROR_CODE SDPH264MediaInfoParser::parseParameterSets(const char* aParamSetBuf,
        int   aParamSetBufLen,
        h264_mediaInfo* aH264MediaInfo,
        uint32 aPayLoadNumber)
{
    /*Determine number of parameter sets */
    const char *tmp_start_line = aParamSetBuf;
    int i;
    uint32 numParamSets = 0;
    Oscl_Vector<uint8*, OsclMemAllocator> paramSetStartBufVec;
    Oscl_Vector<uint32, OsclMemAllocator> paramSetBufSizeVec;
    paramSetStartBufVec.push_back((uint8*)tmp_start_line);
    uint32 prevIndex = 0;
    for (i = 0; i < aParamSetBufLen; i++)
    {
        if (tmp_start_line[i] == ',')
        {
            uint8* ptr = (uint8*)(tmp_start_line + (i + 1));
            paramSetStartBufVec.push_back(ptr);
            uint32 size = (i - prevIndex);
            prevIndex = i + 1;
            paramSetBufSizeVec.push_back(size);
            numParamSets++;
        }
    }
    numParamSets++;
    paramSetBufSizeVec.push_back((aParamSetBufLen - prevIndex));

    if (paramSetBufSizeVec[0] >= MIN_ENCODED_BYTES)
    {
        uint8  decoded[MIN_ENCODED_BYTES];
        uint32 outBufLen = 0;
        //Decode the minimum amount required to extract the NAL type.
        if (sdp_decodebase64(paramSetStartBufVec[0],
                             MIN_ENCODED_BYTES,
                             decoded,
                             outBufLen,
                             sizeof(decoded)
                            ))
        {
            uint8 nal_type = decoded[0] & AVC_NALTYPE_MASK;
            switch (nal_type)
            {
                    //Rather than modify every codec to accept SPS and PPS in any order,
                    //it is best to simply swap the order in the SDP parser so SPS
                    //always comes before PPS.
                    //If PPS comes before SPS, swap the order.
                case AVC_NALTYPE_PPS:
                {
                    uint8* tempBuf = paramSetStartBufVec.back();
                    paramSetStartBufVec.pop_back();
                    paramSetStartBufVec.push_front(tempBuf);
                    uint32 tempSize = paramSetBufSizeVec.back();
                    paramSetBufSizeVec.pop_back();
                    paramSetBufSizeVec.push_front(tempSize);
                }
                break;

                case AVC_NALTYPE_SPS:
                default:
                    break;
            }
        }
    }

    int configBufLength = aParamSetBufLen + numParamSets * (sizeof(uint16));
    SDPAllocDestructDealloc<uint8> SDP_alloc;
    uint8 *configPtr = SDP_alloc.allocate(configBufLength);
    OsclRefCounterSA< SDPAllocDestructDealloc<uint8> > *refcnt =
        new OsclRefCounterSA< SDPAllocDestructDealloc<uint8> >(configPtr);
    OsclSharedPtr<uint8> parameterSetPtr(configPtr, refcnt);

    uint32 offset = 0;
    for (uint32 j = 0; j < paramSetStartBufVec.size(); j++)
    {
        uint8* inBuf = paramSetStartBufVec[j];
        uint32 inBufLen = paramSetBufSizeVec[j];
        uint32 outBufLen = 0;
        uint8* paramSetSizePtr = configPtr + offset;
        offset += 2; // for param set size
        uint8* outPtr = configPtr + offset;
        uint32 maxOutBufLen = configBufLength - offset;
        if (!sdp_decodebase64(inBuf,
                              inBufLen,
                              outPtr,
                              outBufLen,
                              maxOutBufLen))
        {
            PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseParameterSets : unable to set decodebase"));
            return SDP_BAD_MEDIA_FMTP;
        }
        uint16 len = (uint16)outBufLen;
        oscl_memcpy(paramSetSizePtr, &len, sizeof(uint16));
        offset += outBufLen;
    }

    H264PayloadSpecificInfoType* payloadPtr =
        (H264PayloadSpecificInfoType*)aH264MediaInfo->getPayloadSpecificInfoTypePtr(aPayLoadNumber);
    if (payloadPtr == NULL)
    {
        PVMF_SDP_PARSER_LOGERROR((0, "SDPH264MediaInfoParser::parseParameterSets - Unable to find payload ptr for payload"));
        return SDP_PAYLOAD_MISMATCH;
    }

    PVMF_SDP_PARSER_LOGINFO((0, "SDPH264MediaInfoParser::parseParameterSets - processing payload number : %d", aPayLoadNumber));

    payloadPtr->setDecoderSpecificInfo(parameterSetPtr);
    payloadPtr->setDecoderSpecificInfoSize(offset);

    //if sample rate is zero override with defaults
    Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector =
        aH264MediaInfo->getPayloadSpecificInfoVector();
    for (int ii = 0; ii < (int)payloadSpecificInfoVector.size(); ii++)
    {
        if (payloadSpecificInfoVector[ii]->getSampleRate() == 0)
        {
            payloadSpecificInfoVector[ii]->sampleRate =
                PVMF_SDP_DEFAULT_H264_SAMPLE_RATE;
        }
    }
    return SDP_SUCCESS;
}


