MpCodecSubInfo* MpCodecFactory::searchByMIME(const UtlString& mime, int sampleRate, int numChannels) const { // Create a lower case copy of MIME-subtype string. UtlString mime_copy(mime); mime_copy.toLower(); // Create iterator to list all codecs with given MIME subtype. UtlHashBagIterator iter(mCodecsInfo, &mime_copy); MpCodecSubInfo* pInfo; while ((pInfo = (MpCodecSubInfo*)iter())) { if ((int)(pInfo->getCodecInfo()->sampleRate) == sampleRate && (int)(pInfo->getCodecInfo()->numChannels) == numChannels) { return pInfo; } } return NULL; /* // Create a lower case copy of MIME-subtype string. UtlString mime_copy(mime); mime_copy.toLower(); // Perform search return (MpCodecSubInfo*)mCodecsInfo.find(&mime_copy); */ }
OsStatus MpCodecFactory::createEncoder(const UtlString &mime, const UtlString &fmtp, int sampleRate, int numChannels, int payloadType, MpEncoderBase*& rpEncoder) const { MpCodecSubInfo* codec = searchByMIME(mime, sampleRate, numChannels); if (codec) { rpEncoder = new MpEncoderBase(payloadType, *codec->getCodecCall(), *codec->getCodecInfo(), fmtp); } else { OsSysLog::add(FAC_MP, PRI_ERR, "MpCodecFactory::createEncoder unknown codec type " "%s, fmtp=%s" "payloadType = %d", mime.data(), fmtp.data(), payloadType); rpEncoder=NULL; } if (NULL != rpEncoder) { return OS_SUCCESS; } return OS_INVALID_ARGUMENT; }
void MpCodecFactory::addCodecsToList(SdpCodecList &codecList) const { UtlHashBagIterator iter(mCodecsInfo); MpCodecSubInfo* pCodec; while ((pCodec = (MpCodecSubInfo*)iter())) { const MppCodecInfoV1_1 *pCodecInfo = pCodec->getCodecInfo(); if (pCodecInfo->fmtpsNum == 0) { SdpCodec::SdpCodecTypes codecType; OsStatus res = SdpDefaultCodecFactory::getCodecType(pCodecInfo->mimeSubtype, pCodecInfo->sampleRate, pCodecInfo->numChannels, "", codecType); OsSysLog::add(FAC_MP, PRI_DEBUG, "Codec added to list: [%3d]:%s/%d/%d fmtp=\"%s\"\n", res==OS_SUCCESS?codecType:-1, pCodecInfo->mimeSubtype, pCodecInfo->sampleRate, pCodecInfo->numChannels, ""); if (res == OS_SUCCESS) { codecList.addCodec(SdpDefaultCodecFactory::getCodec(codecType)); } } else { for (unsigned fmtpIdx=0; fmtpIdx<pCodecInfo->fmtpsNum; fmtpIdx++) { SdpCodec::SdpCodecTypes codecType; OsStatus res = SdpDefaultCodecFactory::getCodecType(pCodecInfo->mimeSubtype, pCodecInfo->sampleRate, pCodecInfo->numChannels, pCodecInfo->fmtps[fmtpIdx], codecType); OsSysLog::add(FAC_MP, PRI_DEBUG, "Codec added to list: [%3d]:%s/%d/%d fmtp=\"%s\"\n", res==OS_SUCCESS?codecType:-1, pCodecInfo->mimeSubtype, pCodecInfo->sampleRate, pCodecInfo->numChannels, pCodecInfo->fmtps[fmtpIdx]); if (res == OS_SUCCESS) { codecList.addCodec(SdpDefaultCodecFactory::getCodec(codecType)); } } } } }
MpCodecSubInfo* MpCodecFactory::searchByMIME(const UtlString& mime, int sampleRate, int numChannels) const { // Create a lower case copy of MIME-subtype string. UtlString mime_copy(mime); mime_copy.toLower(); int _sampleRate = sampleRate; if(mime == "G722" && sampleRate == 8000) { // From RFC 3551 s4.5.2: // // Even though the actual sampling rate for G.722 audio is 16,000 Hz, // the RTP clock rate for the G722 payload format is 8,000 Hz because // that value was erroneously assigned in RFC 1890 and must remain // unchanged for backward compatibility. The octet rate or sample-pair // rate is 8,000 Hz. // // Therefore, when the codec is G722 and we see 8000 in RTP, we need // to look for the standard 16000 codec implementation. // // This is often described as a hack, but it is a hack specified by the RFC // and we have to live with it. Some implementations may not implement // the hack correctly and may not interoperate. _sampleRate = 16000; } // Create iterator to list all codecs with given MIME subtype. UtlHashBagIterator iter(mCodecsInfo, &mime_copy); MpCodecSubInfo* pInfo; while ((pInfo = (MpCodecSubInfo*)iter())) { if (pInfo->getCodecInfo()->sampleRate == _sampleRate && pInfo->getCodecInfo()->numChannels == numChannels) { return pInfo; } } return NULL; /* // Create a lower case copy of MIME-subtype string. UtlString mime_copy(mime); mime_copy.toLower(); // Perform search return (MpCodecSubInfo*)mCodecsInfo.find(&mime_copy); */ }
void MpCodecFactory::updateCodecInfoCache() const { // First delete old data. delete[] mpCodecInfoCache; // Allocate memory for new array. mCachedCodecInfoNum = mCodecsInfo.entries(); mpCodecInfoCache = new const MppCodecInfoV1_1*[mCachedCodecInfoNum]; // Fill array with data. UtlHashBagIterator iter(mCodecsInfo); for (unsigned i=0; i<mCachedCodecInfoNum; i++) { MpCodecSubInfo* pInfo = (MpCodecSubInfo*)iter(); mpCodecInfoCache[i] = pInfo->getCodecInfo(); } // Cache successfully updated. mCodecInfoCacheValid = TRUE; }