Ejemplo n.º 1
0
OSCL_EXPORT_REF  oscl_wchar* oscl_strstr(oscl_wchar* str1,  const oscl_wchar* str2)
{
    uint32 size = oscl_strlen(str1);
    uint32 size2 = oscl_strlen(str2);
    oscl_wchar* p = (oscl_wchar*) str1;
    while ((*p != '\0') && (size >= size2))
    {
        if (!oscl_strncmp(p, str2, size2))
            return p;
        else
        {
            p += 1;
            size -= 1;
        }
    }
    return 0;
}
void pv_metadata_engine_test::GetSourceFormatType(char* aFileName, PVMFFormatType& aInputFileFormatType)
{
    // Check the file extension to determine format type
    // AAC file
    if (oscl_strstr(aFileName, ".aac") != NULL || oscl_strstr(aFileName, ".AAC") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_AACFF;
    }
    // MP3 file
    else  if (oscl_strstr(aFileName, ".mp3") != NULL || oscl_strstr(aFileName, ".MP3") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_MP3FF;
    }
    // AMR file (IETF and IF2)
    else  if (oscl_strstr(aFileName, ".amr") != NULL || oscl_strstr(aFileName, ".AMR") != NULL ||
              oscl_strstr(aFileName, ".cod") != NULL || oscl_strstr(aFileName, ".COD") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_AMRFF;
    }
    // RTSP URL
    else  if ((!oscl_strncmp("rtsp", aFileName, 4)) ||
              (!oscl_strncmp("RTSP", aFileName, 4)))
    {
        aInputFileFormatType = PVMF_MIME_DATA_SOURCE_RTSP_URL;
    }
    // HTTP URL
    else  if (oscl_strstr(aFileName, "http:") != NULL || oscl_strstr(aFileName, "HTTP:") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_DATA_SOURCE_HTTP_URL;
    }
    // MP4/3GP file
    else  if (oscl_strstr(aFileName, ".mp4") != NULL || oscl_strstr(aFileName, ".MP4") != NULL ||
              oscl_strstr(aFileName, ".3gp") != NULL || oscl_strstr(aFileName, ".3GP") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_MPEG4FF;
    }
    // ASF file
    else  if (oscl_strstr(aFileName, ".asf") != NULL || oscl_strstr(aFileName, ".ASF") != NULL ||
              oscl_strstr(aFileName, ".wma") != NULL || oscl_strstr(aFileName, ".WMA") != NULL ||
              oscl_strstr(aFileName, ".wmv") != NULL || oscl_strstr(aFileName, ".WMV") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_ASFFF;
    }
    // SDP file
    else  if (oscl_strstr(aFileName, ".sdp") != NULL || oscl_strstr(aFileName, ".SDP") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_DATA_SOURCE_SDP_FILE;
    }
    // PVX file
    else  if (oscl_strstr(aFileName, ".pvx") != NULL || oscl_strstr(aFileName, ".PVX") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_DATA_SOURCE_PVX_FILE;
    }
    // WAV file
    else  if (oscl_strstr(aFileName, ".wav") != NULL || oscl_strstr(aFileName, ".WAV") != NULL)
    {
        aInputFileFormatType = PVMF_MIME_WAVFF;
    }
    // Unknown so set to unknown and let the player engine determine the format type
    else
    {
        aInputFileFormatType = PVMF_MIME_FORMAT_UNKNOWN;
    }
}
OSCL_EXPORT_REF bool parseRtspRange(const char *rangeString, int length, RtspRangeType& range)
{
    const char *end = rangeString + length;

    const char* sptr, *eptr;

    // initialize range to invalid format
    range.format = RtspRangeType::INVALID_RANGE;

    // find the first word before the "="
    sptr = skip_whitespace_and_line_term(rangeString, end);
    if (sptr >= end)
    {
        return false;
    }

    for (eptr = sptr; eptr < end &&
            (*eptr != '=' && *eptr != ':' && *eptr != ' ' && *eptr != '\t');
            ++eptr);


    StrPtrLen smpte_type("smpte");
    StrPtrLen smpte25_type("smpte-25");
    StrPtrLen smpte30_type("smpte-30-drop");
    StrPtrLen npt_type("npt");
    StrPtrLen abs_type("clock");
//#ifdef RTSP_PLAYLIST_SUPPORT
    StrPtrLen playlist_play_time_type("playlist_play_time");
//#endif //#ifdef RTSP_PLAYLIST_SUPPORT

    if (!oscl_strncmp(sptr, smpte_type.c_str(), eptr - sptr) ||
            !oscl_strncmp(sptr, smpte25_type.c_str(), eptr - sptr) ||
            !oscl_strncmp(sptr, smpte30_type.c_str(), eptr - sptr))
    {
        // Parsing one of the SMPTE time formats

        // save the exact format temporarily
        RtspRangeType::RtspRangeFormat tmp_format;
        if (!oscl_strncmp(sptr, smpte30_type.c_str(), smpte30_type.length()))
        {
            tmp_format = RtspRangeType::SMPTE_30_RANGE;
        }
        else if (!oscl_strncmp(sptr, smpte25_type.c_str(), smpte25_type.length()))
        {
            tmp_format = RtspRangeType::SMPTE_25_RANGE;
        }
        else
        {
            tmp_format = RtspRangeType::SMPTE_RANGE;
        }

        // skip ahead to beyond the "="
        if (*eptr != '=')
        {
            for (; eptr < end && *eptr != '='; ++eptr);
        }

        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the start/end separator
        for (eptr = sptr; eptr < end &&
                (*eptr != '-'); ++eptr);

        if (*eptr != '-')
        {
            return false;
        }

        range.start_is_set = false;
        if (eptr > sptr)
        {
            // there is a start time

            if (parse_smpte_format(sptr, eptr, tmp_format, range.smpte_start) == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.start_is_set = true;
        }

        // see if there is a stop time
        sptr = skip_whitespace_and_line_term(eptr + 1, end);
        range.end_is_set = false;
        if (sptr < end)
        {
            // there is a stop time specification
            eptr = skip_to_whitespace(sptr, end);

            if (parse_smpte_format(sptr, eptr, tmp_format, range.smpte_end)
                    == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.end_is_set = true;
        }

        // now set the appropriate range format
        range.format = tmp_format;

    } // end if this is an SMPTE time format

    else if (!oscl_strncmp(sptr, npt_type.c_str(), eptr - sptr))
    {

        // skip ahead to beyond the "=" or ":"
        if (*eptr != '=')
        {
            for (; eptr < end && *eptr != '=' && *eptr != ':'; ++eptr);
        }

        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the start/end separator
        for (eptr = sptr; eptr < end &&
                (*eptr != '-'); ++eptr);

        if (*eptr != '-')
        {
            return false;
        }

        range.start_is_set = false;
        if (eptr > sptr)
        {
            // there is a start time
            if (parse_npt_format(sptr, eptr, range.npt_start) == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.start_is_set = true;

        }

        // see if there is a stop time
        range.end_is_set = false;
        sptr = skip_whitespace_and_line_term(eptr + 1, end);
        if (sptr < end)
        {
            // there is a stop time specification
            eptr = skip_to_whitespace(sptr, end);

            if (parse_npt_format(sptr, eptr, range.npt_end)
                    == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.end_is_set = true;
        }

        // now set the appropriate range format
        range.format = RtspRangeType::NPT_RANGE;

    } // end if this is an NPT time format

    else if (!oscl_strncmp(sptr, abs_type.c_str(), eptr - sptr))
    {


        // skip ahead to beyond the "="
        if (*eptr != '=')
        {
            for (; eptr < end && *eptr != '='; ++eptr);
        }

        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the start/end separator
        for (eptr = sptr; eptr < end &&
                (*eptr != '-'); ++eptr);

        if (*eptr != '-')
        {
            return false;
        }

        range.start_is_set = false;
        if (eptr > sptr)
        {
            // there is a start time
            if (parse_abs_format(sptr, eptr, range.abs_start) == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.start_is_set = true;

        }

        // see if there is a stop time
        sptr = skip_whitespace_and_line_term(eptr + 1, end);
        range.end_is_set = true;
        if (sptr < end)
        {
            // there is a stop time specification
            eptr = skip_to_whitespace(sptr, end);

            if (parse_abs_format(sptr, eptr, range.abs_end)
                    == false)
            {
                return false;
            }

            // now set the appropriate flags
            range.end_is_set = true;
        }

        // now set the appropriate range format
        range.format = RtspRangeType::ABS_RANGE;

    } // end if this is an ABS time format
//#ifdef RTSP_PLAYLIST_SUPPORT
    // for Range:playlist_play_time=<URN,clipIndex,clipOffset>
    //playlist_play_time=</public/playlist/va_playlists/test.ply,3,0.0>;npt=194.81542
    else if (!oscl_strncmp(sptr, playlist_play_time_type.c_str(), eptr - sptr))
    {
        // store the whole string since we may not need the parsed version of things
        //oscl_memcpy(range.iPlaylistPlayStr,rangeString,length);
        //range.iPlaylistPlayStr[length] = '\0';

        range.format = RtspRangeType::PLAYLIST_TIME_RANGE;
        range.start_is_set = range.end_is_set = false;

        // now set the appropriate flags
        range.start_is_set = true;

        // skip ahead to beyond the "="
        if (*eptr != '=')
        {
            for (; eptr < end && *eptr != '='; ++eptr);
        }

        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // next should be the opening "<"
        // skip ahead to beyond the "<"
        if (*eptr != '<')
        {
            for (; eptr < end && *eptr != '<'; ++eptr);
        }

        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the comma separator
        for (eptr = sptr; eptr < end &&
                (*eptr != ','); ++eptr);

        if (*eptr != ',')
        {
            return false;
        }

        // first the urn
        if (eptr > sptr)
        {
            // there is a urn
            if (oscl_memcpy(range.iPlaylistUrl, sptr, eptr - sptr) == false)
            {
                return false;
            }
            //range.iUrn[(eptr-sptr)+1] = '\0';
            range.iPlaylistUrl[eptr-sptr] = '\0';
        }

        // now the clipIndex
        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the next comma separator
        for (eptr = sptr; eptr < end &&
                (*eptr != ','); ++eptr);

        if (*eptr != ',')
        {
            return false;
        }

        // now the clipIndex
        if (eptr > sptr)
        {
            // there is a clipIndex
            uint32 tmp;
            if (PV_atoi(sptr, 'd', eptr - sptr, tmp) == false)
            {
                return false;
            }
            range.playlist_start.iClipIndex = (int32)tmp;
        }

        // now the clipOffset
        sptr = skip_whitespace(eptr + 1, end);
        if (sptr >= end)
        {
            return false;
        }

        // find the final '>' separator or the final possible '.' in offset
        //<sec>.<frac>
        for (eptr = sptr; eptr < end &&
                (*eptr != '>') && (*eptr != '.'); ++eptr);

        if (eptr >= end)
        {
            return false;
        }

        // @todo ignore the factional part for now
        // now the clipOffset
        if (eptr > sptr)
        {
            // there is a clipOffset
            uint32 tmp;
            if (PV_atoi(sptr, 'd', eptr - sptr, tmp) == false)
            {
                return false;
            }
            range.playlist_start.sec = (int32)tmp;

            {
                range.playlist_start.milli_sec = 0;
                if (*eptr == '.')
                {
                    // there is an optional fractional seconds field

                    // get the fractional seconds
                    const int MAX_TMP_BUFSIZE = 12;
                    char tmpbuf[MAX_TMP_BUFSIZE];
                    int copy_size;

                    eptr = skip_to_whitespace(sptr, end);

                    copy_size = eptr - sptr;

                    if (copy_size > MAX_TMP_BUFSIZE - 1)
                    {
                        copy_size = MAX_TMP_BUFSIZE - 1;
                    }

                    oscl_strncpy(tmpbuf, sptr, copy_size);


                    tmpbuf[copy_size] = '\0';

                    OsclFloat tmp_fnum;
                    if (!PV_atof(tmpbuf, tmp_fnum))
                        return false;
                    range.playlist_start.milli_sec = (uint32)(1000.0 * tmp_fnum + 0.5);
                }
            }
        }
    }  // end if this is a playlist_play_time format, for response to playlist_play commands
//#endif //#ifdef RTSP_PLAYLIST_SUPPORT
    else
    {
        /*Unsupported time format*/
        range.format = RtspRangeType::UNKNOWN_RANGE;
        range.start_is_set = false;
        range.end_is_set = false;
        return false;
    }

    return true;
}
OSCL_EXPORT_REF bool parse_npt_format(const char* start_ptr, const char *end_ptr,
                                      NptTimeFormat& npt_range)
{

    // get required HH:MM:SS values
    const char *sptr, *eptr;
    uint32 tmp;

    sptr = start_ptr;

    StrPtrLen now_str("now");
    if (!oscl_strncmp(sptr, now_str.c_str(), now_str.length()))
    {
        // this is the "now" keyword
        npt_range.npt_format = NptTimeFormat::NOW;
        return true;
    }

    // see if the format contains a ':' separator character
    for (eptr = sptr; eptr < end_ptr && *eptr != ':'; ++eptr);

    if (*eptr == ':')
    {
        // this is the npt-hhmmss format

        char sep = ':';
        // get the number of hours
        sptr = parse_range_integer(sptr, eptr,
                                   0, &sep, tmp);

        if (!sptr)
        {
            return false;
        }

        npt_range.npt_format = NptTimeFormat::NPT_HHMMSS;
        npt_range.npt_hhmmss.hours = tmp;


        // get the number of minutes
        sptr = parse_range_integer(sptr + 1, end_ptr,
                                   2, &sep, tmp);

        if (!sptr || *sptr != ':')
        {
            return false;
        }

        if (tmp > 59)
        {
            return false;
        }

        npt_range.npt_hhmmss.min = (uint8)tmp;


        sep = '.';
        // get the number of seconds
        sptr = parse_range_integer(sptr + 1, end_ptr,
                                   2, &sep, tmp);

        if (!sptr)
        {
            return false;
        }

        if (tmp > 59)
        {
            return false;
        }

        npt_range.npt_hhmmss.sec = (uint8)tmp;

        npt_range.npt_hhmmss.frac_sec = 0;
        // determine if the fractional seconds exists
        if (*sptr == '.')
        {
            // get the fractional seconds
            const int MAX_TMP_BUFSIZE = 12;
            char tmpbuf[MAX_TMP_BUFSIZE];
            int copy_size;

            eptr = skip_to_whitespace(sptr, end_ptr);

            copy_size = eptr - sptr;
            if (copy_size > MAX_TMP_BUFSIZE - 1)
            {
                copy_size = MAX_TMP_BUFSIZE - 1;
            }

            oscl_strncpy(tmpbuf, sptr, copy_size);

            tmpbuf[copy_size] = '\0';

            if (!PV_atof(tmpbuf, npt_range.npt_hhmmss.frac_sec))
                return false;

        }

    } // end if the format is NPT_HHMMSS

    else
    {

        char sep = '.';
        // this is the NPT_SEC format
        npt_range.npt_format = NptTimeFormat::NPT_SEC;

        // get the number of seconds
        sptr = parse_range_integer(sptr, eptr,
                                   0, &sep, tmp);

        if (!sptr)
        {
            return false;
        }

        npt_range.npt_sec.sec = tmp;

        npt_range.npt_sec.milli_sec = 0;
        if (*sptr == '.')
        {
            // there is an optional fractional seconds field

            // get the fractional seconds
            const int MAX_TMP_BUFSIZE = 12;
            char tmpbuf[MAX_TMP_BUFSIZE];
            int copy_size;

            eptr = skip_to_whitespace(sptr, end_ptr);

            copy_size = eptr - sptr;

            if (copy_size > MAX_TMP_BUFSIZE - 1)
            {
                copy_size = MAX_TMP_BUFSIZE - 1;
            }

            oscl_strncpy(tmpbuf, sptr, copy_size);


            tmpbuf[copy_size] = '\0';

            OsclFloat tmp_fnum;
            if (!PV_atof(tmpbuf, tmp_fnum))
                return false;
            npt_range.npt_sec.milli_sec = (uint32)(1000.0 * tmp_fnum + 0.5);
        }

    } // end if the format is NPT_SEC

    return true;
}
OSCL_EXPORT_REF OMX_BOOL hantro_OMXConfigParser(
    OMX_PTR aInputParameters,
    OMX_PTR aOutputParameters)

{
    OMXConfigParserInputs* pInputs;

    pInputs = (OMXConfigParserInputs*) aInputParameters;


    if (NULL != pInputs->cComponentRole)
    {
        if (0 == oscl_strncmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder", oscl_strlen("audio_decoder")))
        {
            OMX_S32 Status;
            pvAudioConfigParserInputs aInputs;

            aInputs.inPtr = pInputs->inPtr;
            aInputs.inBytes = pInputs->inBytes;

            if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.wma"))
            {
                aInputs.iMimeType = PVMF_MIME_WMA;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.aac"))
            {
                aInputs.iMimeType = PVMF_MIME_AAC_SIZEHDR;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amr"))
            {
                aInputs.iMimeType = PVMF_MIME_AMR;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amrnb"))
            {
                aInputs.iMimeType = PVMF_MIME_AMR;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.amrwb"))
            {
                aInputs.iMimeType = PVMF_MIME_AMRWB;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"audio_decoder.mp3"))
            {
                aInputs.iMimeType = PVMF_MIME_MP3;

            }
            else
            {
                return OMX_FALSE;
            }

            Status = pv_audio_config_parser(&aInputs, (pvAudioConfigParserOutputs *)aOutputParameters);
            if (0 == Status)
            {
                return OMX_FALSE;
            }
        }
        else if (0 == oscl_strncmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder", oscl_strlen("video_decoder")))
        {

            OMX_S32 Status;
            pvVideoConfigParserInputs aInputs;

            aInputs.inPtr = pInputs->inPtr;
            aInputs.inBytes = pInputs->inBytes;

            if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.wmv"))
            {
                aInputs.iMimeType = PVMF_MIME_WMV;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.avc"))
            {
                aInputs.iMimeType = PVMF_MIME_H264_VIDEO;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.mpeg4"))
            {
                aInputs.iMimeType = PVMF_MIME_M4V;

            }
            else if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.h263"))
            {
                aInputs.iMimeType = PVMF_MIME_H2632000;

            }
            else
            {
                return OMX_FALSE;
            }
            
            if (0 == oscl_strcmp(pInputs->cComponentRole, (OMX_STRING)"video_decoder.mpeg4"))
            {
                Status = hantro_video_config_parser((hantroVideoConfigParserInputs *)&aInputs, (hantroVideoConfigParserOutputs *)aOutputParameters);
            }
            else
            {
                Status = pv_video_config_parser(&aInputs, (pvVideoConfigParserOutputs *)aOutputParameters);
            }
            if (0 != Status)
            {
                return OMX_FALSE;
            }
        }
        else
        {
            return OMX_FALSE;
        }

    }
    else
    {
        return OMX_FALSE;
    }

    return OMX_TRUE;
}
/* ======================================================================== */
SDP_ERROR_CODE
SDPMPEG4MediaInfoParser::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;
    int VOLLength = 0;
    int fmtp_cnt = 0 ;
    bool framesize_found_in_fmtp = false;
    SDPAllocDestructDealloc<uint8> SDP_alloc;


    while (get_next_line(current_start, end,
                         line_start_ptr, line_end_ptr))
    {
        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:")))
        {
            char *tmp_start_line, *tmp_end_line;
            fmtp_cnt++ ;

            tmp_start_line = (char *)line_start_ptr + oscl_strlen("a=fmtp:");
            tmp_start_line = (char *)skip_whitespace(tmp_start_line, line_end_ptr);
            if (tmp_start_line >= line_end_ptr)
            {
                break;
            }
            tmp_end_line = (char *)skip_to_whitespace(tmp_start_line, line_end_ptr);
            if (tmp_end_line < tmp_start_line)
            {
                break;
            }
            tmp_start_line = tmp_end_line + 1;
            tmp_start_line = (char *)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 ((line_end_ptr - tmp_start_line - 1) == ii)
                    {
                        tmp_end_line++;
                    }
                    if (!oscl_strncmp(temp, "config=", oscl_strlen("config=")))
                    {
                        int currentVOLLength;
                        temp += oscl_strlen("config=");
                        temp = skip_whitespace(temp, line_end_ptr);
                        if (temp >= line_end_ptr)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad config field"));
                            return SDP_BAD_MEDIA_FMTP;
                        }

                        currentVOLLength = (int)(tmp_end_line - temp) / 2;
                        if (VOLLength < currentVOLLength)
                            VOLLength = currentVOLLength;
                    }
                    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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format"));
                        return SDP_BAD_MEDIA_FMTP;
                    }

                }
            }
        }


        current_start = line_end_ptr + 1;
    }

    if (fmtp_cnt == 0 && isSipSdp == false)
    {
        PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - No fmtp line found"));
        return SDP_BAD_MEDIA_FORMAT;
    }

    if (VOLLength < 0)
    {
        VOLLength = 0;
    }

    bool altMedia = false;
    if (!alt_id || (alt_def_id == true))
        altMedia = false;
    else
        altMedia = true;

    void *memory = sdp->alloc(sizeof(m4v_mediaInfo), altMedia);
    if (NULL == memory)
    {
        PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - memory allocation failure"));
        return SDP_NO_MEMORY;
    }
    else
    {
        m4v_mediaInfo *m4Video = OSCL_PLACEMENT_NEW(memory, m4v_mediaInfo());

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

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


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

        SDP_ERROR_CODE status = baseMediaInfoParser(buff, m4Video, index, alt_id, alt_def_id, isSipSdp);
        if (status != SDP_SUCCESS)
        {
            return status;
        }

        current_start = buff;


        while (get_next_line(current_start, end,
                             line_start_ptr, line_end_ptr))
        {
            switch (*line_start_ptr)
            {
                case 'a':
                {
                    const char *sptr;
                    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=framerate:", oscl_strlen("a=framerate:")))
                    {
                        sptr = line_start_ptr + oscl_strlen("a=framerate:");
                        sptr = skip_whitespace(sptr, line_end_ptr);
                        if (sptr >= line_end_ptr)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=framerate line format"));
                            return SDP_BAD_MEDIA_FRAME_RATE;
                        }
                        OsclFloat rate;
                        if (!PV_atof(sptr, line_end_ptr - sptr, rate))
                            return SDP_BAD_MEDIA_FORMAT;
                        ((m4v_mediaInfo *)m4Video)->setFrameRate(rate);
                    }
                    if (!oscl_strncmp(line_start_ptr, "a=I_frame_interval:", oscl_strlen("a=I_frame_interval:")))
                    {
                        sptr = line_start_ptr + oscl_strlen("a=I_frame_interval:");
                        sptr = skip_whitespace(sptr, line_end_ptr);
                        if (sptr >= line_end_ptr)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=I_frame_interval line format"));
                            return SDP_BAD_MEDIA_FRAME_INTERVAL;
                        }
                        uint32 ifi;
                        if (PV_atoi(sptr, 'd', (line_end_ptr - sptr), ifi) == true)((m4v_mediaInfo *)m4Video)->setIFrameInterval(ifi);
                    }
                    if (!oscl_strncmp(line_start_ptr, "a=fmtp:", oscl_strlen("a=fmtp:")))
                    {
                        const char *tmp_start_line, *tmp_end_line;
                        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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad payload number"));
                            return SDP_BAD_MEDIA_FMTP;
                        }
                        else
                        {
                            int p;
                            if (!m4Video->lookupPayloadNumber(payloadNumber, p))
                            {
                                fmtp_cnt--;
                                break;
                            }
                        }

                        M4vPayloadSpecificInfoType* payloadPtr =
                            (M4vPayloadSpecificInfoType*)m4Video->getPayloadSpecificInfoTypePtr(payloadNumber);
                        if (payloadPtr == NULL)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - payload pointer not found for payload"));
                            return SDP_PAYLOAD_MISMATCH;
                        }

                        PVMF_SDP_PARSER_LOGINFO((0, "SDPM4VMediaInfoParser::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, "config=", oscl_strlen("config=")))
                                {
                                    uint8 *mptr = SDP_alloc.allocate(VOLLength);
                                    OsclRefCounterSA< SDPAllocDestructDealloc<uint8> > *refcnt = new OsclRefCounterSA< SDPAllocDestructDealloc<uint8> >(mptr);
                                    OsclSharedPtr<uint8> VOLPtr(mptr, refcnt);

                                    temp += oscl_strlen("config=");
                                    temp = skip_whitespace(temp, line_end_ptr);
                                    if (temp >= line_end_ptr)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad config field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    VOLLength = (int)(tmp_end_line - temp) / 2;
                                    int idx = 0;
                                    for (idx = 0; idx < VOLLength; idx++)
                                    {
                                        uint32 val;
                                        //Set this value in the vol header array
                                        if (PV_atoi((temp + 2*idx), 'x', 2 , val) == false)
                                        {
                                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad config field"));
                                            return SDP_BAD_MEDIA_FMTP;
                                        }

                                        *(VOLPtr + idx) = (uint8)val;

                                    }

                                    payloadPtr->setVOLHeader(VOLPtr);
                                    payloadPtr->setVOLHeaderSize(VOLLength);
                                    payloadPtr->setDecoderSpecificInfo(VOLPtr);
                                    payloadPtr->setDecoderSpecificInfoSize(VOLLength);

                                }
                                if (!oscl_strncmp(temp, "profile-level-id=", oscl_strlen("profile-level-id=")))
                                {
                                    temp += oscl_strlen("profile-level-id=");
                                    temp = skip_whitespace(temp, line_end_ptr);
                                    if (temp > line_end_ptr)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad profile-level-id field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 pl;
                                    if (PV_atoi(temp, 'd', tmp_end_line - temp ,  pl) == true)
                                        payloadPtr->setProfileLevelID(pl);

                                }
                                if (!oscl_strncmp(temp, "framesize=", oscl_strlen("framesize=")))
                                {
                                    temp += oscl_strlen("framesize=");
                                    temp = skip_whitespace(temp, tmp_end_line);
                                    framesize_found_in_fmtp  = true;
                                    if (temp > tmp_end_line)
                                    {
                                        PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - framesize width info 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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - framesize height info 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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format - Bad decode_buf field"));
                                        return SDP_BAD_MEDIA_FMTP;
                                    }
                                    uint32 dec;
                                    if (PV_atoi(temp, 'd', tmp_end_line - temp, dec) == true)
                                        payloadPtr->setMaxBufferSize(dec);
                                }
                                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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=fmtp line format"));
                                    return SDP_BAD_MEDIA_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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=framesize line format"));
                            return SDP_BAD_MEDIA_FRAMESIZE;
                        }
                        uint32 payloadNo;
                        if (PV_atoi(sptr, 'd', (eptr - sptr), payloadNo))
                        {
                            int p;
                            if (!((m4v_mediaInfo *)m4Video)->lookupPayloadNumber(payloadNo, p))
                                break;

                        }
                        else
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=framesize line format - Bad payload number"));
                            return SDP_BAD_MEDIA_FRAMESIZE;
                        }

                        M4vPayloadSpecificInfoType* payloadPtr2 =
                            (M4vPayloadSpecificInfoType*)m4Video->getPayloadSpecificInfoTypePtr(payloadNo);
                        if (payloadPtr2 == NULL)
                        {
                            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=framesize line format - payload pointer not found for payload"));
                            return SDP_PAYLOAD_MISMATCH;
                        }

                        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, "SDPM4VMediaInfoParser::parseMediaInfo - Bad a=framesize line format"));
                            return SDP_BAD_MEDIA_FRAMESIZE;
                        }

                        eptr = eptr + 1;
                        sptr = eptr;
                        if (sptr > line_end_ptr)
                            return SDP_BAD_MEDIA_FRAMESIZE;
                        eptr = skip_to_line_term(sptr, line_end_ptr);
                        if (!PV_atoi(sptr, 'd', eptr - sptr, height))
                            return SDP_BAD_MEDIA_FRAMESIZE;

                        if (framesize_found_in_fmtp)
                        {
                            if ((int)width != payloadPtr2->getFrameWidth() || (int)height != payloadPtr2->getFrameHeight())
                            {
                                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, m4Video, 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, m4Video, alt_id);
            if (status != SDP_SUCCESS)
                return SDP_BAD_MEDIA_ALT_ID;
        }

        if (m4Video->getCFieldStatus()	|| session->getCFieldStatus())
        {
            //if sample rate is zero override with defaults
            Oscl_Vector<PayloadSpecificInfoTypeBase*, SDPParserAlloc> payloadSpecificInfoVector =
                m4Video->getPayloadSpecificInfoVector();
            for (int ii = 0; ii < (int)payloadSpecificInfoVector.size();ii++)
            {
                if (payloadSpecificInfoVector[ii]->getSampleRate() == 0)
                {
                    payloadSpecificInfoVector[ii]->sampleRate =
                        PVMF_SDP_DEFAULT_MPEG4_VIDEO_SAMPLE_RATE;
                }
            }
            return SDP_SUCCESS;
        }
        else
        {
            PVMF_SDP_PARSER_LOGERROR((0, "SDPM4VMediaInfoParser::parseMediaInfo - No C field present"));
            return SDP_FAILURE_NO_C_FIELD;
        }
    }

}
// Pull out source file name from arguments
//  -source sometestfile.mp4
//
//
void FindSourceFile(cmd_line* command_line, OSCL_HeapString<OsclMemAllocator>& aFileNameInfo, PVMFFormatType& aInputFileFormatType, FILE* aFile)
{
    aFileNameInfo = SOURCENAME_PREPEND_STRING;
    aFileNameInfo += DEFAULTSOURCEFILENAME;
    aInputFileFormatType = DEFAULTSOURCEFORMATTYPE;

    int iFileArgument = 0;
    bool iFileFound = false;
    bool cmdline_iswchar = command_line->is_wchar();

    int count = command_line->get_count();

    // Search for the "-source" argument
    // Go through each argument
    for (int iFileSearch = 0; iFileSearch < count; iFileSearch++)
    {
        char argstr[128];
        // Convert to UTF8 if necessary
        if (cmdline_iswchar)
        {
            oscl_wchar* argwstr = NULL;
            command_line->get_arg(iFileSearch, argwstr);
            oscl_UnicodeToUTF8(argwstr, oscl_strlen(argwstr), argstr, 128);
            argstr[127] = NULL;
        }
        else
        {
            char* tmpstr = NULL;
            command_line->get_arg(iFileSearch, tmpstr);
            int32 tmpstrlen = oscl_strlen(tmpstr) + 1;
            if (tmpstrlen > 128)
            {
                tmpstrlen = 128;
            }
            oscl_strncpy(argstr, tmpstr, tmpstrlen);
            argstr[tmpstrlen-1] = NULL;
        }

        // Do the string compare
        if (oscl_strcmp(argstr, "-help") == NULL)
        {
            fprintf(aFile, "Source specification option. Default is 'test.mp4':\n");
            fprintf(aFile, "  -source sourcename\n");
            fprintf(aFile, "   Specify the source filename or URL to use for test cases which\n");
            fprintf(aFile, "   allow user-specified source name. The unit test determines the\n");
            fprintf(aFile, "   source format type using extension or URL header.\n\n");
        }
        else if (oscl_strcmp(argstr, "-source") == NULL)
        {
            iFileFound = true;
            iFileArgument = ++iFileSearch;
            break;
        }
    }

    if (iFileFound)
    {
        // Convert to UTF8 if necessary
        if (cmdline_iswchar)
        {
            oscl_wchar* cmd;
            command_line->get_arg(iFileArgument, cmd);
            char tmpstr[256];
            oscl_UnicodeToUTF8(cmd, oscl_strlen(cmd), tmpstr, 256);
            tmpstr[255] = NULL;
            aFileNameInfo = tmpstr;
        }
        else
        {
            char* cmdlinefilename = NULL;
            command_line->get_arg(iFileArgument, cmdlinefilename);
            aFileNameInfo = cmdlinefilename;
        }

        // Check the file extension to determine format type
        // AAC file
        if (oscl_strstr(aFileNameInfo.get_cstr(), ".aac") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".AAC") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_AACFF;
        }
        // MP3 file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".mp3") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".MP3") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_MP3FF;
        }
        // AMR file (IETF and IF2)
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".amr") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".AMR") != NULL ||
                  oscl_strstr(aFileNameInfo.get_cstr(), ".cod") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".COD") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_AMRFF;
        }
        // RTSP URL
        else  if ((!oscl_strncmp("rtsp", aFileNameInfo.get_cstr(), 4)) ||
                  (!oscl_strncmp("RTSP", aFileNameInfo.get_cstr(), 4)))
        {
            aInputFileFormatType = PVMF_MIME_DATA_SOURCE_RTSP_URL;
        }
        // HTTP URL
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), "http:") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), "HTTP:") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_DATA_SOURCE_HTTP_URL;
        }
        // MP4/3GP file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".mp4") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".MP4") != NULL ||
                  oscl_strstr(aFileNameInfo.get_cstr(), ".3gp") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".3GP") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_MPEG4FF;
        }
        // ASF file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".asf") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".ASF") != NULL ||
                  oscl_strstr(aFileNameInfo.get_cstr(), ".wma") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".WMA") != NULL ||
                  oscl_strstr(aFileNameInfo.get_cstr(), ".wmv") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".WMV") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_ASFFF;
        }
        // SDP file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".sdp") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".SDP") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_DATA_SOURCE_SDP_FILE;
        }
        // PVX file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".pvx") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".PVX") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_DATA_SOURCE_PVX_FILE;
        }
        // WAV file
        else  if (oscl_strstr(aFileNameInfo.get_cstr(), ".wav") != NULL || oscl_strstr(aFileNameInfo.get_cstr(), ".WAV") != NULL)
        {
            aInputFileFormatType = PVMF_MIME_WAVFF;
        }
        // Unknown so set to unknown and let the player engine determine the format type
        else
        {
            fprintf(file, "Source type unknown so setting to unknown and have the utility recognize it\n");
            aInputFileFormatType = PVMF_MIME_FORMAT_UNKNOWN;
        }
    }
}
Ejemplo n.º 8
0
    static PVMFStatus parseMP3(const char *filename,MediaScannerClient& client) {
        PVID3ParCom pvId3Param;
        PVFile fileHandle;
        Oscl_FileServer iFs;
        uint32 duration;
        //LOGD("c---> filename 好的 = %s", filename);
        if (iFs.Connect() != 0) {
            LOGD("=======iFs.Connect failed========>\n");
            return PVMFFailure;
        }

        oscl_wchar output[MAX_BUFF_SIZE];
        oscl_UTF8ToUnicode((const char *) filename, oscl_strlen((const char *) filename),
                           (oscl_wchar *) output, MAX_BUFF_SIZE);
        if (0 !=
            fileHandle.Open((oscl_wchar *) output, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
                            iFs)) {
            //LOGE("Could not open the input file for reading(Test: parse id3).\n");
            return PVMFFailure;
        }

        fileHandle.Seek(0, Oscl_File::SEEKSET);
        pvId3Param.ParseID3Tag(&fileHandle);
        fileHandle.Close();
        iFs.Close();

        //Get the frames information from ID3 library
        PvmiKvpSharedPtrVector framevector;
        pvId3Param.GetID3Frames(framevector);

        uint32 num_frames = framevector.size();

        for (uint32 i = 0; i < num_frames; i++) {
            const char *key = framevector[i]->key;
            bool isUtf8 = false;
            bool isIso88591 = false;

            // type should follow first semicolon
            const char *type = strchr(key, ';');
            if (type == NULL) continue;
            type++;

            char tracknumkeybuf[100];
            if (strncmp(key, "track-info/track-number;", 24) == 0) {
                // Java expects the track number key to be called "tracknumber", so
                // construct a temporary one here.
                snprintf(tracknumkeybuf, sizeof(tracknumkeybuf), "tracknumber;%s", type);
                key = tracknumkeybuf;
            }

            const char *value = framevector[i]->value.pChar_value;

            // KVP_VALTYPE_UTF8_CHAR check must be first, since KVP_VALTYPE_ISO88591_CHAR
            // is a substring of KVP_VALTYPE_UTF8_CHAR.
            // Similarly, KVP_VALTYPE_UTF16BE_WCHAR must be checked before KVP_VALTYPE_UTF16_WCHAR
            if (oscl_strncmp(type, KVP_VALTYPE_UTF8_CHAR, KVP_VALTYPE_UTF8_CHAR_LEN) == 0) {
                isUtf8 = true;
            } else if (
                    oscl_strncmp(type, KVP_VALTYPE_ISO88591_CHAR, KVP_VALTYPE_ISO88591_CHAR_LEN) ==
                    0) {
                isIso88591 = true;
            }

            if (isUtf8) {
                // validate to make sure it is legal utf8
                uint32 valid_chars;
                if (oscl_str_is_valid_utf8((const uint8 *) value, valid_chars)) {
                    // utf8 can be passed through directly
                    //LOGD("c---> key(utf8) = %s  ; value = %s", key, value);
                    if (!client.handleStringTag(key, value)) goto failure;
                } else {
                    // treat as ISO-8859-1 if UTF-8 fails
                    isIso88591 = true;
                }
            }

            if (isIso88591) {
                size_t iInLen = strlen(value);
                char sOutBuf[100];
                size_t iOutLen = 100;
                memset(sOutBuf, 0x00, 100);
                ChangeCode("GBK", "UTF-8", value, &iInLen, sOutBuf, &iOutLen);
                //LOGD("c---> key(gbk) = %s  ; value = %s", key, sOutBuf);
                if (!client.handleStringTag(key, sOutBuf)) goto failure;
            }

            // treat it as iso-8859-1 and our native encoding detection will try to
            // figure out what it is
/*            if (isIso88591) {
                // convert ISO-8859-1 to utf8, worse case is 2x inflation
                const unsigned char *src = (const unsigned char *) value;
                char *temp = (char *) alloca(strlen(value) * 2 + 1);
                if (temp) {
                    char *dest = temp;
                    unsigned int uch;
                    while ((uch = *src++) != 0) {
                        if (uch & 0x80) {
                            *dest++ = (uch >> 6) | 0xc0;
                            *dest++ = (uch & 0x3f) | 0x80;
                        } else *dest++ = uch;
                    }
                    *dest = 0;
                    LOGD("c---> key(iso) = %s  ; value = %s", key, temp);
                    //if (!client.addStringTag(key, temp)) goto failure;
                }
            }*/

            // not UTF-8 or ISO-8859-1, try wide char formats
            if (!isUtf8 && !isIso88591 &&
                (oscl_strncmp(type, KVP_VALTYPE_UTF16BE_WCHAR, KVP_VALTYPE_UTF16BE_WCHAR_LEN) ==
                 0 ||
                 oscl_strncmp(type, KVP_VALTYPE_UTF16_WCHAR, KVP_VALTYPE_UTF16_WCHAR_LEN) == 0)) {
                // convert wchar to utf8
                // the id3parcom library has already taken care of byteswapping
                const oscl_wchar *src = framevector[i]->value.pWChar_value;
                int srcLen = oscl_strlen(src);
                // worse case is 3 bytes per character, plus zero termination
                int destLen = srcLen * 3 + 1;
                char *dest = (char *) alloca(destLen);

                if (oscl_UnicodeToUTF8(src, oscl_strlen(src), dest, destLen) > 0) {
                    //LOGD("c---> key(!utf8 && !iso) = %s  ; value = %s", key, dest);
                    if (!client.handleStringTag(key, dest)) goto failure;
                }
            } else if (oscl_strncmp(type, KVP_VALTYPE_UINT32, KVP_VALTYPE_UINT32_LEN) == 0) {
                char temp[20];
                snprintf(temp, sizeof(temp), "%d", (int) framevector[i]->value.uint32_value);
                //LOGD("c---> key() = %s  ; value = %s", key, temp);
                if (!client.handleStringTag(key, temp)) goto failure;
            } else {
                //LOGE("unknown tag type %s for key %s\n", type, key);
            }
        }

        // extract non-ID3 properties below
        {
            OSCL_wHeapString<OsclMemAllocator> mp3filename(output);
            MP3ErrorType err;
            IMpeg3File mp3File(mp3filename, err);
            if (err != MP3_SUCCESS) {
                //LOGE("IMpeg3File constructor returned %d for %s\n", err, filename);
                return err;
            }
            err = mp3File.ParseMp3File();
            if (err != MP3_SUCCESS) {
                //LOGE("IMpeg3File::ParseMp3File returned %d for %s\n", err, filename);
                return err;
            }

            char buffer[20];
            duration = mp3File.GetDuration();
            sprintf(buffer, "%d", duration);
            LOGD("c---> duration = %s", "duration");
            //if (!client.addStringTag("duration", buffer)) goto failure;
        }

        return PVMFSuccess;

        failure:
        return PVMFFailure;
    }
static PVMFStatus parseMP3(const char *filename, MediaScannerClient& client)
{
    PVID3ParCom pvId3Param;
    PVFile fileHandle;
    Oscl_FileServer iFs;
    uint32 duration;

    if (iFs.Connect() != 0)
    {
        LOGE("iFs.Connect failed\n");
        return PVMFFailure;
    }

    oscl_wchar output[MAX_BUFF_SIZE];
    oscl_UTF8ToUnicode((const char *)filename, oscl_strlen((const char *)filename), (oscl_wchar *)output, MAX_BUFF_SIZE);
    if (0 != fileHandle.Open((oscl_wchar *)output, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, iFs) )
    {
        LOGE("Could not open the input file for reading(Test: parse id3).\n");
        return PVMFFailure;
    }

    fileHandle.Seek(0, Oscl_File::SEEKSET);
    pvId3Param.ParseID3Tag(&fileHandle);
    fileHandle.Close();
    iFs.Close();

    //Get the frames information from ID3 library
    PvmiKvpSharedPtrVector framevector;
    pvId3Param.GetID3Frames(framevector);

    uint32 num_frames = framevector.size();

    for (uint32 i = 0; i < num_frames;i++)
    {
        const char* key = framevector[i]->key;
        bool validUtf8 = true;

        // type should follow first semicolon
        const char* type = strchr(key, ';') + 1;
        if (type == 0) continue;
        
        const char* value = framevector[i]->value.pChar_value;

        // KVP_VALTYPE_UTF8_CHAR check must be first, since KVP_VALTYPE_ISO88591_CHAR 
        // is a substring of KVP_VALTYPE_UTF8_CHAR.
        // Similarly, KVP_VALTYPE_UTF16BE_WCHAR must be checked before KVP_VALTYPE_UTF16_WCHAR
        if (oscl_strncmp(type, KVP_VALTYPE_UTF8_CHAR, KVP_VALTYPE_UTF8_CHAR_LEN) == 0) {
            // utf8 can be passed through directly
            // but first validate to make sure it is legal utf8
            uint32 valid_chars;
            validUtf8 = oscl_str_is_valid_utf8((const uint8 *)value, valid_chars);
            if (validUtf8 && !client.handleStringTag(key, value)) goto failure;
        } 

        // if the value is not valid utf8, then we will treat it as iso-8859-1 
        // and our native encoding detection will try to figure out what it is
        if (oscl_strncmp(type, KVP_VALTYPE_ISO88591_CHAR, KVP_VALTYPE_ISO88591_CHAR_LEN) == 0 
                || !validUtf8) {
            // iso-8859-1
            // convert to utf8
            // worse case is 2x inflation
            const unsigned char* src = (const unsigned char *)value;
            char* temp = (char *)alloca(strlen(value) * 2 + 1);
            if (temp) {
                char* dest = temp;
                unsigned int uch;
                while ((uch = *src++) != 0) {
                    if (uch & 0x80) {
                        *dest++ = (uch >> 6) | 0xc0;
                        *dest++ = (uch & 0x3f) | 0x80;
                    } else *dest++ = uch;
                }
                *dest = 0;
                if (!client.addStringTag(key, temp)) goto failure;           
            }
        } else if (oscl_strncmp(type, KVP_VALTYPE_UTF16BE_WCHAR, KVP_VALTYPE_UTF16BE_WCHAR_LEN) == 0 ||