UDPVideoStreamSvr.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 
00019 //
00020 // based on the video streaming app of the similar name by Johnny Lai
00021 //
00022 
00023 
00024 #include "UDPVideoStreamSvr.h"
00025 #include "UDPControlInfo_m.h"
00026 
00027 
00028 Define_Module(UDPVideoStreamSvr);
00029 
00030 inline std::ostream& operator<<(std::ostream& out, const UDPVideoStreamSvr::VideoStreamData& d) {
00031     out << "client=" << d.clientAddr << ":" << d.clientPort
00032         << "  size=" << d.videoSize << "  pksent=" << d.numPkSent << "  bytesleft=" << d.bytesLeft;
00033     return out;
00034 }
00035 
00036 UDPVideoStreamSvr::UDPVideoStreamSvr()
00037 {
00038 }
00039 
00040 UDPVideoStreamSvr::~UDPVideoStreamSvr()
00041 {
00042     for (unsigned int i=0; i<streamVector.size(); i++)
00043         delete streamVector[i];
00044 }
00045 
00046 void UDPVideoStreamSvr::initialize()
00047 {
00048     waitInterval = &par("waitInterval");
00049     packetLen = &par("packetLen");
00050     videoSize = &par("videoSize");
00051     serverPort = par("serverPort");
00052 
00053     numStreams = 0;
00054     numPkSent = 0;
00055 
00056     WATCH_PTRVECTOR(streamVector);
00057 
00058     bindToPort(serverPort);
00059 }
00060 
00061 void UDPVideoStreamSvr::finish()
00062 {
00063     recordScalar("streams served", numStreams);
00064     recordScalar("packets sent", numPkSent);
00065 }
00066 
00067 void UDPVideoStreamSvr::handleMessage(cMessage *msg)
00068 {
00069     if (msg->isSelfMessage())
00070     {
00071         // timer for a particular video stream expired, send packet
00072         sendStreamData(msg);
00073     }
00074     else
00075     {
00076         // start streaming
00077         processStreamRequest(msg);
00078     }
00079 }
00080 
00081 
00082 void UDPVideoStreamSvr::processStreamRequest(cMessage *msg)
00083 {
00084     // register video stream...
00085     UDPControlInfo *ctrl = check_and_cast<UDPControlInfo *>(msg->getControlInfo());
00086 
00087     VideoStreamData *d = new VideoStreamData;
00088     d->clientAddr = ctrl->getSrcAddr();
00089     d->clientPort = ctrl->getSrcPort();
00090     d->videoSize = (*videoSize);
00091     d->bytesLeft = d->videoSize;
00092     d->numPkSent = 0;
00093     streamVector.push_back(d);
00094 
00095     cMessage *timer = new cMessage("VideoStreamTmr");
00096     timer->setContextPointer(d);
00097 
00098     // ... then transmit first packet right away
00099     sendStreamData(timer);
00100 
00101     numStreams++;
00102 }
00103 
00104 
00105 void UDPVideoStreamSvr::sendStreamData(cMessage *timer)
00106 {
00107     VideoStreamData *d = (VideoStreamData *) timer->getContextPointer();
00108 
00109     // generate and send a packet
00110     cPacket *pkt = new cPacket("VideoStrmPk");
00111     long pktLen = packetLen->longValue();
00112     if (pktLen > d->bytesLeft)
00113         pktLen = d->bytesLeft;
00114     pkt->setByteLength(pktLen);
00115     sendToUDP(pkt, serverPort, d->clientAddr, d->clientPort);
00116 
00117     d->bytesLeft -= pktLen;
00118     d->numPkSent++;
00119     numPkSent++;
00120 
00121     // reschedule timer if there's bytes left to send
00122     if (d->bytesLeft!=0)
00123     {
00124         simtime_t interval = (*waitInterval);
00125         scheduleAt(simTime()+interval, timer);
00126     }
00127     else
00128     {
00129         delete timer;
00130         // TBD find VideoStreamData in streamVector and delete it
00131     }
00132 }