1d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org/*
2d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *
4d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  Use of this source code is governed by a BSD-style license
5d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  that can be found in the LICENSE file in the root of the source
6d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  tree. An additional intellectual property rights grant can be found
7d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  in the file PATENTS.  All contributing project authors may
8d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org */
10d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
11d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
12d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
13d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org#if BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
14d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
153ecc162d010d9943925be27773f73b901904bff1pbos@webrtc.org#include <stdarg.h>
163ecc162d010d9943925be27773f73b901904bff1pbos@webrtc.org#include <stdio.h>
173ecc162d010d9943925be27773f73b901904bff1pbos@webrtc.org
18d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org#include <algorithm>
19dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer#include <sstream>
20d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
21dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi#include "webrtc/base/platform_thread.h"
2298f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
23d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
24d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgnamespace webrtc {
25d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgnamespace testing {
26d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgnamespace bwe {
27d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
28d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging Logging::g_Logging;
29d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
30c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgstatic std::string ToString(uint32_t v) {
31dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer  std::stringstream ss;
32dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer  ss << v;
33dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer  return ss.str();
34c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
35c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
36c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgLogging::Context::Context(uint32_t name, int64_t timestamp_ms, bool enabled) {
37c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  Logging::GetInstance()->PushState(ToString(name), timestamp_ms, enabled);
38d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
39d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
40d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging::Context::Context(const std::string& name, int64_t timestamp_ms,
41d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org                          bool enabled) {
42c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  Logging::GetInstance()->PushState(name, timestamp_ms, enabled);
43d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
44d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
45d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging::Context::Context(const char* name, int64_t timestamp_ms,
46d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org                          bool enabled) {
47d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  Logging::GetInstance()->PushState(name, timestamp_ms, enabled);
48d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
49d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
50d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging::Context::~Context() {
51d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  Logging::GetInstance()->PopState();
52d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
53d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
54d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging* Logging::GetInstance() {
55d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  return &g_Logging;
56d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
57d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
58c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::SetGlobalContext(uint32_t name) {
59c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
60dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  thread_map_[rtc::CurrentThreadId()].global_state.tag = ToString(name);
61c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
62c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
63c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::SetGlobalContext(const std::string& name) {
64c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
65dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  thread_map_[rtc::CurrentThreadId()].global_state.tag = name;
66c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
67c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
68c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::SetGlobalContext(const char* name) {
69c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
70dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  thread_map_[rtc::CurrentThreadId()].global_state.tag = name;
71c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
72c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
73c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::SetGlobalEnable(bool enabled) {
74c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
75dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  thread_map_[rtc::CurrentThreadId()].global_state.enabled = enabled;
76c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
77c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
78d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgvoid Logging::Log(const char format[], ...) {
79d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
80dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
81d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  assert(it != thread_map_.end());
82c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  const State& state = it->second.stack.top();
83d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  if (state.enabled) {
84d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    printf("%s\t", state.tag.c_str());
85d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    va_list args;
86d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    va_start(args, format);
87d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    vprintf(format, args);
88d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    va_end(args);
89d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    printf("\n");
90d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  }
91d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
92d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
93dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmervoid Logging::Plot(int figure, double value) {
94d55ce2ddb9eb67e237725820b751f404df6dba0dCesar Magalhaes  Plot(figure, value, "-");
959c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
969c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
979c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::Plot(int figure, double value, const std::string& alg_name) {
98d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
99dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
100d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  assert(it != thread_map_.end());
101c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  const State& state = it->second.stack.top();
1029c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  std::string label = state.tag + '@' + alg_name;
1039c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  std::string prefix("Available");
1049c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (alg_name.compare(0, prefix.length(), prefix) == 0) {
1059c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    std::string receiver("Receiver");
1069c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    size_t start_pos = label.find(receiver);
1079c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    if (start_pos != std::string::npos) {
1089c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes      label.replace(start_pos, receiver.length(), "Sender");
1099c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    }
1109c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
111d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  if (state.enabled) {
1129c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("PLOT\t%d\t%s\t%f\t%f\n", figure, label.c_str(),
113dcbd3acbef881b0e6a5d459c6f6b7c7080eb1a20Stefan Holmer           state.timestamp_ms * 0.001, value);
114d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  }
115d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
116d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
1179c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::PlotBar(int figure,
1189c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                      const std::string& name,
1199c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                      double value,
1209c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                      int flow_id) {
1219c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  CriticalSectionScoped cs(crit_sect_.get());
122dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
1239c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  assert(it != thread_map_.end());
1249c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const State& state = it->second.stack.top();
1259c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (state.enabled) {
1269c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("BAR\t%d\t%s_%d\t%f\n", figure, name.c_str(), flow_id, value);
1279c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
1289c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1299c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1309c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::PlotBaselineBar(int figure,
1319c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                              const std::string& name,
1329c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                              double value,
1339c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                              int flow_id) {
1349c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  CriticalSectionScoped cs(crit_sect_.get());
135dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
1369c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  assert(it != thread_map_.end());
1379c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const State& state = it->second.stack.top();
1389c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (state.enabled) {
1399c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("BASELINE\t%d\t%s_%d\t%f\n", figure, name.c_str(), flow_id, value);
1409c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
1419c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1429c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1439c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::PlotErrorBar(int figure,
1449c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           const std::string& name,
1459c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           double value,
1469c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           double ylow,
1479c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           double yhigh,
1489c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           const std::string& error_title,
1499c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                           int flow_id) {
1509c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  CriticalSectionScoped cs(crit_sect_.get());
151dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
1529c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  assert(it != thread_map_.end());
1539c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const State& state = it->second.stack.top();
1549c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (state.enabled) {
1559c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("ERRORBAR\t%d\t%s_%d\t%f\t%f\t%f\t%s\n", figure, name.c_str(),
1569c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes           flow_id, value, ylow, yhigh, error_title.c_str());
1579c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
1589c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1599c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1609c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::PlotLimitErrorBar(int figure,
1619c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                const std::string& name,
1629c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                double value,
1639c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                double ylow,
1649c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                double yhigh,
1659c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                const std::string& error_title,
1669c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                double ymax,
1679c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                const std::string& limit_title,
1689c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                                int flow_id) {
1699c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  CriticalSectionScoped cs(crit_sect_.get());
170dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
1719c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  assert(it != thread_map_.end());
1729c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const State& state = it->second.stack.top();
1739c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (state.enabled) {
1749c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("LIMITERRORBAR\t%d\t%s_%d\t%f\t%f\t%f\t%s\t%f\t%s\n", figure,
1759c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes           name.c_str(), flow_id, value, ylow, yhigh, error_title.c_str(), ymax,
1769c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes           limit_title.c_str());
1779c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
1789c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1799c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
1809c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaesvoid Logging::PlotLabel(int figure,
1819c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                        const std::string& title,
1829c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                        const std::string& y_label,
1839c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes                        int num_flows) {
1849c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  CriticalSectionScoped cs(crit_sect_.get());
185dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
1869c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  assert(it != thread_map_.end());
1879c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  const State& state = it->second.stack.top();
1889c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  if (state.enabled) {
1899c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes    printf("LABEL\t%d\t%s\t%s\t%d\n", figure, title.c_str(), y_label.c_str(),
1909c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes           num_flows);
1919c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes  }
1929c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes}
1939c261f2d13793fbb5a0d07b26bec4154bc38342bCesar Magalhaes
194d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgLogging::Logging()
195d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
196d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org      thread_map_() {
197d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
198d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
199c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgLogging::State::State() : tag(""), timestamp_ms(0), enabled(true) {}
200c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
201c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgLogging::State::State(const std::string& tag, int64_t timestamp_ms,
202c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org                      bool enabled)
203c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    : tag(tag),
204c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org      timestamp_ms(timestamp_ms),
205c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org      enabled(enabled) {
206c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
207c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
208c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::State::MergePrevious(const State& previous) {
209bb36fdf95f9667fb1f3fbf3073bd15007681322cpbos  if (tag.empty()) {
210c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    tag = previous.tag;
211bb36fdf95f9667fb1f3fbf3073bd15007681322cpbos  } else if (!previous.tag.empty()) {
212c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    tag = previous.tag + "_" + tag;
213c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  }
214c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  timestamp_ms = std::max(previous.timestamp_ms, timestamp_ms);
215c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  enabled = previous.enabled && enabled;
216c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org}
217c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org
218c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.orgvoid Logging::PushState(const std::string& append_to_tag, int64_t timestamp_ms,
219d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org                        bool enabled) {
220d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
221c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  State new_state(append_to_tag, timestamp_ms, enabled);
222dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadState* thread_state = &thread_map_[rtc::CurrentThreadId()];
223c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  std::stack<State>* stack = &thread_state->stack;
224d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  if (stack->empty()) {
225c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    new_state.MergePrevious(thread_state->global_state);
226d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  } else {
227c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    new_state.MergePrevious(stack->top());
228d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  }
229c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  stack->push(new_state);
230d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
231d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
232d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.orgvoid Logging::PopState() {
233d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  CriticalSectionScoped cs(crit_sect_.get());
234dfafd124186bcecfd1b3b18c24ce495972e4b50cTommi  ThreadMap::iterator it = thread_map_.find(rtc::CurrentThreadId());
235d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  assert(it != thread_map_.end());
236c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  std::stack<State>* stack = &it->second.stack;
237c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  int64_t newest_timestamp_ms = stack->top().timestamp_ms;
238c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  stack->pop();
239c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org  if (!stack->empty()) {
240c8f76ddc19d81a70c1aa577d82a0189ec58b29e0solenberg@webrtc.org    State* state = &stack->top();
241d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    // Update time so that next log/plot will use the latest time seen so far
242d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    // in this call tree.
243d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org    state->timestamp_ms = std::max(state->timestamp_ms, newest_timestamp_ms);
244d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org  }
245d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}
246d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}  // namespace bwe
247d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}  // namespace testing
248d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org}  // namespace webrtc
249d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org
250d6e46638ec77329de634b7592623bb53f59e47b4solenberg@webrtc.org#endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
251