diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 7f7070c7f..b0b015128 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -187,38 +187,6 @@ bool SrsRtpRingBuffer::overflow() return high_ - low_ >= capacity_; } -uint16_t SrsRtpRingBuffer::next_start_of_frame() -{ - if (low_ == high_) { - return low_; - } - - for (uint16_t s = low_ + 1 ; s != high_; ++s) { - SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->video_is_first_packet) { - return s; - } - } - - return low_; -} - -uint16_t SrsRtpRingBuffer::next_keyframe() -{ - if (low_ == high_) { - return low_; - } - - for (uint16_t s = low_ + 1 ; s != high_; ++s) { - SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { - return s; - } - } - - return low_; -} - uint32_t SrsRtpRingBuffer::get_extended_highest_sequence() { return nn_seq_flip_backs * 65536 + high_; @@ -333,34 +301,6 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt return err; } -void SrsRtpQueue::notify_drop_seq(uint16_t seq) -{ - uint16_t next = queue_->next_start_of_frame(); - - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is timeout, move to the next start of frame. - srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); - queue_->advance_to(next + 1); -} - -void SrsRtpQueue::notify_nack_list_full() -{ - uint16_t next = queue_->next_keyframe(); - - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is overflow, move to the next keyframe. - srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); - queue_->advance_to(next + 1); -} - uint32_t SrsRtpQueue::get_extended_highest_sequence() { return queue_->get_extended_highest_sequence(); @@ -408,6 +348,18 @@ SrsRtpAudioQueue::~SrsRtpAudioQueue() { } +void SrsRtpAudioQueue::notify_drop_seq(uint16_t seq) +{ + // TODO: FIXME: The seq may be greater than high. + queue_->advance_to(seq + 1); +} + +void SrsRtpAudioQueue::notify_nack_list_full() +{ + // TODO: FIXME: Maybe we should not drop all packets. + queue_->advance_to(queue_->high()); +} + void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vector& frames) { // When done, s point to the next available packet. @@ -450,6 +402,34 @@ SrsRtpVideoQueue::~SrsRtpVideoQueue() { } +void SrsRtpVideoQueue::notify_drop_seq(uint16_t seq) +{ + uint16_t next = next_start_of_frame(); + + // Note that low_ mean not found, clear queue util one packet. + if (next == queue_->low()) { + next = queue_->high() - 1; + } + + // When NACK is timeout, move to the next start of frame. + srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + +void SrsRtpVideoQueue::notify_nack_list_full() +{ + uint16_t next = next_keyframe(); + + // Note that low_ mean not found, clear queue util one packet. + if (next == queue_->low()) { + next = queue_->high() - 1; + } + + // When NACK is overflow, move to the next keyframe. + srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) { srs_error_t err = srs_success; @@ -520,7 +500,7 @@ void SrsRtpVideoQueue::request_keyframe() void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) { - uint16_t next = queue_->next_start_of_frame(); + uint16_t next = next_start_of_frame(); // Note that low_ mean not found, clear queue util one packet. if (next == queue_->low()) { @@ -647,3 +627,35 @@ void SrsRtpVideoQueue::covert_packet(std::vector& frame, SrsRtpP *ppkt = pkt; } +uint16_t SrsRtpVideoQueue::next_start_of_frame() +{ + if (queue_->low() == queue_->high()) { + return queue_->low(); + } + + for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + SrsRtpPacket2* pkt = queue_->at(s); + if (pkt && pkt->video_is_first_packet) { + return s; + } + } + + return queue_->low(); +} + +uint16_t SrsRtpVideoQueue::next_keyframe() +{ + if (queue_->low() == queue_->high()) { + return queue_->low(); + } + + for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + SrsRtpPacket2* pkt = queue_->at(s); + if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { + return s; + } + } + + return queue_->low(); +} + diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index d5674f429..7ef0485e1 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -143,13 +143,6 @@ public: void reset(uint16_t low, uint16_t high); // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); - // For video, get the next start packet of frame. - // @remark If not found, return the low_, which should never be the "next" one, - // because it MAY or NOT current start packet of frame but never be the next. - uint16_t next_start_of_frame(); - // For video, get the next seq of keyframe. - // @remark Return low_ if not found. - uint16_t next_keyframe(); // The highest sequence number, calculate the flip back base. uint32_t get_extended_highest_sequence(); // Update the sequence, got the nack range by [low, high]. @@ -176,8 +169,8 @@ public: virtual ~SrsRtpQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); - void notify_drop_seq(uint16_t seq); - void notify_nack_list_full(); + virtual void notify_drop_seq(uint16_t seq) = 0; + virtual void notify_nack_list_full() = 0; public: uint32_t get_extended_highest_sequence(); uint8_t get_fraction_lost(); @@ -193,6 +186,8 @@ public: SrsRtpAudioQueue(int capacity); virtual ~SrsRtpAudioQueue(); public: + virtual void notify_drop_seq(uint16_t seq); + virtual void notify_nack_list_full(); virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frames); }; @@ -204,6 +199,8 @@ public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: + virtual void notify_drop_seq(uint16_t seq); + virtual void notify_nack_list_full(); virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frame); bool should_request_key_frame(); @@ -212,6 +209,13 @@ private: virtual void on_overflow(SrsRtpNackForReceiver* nack); virtual void collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt); virtual void covert_packet(std::vector& frame, SrsRtpPacket2** ppkt); + // For video, get the next start packet of frame. + // @remark If not found, return the low_, which should never be the "next" one, + // because it MAY or NOT current start packet of frame but never be the next. + uint16_t next_start_of_frame(); + // For video, get the next seq of keyframe. + // @remark Return low_ if not found. + uint16_t next_keyframe(); }; #endif