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