void OnExpire(event e, int members, int senders, double rtcp_bw, int we_sent, double *avg_rtcp_size, int *initial, time_tp tc, time_tp *tp, int *pmembers) { /* This function is responsible for deciding whether to send * an RTCP report or BYE packet now, or to reschedule transmission. * It is also responsible for updating the pmembers, initial, tp, * and avg_rtcp_size state variables. This function should be called * upon expiration of the event timer used by Schedule(). */ double t; /* Interval */ double tn; /* Next transmit time */ /* In the case of a BYE, we use "unconditional reconsideration" to * reschedule the transmission of the BYE if necessary */ if (TypeOfEvent(e) == EVENT_BYE) { t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); tn = *tp + t; if (tn <= tc) { SendBYEPacket(e); exit(1); } else { Schedule(tn, e); } } else if (TypeOfEvent(e) == EVENT_REPORT) { t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); tn = *tp + t; if (tn <= tc) { SendRTCPReport(e); *avg_rtcp_size = (1./16.)*SentPacketSize(e) + (15./16.)*(*avg_rtcp_size); *tp = tc; /* We must redraw the interval. Don't reuse the one computed above, since its not actually distributed the same, as we are conditioned on it being small enough to cause a packet to be sent */ t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); Schedule(t+tc,e); *initial = 0; } else { Schedule(tn, e); } *pmembers = members; } }
void IPTVStreamHandlerWriteHelper::timerEvent(QTimerEvent* event) { if (event->timerId() == m_timer_rtcp) { SendRTCPReport(); return; } if (!m_parent->m_buffer->HasAvailablePacket()) return; while (!m_parent->m_use_rtp_streaming) { UDPPacket packet(m_parent->m_buffer->PopDataPacket()); if (packet.GetDataReference().isEmpty()) break; int remainder = 0; { QMutexLocker locker(&m_parent->_listener_lock); QByteArray &data = packet.GetDataReference(); IPTVStreamHandler::StreamDataList::const_iterator sit; sit = m_parent->_stream_data_list.begin(); for (; sit != m_parent->_stream_data_list.end(); ++sit) { remainder = sit.key()->ProcessData( reinterpret_cast<const unsigned char*>(data.data()), data.size()); } } if (remainder != 0) { LOG(VB_RECORD, LOG_INFO, LOC_WH + QString("data_length = %1 remainder = %2") .arg(packet.GetDataReference().size()).arg(remainder)); } m_parent->m_buffer->FreePacket(packet); } while (m_parent->m_use_rtp_streaming) { RTPDataPacket packet(m_parent->m_buffer->PopDataPacket()); if (!packet.IsValid()) break; if (packet.GetPayloadType() == RTPDataPacket::kPayLoadTypeTS) { RTPTSDataPacket ts_packet(packet); if (!ts_packet.IsValid()) { m_parent->m_buffer->FreePacket(packet); continue; } uint exp_seq_num = m_last_sequence_number + 1; uint seq_num = ts_packet.GetSequenceNumber(); if (m_last_sequence_number && ((exp_seq_num&0xFFFF) != (seq_num&0xFFFF))) { LOG(VB_RECORD, LOG_INFO, LOC_WH + QString("Sequence number mismatch %1!=%2") .arg(seq_num).arg(exp_seq_num)); if (seq_num > exp_seq_num) { m_lost_interval = seq_num - exp_seq_num; m_lost += m_lost_interval; } } m_last_sequence_number = seq_num; m_last_timestamp = ts_packet.GetTimeStamp(); LOG(VB_RECORD, LOG_DEBUG, QString("Processing RTP packet(seq:%1 ts:%2)") .arg(m_last_sequence_number).arg(m_last_timestamp)); m_parent->_listener_lock.lock(); int remainder = 0; IPTVStreamHandler::StreamDataList::const_iterator sit; sit = m_parent->_stream_data_list.begin(); for (; sit != m_parent->_stream_data_list.end(); ++sit) { remainder = sit.key()->ProcessData( ts_packet.GetTSData(), ts_packet.GetTSDataSize()); } m_parent->_listener_lock.unlock(); if (remainder != 0) { LOG(VB_RECORD, LOG_INFO, LOC_WH + QString("data_length = %1 remainder = %2") .arg(ts_packet.GetTSDataSize()).arg(remainder)); } } m_parent->m_buffer->FreePacket(packet); } }