Commit 3c80d5d4 authored by imcheng@chromium.org's avatar imcheng@chromium.org

Cast: Implemented relative RTP timestamp in EncodingEventSubscriber.

- RTP timestamps in the maps of EncodingEventSubscribers (map keys, rtp timestamp fields in protos) are now relative to the first RTP timestamp seen since last Reset().
- The two GetXXXEventsAndReset() functions have been combined into one. In addition, it will now return the first RTP timestamp seen since the last Reset(). It will also reset the first RTP timestamp seen.
- There are two motivations for this change:
-- 1. RTP timestamps wrap around easily - around every 12 hours or so. If we do not use relative RTP timestamps, the ordering in the map, as well as general order of the events by frame, will be messed up.
-- 2. Using relative values will be more compact in variable-length encoding of the RTP timestamp fields.

Review URL: https://codereview.chromium.org/168933002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251973 0039d316-1c4b-4281-b951-d872f2087c98
parent b72c7323
...@@ -20,8 +20,12 @@ namespace media { ...@@ -20,8 +20,12 @@ namespace media {
namespace cast { namespace cast {
EncodingEventSubscriber::EncodingEventSubscriber( EncodingEventSubscriber::EncodingEventSubscriber(
EventMediaType event_media_type, size_t max_frames) EventMediaType event_media_type,
: event_media_type_(event_media_type), max_frames_(max_frames) {} size_t max_frames)
: event_media_type_(event_media_type),
max_frames_(max_frames),
seen_first_rtp_timestamp_(false),
first_rtp_timestamp_(0u) {}
EncodingEventSubscriber::~EncodingEventSubscriber() { EncodingEventSubscriber::~EncodingEventSubscriber() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
...@@ -32,16 +36,17 @@ void EncodingEventSubscriber::OnReceiveFrameEvent( ...@@ -32,16 +36,17 @@ void EncodingEventSubscriber::OnReceiveFrameEvent(
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
if (ShouldProcessEvent(frame_event.type)) { if (ShouldProcessEvent(frame_event.type)) {
FrameEventMap::iterator it = RtpTimestamp relative_rtp_timestamp =
frame_event_map_.find(frame_event.rtp_timestamp); GetRelativeRtpTimestamp(frame_event.rtp_timestamp);
FrameEventMap::iterator it = frame_event_map_.find(relative_rtp_timestamp);
linked_ptr<AggregatedFrameEvent> event_proto; linked_ptr<AggregatedFrameEvent> event_proto;
// Look up existing entry. If not found, create a new entry and add to map. // Look up existing entry. If not found, create a new entry and add to map.
if (it == frame_event_map_.end()) { if (it == frame_event_map_.end()) {
event_proto.reset(new AggregatedFrameEvent); event_proto.reset(new AggregatedFrameEvent);
event_proto->set_rtp_timestamp(frame_event.rtp_timestamp); event_proto->set_rtp_timestamp(relative_rtp_timestamp);
frame_event_map_.insert( frame_event_map_.insert(
std::make_pair(frame_event.rtp_timestamp, event_proto)); std::make_pair(relative_rtp_timestamp, event_proto));
} else { } else {
event_proto = it->second; event_proto = it->second;
} }
...@@ -69,17 +74,19 @@ void EncodingEventSubscriber::OnReceivePacketEvent( ...@@ -69,17 +74,19 @@ void EncodingEventSubscriber::OnReceivePacketEvent(
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
if (ShouldProcessEvent(packet_event.type)) { if (ShouldProcessEvent(packet_event.type)) {
RtpTimestamp relative_rtp_timestamp =
GetRelativeRtpTimestamp(packet_event.rtp_timestamp);
PacketEventMap::iterator it = PacketEventMap::iterator it =
packet_event_map_.find(packet_event.rtp_timestamp); packet_event_map_.find(relative_rtp_timestamp);
linked_ptr<AggregatedPacketEvent> event_proto; linked_ptr<AggregatedPacketEvent> event_proto;
BasePacketEvent* base_packet_event_proto = NULL; BasePacketEvent* base_packet_event_proto = NULL;
// Look up existing entry. If not found, create a new entry and add to map. // Look up existing entry. If not found, create a new entry and add to map.
if (it == packet_event_map_.end()) { if (it == packet_event_map_.end()) {
event_proto.reset(new AggregatedPacketEvent); event_proto.reset(new AggregatedPacketEvent);
event_proto->set_rtp_timestamp(packet_event.rtp_timestamp); event_proto->set_rtp_timestamp(relative_rtp_timestamp);
packet_event_map_.insert( packet_event_map_.insert(
std::make_pair(packet_event.rtp_timestamp, event_proto)); std::make_pair(relative_rtp_timestamp, event_proto));
base_packet_event_proto = event_proto->add_base_packet_event(); base_packet_event_proto = event_proto->add_base_packet_event();
base_packet_event_proto->set_packet_id(packet_event.packet_id); base_packet_event_proto->set_packet_id(packet_event.packet_id);
} else { } else {
...@@ -120,21 +127,18 @@ void EncodingEventSubscriber::OnReceiveGenericEvent( ...@@ -120,21 +127,18 @@ void EncodingEventSubscriber::OnReceiveGenericEvent(
// Do nothing, there are no generic events we are interested in. // Do nothing, there are no generic events we are interested in.
} }
void EncodingEventSubscriber::GetFrameEventsAndReset( void EncodingEventSubscriber::GetEventsAndReset(
FrameEventMap* frame_event_map) { FrameEventMap* frame_events,
PacketEventMap* packet_events,
RtpTimestamp* first_rtp_timestamp) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
frame_event_map->swap(frame_event_map_);
frame_event_map_.clear();
}
void EncodingEventSubscriber::GetPacketEventsAndReset( frame_events->swap(frame_event_map_);
PacketEventMap* packet_event_map) { packet_events->swap(packet_event_map_);
DCHECK(thread_checker_.CalledOnValidThread()); *first_rtp_timestamp = first_rtp_timestamp_;
packet_event_map->swap(packet_event_map_); Reset();
packet_event_map_.clear();
} }
bool EncodingEventSubscriber::ShouldProcessEvent(CastLoggingEvent event) { bool EncodingEventSubscriber::ShouldProcessEvent(CastLoggingEvent event) {
return GetEventMediaType(event) == event_media_type_; return GetEventMediaType(event) == event_media_type_;
} }
...@@ -153,5 +157,22 @@ void EncodingEventSubscriber::TruncatePacketEventMapIfNeeded() { ...@@ -153,5 +157,22 @@ void EncodingEventSubscriber::TruncatePacketEventMapIfNeeded() {
packet_event_map_.erase(packet_event_map_.begin()); packet_event_map_.erase(packet_event_map_.begin());
} }
RtpTimestamp EncodingEventSubscriber::GetRelativeRtpTimestamp(
RtpTimestamp rtp_timestamp) {
if (!seen_first_rtp_timestamp_) {
seen_first_rtp_timestamp_ = true;
first_rtp_timestamp_ = rtp_timestamp;
}
return rtp_timestamp - first_rtp_timestamp_;
}
void EncodingEventSubscriber::Reset() {
frame_event_map_.clear();
packet_event_map_.clear();
seen_first_rtp_timestamp_ = false;
first_rtp_timestamp_ = 0u;
}
} // namespace cast } // namespace cast
} // namespace media } // namespace media
...@@ -46,13 +46,18 @@ class EncodingEventSubscriber : public RawEventSubscriber { ...@@ -46,13 +46,18 @@ class EncodingEventSubscriber : public RawEventSubscriber {
virtual void OnReceiveGenericEvent(const GenericEvent& generic_event) virtual void OnReceiveGenericEvent(const GenericEvent& generic_event)
OVERRIDE; OVERRIDE;
// Assigns frame events received so far to |frame_events| and clears them // Assigns frame events and packet events received so far to |frame_events|
// from this object. // and clears them |packet_events| respectively, assigns the first seen RTP
void GetFrameEventsAndReset(FrameEventMap* frame_events); // timestamp (which is used as a reference for all event entries) to
// |first_rtp_timestamp|, and reset this object's internal states.
// Assigns packet events received so far to |packet_events| and clears them // All RTP timestamp values returned in the maps are relative to
// from this object. // |first_rtp_timestamp|, i.e. suppose |first_rtp_timestamp| is X,
void GetPacketEventsAndReset(PacketEventMap* packet_events); // then the first event will be recorded with a relative
// RTP timestamp value of 0. If the next event has original RTP timestamp
// X+20, it will be recorded with a relative RTP timestamp of 20.
void GetEventsAndReset(FrameEventMap* frame_events,
PacketEventMap* packet_events,
RtpTimestamp* first_rtp_timestamp);
private: private:
bool ShouldProcessEvent(CastLoggingEvent event); bool ShouldProcessEvent(CastLoggingEvent event);
...@@ -63,6 +68,13 @@ class EncodingEventSubscriber : public RawEventSubscriber { ...@@ -63,6 +68,13 @@ class EncodingEventSubscriber : public RawEventSubscriber {
// Removes oldest entry from |packet_event_map_| (ordered by RTP timestamp). // Removes oldest entry from |packet_event_map_| (ordered by RTP timestamp).
void TruncatePacketEventMapIfNeeded(); void TruncatePacketEventMapIfNeeded();
// Returns the difference between |rtp_timestamp| and |first_rtp_timestamp_|.
// Sets |first_rtp_timestamp_| if it is not already set.
RtpTimestamp GetRelativeRtpTimestamp(RtpTimestamp rtp_timestamp);
// Clears the maps and first RTP timestamp seen.
void Reset();
const EventMediaType event_media_type_; const EventMediaType event_media_type_;
const size_t max_frames_; const size_t max_frames_;
...@@ -72,6 +84,12 @@ class EncodingEventSubscriber : public RawEventSubscriber { ...@@ -72,6 +84,12 @@ class EncodingEventSubscriber : public RawEventSubscriber {
// All functions must be called on the main thread. // All functions must be called on the main thread.
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
// Set to true on first event encountered after a |Reset()|.
bool seen_first_rtp_timestamp_;
// Set to RTP timestamp of first event encountered after a |Reset()|.
RtpTimestamp first_rtp_timestamp_;
DISALLOW_COPY_AND_ASSIGN(EncodingEventSubscriber); DISALLOW_COPY_AND_ASSIGN(EncodingEventSubscriber);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment