1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
113bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
12c4e10b884294e4622e2470235489809a7bd73a1epbos@webrtc.org#include "webrtc/modules/video_processing/main/source/video_processing_impl.h"
13c4e10b884294e4622e2470235489809a7bd73a1epbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
149402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
163f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h>
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
20b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgnamespace {
21b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid  SetSubSampling(VideoProcessingModule::FrameStats* stats,
22b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                     const int32_t width,
23b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                     const int32_t height) {
24b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  if (width * height >= 640 * 480) {
25b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplWidth = 3;
26b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplHeight = 3;
27b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  } else if (width * height >= 352 * 288) {
28b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplWidth = 2;
29b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplHeight = 2;
30b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  } else if (width * height >= 176 * 144) {
31b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplWidth = 1;
32b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplHeight = 1;
33b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  } else {
34b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplWidth = 0;
35b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    stats->subSamplHeight = 0;
36b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  }
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
38b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org}  // namespace
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
40b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgVideoProcessingModule* VideoProcessingModule::Create(const int32_t id) {
41b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return new VideoProcessingModuleImpl(id);
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
44b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModule::Destroy(VideoProcessingModule* module) {
45b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  if (module)
46b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    delete static_cast<VideoProcessingModuleImpl*>(module);
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::ChangeUniqueId(const int32_t id) {
50b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
51b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  id_ = id;
52b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  brightness_detection_.ChangeUniqueId(id);
53b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  deflickering_.ChangeUniqueId(id);
54b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.ChangeUniqueId(id);
55b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return VPM_OK;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
58b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::Id() const {
59b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
60b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return id_;
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
63b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgVideoProcessingModuleImpl::VideoProcessingModuleImpl(const int32_t id)
64b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    : id_(id),
65b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    mutex_(*CriticalSectionWrapper::CreateCriticalSection()) {
66b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  brightness_detection_.ChangeUniqueId(id);
67b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  deflickering_.ChangeUniqueId(id);
68b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.ChangeUniqueId(id);
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgVideoProcessingModuleImpl::~VideoProcessingModuleImpl() {
72b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  delete &mutex_;
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
75b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModuleImpl::Reset() {
76b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
77b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  deflickering_.Reset();
78b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  brightness_detection_.Reset();
79b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.Reset();
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
82b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModule::GetFrameStats(FrameStats* stats,
83b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                                             const I420VideoFrame& frame) {
84b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  if (frame.IsZeroSize()) {
859402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org    LOG(LS_ERROR) << "Zero size frame.";
86b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    return VPM_PARAMETER_ERROR;
87b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  }
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
89b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  int width = frame.width();
90b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  int height = frame.height();
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  ClearFrameStats(stats);  // The histogram needs to be zeroed out.
93b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  SetSubSampling(stats, width, height);
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
95b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  const uint8_t* buffer = frame.buffer(kYPlane);
96b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  // Compute histogram and sum of frame
97b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  for (int i = 0; i < height; i += (1 << stats->subSamplHeight)) {
98b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    int k = i * width;
99b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    for (int j = 0; j < width; j += (1 << stats->subSamplWidth)) {
100b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org      stats->hist[buffer[k + j]]++;
101b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org      stats->sum += buffer[k + j];
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
103b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  }
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
105b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->num_pixels = (width * height) / ((1 << stats->subSamplWidth) *
106b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                     (1 << stats->subSamplHeight));
107b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  assert(stats->num_pixels > 0);
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
109b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  // Compute mean value of frame
110b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->mean = stats->sum / stats->num_pixels;
111b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org
112b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return VPM_OK;
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
115b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgbool VideoProcessingModule::ValidFrameStats(const FrameStats& stats) {
1169402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org  if (stats.num_pixels == 0) {
1179402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org    LOG(LS_WARNING) << "Invalid frame stats.";
1189402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org    return false;
1199402619982e7ab5113d4d2a6fb2cbdf8d50f4f65asapersson@webrtc.org  }
120b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return true;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModule::ClearFrameStats(FrameStats* stats) {
124b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->mean = 0;
125b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->sum = 0;
126b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->num_pixels = 0;
127b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->subSamplWidth = 0;
128b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  stats->subSamplHeight = 0;
129b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  memset(stats->hist, 0, sizeof(stats->hist));
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
132b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModule::ColorEnhancement(I420VideoFrame* frame) {
133b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return VideoProcessing::ColorEnhancement(frame);
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModule::Brighten(I420VideoFrame* frame, int delta) {
137b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return VideoProcessing::Brighten(frame, delta);
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
140b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::Deflickering(I420VideoFrame* frame,
141b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                                                FrameStats* stats) {
142b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
143b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return deflickering_.ProcessFrame(frame, stats);
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
146b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::BrightnessDetection(
147b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  const I420VideoFrame& frame,
148b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  const FrameStats& stats) {
149b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
150b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return brightness_detection_.ProcessFrame(frame, stats);
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
154b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModuleImpl::EnableTemporalDecimation(bool enable) {
155b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
156b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.EnableTemporalDecimation(enable);
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
160b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModuleImpl::SetInputFrameResampleMode(VideoFrameResampling
161b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                                                          resampling_mode) {
162b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped cs(&mutex_);
163b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.SetInputFrameResampleMode(resampling_mode);
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::SetTargetResolution(uint32_t width,
167b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                                                       uint32_t height,
168b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org                                                       uint32_t frame_rate) {
169b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped cs(&mutex_);
170b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return frame_pre_processor_.SetTargetResolution(width, height, frame_rate);
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
173b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orguint32_t VideoProcessingModuleImpl::Decimatedframe_rate() {
174b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped cs(&mutex_);
175b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return  frame_pre_processor_.Decimatedframe_rate();
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orguint32_t VideoProcessingModuleImpl::DecimatedWidth() const {
179b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped cs(&mutex_);
180b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return frame_pre_processor_.DecimatedWidth();
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
183b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orguint32_t VideoProcessingModuleImpl::DecimatedHeight() const {
184b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped cs(&mutex_);
185b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return frame_pre_processor_.DecimatedHeight();
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgint32_t VideoProcessingModuleImpl::PreprocessFrame(
189b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    const I420VideoFrame& frame,
190b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org    I420VideoFrame **processed_frame) {
191b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
192b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return frame_pre_processor_.PreprocessFrame(frame, processed_frame);
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
195b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgVideoContentMetrics* VideoProcessingModuleImpl::ContentMetrics() const {
196b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
197b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  return frame_pre_processor_.ContentMetrics();
198b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org}
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
200b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.orgvoid VideoProcessingModuleImpl::EnableContentAnalysis(bool enable) {
201b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  CriticalSectionScoped mutex(&mutex_);
202b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org  frame_pre_processor_.EnableContentAnalysis(enable);
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
205b576a696e444c2873191463dcf03de1a82a50dd4mikhal@webrtc.org}  // namespace webrtc
206