Exemple #1
0
unsigned int RtpSource::GetPacketData(char* buffer, unsigned int length, unsigned int *firstSequenceNumber, unsigned int *lastSequenceNumber, bool getUncontinousPackets) 
{
  unsigned int result = UINT_MAX;
  bool setFirstSequenceNumber = false;

  if ((this->firstRtpPacket != NULL) && (firstSequenceNumber != NULL) && (lastSequenceNumber != NULL))
  {
    result = 0;
    bool finishWork = false;
    RtpPacket *currentRtpPacket = this->firstRtpPacket;

    while (!finishWork)
    {
      unsigned int freeSpace = length - result;
      finishWork = (currentRtpPacket->GetDataLength() >= freeSpace);
      if (!finishWork)
      {
        // in buffer is enough free space for data from first RTP packet
        int copiedDataLength = currentRtpPacket->GetData(buffer + result, freeSpace);
        if (copiedDataLength >= 0)
        {
          // no error occured
          result += copiedDataLength;
          if (!setFirstSequenceNumber)
          {
            *firstSequenceNumber = currentRtpPacket->GetSequenceNumber();
            setFirstSequenceNumber = true;
          }
          else
          {
            *lastSequenceNumber = currentRtpPacket->GetSequenceNumber();
          }
        }
        // if error occured we skip this RTP packet

        if (currentRtpPacket->GetNextPacket() != NULL)
        {
          // check if next packet is continous
          bool isContinous = this->IsSequenceContinuous(currentRtpPacket->GetSequenceNumber(), currentRtpPacket->GetNextPacket()->GetSequenceNumber());
          if (!isContinous)
          {
            this->logger->Log(LOGGER_WARNING, _T("%s: %s: got uncontinous packet, last sequence number: %u"), PROTOCOL_IMPLEMENTATION_NAME, METHOD_GET_PACKET_DATA_NAME, currentRtpPacket->GetSequenceNumber());
          }

          finishWork |= ((!getUncontinousPackets) && (!isContinous));
        }

        finishWork |= (currentRtpPacket->GetNextPacket() == NULL);

        if (!finishWork)
        {
          // move to next packet
          currentRtpPacket = currentRtpPacket->GetNextPacket();
        }
      }
    }
  }

  return result;
}
Exemple #2
0
unsigned int RtpSource::GetPacketCount(void)
{
  unsigned int result = 0;
  RtpPacket *currentRtpPacket = this->firstRtpPacket;

  while (currentRtpPacket != NULL)
  {
    result++;
    currentRtpPacket = currentRtpPacket->GetNextPacket();
  }

  return result;
}
Exemple #3
0
RtpPacket *RtpSource::GetInternalRtpPacket(unsigned int sequenceNumber)
{
  RtpPacket *result = NULL;

  RtpPacket *currentRtpPacket = this->firstRtpPacket;
  while ((currentRtpPacket != NULL) && (result == NULL))
  {
    if (currentRtpPacket->GetSequenceNumber() == sequenceNumber)
    {
      result = currentRtpPacket;
    }
    currentRtpPacket = currentRtpPacket->GetNextPacket();
  }

  return result;
}
Exemple #4
0
RtpPacket *RtpSource::GetInternalRtpPacket(int index)
{
  RtpPacket *result = NULL;
  if ((this->firstRtpPacket != NULL) && (index >= 0))
  {
    RtpPacket *currentRtpPacket = this->firstRtpPacket;
    for (int i = 0; ((i < index) && (currentRtpPacket != NULL)); i++)
    {
      currentRtpPacket = currentRtpPacket->GetNextPacket();
    }

    if (currentRtpPacket != NULL)
    {
      result = currentRtpPacket;
    }
  }

  return result;
}
Exemple #5
0
bool RtpSource::AddPacket(RtpPacket *rtpPacket) 
{
  bool result = (rtpPacket != NULL);

  if (result)
  {
    result &= rtpPacket->IsRtpPacket();
  }

  if (result)
  {
    this->logger->Log(LOGGER_DATA, _T("%s: %s: sequence number: %u"), PROTOCOL_IMPLEMENTATION_NAME, METHOD_ADD_PACKET_NAME, rtpPacket->GetSequenceNumber());

    // check where packet need to be inserted
    if (this->firstRtpPacket == NULL)
    {
      this->firstRtpPacket = rtpPacket;
    }
    else
    {
      unsigned int rtpPacketSequenceNumber = rtpPacket->GetSequenceNumber();

      // in RTP packets chain cannot be wrong packets

      RtpPacket *firstPacket = NULL;
      RtpPacket *secondPacket = this->firstRtpPacket;

      // go to the end of chain
      while (secondPacket != NULL)
      {
        firstPacket = secondPacket;
        secondPacket = secondPacket->GetNextPacket();
      }

      // now go from end of chain to start of chain
      while (1)
      {
        bool between = true;

        if ((firstPacket != NULL) && (secondPacket != NULL))
        {
          between &= this->IsPacketBetween(rtpPacket, firstPacket, secondPacket);
        }
        else if (firstPacket != NULL)
        {
          // rtpPacket is after first packet ?
          between &= (this->PacketSequenceNumberDifference(firstPacket, rtpPacket) >= 0);
        }
        else if (secondPacket != NULL)
        {
          // rtpPacket is before second packet ?
          between &= (this->PacketSequenceNumberDifference(rtpPacket, secondPacket) <= 0);
        }

        if (between)
        {
          // got combination of two packets
          break;
        }

        secondPacket = firstPacket;
        if (firstPacket != NULL)
        {
          firstPacket = firstPacket->GetPreviousPacket();
        }
      }

      if ((firstPacket == NULL) && (secondPacket != NULL))
      {
        // packet have to be added before this->firstRtpPacket
        this->firstRtpPacket->SetPreviousPacket(rtpPacket);
        rtpPacket->SetNextPacket(this->firstRtpPacket);
        rtpPacket->SetPreviousPacket(NULL);
        this->firstRtpPacket = rtpPacket;
      }
      else if ((firstPacket != NULL) && (secondPacket != NULL))
      {
        // packet have to be added between first and second packet
        firstPacket->SetNextPacket(rtpPacket);
        secondPacket->SetPreviousPacket(rtpPacket);
        rtpPacket->SetPreviousPacket(firstPacket);
        rtpPacket->SetNextPacket(secondPacket);
      }
      else if ((firstPacket != NULL) && (secondPacket == NULL))
      {
        // packet have to be added at the end (after first packet)
        firstPacket->SetNextPacket(rtpPacket);
        rtpPacket->SetPreviousPacket(firstPacket);
        rtpPacket->SetNextPacket(NULL);
      }
    }
  }

  return result;
}