summaryrefslogtreecommitdiffstats
path: root/media/cast/logging
diff options
context:
space:
mode:
Diffstat (limited to 'media/cast/logging')
-rw-r--r--media/cast/logging/logging.cc113
-rw-r--r--media/cast/logging/logging.gyp27
-rw-r--r--media/cast/logging/logging.h92
-rw-r--r--media/cast/logging/logging_defines.h88
-rw-r--r--media/cast/logging/logging_internal.cc79
-rw-r--r--media/cast/logging/logging_internal.h95
6 files changed, 494 insertions, 0 deletions
diff --git a/media/cast/logging/logging.cc b/media/cast/logging/logging.cc
new file mode 100644
index 0000000..ce68aa4
--- /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,
+ uint8 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,
+ uint8 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,
+ uint8 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,
+ uint8 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.gyp b/media/cast/logging/logging.gyp
new file mode 100644
index 0000000..d04ef6b
--- /dev/null
+++ b/media/cast/logging/logging.gyp
@@ -0,0 +1,27 @@
+# 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.
+
+
+{
+ 'targets': [
+ {
+ 'target_name': 'cast_logging',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '<(DEPTH)/',
+ ],
+ 'sources': [
+ 'logging.cc',
+ 'logging.h',
+ 'logging_defines.h',
+ 'logging_internal.cc',
+ 'logging_internal.h',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:base',
+ '<(DEPTH)/base/base.gyp:test_support_base',
+ ],
+ },
+ ], # targets
+} \ No newline at end of file
diff --git a/media/cast/logging/logging.h b/media/cast/logging/logging.h
new file mode 100644
index 0000000..426fe3a
--- /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.
+ 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,
+ uint8 frame_id);
+ // Size - Inserting the size implies that this is an encoded frame.
+ void InsertFrameEventWithSize(CastLoggingEvent event,
+ uint32 rtp_timestamp,
+ uint8 frame_id,
+ int frame_size);
+ // Render/playout delay
+ void InsertFrameEventWithDelay(CastLoggingEvent event,
+ uint32 rtp_timestamp,
+ uint8 frame_id,
+ base::TimeDelta delay);
+
+ // Insert a packet event.
+ void InsertPacketEvent(CastLoggingEvent event,
+ uint32 rtp_timestamp,
+ uint8 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
new file mode 100644
index 0000000..10c49dd
--- /dev/null
+++ b/media/cast/logging/logging_defines.h
@@ -0,0 +1,88 @@
+// 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_DEFINES_H_
+#define MEDIA_CAST_LOGGING_LOGGING_DEFINES_H_
+
+#include "base/logging.h"
+
+namespace media {
+namespace cast {
+
+enum CastLoggingEvent {
+ // Generic events.
+ kRtt,
+ kPacketLoss,
+ kJitter,
+ kAckReceived,
+ kAckSent,
+ kLastEvent,
+ // Audio sender.
+ kAudioFrameCaptured,
+ kAudioFrameEncoded,
+ // Audio receiver.
+ kAudioPlayoutDelay,
+ kAudioFrameDecoded,
+ // Video sender.
+ kVideoFrameCaptured,
+ kVideoFrameSentToEncoder,
+ kVideoFrameEncoded,
+ // Video receiver.
+ kVideoFrameDecoded,
+ kVideoRenderDelay,
+ // Send-side packet events.
+ kPacketSentToPacer,
+ kPacketSentToNetwork,
+ kPacketRetransmited,
+ // Receive-side packet events.
+ kPacketReceived,
+};
+
+std::string CastEnumToString(CastLoggingEvent event) {
+ switch (event) {
+ case(kRtt):
+ return "Rtt";
+ case(kPacketLoss):
+ return "PacketLoss";
+ case(kJitter):
+ return "Jitter";
+ case(kAckReceived):
+ return "AckReceived";
+ case(kAckSent):
+ return "AckSent";
+ case(kLastEvent):
+ return "LastEvent";
+ case(kAudioFrameCaptured):
+ return "AudioFrameCaptured";
+ case(kAudioFrameEncoded):
+ return "AudioFrameEncoded";
+ case(kAudioPlayoutDelay):
+ return "AudioPlayoutDelay";
+ case(kAudioFrameDecoded):
+ return "AudioFrameDecoded";
+ case(kVideoFrameCaptured):
+ return "VideoFrameCaptured";
+ case(kVideoFrameSentToEncoder):
+ return "VideoFrameSentToEncoder";
+ case(kVideoFrameEncoded):
+ return "VideoFrameEncoded";
+ case(kVideoFrameDecoded):
+ return "VideoFrameDecoded";
+ case(kVideoRenderDelay):
+ return "VideoRenderDelay";
+ case(kPacketSentToPacer):
+ return "PacketSentToPacer";
+ case(kPacketSentToNetwork):
+ return "PacketSentToNetwork";
+ case(kPacketRetransmited):
+ return "PacketRetransmited";
+ case(kPacketReceived):
+ return "PacketReceived";
+ }
+}
+
+} // namespace cast
+} // namespace media
+
+#endif // MEDIA_CAST_LOGGING_LOGGING_DEFINES_H_
diff --git a/media/cast/logging/logging_internal.cc b/media/cast/logging/logging_internal.cc
new file mode 100644
index 0000000..aec0c96
--- /dev/null
+++ b/media/cast/logging/logging_internal.cc
@@ -0,0 +1,79 @@
+// 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_internal.h"
+
+namespace media {
+namespace cast {
+
+FrameLogData::FrameLogData(base::TickClock* clock)
+ : clock_(clock),
+ frame_map_() {}
+
+FrameLogData::~FrameLogData() {}
+
+void FrameLogData::Insert(uint32 rtp_timestamp, uint8 frame_id) {
+ FrameEvent info;
+ InsertBase(rtp_timestamp, frame_id, info);
+}
+
+void FrameLogData::InsertWithSize(
+ uint32 rtp_timestamp, uint8 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) {
+ FrameEvent info;
+ info.delay_delta = delay;
+ InsertBase(rtp_timestamp, frame_id, info);
+}
+
+void FrameLogData::InsertBase(
+ uint32 rtp_timestamp, uint8 frame_id, FrameEvent info) {
+ info.timestamp = clock_->NowTicks();
+ info.frame_id = frame_id;
+ frame_map_.insert(std::make_pair(rtp_timestamp, info));
+}
+
+PacketLogData::PacketLogData(base::TickClock* clock)
+ : clock_(clock),
+ packet_map_() {}
+
+PacketLogData::~PacketLogData() {}
+
+void PacketLogData::Insert(uint32 rtp_timestamp,
+ uint8 frame_id, uint16 packet_id, uint16 max_packet_id, int size) {
+ PacketEvent info;
+ info.size = size;
+ info.max_packet_id = max_packet_id;
+ info.frame_id = frame_id;
+ info.timestamp = clock_->NowTicks();
+ // Is this a new frame?
+ PacketMap::iterator it = packet_map_.find(rtp_timestamp);
+ if (it == packet_map_.end()) {
+ // New rtp_timestamp id - create base packet map.
+ BasePacketMap base_map;
+ base_map.insert(std::make_pair(packet_id, info));
+ packet_map_.insert(std::make_pair(rtp_timestamp, base_map));
+ } else {
+ // Existing rtp_timestamp.
+ it->second.insert(std::make_pair(packet_id, info));
+ }
+}
+
+GenericLogData::GenericLogData(base::TickClock* clock)
+ : clock_(clock) {}
+
+GenericLogData::~GenericLogData() {}
+
+void GenericLogData::Insert(int data) {
+ data_.push_back(data);
+ timestamp_.push_back(clock_->NowTicks());
+}
+
+} // namespace cast
+} // namespace media
diff --git a/media/cast/logging/logging_internal.h b/media/cast/logging/logging_internal.h
new file mode 100644
index 0000000..0f787600
--- /dev/null
+++ b/media/cast/logging/logging_internal.h
@@ -0,0 +1,95 @@
+// 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_INTERNAL_H_
+#define MEDIA_CAST_LOGGING_LOGGING_INTERNAL_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/time/tick_clock.h"
+#include "base/time/time.h"
+
+namespace media {
+namespace cast {
+
+// TODO(mikhal): Consider storing only the delta time and not absolute time.
+struct FrameEvent {
+ uint8 frame_id;
+ int size;
+ base::TimeTicks timestamp;
+ base::TimeDelta delay_delta; // render/playout delay.
+};
+
+struct PacketEvent {
+ uint8 frame_id;
+ int max_packet_id;
+ int size;
+ base::TimeTicks timestamp;
+};
+
+// Frame and packet maps are sorted based on the rtp_timestamp.
+typedef std::map<uint32, FrameEvent> FrameMap;
+typedef std::map<uint16, PacketEvent> BasePacketMap;
+typedef std::map<uint32, BasePacketMap> PacketMap;
+
+class FrameLogData {
+ public:
+ explicit FrameLogData(base::TickClock* clock);
+ ~FrameLogData();
+ void Insert(uint32 rtp_timestamp, uint8 frame_id);
+ // Include size for encoded images (compute bitrate),
+ void InsertWithSize(uint32 rtp_timestamp, uint8 frame_id, int size);
+ // Include playout/render delay info.
+ void InsertWithDelay(
+ uint32 rtp_timestamp, uint8 frame_id, base::TimeDelta delay);
+ void Reset();
+
+ private:
+ void InsertBase(uint32 rtp_timestamp, uint8 frame_id, FrameEvent info);
+
+ base::TickClock* const clock_; // Not owned by this class.
+ FrameMap frame_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameLogData);
+};
+
+// TODO(mikhal): Should be able to handle packet bursts.
+class PacketLogData {
+ public:
+ explicit PacketLogData(base::TickClock* clock);
+ ~PacketLogData();
+ void Insert(uint32 rtp_timestamp, uint8 frame_id, uint16 packet_id,
+ uint16 max_packet_id, int size);
+ void Reset();
+
+ private:
+ base::TickClock* const clock_; // Not owned by this class.
+ PacketMap packet_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(PacketLogData);
+};
+
+class GenericLogData {
+ public:
+ explicit GenericLogData(base::TickClock* clock);
+ ~GenericLogData();
+ void Insert(int value);
+ void Reset();
+
+ private:
+ base::TickClock* const clock_; // Not owned by this class.
+ std::vector<int> data_;
+ std::vector<base::TimeTicks> timestamp_;
+
+ DISALLOW_COPY_AND_ASSIGN(GenericLogData);
+};
+
+
+} // namespace cast
+} // namespace media
+
+#endif // MEDIA_CAST_LOGGING_LOGGING_INTERNAL_H_