00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "QCELPAudioRTPSource.hh"
00022 #include "MultiFramedRTPSource.hh"
00023 #include "FramedFilter.hh"
00024 #include <string.h>
00025 #include <stdlib.h>
00026
00027
00028
00029
00030
00031
00032 class RawQCELPRTPSource: public MultiFramedRTPSource {
00033 public:
00034 static RawQCELPRTPSource* createNew(UsageEnvironment& env,
00035 Groupsock* RTPgs,
00036 unsigned char rtpPayloadFormat,
00037 unsigned rtpTimestampFrequency);
00038
00039 unsigned char interleaveL() const { return fInterleaveL; }
00040 unsigned char interleaveN() const { return fInterleaveN; }
00041 unsigned char& frameIndex() { return fFrameIndex; }
00042
00043 private:
00044 RawQCELPRTPSource(UsageEnvironment& env, Groupsock* RTPgs,
00045 unsigned char rtpPayloadFormat,
00046 unsigned rtpTimestampFrequency);
00047
00048
00049 virtual ~RawQCELPRTPSource();
00050
00051 private:
00052
00053 virtual Boolean processSpecialHeader(BufferedPacket* packet,
00054 unsigned& resultSpecialHeaderSize);
00055 virtual char const* MIMEtype() const;
00056
00057 virtual Boolean hasBeenSynchronizedUsingRTCP();
00058
00059 private:
00060 unsigned char fInterleaveL, fInterleaveN, fFrameIndex;
00061 unsigned fNumSuccessiveSyncedPackets;
00062 };
00063
00064 class QCELPDeinterleaver: public FramedFilter {
00065 public:
00066 static QCELPDeinterleaver* createNew(UsageEnvironment& env,
00067 RawQCELPRTPSource* inputSource);
00068
00069 private:
00070 QCELPDeinterleaver(UsageEnvironment& env,
00071 RawQCELPRTPSource* inputSource);
00072
00073
00074 virtual ~QCELPDeinterleaver();
00075
00076 static void afterGettingFrame(void* clientData, unsigned frameSize,
00077 unsigned numTruncatedBytes,
00078 struct timeval presentationTime,
00079 unsigned durationInMicroseconds);
00080 void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime);
00081
00082 private:
00083
00084 void doGetNextFrame();
00085
00086 private:
00087 class QCELPDeinterleavingBuffer* fDeinterleavingBuffer;
00088 Boolean fNeedAFrame;
00089 };
00090
00091
00093
00094 FramedSource*
00095 QCELPAudioRTPSource::createNew(UsageEnvironment& env,
00096 Groupsock* RTPgs,
00097 RTPSource*& resultRTPSource,
00098 unsigned char rtpPayloadFormat,
00099 unsigned rtpTimestampFrequency) {
00100 RawQCELPRTPSource* rawRTPSource;
00101 resultRTPSource = rawRTPSource
00102 = RawQCELPRTPSource::createNew(env, RTPgs, rtpPayloadFormat,
00103 rtpTimestampFrequency);
00104 if (resultRTPSource == NULL) return NULL;
00105
00106 QCELPDeinterleaver* deinterleaver
00107 = QCELPDeinterleaver::createNew(env, rawRTPSource);
00108 if (deinterleaver == NULL) {
00109 Medium::close(resultRTPSource);
00110 resultRTPSource = NULL;
00111 }
00112
00113 return deinterleaver;
00114 }
00115
00116
00118
00119
00120
00121 class QCELPBufferedPacket: public BufferedPacket {
00122 public:
00123 QCELPBufferedPacket(RawQCELPRTPSource& ourSource);
00124 virtual ~QCELPBufferedPacket();
00125
00126 private:
00127 virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr,
00128 unsigned dataSize);
00129 private:
00130 RawQCELPRTPSource& fOurSource;
00131 };
00132
00133 class QCELPBufferedPacketFactory: public BufferedPacketFactory {
00134 private:
00135 virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);
00136 };
00137
00138
00140
00141 RawQCELPRTPSource*
00142 RawQCELPRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,
00143 unsigned char rtpPayloadFormat,
00144 unsigned rtpTimestampFrequency) {
00145 return new RawQCELPRTPSource(env, RTPgs, rtpPayloadFormat,
00146 rtpTimestampFrequency);
00147 }
00148
00149 RawQCELPRTPSource::RawQCELPRTPSource(UsageEnvironment& env,
00150 Groupsock* RTPgs,
00151 unsigned char rtpPayloadFormat,
00152 unsigned rtpTimestampFrequency)
00153 : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat,
00154 rtpTimestampFrequency,
00155 new QCELPBufferedPacketFactory),
00156 fInterleaveL(0), fInterleaveN(0), fFrameIndex(0),
00157 fNumSuccessiveSyncedPackets(0) {
00158 }
00159
00160 RawQCELPRTPSource::~RawQCELPRTPSource() {
00161 }
00162
00163 Boolean RawQCELPRTPSource
00164 ::processSpecialHeader(BufferedPacket* packet,
00165 unsigned& resultSpecialHeaderSize) {
00166 unsigned char* headerStart = packet->data();
00167 unsigned packetSize = packet->dataSize();
00168
00169
00170 if (RTPSource::hasBeenSynchronizedUsingRTCP()) {
00171 ++fNumSuccessiveSyncedPackets;
00172 } else {
00173 fNumSuccessiveSyncedPackets = 0;
00174 }
00175
00176
00177 if (packetSize < 1) return False;
00178
00179
00180
00181 unsigned char const firstByte = headerStart[0];
00182 unsigned char const interleaveL = (firstByte&0x38)>>3;
00183 unsigned char const interleaveN = firstByte&0x07;
00184 #ifdef DEBUG
00185 fprintf(stderr, "packetSize: %d, interleaveL: %d, interleaveN: %d\n", packetSize, interleaveL, interleaveN);
00186 #endif
00187 if (interleaveL > 5 || interleaveN > interleaveL) return False;
00188
00189 fInterleaveL = interleaveL;
00190 fInterleaveN = interleaveN;
00191 fFrameIndex = 0;
00192
00193 resultSpecialHeaderSize = 1;
00194 return True;
00195 }
00196
00197 char const* RawQCELPRTPSource::MIMEtype() const {
00198 return "audio/QCELP";
00199 }
00200
00201 Boolean RawQCELPRTPSource::hasBeenSynchronizedUsingRTCP() {
00202
00203
00204
00205
00206 if (fNumSuccessiveSyncedPackets > (unsigned)(fInterleaveL+1)) {
00207 fNumSuccessiveSyncedPackets = fInterleaveL+2;
00208 return True;
00209 }
00210 return False;
00211 }
00212
00213
00215
00216 QCELPBufferedPacket::QCELPBufferedPacket(RawQCELPRTPSource& ourSource)
00217 : fOurSource(ourSource) {
00218 }
00219
00220 QCELPBufferedPacket::~QCELPBufferedPacket() {
00221 }
00222
00223 unsigned QCELPBufferedPacket::
00224 nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {
00225
00226 if (dataSize == 0) return 0;
00227 unsigned char const firstByte = framePtr[0];
00228
00229 unsigned frameSize;
00230 switch (firstByte) {
00231 case 0: { frameSize = 1; break; }
00232 case 1: { frameSize = 4; break; }
00233 case 2: { frameSize = 8; break; }
00234 case 3: { frameSize = 17; break; }
00235 case 4: { frameSize = 35; break; }
00236 default: { frameSize = 0; break; }
00237 }
00238
00239 #ifdef DEBUG
00240 fprintf(stderr, "QCELPBufferedPacket::nextEnclosedFrameSize(): frameSize: %d, dataSize: %d\n", frameSize, dataSize);
00241 #endif
00242 if (dataSize < frameSize) return 0;
00243
00244 ++fOurSource.frameIndex();
00245 return frameSize;
00246 }
00247
00248 BufferedPacket* QCELPBufferedPacketFactory
00249 ::createNewPacket(MultiFramedRTPSource* ourSource) {
00250 return new QCELPBufferedPacket((RawQCELPRTPSource&)(*ourSource));
00251 }
00252
00254
00255
00256 #define QCELP_MAX_FRAME_SIZE 35
00257 #define QCELP_MAX_INTERLEAVE_L 5
00258 #define QCELP_MAX_FRAMES_PER_PACKET 10
00259 #define QCELP_MAX_INTERLEAVE_GROUP_SIZE \
00260 ((QCELP_MAX_INTERLEAVE_L+1)*QCELP_MAX_FRAMES_PER_PACKET)
00261
00262 class QCELPDeinterleavingBuffer {
00263 public:
00264 QCELPDeinterleavingBuffer();
00265 virtual ~QCELPDeinterleavingBuffer();
00266
00267 void deliverIncomingFrame(unsigned frameSize,
00268 unsigned char interleaveL,
00269 unsigned char interleaveN,
00270 unsigned char frameIndex,
00271 unsigned short packetSeqNum,
00272 struct timeval presentationTime);
00273 Boolean retrieveFrame(unsigned char* to, unsigned maxSize,
00274 unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,
00275 struct timeval& resultPresentationTime);
00276
00277 unsigned char* inputBuffer() { return fInputBuffer; }
00278 unsigned inputBufferSize() const { return QCELP_MAX_FRAME_SIZE; }
00279
00280 private:
00281 class FrameDescriptor {
00282 public:
00283 FrameDescriptor();
00284 virtual ~FrameDescriptor();
00285
00286 unsigned frameSize;
00287 unsigned char* frameData;
00288 struct timeval presentationTime;
00289 };
00290
00291
00292 FrameDescriptor fFrames[QCELP_MAX_INTERLEAVE_GROUP_SIZE][2];
00293 unsigned char fIncomingBankId;
00294 unsigned char fIncomingBinMax;
00295 unsigned char fOutgoingBinMax;
00296 unsigned char fNextOutgoingBin;
00297 Boolean fHaveSeenPackets;
00298 u_int16_t fLastPacketSeqNumForGroup;
00299 unsigned char* fInputBuffer;
00300 struct timeval fLastRetrievedPresentationTime;
00301 };
00302
00303
00305
00306 QCELPDeinterleaver*
00307 QCELPDeinterleaver::createNew(UsageEnvironment& env,
00308 RawQCELPRTPSource* inputSource) {
00309 return new QCELPDeinterleaver(env, inputSource);
00310 }
00311
00312 QCELPDeinterleaver::QCELPDeinterleaver(UsageEnvironment& env,
00313 RawQCELPRTPSource* inputSource)
00314 : FramedFilter(env, inputSource),
00315 fNeedAFrame(False) {
00316 fDeinterleavingBuffer = new QCELPDeinterleavingBuffer();
00317 }
00318
00319 QCELPDeinterleaver::~QCELPDeinterleaver() {
00320 delete fDeinterleavingBuffer;
00321 }
00322
00323 static unsigned const uSecsPerFrame = 20000;
00324
00325 void QCELPDeinterleaver::doGetNextFrame() {
00326
00327 if (fDeinterleavingBuffer->retrieveFrame(fTo, fMaxSize,
00328 fFrameSize, fNumTruncatedBytes,
00329 fPresentationTime)) {
00330
00331 fNeedAFrame = False;
00332
00333 fDurationInMicroseconds = uSecsPerFrame;
00334
00335
00336
00337
00338 afterGetting(this);
00339 return;
00340 }
00341
00342
00343 fNeedAFrame = True;
00344 if (!fInputSource->isCurrentlyAwaitingData()) {
00345 fInputSource->getNextFrame(fDeinterleavingBuffer->inputBuffer(),
00346 fDeinterleavingBuffer->inputBufferSize(),
00347 afterGettingFrame, this,
00348 FramedSource::handleClosure, this);
00349 }
00350 }
00351
00352 void QCELPDeinterleaver
00353 ::afterGettingFrame(void* clientData, unsigned frameSize,
00354 unsigned ,
00355 struct timeval presentationTime,
00356 unsigned ) {
00357 QCELPDeinterleaver* deinterleaver = (QCELPDeinterleaver*)clientData;
00358 deinterleaver->afterGettingFrame1(frameSize, presentationTime);
00359 }
00360
00361 void QCELPDeinterleaver
00362 ::afterGettingFrame1(unsigned frameSize, struct timeval presentationTime) {
00363 RawQCELPRTPSource* source = (RawQCELPRTPSource*)fInputSource;
00364
00365
00366 fDeinterleavingBuffer
00367 ->deliverIncomingFrame(frameSize, source->interleaveL(),
00368 source->interleaveN(), source->frameIndex(),
00369 source->curPacketRTPSeqNum(),
00370 presentationTime);
00371
00372
00373 if (fNeedAFrame) doGetNextFrame();
00374 }
00375
00376
00378
00379 QCELPDeinterleavingBuffer::QCELPDeinterleavingBuffer()
00380 : fIncomingBankId(0), fIncomingBinMax(0),
00381 fOutgoingBinMax(0), fNextOutgoingBin(0),
00382 fHaveSeenPackets(False) {
00383 fInputBuffer = new unsigned char[QCELP_MAX_FRAME_SIZE];
00384 }
00385
00386 QCELPDeinterleavingBuffer::~QCELPDeinterleavingBuffer() {
00387 delete[] fInputBuffer;
00388 }
00389
00390 void QCELPDeinterleavingBuffer
00391 ::deliverIncomingFrame(unsigned frameSize,
00392 unsigned char interleaveL,
00393 unsigned char interleaveN,
00394 unsigned char frameIndex,
00395 unsigned short packetSeqNum,
00396 struct timeval presentationTime) {
00397
00398
00399 if (frameSize > QCELP_MAX_FRAME_SIZE
00400 || interleaveL > QCELP_MAX_INTERLEAVE_L || interleaveN > interleaveL
00401 || frameIndex == 0 || frameIndex > QCELP_MAX_FRAMES_PER_PACKET) {
00402 #ifdef DEBUG
00403 fprintf(stderr, "QCELPDeinterleavingBuffer::deliverIncomingFrame() param sanity check failed (%d,%d,%d,%d)\n", frameSize, interleaveL, interleaveN, frameIndex);
00404 #endif
00405 exit(1);
00406 }
00407
00408
00409
00410 unsigned uSecIncrement = (frameIndex-1)*(interleaveL+1)*uSecsPerFrame;
00411 presentationTime.tv_usec += uSecIncrement;
00412 presentationTime.tv_sec += presentationTime.tv_usec/1000000;
00413 presentationTime.tv_usec = presentationTime.tv_usec%1000000;
00414
00415
00416 if (!fHaveSeenPackets
00417 || seqNumLT(fLastPacketSeqNumForGroup, packetSeqNum)) {
00418
00419 fHaveSeenPackets = True;
00420 fLastPacketSeqNumForGroup = packetSeqNum + interleaveL - interleaveN;
00421
00422
00423 fIncomingBankId ^= 1;
00424 unsigned char tmp = fIncomingBinMax;
00425 fIncomingBinMax = fOutgoingBinMax;
00426 fOutgoingBinMax = tmp;
00427 fNextOutgoingBin = 0;
00428 }
00429
00430
00431 unsigned const binNumber
00432 = interleaveN + (frameIndex-1)*(interleaveL+1);
00433 FrameDescriptor& inBin = fFrames[binNumber][fIncomingBankId];
00434 unsigned char* curBuffer = inBin.frameData;
00435 inBin.frameData = fInputBuffer;
00436 inBin.frameSize = frameSize;
00437 inBin.presentationTime = presentationTime;
00438
00439 if (curBuffer == NULL) curBuffer = new unsigned char[QCELP_MAX_FRAME_SIZE];
00440 fInputBuffer = curBuffer;
00441
00442 if (binNumber >= fIncomingBinMax) {
00443 fIncomingBinMax = binNumber + 1;
00444 }
00445 }
00446
00447 Boolean QCELPDeinterleavingBuffer
00448 ::retrieveFrame(unsigned char* to, unsigned maxSize,
00449 unsigned& resultFrameSize, unsigned& resultNumTruncatedBytes,
00450 struct timeval& resultPresentationTime) {
00451 if (fNextOutgoingBin >= fOutgoingBinMax) return False;
00452
00453 FrameDescriptor& outBin = fFrames[fNextOutgoingBin][fIncomingBankId^1];
00454 unsigned char* fromPtr;
00455 unsigned char fromSize = outBin.frameSize;
00456 outBin.frameSize = 0;
00457
00458
00459 unsigned char erasure = 14;
00460 if (fromSize == 0) {
00461 fromPtr = &erasure;
00462 fromSize = 1;
00463
00464
00465 resultPresentationTime = fLastRetrievedPresentationTime;
00466 resultPresentationTime.tv_usec += uSecsPerFrame;
00467 if (resultPresentationTime.tv_usec >= 1000000) {
00468 ++resultPresentationTime.tv_sec;
00469 resultPresentationTime.tv_usec -= 1000000;
00470 }
00471 } else {
00472
00473 fromPtr = outBin.frameData;
00474 resultPresentationTime = outBin.presentationTime;
00475 }
00476
00477 fLastRetrievedPresentationTime = resultPresentationTime;
00478
00479 if (fromSize > maxSize) {
00480 resultNumTruncatedBytes = fromSize - maxSize;
00481 resultFrameSize = maxSize;
00482 } else {
00483 resultNumTruncatedBytes = 0;
00484 resultFrameSize = fromSize;
00485 }
00486 memmove(to, fromPtr, resultFrameSize);
00487
00488 ++fNextOutgoingBin;
00489 return True;
00490 }
00491
00492 QCELPDeinterleavingBuffer::FrameDescriptor::FrameDescriptor()
00493 : frameSize(0), frameData(NULL) {
00494 }
00495
00496 QCELPDeinterleavingBuffer::FrameDescriptor::~FrameDescriptor() {
00497 delete[] frameData;
00498 }