Exemple #1
0
bool RtpSource::RemoveInternalRtpPacket(RtpPacket *rtpPacket)
{
  bool result = false;

  if (rtpPacket != NULL)
  {
    RtpPacket *previousRtpPacket = rtpPacket->GetPreviousPacket();;
    RtpPacket *nextRtpPacket = rtpPacket->GetNextPacket();

    if (previousRtpPacket != NULL)
    {
      // next RTP packet can be NULL, in that case previous RTP packet will be last
      previousRtpPacket->SetNextPacket(nextRtpPacket);
    }
    else
    {
      // first packet will be deleted, first packet need to be moved to next packet
      // if next RTP packet is NULL then packet to delete was one and only and this->firstRtpPacket will be set to NULL
      this->firstRtpPacket = nextRtpPacket;
    }

    if (nextRtpPacket != NULL)
    {
      // previous RTP packet can be NULL, in that case next RTP packet will be first
      nextRtpPacket->SetPreviousPacket(previousRtpPacket);
    }

    delete rtpPacket;
    result = true;
  }

  return result;
}
Exemple #2
0
bool RtpSource::IsRtpPacket(char *buffer, unsigned int length)
{
  RtpPacket *rtpPacket = new RtpPacket(buffer, length, NULL, NULL);
  bool isRtpPacket = rtpPacket->IsRtpPacket();
  delete rtpPacket;

  return isRtpPacket;
}
Exemple #3
0
bool RtpSource::ProcessPacket(char *buffer, unsigned int length) 
{
  RtpPacket *rtpPacket = new RtpPacket(buffer, length, NULL, NULL);
  if (!rtpPacket->IsRtpPacket())
  {
    // some problem occured
    return false;
  }
  return (this->AddPacket(rtpPacket));
}
Exemple #4
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 #5
0
RtpPacket *RtpSource::GetRtpPacket(unsigned int sequenceNumber)
{
  RtpPacket *result = this->GetInternalRtpPacket(sequenceNumber);

  if (result != NULL)
  {
    result = result->Clone();
  }

  return result;
}
Exemple #6
0
RtpPacket *RtpSource::GetRtpPacket(int index)
{
  RtpPacket *result = this->GetInternalRtpPacket(index);

  if (result != NULL)
  {
    result = result->Clone();
  }

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

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

  return result;
}
Exemple #8
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;
}
const RtpPacket* RtpBuffer::takePacket()
{
    RtpPacket* packet = NULL;

    m_mutex.lock();
    if (m_state == Ready || m_state == Flushing) {
        // take from top, until free packet or flush
        packet = &(m_data[m_first]);

        // we might catch a packet which is marked as flush but is not received yet
        if (packet->flush) {
            qDebug()<<Q_FUNC_INFO<<": flush packet: " << packet->sequenceNumber;
            setState(Filling);
            packet->flush = false;
        } else {
            switch (packet->status) {
            case RtpPacket::PacketFree:
                qWarning()<<Q_FUNC_INFO<<": free packet: " << packet->sequenceNumber;
                setState(Empty);
                packet = NULL;
                break;
            case RtpPacket::PacketMissing:
                qWarning()<<Q_FUNC_INFO<< "missing packet: "<<packet->sequenceNumber<<", payload size: "<<packet->payloadSize;
                memcpy(packet->payload, m_silence, packet->payloadSize);
            case RtpPacket::PacketOk:
                if (m_first == m_last) {
                    qDebug()<<Q_FUNC_INFO<<": buffer empty";
                    setState(Empty);
                } else {
                    m_first = (m_first+1) % m_capacity;
                }
                packet->init();
                break;
            default:
                qFatal(__func__);
                packet = NULL;
            }
        }
    }
    State currentState = m_state;
    m_mutex.unlock();

    emitStateChanged(currentState);

    return packet;
}
RtpPacket* RtpAudioReceiver::receive(char* encodedData, int encodedDataLen) {
    int received = recv(socketFd, encodedData, encodedDataLen, 0);

    if (received == -1) {
        __android_log_print(ANDROID_LOG_WARN, TAG, "recv() failed!");
        return NULL;
    }

    RtpPacket *packet = new RtpPacket(encodedData, received);

    if (srtpStream.decrypt(*packet, sequenceCounter.convertNext(packet->getSequenceNumber())) != 0) {
        __android_log_print(ANDROID_LOG_WARN, TAG, "SRTP decrypt failed!");
        delete packet;
        return NULL;
    }

    return packet;
}
Exemple #11
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 #12
0
int RtpManager::sendRtp(RtpType rt, const uchar *buffer, size_t len) {
	XASSERT(this->pSendManager != XNULL, "SendManager not inited.");
	ushort packetCount = ceil((double) len / (double) RTP_DATA_MAX_SIZE);
	if (packetCount > SUB_PACKET_MAX_COUNT) {
		LOG("This RtpData (Size = %d) is Too Big!\n", len);
		return ERROR_CODE_RTP_DATA_OVERSIZE;
	}
	this->mRtpSequence++;
	uint currentMilliSeconds = XUtils::currentMilliSeconds()
			% (24 * 3600 * 1000);
	size_t offset = 0;
	int err = 0;
	RtpPacket *rp = RtpPacket::obtain(this->mSsrc, rt, currentMilliSeconds,
			this->mRtpSequence);
	for (int i = 0; i < packetCount; i++) {
		size_t myLen =
				(len - offset) > iAvalableSize ? iAvalableSize : (len - offset);
		rp->setSubCount(packetCount)->setSubSequence(i)->setTotalLength(len)->setLength(
				myLen)->setOffset(offset);
		offset = rp->setData(buffer, offset, myLen);
		err = this->pSendManager->send(rp);
		if (err < 0) {
			return err;
		} else {
			//this->mPacksSent++;
			//this->mOcetsSent += rp->getBytesLength();
		}
	}
	/*
	{
		char *hex = new char[2 * len + 1];
		XUtils::bytesToHexString(buffer, len, hex);
		LOG("SEND(%d):%s\n", len, hex);
		delete[] hex;
	}*/
	return err;
}
bool RtpSession::send_rtp_packet(void *buf, uint16_t size, uint32_t ts_inc )
{
	uint32_t timestamp;
	struct timeval start_time_tv, now_tv;
	double play_time, now;
	
	timestamp = m_prev_timestamp + ts_inc;
	m_prev_timestamp = timestamp;
	
	if ( !buf || !size ) {
	  printf("Cannot send packet.\n");
	  return false;
	}
	
	if ( ! m_psent ) {
		/* This is the 1th packet that we send.
		 * Here we should send an RTCP SDES packet with all the 
		 * infos...
		 */
		gettimeofday(&start_time_tv, NULL);
		m_start_time = tv2dbl(start_time_tv);
		
		/*! Build the SDES CNAME packet */
		uint16_t s = 10 + strlen( m_cname );
		/* Align to 32 bit boundary .. */
		s = (uint16_t)ceil( (double)s /4 ) * 4;
		
		m_sdes_pkt = (rtcp_t *)calloc( s , 1 );
		RtcpPacket *p = new RtcpPacket( m_sdes_pkt, s );
		p->set_version( 2 );
		p->set_padding( 0 );
		p->set_count( 1 );
		p->set_type( RTCP_SDES );
		p->set_length( (uint16_t)s/4 - 1 );
		m_sdes_pkt->r.sdes.src = htonl( m_ssrc );
		m_sdes_pkt->r.sdes.item->type = RTCP_SDES_CNAME;
		m_sdes_pkt->r.sdes.item->length = strlen( m_cname );
		memcpy( m_sdes_pkt->r.sdes.item[0].data, m_cname, strlen(m_cname) );
		m_sdes_pkt_size = s;

		/*! Schedule an RTCP for now.. */
		event_t *e = (event_t*)malloc( sizeof( event_t ) );
 		e->type = RTCP_SR;
		e->time = 0.0;
		e->next = NULL;
		insert_event( e );
		send_rtcp();
	}

	/** OK, we build the real RTP packet... */
	RtpPacket *pkt = new RtpPacket( (uint8_t*)buf, size );
	pkt->set_ssrc( m_ssrc );
	pkt->set_payload_type( m_payload_type );
	pkt->set_sequence( m_seq++ );
	pkt->set_timestamp( timestamp );
	delete pkt;

	if ( ! send_pkt( buf, size ) ) {
		/* Problems sending packet.. probably the client closed
		 * the connection..
		 */
		return false;
	}

	/* *************************************************** */
	/*! Here we check for events or things to do... */

	/* Schedule the times to play packets as an absolute offset from
	 * our start time, rather than a relative offset from the initial
	 * packet.  (We're less vulnerable to drifting clocks that way).
	 * Alternative version based on timestamps and RTP clock..
	 */
	play_time = m_start_time + ((double)(timestamp - m_base_timestamp)/ m_rtp_clock);
	// printf("play_time: %f - difference: %f sec.\n", play_time,
	//		((double)(timestamp - m_base_timestamp)/ m_rtp_clock));

	while (gettimeofday(&now_tv, NULL), (now = tv2dbl(now_tv)) < play_time) {

		int event = 0;
		int retval;
		double timeout;
		struct timeval timeout_tv;
		fd_set sockets;

		if (	m_event_queue != NULL && 
			m_event_queue->time < play_time ) {
			event = 1;
			timeout = m_event_queue->time - now;
		} else {
			event = 0;
			timeout = play_time - now;
		}
		if ( timeout < 0 )
			timeout = 0;
		timeout_tv = dbl2tv( timeout );

		FD_ZERO( &sockets );
		FD_SET( m_rtp_sock, &sockets );
		FD_SET( m_rtcp_sock, &sockets );

		int max_fd = ((m_rtp_sock > m_rtcp_sock) ? m_rtp_sock : m_rtcp_sock ) + 1;

		retval = select(max_fd, &sockets, NULL, NULL, &timeout_tv);
		if ( retval < 0 ) {
			perror("select");
			exit(1);
		} else if ( retval > 0 ) { // There are some events...
			if (FD_ISSET(m_rtp_sock, &sockets)) {
				/* There's an RTP packet to be read... 
				 * We should receive, validate and .. trash it..
				 */
				receive_rtp( (void*)m_buf );
			}
			
			if (FD_ISSET(m_rtcp_sock, &sockets)) {
				receive_rtcp();
			}
		}  else { /* retval == 0, select timed out */
			if (event) {
				gettimeofday( &now_tv, NULL );
				now = tv2dbl( now_tv );
				while ( m_event_queue != NULL &&
					m_event_queue->time <= now ) {
					/* There is a pending RTCP packet to send) */
					send_rtcp();
				}
			} else
				break;  /* Time for the next packet */
		}
	}
	/* **************************************************** */
	return true;
}
Exemple #14
0
RtpPacket* AsfParser::MakeRtpPacket(AsfPacket* packet) 
{
	assert(packet != NULL);
    
	if( packet->PadLen == 0 ) 
    {
		uint16_t rtpSize = RtpPacket::RTP_HEAD_LEN + 4 + packet->PacketLen; 
		RtpPacket* rtpPacket = new RtpPacket( rtpSize );
		uint8_t* p = rtpPacket->payload;
        
		*(uint16_t*) p = htons(0x4000);
		p += 2;
        
		*(uint16_t*) p = htons(rtpPacket->payloadSize);
		p += 2;
        
		memcpy( p, packet->Buf, packet->PacketLen );
		assert ( packet->PacketLen + 4 == rtpPacket->payloadSize );
		rtpPacket->SetTimeStamp( packet->Time );
		return rtpPacket;
	}
	else 
    {
		uint16_t rtpSize = RtpPacket::RTP_HEAD_LEN + 4 + 7 + 6 + packet->PayloadSize ; 
		RtpPacket* rtpPacket = new RtpPacket( rtpSize );
		uint8_t* buf = new uint8_t [ rtpPacket->payloadSize ];
		uint8_t* p = buf;
        
		*(uint16_t*) p = htons(0x4000);
		p += 2;
        
		*(uint16_t*) p = htons(rtpPacket->payloadSize);
		p += 2;
        
		(*p) = packet->ErrorFlags;
		p += 1;
		for(int i = 0; i < packet->ErrorDataLen; i++) 
        {
			(*p) = packet->ErrorData[i];
			p += 1;
		}
        
		(*p) = 0x40;
		if( (packet->LenFlags&0x01) != 0 ) 
        {
			(*p) |= 0x01;
		}
		p += 1;
        
		(*p) = packet->PropFlags;
		p += 1;
        
		*(uint16_t*)p =  rtpPacket->payloadSize - 4 ;
		p += 2;
        
		*(uint16_t*) p = packet->Time;
		p += 4;
        
		*(uint16_t*) p = packet->Duration;
		p += 2;
        
		memcpy( p, packet->Payload, packet->PayloadSize );
		p += packet->PayloadSize;
		
		assert( p - buf == rtpPacket->payloadSize );
        
        
		rtpPacket->SetPayLoad( buf, rtpPacket->payloadSize );
		rtpPacket->SetTimeStamp( packet->Time );
		delete buf;
		return rtpPacket;
	}
}
void CacheSegment::add_packet( const void *buf, uint16_t size, 
			bool adjust_ts, bool set_offset )
{
	assert( buf );
	assert( size );
	uint32_t timestamp = 0;
	RtpPacket *rtp;

	if ( m_fd == NULL )
		this->open( false);

	if ( m_first_time ) {
		/* This is the 1th packet */
		pthread_mutex_lock( &s_cache_segment_mutex );
		s_cache_segment = this;

		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_create( &m_thread, &attr , &thread_main, NULL);
		pthread_detach( m_thread );

		m_first_time = false;
	}

	if ( IS_RTP( m_transport_type ) ) {
		rtp = new RtpPacket( (uint8_t*)buf, size );
		timestamp = rtp->timestamp();
		// dbg("payload: %u - ts: %u - size: %u \n",
		//    rtp->payload_type(), timestamp, size);
	} else {
		dbg("Unknown transport type %u... cannot cache packets...\n",
			 m_transport_type);
		return;
	}

    #warning Locking disabilitato
    /// printf("locking\n");
	// /this->lock();

	/* Go to EOF */
	fseek( m_fd, 0L, SEEK_END );

	if ( fwrite( buf, 1, size, m_fd ) < (int32_t)size ) {
		perror("CacheSegment::add_packet() : Error writing to file.");
		return;
	}
	/// this->unlock();
    /// printf("unlocked\n");

	free( (uint8_t*)buf );
	delete rtp;

	packet_t *p = (packet_t *)malloc( sizeof( packet_t ) );

	if ( set_offset )
		m_ts_offset = timestamp - m_prev_timestamp;

	if ( adjust_ts ) {
		p->timestamp = timestamp - m_ts_offset;
	} else p->timestamp = timestamp;

	// dbg("Ts: %u\n", p->timestamp );

	p->size = size;
	p->offset = m_prev_offset;
	m_packet_list->InsertTail( p );

	m_prev_offset += size;
	m_prev_timestamp = p->timestamp;
	m_size += size;
	++m_num_packets;
}
Exemple #16
0
RtpPacket * AsfReader::Packet2Rtp(AsfPacket * pa) 
{
	//将从文件读出的packet 转换成 RtpPacket  包 , 用Packet 中的time设置其Timestamp 值
	ASSERT( pa != NULL);

	DWORD rtpSize;
	if( pa->PadLen == 0 ) {
		rtpSize = RtpPacket::RTP_HEAD_LEN + 4 + pa->PacketSize;
#pragma warning(disable : 4244)
		RtpPacket* rtpPa = new RtpPacket ( rtpSize );
#pragma warning(default : 4244)
		BYTE * p = rtpPa->payload;

		*(WORD*) p = htons(0x4000);
		//if( isFirstPacket ) p|= 0x10;
		p += 2;

		*(WORD*) p = htons(rtpPa->payloadSize);
		p += 2;

		memcpy( p, pa->buf, pa->PacketSize );
		ASSERT ( pa->PacketSize + 4 == rtpPa->payloadSize );
		rtpPa->SetTimeStamp( pa->Time );
		return rtpPa;
	}
		
	
	else {
		rtpSize = RtpPacket::RTP_HEAD_LEN + 4 + 7 + 6 + pa->PayloadSize;
#pragma warning(disable : 4244)
		RtpPacket* rtpPa = new RtpPacket ( rtpSize );
#pragma warning(default : 4244)
		BYTE * buf = new BYTE [ rtpPa->payloadSize ];
		BYTE* p = buf;

		*(WORD*) p = htons(0x4000);
		p += 2;

		*(WORD*) p = htons(rtpPa->payloadSize);
		p += 2;

		(*p) = pa->ErrorFlags;
		p +=1;
		for(int i=0; i<pa->ErrorDataLen; i++) {
			(*p) = pa->ErrorData[i];
			p+=1;
		}

		(*p) = 0x40;
		if( (pa->LenFlags&0x01) != 0 ) {
			(*p)|=0x01;
		}
		p+=1;

		(*p) = pa->PropFlags;
		p+=1;

		*(WORD*)p =  rtpPa->payloadSize - 4 ;
		p+=2;

		*(DWORD*) p = pa->Time;
		p+=4;

		*(WORD*) p = pa->Duration;
		p+=2;

		memcpy( p, pa->Payload, pa->PayloadSize );
		p+=pa->PayloadSize;
		
		ASSERT( p - buf == rtpPa->payloadSize );


		rtpPa->SetPayLoad( buf, rtpPa->payloadSize );
		rtpPa->SetTimeStamp( pa->Time );
		delete buf;
		return rtpPa;

	}
	
}
Exemple #17
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;
}