diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 981a034b0..34dad0f46 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1924,10 +1924,6 @@ void SrsRtcPublisher::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* bu srs_error_t SrsRtcPublisher::on_audio(SrsRtpPacket2* pkt) { - pkt->is_first_packet_of_frame = true; - pkt->is_last_packet_of_frame = true; - pkt->is_key_frame = true; - // TODO: FIXME: Error check. audio_queue_->consume(audio_nack_, pkt); @@ -2005,17 +2001,17 @@ srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A payload"); } - pkt->is_first_packet_of_frame = payload->start; - pkt->is_last_packet_of_frame = payload->end; - pkt->is_key_frame = (payload->nalu_type == SrsAvcNaluTypeIDR); + pkt->video_is_first_packet = payload->start; + pkt->video_is_last_packet = payload->end; + pkt->video_is_idr = (payload->nalu_type == SrsAvcNaluTypeIDR); } else { - pkt->is_first_packet_of_frame = true; - pkt->is_last_packet_of_frame = true; + pkt->video_is_first_packet = true; + pkt->video_is_last_packet = true; if (v == kStapA) { - pkt->is_key_frame = true; + pkt->video_is_idr = true; } else { - pkt->is_key_frame = (pkt->nalu_type == SrsAvcNaluTypeIDR); + pkt->video_is_idr = (pkt->nalu_type == SrsAvcNaluTypeIDR); } } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 290d405c8..3f4018644 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -53,8 +53,8 @@ class SrsSource; class SrsRtpPacket2; class ISrsUdpSender; class SrsRtpQueue; -class SrsRtpH264Demuxer; -class SrsRtpOpusDemuxer; +class SrsRtpAudioQueue; +class SrsRtpVideoQueue; class SrsRtpPacket2; class ISrsCodec; class SrsRtpNackForReceiver; @@ -261,9 +261,9 @@ private: uint32_t video_ssrc; uint32_t audio_ssrc; private: - SrsRtpQueue* video_queue_; + SrsRtpVideoQueue* video_queue_; SrsRtpNackForReceiver* video_nack_; - SrsRtpQueue* audio_queue_; + SrsRtpAudioQueue* audio_queue_; SrsRtpNackForReceiver* audio_nack_; private: SrsRequest* req; diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 5adef6e95..b685cebce 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -200,7 +200,7 @@ uint16_t SrsRtpRingBuffer::next_start_of_frame() for (uint16_t s = low_ + 1 ; s != high_; ++s) { SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->is_first_packet_of_frame) { + if (pkt && pkt->video_is_first_packet) { return s; } } @@ -216,7 +216,7 @@ uint16_t SrsRtpRingBuffer::next_keyframe() for (uint16_t s = low_ + 1 ; s != high_; ++s) { SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->is_key_frame && pkt->is_first_packet_of_frame) { + if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { return s; } } @@ -283,7 +283,6 @@ SrsRtpQueue::SrsRtpQueue(const char* tag, int capacity) num_of_packet_received_ = 0; number_of_packet_lossed_ = 0; - request_key_frame_ = false; tag_ = tag; } @@ -337,23 +336,7 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt // When packets overflow, collect frame and move head to next frame start. if (queue_->overflow()) { - collect_packet(nack); - - 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; - } - srs_trace("%s seq out of range [%u, %u]", tag_, queue_->low(), next); - - for (uint16_t s = queue_->low(); s != next; ++s) { - nack->remove(s); - queue_->remove(s); - } - - srs_trace("%s force update seq %u to %u", tag_, queue_->low(), next + 1); - queue_->advance_to(next + 1); + on_overflow(nack); } // Save packet at the position seq. @@ -367,16 +350,6 @@ void SrsRtpQueue::collect_frames(std::vector >& fram frames.swap(frames_); } -bool SrsRtpQueue::should_request_key_frame() -{ - if (request_key_frame_) { - request_key_frame_ = false; - return true; - } - - return request_key_frame_; -} - void SrsRtpQueue::notify_drop_seq(uint16_t seq) { uint16_t next = queue_->next_start_of_frame(); @@ -405,11 +378,6 @@ void SrsRtpQueue::notify_nack_list_full() queue_->advance_to(next + 1); } -void SrsRtpQueue::request_keyframe() -{ - request_key_frame_ = true; -} - uint32_t SrsRtpQueue::get_extended_highest_sequence() { return queue_->get_extended_highest_sequence(); @@ -471,6 +439,12 @@ srs_error_t SrsRtpAudioQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2 return err; } +void SrsRtpAudioQueue::on_overflow(SrsRtpNackForReceiver* nack) +{ + collect_packet(nack); + queue_->advance_to(queue_->high()); +} + void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) { // When done, s point to the next available packet. @@ -505,6 +479,7 @@ void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) SrsRtpVideoQueue::SrsRtpVideoQueue(int capacity) : SrsRtpQueue("video", capacity) { + request_key_frame_ = false; } SrsRtpVideoQueue::~SrsRtpVideoQueue() @@ -530,6 +505,42 @@ srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2 return err; } +bool SrsRtpVideoQueue::should_request_key_frame() +{ + if (request_key_frame_) { + request_key_frame_ = false; + return true; + } + + return request_key_frame_; +} + +void SrsRtpVideoQueue::request_keyframe() +{ + request_key_frame_ = true; +} + +void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) +{ + collect_packet(nack); + + 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; + } + srs_trace("%s seq out of range [%u, %u]", tag_, queue_->low(), next); + + for (uint16_t s = queue_->low(); s != next; ++s) { + nack->remove(s); + queue_->remove(s); + } + + srs_trace("%s force update seq %u to %u", tag_, queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack) { while (queue_->low() != queue_->high()) { @@ -563,7 +574,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorlow() && !pkt->is_first_packet_of_frame) { + if (next == queue_->low() && !pkt->video_is_first_packet) { break; } @@ -572,7 +583,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorrtp_header.get_marker() || pkt->is_last_packet_of_frame) { + if (pkt->rtp_header.get_marker() || pkt->video_is_last_packet) { found = true; next++; break; diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index cb14a3d19..07472d6de 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -144,11 +144,11 @@ public: // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); bool is_heavy(); - // Get the next start packet of frame. + // 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(); - // Get the next seq of keyframe. + // 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. @@ -174,8 +174,6 @@ protected: uint64_t nn_collected_frames; std::vector > frames_; const char* tag_; -private: - bool request_key_frame_; public: SrsRtpQueue(const char* tag, int capacity); virtual ~SrsRtpQueue(); @@ -183,10 +181,8 @@ public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); // TODO: FIXME: Should merge FU-A to RAW, then we can return RAW payloads. void collect_frames(std::vector >& frames); - bool should_request_key_frame(); void notify_drop_seq(uint16_t seq); void notify_nack_list_full(); - void request_keyframe(); public: uint32_t get_extended_highest_sequence(); uint8_t get_fraction_lost(); @@ -195,7 +191,7 @@ public: private: void insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t seq_start, uint16_t seq_end); protected: - virtual void collect_packet(SrsRtpNackForReceiver* nack) = 0; + virtual void on_overflow(SrsRtpNackForReceiver* nack) = 0; }; class SrsRtpAudioQueue : public SrsRtpQueue @@ -205,20 +201,27 @@ public: virtual ~SrsRtpAudioQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); +private: + virtual void on_overflow(SrsRtpNackForReceiver* nack); protected: virtual void collect_packet(SrsRtpNackForReceiver* nack); }; class SrsRtpVideoQueue : public SrsRtpQueue { +private: + bool request_key_frame_; public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); + bool should_request_key_frame(); + void request_keyframe(); protected: - virtual void collect_packet(SrsRtpNackForReceiver* nack); + virtual void on_overflow(SrsRtpNackForReceiver* nack); private: + virtual void collect_packet(SrsRtpNackForReceiver* nack); virtual void do_collect_packet(SrsRtpNackForReceiver* nack, std::vector& frame); }; diff --git a/trunk/src/kernel/srs_kernel_rtp.cpp b/trunk/src/kernel/srs_kernel_rtp.cpp index c21c9157b..a27b2cdd4 100644 --- a/trunk/src/kernel/srs_kernel_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtp.cpp @@ -277,9 +277,9 @@ SrsRtpPacket2::SrsRtpPacket2() payload = NULL; decode_handler = NULL; - is_first_packet_of_frame = false; - is_last_packet_of_frame = false; - is_key_frame = false; + video_is_first_packet = false; + video_is_last_packet = false; + video_is_idr = false; nalu_type = SrsAvcNaluTypeReserved; cache_raw = new SrsRtpRawPayload(); diff --git a/trunk/src/kernel/srs_kernel_rtp.hpp b/trunk/src/kernel/srs_kernel_rtp.hpp index fd38a4d12..baaeb0281 100644 --- a/trunk/src/kernel/srs_kernel_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtp.hpp @@ -114,10 +114,10 @@ public: int padding; // Decoder helper. public: - // Helper information for decoder. - bool is_first_packet_of_frame; - bool is_last_packet_of_frame; - bool is_key_frame; + // Helper information for video decoder only. + bool video_is_first_packet; + bool video_is_last_packet; + bool video_is_idr; // The first byte as nalu type, for video decoder only. SrsAvcNaluType nalu_type; // The original payload bytes length.