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; } } }
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 ||