~ubuntu-branches/ubuntu/trusty/liblivemedia/trusty

« back to all changes in this revision

Viewing changes to liveMedia/RTPInterface.cpp

  • Committer: Package Import Robot
  • Author(s): Benjamin Drung
  • Date: 2013-10-30 10:30:48 UTC
  • mfrom: (27.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20131030103048-ggp9ojaizodox2y6
Tags: 2013.10.25-1
* Team upload.
* New upstream release.
* Link shared libraries with g++ instead of gcc to fix build failure.
* Refresh patches.
* Update shared library versions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
  ServerRequestAlternativeByteHandler* fServerRequestAlternativeByteHandler;
72
72
  void* fServerRequestAlternativeByteHandlerClientData;
73
73
  u_int8_t fStreamChannelId, fSizeByte1;
74
 
  Boolean fReadErrorOccurred, fDeleteMyselfNext;
 
74
  Boolean fReadErrorOccurred, fDeleteMyselfNext, fAreInReadHandlerLoop;
75
75
  enum { AWAITING_DOLLAR, AWAITING_STREAM_CHANNEL_ID, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_PACKET_DATA } fTCPReadingState;
76
76
};
77
77
 
129
129
}
130
130
 
131
131
RTPInterface::~RTPInterface() {
 
132
  stopNetworkReading();
132
133
  delete fTCPStreams;
133
134
}
134
135
 
135
136
void RTPInterface::setStreamSocket(int sockNum,
136
137
                                   unsigned char streamChannelId) {
137
138
  fGS->removeAllDestinations();
 
139
  envir().taskScheduler().disableBackgroundHandling(fGS->socketNum()); // turn off any reading on our datagram socket
 
140
  fGS->reset(); // and close our datagram socket, because we won't be using it anymore
138
141
  addStreamSocket(sockNum, streamChannelId);
139
142
}
140
143
 
184
187
  }
185
188
}
186
189
 
187
 
void RTPInterface
188
 
::setServerRequestAlternativeByteHandler(int socketNum, ServerRequestAlternativeByteHandler* handler, void* clientData) {
189
 
  SocketDescriptor* socketDescriptor = lookupSocketDescriptor(envir(), socketNum);
 
190
void RTPInterface::setServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum,
 
191
                                                          ServerRequestAlternativeByteHandler* handler, void* clientData) {
 
192
  SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, socketNum, False);
190
193
 
191
194
  if (socketDescriptor != NULL) socketDescriptor->setServerRequestAlternativeByteHandler(handler, clientData);
192
195
}
193
196
 
 
197
void RTPInterface::clearServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum) {
 
198
  setServerRequestAlternativeByteHandler(env, socketNum, NULL, NULL);
 
199
}
194
200
 
195
201
Boolean RTPInterface::sendPacket(unsigned char* packet, unsigned packetSize) {
196
202
  Boolean success = True; // we'll return False instead if any of the sends fail
277
283
  envir().taskScheduler().turnOffBackgroundReadHandling(fGS->socketNum());
278
284
 
279
285
  // Also turn off read handling on each of our TCP connections:
280
 
  for (tcpStreamRecord* streams = fTCPStreams; streams != NULL;
281
 
       streams = streams->fNext) {
 
286
  for (tcpStreamRecord* streams = fTCPStreams; streams != NULL; streams = streams->fNext) {
282
287
    deregisterSocket(envir(), streams->fStreamSocketNum, streams->fStreamChannelId);
283
288
  }
284
289
}
343
348
  :fEnv(env), fOurSocketNum(socketNum),
344
349
    fSubChannelHashTable(HashTable::create(ONE_WORD_HASH_KEYS)),
345
350
   fServerRequestAlternativeByteHandler(NULL), fServerRequestAlternativeByteHandlerClientData(NULL),
346
 
   fReadErrorOccurred(False), fDeleteMyselfNext(False), fTCPReadingState(AWAITING_DOLLAR) {
 
351
   fReadErrorOccurred(False), fDeleteMyselfNext(False), fAreInReadHandlerLoop(False), fTCPReadingState(AWAITING_DOLLAR) {
347
352
}
348
353
 
349
354
SocketDescriptor::~SocketDescriptor() {
350
355
  fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum);
 
356
  removeSocketDescription(fEnv, fOurSocketNum);
 
357
 
 
358
  if (fSubChannelHashTable != NULL) {
 
359
    // Remove knowledge of this socket from any "RTPInterface"s that are using it:
 
360
    HashTable::Iterator* iter = HashTable::Iterator::create(*fSubChannelHashTable);
 
361
    RTPInterface* rtpInterface;
 
362
    char const* key;
 
363
 
 
364
    while ((rtpInterface = (RTPInterface*)(iter->next(key))) != NULL) {
 
365
      long streamChannelIdLong = (long)key;
 
366
      unsigned char streamChannelId = (unsigned char)streamChannelIdLong;
 
367
 
 
368
      rtpInterface->removeStreamSocket(fOurSocketNum, streamChannelId);
 
369
    }
 
370
    delete iter;
 
371
 
 
372
    // Then remove the hash table entries themselves, and then remove the hash table:
 
373
    while (fSubChannelHashTable->RemoveNext() != NULL) {}
 
374
    delete fSubChannelHashTable;
 
375
  }
 
376
 
 
377
  // Finally:
351
378
  if (fServerRequestAlternativeByteHandler != NULL) {
352
379
    // Hack: Pass a special character to our alternative byte handler, to tell it that either
353
380
    // - an error occurred when reading the TCP socket, or
355
382
    u_int8_t specialChar = fReadErrorOccurred ? 0xFF : 0xFE;
356
383
    (*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, specialChar);
357
384
  }
358
 
  removeSocketDescription(fEnv, fOurSocketNum);
359
 
 
360
 
  if (fSubChannelHashTable != NULL) {
361
 
    while (fSubChannelHashTable->RemoveNext() != NULL) {} // remove the "RTPInterface"s from the table, but don't delete them
362
 
    delete fSubChannelHashTable;
363
 
  }
364
385
}
365
386
 
366
387
void SocketDescriptor::registerRTPInterface(unsigned char streamChannelId,
396
417
 
397
418
  if (fSubChannelHashTable->IsEmpty()) {
398
419
    // No more interfaces are using us, so it's curtains for us now:
399
 
    fDeleteMyselfNext = True; // hack to cause ourself to be deleted from "tcpReadHandler()" below
 
420
    if (fAreInReadHandlerLoop) {
 
421
      fDeleteMyselfNext = True; // we can't delete ourself yet, but we'll do so from "tcpReadHandler()" below
 
422
    } else {
 
423
      delete this;
 
424
    }
400
425
  }
401
426
}
402
427
 
403
428
void SocketDescriptor::tcpReadHandler(SocketDescriptor* socketDescriptor, int mask) {
404
429
  // Call the read handler until it returns false, with a limit to avoid starving other sockets
405
430
  unsigned count = 2000;
 
431
  socketDescriptor->fAreInReadHandlerLoop = True;
406
432
  while (!socketDescriptor->fDeleteMyselfNext && socketDescriptor->tcpReadHandler1(mask) && --count > 0) {}
 
433
  socketDescriptor->fAreInReadHandlerLoop = False;
407
434
  if (socketDescriptor->fDeleteMyselfNext) delete socketDescriptor;
408
435
}
409
436