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; }
bool RtpSource::IsRtpPacket(char *buffer, unsigned int length) { RtpPacket *rtpPacket = new RtpPacket(buffer, length, NULL, NULL); bool isRtpPacket = rtpPacket->IsRtpPacket(); delete rtpPacket; return isRtpPacket; }
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)); }
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; }
RtpPacket *RtpSource::GetRtpPacket(unsigned int sequenceNumber) { RtpPacket *result = this->GetInternalRtpPacket(sequenceNumber); if (result != NULL) { result = result->Clone(); } return result; }
RtpPacket *RtpSource::GetRtpPacket(int index) { RtpPacket *result = this->GetInternalRtpPacket(index); if (result != NULL) { result = result->Clone(); } 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; }
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; }
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; }
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; }
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; }
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; } }
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; }