bool Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport, SIP_PDU & pdu) { if (pdu.GetMIME().GetContentType(false) != "text/plain") return false; // Ignore what we do not handle. PString from = pdu.GetMIME().GetFrom(); PINDEX j = from.Find (';'); if (j != P_MAX_INDEX) from = from.Left(j); // Remove all parameters j = from.Find ('<'); if (j != P_MAX_INDEX && from.Find ('>') == P_MAX_INDEX) from += '>'; SIPURL uri = from; uri.Sanitise (SIPURL::RequestURI); std::string display_name = (const char *) uri.GetDisplayName (); std::string message_uri = (const char *) uri.AsString (); std::string _message = (const char *) pdu.GetEntityBody (); Ekiga::Runtime::run_in_main (boost::bind (&Opal::Sip::EndPoint::push_message_in_main, this, message_uri, display_name, _message)); return SIPEndPoint::OnReceivedMESSAGE (transport, pdu); }
bool Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport, SIP_PDU & pdu) { PString *last = NULL; PString *val = NULL; PString from = pdu.GetMIME().GetFrom(); PINDEX j = from.Find (';'); if (j != P_MAX_INDEX) from = from.Left(j); // Remove all parameters j = from.Find ('<'); if (j != P_MAX_INDEX && from.Find ('>') == P_MAX_INDEX) from += '>'; PWaitAndSignal m(msgDataMutex); last = msgData.GetAt (SIPURL (from).AsString ()); if (!last || *last != pdu.GetMIME ().GetFrom ()) { val = new PString (pdu.GetMIME ().GetFrom ()); msgData.SetAt (SIPURL (from).AsString (), val); SIPURL uri = from; uri.Sanitise (SIPURL::RequestURI); std::string display_name = (const char *) uri.GetDisplayName (); std::string message_uri = (const char *) uri.AsString (); std::string _message = (const char *) pdu.GetEntityBody (); runtime.run_in_main (sigc::bind (sigc::ptr_fun (push_message_in_main), dialect, message_uri, display_name, _message)); } return SIPEndPoint::OnReceivedMESSAGE (transport, pdu); }
bool Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport, SIP_PDU & pdu) { if (pdu.GetMIME().GetContentType(false) != "text/plain") return false; // Ignore what we do not handle. PString from = pdu.GetMIME().GetFrom(); PINDEX j = from.Find (';'); if (j != P_MAX_INDEX) from = from.Left(j); // Remove all parameters j = from.Find ('<'); if (j != P_MAX_INDEX && from.Find ('>') == P_MAX_INDEX) from += '>'; SIPURL uri = from; uri.Sanitise (SIPURL::RequestURI); std::string display_name = (const char *) uri.GetDisplayName (); std::string message_uri = (const char *) uri.AsString (); std::string _message = (const char *) pdu.GetEntityBody (); Ekiga::Message::payload_type payload; // FIXME: we push as 'text/plain' without really knowing payload.insert (std::make_pair ("text/plain", _message)); GTimeVal current; g_get_current_time (¤t); gchar* time = g_time_val_to_iso8601 (¤t); Ekiga::Message msg = {time, display_name, payload }; g_free (time); Ekiga::Runtime::run_in_main (boost::bind (&Opal::Sip::EndPoint::push_message_in_main, this, message_uri, msg)); return SIPEndPoint::OnReceivedMESSAGE (transport, pdu); }
PString XMH323URL::GetDisplayName() { PINDEX paramIndex; PString s = AsString(); s.Replace("h323:", ""); paramIndex = s.Find(';'); if (paramIndex != P_MAX_INDEX) { s = s.Left(paramIndex); } return s; }
bool PVideoOutputDevice_EKIGA::Open (const PString &name, G_GNUC_UNUSED bool unused) { if (name == "EKIGAIN") { device_id = LOCAL; } else { // EKIGAOUT PString devname = name; PINDEX id = devname.Find("ID="); device_id = REMOTE + atoi(&devname[id + 3]); } return TRUE; }
unsigned XMMediaStream::GetKeyFrameInterval(XMCodecIdentifier codecIdentifier) { XMCallProtocol callProtocol = XMEndPoint::GetCallProtocolForCall(connection); PString remoteApplicationString = XMOpalManager::GetRemoteApplicationString(connection.GetRemoteProductInfo()); // Polycom MGC (Accord MGC) has problems decoding QuickTime H.263. If at all, only I-frames should be sent. if (codecIdentifier == XMCodecIdentifier_H263 && remoteApplicationString.Find("ACCORD MGC") != P_MAX_INDEX) { // zero key frame interval means sending only I-frames return 0; } switch (callProtocol) { case XMCallProtocol_H323: return 200; case XMCallProtocol_SIP: return 60; default: return 0; } }
bool APPlayerInfo::GetModuleInformation(int32 line, PString &description, PString &value) { PString tempStr; int32 index; PLock lock(&varLock); // Is the line number out of range? if (line >= modInfo.CountItems()) return (false); // Get the information tempStr = modInfo.GetItem(line); // Find the spliter character between the description and value index = tempStr.Find('\t'); if (index == -1) return (false); // Extract the information description = tempStr.Left(index); value = tempStr.Mid(index + 1); return (true); }
virtual bool ValidateDeviceName (const PString & deviceName, int) const { return deviceName.Find ("EKIGA") == 0; }
void Opal::Sip::EndPoint::OnRegistrationStatus (const RegistrationStatus & status) { std::string info; boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store"); if (!bank) return; Opal::AccountPtr account = bank->find_account (status.m_addressofRecord); if (!account) return; if (status.m_reason == SIP_PDU::Information_Trying) return; SIPEndPoint::OnRegistrationStatus (status); /* Only handle registration state transitions we are interested in. * * For example, if we were registering, we are interested in knowing if * the registration was successful or not. If the registration was not * successful and OPAL cleanly unregisters the account (as a consequence), * we are not interested in knowing the unregistration worked. */ if (status.m_wasRegistering != account->is_enabled ()) return; /* Successful registration or unregistration */ if (status.m_reason == SIP_PDU::Successful_OK) { Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account, status.m_wasRegistering?Account::Registered:Account::Unregistered, std::string (), status.m_addressofRecord)); } /* Registration or unregistration failure */ else { SIPURL m_addressOfRecord = SIPURL (status.m_addressofRecord); /* Try again in UDP mode */ if (m_addressOfRecord.GetTransportProto () == "TCP") { SIPRegister::Params params; PString _aor; m_addressOfRecord.SetParamVar ("transport", "udp"); if (m_addressOfRecord.GetParamVars ().Contains ("OPAL-proxy")) { PString proxy = m_addressOfRecord.GetParamVars().Get ("OPAL-proxy"); PINDEX p = proxy.Find (";"); if (p != P_MAX_INDEX) proxy = proxy.Left (p); m_addressOfRecord.SetParamVar ("OPAL-proxy", proxy); } params.m_addressOfRecord = m_addressOfRecord; params.m_instanceId = GetInstanceID (); params.m_compatibility = SIPRegister::e_RFC5626; params.m_authID = status.m_handler->GetAuthID (); params.m_password = status.m_handler->GetPassword (); params.m_expire = status.m_handler->GetExpire (); params.m_minRetryTime = PMaxTimeInterval; // use default value params.m_maxRetryTime = PMaxTimeInterval; // use default value if (status.m_handler->ShutDown ()) activeSIPHandlers.Remove (status.m_handler); // Make sure the TCP handler is deleted // or it will be retried indefinitely. SIPEndPoint::Register (params, _aor); return; } /* all these codes are defined in opal, file include/sip/sippdu.h */ switch (status.m_reason) { case SIP_PDU::IllegalStatusCode: info = _("Illegal status code"); break; case SIP_PDU::Local_TransportError: info = _("Transport error"); break; case SIP_PDU::Local_BadTransportAddress: info = _("Invalid address"); break; case SIP_PDU::Local_Timeout: /* Translators: Host of the remote party is offline, this should * appear when the remote host does not reply in an acceptable time */ info = _("Remote party host is offline"); break; case SIP_PDU::Information_Trying: case SIP_PDU::Information_Ringing: case SIP_PDU::Information_CallForwarded: case SIP_PDU::Information_Queued: case SIP_PDU::Information_Session_Progress: case SIP_PDU::Successful_OK: case SIP_PDU::Successful_Accepted: break; case SIP_PDU::Redirection_MultipleChoices: /* Translators: the following strings are answers from the SIP server * when the packet it receives has an error, see * http://www.ietf.org/rfc/rfc3261.txt, chapter 21 for more information */ info = _("Multiple choices"); break; case SIP_PDU::Redirection_MovedPermanently: info = _("Moved permanently"); break; case SIP_PDU::Redirection_MovedTemporarily: info = _("Moved temporarily"); break; case SIP_PDU::Redirection_UseProxy: info = _("Use proxy"); break; case SIP_PDU::Redirection_AlternativeService: info = _("Alternative service"); break; case SIP_PDU::Failure_BadRequest: info = _("Bad request"); break; case SIP_PDU::Failure_UnAuthorised: info = _("Unauthorized"); break; case SIP_PDU::Failure_PaymentRequired: info = _("Payment required"); break; case SIP_PDU::Failure_Forbidden: info = _("Forbidden, please check that username and password are correct"); break; case SIP_PDU::Failure_NotFound: info = _("Not found"); break; case SIP_PDU::Failure_MethodNotAllowed: info = _("Method not allowed"); break; case SIP_PDU::Failure_NotAcceptable: info = _("Not acceptable"); break; case SIP_PDU::Failure_ProxyAuthenticationRequired: info = _("Proxy authentication required"); break; case SIP_PDU::Failure_RequestTimeout: info = _("Timeout"); break; case SIP_PDU::Failure_Conflict: info = _("Conflict"); break; case SIP_PDU::Failure_LengthRequired: info = _("Length required"); break; case SIP_PDU::Failure_RequestEntityTooLarge: info = _("Request entity too big"); break; case SIP_PDU::Failure_RequestURITooLong: info = _("Request URI too long"); break; case SIP_PDU::Failure_UnsupportedMediaType: info = _("Unsupported media type"); break; case SIP_PDU::Failure_UnsupportedURIScheme: info = _("Unsupported URI scheme"); break; case SIP_PDU::Failure_BadExtension: /* Translators: The extension we are trying to register does not exist. * Here extension is a specific "phone number", see * http://en.wikipedia.org/wiki/Extension_(telephone) * for more information */ info = _("Bad extension"); break; case SIP_PDU::Failure_ExtensionRequired: info = _("Extension required"); break; case SIP_PDU::Failure_IntervalTooBrief: info = _("Interval too brief"); break; case SIP_PDU::Failure_TemporarilyUnavailable: info = _("Temporarily unavailable"); break; case SIP_PDU::Failure_LoopDetected: info = _("Loop detected"); break; case SIP_PDU::Failure_TooManyHops: info = _("Too many hops"); break; case SIP_PDU::Failure_AddressIncomplete: info = _("Address incomplete"); break; case SIP_PDU::Failure_Ambiguous: info = _("Ambiguous"); break; case SIP_PDU::Failure_BusyHere: info = _("Busy Here"); break; case SIP_PDU::Failure_RequestTerminated: info = _("Request terminated"); break; case SIP_PDU::Failure_NotAcceptableHere: info = _("Not acceptable here"); break; case SIP_PDU::Failure_BadEvent: info = _("Bad event"); break; case SIP_PDU::Failure_RequestPending: info = _("Request pending"); break; case SIP_PDU::Failure_Undecipherable: info = _("Undecipherable"); break; case SIP_PDU::Failure_InternalServerError: info = _("Internal server error"); break; case SIP_PDU::Failure_NotImplemented: info = _("Not implemented"); break; case SIP_PDU::Failure_BadGateway: info = _("Bad gateway"); break; case SIP_PDU::Failure_ServiceUnavailable: info = _("Service unavailable"); break; case SIP_PDU::Failure_ServerTimeout: info = _("Server timeout"); break; case SIP_PDU::Failure_SIPVersionNotSupported: info = _("SIP version not supported"); break; case SIP_PDU::Failure_MessageTooLarge: info = _("Message too large"); break; case SIP_PDU::GlobalFailure_BusyEverywhere: info = _("Busy everywhere"); break; case SIP_PDU::GlobalFailure_Decline: info = _("Decline"); break; case SIP_PDU::GlobalFailure_DoesNotExistAnywhere: info = _("Does not exist anymore"); break; case SIP_PDU::GlobalFailure_NotAcceptable: info = _("Globally not acceptable"); break; case SIP_PDU::Local_NotAuthenticated: info = _("Invalid certificates"); break; case SIP_PDU::Failure_TransactionDoesNotExist: case SIP_PDU::Failure_Gone: case SIP_PDU::MaxStatusCode: case SIP_PDU::Local_NoCompatibleListener: case SIP_PDU::Local_CannotMapScheme: case SIP_PDU::Local_KeepAlive: case SIP_PDU::Local_TransportLost: case SIP_PDU::Failure_UnresolvableDestination: default: info = _("Failed"); } /* Opal adds a RequestTerminated, and this should not be shown to user, * as a sip code has already been scheduled to be shown */ if (status.m_reason != SIP_PDU::Failure_RequestTerminated) { Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account, status.m_wasRegistering?Account::RegistrationFailed:Account::UnregistrationFailed, info, std::string ())); } } }
BOOL CMyPhoneEndPoint::OpenVideoChannel(H323Connection & connection, BOOL isEncoding, H323VideoCodec & codec) { PVideoChannel * channel = new PVideoChannel; PVideoDevice * displayDevice = NULL; if (isEncoding) { // Transmitter part if(!autoStartTransmitVideo) return FALSE; codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,15)); codec.SetBackgroundFill(2); int videoOutMaxBitRate = config.GetInteger(VideoOutMaxbandWidthKey, 320); videoOutMaxBitRate = 1024 * PMAX(16, PMIN(10240, videoOutMaxBitRate)); H323Channel * lchannel = codec.GetLogicalChannel(); const H323Capability & capability = lchannel->GetCapability(); PString cname = capability.GetFormatName(); PINDEX suffixPos = cname.Find("H.263"); if(suffixPos == P_MAX_INDEX) suffixPos = cname.Find("H.261"); int videoSize = config.GetInteger(VideoOutSizeConfigKey, 2); int width=352, height=288; suffixPos = P_MAX_INDEX; switch(videoSize) { case 0: //QCIF width = 176; height = 144; break; case 1: //QVGA if(suffixPos == P_MAX_INDEX) { width = 320; height = 240; break; } case 2: //CIF width = 352; height = 288; break; case 3: //VGA if(suffixPos == P_MAX_INDEX) { width = 640; height = 480; break; } case 5: //SVGA if(suffixPos == P_MAX_INDEX) { width = 800; height = 600; break; } case 6: //XVGA if(suffixPos == P_MAX_INDEX) { width = 1024; height = 768; break; } case 4: //4CIF width = 704; height = 576; break; case 7: //HD 720 if(suffixPos == P_MAX_INDEX) { width = 1280; height = 720; break; } case 8: //SXGA if(suffixPos == P_MAX_INDEX) { width = 1280; height = 1024; break; } case 9: //16CIF width = 1408; height = 1152; break; case 10: //UXGA if(suffixPos == P_MAX_INDEX) { width = 1600; height = 1200; break; } case 11: //HD 1080 if(suffixPos == P_MAX_INDEX) { width = 1920; height = 1080; break; } default: break; } PTRACE(1, "Video device videoSize=" << videoSize << " width=" << width << " height=" << height); codec.SetVideoSize(width, height); width = codec.GetWidth(); height = codec.GetHeight(); PTRACE(1, "Accepted video device width=" << width << " height=" << height); int curMBR = codec.GetMaxBitRate(); if(curMBR > videoOutMaxBitRate) codec.SetMaxBitRate(videoOutMaxBitRate); int videoFramesPS = config.GetInteger(VideoFPSKey, 10); codec.SetGeneralCodecOption("Frame Rate",videoFramesPS); //Create grabber. bool NoDevice = false; PString deviceName = config.GetString(VideoDeviceConfigKey, deviceName); if (deviceName.IsEmpty()) { PStringArray devices = PVideoInputDevice::GetDriversDeviceNames(VideoInputDriver); if (!devices.IsEmpty()) deviceName = devices[0]; else NoDevice = true; } PVideoInputDevice * grabber = NULL; if (deviceName.Find("fake") == 0) NoDevice = true; // else if (deviceName.Find("screen") == 0) grabber = PVideoInputDevice::CreateDevice("ScreenVideo"); else grabber = PVideoInputDevice::CreateDeviceByName(deviceName,VideoInputDriver); if (NoDevice || !grabber->Open(deviceName, FALSE) || !grabber->SetFrameSize(width, height) || !grabber->SetColourFormatConverter("YUV420P") || !grabber->SetVFlipState(localFlip)) { if(!NoDevice) { char sSrc[64]; m_dialog->OutputStatusStr((LPCTSTR)LoadStringLang(IDS_ERRVDEVSTR), S_SYSTEM, (const char *) deviceName, itoa(config.GetInteger(VideoSourceConfigKey,0), sSrc, 10)); PTRACE(1, "Failed to open or configure the video device \"" << deviceName << '"'); } if(grabber) delete grabber; grabber = PVideoInputDevice::CreateDevice("FakeVideo"); grabber->SetColourFormat("YUV420P"); grabber->SetVideoFormat(PVideoDevice::PAL); grabber->SetFrameSize(width, height); grabber->SetVFlipState(localFlip); grabber->SetChannel(4); } if(videoFramesPS >0 && videoFramesPS<30) grabber->SetFrameRate(videoFramesPS); grabber->Start(); channel->AttachVideoReader(grabber); /* if (localVideo) { BOOL curVFlip = config.GetBoolean(VideoOutVFlipConfigKey, FALSE); BOOL curHFlip = config.GetBoolean(VideoOutHFlipConfigKey, FALSE); displayDevice = new CVideoOutputDevice(m_dialog, connection.GetLocalPartyName(), curVFlip, curHFlip, TRUE, FALSE); } else */ displayDevice = PVideoOutputDevice::CreateDevice("NULLOutput"); } else { // Receiver part if(!autoStartReceiveVideo) return FALSE; BOOL curVFlip = config.GetBoolean(VideoInVFlipConfigKey, FALSE); BOOL curHFlip = config.GetBoolean(VideoInHFlipConfigKey, FALSE); displayDevice = new CVideoOutputDevice( m_vdlg, (LPCTSTR)m_dialog->FindContactName(connection), curVFlip, curHFlip, FALSE, localVideo); } if(displayDevice) { int width = codec.GetWidth(); int height = codec.GetHeight(); // if( m_dialog->autohideVideoPan && !m_dialog->showVideoPan) // m_dialog->ShowVideoPanels(TRUE); // show Video panel if it's hiden displayDevice->SetColourFormat("RGB32"); displayDevice->SetColourFormatConverter("YUV420P"); displayDevice->SetFrameSize(width, height); //Give the video window refreshing class to the channel. channel->AttachVideoPlayer((PVideoOutputDevice *)displayDevice); } return codec.AttachChannel(channel,TRUE); }
void CMyPhoneEndPoint::LoadCapabilities() { BOOL sizeChange = FALSE; capabilities.RemoveAll(); // Add the codecs we know about AddAllCapabilities(0, 0, "*"); // Удаляю не поддерживаемые видео кодеки из реестра PINDEX videoNum = 0; for (;;) { PString key = psprintf("%u", ++videoNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = videoNum; videoNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(VideoCodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(VideoCodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(VideoCodecsConfigSection, psprintf("%u", j-1)); } } // добавляю новые видео кодеки если их нет в конфигурации for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(VideoCodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } PINDEX audioNum = 0; for (;;) { PString key = psprintf("%u", ++audioNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } int res = 0; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { if(capabilities[i].GetFormatName() == name) { res = 1; break; } } } if(res == 0) { PINDEX j = audioNum; audioNum--; for (;;) { PString key1 = psprintf("%u", ++j); PString name1 = config.GetString(CodecsConfigSection, key1, ""); if (name1.IsEmpty()) break; config.SetString(CodecsConfigSection, psprintf("%u", j-2), name1); } config.DeleteKey(CodecsConfigSection, psprintf("%u", j-1)); } } for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { PINDEX codecNum=0; int res = 0; int suffix = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; suffix = 0; PINDEX suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); else { suffix = 1; suffixPos = name.Find(OffCodecSuffix); name.Delete(suffixPos, P_MAX_INDEX); } if(capabilities[i].GetFormatName() == name) { res = 1; break; } } if(res == 0) { config.SetString(CodecsConfigSection, psprintf("%u", codecNum), capabilities[i].GetFormatName() + ((suffix==0)?OnCodecSuffix:OffCodecSuffix)); } } } // Add all the UserInput capabilities AddAllUserInputCapabilities(0, 1); int videoSizeRx = config.GetInteger(VideoInSizeConfigKey, 2); int videoSizeTx = config.GetInteger(VideoOutSizeConfigKey, 2); RemoveCapability(H323Capability::e_ExtendVideo); autoStartTransmitVideo = config.GetBoolean(AutoTransmitVideoConfigKey, TRUE); autoStartReceiveVideo = config.GetBoolean(AutoReceiveVideoConfigKey, TRUE); localVideo = config.GetBoolean(VideoLocalConfigKey, FALSE); localFlip = config.GetBoolean(VideoFlipLocalConfigKey, FALSE); int videoInMaxBitRate = config.GetInteger(VideoInMaxbandWidthKey, 320); videoInMaxBitRate = 1024 * PMAX(16, PMIN(10240, videoInMaxBitRate)); // changing audio codecs PStringArray enabledCodecs; PINDEX codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(CodecsConfigSection, key, ""); if (name.IsEmpty()) break; PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); enabledCodecs.AppendString(name); } codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; } int tvNum = 0; // if(tvCaps==NULL) this generates error in free tvCaps = (char **)calloc(codecNum+1,sizeof(char *)); // while(tvCaps[tvNum]!=NULL) { free(tvCaps[tvNum]); tvCaps[tvNum]=NULL; tvNum++; } tvNum = 0; codecNum = 0; for (;;) { PString key = psprintf("%u", ++codecNum); PString name = config.GetString(VideoCodecsConfigSection, key, ""); if (name.IsEmpty()) break; // удаление отключенных кодеков PINDEX suffixPos = name.Find(OffCodecSuffix); if (suffixPos != P_MAX_INDEX) { capabilities.Remove(name(0, suffixPos-1)); continue; } // удаление суффикса on из имени кодека suffixPos = name.Find(OnCodecSuffix); if (suffixPos != P_MAX_INDEX) name.Delete(suffixPos, P_MAX_INDEX); // проверка кодека на соответствие размеру принимаемой картинки // (меньше можно, больше нельзя) и удаление из списка локальных кодеков suffixPos = P_MAX_INDEX; switch(videoSizeRx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; case 7: //SXGA suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 8: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) enabledCodecs.AppendString(name); else capabilities.Remove(name); // проверка кодека на соответствие размеру отправляемой картинки // (меньше можно, больше нельзя) и создание списка допустимых кодеков suffixPos = P_MAX_INDEX; switch(videoSizeTx) { case 0: //QCIF suffixPos = name.Find("-CIF"); if(suffixPos != P_MAX_INDEX) break; case 1: //QVGA case 2: //CIF suffixPos = name.Find("-4CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-480P"); if(suffixPos != P_MAX_INDEX) break; case 3: //VGA case 4: //4CIF suffixPos = name.Find("-SD"); if(suffixPos != P_MAX_INDEX) break; case 5: //SVGA case 6: //XVGA suffixPos = name.Find("-HD"); if(suffixPos != P_MAX_INDEX) break; case 7: //HD 720 suffixPos = name.Find("-720P"); if(suffixPos != P_MAX_INDEX) break; case 8: //SXGA suffixPos = name.Find("-16CIF"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-FHD"); if(suffixPos != P_MAX_INDEX) break; suffixPos = name.Find("-1080P"); if(suffixPos != P_MAX_INDEX) break; case 9: //16CIF default: break; } if(suffixPos == P_MAX_INDEX) // добавляю в список допустимых { const char *p2pstr=name; tvCaps[tvNum]=strdup(p2pstr); tvNum++; } } // Reorder the codecs we have capabilities.Reorder(enabledCodecs); for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Video) { capabilities[i].SetMediaFormatOptionInteger(OpalVideoFormat::MaxBitRateOption, videoInMaxBitRate); if((capabilities[i].GetFormatName().Find("H.264")!=P_MAX_INDEX) || (capabilities[i].GetFormatName().Find("VP8-")==0)) { H323GenericVideoCapability *h264cap = (H323GenericVideoCapability *) &capabilities[i]; h264cap->SetMaxBitRate(videoInMaxBitRate/100); } } } /* PINDEX audioNum = 1; PINDEX videoNum = 1; for (PINDEX i = 0; i < capabilities.GetSize(); i++) { if (capabilities[i].GetMainType() == H323Capability::e_Audio) { config.SetString(CodecsConfigSection, psprintf("%u", audioNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } else if (capabilities[i].GetMainType() == H323Capability::e_Video) { config.SetString(VideoCodecsConfigSection, psprintf("%u", videoNum++), capabilities[i].GetFormatName() + OnCodecSuffix); } } */ PTRACE(1, "MyPhone\tCapability Table:\n" << setprecision(4) << capabilities); }
void CVisualPage::OnCamSetupButton() { CComboBox * box = (CComboBox*)(GetDlgItem(IDC_RECORDING_COMBO)); int i = box->GetCurSel(); int n = box->GetLBTextLen(i); CString s; box->GetLBText(i, s.GetBuffer(n)); PString setupDeviceName = s; s.ReleaseBuffer(); if (setupDeviceName.IsEmpty()) return; if (setupDeviceName.Find("fake") == 0) return; if (setupDeviceName.Find("monitor") == 0) return; if (setupDeviceName.Find("zmonitor") == 0) return; PTRACE(4,"PVidDirectShow\tCurrent device: " << setupDeviceName); HRESULT hr; IBaseFilter * pFilter = NULL; IMoniker *pMoniker =NULL; ICreateDevEnum *pDevEnum =NULL; IEnumMoniker *pClassEnum = NULL; ULONG cFetched; ::CoInitialize(NULL); // Create the system device enumerator hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &pDevEnum); if (FAILED(hr)) { ::CoUninitialize(); return; } // Create an enumerator for the video capture devices hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); if (FAILED(hr)) { ::CoUninitialize(); return; } if (pClassEnum == NULL) { ::CoUninitialize(); return; } PTRACE(4,"PVidDirectShow\tEntering device enumeration loop..."); while (1) { // Get the next device hr = pClassEnum->Next(1, &pMoniker, &cFetched); if (hr != S_OK) { PTRACE(4, "PVidDirectShow\tGetInputDeviceNames() No more video capture device"); break; } // Get the property bag IPropertyBag *pPropBag; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag)); if (FAILED(hr)) { PTRACE(4,"PVidDerectShow\tBindToStorage failed, continue"); pMoniker->Release(); continue; } // Find the description or friendly name. VARIANT DeviceName; DeviceName.vt = VT_BSTR; hr = pPropBag->Read(L"Description", &DeviceName, NULL); if (FAILED(hr)) hr = pPropBag->Read(L"FriendlyName", &DeviceName, NULL); if (SUCCEEDED(hr)) { char *pDeviceName = BSTR_to_ANSI(DeviceName.bstrVal); if (pDeviceName) { PTRACE(4, "PVidDirectShow\tGetInputDeviceNames() Found this capture device '"<< pDeviceName <<"'"); if(PString(pDeviceName) == setupDeviceName) { PTRACE(4, "PVidDirectShow\tCamera Setup: device found"); pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**) &pFilter); ISpecifyPropertyPages *p_spec; CAUUID cauuid; HRESULT hr = pFilter->QueryInterface( IID_ISpecifyPropertyPages, (void **)&p_spec ); if( !FAILED(hr) ) if( SUCCEEDED(p_spec->GetPages( &cauuid )) ) { if( cauuid.cElems > 0 ) { HWND hwnd_desktop = ::GetDesktopWindow(); OleCreatePropertyFrame( hwnd_desktop, 30, 30, NULL, 1, (LPUNKNOWN *)(&pFilter), cauuid.cElems, cauuid.pElems, 0, 0, NULL ); CoTaskMemFree( cauuid.pElems ); } p_spec->Release(); } } free(pDeviceName); } } pPropBag->Release(); pMoniker->Release(); } ::CoUninitialize(); }
bool SIDStil::GetField(PString &result, PString buffer, int32 tuneNo, STILField field) { int32 start, firstTuneNo, temp, temp2 = -1; // Clean out the result buffer first result.MakeEmpty(); // Position pointer to the first char beyond the file designation start = buffer.Find('\n'); start++; // Check whether this is a NULL entry or not if (start == 0) return (false); // Is this a multitune entry? firstTuneNo = buffer.Find("(#", start); // This is a tune designation only if the previous char was // a newline (ie. if the "(#" is on the beginning of a line). if ((firstTuneNo >= 1) && (buffer.GetAt(firstTuneNo - 1) != '\n')) firstTuneNo = -1; if (firstTuneNo == -1) { //-------------------// // SINGLE TUNE ENTRY // //-------------------// // // Is the first thing in this STIL entry the COMMENT? temp = buffer.Find(_COMMENT_STR, start); // Search for other potential fields beyond the COMMENT if (temp == start) { temp2 = buffer.Find(_NAME_STR, start); if (temp2 == -1) { temp2 = buffer.Find(_AUTHOR_STR, start); if (temp2 == -1) { temp2 = buffer.Find(_TITLE_STR, start); if (temp2 == -1) temp2 = buffer.Find(_ARTIST_STR, start); } } } if (temp == start) { // Yes. So it's assumed to be a file-global comment if ((tuneNo == 0) && ((field == all) || ((field == comment) && (temp2 == -1)))) { // Simply copy the stuff in result = buffer.Mid(start); return (true); } else if ((tuneNo == 0) && (field == comment)) { // Just copy the comment result = buffer.Mid(start, temp2 - start); return (true); } else if ((tuneNo == 1) && (temp2 != -1)) { // A specific field was asked for return (GetOneField(result, buffer.Mid(temp2), field)); } else { // Anything else is invalid as of v2.00 return (false); } } else { // No. Handle it as a regular entry if ((field == all) && ((tuneNo == 0) || (tuneNo == 1))) { // The complete entry was asked for. Simply copy the stuff in result = buffer.Mid(start); return (true); } else if (tuneNo == 1) { // A specific field was asked for return (GetOneField(result, buffer.Mid(start), field)); } else { // Anything else is invalid as of v2.00 return (false); } } } else { //-----------------// // MULTITUNE ENTRY // //-----------------// int32 myTuneNo, nextTuneNo; PString tuneNoStr; // Was the complete entry asked for? if (tuneNo == 0) { switch (field) { case all: { // Yes. Simply copy the stuff in result = buffer.Mid(start); return (true); } case comment: { // Only the file-global comment field was asked for if (firstTuneNo != start) return (GetOneField(result, buffer.Mid(start, firstTuneNo - start), comment)); else return (false); } default: { // If a specific field other than a comment is // asked for tuneNo=0, this is illegal return (false); } } } // Search for the requested tune number tuneNoStr.Format("(#%d)", tuneNo); myTuneNo = buffer.Find(tuneNoStr, start); if (myTuneNo != -1) { // We found the requested tune number. // Set the pointer beyond it myTuneNo = buffer.Find('\n', myTuneNo) + 1; // Where is the next one? nextTuneNo = buffer.Find("\n(#", myTuneNo); if (nextTuneNo == -1) { // There is no next one - set pointer to the end of entry nextTuneNo = buffer.GetLength(); } else { // The search included the \n - go beyond it nextTuneNo++; } // Put the desired fields into the result (which may be 'all') PString tempResult; bool retVal; retVal = GetOneField(tempResult, buffer.Mid(myTuneNo, nextTuneNo - myTuneNo), field); result += tempResult; return (retVal); } else return (false); } }
bool SIDStil::GetOneField(PString &result, PString buffer, STILField field) { int32 temp = -1; // Sanity check if (buffer.GetAt(buffer.GetLength() - 1) != '\n') { result.MakeEmpty(); return (false); } switch (field) { case all: result += buffer; return (true); case name: temp = buffer.Find(_NAME_STR); break; case author: temp = buffer.Find(_AUTHOR_STR); break; case title: temp = buffer.Find(_TITLE_STR); break; case artist: temp = buffer.Find(_ARTIST_STR); break; case comment: temp = buffer.Find(_COMMENT_STR); break; default: break; } // If the field was not found or it is not in between 'start' // and 'end', it is declared a failure if (temp == -1) { result.MakeEmpty(); return (false); } // Search for the end of this field. This is done by finding // where the next field starts int32 nextName, nextAuthor, nextTitle, nextArtist, nextComment, nextField; nextName = buffer.Find(_NAME_STR, temp + 1); nextAuthor = buffer.Find(_AUTHOR_STR, temp + 1); nextTitle = buffer.Find(_TITLE_STR, temp + 1); nextArtist = buffer.Find(_ARTIST_STR, temp + 1); nextComment = buffer.Find(_COMMENT_STR, temp + 1); // Now determine which one is the closest to our field - that one // will mark the end of the required field nextField = nextName; if (nextField == -1) nextField = nextAuthor; else if ((nextAuthor != -1) && (nextAuthor < nextField)) nextField = nextAuthor; if (nextField == -1) nextField = nextTitle; else if ((nextTitle != -1) && (nextTitle < nextField)) nextField = nextTitle; if (nextField == -1) nextField = nextArtist; else if ((nextArtist != -1) && (nextArtist < nextField)) nextField = nextArtist; if (nextField == -1) nextField = nextComment; else if ((nextComment != -1) && (nextComment < nextField)) nextField = nextComment; if (nextField == -1) nextField = buffer.GetLength(); // Now nextField points to the last+1 char that should be copied to // result. Do that result += buffer.Mid(temp, nextField - temp); return (true); }