Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: media/cast/framer/frame_id_map.cc

Issue 23467003: Added framer to cast. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rtcp
Patch Set: Addressed comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/cast/framer/frame_id_map.cc
diff --git a/media/cast/framer/frame_id_map.cc b/media/cast/framer/frame_id_map.cc
new file mode 100644
index 0000000000000000000000000000000000000000..209ece8affda6b10ec4cb5d8b5b12355c43dd3cb
--- /dev/null
+++ b/media/cast/framer/frame_id_map.cc
@@ -0,0 +1,252 @@
+// 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/framer/frame_id_map.h"
+
+#include "base/logging.h"
+#include "media/cast/rtp_common/rtp_defines.h"
+
+namespace media {
+namespace cast {
+
+FrameInfo::FrameInfo(uint8 frame_id,
+ uint8 referenced_frame_id,
+ uint16 max_packet_id,
+ bool key_frame)
+ : is_key_frame_(key_frame),
+ frame_id_(frame_id),
+ referenced_frame_id_(referenced_frame_id),
+ max_received_packet_id_(0) {
+ if (max_packet_id > 0) {
+ // Create the set with all packets missing.
+ for (uint16 i = 0; i <= max_packet_id; i++) {
+ missing_packets_.insert(i);
+ }
+ }
+}
+
+FrameInfo::~FrameInfo() {}
+
+bool FrameInfo::InsertPacket(uint16 packet_id) {
+ // Update the last received packet id.
+ if (IsNewerPacketId(packet_id, max_received_packet_id_)) {
+ max_received_packet_id_ = packet_id;
+ }
+ missing_packets_.erase(packet_id);
+ return missing_packets_.empty();
+}
+
+bool FrameInfo::Complete() const {
+ return missing_packets_.empty();
+}
+
+void FrameInfo::GetMissingPackets(bool newest_frame,
+ PacketIdSet* missing_packets) const {
+ if (newest_frame) {
+ // Missing packets capped by max_received_packet_id_.
+ PacketIdSet::const_iterator it_after_last_received =
+ missing_packets_.lower_bound(max_received_packet_id_);
+ missing_packets->insert(missing_packets_.begin(), it_after_last_received);
+ } else {
+ missing_packets->insert(missing_packets_.begin(), missing_packets_.end());
+ }
+}
+
+
+FrameIdMap::FrameIdMap()
+ : waiting_for_key_(true),
+ last_released_frame_(kStartFrameId),
+ newest_frame_id_(kStartFrameId) {
+}
+
+FrameIdMap::~FrameIdMap() {}
+
+bool FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header, bool* complete) {
+ uint8 frame_id = rtp_header.frame_id;
+ uint8 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);
+ }
+
+ if (rtp_header.is_key_frame && waiting_for_key_) {
+ last_released_frame_ = static_cast<uint8>(frame_id - 1);
+ waiting_for_key_ = false;
+ }
+
+ if (IsOlderFrameId(frame_id, last_released_frame_) && !waiting_for_key_) {
+ return false;
+ }
+
+ // Update the last received frame id.
+ if (IsNewerFrameId(frame_id, newest_frame_id_)) {
+ newest_frame_id_ = frame_id;
+ }
+
+ // Does this packet belong to a new frame?
+ FrameMap::iterator it = frame_map_.find(frame_id);
+ if (it == frame_map_.end()) {
+ // New frame.
+ FrameInfo* frame_info = new FrameInfo(frame_id,
Alpha Left Google 2013/08/28 19:13:48 Should be linked_ptr<FrameInfo> frame_info = ...
pwestin 2013/08/28 20:37:21 Done.
+ reference_frame_id,
+ rtp_header.max_packet_id,
+ rtp_header.is_key_frame);
+ std::pair<FrameMap::iterator, bool> retval =
+ frame_map_.insert(std::make_pair(frame_id, frame_info));
+
+ *complete = retval.first->second->InsertPacket(rtp_header.packet_id);
+ } else {
+ // Insert packet to existing frame.
+ *complete = it->second->InsertPacket(rtp_header.packet_id);
+ }
+ return true;
+}
+
+void FrameIdMap::RemoveOldFrames(uint8 frame_id) {
+ FrameMap::iterator it = frame_map_.begin();
+
+ while (it != frame_map_.end()) {
+ if (IsNewerFrameId(it->first, frame_id)) {
+ ++it;
+ } else {
+ // Older or equal; erase.
+ frame_map_.erase(it++);
+ }
+ }
+ last_released_frame_ = frame_id;
+}
+
+void FrameIdMap::Clear() {
+ frame_map_.clear();
+ waiting_for_key_ = true;
+ last_released_frame_ = kStartFrameId;
+ newest_frame_id_ = kStartFrameId;
+}
+
+uint8 FrameIdMap::NewestFrameId() const {
+ return newest_frame_id_;
+}
+
+bool FrameIdMap::NextContinuousFrame(uint8* frame_id) const {
+ FrameMap::const_iterator it;
+
+ for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
+ if (it->second->Complete() && ContinuousFrame(it->second.get())) {
+ *frame_id = it->first;
+ return true;
+ }
+ }
+ return false;
+}
+
+uint8 FrameIdMap::LastContinuousFrame() const {
+ uint8 last_continuous_frame_id = last_released_frame_;
+ uint8 next_expected_frame = last_released_frame_;
+
+ FrameMap::const_iterator it;
+
+ do {
+ next_expected_frame++;
+ it = frame_map_.find(next_expected_frame);
+ if (it == frame_map_.end()) break;
+ if (!it->second->Complete()) break;
+
+ // We found the next continuous frame.
+ last_continuous_frame_id = it->first;
+ } while (next_expected_frame != newest_frame_id_);
+ return last_continuous_frame_id;
+}
+
+bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint8* frame_id) const {
+ // First check if we have continuous frames.
+ if (NextContinuousFrame(frame_id)) return true;
+
+ // Find the oldest frame.
+ FrameMap::const_iterator it_best_match = frame_map_.end();
+ FrameMap::const_iterator it;
+
+ // Find first complete frame.
+ for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
+ if (it->second->Complete()) {
+ it_best_match = it;
+ break;
+ }
+ }
+ if (it_best_match == frame_map_.end()) return false; // No complete frame.
+
+ ++it;
+ for (; it != frame_map_.end(); ++it) {
+ if (it->second->Complete() &&
+ IsOlderFrameId(it->first, it_best_match->first)) {
+ it_best_match = it;
+ }
+ }
+ *frame_id = it_best_match->first;
+ return true;
+}
+
+bool FrameIdMap::NextVideoFrameAllowingSkippingFrames(uint8* frame_id) const {
+ // Find the oldest decodable frame.
+ FrameMap::const_iterator it_best_match = frame_map_.end();
+ FrameMap::const_iterator it;
+ for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
+ if (it->second->Complete() && DecodableVideoFrame(it->second.get())) {
+ it_best_match = it;
+ }
+ }
+ if (it_best_match == frame_map_.end()) return false;
+
+ *frame_id = it_best_match->first;
+ return true;
+}
+
+bool FrameIdMap::Empty() const {
+ return frame_map_.empty();
+}
+
+int FrameIdMap::NumberOfCompleteFrames() const {
+ int count = 0;
+ FrameMap::const_iterator it;
+ for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
+ if (it->second->Complete()) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+bool FrameIdMap::FrameExists(uint8 frame_id) const {
+ return frame_map_.end() != frame_map_.find(frame_id);
+}
+
+void FrameIdMap::GetMissingPackets(uint8 frame_id,
+ bool last_frame,
+ PacketIdSet* missing_packets) const {
+ FrameMap::const_iterator it = frame_map_.find(frame_id);
+ if (it == frame_map_.end()) return;
+
+ it->second->GetMissingPackets(last_frame, missing_packets);
+}
+
+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();
+}
+
+bool FrameIdMap::DecodableVideoFrame(FrameInfo* frame) const {
+ if (frame->is_key_frame()) return true;
+ if (waiting_for_key_ && !frame->is_key_frame()) return false;
+
+ // Current frame is not necessarily referencing the last frame.
+ // Do we have the reference frame?
+ if (IsOlderFrameId(frame->referenced_frame_id(), last_released_frame_)) {
+ return true;
+ }
+ return frame->referenced_frame_id() == last_released_frame_;
+}
+
+} // namespace cast
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698