00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MP3ADUinterleaving.hh"
00022 #include "MP3ADUdescriptor.hh"
00023
00024 #include <string.h>
00025
00026 #ifdef TEST_LOSS
00027 #include "GroupsockHelper.hh"
00028 #endif
00029
00031
00032 Interleaving::Interleaving(unsigned cycleSize,
00033 unsigned char const* cycleArray)
00034 : fCycleSize(cycleSize) {
00035 for (unsigned i = 0; i < fCycleSize; ++i) {
00036 fInverseCycle[cycleArray[i]] = i;
00037 }
00038 }
00039
00040 Interleaving::~Interleaving() {
00041 }
00042
00044
00045 MP3ADUinterleaverBase::MP3ADUinterleaverBase(UsageEnvironment& env,
00046 FramedSource* inputSource)
00047 : FramedFilter(env, inputSource) {
00048 }
00049 MP3ADUinterleaverBase::~MP3ADUinterleaverBase() {
00050 }
00051
00052 FramedSource* MP3ADUinterleaverBase::getInputSource(UsageEnvironment& env,
00053 char const* inputSourceName) {
00054 FramedSource* inputSource;
00055 if (!FramedSource::lookupByName(env, inputSourceName, inputSource))
00056 return NULL;
00057
00058 if (strcmp(inputSource->MIMEtype(), "audio/MPA-ROBUST") != 0) {
00059 env.setResultMsg(inputSourceName, " is not an MP3 ADU source");
00060 return NULL;
00061 }
00062
00063 return inputSource;
00064 }
00065
00066 void MP3ADUinterleaverBase::afterGettingFrame(void* clientData,
00067 unsigned numBytesRead,
00068 unsigned ,
00069 struct timeval presentationTime,
00070 unsigned durationInMicroseconds) {
00071 MP3ADUinterleaverBase* interleaverBase = (MP3ADUinterleaverBase*)clientData;
00072
00073 interleaverBase->afterGettingFrame(numBytesRead,
00074 presentationTime, durationInMicroseconds);
00075
00076
00077 interleaverBase->doGetNextFrame();
00078 }
00079
00080
00082
00083 class InterleavingFrames {
00084 public:
00085 InterleavingFrames(unsigned maxCycleSize);
00086 virtual ~InterleavingFrames();
00087
00088 Boolean haveReleaseableFrame();
00089 void getIncomingFrameParams(unsigned char index,
00090 unsigned char*& dataPtr,
00091 unsigned& bytesAvailable);
00092 void getReleasingFrameParams(unsigned char index,
00093 unsigned char*& dataPtr,
00094 unsigned& bytesInUse,
00095 struct timeval& presentationTime,
00096 unsigned& durationInMicroseconds);
00097 void setFrameParams(unsigned char index,
00098 unsigned char icc, unsigned char ii,
00099 unsigned frameSize, struct timeval presentationTime,
00100 unsigned durationInMicroseconds);
00101 unsigned nextIndexToRelease() {return fNextIndexToRelease;}
00102 void releaseNext();
00103
00104 private:
00105 unsigned fMaxCycleSize;
00106 unsigned fNextIndexToRelease;
00107 class InterleavingFrameDescriptor* fDescriptors;
00108 };
00109
00111
00112
00113 MP3ADUinterleaver::MP3ADUinterleaver(UsageEnvironment& env,
00114 Interleaving const& interleaving,
00115 FramedSource* inputSource)
00116 : MP3ADUinterleaverBase(env, inputSource),
00117 fInterleaving(interleaving),
00118 fFrames(new InterleavingFrames(interleaving.cycleSize())),
00119 fII(0), fICC(0) {
00120 }
00121
00122 MP3ADUinterleaver::~MP3ADUinterleaver() {
00123 delete fFrames;
00124 }
00125
00126 MP3ADUinterleaver* MP3ADUinterleaver::createNew(UsageEnvironment& env,
00127 Interleaving const& interleaving,
00128 FramedSource* inputSource) {
00129 return new MP3ADUinterleaver(env, interleaving, inputSource);
00130 }
00131
00132 void MP3ADUinterleaver::doGetNextFrame() {
00133
00134
00135 if (fFrames->haveReleaseableFrame()) {
00136 releaseOutgoingFrame();
00137
00138
00139
00140 afterGetting(this);
00141 } else {
00142 fPositionOfNextIncomingFrame = fInterleaving.lookupInverseCycle(fII);
00143 unsigned char* dataPtr;
00144 unsigned bytesAvailable;
00145 fFrames->getIncomingFrameParams(fPositionOfNextIncomingFrame,
00146 dataPtr, bytesAvailable);
00147
00148
00149 fInputSource->getNextFrame(dataPtr, bytesAvailable,
00150 &MP3ADUinterleaverBase::afterGettingFrame, this,
00151 handleClosure, this);
00152 }
00153 }
00154
00155 void MP3ADUinterleaver::releaseOutgoingFrame() {
00156 unsigned char* fromPtr;
00157 fFrames->getReleasingFrameParams(fFrames->nextIndexToRelease(),
00158 fromPtr, fFrameSize,
00159 fPresentationTime, fDurationInMicroseconds);
00160
00161 if (fFrameSize > fMaxSize) {
00162 fNumTruncatedBytes = fFrameSize - fMaxSize;
00163 fFrameSize = fMaxSize;
00164 }
00165 memmove(fTo, fromPtr, fFrameSize);
00166
00167 fFrames->releaseNext();
00168 }
00169
00170 void MP3ADUinterleaver::afterGettingFrame(unsigned numBytesRead,
00171 struct timeval presentationTime,
00172 unsigned durationInMicroseconds) {
00173
00174 fFrames->setFrameParams(fPositionOfNextIncomingFrame,
00175 fICC, fII, numBytesRead,
00176 presentationTime, durationInMicroseconds);
00177
00178
00179 if (++fII == fInterleaving.cycleSize()) {
00180 fII = 0;
00181 fICC = (fICC+1)%8;
00182 }
00183 }
00184
00186
00187 class DeinterleavingFrames {
00188 public:
00189 DeinterleavingFrames();
00190 virtual ~DeinterleavingFrames();
00191
00192 Boolean haveReleaseableFrame();
00193 void getIncomingFrameParams(unsigned char*& dataPtr,
00194 unsigned& bytesAvailable);
00195 void getIncomingFrameParamsAfter(unsigned frameSize,
00196 struct timeval presentationTime,
00197 unsigned durationInMicroseconds,
00198 unsigned char& icc, unsigned char& ii);
00199 void getReleasingFrameParams(unsigned char*& dataPtr,
00200 unsigned& bytesInUse,
00201 struct timeval& presentationTime,
00202 unsigned& durationInMicroseconds);
00203 void moveIncomingFrameIntoPlace();
00204 void releaseNext();
00205 void startNewCycle();
00206
00207 private:
00208 unsigned fNextIndexToRelease;
00209 Boolean fHaveEndedCycle;
00210 unsigned fIIlastSeen;
00211 unsigned fMinIndexSeen, fMaxIndexSeen;
00212 class DeinterleavingFrameDescriptor* fDescriptors;
00213 };
00214
00216
00217 MP3ADUdeinterleaver::MP3ADUdeinterleaver(UsageEnvironment& env,
00218 FramedSource* inputSource)
00219 : MP3ADUinterleaverBase(env, inputSource),
00220 fFrames(new DeinterleavingFrames),
00221 fIIlastSeen(~0), fICClastSeen(~0) {
00222 }
00223
00224 MP3ADUdeinterleaver::~MP3ADUdeinterleaver() {
00225 delete fFrames;
00226 }
00227
00228 MP3ADUdeinterleaver* MP3ADUdeinterleaver::createNew(UsageEnvironment& env,
00229 FramedSource* inputSource) {
00230 return new MP3ADUdeinterleaver(env, inputSource);
00231 }
00232
00233 void MP3ADUdeinterleaver::doGetNextFrame() {
00234
00235
00236 if (fFrames->haveReleaseableFrame()) {
00237 releaseOutgoingFrame();
00238
00239
00240
00241 afterGetting(this);
00242 } else {
00243 #ifdef TEST_LOSS
00244 NOTE: This code no longer works, because it uses synchronous reads,
00245 which are no longer supported.
00246 static unsigned const framesPerPacket = 3;
00247 static unsigned const frameCount = 0;
00248 static Boolean packetIsLost;
00249 while (1) {
00250 unsigned packetCount = frameCount/framesPerPacket;
00251 if ((frameCount++)%framesPerPacket == 0) {
00252 packetIsLost = (our_random()%10 == 0);
00253 }
00254
00255 if (packetIsLost) {
00256
00257
00258 unsigned char dummyBuf[2000];
00259 unsigned numBytesRead;
00260 struct timeval presentationTime;
00261
00262 fInputSource->syncGetNextFrame(dummyBuf, sizeof dummyBuf,
00263 numBytesRead, presentationTime);
00264 } else {
00265 break;
00266 }
00267 }
00268 #endif
00269 unsigned char* dataPtr;
00270 unsigned bytesAvailable;
00271 fFrames->getIncomingFrameParams(dataPtr, bytesAvailable);
00272
00273
00274 fInputSource->getNextFrame(dataPtr, bytesAvailable,
00275 &MP3ADUinterleaverBase::afterGettingFrame, this,
00276 handleClosure, this);
00277 }
00278 }
00279
00280 void MP3ADUdeinterleaver::afterGettingFrame(unsigned numBytesRead,
00281 struct timeval presentationTime,
00282 unsigned durationInMicroseconds) {
00283
00284 unsigned char icc, ii;
00285 fFrames->getIncomingFrameParamsAfter(numBytesRead,
00286 presentationTime, durationInMicroseconds,
00287 icc, ii);
00288
00289
00290 if (icc != fICClastSeen || ii == fIIlastSeen) {
00291
00292
00293
00294 fFrames->startNewCycle();
00295 } else {
00296
00297
00298 fFrames->moveIncomingFrameIntoPlace();
00299 }
00300
00301 fICClastSeen = icc;
00302 fIIlastSeen = ii;
00303 }
00304
00305 void MP3ADUdeinterleaver::releaseOutgoingFrame() {
00306 unsigned char* fromPtr;
00307 fFrames->getReleasingFrameParams(fromPtr, fFrameSize,
00308 fPresentationTime, fDurationInMicroseconds);
00309
00310 if (fFrameSize > fMaxSize) {
00311 fNumTruncatedBytes = fFrameSize - fMaxSize;
00312 fFrameSize = fMaxSize;
00313 }
00314 memmove(fTo, fromPtr, fFrameSize);
00315
00316 fFrames->releaseNext();
00317 }
00318
00320
00321 #define MAX_FRAME_SIZE 2000
00322
00323 class InterleavingFrameDescriptor {
00324 public:
00325 InterleavingFrameDescriptor() {frameDataSize = 0;}
00326
00327 unsigned frameDataSize;
00328 struct timeval presentationTime;
00329 unsigned durationInMicroseconds;
00330 unsigned char frameData[MAX_FRAME_SIZE];
00331 };
00332
00333 InterleavingFrames::InterleavingFrames(unsigned maxCycleSize)
00334 : fMaxCycleSize(maxCycleSize), fNextIndexToRelease(0),
00335 fDescriptors(new InterleavingFrameDescriptor[maxCycleSize]) {
00336 }
00337 InterleavingFrames::~InterleavingFrames() {
00338 delete[] fDescriptors;
00339 }
00340
00341 Boolean InterleavingFrames::haveReleaseableFrame() {
00342 return fDescriptors[fNextIndexToRelease].frameDataSize > 0;
00343 }
00344
00345 void InterleavingFrames::getIncomingFrameParams(unsigned char index,
00346 unsigned char*& dataPtr,
00347 unsigned& bytesAvailable) {
00348 InterleavingFrameDescriptor& desc = fDescriptors[index];
00349 dataPtr = &desc.frameData[0];
00350 bytesAvailable = MAX_FRAME_SIZE;
00351 }
00352
00353 void InterleavingFrames::getReleasingFrameParams(unsigned char index,
00354 unsigned char*& dataPtr,
00355 unsigned& bytesInUse,
00356 struct timeval& presentationTime,
00357 unsigned& durationInMicroseconds) {
00358 InterleavingFrameDescriptor& desc = fDescriptors[index];
00359 dataPtr = &desc.frameData[0];
00360 bytesInUse = desc.frameDataSize;
00361 presentationTime = desc.presentationTime;
00362 durationInMicroseconds = desc.durationInMicroseconds;
00363 }
00364
00365 void InterleavingFrames::setFrameParams(unsigned char index,
00366 unsigned char icc,
00367 unsigned char ii,
00368 unsigned frameSize,
00369 struct timeval presentationTime,
00370 unsigned durationInMicroseconds) {
00371 InterleavingFrameDescriptor& desc = fDescriptors[index];
00372 desc.frameDataSize = frameSize;
00373 desc.presentationTime = presentationTime;
00374 desc.durationInMicroseconds = durationInMicroseconds;
00375
00376
00377 unsigned char* ptr = &desc.frameData[0];
00378 (void)ADUdescriptor::getRemainingFrameSize(ptr);
00379
00380
00381 *ptr++ = ii;
00382 *ptr &=~ 0xE0;
00383 *ptr |= (icc<<5);
00384 }
00385
00386 void InterleavingFrames::releaseNext() {
00387 fDescriptors[fNextIndexToRelease].frameDataSize = 0;
00388 fNextIndexToRelease = (fNextIndexToRelease+1)%fMaxCycleSize;
00389 }
00390
00392
00393 class DeinterleavingFrameDescriptor {
00394 public:
00395 DeinterleavingFrameDescriptor() {frameDataSize = 0; frameData = NULL;}
00396 virtual ~DeinterleavingFrameDescriptor() {delete[] frameData;}
00397
00398 unsigned frameDataSize;
00399 struct timeval presentationTime;
00400 unsigned durationInMicroseconds;
00401 unsigned char* frameData;
00402 };
00403
00404 DeinterleavingFrames::DeinterleavingFrames()
00405 : fNextIndexToRelease(0), fHaveEndedCycle(False),
00406 fMinIndexSeen(MAX_CYCLE_SIZE), fMaxIndexSeen(0),
00407 fDescriptors(new DeinterleavingFrameDescriptor[MAX_CYCLE_SIZE+1]) {
00408 }
00409 DeinterleavingFrames::~DeinterleavingFrames() {
00410 delete[] fDescriptors;
00411 }
00412
00413 Boolean DeinterleavingFrames::haveReleaseableFrame() {
00414 if (!fHaveEndedCycle) {
00415
00416 return fDescriptors[fNextIndexToRelease].frameDataSize > 0;
00417 } else {
00418
00419
00420 if (fNextIndexToRelease < fMinIndexSeen) {
00421 fNextIndexToRelease = fMinIndexSeen;
00422 }
00423 while (fNextIndexToRelease < fMaxIndexSeen
00424 && fDescriptors[fNextIndexToRelease].frameDataSize == 0) {
00425 ++fNextIndexToRelease;
00426 }
00427 if (fNextIndexToRelease >= fMaxIndexSeen) {
00428
00429
00430
00431 for (unsigned i = fMinIndexSeen; i < fMaxIndexSeen; ++i) {
00432 fDescriptors[i].frameDataSize = 0;
00433 }
00434
00435 fMinIndexSeen = MAX_CYCLE_SIZE; fMaxIndexSeen = 0;
00436 moveIncomingFrameIntoPlace();
00437
00438 fHaveEndedCycle = False;
00439 fNextIndexToRelease = 0;
00440 return False;
00441 }
00442
00443 return True;
00444 }
00445 }
00446
00447 void DeinterleavingFrames::getIncomingFrameParams(unsigned char*& dataPtr,
00448 unsigned& bytesAvailable) {
00449
00450
00451 DeinterleavingFrameDescriptor& desc = fDescriptors[MAX_CYCLE_SIZE];
00452 if (desc.frameData == NULL) {
00453
00454 desc.frameData = new unsigned char[MAX_FRAME_SIZE];
00455 }
00456 dataPtr = desc.frameData;
00457 bytesAvailable = MAX_FRAME_SIZE;
00458 }
00459
00460 void DeinterleavingFrames
00461 ::getIncomingFrameParamsAfter(unsigned frameSize,
00462 struct timeval presentationTime,
00463 unsigned durationInMicroseconds,
00464 unsigned char& icc, unsigned char& ii) {
00465 DeinterleavingFrameDescriptor& desc = fDescriptors[MAX_CYCLE_SIZE];
00466 desc.frameDataSize = frameSize;
00467 desc.presentationTime = presentationTime;
00468 desc.durationInMicroseconds = durationInMicroseconds;
00469
00470
00471 unsigned char* ptr = desc.frameData;
00472 (void)ADUdescriptor::getRemainingFrameSize(ptr);
00473
00474
00475 fIIlastSeen = ii = *ptr; *ptr++ = 0xFF;
00476 icc = (*ptr&0xE0)>>5; *ptr |= 0xE0;
00477 }
00478
00479 void DeinterleavingFrames::getReleasingFrameParams(unsigned char*& dataPtr,
00480 unsigned& bytesInUse,
00481 struct timeval& presentationTime,
00482 unsigned& durationInMicroseconds) {
00483 DeinterleavingFrameDescriptor& desc = fDescriptors[fNextIndexToRelease];
00484 dataPtr = desc.frameData;
00485 bytesInUse = desc.frameDataSize;
00486 presentationTime = desc.presentationTime;
00487 durationInMicroseconds = desc.durationInMicroseconds;
00488 }
00489
00490 void DeinterleavingFrames::moveIncomingFrameIntoPlace() {
00491 DeinterleavingFrameDescriptor& fromDesc = fDescriptors[MAX_CYCLE_SIZE];
00492 DeinterleavingFrameDescriptor& toDesc = fDescriptors[fIIlastSeen];
00493
00494 toDesc.frameDataSize = fromDesc.frameDataSize;
00495 toDesc.presentationTime = fromDesc.presentationTime;
00496
00497
00498 unsigned char* tmp = toDesc.frameData;
00499 toDesc.frameData = fromDesc.frameData;
00500 fromDesc.frameData = tmp;
00501
00502 if (fIIlastSeen < fMinIndexSeen) {
00503 fMinIndexSeen = fIIlastSeen;
00504 }
00505 if (fIIlastSeen + 1 > fMaxIndexSeen) {
00506 fMaxIndexSeen = fIIlastSeen + 1;
00507 }
00508 }
00509
00510 void DeinterleavingFrames::releaseNext() {
00511 fDescriptors[fNextIndexToRelease].frameDataSize = 0;
00512 fNextIndexToRelease = (fNextIndexToRelease+1)%MAX_CYCLE_SIZE;
00513 }
00514
00515 void DeinterleavingFrames::startNewCycle() {
00516 fHaveEndedCycle = True;
00517 }