<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-15">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <small>Dear support,<br>
      <br>
      I have implemented a RTSP live streaming server with multiple
      stream that is used in our ONVIF server. In this server we create
      several profiles, every profile set up a live555  streaming server
      on different port (h264).<br>
      I use latest Live555 (25 march 2014).<br>
      <br>
      The problem occurs in the release version when from the client
      switch from a stream to another. I don't identify exactly where
      the system crash, but it seem block after a call of
      serverMediaSubsession::createNewRTPSink. I add some log to
      understand better and I find to sometimes the system crash in the
      doGetNextFrame method.<br>
      This problem is not present in the debug version.<br>
      <br>
      I tried to insert different passive wait (before calling
      createNewStreamSource(), createNewRTPSink() and deleteStream())
      and the problem occurs far less times.<br>
      <br>
      Do you have any idea of the problem?<br>
      <br>
      <br>
      Thanks in advance for your help.<br>
      <br>
      Bets regards<br>
      <br>
      Andrea<br>
    </small><big><br>
    </big><small><small><big>Here there is the code of my
          serverMediaSubsession and of the functions doGetNextFrame()
          and  deliverFrame() of our framedSource :</big><br>
        <br>
        <br>
      </small>class serverMediaSubsession: public
      OnDemandServerMediaSubsession <br>
              {<br>
      <br>
              public :<br>
                  static serverMediaSubsession*
      createNew(UsageEnvironment &env, Boolean reuseFirstSource,
      rtspVideoStreamer::parameters params, rtspVideoStreamer* parent);<br>
      <br>
             <br>
                  void checkForAuxSDPLine1();<br>
                  void afterPlayingDummy1();<br>
      <br>
              protected: <br>
                  serverMediaSubsession(UsageEnvironment &env, 
      Boolean reuseFirstSource, rtspVideoStreamer::parameters params,
      rtspVideoStreamer* parent);<br>
                  virtual ~serverMediaSubsession();<br>
      <br>
                  void setDoneFlag() { fDoneFlag = ~0; }<br>
      <br>
              protected:<br>
      <br>
                  //redefined virtual functions<br>
                  virtual char const* getAuxSDPLine(RTPSink* rtpSink,
      FramedSource* inputSource);<br>
                  virtual FramedSource* createNewStreamSource(unsigned
      clientSessionId, unsigned& estBitrate);<br>
                  // "estBitrate" is the stream's estimated bitrate, in
      kbps<br>
                  virtual RTPSink* createNewRTPSink(Groupsock*
      rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource*
      inputSource);<br>
      <br>
                  virtual void deleteStream(unsigned clientSessionId,
      void*& streamToken);<br>
              private:<br>
      <br>
                  UsageEnvironment* m_pEnvironment;<br>
             <br>
                  rtspVideoStreamer * m_pParent;<br>
                  rtspVideoStreamer::parameters  fParam;<br>
      <br>
                  char* fAuxSDPLine;<br>
                  char fDoneFlag; // used when setting up "fAuxSDPLine"<br>
                  RTPSink* fDummyRTPSink; <br>
              };<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          rtspVideoStreamer::serverMediaSubsession*
      rtspVideoStreamer::serverMediaSubsession::createNew(UsageEnvironment&
      env, Boolean reuseFirstSource, rtspVideoStreamer::parameters
      params, rtspVideoStreamer* parent)<br>
          {<br>
      <br>
              return new serverMediaSubsession(env,
      reuseFirstSource,params,parent);<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          rtspVideoStreamer::serverMediaSubsession
      ::serverMediaSubsession(UsageEnvironment& env, Boolean
      reuseFirstSource, rtspVideoStreamer::parameters params,
      rtspVideoStreamer* parent) <br>
              : OnDemandServerMediaSubsession(env, reuseFirstSource),
      fParam(params), m_pParent(parent)<br>
          {<br>
              m_pEnvironment = &env;<br>
              fAuxSDPLine = NULL;<br>
              fDoneFlag = 0;<br>
              fDummyRTPSink = NULL;<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
         
      rtspVideoStreamer::serverMediaSubsession::~serverMediaSubsession()
      <br>
          {<br>
              envir().taskScheduler().unscheduleDelayedTask(nextTask());<br>
              delete[] fAuxSDPLine;<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          static void afterPlayingDummy(void* clientData) <br>
          {<br>
              rtspVideoStreamer::serverMediaSubsession* subsess =
      (rtspVideoStreamer::serverMediaSubsession*)clientData;<br>
              subsess->afterPlayingDummy1();<br>
          }<br>
         
      /*--------------------------------------------------------------------*/<br>
          void
      rtspVideoStreamer::serverMediaSubsession::afterPlayingDummy1() <br>
          {<br>
              envir().taskScheduler().unscheduleDelayedTask(nextTask());<br>
              setDoneFlag();<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          static void checkForAuxSDPLine(void* clientData) <br>
          {<br>
              rtspVideoStreamer::serverMediaSubsession* subsess =
      (rtspVideoStreamer::serverMediaSubsession*)clientData;<br>
              subsess->checkForAuxSDPLine1();<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          void
      rtspVideoStreamer::serverMediaSubsession::checkForAuxSDPLine1() <br>
          {<br>
              char const* dasl;<br>
              if (fAuxSDPLine != NULL) {<br>
                  setDoneFlag();<br>
              } else if (fDummyRTPSink != NULL && (dasl =
      fDummyRTPSink->auxSDPLine()) != NULL) {<br>
                  fAuxSDPLine = strDup(dasl);<br>
                  fDummyRTPSink = NULL;<br>
      <br>
                  setDoneFlag();<br>
              } else {<br>
                  int uSecsToDelay = 100000; // 100 ms<br>
                  nextTask() =
      envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
      (TaskFunc*)checkForAuxSDPLine, this);<br>
              }<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          char const*
      rtspVideoStreamer::serverMediaSubsession::getAuxSDPLine(RTPSink*
      rtpSink, FramedSource* inputSource) <br>
          {<br>
              if (fAuxSDPLine != NULL) return fAuxSDPLine; <br>
      <br>
              if (fDummyRTPSink == NULL) { <br>
                  fDummyRTPSink = rtpSink;<br>
      <br>
                  fDummyRTPSink->startPlaying(*inputSource,
      afterPlayingDummy, this);<br>
      <br>
                  checkForAuxSDPLine(this);<br>
              }<br>
      <br>
              envir().taskScheduler().doEventLoop(&fDoneFlag);<br>
      <br>
              return fAuxSDPLine;<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          FramedSource*
      rtspVideoStreamer::serverMediaSubsession::createNewStreamSource(unsigned
      clientSessionId, unsigned& estBitrate)<br>
          {<br>
             passiveWait(1000*1000);<br>
      <br>
              estBitrate = 500;<br>
              m_pParent->lockSource();<br>
              FramedSource* mysource = NULL;<br>
      <br>
              if (fParam.m_encoderParams.m_videoCodec != mjpeg)<br>
              {<br>
                  mysource = genericSource::createNew(*m_pEnvironment,
      fParam, m_pParent);<br>
              }<br>
              else<br>
              {<br>
                  mysource =  new myJPEGVideoSource(*m_pEnvironment,
      fParam, m_pParent);<br>
              }<br>
      <br>
              m_pParent->m_bClientConnected = true;<br>
              m_pParent->unlockSource();<br>
      <br>
              FramedSource* videoES = mysource;<br>
      <br>
              switch(fParam.m_encoderParams.m_videoCodec)<br>
              {<br>
              case mpeg4:<br>
                  return
      MPEG4VideoStreamFramer::createNew(*m_pEnvironment, videoES);<br>
                  break;<br>
              case h263p:<br>
                  return
      H263plusVideoStreamFramer::createNew(*m_pEnvironment, videoES);<br>
                  break;<br>
              case h264:<br>
                  return
      H264VideoStreamFramer::createNew(*m_pEnvironment, videoES);<br>
                  break;<br>
              case mpeg2:<br>
              case mpeg1:<br>
                  return
      MPEG1or2VideoStreamFramer::createNew(*m_pEnvironment, videoES);<br>
                  break;<br>
              case mjpeg:<br>
                  return mysource;<br>
                  break;<br>
              default:<br>
                  return NULL;<br>
                  break;<br>
              }<br>
      <br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          RTPSink*
      rtspVideoStreamer::serverMediaSubsession::createNewRTPSink(Groupsock*
      rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource*
      inputSource)<br>
          {<br>
              passiveWait(1000*1000);<br>
              switch(fParam.m_encoderParams.m_videoCodec)<br>
              {<br>
              case mpeg4:<br>
                  return MPEG4ESVideoRTPSink::createNew(*m_pEnvironment,
      rtpGroupsock, 96);<br>
                  break;<br>
              case h263p:<br>
                  return
      H263plusVideoRTPSink::createNew(*m_pEnvironment, rtpGroupsock,
      96);<br>
                  break;<br>
              case h264:<br>
                  return  H264VideoRTPSink::createNew(*m_pEnvironment,
      rtpGroupsock, rtpPayloadTypeIfDynamic/*96*/);<br>
                  break;<br>
              case mpeg2:<br>
              case mpeg1:<br>
                  return
      MPEG1or2VideoRTPSink::createNew(*m_pEnvironment, rtpGroupsock);<br>
                  break;<br>
              case mjpeg:<br>
                  return JPEGVideoRTPSink::createNew(*m_pEnvironment,
      rtpGroupsock);<br>
                  break;<br>
              default:<br>
                  return NULL;<br>
                  break;<br>
              }<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          void
      rtspVideoStreamer::serverMediaSubsession::deleteStream(unsigned
      clientSessionId, void*& streamToken) <br>
          {<br>
             
      OnDemandServerMediaSubsession::deleteStream(clientSessionId,
      streamToken);<br>
             passiveWait(1500*1000);<br>
      <br>
              StreamState* streamState = (StreamState*)streamToken;<br>
              if (streamState != NULL) <br>
                  m_pParent->m_bClientConnected = true;<br>
              else<br>
                  m_pParent->m_bClientConnected = false;<br>
          }</small><br>
    <br>
    <small>   
      /*--------------------------------------------------------------------*/</small><br>
    <small>    void rtspVideoStreamer::genericSource::doGetNextFrame()<br>
          {<br>
              bool ret;<br>
              ucImage img;<br>
              m_pParent->getImage(img);<br>
              if (img.isValid())<br>
              {<br>
                  if ((m_imgSize.width()!=img.getWidth()) ||
      (m_imgSize.height()!=img.getHeight()))<br>
                  {<br>
                      imgResizer imgres;<br>
                      imgResizer::parameters resizeparam;<br>
                      resizeparam.m_width = m_imgSize.width();<br>
                      resizeparam.m_height = m_imgSize.height();<br>
                      imgres.setParameters(resizeparam);<br>
                      imgres.apply(img);<br>
                  }<br>
                  try<br>
                  {<br>
                      ret = m_enc.apply(img, m_pBufferCompressed,
      m_iCompressedSize);<br>
                  }<br>
                  catch (...)<br>
                  {<br>
                      <br>
                  }<br>
      <br>
      <br>
              }<br>
      <br>
              try<br>
              {<br>
                  deliverFrame();<br>
              }<br>
              catch (...)<br>
              {<br>
                 
      LOG_DBG("rtspVideoStreamer::genericSource::doGetNextFrame()::deliverFrame()
      ecception");<br>
              }<br>
              if (0 /* the source stops being readable */)<br>
              {<br>
                  handleClosure(this);<br>
                  return;<br>
              }<br>
          }<br>
      <br>
         
      /*--------------------------------------------------------------------*/<br>
          void rtspVideoStreamer::genericSource::deliverFrame()<br>
          {<br>
              if ((unsigned)m_iCompressedSize > fMaxSize)<br>
              {<br>
                  fNumTruncatedBytes = m_iCompressedSize - fMaxSize;<br>
                  fFrameSize = fMaxSize;<br>
                  memcpy(fTo, m_pBufferCompressed, fMaxSize);<br>
              }<br>
              else<br>
              {<br>
                  memcpy(fTo, m_pBufferCompressed, m_iCompressedSize);<br>
                  fFrameSize = m_iCompressedSize;<br>
              }<br>
      <br>
              gettimeofday(&fPresentationTime, NULL);<br>
      <br>
              if (!isCurrentlyAwaitingData()) return; // we're not ready
      for the data yet<br>
      <br>
              FramedSource::afterGetting(this);<br>
          }</small><br>
    <br>
    <pre class="moz-signature" cols="72">-- 
*Andrea Beoldo*
Project Manager/R&D
Technoaware Srl
Corso Buenos Aires 18/11, 16129 Genova (GE) 
Ph. +39 010 5539239 Fax. +39 0105539240
Email: <a class="moz-txt-link-abbreviated" href="mailto:andrea.beoldo@technoaware.com">andrea.beoldo@technoaware.com</a>
Web: <a class="moz-txt-link-abbreviated" href="http://www.technoaware.com">www.technoaware.com</a> 

------------------------------------------------------------------------
*Privacy*

Le informazioni contenute in questo messaggio sono riservate e confidenziali. Il loro utilizzo č consentito esclusivamente al destinatario del messaggio, per le finalitā indicate nel messaggio stesso. Qualora Lei non fosse la persona a cui il presente messaggio č destinato, La invitiamo ad eliminarlo dal Suo sistema ed a distruggere le varie copie o stampe, dandocene gentilmente comunicazione. Ogni utilizzo improprio č contrario ai principi del D.lgs 196/03 e alla legislazione europea (Direttiva 2002/58/CE). TechnoAware opera in conformitā al D.lgs 196/2003 e alla legislazione europea.

The information contained in this message as well as the attached file(s)is confidential/privileged and is only intended for the person to whom it is addressed. If the reader of this message is not the intended recipient or the employee or agent responsible for delivering the message to the intended recipient, or you have received this communication in error, please be aware that any dissemination, distribution or duplication is strictly prohibited and can be illegal. Please notify us immediately and delete all copies from your mailbox and other archives. Thank you.</pre>
  </body>
</html>