diff options
author | pwestin@google.com <pwestin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 16:40:01 +0000 |
---|---|---|
committer | pwestin@google.com <pwestin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 16:40:01 +0000 |
commit | 51de68e9c63baa59293b2ab7525488755fca5386 (patch) | |
tree | 1e3077a29da31f1bb06926afd54ec94b00a9d824 | |
parent | 1c219d4058d435d367120e3c2ea316b4d8f5c69c (diff) | |
download | chromium_src-51de68e9c63baa59293b2ab7525488755fca5386.zip chromium_src-51de68e9c63baa59293b2ab7525488755fca5386.tar.gz chromium_src-51de68e9c63baa59293b2ab7525488755fca5386.tar.bz2 |
Cast: Change internal frame_id from 8 bits to 32 bits.
Needed since we will use the frame_id as a key to the crypto.
It will remain 8 bits over the wire.
Review URL: https://codereview.chromium.org/65013004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235349 0039d316-1c4b-4281-b951-d872f2087c98
53 files changed, 520 insertions, 275 deletions
diff --git a/media/cast/audio_sender/audio_encoder.cc b/media/cast/audio_sender/audio_encoder.cc index 7264da8..2e7559c 100644 --- a/media/cast/audio_sender/audio_encoder.cc +++ b/media/cast/audio_sender/audio_encoder.cc @@ -108,8 +108,8 @@ class AudioEncoder::ImplBase { // call. int buffer_fill_end_; - // A rotating counter used to label EncodedAudioFrames. - uint8 frame_id_; + // A counter used to label EncodedAudioFrames. + uint32 frame_id_; private: DISALLOW_COPY_AND_ASSIGN(ImplBase); diff --git a/media/cast/cast_config.h b/media/cast/cast_config.h index 4a723b9..84a6af2 100644 --- a/media/cast/cast_config.h +++ b/media/cast/cast_config.h @@ -152,8 +152,8 @@ struct EncodedVideoFrame { VideoCodec codec; bool key_frame; - uint8 frame_id; - uint8 last_referenced_frame_id; + uint32 frame_id; + uint32 last_referenced_frame_id; std::vector<uint8> data; }; @@ -173,7 +173,7 @@ struct EncodedAudioFrame { ~EncodedAudioFrame(); AudioCodec codec; - uint8 frame_id; // Needed to release the frame. Not used send side. + uint32 frame_id; // Needed to release the frame. int samples; // Needed send side to advance the RTP timestamp. // Not used receive side. std::vector<uint8> data; @@ -225,7 +225,7 @@ class VideoEncoderController { virtual void GenerateKeyFrame() = 0; // Inform the encoder to only reference frames older or equal to frame_id; - virtual void LatestFrameIdToReference(uint8 frame_id) = 0; + virtual void LatestFrameIdToReference(uint32 frame_id) = 0; // Query the codec about how many frames it has skipped due to slow ACK. virtual int NumberOfSkippedFrames() const = 0; diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h index defa1db..69ba4cc 100644 --- a/media/cast/cast_defines.h +++ b/media/cast/cast_defines.h @@ -18,7 +18,7 @@ namespace cast { const int64 kDontShowTimeoutMs = 33; const float kDefaultCongestionControlBackOff = 0.875f; -const uint8 kStartFrameId = 255; +const uint32 kStartFrameId = GG_UINT32_C(0xffffffff); const uint32 kVideoFrequency = 90000; const int64 kSkippedFramesCheckPeriodkMs = 10000; @@ -65,12 +65,12 @@ static const int64 kUnixEpochInNtpSeconds = GG_INT64_C(2208988800); // fractional NTP seconds. static const double kMagicFractionalUnit = 4.294967296E3; -inline bool IsNewerFrameId(uint8 frame_id, uint8 prev_frame_id) { +inline bool IsNewerFrameId(uint32 frame_id, uint32 prev_frame_id) { return (frame_id != prev_frame_id) && - static_cast<uint8>(frame_id - prev_frame_id) < 0x80; + static_cast<uint32>(frame_id - prev_frame_id) < 0x80000000; } -inline bool IsOlderFrameId(uint8 frame_id, uint8 prev_frame_id) { +inline bool IsOlderFrameId(uint32 frame_id, uint32 prev_frame_id) { return (frame_id == prev_frame_id) || IsNewerFrameId(prev_frame_id, frame_id); } @@ -132,6 +132,41 @@ inline base::TimeTicks ConvertNtpToTimeTicks(uint32 ntp_seconds, return base::TimeTicks::UnixEpoch() + elapsed_since_unix_epoch; } +class FrameIdWrapHelper { + public: + FrameIdWrapHelper() + : first_(true), + can_we_wrap_(false), + frame_id_wrap_count_(0) {} + + uint32 MapTo32bitsFrameId(const uint8 over_the_wire_frame_id) { + if (first_) { + first_ = false; + if (over_the_wire_frame_id == 0xff) { + // Special case for startup. + return kStartFrameId; + } + } + if (can_we_wrap_) { + if (over_the_wire_frame_id < 0x0f) { + // Disable wrap check until we are closer to the max of uint8. + can_we_wrap_ = false; + } + } else { + if (over_the_wire_frame_id > 0xf0) { + // Enable wrap check until we have wrapped. + can_we_wrap_ = true; + } + } + return (frame_id_wrap_count_ << 8) + over_the_wire_frame_id; + } + + private: + bool first_; + bool can_we_wrap_; + uint32 frame_id_wrap_count_; +}; + } // namespace cast } // namespace media diff --git a/media/cast/framer/cast_message_builder.cc b/media/cast/framer/cast_message_builder.cc index f65e355..7d89f74 100644 --- a/media/cast/framer/cast_message_builder.cc +++ b/media/cast/framer/cast_message_builder.cc @@ -32,7 +32,7 @@ CastMessageBuilder::CastMessageBuilder( CastMessageBuilder::~CastMessageBuilder() {} -void CastMessageBuilder::CompleteFrameReceived(uint8 frame_id, +void CastMessageBuilder::CompleteFrameReceived(uint32 frame_id, bool is_key_frame) { if (last_update_time_.is_null()) { // Our first update. @@ -83,7 +83,7 @@ bool CastMessageBuilder::UpdateAckMessage() { // time; and it's not needed since we can skip frames to catch up. } } else { - uint8 frame_id = frame_id_map_->LastContinuousFrame(); + uint32 frame_id = frame_id_map_->LastContinuousFrame(); // Is it a new frame? if (last_acked_frame_id_ == frame_id) return false; @@ -153,9 +153,8 @@ void CastMessageBuilder::BuildPacketList() { // Are we missing packets? if (frame_id_map_->Empty()) return; - uint8 newest_frame_id = frame_id_map_->NewestFrameId(); - uint8 next_expected_frame_id = - static_cast<uint8>(cast_msg_.ack_frame_id_ + 1); + uint32 newest_frame_id = frame_id_map_->NewestFrameId(); + uint32 next_expected_frame_id = cast_msg_.ack_frame_id_ + 1; // Iterate over all frames. for (; !IsNewerFrameId(next_expected_frame_id, newest_frame_id); diff --git a/media/cast/framer/cast_message_builder.h b/media/cast/framer/cast_message_builder.h index 9bbbf63..92fd742 100644 --- a/media/cast/framer/cast_message_builder.h +++ b/media/cast/framer/cast_message_builder.h @@ -18,7 +18,7 @@ namespace cast { class RtpPayloadFeedback; -typedef std::map<uint8, base::TimeTicks> TimeLastNackMap; +typedef std::map<uint32, base::TimeTicks> TimeLastNackMap; class CastMessageBuilder { public: @@ -30,7 +30,7 @@ class CastMessageBuilder { int max_unacked_frames); ~CastMessageBuilder(); - void CompleteFrameReceived(uint8 frame_id, bool is_key_frame); + void CompleteFrameReceived(uint32 frame_id, bool is_key_frame); bool TimeToSendNextCastMessage(base::TimeTicks* time_to_send); void UpdateCastMessage(); void Reset(); @@ -57,7 +57,7 @@ class CastMessageBuilder { bool slowing_down_ack_; bool acked_last_frame_; - uint8 last_acked_frame_id_; + uint32 last_acked_frame_id_; DISALLOW_COPY_AND_ASSIGN(CastMessageBuilder); }; diff --git a/media/cast/framer/cast_message_builder_unittest.cc b/media/cast/framer/cast_message_builder_unittest.cc index 99c07eb..db5c2b2 100644 --- a/media/cast/framer/cast_message_builder_unittest.cc +++ b/media/cast/framer/cast_message_builder_unittest.cc @@ -18,7 +18,7 @@ static const uint32 kLongTimeIncrementMs = 40; static const int64 kStartMillisecond = GG_INT64_C(12345678900000); namespace { -typedef std::map<uint8, size_t> MissingPacketsMap; +typedef std::map<uint32, size_t> MissingPacketsMap; class NackFeedbackVerification : public RtpPayloadFeedback { public: @@ -53,7 +53,7 @@ class NackFeedbackVerification : public RtpPayloadFeedback { triggered_ = true; } - size_t num_missing_packets(uint8 frame_id) { + size_t num_missing_packets(uint32 frame_id) { MissingPacketsMap::iterator it; it = missing_packets_.find(frame_id); if (it == missing_packets_.end()) return 0; @@ -68,12 +68,12 @@ class NackFeedbackVerification : public RtpPayloadFeedback { return ret_val; } - uint8 last_frame_acked() { return last_frame_acked_; } + uint32 last_frame_acked() { return last_frame_acked_; } private: bool triggered_; MissingPacketsMap missing_packets_; // Missing packets per frame. - uint8 last_frame_acked_; + uint32 last_frame_acked_; }; } // namespace @@ -94,7 +94,7 @@ class CastMessageBuilderTest : public ::testing::Test { virtual ~CastMessageBuilderTest() {} - void SetFrameId(uint8 frame_id) { + void SetFrameId(uint32 frame_id) { rtp_header_.frame_id = frame_id; } @@ -110,7 +110,7 @@ class CastMessageBuilderTest : public ::testing::Test { rtp_header_.is_key_frame = is_key; } - void SetReferenceFrameId(uint8 reference_frame_id) { + void SetReferenceFrameId(uint32 reference_frame_id) { rtp_header_.is_reference = true; rtp_header_.reference_frame_id = reference_frame_id; } @@ -158,7 +158,7 @@ TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) { base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); cast_msg_builder_->UpdateCastMessage(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(5, feedback_.last_frame_acked()); + EXPECT_EQ(5u, feedback_.last_frame_acked()); } TEST_F(CastMessageBuilderTest, OneFrameNackList) { @@ -205,7 +205,7 @@ TEST_F(CastMessageBuilderTest, FastForwardAck) { SetMaxPacketId(0); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(255, feedback_.last_frame_acked()); + EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked()); testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); SetFrameId(0); @@ -214,7 +214,7 @@ TEST_F(CastMessageBuilderTest, FastForwardAck) { SetKeyFrame(true); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(2, feedback_.last_frame_acked()); + EXPECT_EQ(2u, feedback_.last_frame_acked()); } TEST_F(CastMessageBuilderTest, RemoveOldFrames) { @@ -237,7 +237,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) { SetMaxPacketId(5); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(255, feedback_.last_frame_acked()); + EXPECT_EQ(kStartFrameId, feedback_.last_frame_acked()); testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); SetFrameId(5); @@ -250,7 +250,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) { frame_id_map_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering. cast_msg_builder_->UpdateCastMessage(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(5, feedback_.last_frame_acked()); + EXPECT_EQ(5u, feedback_.last_frame_acked()); testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); SetFrameId(1); @@ -262,7 +262,7 @@ TEST_F(CastMessageBuilderTest, RemoveOldFrames) { base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(5, feedback_.last_frame_acked()); + EXPECT_EQ(5u, feedback_.last_frame_acked()); } TEST_F(CastMessageBuilderTest, WrapFastForward) { @@ -280,16 +280,16 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) { SetKeyFrame(false); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(253, feedback_.last_frame_acked()); + EXPECT_EQ(253u, feedback_.last_frame_acked()); testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); - SetFrameId(0); + SetFrameId(256); SetPacketId(0); SetMaxPacketId(0); SetKeyFrame(false); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(253, feedback_.last_frame_acked()); + EXPECT_EQ(253u, feedback_.last_frame_acked()); testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs)); SetFrameId(254); @@ -298,7 +298,7 @@ TEST_F(CastMessageBuilderTest, WrapFastForward) { SetKeyFrame(true); InsertPacket(); EXPECT_TRUE(feedback_.triggered()); - EXPECT_EQ(0, feedback_.last_frame_acked()); + EXPECT_EQ(256u, feedback_.last_frame_acked()); } TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) { @@ -472,7 +472,7 @@ TEST_F(CastMessageBuilderTest, SlowDownAck) { SetKeyFrame(true); InsertPacket(); - int frame_id; + uint32 frame_id; testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); SetKeyFrame(false); @@ -485,7 +485,7 @@ TEST_F(CastMessageBuilderTest, SlowDownAck) { base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs)); } // We should now have entered the slowdown ACK state. - uint8_t expected_frame_id = 1; + uint32 expected_frame_id = 1; for (; frame_id < 10; ++frame_id) { if (frame_id % 2) ++expected_frame_id; EXPECT_TRUE(feedback_.triggered()); diff --git a/media/cast/framer/frame_buffer.cc b/media/cast/framer/frame_buffer.cc index 6fcdcf4..fc38c72 100644 --- a/media/cast/framer/frame_buffer.cc +++ b/media/cast/framer/frame_buffer.cc @@ -29,7 +29,7 @@ void FrameBuffer::InsertPacket(const uint8* payload_data, if (rtp_header.is_reference) { last_referenced_frame_id_ = rtp_header.reference_frame_id; } else { - last_referenced_frame_id_ = static_cast<uint8>(rtp_header.frame_id - 1); + last_referenced_frame_id_ = rtp_header.frame_id - 1; } rtp_timestamp_ = rtp_header.webrtc.header.timestamp; diff --git a/media/cast/framer/frame_buffer.h b/media/cast/framer/frame_buffer.h index 591ff2f..0d839aa 100644 --- a/media/cast/framer/frame_buffer.h +++ b/media/cast/framer/frame_buffer.h @@ -32,16 +32,15 @@ class FrameBuffer { uint32* rtp_timestamp) const; bool is_key_frame() const { return is_key_frame_; } - uint8 frame_id() const { return frame_id_; } - uint8 last_referenced_frame_id() const { return last_referenced_frame_id_; } + uint32 last_referenced_frame_id() const { return last_referenced_frame_id_; } private: - uint8 frame_id_; + uint32 frame_id_; uint16 max_packet_id_; uint16 num_packets_received_; bool is_key_frame_; size_t total_data_size_; - uint8 last_referenced_frame_id_; + uint32 last_referenced_frame_id_; uint32 rtp_timestamp_; PacketMap packets_; diff --git a/media/cast/framer/frame_id_map.cc b/media/cast/framer/frame_id_map.cc index 88560ed3..0434b19 100644 --- a/media/cast/framer/frame_id_map.cc +++ b/media/cast/framer/frame_id_map.cc @@ -10,8 +10,8 @@ namespace media { namespace cast { -FrameInfo::FrameInfo(uint8 frame_id, - uint8 referenced_frame_id, +FrameInfo::FrameInfo(uint32 frame_id, + uint32 referenced_frame_id, uint16 max_packet_id, bool key_frame) : is_key_frame_(key_frame), @@ -63,20 +63,20 @@ FrameIdMap::FrameIdMap() FrameIdMap::~FrameIdMap() {} bool FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header, bool* complete) { - uint8 frame_id = rtp_header.frame_id; - uint8 reference_frame_id; + uint32 frame_id = rtp_header.frame_id; + uint32 reference_frame_id; if (rtp_header.is_reference) { reference_frame_id = rtp_header.reference_frame_id; } else { - reference_frame_id = static_cast<uint8>(frame_id - 1); + reference_frame_id = static_cast<uint32>(frame_id - 1); } if (rtp_header.is_key_frame && waiting_for_key_) { - last_released_frame_ = static_cast<uint8>(frame_id - 1); + last_released_frame_ = static_cast<uint32>(frame_id - 1); waiting_for_key_ = false; } - VLOG(1) << "InsertPacket frame:" << static_cast<int>(frame_id) + VLOG(1) << "InsertPacket frame:" << frame_id << " packet:" << static_cast<int>(rtp_header.packet_id) << " max packet:" << static_cast<int>(rtp_header.max_packet_id); @@ -108,7 +108,7 @@ bool FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header, bool* complete) { return true; } -void FrameIdMap::RemoveOldFrames(uint8 frame_id) { +void FrameIdMap::RemoveOldFrames(uint32 frame_id) { FrameMap::iterator it = frame_map_.begin(); while (it != frame_map_.end()) { @@ -129,11 +129,11 @@ void FrameIdMap::Clear() { newest_frame_id_ = kStartFrameId; } -uint8 FrameIdMap::NewestFrameId() const { +uint32 FrameIdMap::NewestFrameId() const { return newest_frame_id_; } -bool FrameIdMap::NextContinuousFrame(uint8* frame_id) const { +bool FrameIdMap::NextContinuousFrame(uint32* frame_id) const { FrameMap::const_iterator it; for (it = frame_map_.begin(); it != frame_map_.end(); ++it) { @@ -145,9 +145,9 @@ bool FrameIdMap::NextContinuousFrame(uint8* frame_id) const { return false; } -uint8 FrameIdMap::LastContinuousFrame() const { - uint8 last_continuous_frame_id = last_released_frame_; - uint8 next_expected_frame = last_released_frame_; +uint32 FrameIdMap::LastContinuousFrame() const { + uint32 last_continuous_frame_id = last_released_frame_; + uint32 next_expected_frame = last_released_frame_; FrameMap::const_iterator it; @@ -163,7 +163,7 @@ uint8 FrameIdMap::LastContinuousFrame() const { return last_continuous_frame_id; } -bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint8* frame_id) const { +bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint32* frame_id) const { // First check if we have continuous frames. if (NextContinuousFrame(frame_id)) return true; @@ -191,7 +191,7 @@ bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint8* frame_id) const { return true; } -bool FrameIdMap::NextVideoFrameAllowingSkippingFrames(uint8* frame_id) const { +bool FrameIdMap::NextVideoFrameAllowingSkippingFrames(uint32* frame_id) const { // Find the oldest decodable frame. FrameMap::const_iterator it_best_match = frame_map_.end(); FrameMap::const_iterator it; @@ -221,11 +221,11 @@ int FrameIdMap::NumberOfCompleteFrames() const { return count; } -bool FrameIdMap::FrameExists(uint8 frame_id) const { +bool FrameIdMap::FrameExists(uint32 frame_id) const { return frame_map_.end() != frame_map_.find(frame_id); } -void FrameIdMap::GetMissingPackets(uint8 frame_id, +void FrameIdMap::GetMissingPackets(uint32 frame_id, bool last_frame, PacketIdSet* missing_packets) const { FrameMap::const_iterator it = frame_map_.find(frame_id); @@ -237,7 +237,7 @@ void FrameIdMap::GetMissingPackets(uint8 frame_id, bool FrameIdMap::ContinuousFrame(FrameInfo* frame) const { DCHECK(frame); if (waiting_for_key_ && !frame->is_key_frame()) return false; - return static_cast<uint8>(last_released_frame_ + 1) == frame->frame_id(); + return static_cast<uint32>(last_released_frame_ + 1) == frame->frame_id(); } bool FrameIdMap::DecodableVideoFrame(FrameInfo* frame) const { diff --git a/media/cast/framer/frame_id_map.h b/media/cast/framer/frame_id_map.h index cecaaeb..1d4fb09 100644 --- a/media/cast/framer/frame_id_map.h +++ b/media/cast/framer/frame_id_map.h @@ -19,8 +19,8 @@ namespace cast { class FrameInfo { public: - FrameInfo(uint8 frame_id, - uint8 referenced_frame_id, + FrameInfo(uint32 frame_id, + uint32 referenced_frame_id, uint16 max_packet_id, bool key_frame); ~FrameInfo(); @@ -32,13 +32,13 @@ class FrameInfo { PacketIdSet* missing_packets) const; bool is_key_frame() const { return is_key_frame_; } - uint8 frame_id() const { return frame_id_; } - uint8 referenced_frame_id() const { return referenced_frame_id_; } + uint32 frame_id() const { return frame_id_; } + uint32 referenced_frame_id() const { return referenced_frame_id_; } private: const bool is_key_frame_; - const uint8 frame_id_; - const uint8 referenced_frame_id_; + const uint32 frame_id_; + const uint32 referenced_frame_id_; uint16 max_received_packet_id_; PacketIdSet missing_packets_; @@ -46,7 +46,7 @@ class FrameInfo { DISALLOW_COPY_AND_ASSIGN(FrameInfo); }; -typedef std::map<uint8, linked_ptr<FrameInfo> > FrameMap; +typedef std::map<uint32, linked_ptr<FrameInfo> > FrameMap; class FrameIdMap { public: @@ -57,21 +57,21 @@ class FrameIdMap { bool InsertPacket(const RtpCastHeader& rtp_header, bool* complete); bool Empty() const; - bool FrameExists(uint8 frame_id) const; - uint8 NewestFrameId() const; + bool FrameExists(uint32 frame_id) const; + uint32 NewestFrameId() const; - void RemoveOldFrames(uint8 frame_id); + void RemoveOldFrames(uint32 frame_id); void Clear(); // Identifies the next frame to be released (rendered). - bool NextContinuousFrame(uint8* frame_id) const; - uint8 LastContinuousFrame() const; + bool NextContinuousFrame(uint32* frame_id) const; + uint32 LastContinuousFrame() const; - bool NextAudioFrameAllowingMissingFrames(uint8* frame_id) const; - bool NextVideoFrameAllowingSkippingFrames(uint8* frame_id) const; + bool NextAudioFrameAllowingMissingFrames(uint32* frame_id) const; + bool NextVideoFrameAllowingSkippingFrames(uint32* frame_id) const; int NumberOfCompleteFrames() const; - void GetMissingPackets(uint8 frame_id, + void GetMissingPackets(uint32 frame_id, bool last_frame, PacketIdSet* missing_packets) const; @@ -81,8 +81,8 @@ class FrameIdMap { FrameMap frame_map_; bool waiting_for_key_; - uint8 last_released_frame_; - uint8 newest_frame_id_; + uint32 last_released_frame_; + uint32 newest_frame_id_; DISALLOW_COPY_AND_ASSIGN(FrameIdMap); }; diff --git a/media/cast/framer/framer.cc b/media/cast/framer/framer.cc index fb16e66..b06e60f 100644 --- a/media/cast/framer/framer.cc +++ b/media/cast/framer/framer.cc @@ -56,7 +56,7 @@ bool Framer::InsertPacket(const uint8* payload_data, bool Framer::GetEncodedAudioFrame(EncodedAudioFrame* audio_frame, uint32* rtp_timestamp, bool* next_frame) { - uint8 frame_id; + uint32 frame_id; // Find frame id. if (frame_id_map_.NextContinuousFrame(&frame_id)) { // We have our next frame. @@ -79,7 +79,7 @@ bool Framer::GetEncodedAudioFrame(EncodedAudioFrame* audio_frame, bool Framer::GetEncodedVideoFrame(EncodedVideoFrame* video_frame, uint32* rtp_timestamp, bool* next_frame) { - uint8 frame_id; + uint32 frame_id; // Find frame id. if (frame_id_map_.NextContinuousFrame(&frame_id)) { // We have our next frame. @@ -107,7 +107,7 @@ void Framer::Reset() { cast_msg_builder_->Reset(); } -void Framer::ReleaseFrame(uint8 frame_id) { +void Framer::ReleaseFrame(uint32 frame_id) { frame_id_map_.RemoveOldFrames(frame_id); frames_.erase(frame_id); diff --git a/media/cast/framer/framer.h b/media/cast/framer/framer.h index e208ab1..0b2e004 100644 --- a/media/cast/framer/framer.h +++ b/media/cast/framer/framer.h @@ -21,7 +21,7 @@ namespace media { namespace cast { -typedef std::map<uint8, linked_ptr<FrameBuffer> > FrameList; +typedef std::map<uint32, linked_ptr<FrameBuffer> > FrameList; class Framer { public: @@ -50,7 +50,7 @@ class Framer { uint32* rtp_timestamp, bool* next_frame); - void ReleaseFrame(uint8 frame_id); + void ReleaseFrame(uint32 frame_id); // Reset framer state to original state and flush all pending buffers. void Reset(); diff --git a/media/cast/framer/framer_unittest.cc b/media/cast/framer/framer_unittest.cc index bfeb7de..33897e2 100644 --- a/media/cast/framer/framer_unittest.cc +++ b/media/cast/framer/framer_unittest.cc @@ -43,7 +43,7 @@ class FramerTest : public ::testing::Test { TEST_F(FramerTest, EmptyState) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; EXPECT_FALSE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); @@ -51,7 +51,7 @@ TEST_F(FramerTest, EmptyState) { TEST_F(FramerTest, AlwaysStartWithKey) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // Insert non key first frame. @@ -64,14 +64,14 @@ TEST_F(FramerTest, AlwaysStartWithKey) { EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(1, frame.frame_id); + EXPECT_EQ(1u, frame.frame_id); EXPECT_TRUE(frame.key_frame); framer_.ReleaseFrame(frame.frame_id); } TEST_F(FramerTest, CompleteFrame) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // start with a complete key frame. @@ -80,7 +80,7 @@ TEST_F(FramerTest, CompleteFrame) { EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(0u, frame.frame_id); EXPECT_TRUE(frame.key_frame); framer_.ReleaseFrame(frame.frame_id); @@ -102,7 +102,7 @@ TEST_F(FramerTest, CompleteFrame) { TEST_F(FramerTest, ContinuousSequence) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // start with a complete key frame. @@ -111,7 +111,7 @@ TEST_F(FramerTest, ContinuousSequence) { EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(0u, frame.frame_id); EXPECT_TRUE(frame.key_frame); framer_.ReleaseFrame(frame.frame_id); @@ -126,33 +126,33 @@ TEST_F(FramerTest, ContinuousSequence) { TEST_F(FramerTest, Wrap) { // Insert key frame, frame_id = 255 (will jump to that) EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // Start with a complete key frame. rtp_header_.is_key_frame = true; - rtp_header_.frame_id = 255; + rtp_header_.frame_id = 255u; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(255, frame.frame_id); + EXPECT_EQ(255u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); // Insert wrapped delta frame - should be continuous. rtp_header_.is_key_frame = false; - rtp_header_.frame_id = 0; + rtp_header_.frame_id = 256; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(256u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); } TEST_F(FramerTest, Reset) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // Start with a complete key frame. @@ -165,13 +165,13 @@ TEST_F(FramerTest, Reset) { TEST_F(FramerTest, RequireKeyAfterReset) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; framer_.Reset(); // Start with a complete key frame. rtp_header_.is_key_frame = false; - rtp_header_.frame_id = 0; + rtp_header_.frame_id = 0u; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_FALSE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); @@ -185,7 +185,7 @@ TEST_F(FramerTest, RequireKeyAfterReset) { TEST_F(FramerTest, BasicNonLastReferenceId) { EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; rtp_header_.is_key_frame = true; rtp_header_.frame_id = 0; @@ -198,7 +198,7 @@ TEST_F(FramerTest, BasicNonLastReferenceId) { rtp_header_.is_key_frame = false; rtp_header_.is_reference = true; rtp_header_.reference_frame_id = 0; - rtp_header_.frame_id = 5; + rtp_header_.frame_id = 5u; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, @@ -209,7 +209,7 @@ TEST_F(FramerTest, BasicNonLastReferenceId) { TEST_F(FramerTest, InOrderReferenceFrameSelection) { // Create pattern: 0, 1, 4, 5. EncodedVideoFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; rtp_header_.is_key_frame = true; @@ -230,17 +230,17 @@ TEST_F(FramerTest, InOrderReferenceFrameSelection) { framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(0u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(1, frame.frame_id); + EXPECT_EQ(1u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_FALSE(next_frame); - EXPECT_EQ(4, frame.frame_id); + EXPECT_EQ(4u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); // Insert remaining packet of frame #2 - should no be continuous. rtp_header_.frame_id = 2; @@ -256,13 +256,13 @@ TEST_F(FramerTest, InOrderReferenceFrameSelection) { EXPECT_TRUE(framer_.GetEncodedVideoFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(5, frame.frame_id); + EXPECT_EQ(5u, frame.frame_id); } TEST_F(FramerTest, AudioWrap) { // All audio frames are marked as key frames. EncodedAudioFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; rtp_header_.is_key_frame = true; rtp_header_.frame_id = 254; @@ -271,33 +271,33 @@ TEST_F(FramerTest, AudioWrap) { EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(254, frame.frame_id); + EXPECT_EQ(254u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); rtp_header_.frame_id = 255; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); // Insert wrapped frame - should be continuous. - rtp_header_.frame_id = 0; + rtp_header_.frame_id = 256; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(255, frame.frame_id); + EXPECT_EQ(255u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(256u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); } TEST_F(FramerTest, AudioWrapWithMissingFrame) { // All audio frames are marked as key frames. EncodedAudioFrame frame; - uint32_t rtp_timestamp; + uint32 rtp_timestamp; bool next_frame = false; // Insert and get first packet. @@ -307,25 +307,25 @@ TEST_F(FramerTest, AudioWrapWithMissingFrame) { EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(253, frame.frame_id); + EXPECT_EQ(253u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); // Insert third and fourth packets. rtp_header_.frame_id = 255; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); - rtp_header_.frame_id = 0; + rtp_header_.frame_id = 256; framer_.InsertPacket(payload_.data(), payload_.size(), rtp_header_); // Get third and fourth packets. EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_FALSE(next_frame); - EXPECT_EQ(255, frame.frame_id); + EXPECT_EQ(255u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); EXPECT_TRUE(framer_.GetEncodedAudioFrame(&frame, &rtp_timestamp, &next_frame)); EXPECT_TRUE(next_frame); - EXPECT_EQ(0, frame.frame_id); + EXPECT_EQ(256u, frame.frame_id); framer_.ReleaseFrame(frame.frame_id); } diff --git a/media/cast/logging/logging.cc b/media/cast/logging/logging.cc new file mode 100644 index 0000000..7f2658c --- /dev/null +++ b/media/cast/logging/logging.cc @@ -0,0 +1,113 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/cast/logging/logging.h" + +#include "base/debug/trace_event.h" +#include "base/logging.h" +#include "base/metrics/histogram.h" + +namespace media { +namespace cast { + +Logging::Logging(base::TickClock* clock) + : clock_(clock), + frame_map_(), + packet_map_(), + generic_map_(), + weak_factory_(this) {} + +Logging::~Logging() {} + +void Logging::InsertFrameEvent(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id) { + // Is this a new event? + FrameLogMap::iterator it = frame_map_.find(event); + if (it == frame_map_.end()) { + // Create new entry. + FrameLogData data(clock_); + data.Insert(rtp_timestamp, frame_id); + frame_map_.insert(std::make_pair(event, &data)); + } else { + // Insert to existing entry. + it->second->Insert(rtp_timestamp, frame_id); + } +} + +void Logging::InsertFrameEventWithSize(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + int size) { + // Is this a new event? + FrameLogMap::iterator it = frame_map_.find(event); + if (it == frame_map_.end()) { + // Create new entry. + FrameLogData data(clock_); + data.InsertWithSize(rtp_timestamp, frame_id, size); + frame_map_.insert(std::make_pair(event, &data)); + } else { + // Insert to existing entry. + it->second->InsertWithSize(rtp_timestamp, frame_id, size); + } +} + +void Logging::InsertFrameEventWithDelay(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + base::TimeDelta delay) { + // Is this a new event? + FrameLogMap::iterator it = frame_map_.find(event); + if (it == frame_map_.end()) { + // Create new entry. + FrameLogData data(clock_); + data.InsertWithDelay(rtp_timestamp, frame_id, delay); + frame_map_.insert(std::make_pair(event, &data)); + } else { + // Insert to existing entry. + it->second->InsertWithDelay(rtp_timestamp, frame_id, delay); + } +} + +void Logging::InsertPacketEvent(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + uint16 packet_id, + uint16 max_packet_id, + int size) { + // Is this a new event? + PacketLogMap::iterator it = packet_map_.find(event); + if (it == packet_map_.end()) { + // Create new entry. + PacketLogData data(clock_); + data.Insert(rtp_timestamp, frame_id, packet_id, max_packet_id, size); + packet_map_.insert(std::make_pair(event, &data)); + } else { + // Insert to existing entry. + it->second->Insert(rtp_timestamp, frame_id, packet_id, max_packet_id, size); + } +} + +void Logging::InsertGenericEvent(CastLoggingEvent event, int value) { + // Is this a new event? + GenericLogMap::iterator it = generic_map_.find(event); + if (it == generic_map_.end()) { + // Create new entry. + GenericLogData data(clock_); + data.Insert(value); + generic_map_.insert(std::make_pair(event, &data)); + } else { + // Insert to existing entry. + it->second->Insert(value); + } +} + +void Logging::Reset() { + frame_map_.clear(); + packet_map_.clear(); + generic_map_.clear(); +} +} // namespace cast +} // namespace media + diff --git a/media/cast/logging/logging.h b/media/cast/logging/logging.h new file mode 100644 index 0000000..f327a6f --- /dev/null +++ b/media/cast/logging/logging.h @@ -0,0 +1,92 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CAST_LOGGING_LOGGING_H_ +#define MEDIA_CAST_LOGGING_LOGGING_H_ + +// Generic class that handles event logging for the cast library. +// Logging has three possible forms: +// 1. [default] Raw data accessible by the application. +// 2. [optional] UMA stats. +// 3. [optional] Tracing. + +#include <map> +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/linked_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "base/time/tick_clock.h" +#include "base/time/time.h" +#include "media/cast/logging/logging_defines.h" +#include "media/cast/logging/logging_internal.h" + +namespace media { +namespace cast { + +// Store all log types in a map based on the event. +typedef std::map<CastLoggingEvent, linked_ptr<FrameLogData> > FrameLogMap; +typedef std::map<CastLoggingEvent, linked_ptr<PacketLogData> > PacketLogMap; +typedef std::map<CastLoggingEvent, linked_ptr<GenericLogData> > GenericLogMap; + + +// This class is not thread safe, and should only be called from the main +// thread. +class Logging : public base::NonThreadSafe, + public base::SupportsWeakPtr<Logging> { + public: + // When tracing is enabled - all events will be added to the trace. + explicit Logging(base::TickClock* clock); + ~Logging(); + // Inform of new event: three types of events: frame, packets and generic. + // Frame events can be inserted with different parameters. + void InsertFrameEvent(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id); + // Size - Inserting the size implies that this is an encoded frame. + void InsertFrameEventWithSize(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + int frame_size); + // Render/playout delay + void InsertFrameEventWithDelay(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + base::TimeDelta delay); + + // Insert a packet event. + void InsertPacketEvent(CastLoggingEvent event, + uint32 rtp_timestamp, + uint32 frame_id, + uint16 packet_id, + uint16 max_packet_id, + int size); + + void InsertGenericEvent(CastLoggingEvent event, int value); + + // Get log data. + void GetRawFrameData(FrameLogMap frame_data); + void GetRawPacketData(PacketLogMap packet_data); + void GetRawGenericData(GenericLogMap generic_data); + + // Reset all log data (not flags). + void Reset(); + + private: + base::WeakPtrFactory<Logging> weak_factory_; + base::TickClock* const clock_; // Not owned by this class. + FrameLogMap frame_map_; + PacketLogMap packet_map_; + GenericLogMap generic_map_; + + DISALLOW_COPY_AND_ASSIGN(Logging); +}; + +} // namespace cast +} // namespace media + +#endif // MEDIA_CAST_LOGGING_LOGGING_H_ + diff --git a/media/cast/logging/logging_defines.h b/media/cast/logging/logging_defines.h index 835c022..6388a12 100644 --- a/media/cast/logging/logging_defines.h +++ b/media/cast/logging/logging_defines.h @@ -50,7 +50,7 @@ struct FrameEvent { FrameEvent(); ~FrameEvent(); - uint8 frame_id; + uint32 frame_id; int size; // Encoded size only. std::vector<base::TimeTicks> timestamp; std::vector<CastLoggingEvent> type; @@ -72,7 +72,7 @@ typedef std::map<uint16, BasePacketInfo> BasePacketMap; struct PacketEvent { PacketEvent(); ~PacketEvent(); - uint8 frame_id; + uint32 frame_id; int max_packet_id; BasePacketMap packet_map; }; diff --git a/media/cast/logging/logging_impl.cc b/media/cast/logging/logging_impl.cc index 7f91df2..ed189a9 100644 --- a/media/cast/logging/logging_impl.cc +++ b/media/cast/logging/logging_impl.cc @@ -23,7 +23,7 @@ LoggingImpl::~LoggingImpl() {} void LoggingImpl::InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id) { + uint32 frame_id) { if (enable_data_collection_) { raw_.InsertFrameEvent(event, rtp_timestamp, frame_id); stats_.InsertFrameEvent(event, rtp_timestamp, frame_id); @@ -38,7 +38,7 @@ void LoggingImpl::InsertFrameEvent(CastLoggingEvent event, void LoggingImpl::InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int frame_size) { if (enable_data_collection_) { raw_.InsertFrameEventWithSize(event, rtp_timestamp, frame_id, frame_size); @@ -58,7 +58,7 @@ void LoggingImpl::InsertFrameEventWithSize(CastLoggingEvent event, void LoggingImpl::InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay) { if (enable_data_collection_) { raw_.InsertFrameEventWithDelay(event, rtp_timestamp, frame_id, delay); @@ -77,7 +77,7 @@ void LoggingImpl::InsertFrameEventWithDelay(CastLoggingEvent event, void LoggingImpl::InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size) { diff --git a/media/cast/logging/logging_impl.h b/media/cast/logging/logging_impl.h index 568bff5..5e724e0 100644 --- a/media/cast/logging/logging_impl.h +++ b/media/cast/logging/logging_impl.h @@ -28,18 +28,18 @@ class LoggingImpl { void InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id); + uint32 frame_id); void InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int frame_size); void InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay); void InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size); diff --git a/media/cast/logging/logging_internal.cc b/media/cast/logging/logging_internal.cc index aec0c96..ce2249e 100644 --- a/media/cast/logging/logging_internal.cc +++ b/media/cast/logging/logging_internal.cc @@ -13,27 +13,27 @@ FrameLogData::FrameLogData(base::TickClock* clock) FrameLogData::~FrameLogData() {} -void FrameLogData::Insert(uint32 rtp_timestamp, uint8 frame_id) { +void FrameLogData::Insert(uint32 rtp_timestamp, uint32 frame_id) { FrameEvent info; InsertBase(rtp_timestamp, frame_id, info); } void FrameLogData::InsertWithSize( - uint32 rtp_timestamp, uint8 frame_id, int size) { + uint32 rtp_timestamp, uint32 frame_id, int size) { FrameEvent info; info.size = size; InsertBase(rtp_timestamp, frame_id, info); } void FrameLogData::InsertWithDelay( - uint32 rtp_timestamp, uint8 frame_id, base::TimeDelta delay) { + uint32 rtp_timestamp, uint32 frame_id, base::TimeDelta delay) { FrameEvent info; info.delay_delta = delay; InsertBase(rtp_timestamp, frame_id, info); } void FrameLogData::InsertBase( - uint32 rtp_timestamp, uint8 frame_id, FrameEvent info) { + uint32 rtp_timestamp, uint32 frame_id, FrameEvent info) { info.timestamp = clock_->NowTicks(); info.frame_id = frame_id; frame_map_.insert(std::make_pair(rtp_timestamp, info)); @@ -46,7 +46,7 @@ PacketLogData::PacketLogData(base::TickClock* clock) PacketLogData::~PacketLogData() {} void PacketLogData::Insert(uint32 rtp_timestamp, - uint8 frame_id, uint16 packet_id, uint16 max_packet_id, int size) { + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size) { PacketEvent info; info.size = size; info.max_packet_id = max_packet_id; diff --git a/media/cast/logging/logging_internal.h b/media/cast/logging/logging_internal.h index 0f787600..ea66b1c 100644 --- a/media/cast/logging/logging_internal.h +++ b/media/cast/logging/logging_internal.h @@ -18,14 +18,14 @@ namespace cast { // TODO(mikhal): Consider storing only the delta time and not absolute time. struct FrameEvent { - uint8 frame_id; + uint32 frame_id; int size; base::TimeTicks timestamp; base::TimeDelta delay_delta; // render/playout delay. }; struct PacketEvent { - uint8 frame_id; + uint32 frame_id; int max_packet_id; int size; base::TimeTicks timestamp; @@ -40,16 +40,16 @@ class FrameLogData { public: explicit FrameLogData(base::TickClock* clock); ~FrameLogData(); - void Insert(uint32 rtp_timestamp, uint8 frame_id); + void Insert(uint32 rtp_timestamp, uint32 frame_id); // Include size for encoded images (compute bitrate), - void InsertWithSize(uint32 rtp_timestamp, uint8 frame_id, int size); + void InsertWithSize(uint32 rtp_timestamp, uint32 frame_id, int size); // Include playout/render delay info. void InsertWithDelay( - uint32 rtp_timestamp, uint8 frame_id, base::TimeDelta delay); + uint32 rtp_timestamp, uint32 frame_id, base::TimeDelta delay); void Reset(); private: - void InsertBase(uint32 rtp_timestamp, uint8 frame_id, FrameEvent info); + void InsertBase(uint32 rtp_timestamp, uint32 frame_id, FrameEvent info); base::TickClock* const clock_; // Not owned by this class. FrameMap frame_map_; @@ -62,7 +62,7 @@ class PacketLogData { public: explicit PacketLogData(base::TickClock* clock); ~PacketLogData(); - void Insert(uint32 rtp_timestamp, uint8 frame_id, uint16 packet_id, + void Insert(uint32 rtp_timestamp, uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size); void Reset(); diff --git a/media/cast/logging/logging_raw.cc b/media/cast/logging/logging_raw.cc index fa865a4..820fd0f 100644 --- a/media/cast/logging/logging_raw.cc +++ b/media/cast/logging/logging_raw.cc @@ -23,13 +23,13 @@ LoggingRaw::~LoggingRaw() {} void LoggingRaw::InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id) { + uint32 frame_id) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); } void LoggingRaw::InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int size) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); // Now insert size. @@ -40,7 +40,7 @@ void LoggingRaw::InsertFrameEventWithSize(CastLoggingEvent event, void LoggingRaw::InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); // Now insert delay. @@ -49,7 +49,7 @@ void LoggingRaw::InsertFrameEventWithDelay(CastLoggingEvent event, it->second.delay_delta = delay; } void LoggingRaw::InsertBaseFrameEvent(CastLoggingEvent event, - uint8 frame_id, + uint32 frame_id, uint32 rtp_timestamp) { // Is this a new event? FrameRawMap::iterator it = frame_map_.find(event); @@ -69,7 +69,7 @@ void LoggingRaw::InsertBaseFrameEvent(CastLoggingEvent event, void LoggingRaw::InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size) { diff --git a/media/cast/logging/logging_raw.h b/media/cast/logging/logging_raw.h index 91de12a..191e5e1 100644 --- a/media/cast/logging/logging_raw.h +++ b/media/cast/logging/logging_raw.h @@ -31,24 +31,24 @@ class LoggingRaw : public base::NonThreadSafe, // Frame events can be inserted with different parameters. void InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id); + uint32 frame_id); // Size - Inserting the size implies that this is an encoded frame. void InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int frame_size); // Render/playout delay void InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay); // Insert a packet event. void InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size); @@ -66,7 +66,7 @@ class LoggingRaw : public base::NonThreadSafe, private: void InsertBaseFrameEvent(CastLoggingEvent event, - uint8 frame_id, + uint32 frame_id, uint32 rtp_timestamp); base::WeakPtrFactory<LoggingRaw> weak_factory_; diff --git a/media/cast/logging/logging_stats.cc b/media/cast/logging/logging_stats.cc index 9d79f69..95e916a 100644 --- a/media/cast/logging/logging_stats.cc +++ b/media/cast/logging/logging_stats.cc @@ -29,13 +29,13 @@ void LoggingStats::Reset() { void LoggingStats::InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id) { + uint32 frame_id) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); } void LoggingStats::InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int frame_size) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); // Update size. @@ -46,7 +46,7 @@ void LoggingStats::InsertFrameEventWithSize(CastLoggingEvent event, void LoggingStats::InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay) { InsertBaseFrameEvent(event, frame_id, rtp_timestamp); // Update size. @@ -63,7 +63,7 @@ void LoggingStats::InsertFrameEventWithDelay(CastLoggingEvent event, } void LoggingStats::InsertBaseFrameEvent(CastLoggingEvent event, - uint8 frame_id, + uint32 frame_id, uint32 rtp_timestamp) { // Does this belong to an existing event? FrameStatsMap::iterator it = frame_stats_.find(event); @@ -79,7 +79,7 @@ void LoggingStats::InsertBaseFrameEvent(CastLoggingEvent event, void LoggingStats::InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size) { diff --git a/media/cast/logging/logging_stats.h b/media/cast/logging/logging_stats.h index 65dccbd..e5595476 100644 --- a/media/cast/logging/logging_stats.h +++ b/media/cast/logging/logging_stats.h @@ -25,21 +25,21 @@ class LoggingStats { void InsertFrameEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id); + uint32 frame_id); void InsertFrameEventWithSize(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, int frame_size); void InsertFrameEventWithDelay(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, base::TimeDelta delay); void InsertPacketEvent(CastLoggingEvent event, uint32 rtp_timestamp, - uint8 frame_id, + uint32 frame_id, uint16 packet_id, uint16 max_packet_id, int size); @@ -56,7 +56,7 @@ class LoggingStats { private: void InsertBaseFrameEvent(CastLoggingEvent event, - uint8 frame_id, + uint32 frame_id, uint32 rtp_timestamp); FrameStatsMap frame_stats_; PacketStatsMap packet_stats_; diff --git a/media/cast/logging/logging_unittest.cc b/media/cast/logging/logging_unittest.cc index ce55e65..5ce760e 100644 --- a/media/cast/logging/logging_unittest.cc +++ b/media/cast/logging/logging_unittest.cc @@ -40,7 +40,7 @@ TEST_F(TestLogging, BasicFrameLogging) { base::TimeTicks start_time = testing_clock_.NowTicks(); base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time; uint32 rtp_timestamp = 0; - uint8 frame_id = 0; + uint32 frame_id = 0; do { logging_.InsertFrameEvent(kAudioFrameCaptured, rtp_timestamp, frame_id); testing_clock_.Advance( @@ -73,7 +73,7 @@ TEST_F(TestLogging, FrameLoggingWithSize) { base::TimeTicks start_time = testing_clock_.NowTicks(); base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time; uint32 rtp_timestamp = 0; - uint8 frame_id = 0; + uint32 frame_id = 0; do { int size = kBaseFrameSizeBytes + base::RandInt(-kRandomSizeInterval, kRandomSizeInterval); @@ -110,7 +110,7 @@ TEST_F(TestLogging, FrameLoggingWithDelay) { base::TimeTicks start_time = testing_clock_.NowTicks(); base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time; uint32 rtp_timestamp = 0; - uint8 frame_id = 0; + uint32 frame_id = 0; do { int delay = kPlayoutDelayMs + base::RandInt(-kRandomSizeInterval, kRandomSizeInterval); @@ -145,7 +145,7 @@ TEST_F(TestLogging, MultipleEventFrameLogging) { base::TimeTicks start_time = testing_clock_.NowTicks(); base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time; uint32 rtp_timestamp = 0; - uint8 frame_id = 0; + uint32 frame_id = 0; do { logging_.InsertFrameEvent(kAudioFrameCaptured, rtp_timestamp, frame_id); if (frame_id % 2) { @@ -178,7 +178,7 @@ TEST_F(TestLogging, PacketLogging) { base::TimeTicks start_time = testing_clock_.NowTicks(); base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time; uint32 rtp_timestamp = 0; - uint8 frame_id = 0; + uint32 frame_id = 0; do { for (int i = 0; i < kNumPacketsPerFrame; ++i) { int size = kBaseSize + base::RandInt(-kSizeInterval, kSizeInterval); diff --git a/media/cast/rtcp/rtcp_defines.h b/media/cast/rtcp/rtcp_defines.h index d2e7c90..c02b099 100644 --- a/media/cast/rtcp/rtcp_defines.h +++ b/media/cast/rtcp/rtcp_defines.h @@ -21,7 +21,7 @@ class RtcpCastMessage { ~RtcpCastMessage(); uint32 media_ssrc_; - uint8 ack_frame_id_; + uint32 ack_frame_id_; MissingFramesAndPacketsMap missing_frames_and_packets_; }; diff --git a/media/cast/rtcp/rtcp_receiver.cc b/media/cast/rtcp/rtcp_receiver.cc index 5bdaadd..812a541 100644 --- a/media/cast/rtcp/rtcp_receiver.cc +++ b/media/cast/rtcp/rtcp_receiver.cc @@ -376,7 +376,8 @@ void RtcpReceiver::HandlePayloadSpecificCastItem(RtcpParser* rtcp_parser) { const RtcpField& rtcp_field = rtcp_parser->Field(); RtcpCastMessage cast_message(remote_ssrc_); - cast_message.ack_frame_id_ = rtcp_field.cast_item.last_frame_id; + cast_message.ack_frame_id_ = ack_frame_id_wrap_helper_.MapTo32bitsFrameId( + rtcp_field.cast_item.last_frame_id); RtcpFieldTypes packet_type = rtcp_parser->Iterate(); while (packet_type == kRtcpPayloadSpecificCastNackItemCode) { diff --git a/media/cast/rtcp/rtcp_receiver.h b/media/cast/rtcp/rtcp_receiver.h index 585f861..0d68d47 100644 --- a/media/cast/rtcp/rtcp_receiver.h +++ b/media/cast/rtcp/rtcp_receiver.h @@ -97,6 +97,8 @@ class RtcpReceiver { RtcpReceiverFeedback* const receiver_feedback_; RtcpRttFeedback* const rtt_feedback_; + FrameIdWrapHelper ack_frame_id_wrap_helper_; + DISALLOW_COPY_AND_ASSIGN(RtcpReceiver); }; diff --git a/media/cast/rtcp/rtcp_sender.cc b/media/cast/rtcp/rtcp_sender.cc index cd1c50c..74f7768 100644 --- a/media/cast/rtcp/rtcp_sender.cc +++ b/media/cast/rtcp/rtcp_sender.cc @@ -478,7 +478,7 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. big_endian_writer.WriteU32(kCast); - big_endian_writer.WriteU8(cast->ack_frame_id_); + big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); size_t cast_loss_field_pos = start_size + 17; // Save loss field position. big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. big_endian_writer.WriteU8(0); // Reserved. @@ -499,7 +499,7 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, start_size = packet->size(); packet->resize(start_size + 4); net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); - big_endian_nack_writer.WriteU8(frame_it->first); + big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); big_endian_nack_writer.WriteU8(0); ++number_of_loss_fields; @@ -514,7 +514,7 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, &((*packet)[start_size]), 4); // Write frame and packet id to buffer before calculating bitmask. - big_endian_nack_writer.WriteU8(frame_it->first); + big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); big_endian_nack_writer.WriteU16(packet_id); uint8 bitmask = 0; diff --git a/media/cast/rtcp/test_rtcp_packet_builder.h b/media/cast/rtcp/test_rtcp_packet_builder.h index 8c5479f..0945ba4 100644 --- a/media/cast/rtcp/test_rtcp_packet_builder.h +++ b/media/cast/rtcp/test_rtcp_packet_builder.h @@ -44,9 +44,9 @@ static const uint64 kPictureId = 0x1234567890; static const int kMissingPacket = 34567; // CAST. -static const int kAckFrameId = 17; -static const int kLostFrameId = 18; -static const int kFrameIdWithLostPackets = 19; +static const uint32 kAckFrameId = 17; +static const uint32 kLostFrameId = 18; +static const uint32 kFrameIdWithLostPackets = 19; static const int kLostPacketId1 = 3; static const int kLostPacketId2 = 5; static const int kLostPacketId3 = 12; diff --git a/media/cast/rtp_common/rtp_defines.h b/media/cast/rtp_common/rtp_defines.h index ca5ca94..b4bc1a2 100644 --- a/media/cast/rtp_common/rtp_defines.h +++ b/media/cast/rtp_common/rtp_defines.h @@ -26,12 +26,12 @@ struct RtpCastHeader { } webrtc::WebRtcRTPHeader webrtc; bool is_key_frame; - uint8 frame_id; + uint32 frame_id; uint16 packet_id; uint16 max_packet_id; bool is_reference; // Set to true if the previous frame is not available, // and the reference frame id is available. - uint8 reference_frame_id; + uint32 reference_frame_id; }; class RtpPayloadFeedback { diff --git a/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc b/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc index 79cc55e..6ef20fe 100644 --- a/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc +++ b/media/cast/rtp_receiver/rtp_parser/rtp_parser.cc @@ -20,11 +20,9 @@ static const uint8 kCastReferenceFrameIdBitMask = 0x40; RtpParser::RtpParser(RtpData* incoming_payload_callback, const RtpParserConfig parser_config) : data_callback_(incoming_payload_callback), - parser_config_(parser_config) { -} + parser_config_(parser_config) {} -RtpParser::~RtpParser() { -} +RtpParser::~RtpParser() {} bool RtpParser::ParsePacket(const uint8* packet, size_t length, RtpCastHeader* rtp_header) { @@ -85,14 +83,15 @@ bool RtpParser::ParseCast(const uint8* packet, size_t data_length = length; rtp_header->is_key_frame = (data_ptr[0] & kCastKeyFrameBitMask); rtp_header->is_reference = (data_ptr[0] & kCastReferenceFrameIdBitMask); - rtp_header->frame_id = data_ptr[1]; + rtp_header->frame_id = frame_id_wrap_helper_.MapTo32bitsFrameId(data_ptr[1]); net::BigEndianReader big_endian_reader(data_ptr + 2, 4); big_endian_reader.ReadU16(&rtp_header->packet_id); big_endian_reader.ReadU16(&rtp_header->max_packet_id); if (rtp_header->is_reference) { - rtp_header->reference_frame_id = data_ptr[6]; + rtp_header->reference_frame_id = + reference_frame_id_wrap_helper_.MapTo32bitsFrameId(data_ptr[6]); data_ptr += kRtpCastHeaderLength; data_length -= kRtpCastHeaderLength; } else { diff --git a/media/cast/rtp_receiver/rtp_parser/rtp_parser.h b/media/cast/rtp_receiver/rtp_parser/rtp_parser.h index d8d1e34..92ac30c 100644 --- a/media/cast/rtp_receiver/rtp_parser/rtp_parser.h +++ b/media/cast/rtp_receiver/rtp_parser/rtp_parser.h @@ -45,6 +45,8 @@ class RtpParser { RtpData* data_callback_; RtpParserConfig parser_config_; + FrameIdWrapHelper frame_id_wrap_helper_; + FrameIdWrapHelper reference_frame_id_wrap_helper_; }; } // namespace cast diff --git a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc index d667dee..e8d213d 100644 --- a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc +++ b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.cc @@ -30,7 +30,7 @@ void RtpPacketBuilder::SetKeyFrame(bool is_key) { is_key_ = is_key; } -void RtpPacketBuilder::SetFrameId(uint8 frame_id) { +void RtpPacketBuilder::SetFrameId(uint32 frame_id) { frame_id_ = frame_id; } @@ -42,7 +42,7 @@ void RtpPacketBuilder::SetMaxPacketId(uint16 max_packet_id) { max_packet_id_ = max_packet_id; } -void RtpPacketBuilder::SetReferenceFrameId(uint8 reference_frame_id, +void RtpPacketBuilder::SetReferenceFrameId(uint32 reference_frame_id, bool is_set) { is_reference_set_ = is_set; if (is_set) diff --git a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h index 70f520e..b6b1a41 100644 --- a/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h +++ b/media/cast/rtp_receiver/rtp_parser/test/rtp_packet_builder.h @@ -17,10 +17,10 @@ class RtpPacketBuilder { public: RtpPacketBuilder(); void SetKeyFrame(bool is_key); - void SetFrameId(uint8 frame_id); + void SetFrameId(uint32 frame_id); void SetPacketId(uint16 packet_id); void SetMaxPacketId(uint16 max_packet_id); - void SetReferenceFrameId(uint8 reference_frame_id, bool is_set); + void SetReferenceFrameId(uint32 reference_frame_id, bool is_set); void SetTimestamp(uint32 timestamp); void SetSequenceNumber(uint16 sequence_number); void SetMarkerBit(bool marker); @@ -30,10 +30,10 @@ class RtpPacketBuilder { private: bool is_key_; - uint8 frame_id_; + uint32 frame_id_; uint16 packet_id_; uint16 max_packet_id_; - uint8 reference_frame_id_; + uint32 reference_frame_id_; bool is_reference_set_; uint32 timestamp_; uint16 sequence_number_; diff --git a/media/cast/rtp_sender/mock_rtp_sender.h b/media/cast/rtp_sender/mock_rtp_sender.h index 334bc88..4e74aac 100644 --- a/media/cast/rtp_sender/mock_rtp_sender.h +++ b/media/cast/rtp_sender/mock_rtp_sender.h @@ -22,7 +22,7 @@ class MockRtpSender : public RtpSender { bool(const EncodedAudioFrame& frame, int64 recorded_time)); MOCK_METHOD3(ResendPacket, - bool(bool is_audio, uint8 frame_id, uint16 packet_id)); + bool(bool is_audio, uint32 frame_id, uint16 packet_id)); MOCK_METHOD0(RtpStatistics, void()); }; diff --git a/media/cast/rtp_sender/packet_storage/packet_storage.cc b/media/cast/rtp_sender/packet_storage/packet_storage.cc index d20dc9d..96e2d27 100644 --- a/media/cast/rtp_sender/packet_storage/packet_storage.cc +++ b/media/cast/rtp_sender/packet_storage/packet_storage.cc @@ -96,12 +96,13 @@ void PacketStorage::CleanupOldPackets(base::TimeTicks now) { } } -void PacketStorage::StorePacket(uint8 frame_id, uint16 packet_id, +void PacketStorage::StorePacket(uint32 frame_id, uint16 packet_id, const Packet* packet) { base::TimeTicks now = clock_->NowTicks(); CleanupOldPackets(now); - uint32 index = (static_cast<uint32>(frame_id) << 16) + packet_id; + // Internally we only use the 8 LSB of the frame id. + uint32 index = ((0xff & frame_id) << 16) + packet_id; PacketMapIterator it = stored_packets_.find(index); if (it != stored_packets_.end()) { // We have already saved this. @@ -122,15 +123,50 @@ void PacketStorage::StorePacket(uint8 frame_id, uint16 packet_id, time_to_packet_map_.insert(std::make_pair(now, index)); } +PacketList PacketStorage::GetPackets( + const MissingFramesAndPacketsMap& missing_frames_and_packets) { + PacketList packets_to_resend; + + // Iterate over all frames in the list. + for (MissingFramesAndPacketsMap::const_iterator it = + missing_frames_and_packets.begin(); + it != missing_frames_and_packets.end(); ++it) { + uint8 frame_id = it->first; + const PacketIdSet& packets_set = it->second; + bool success = false; + + if (packets_set.empty()) { + VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id); + + uint16 packet_id = 0; + do { + // Get packet from storage. + success = GetPacket(frame_id, packet_id, &packets_to_resend); + ++packet_id; + } while (success); + } else { + // Iterate over all of the packets in the frame. + for (PacketIdSet::const_iterator set_it = packets_set.begin(); + set_it != packets_set.end(); ++set_it) { + GetPacket(frame_id, *set_it, &packets_to_resend); + } + } + } + return packets_to_resend; +} + bool PacketStorage::GetPacket(uint8 frame_id, uint16 packet_id, PacketList* packets) { + // Internally we only use the 8 LSB of the frame id. uint32 index = (static_cast<uint32>(frame_id) << 16) + packet_id; PacketMapIterator it = stored_packets_.find(index); if (it == stored_packets_.end()) { return false; } it->second->GetCopy(packets); + VLOG(1) << "Resend " << static_cast<int>(frame_id) + << ":" << packet_id; return true; } diff --git a/media/cast/rtp_sender/packet_storage/packet_storage.h b/media/cast/rtp_sender/packet_storage/packet_storage.h index 791fed6..bcb0079 100644 --- a/media/cast/rtp_sender/packet_storage/packet_storage.h +++ b/media/cast/rtp_sender/packet_storage/packet_storage.h @@ -30,9 +30,13 @@ class PacketStorage { PacketStorage(base::TickClock* clock, int max_time_stored_ms); virtual ~PacketStorage(); - void StorePacket(uint8 frame_id, uint16 packet_id, const Packet* packet); + void StorePacket(uint32 frame_id, uint16 packet_id, const Packet* packet); - // Copies packet into the buffer pointed to by rtp_buffer. + // Copies all missing packets into the packet list. + PacketList GetPackets( + const MissingFramesAndPacketsMap& missing_frames_and_packets); + + // Copies packet into the packet list. bool GetPacket(uint8 frame_id, uint16 packet_id, PacketList* packets); private: diff --git a/media/cast/rtp_sender/packet_storage/packet_storage_unittest.cc b/media/cast/rtp_sender/packet_storage/packet_storage_unittest.cc index 04092c2..86ce06c 100644 --- a/media/cast/rtp_sender/packet_storage/packet_storage_unittest.cc +++ b/media/cast/rtp_sender/packet_storage/packet_storage_unittest.cc @@ -33,7 +33,7 @@ class PacketStorageTest : public ::testing::Test { TEST_F(PacketStorageTest, TimeOut) { Packet test_123(100, 123); // 100 insertions of the value 123. PacketList packets; - for (uint8 frame_id = 0; frame_id < 30; ++frame_id) { + for (uint32 frame_id = 0; frame_id < 30; ++frame_id) { for (uint16 packet_id = 0; packet_id < 10; ++packet_id) { packet_storage_.StorePacket(frame_id, packet_id, &test_123); } @@ -41,14 +41,14 @@ TEST_F(PacketStorageTest, TimeOut) { } // All packets belonging to the first 14 frames is expected to be expired. - for (uint8 frame_id = 0; frame_id < 14; ++frame_id) { + for (uint32 frame_id = 0; frame_id < 14; ++frame_id) { for (uint16 packet_id = 0; packet_id < 10; ++packet_id) { Packet packet; EXPECT_FALSE(packet_storage_.GetPacket(frame_id, packet_id, &packets)); } } // All packets belonging to the next 15 frames is expected to be valid. - for (uint8 frame_id = 14; frame_id < 30; ++frame_id) { + for (uint32 frame_id = 14; frame_id < 30; ++frame_id) { for (uint16 packet_id = 0; packet_id < 10; ++packet_id) { EXPECT_TRUE(packet_storage_.GetPacket(frame_id, packet_id, &packets)); EXPECT_TRUE(packets.front() == test_123); @@ -60,7 +60,7 @@ TEST_F(PacketStorageTest, MaxNumberOfPackets) { Packet test_123(100, 123); // 100 insertions of the value 123. PacketList packets; - uint8 frame_id = 0; + uint32 frame_id = 0; for (uint16 packet_id = 0; packet_id <= PacketStorage::kMaxStoredPackets; ++packet_id) { packet_storage_.StorePacket(frame_id, packet_id, &test_123); @@ -81,7 +81,7 @@ TEST_F(PacketStorageTest, PacketContent) { Packet test_234(200, 234); // 200 insertions of the value 234. PacketList packets; - for (uint8 frame_id = 0; frame_id < 10; ++frame_id) { + for (uint32 frame_id = 0; frame_id < 10; ++frame_id) { for (uint16 packet_id = 0; packet_id < 10; ++packet_id) { // Every other packet. if (packet_id % 2 == 0) { @@ -92,7 +92,7 @@ TEST_F(PacketStorageTest, PacketContent) { } testing_clock_.Advance(kDeltaBetweenFrames); } - for (uint8 frame_id = 0; frame_id < 10; ++frame_id) { + for (uint32 frame_id = 0; frame_id < 10; ++frame_id) { for (uint16 packet_id = 0; packet_id < 10; ++packet_id) { EXPECT_TRUE(packet_storage_.GetPacket(frame_id, packet_id, &packets)); // Every other packet. diff --git a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.cc b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.cc index 790c513..d39d08b 100644 --- a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.cc +++ b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.cc @@ -79,10 +79,10 @@ bool RtpPacketizer::LastSentTimestamp(base::TimeTicks* time_sent, } void RtpPacketizer::Cast(bool is_key, - uint8 frame_id, - uint8 reference_frame_id, + uint32 frame_id, + uint32 reference_frame_id, uint32 timestamp, - std::vector<uint8> data) { + Packet data) { uint16 rtp_header_length = kCommonRtpHeaderLength + kCastRtpHeaderLength; uint16 max_length = config_.max_payload_length - rtp_header_length - 1; @@ -113,7 +113,7 @@ void RtpPacketizer::Cast(bool is_key, net::BigEndianWriter big_endian_writer(&(packet[start_size]), 4); big_endian_writer.WriteU16(packet_id_); big_endian_writer.WriteU16(static_cast<uint16>(num_packets - 1)); - packet.push_back(reference_frame_id); + packet.push_back(static_cast<uint8>(reference_frame_id)); // Copy payload data. packet.insert(packet.end(), data_iter, data_iter + payload_length); diff --git a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.h b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.h index cfe1ef9..9279fd0 100644 --- a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.h +++ b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer.h @@ -49,9 +49,8 @@ class RtpPacketizer { size_t send_octet_count() { return send_octet_count_; } private: - void Cast(bool is_key, - uint8 frame_id, - uint8 reference_frame_id, + void Cast(bool is_key, uint32 frame_id, + uint32 reference_frame_id, uint32 timestamp, std::vector<uint8> data); void BuildCommonRTPheader(std::vector<uint8>* packet, bool marker_bit, diff --git a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc index 0322b1d..16959e0 100644 --- a/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc +++ b/media/cast/rtp_sender/rtp_packetizer/rtp_packetizer_unittest.cc @@ -55,8 +55,7 @@ class TestRtpPacketTransport : public PacedPacketSender { EXPECT_EQ(expected_packet_id_, rtp_header.packet_id); EXPECT_EQ(expected_number_of_packets_ - 1, rtp_header.max_packet_id); EXPECT_TRUE(rtp_header.is_reference); - EXPECT_EQ(static_cast<uint8>(expected_frame_id_ - 1), - rtp_header.reference_frame_id); + EXPECT_EQ(expected_frame_id_ - 1u, rtp_header.reference_frame_id); } virtual bool SendPackets(const PacketList& packets) OVERRIDE { @@ -94,7 +93,7 @@ class TestRtpPacketTransport : public PacedPacketSender { int expected_number_of_packets_; // Assuming packets arrive in sequence. int expected_packet_id_; - int expected_frame_id_; + uint32 expected_frame_id_; }; class RtpPacketizerTest : public ::testing::Test { @@ -116,7 +115,7 @@ class RtpPacketizerTest : public ::testing::Test { virtual void SetUp() { video_frame_.key_frame = false; video_frame_.frame_id = 0; - video_frame_.last_referenced_frame_id = 255; + video_frame_.last_referenced_frame_id = kStartFrameId; video_frame_.data.assign(kFrameSize, 123); } diff --git a/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.cc b/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.cc index 49aac94..5c1c9fe 100644 --- a/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.cc +++ b/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.cc @@ -39,9 +39,7 @@ bool RtpHeaderParser::ParseCommon(RtpCastHeader* parsed_packet) const { const uint8 num_csrcs = rtp_data_begin_[0] & 0x0f; const bool marker = ((rtp_data_begin_[1] & 0x80) == 0) ? false : true; - const uint8 payload_type = rtp_data_begin_[1] & 0x7f; - const uint16 sequence_number = (rtp_data_begin_[2] << 8) + rtp_data_begin_[3]; @@ -72,14 +70,15 @@ bool RtpHeaderParser::ParseCast(RtpCastHeader* parsed_packet) const { const uint8* data = rtp_data_begin_ + kRtpCommonHeaderLength; parsed_packet->is_key_frame = (data[0] & kCastKeyFrameBitMask); parsed_packet->is_reference = (data[0] & kCastReferenceFrameIdBitMask); - parsed_packet->frame_id = data[1]; + parsed_packet->frame_id = frame_id_wrap_helper_.MapTo32bitsFrameId(data[1]); net::BigEndianReader big_endian_reader(data + 2, 8); big_endian_reader.ReadU16(&parsed_packet->packet_id); big_endian_reader.ReadU16(&parsed_packet->max_packet_id); if (parsed_packet->is_reference) { - parsed_packet->reference_frame_id = data[6]; + parsed_packet->reference_frame_id = + reference_frame_id_wrap_helper_.MapTo32bitsFrameId(data[6]); } return true; } diff --git a/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.h b/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.h index d28f5a8..e4b1465 100644 --- a/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.h +++ b/media/cast/rtp_sender/rtp_packetizer/test/rtp_header_parser.h @@ -23,6 +23,9 @@ class RtpHeaderParser { const uint8* const rtp_data_begin_; size_t length_; + mutable FrameIdWrapHelper frame_id_wrap_helper_; + mutable FrameIdWrapHelper reference_frame_id_wrap_helper_; + DISALLOW_COPY_AND_ASSIGN(RtpHeaderParser); }; diff --git a/media/cast/rtp_sender/rtp_sender.cc b/media/cast/rtp_sender/rtp_sender.cc index d06a503..37487a0 100644 --- a/media/cast/rtp_sender/rtp_sender.cc +++ b/media/cast/rtp_sender/rtp_sender.cc @@ -58,52 +58,15 @@ void RtpSender::IncomingEncodedAudioFrame(const EncodedAudioFrame* audio_frame, void RtpSender::ResendPackets( const MissingFramesAndPacketsMap& missing_frames_and_packets) { - // Iterate over all frames in the list. - for (MissingFramesAndPacketsMap::const_iterator it = - missing_frames_and_packets.begin(); - it != missing_frames_and_packets.end(); ++it) { - PacketList packets_to_resend; - uint8 frame_id = it->first; - const PacketIdSet& packets_set = it->second; - bool success = false; + PacketList packets_to_resend = + storage_->GetPackets(missing_frames_and_packets); - if (packets_set.empty()) { - VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id); - - uint16 packet_id = 0; - do { - // Get packet from storage. - success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend); - - // Resend packet to the network. - if (success) { - VLOG(1) << "Resend " << static_cast<int>(frame_id) - << ":" << packet_id; - // Set a unique incremental sequence number for every packet. - Packet& packet = packets_to_resend.back(); - UpdateSequenceNumber(&packet); - // Set the size as correspond to each frame. - ++packet_id; - } - } while (success); - } else { - // Iterate over all of the packets in the frame. - for (PacketIdSet::const_iterator set_it = packets_set.begin(); - set_it != packets_set.end(); ++set_it) { - uint16 packet_id = *set_it; - success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend); - - // Resend packet to the network. - if (success) { - VLOG(1) << "Resend " << static_cast<int>(frame_id) - << ":" << packet_id; - Packet& packet = packets_to_resend.back(); - UpdateSequenceNumber(&packet); - } - } - } - transport_->ResendPackets(packets_to_resend); + PacketList::iterator it = packets_to_resend.begin(); + for (; it != packets_to_resend.end(); ++it) { + Packet& packet = *it; + UpdateSequenceNumber(&packet); } + transport_->ResendPackets(packets_to_resend); } void RtpSender::UpdateSequenceNumber(Packet* packet) { diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index c58a85d..f125d6d 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc @@ -96,7 +96,7 @@ class LoopBackTransport : public PacketSender { for (size_t i = 0; i < packets.size(); ++i) { const Packet& packet = packets[i]; if (drop_packets_belonging_to_odd_frames_) { - uint8 frame_id = packet[13]; + uint32 frame_id = packet[13]; if (frame_id % 2 == 1) continue; } uint8* packet_copy = new uint8[packet.size()]; diff --git a/media/cast/video_sender/codecs/vp8/vp8_encoder.cc b/media/cast/video_sender/codecs/vp8/vp8_encoder.cc index 1021438..bea7507 100644 --- a/media/cast/video_sender/codecs/vp8/vp8_encoder.cc +++ b/media/cast/video_sender/codecs/vp8/vp8_encoder.cc @@ -230,7 +230,7 @@ void Vp8Encoder::GetCodecReferenceFlags(vpx_codec_flags_t* flags) { } } -uint8 Vp8Encoder::GetLatestFrameIdToReference() { +uint32 Vp8Encoder::GetLatestFrameIdToReference() { if (!use_multiple_video_buffers_) return last_encoded_frame_id_; int latest_frame_id_to_reference = -1; @@ -258,7 +258,7 @@ uint8 Vp8Encoder::GetLatestFrameIdToReference() { } } DCHECK(latest_frame_id_to_reference != -1) << "Invalid state"; - return static_cast<uint8>(latest_frame_id_to_reference); + return static_cast<uint32>(latest_frame_id_to_reference); } Vp8Encoder::Vp8Buffers Vp8Encoder::GetNextBufferToUpdate() { @@ -333,7 +333,7 @@ void Vp8Encoder::UpdateRates(uint32 new_bitrate) { } } -void Vp8Encoder::LatestFrameIdToReference(uint8 frame_id) { +void Vp8Encoder::LatestFrameIdToReference(uint32 frame_id) { if (!use_multiple_video_buffers_) return; VLOG(1) << "VP8 ok to reference frame:" << static_cast<int>(frame_id); diff --git a/media/cast/video_sender/codecs/vp8/vp8_encoder.h b/media/cast/video_sender/codecs/vp8/vp8_encoder.h index 777f862..709ca98 100644 --- a/media/cast/video_sender/codecs/vp8/vp8_encoder.h +++ b/media/cast/video_sender/codecs/vp8/vp8_encoder.h @@ -35,7 +35,7 @@ class Vp8Encoder { // Set the next frame to be a key frame. void GenerateKeyFrame(); - void LatestFrameIdToReference(uint8 frame_id); + void LatestFrameIdToReference(uint32 frame_id); private: enum Vp8Buffers { @@ -54,7 +54,7 @@ class Vp8Encoder { Vp8Buffers GetNextBufferToUpdate(); // Calculate which previous frame to reference. - uint8 GetLatestFrameIdToReference(); + uint32 GetLatestFrameIdToReference(); // Get encoder flags for our referenced encoder buffers. void GetCodecReferenceFlags(vpx_codec_flags_t* flags); @@ -74,8 +74,8 @@ class Vp8Encoder { bool key_frame_requested_; int64 timestamp_; - uint8 last_encoded_frame_id_; - uint8 used_buffers_frame_id_[kNumberOfVp8VideoBuffers]; + uint32 last_encoded_frame_id_; + uint32 used_buffers_frame_id_[kNumberOfVp8VideoBuffers]; bool acked_frame_buffers_[kNumberOfVp8VideoBuffers]; Vp8Buffers last_used_vp8_buffer_; int number_of_repeated_buffers_; diff --git a/media/cast/video_sender/mock_video_encoder_controller.h b/media/cast/video_sender/mock_video_encoder_controller.h index a97bcb1..cfc58a9 100644 --- a/media/cast/video_sender/mock_video_encoder_controller.h +++ b/media/cast/video_sender/mock_video_encoder_controller.h @@ -22,7 +22,7 @@ class MockVideoEncoderController : public VideoEncoderController { MOCK_METHOD0(GenerateKeyFrame, void()); - MOCK_METHOD1(LatestFrameIdToReference, void(uint8 frame_id)); + MOCK_METHOD1(LatestFrameIdToReference, void(uint32 frame_id)); MOCK_CONST_METHOD0(NumberOfSkippedFrames, int()); }; diff --git a/media/cast/video_sender/video_encoder.cc b/media/cast/video_sender/video_encoder.cc index 42d1a88..bc2b971 100644 --- a/media/cast/video_sender/video_encoder.cc +++ b/media/cast/video_sender/video_encoder.cc @@ -101,7 +101,7 @@ void VideoEncoder::GenerateKeyFrame() { } // Inform the encoder to only reference frames older or equal to frame_id; -void VideoEncoder::LatestFrameIdToReference(uint8 frame_id) { +void VideoEncoder::LatestFrameIdToReference(uint32 frame_id) { dynamic_config_.latest_frame_id_to_reference = frame_id; } diff --git a/media/cast/video_sender/video_encoder.h b/media/cast/video_sender/video_encoder.h index fa85468..ee4d4f5 100644 --- a/media/cast/video_sender/video_encoder.h +++ b/media/cast/video_sender/video_encoder.h @@ -44,7 +44,7 @@ class VideoEncoder : public VideoEncoderController, struct CodecDynamicConfig { bool key_frame_requested; - uint8 latest_frame_id_to_reference; + uint32 latest_frame_id_to_reference; int bit_rate; }; @@ -60,7 +60,7 @@ class VideoEncoder : public VideoEncoderController, virtual void SetBitRate(int new_bit_rate) OVERRIDE; virtual void SkipNextFrame(bool skip_next_frame) OVERRIDE; virtual void GenerateKeyFrame() OVERRIDE; - virtual void LatestFrameIdToReference(uint8 frame_id) OVERRIDE; + virtual void LatestFrameIdToReference(uint32 frame_id) OVERRIDE; virtual int NumberOfSkippedFrames() const OVERRIDE; private: diff --git a/media/cast/video_sender/video_sender.cc b/media/cast/video_sender/video_sender.cc index 7d8f7c1..d706f02 100644 --- a/media/cast/video_sender/video_sender.cc +++ b/media/cast/video_sender/video_sender.cc @@ -204,7 +204,7 @@ void VideoSender::ResendCheck() { DCHECK_GE(255, last_acked_frame_id_); DCHECK_LE(0, last_acked_frame_id_); - uint8 frame_id = static_cast<uint8>(last_acked_frame_id_ + 1); + uint32 frame_id = static_cast<uint32>(last_acked_frame_id_ + 1); VLOG(1) << "ACK timeout resend frame:" << static_cast<int>(frame_id); ResendFrame(frame_id); } @@ -263,7 +263,7 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { video_encoder_controller_->LatestFrameIdToReference( cast_feedback.ack_frame_id_); - if (static_cast<uint8>(last_acked_frame_id_ + 1) == + if (static_cast<uint32>(last_acked_frame_id_ + 1) == cast_feedback.ack_frame_id_) { uint32 new_bitrate = 0; if (congestion_control_.OnAck(rtt, &new_bitrate)) { @@ -279,14 +279,14 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { } if (duplicate_ack_ >= 2 && duplicate_ack_ % 3 == 2) { // Resend last ACK + 1 frame. - resend_frame = static_cast<uint8>(last_acked_frame_id_ + 1); + resend_frame = static_cast<uint32>(last_acked_frame_id_ + 1); } if (resend_frame != -1) { DCHECK_GE(255, resend_frame); DCHECK_LE(0, resend_frame); VLOG(1) << "Received duplicate ACK for frame:" << static_cast<int>(resend_frame); - ResendFrame(static_cast<uint8>(resend_frame)); + ResendFrame(static_cast<uint32>(resend_frame)); } } else { rtp_sender_->ResendPackets(cast_feedback.missing_frames_and_packets_); @@ -300,7 +300,7 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { ReceivedAck(cast_feedback.ack_frame_id_); } -void VideoSender::ReceivedAck(uint8 acked_frame_id) { +void VideoSender::ReceivedAck(uint32 acked_frame_id) { VLOG(1) << "ReceivedAck:" << static_cast<int>(acked_frame_id); last_acked_frame_id_ = acked_frame_id; UpdateFramesInFlight(); @@ -310,12 +310,12 @@ void VideoSender::UpdateFramesInFlight() { if (last_sent_frame_id_ != -1) { DCHECK_GE(255, last_sent_frame_id_); DCHECK_LE(0, last_sent_frame_id_); - uint8 frames_in_flight; + uint32 frames_in_flight; if (last_acked_frame_id_ != -1) { DCHECK_GE(255, last_acked_frame_id_); DCHECK_LE(0, last_acked_frame_id_); - frames_in_flight = static_cast<uint8>(last_sent_frame_id_) - - static_cast<uint8>(last_acked_frame_id_); + frames_in_flight = static_cast<uint32>(last_sent_frame_id_) - + static_cast<uint32>(last_acked_frame_id_); } else { frames_in_flight = last_sent_frame_id_ + 1; } @@ -329,7 +329,7 @@ void VideoSender::UpdateFramesInFlight() { video_encoder_controller_->SkipNextFrame(false); } -void VideoSender::ResendFrame(uint8 resend_frame_id) { +void VideoSender::ResendFrame(uint32 resend_frame_id) { MissingFramesAndPacketsMap missing_frames_and_packets; PacketIdSet missing; missing_frames_and_packets.insert(std::make_pair(resend_frame_id, missing)); diff --git a/media/cast/video_sender/video_sender.h b/media/cast/video_sender/video_sender.h index 168700f..ea89b3c 100644 --- a/media/cast/video_sender/video_sender.h +++ b/media/cast/video_sender/video_sender.h @@ -92,8 +92,8 @@ class VideoSender : public base::NonThreadSafe, void SendEncodedVideoFrame(const EncodedVideoFrame* video_frame, const base::TimeTicks& capture_time); - void ResendFrame(uint8 resend_frame_id); - void ReceivedAck(uint8 acked_frame_id); + void ResendFrame(uint32 resend_frame_id); + void ReceivedAck(uint32 acked_frame_id); void UpdateFramesInFlight(); void SendEncodedVideoFrameMainThread( |