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; }
unsigned int RtpSource::GetPacketCount(void) { unsigned int result = 0; RtpPacket *currentRtpPacket = this->firstRtpPacket; while (currentRtpPacket != NULL) { result++; currentRtpPacket = currentRtpPacket->GetNextPacket(); } return result; }
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; }
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; }
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; }