// // The contents of this file are subject to the Mozilla Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See // the License for the specific language governing rights and limitations // under the License. // // The Original Code is CPhone, a cross platform voip gui. // // The Initial Developer of the Original Code is Derek Smithies. // // Copyright (C) 2002 Indranet Technologies Ltd, // http://www.indranet-technologies.com // All Rights Reserved. // // Contributor(s): _______________ /* * * $Log: statisticsSub.cxx,v $ * Revision 1.4 2004/04/23 05:09:59 dereksmithies * Fixes so it works with latest openh323 lib, and not lock X display. * * Revision 1.3 2003/09/02 03:37:32 dereksmithies * Add statistics, new icons, toolbuttons (icon + name) * * Revision 1.2 2003/08/26 04:48:02 dereksmithies * Fixes to get statistics working right, add icons, add ok,cancel,apply buttons * * Revision 1.1 2003/08/26 03:31:12 dereksmithies * Initial release of statistics display * * * * * */ #include #include #include #include #include #include #include #include #ifdef __GNUC__ #pragma implementation "statisticsSub.h" #endif #include "mainwindowSub.h" #include "statisticsSub.h" #include "gdisplay.h" #define CUSTOM_EVENT_SETUP (QEvent::User + 1) //#define new PNEW Statistics::Statistics() : FormStatistics( 0, "Statistics", FALSE, WStyle_NoBorderEx) { move(350,60); CPhone::Current().SetWindowId(eStatistics, winId()); QApplication::postEvent(this, new QCustomEvent(CUSTOM_EVENT_SETUP)); audioPackets = NULL; videoPackets = NULL; startTime = PTime(); } void Statistics::Setup() { checkBoxAudioStats->setChecked(CPhone::GetUi().connectOpts.audioStats); checkBoxVideoStats->setChecked(CPhone::GetUi().connectOpts.videoStats); audioPackets = new StatisticsPacketList(); videoPackets = new StatisticsPacketList(); ((StatisticsPacketList *)audioPackets)->AllowDeleteObjects(); ((StatisticsPacketList *)videoPackets)->AllowDeleteObjects(); startTimer(1000); //Every 1000 milliseconds, get more data. inCall = FALSE; } /* * Destroys the object and frees any allocated resources */ Statistics::~Statistics() { killTimers(); if (audioPackets != NULL) delete audioPackets; if (videoPackets != NULL) delete videoPackets; } void Statistics::closeEvent(QCloseEvent *e) { CPhone::Current().ForgetExists(eStatistics, winId()); e->accept(); } void Statistics::timerEvent(QTimerEvent *) { frameAudioStats->setHidden(!CPhone::GetUi().connectOpts.audioStats); frameVideoStats->setHidden(!CPhone::GetUi().connectOpts.videoStats); StatisticsPacketList *audio = (StatisticsPacketList *)audioPackets; StatisticsPacketList *video = (StatisticsPacketList *)videoPackets; H323Connection * connection = CPhone::GetUi().GetCurrentConnectionWithLock(); StatisticsPacket *aStats = new StatisticsPacket(connection, RTP_Session::DefaultAudioSessionID); StatisticsPacket *vStats = new StatisticsPacket(connection, RTP_Session::DefaultVideoSessionID); audio->AppendElem(aStats); video->AppendElem(vStats); PString aName, vName, timeString; H323Channel *channel = NULL; if (connection != NULL) { channel = connection->FindChannel(RTP_Session::DefaultAudioSessionID, FALSE); if (channel != NULL) aName = channel->GetCapability().GetFormatName(); channel = connection->FindChannel(RTP_Session::DefaultVideoSessionID, FALSE); if (channel != NULL) vName = channel->GetCapability().GetFormatName(); if (!inCall) { startTime = PTime(); timeString = startTime.AsString("hh:mm:ss dd MMM"); textLabelStartTime->setText(timeString.GetPointer()); inCall = TRUE; } if (inCall) { PTimeInterval pt = PTime() - startTime; timeString = "Duration: " + pt.AsString(1, PTimeInterval::NormalFormat, 0) + " secs"; textLabelCallDuration->setText(timeString.GetPointer()); } connection->Unlock(); } else { textLabelCallDuration->clear(); textLabelStartTime->clear(); inCall = FALSE; } graphDisplayAudio->SetDisplayData(audio); graphDisplayVideo->SetDisplayData(video); textLabelAudioCodec->setText(aName.GetPointer()); textLabelVideoCodec->setText(vName.GetPointer()); textLabelAudioMaxStats->setText(graphDisplayAudio->GetRateString()); textLabelAudioCurrent->setText(graphDisplayAudio->GetDualRateString()); textLabelVideoMaxStats->setText(graphDisplayVideo->GetRateString()); textLabelVideoCurrent->setText(graphDisplayVideo->GetDualRateString()); } void Statistics::customEvent( QCustomEvent *e) { if (e->type() == CUSTOM_EVENT_DIE) close(TRUE); if (e->type() == CUSTOM_EVENT_SETUP) Setup(); } void Statistics::ApplySlot() { CPhone::GetUi().connectOpts.audioStats = checkBoxAudioStats->isChecked(); CPhone::GetUi().connectOpts.videoStats = checkBoxVideoStats->isChecked(); } void Statistics::CancelSlot() { close(TRUE); } void Statistics::OkSlot() { ApplySlot(); close(TRUE); } StatisticsPacket::StatisticsPacket(H323Connection *connection, unsigned sessionId) { thisTime = PTime(); rateSent = 0; rateReceived = 0; RTP_Session * session = NULL; if (connection != NULL) session = connection->GetSession(sessionId); if (session == NULL) { packetsSent = 0; packetsReceived = 0; octetsSent = 0; octetsReceived = 0; return; } packetsSent = session->GetPacketsSent(); packetsReceived = session->GetPacketsReceived(); octetsSent = session->GetOctetsSent(); octetsReceived = session->GetOctetsReceived(); } void StatisticsPacket::operator-=(PObject *src) { StatisticsPacket *sp = (StatisticsPacket *)src; PInt64 elapsedMilliseconds = (thisTime - sp->thisTime).GetMilliSeconds(); double divisor = (8 * 1.024) / elapsedMilliseconds; rateSent = (octetsSent - sp->GetOctets(true)) * divisor; rateReceived = (octetsReceived - sp->GetOctets(false)) * divisor; if (rateSent < 0) rateSent = 0; if (rateReceived < 0) rateReceived = 0; } unsigned StatisticsPacket::GetPacket(bool isSend) { if (isSend) return packetsSent; else return packetsReceived; } unsigned StatisticsPacket::GetOctets(bool isSend) { if (isSend) return octetsSent; else return octetsReceived; } double StatisticsPacket::GetRate (bool isSend) { if (isSend) return rateSent; else return rateReceived; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// StatisticsPacketList:: ~StatisticsPacketList() { } StatisticsPacket *StatisticsPacketList::GetEntry(PINDEX i) { return (StatisticsPacket *)GetAt(i); } void StatisticsPacketList::AppendElem(StatisticsPacket *pack) { if (GetSize() > 0) { *pack -= GetAt(0); RemoveAt(0); } Append(pack); }