00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "BasicUDPSink.hh"
00022 #include <GroupsockHelper.hh>
00023
00024 BasicUDPSink* BasicUDPSink::createNew(UsageEnvironment& env, Groupsock* gs,
00025 unsigned maxPayloadSize) {
00026 return new BasicUDPSink(env, gs, maxPayloadSize);
00027 }
00028
00029 BasicUDPSink::BasicUDPSink(UsageEnvironment& env, Groupsock* gs,
00030 unsigned maxPayloadSize)
00031 : MediaSink(env),
00032 fGS(gs), fMaxPayloadSize(maxPayloadSize) {
00033 fOutputBuffer = new unsigned char[fMaxPayloadSize];
00034 }
00035
00036 BasicUDPSink::~BasicUDPSink() {
00037 delete[] fOutputBuffer;
00038 }
00039
00040 Boolean BasicUDPSink::continuePlaying() {
00041
00042 gettimeofday(&fNextSendTime, NULL);
00043
00044
00045
00046 continuePlaying1();
00047 return True;
00048 }
00049
00050 void BasicUDPSink::continuePlaying1() {
00051 if (fSource != NULL) {
00052 fSource->getNextFrame(fOutputBuffer, fMaxPayloadSize,
00053 afterGettingFrame, this,
00054 onSourceClosure, this);
00055 }
00056 }
00057
00058 void BasicUDPSink::afterGettingFrame(void* clientData, unsigned frameSize,
00059 unsigned numTruncatedBytes,
00060 struct timeval ,
00061 unsigned durationInMicroseconds) {
00062 BasicUDPSink* sink = (BasicUDPSink*)clientData;
00063 sink->afterGettingFrame1(frameSize, numTruncatedBytes, durationInMicroseconds);
00064 }
00065
00066 void BasicUDPSink::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
00067 unsigned durationInMicroseconds) {
00068 if (numTruncatedBytes > 0) {
00069 envir() << "BasicUDPSink::afterGettingFrame1(): The input frame data was too large for our spcified maximum payload size ("
00070 << fMaxPayloadSize << "). "
00071 << numTruncatedBytes << " bytes of trailing data was dropped!\n";
00072 }
00073
00074
00075 fGS->output(envir(), fGS->ttl(), fOutputBuffer, frameSize);
00076
00077
00078
00079 fNextSendTime.tv_usec += durationInMicroseconds;
00080 fNextSendTime.tv_sec += fNextSendTime.tv_usec/1000000;
00081 fNextSendTime.tv_usec %= 1000000;
00082
00083 struct timeval timeNow;
00084 gettimeofday(&timeNow, NULL);
00085 int uSecondsToGo;
00086 if (fNextSendTime.tv_sec < timeNow.tv_sec) {
00087 uSecondsToGo = 0;
00088 } else {
00089 uSecondsToGo = (fNextSendTime.tv_sec - timeNow.tv_sec)*1000000
00090 + (fNextSendTime.tv_usec - timeNow.tv_usec);
00091 }
00092
00093
00094 nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecondsToGo,
00095 (TaskFunc*)sendNext, this);
00096 }
00097
00098
00099 void BasicUDPSink::sendNext(void* firstArg) {
00100 BasicUDPSink* sink = (BasicUDPSink*)firstArg;
00101 sink->continuePlaying1();
00102 }