summaryrefslogtreecommitdiffstats
path: root/media/webrtc/signaling/src/common
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /media/webrtc/signaling/src/common
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'media/webrtc/signaling/src/common')
-rw-r--r--media/webrtc/signaling/src/common/CommonTypes.h63
-rw-r--r--media/webrtc/signaling/src/common/EncodingConstraints.h58
-rwxr-xr-xmedia/webrtc/signaling/src/common/MediaEngineWrapper.h39
-rw-r--r--media/webrtc/signaling/src/common/NullDeleter.h16
-rw-r--r--media/webrtc/signaling/src/common/NullTransport.h44
-rw-r--r--media/webrtc/signaling/src/common/PtrVector.h43
-rw-r--r--media/webrtc/signaling/src/common/Wrapper.h175
-rw-r--r--media/webrtc/signaling/src/common/YuvStamper.cpp469
-rw-r--r--media/webrtc/signaling/src/common/YuvStamper.h83
-rw-r--r--media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp103
-rw-r--r--media/webrtc/signaling/src/common/browser_logging/CSFLog.h50
-rw-r--r--media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp258
-rw-r--r--media/webrtc/signaling/src/common/browser_logging/WebRtcLog.h16
-rw-r--r--media/webrtc/signaling/src/common/csf_common.h79
-rw-r--r--media/webrtc/signaling/src/common/time_profiling/timecard.c125
-rw-r--r--media/webrtc/signaling/src/common/time_profiling/timecard.h81
16 files changed, 1702 insertions, 0 deletions
diff --git a/media/webrtc/signaling/src/common/CommonTypes.h b/media/webrtc/signaling/src/common/CommonTypes.h
new file mode 100644
index 000000000..96f1f3423
--- /dev/null
+++ b/media/webrtc/signaling/src/common/CommonTypes.h
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#pragma once
+
+
+#include <string>
+
+namespace csf
+{
+
+namespace ProviderStateEnum
+{
+ enum ProviderState
+ {
+ Ready,
+ Registering,
+ AwaitingIpAddress,
+ FetchingDeviceConfig,
+ Idle,
+ RecoveryPending,
+ Connected
+ };
+ const std::string toString(ProviderState);
+}
+namespace LoginErrorStatusEnum
+{
+ enum LoginErrorStatus {
+ Ok, // No Error
+ Unknown, // Unknown Error
+ NoCallManagerConfigured, // No Primary or Backup Call Manager
+ NoDevicesFound, // No devices
+ NoCsfDevicesFound, // Devices but none of type CSF
+ PhoneConfigGenError, // Could not generate phone config
+ SipProfileGenError, // Could not build SIP profile
+ ConfigNotSet, // Config not set before calling login()
+ CreateConfigProviderFailed, // Could not create ConfigProvider
+ CreateSoftPhoneProviderFailed, // Could not create SoftPhoneProvider
+ MissingUsername, // Username argument missing,
+ ManualLogout, // logout() has been called
+ LoggedInElseWhere, // Another process has the mutex indicating it is logged in
+ AuthenticationFailure, // Authentication failure (probably bad password, but best not to say for sure)
+ CtiCouldNotConnect, // Could not connect to CTI service
+ InvalidServerSearchList
+ };
+ const std::string toString(LoginErrorStatus);
+}
+
+namespace ErrorCodeEnum
+{
+ enum ErrorCode
+ {
+ Ok,
+ Unknown,
+ InvalidState,
+ InvalidArgument
+ };
+ const std::string toString(ErrorCode);
+}
+
+} // namespace csf
+
diff --git a/media/webrtc/signaling/src/common/EncodingConstraints.h b/media/webrtc/signaling/src/common/EncodingConstraints.h
new file mode 100644
index 000000000..efba7c51c
--- /dev/null
+++ b/media/webrtc/signaling/src/common/EncodingConstraints.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _ENCODING_CONSTRAINTS_H_
+#define _ENCODING_CONSTRAINTS_H_
+
+#include <algorithm>
+
+namespace mozilla
+{
+class EncodingConstraints
+{
+public:
+ EncodingConstraints() :
+ maxWidth(0),
+ maxHeight(0),
+ maxFps(0),
+ maxFs(0),
+ maxBr(0),
+ maxPps(0),
+ maxMbps(0),
+ maxCpb(0),
+ maxDpb(0),
+ scaleDownBy(1.0)
+ {}
+
+ bool operator==(const EncodingConstraints& constraints) const
+ {
+ return
+ maxWidth == constraints.maxWidth &&
+ maxHeight == constraints.maxHeight &&
+ maxFps == constraints.maxFps &&
+ maxFs == constraints.maxFs &&
+ maxBr == constraints.maxBr &&
+ maxPps == constraints.maxPps &&
+ maxMbps == constraints.maxMbps &&
+ maxCpb == constraints.maxCpb &&
+ maxDpb == constraints.maxDpb &&
+ scaleDownBy == constraints.scaleDownBy;
+ }
+
+ uint32_t maxWidth;
+ uint32_t maxHeight;
+ uint32_t maxFps;
+ uint32_t maxFs;
+ uint32_t maxBr;
+ uint32_t maxPps;
+ uint32_t maxMbps; // macroblocks per second
+ uint32_t maxCpb; // coded picture buffer size
+ uint32_t maxDpb; // decoded picture buffer size
+ double scaleDownBy; // To preserve resolution
+};
+} // namespace mozilla
+
+#endif // _ENCODING_CONSTRAINTS_H_
diff --git a/media/webrtc/signaling/src/common/MediaEngineWrapper.h b/media/webrtc/signaling/src/common/MediaEngineWrapper.h
new file mode 100755
index 000000000..f9b1a3415
--- /dev/null
+++ b/media/webrtc/signaling/src/common/MediaEngineWrapper.h
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MEDIA_ENGINE_WRAPPER_H_
+#define MEDIA_ENGINE_WRAPPER_H_
+
+#include <mozilla/Scoped.h>
+
+
+
+namespace mozilla
+{
+/**
+ * A Custom scoped template to release a resoure of Type T
+ * with a function of Type F
+ * ScopedCustomReleasePtr<webrtc::VoENetwork> ptr =
+ * webrtc::VoENetwork->GetInterface(voiceEngine);
+ *
+ */
+template<typename T>
+struct ScopedCustomReleaseTraits0
+{
+ typedef T* type;
+ static T* empty() { return nullptr; }
+ static void release(T* ptr)
+ {
+ if(ptr)
+ {
+ (ptr)->Release();
+ }
+ }
+};
+
+SCOPED_TEMPLATE(ScopedCustomReleasePtr, ScopedCustomReleaseTraits0)
+}//namespace
+
+
+#endif
diff --git a/media/webrtc/signaling/src/common/NullDeleter.h b/media/webrtc/signaling/src/common/NullDeleter.h
new file mode 100644
index 000000000..9b4628390
--- /dev/null
+++ b/media/webrtc/signaling/src/common/NullDeleter.h
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#pragma once
+
+/*
+ * Helper class to allow smart pointers to stack objects to be constructed for ease of unit testing.
+ * Recycled here to help expose a shared_ptr interface to objects which are really raw pointers.
+ */
+struct null_deleter
+{
+ void operator()(void const *) const
+ {
+ }
+};
diff --git a/media/webrtc/signaling/src/common/NullTransport.h b/media/webrtc/signaling/src/common/NullTransport.h
new file mode 100644
index 000000000..bce793304
--- /dev/null
+++ b/media/webrtc/signaling/src/common/NullTransport.h
@@ -0,0 +1,44 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#ifndef NULL_TRANSPORT_H_
+#define NULL_TRANSPORT_H_
+
+#include "mozilla/Attributes.h"
+
+#include "webrtc/common_types.h"
+
+namespace mozilla {
+
+/**
+ * NullTransport is registered as ExternalTransport to throw away data
+ */
+class NullTransport : public webrtc::Transport
+{
+public:
+ virtual int SendPacket(int channel, const void *data, size_t len)
+ {
+ (void) channel; (void) data;
+ return len;
+ }
+
+ virtual int SendRTCPPacket(int channel, const void *data, size_t len)
+ {
+ (void) channel; (void) data;
+ return len;
+ }
+
+ NullTransport() {}
+
+ virtual ~NullTransport() {}
+
+private:
+ NullTransport(const NullTransport& other) = delete;
+ void operator=(const NullTransport& other) = delete;
+};
+
+} // end namespace
+
+#endif
diff --git a/media/webrtc/signaling/src/common/PtrVector.h b/media/webrtc/signaling/src/common/PtrVector.h
new file mode 100644
index 000000000..68c760472
--- /dev/null
+++ b/media/webrtc/signaling/src/common/PtrVector.h
@@ -0,0 +1,43 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef PtrVector_h
+#define PtrVector_h
+
+#include <mozilla/Move.h>
+#include <vector>
+
+namespace mozilla
+{
+
+// Trivial wrapper class around a vector of ptrs.
+// TODO: Remove this once our buildconfig allows us to put unique_ptr in stl
+// containers, and just use std::vector<unique_ptr<T>> instead.
+template <class T> class PtrVector
+{
+public:
+ PtrVector() = default;
+ PtrVector(const PtrVector&) = delete;
+ PtrVector(PtrVector&& aOther)
+ : values(Move(aOther.values))
+ {}
+ PtrVector& operator=(const PtrVector&) = delete;
+ PtrVector& operator=(PtrVector&& aOther)
+ {
+ Swap(values, aOther.values);
+ return *this;
+ }
+
+ ~PtrVector()
+ {
+ for (T* value : values) { delete value; }
+ }
+
+ std::vector<T*> values;
+};
+
+} // namespace mozilla
+
+#endif // PtrVector_h
+
diff --git a/media/webrtc/signaling/src/common/Wrapper.h b/media/webrtc/signaling/src/common/Wrapper.h
new file mode 100644
index 000000000..a88cbd4bf
--- /dev/null
+++ b/media/webrtc/signaling/src/common/Wrapper.h
@@ -0,0 +1,175 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#pragma once
+
+/*
+ * Wrapper - Helper class for wrapper objects.
+ *
+ * This helps to construct a shared_ptr object which wraps access to an underlying handle.
+ * (The handle could be a pointer to some low-level type, a conventional C handle, an int ID, a GUID, etc.)
+ *
+ * Usage:
+ * To obtain a FooPtr from a foo_handle_t, call FooPtr Foo::wrap(foo_handle_t);
+ *
+ * To implement Foo using Wrapper, Foo needs to include this macro in its class definition:
+ * CSF_DECLARE_WRAP(Foo, foo_handle_t);
+ * It also needs to include this in the cpp file, to provide the wrap() implementation and define the static Wrapper.
+ * CSF_IMPLEMENT_WRAP(Foo, foo_handle_t);
+ * These are all declared in common/Wrapper.h - Foo.h needs to include this too.
+ * The client needs to declare Foo(foo_handle_t) as private, and provide a suitable implementation, as well as
+ * implementing wrappers for any other functions to be exposed.
+ * The client needs to implement ~Foo() to perform any cleanup as usual.
+ *
+ * wrap() will always return the same FooPtr for a given foo_handle_t, it will not construct additional objects
+ * if a suitable one already exists.
+ * changeHandle() is used in rare cases where the underlying handle is changed, but the wrapper object is intended
+ * to remain. This is the case for the "fake" CC_DPCall generated on CC_DPLine::CreateCall(), where
+ * the correct IDPCall* is provided later.
+ * reset() is a cleanup step to wipe the handle map and allow memory to be reclaimed.
+ *
+ * Future enhancements:
+ * - For now, objects remain in the map forever. Better would be to add a releaseHandle() function which would
+ * allow the map to be emptied as underlying handles expired. While we can't force the client to give up its
+ * shared_ptr<Foo> objects, we can remove our own copy, for instance on a call ended event.
+ */
+
+#include <map>
+#include "prlock.h"
+#include "mozilla/Assertions.h"
+
+/*
+ * Wrapper has its own autolock class because the instances are declared
+ * statically and mozilla::Mutex will not work properly when instantiated
+ * in a static constructor.
+ */
+
+class LockNSPR {
+public:
+ LockNSPR() : lock_(nullptr) {
+ lock_ = PR_NewLock();
+ MOZ_ASSERT(lock_);
+ }
+ ~LockNSPR() {
+ PR_DestroyLock(lock_);
+ }
+
+ void Acquire() {
+ PR_Lock(lock_);
+ }
+
+ void Release() {
+ PR_Unlock(lock_);
+ }
+
+private:
+ PRLock *lock_;
+};
+
+class AutoLockNSPR {
+public:
+ explicit AutoLockNSPR(LockNSPR& lock) : lock_(lock) {
+ lock_.Acquire();
+ }
+ ~AutoLockNSPR() {
+ lock_.Release();
+ }
+
+private:
+ LockNSPR& lock_;
+};
+
+template <class T>
+class Wrapper
+{
+private:
+ typedef std::map<typename T::Handle, typename T::Ptr> HandleMapType;
+ HandleMapType handleMap;
+ LockNSPR handleMapMutex;
+
+public:
+ Wrapper() {}
+
+ typename T::Ptr wrap(typename T::Handle handle)
+ {
+ AutoLockNSPR lock(handleMapMutex);
+ typename HandleMapType::iterator it = handleMap.find(handle);
+ if(it != handleMap.end())
+ {
+ return it->second;
+ }
+ else
+ {
+ typename T::Ptr p(new T(handle));
+ handleMap[handle] = p;
+ return p;
+ }
+ }
+
+ bool changeHandle(typename T::Handle oldHandle, typename T::Handle newHandle)
+ {
+ AutoLockNSPR lock(handleMapMutex);
+ typename HandleMapType::iterator it = handleMap.find(oldHandle);
+ if(it != handleMap.end())
+ {
+ typename T::Ptr p = it->second;
+ handleMap.erase(it);
+ handleMap[newHandle] = p;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ bool release(typename T::Handle handle)
+ {
+ AutoLockNSPR lock(handleMapMutex);
+ typename HandleMapType::iterator it = handleMap.find(handle);
+ if(it != handleMap.end())
+ {
+ handleMap.erase(it);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ void reset()
+ {
+ AutoLockNSPR lock(handleMapMutex);
+ handleMap.clear();
+ }
+};
+
+#define CSF_DECLARE_WRAP(classname, handletype) \
+ public: \
+ static classname ## Ptr wrap(handletype handle); \
+ static void reset(); \
+ static void release(handletype handle); \
+ private: \
+ friend class Wrapper<classname>; \
+ typedef classname ## Ptr Ptr; \
+ typedef handletype Handle; \
+ static Wrapper<classname>& getWrapper() { \
+ static Wrapper<classname> wrapper; \
+ return wrapper; \
+ }
+
+#define CSF_IMPLEMENT_WRAP(classname, handletype) \
+ classname ## Ptr classname::wrap(handletype handle) \
+ { \
+ return getWrapper().wrap(handle); \
+ } \
+ void classname::reset() \
+ { \
+ getWrapper().reset(); \
+ } \
+ void classname::release(handletype handle) \
+ { \
+ getWrapper().release(handle); \
+ }
diff --git a/media/webrtc/signaling/src/common/YuvStamper.cpp b/media/webrtc/signaling/src/common/YuvStamper.cpp
new file mode 100644
index 000000000..892b640bf
--- /dev/null
+++ b/media/webrtc/signaling/src/common/YuvStamper.cpp
@@ -0,0 +1,469 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined XP_WIN
+#include <winsock2.h>
+#endif
+#include <string.h>
+
+#include "nspr.h"
+#include "YuvStamper.h"
+#include "mozilla/Sprintf.h"
+
+typedef uint32_t UINT4; //Needed for r_crc32() call
+extern "C" {
+#include "r_crc32.h"
+}
+
+namespace mozilla {
+
+#define ON_5 0x20
+#define ON_4 0x10
+#define ON_3 0x08
+#define ON_2 0x04
+#define ON_1 0x02
+#define ON_0 0x01
+
+/*
+ 0, 0, 1, 1, 0, 0,
+ 0, 1, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 0, 1, 0, 0, 1, 0,
+ 0, 0, 1, 1, 0, 0
+*/
+static unsigned char DIGIT_0 [] =
+ { ON_3 | ON_2,
+ ON_4 | ON_1,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_4 | ON_1,
+ ON_3 | ON_2
+ };
+
+/*
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+*/
+static unsigned char DIGIT_1 [] =
+ { ON_2,
+ ON_2,
+ ON_2,
+ ON_2,
+ ON_2,
+ ON_2,
+ ON_2
+ };
+
+/*
+ 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1,
+*/
+static unsigned char DIGIT_2 [] =
+ { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+ ON_0,
+ ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ ON_5,
+ ON_5,
+ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ };
+
+/*
+ 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_3 [] =
+ { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+ ON_0,
+ ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_0,
+ ON_0,
+ ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+ };
+
+/*
+ 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 1,
+ 0, 1, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1
+*/
+static unsigned char DIGIT_4 [] =
+ { ON_4 | ON_0,
+ ON_4 | ON_0,
+ ON_4 | ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_0,
+ ON_0,
+ ON_0,
+ };
+
+/*
+ 0, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_5 [] =
+ { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_5,
+ ON_5,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ ON_0,
+ ON_0,
+ ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+ };
+
+/*
+ 0, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_6 [] =
+ { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_5,
+ ON_5,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ };
+
+/*
+ 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0
+*/
+static unsigned char DIGIT_7 [] =
+ { ON_5 | ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_0,
+ ON_1,
+ ON_2,
+ ON_3,
+ ON_4,
+ ON_5
+ };
+
+/*
+ 0, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 0
+*/
+static unsigned char DIGIT_8 [] =
+ { ON_4 | ON_3 | ON_2 | ON_1,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ };
+
+/*
+ 0, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 0
+*/
+static unsigned char DIGIT_9 [] =
+ { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_5 | ON_0,
+ ON_5 | ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+ ON_0,
+ ON_0,
+ ON_4 | ON_3 | ON_2 | ON_1,
+ };
+
+static unsigned char *DIGITS[] = {
+ DIGIT_0,
+ DIGIT_1,
+ DIGIT_2,
+ DIGIT_3,
+ DIGIT_4,
+ DIGIT_5,
+ DIGIT_6,
+ DIGIT_7,
+ DIGIT_8,
+ DIGIT_9
+};
+
+ YuvStamper::YuvStamper(unsigned char* pYData,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ uint32_t x,
+ uint32_t y,
+ unsigned char symbol_width,
+ unsigned char symbol_height):
+ pYData(pYData), mStride(stride),
+ mWidth(width), mHeight(height),
+ mSymbolWidth(symbol_width), mSymbolHeight(symbol_height),
+ mCursor(x, y) {}
+
+ bool YuvStamper::Encode(uint32_t width, uint32_t height, uint32_t stride,
+ unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+ uint32_t x, uint32_t y)
+ {
+ YuvStamper stamper(pYData, width, height, stride,
+ x, y, sBitSize, sBitSize);
+
+ // Reserve space for a checksum.
+ if (stamper.Capacity() < 8 * (msg_len + sizeof(uint32_t)))
+ {
+ return false;
+ }
+
+ bool ok = false;
+ uint32_t crc;
+ unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
+ r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &crc);
+ crc = htonl(crc);
+
+ while (msg_len-- > 0) {
+ if (!stamper.Write8(*pMsg++)) {
+ return false;
+ }
+ }
+
+ // Add checksum after the message.
+ ok = stamper.Write8(*pCrc++) &&
+ stamper.Write8(*pCrc++) &&
+ stamper.Write8(*pCrc++) &&
+ stamper.Write8(*pCrc++);
+
+ return ok;
+ }
+
+ bool YuvStamper::Decode(uint32_t width, uint32_t height, uint32_t stride,
+ unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+ uint32_t x, uint32_t y)
+ {
+ YuvStamper stamper(pYData, width, height, stride,
+ x, y, sBitSize, sBitSize);
+
+ unsigned char* ptr = pMsg;
+ size_t len = msg_len;
+ uint32_t crc, msg_crc;
+ unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
+
+ // Account for space reserved for the checksum
+ if (stamper.Capacity() < 8 * (len + sizeof(uint32_t))) {
+ return false;
+ }
+
+ while (len-- > 0) {
+ if(!stamper.Read8(*ptr++)) {
+ return false;
+ }
+ }
+
+ if (!(stamper.Read8(*pCrc++) &&
+ stamper.Read8(*pCrc++) &&
+ stamper.Read8(*pCrc++) &&
+ stamper.Read8(*pCrc++))) {
+ return false;
+ }
+
+ r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &msg_crc);
+ return crc == htonl(msg_crc);
+ }
+
+ inline uint32_t YuvStamper::Capacity()
+ {
+ // Enforce at least a symbol width and height offset from outer edges.
+ if (mCursor.y + mSymbolHeight > mHeight) {
+ return 0;
+ }
+
+ if (mCursor.x + mSymbolWidth > mWidth && !AdvanceCursor()) {
+ return 0;
+ }
+
+ // Normalize frame integral to mSymbolWidth x mSymbolHeight
+ uint32_t width = mWidth / mSymbolWidth;
+ uint32_t height = mHeight / mSymbolHeight;
+ uint32_t x = mCursor.x / mSymbolWidth;
+ uint32_t y = mCursor.y / mSymbolHeight;
+
+ return (width * height - width * y)- x;
+ }
+
+ bool YuvStamper::Write8(unsigned char value)
+ {
+ // Encode MSB to LSB.
+ unsigned char mask = 0x80;
+ while (mask) {
+ if (!WriteBit(!!(value & mask))) {
+ return false;
+ }
+ mask >>= 1;
+ }
+ return true;
+ }
+
+ bool YuvStamper::WriteBit(bool one)
+ {
+ // A bit is mapped to a mSymbolWidth x mSymbolHeight square of luma data points.
+ // Don't use ternary op.: https://bugzilla.mozilla.org/show_bug.cgi?id=1001708
+ unsigned char value;
+ if (one)
+ value = sYOn;
+ else
+ value = sYOff;
+
+ for (uint32_t y = 0; y < mSymbolHeight; y++) {
+ for (uint32_t x = 0; x < mSymbolWidth; x++) {
+ *(pYData + (mCursor.x + x) + ((mCursor.y + y) * mStride)) = value;
+ }
+ }
+
+ return AdvanceCursor();
+ }
+
+ bool YuvStamper::AdvanceCursor()
+ {
+ mCursor.x += mSymbolWidth;
+ if (mCursor.x + mSymbolWidth > mWidth) {
+ // move to the start of the next row if possible.
+ mCursor.y += mSymbolHeight;
+ if (mCursor.y + mSymbolHeight > mHeight) {
+ // end of frame, do not advance
+ mCursor.y -= mSymbolHeight;
+ mCursor.x -= mSymbolWidth;
+ return false;
+ } else {
+ mCursor.x = 0;
+ }
+ }
+
+ return true;
+ }
+
+ bool YuvStamper::Read8(unsigned char &value)
+ {
+ unsigned char octet = 0;
+ unsigned char bit = 0;
+
+ for (int i = 8; i > 0; --i) {
+ if (!ReadBit(bit)) {
+ return false;
+ }
+ octet <<= 1;
+ octet |= bit;
+ }
+
+ value = octet;
+ return true;
+ }
+
+ bool YuvStamper::ReadBit(unsigned char &bit)
+ {
+ uint32_t sum = 0;
+ for (uint32_t y = 0; y < mSymbolHeight; y++) {
+ for (uint32_t x = 0; x < mSymbolWidth; x++) {
+ sum += *(pYData + mStride * (mCursor.y + y) + mCursor.x + x);
+ }
+ }
+
+ // apply threshold to collected bit square
+ bit = (sum > (sBitThreshold * mSymbolWidth * mSymbolHeight)) ? 1 : 0;
+ return AdvanceCursor();
+ }
+
+ bool YuvStamper::WriteDigits(uint32_t value)
+ {
+ char buf[20];
+ SprintfLiteral(buf, "%.5u", value);
+ size_t size = strlen(buf);
+
+ if (Capacity() < size) {
+ return false;
+ }
+
+ for (size_t i=0; i < size; ++i) {
+ if (!WriteDigit(buf[i] - '0'))
+ return false;
+ if (!AdvanceCursor()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool YuvStamper::WriteDigit(unsigned char digit) {
+ if (digit > sizeof(DIGITS)/sizeof(DIGITS[0]))
+ return false;
+
+ unsigned char *dig = DIGITS[digit];
+ for (uint32_t row = 0; row < sDigitHeight; ++row) {
+ unsigned char mask = 0x01 << (sDigitWidth - 1);
+ for (uint32_t col = 0; col < sDigitWidth; ++col, mask >>= 1) {
+ if (dig[row] & mask) {
+ for (uint32_t xx=0; xx < sPixelSize; ++xx) {
+ for (uint32_t yy=0; yy < sPixelSize; ++yy) {
+ WritePixel(pYData,
+ mCursor.x + (col * sPixelSize) + xx,
+ mCursor.y + (row * sPixelSize) + yy);
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ void YuvStamper::WritePixel(unsigned char *data, uint32_t x, uint32_t y) {
+ unsigned char *ptr = &data[y * mStride + x];
+ // Don't use ternary op.: https://bugzilla.mozilla.org/show_bug.cgi?id=1001708
+ if (*ptr > sLumaThreshold)
+ *ptr = sLumaMin;
+ else
+ *ptr = sLumaMax;
+ }
+
+} // namespace mozilla.
diff --git a/media/webrtc/signaling/src/common/YuvStamper.h b/media/webrtc/signaling/src/common/YuvStamper.h
new file mode 100644
index 000000000..fb2d6e466
--- /dev/null
+++ b/media/webrtc/signaling/src/common/YuvStamper.h
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef YUV_STAMPER_H_
+#define YUV_STAMPER_H_
+
+#include "nptypes.h"
+
+namespace mozilla {
+
+class
+YuvStamper {
+public:
+ bool WriteDigits(uint32_t value);
+
+ template<typename T>
+ static bool Write(uint32_t width, uint32_t height, uint32_t stride,
+ unsigned char *pYData, const T& value,
+ uint32_t x=0, uint32_t y=0)
+ {
+ YuvStamper stamper(pYData, width, height, stride,
+ x, y,
+ (sDigitWidth + sInterDigit) * sPixelSize,
+ (sDigitHeight + sInterLine) * sPixelSize);
+ return stamper.WriteDigits(value);
+ }
+
+ static bool Encode(uint32_t width, uint32_t height, uint32_t stride,
+ unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+ uint32_t x = 0, uint32_t y = 0);
+
+ static bool Decode(uint32_t width, uint32_t height, uint32_t stride,
+ unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+ uint32_t x = 0, uint32_t y = 0);
+
+ private:
+ YuvStamper(unsigned char* pYData,
+ uint32_t width, uint32_t height, uint32_t stride,
+ uint32_t x, uint32_t y,
+ unsigned char symbol_width, unsigned char symbol_height);
+
+ bool WriteDigit(unsigned char digit);
+ void WritePixel(unsigned char* data, uint32_t x, uint32_t y);
+ uint32_t Capacity();
+ bool AdvanceCursor();
+ bool WriteBit(bool one);
+ bool Write8(unsigned char value);
+ bool ReadBit(unsigned char &value);
+ bool Read8(unsigned char &bit);
+
+ const static unsigned char sPixelSize = 3;
+ const static unsigned char sDigitWidth = 6;
+ const static unsigned char sDigitHeight = 7;
+ const static unsigned char sInterDigit = 1;
+ const static unsigned char sInterLine = 1;
+ const static uint32_t sBitSize = 4;
+ const static uint32_t sBitThreshold = 60;
+ const static unsigned char sYOn = 0x80;
+ const static unsigned char sYOff = 0;
+ const static unsigned char sLumaThreshold = 96;
+ const static unsigned char sLumaMin = 16;
+ const static unsigned char sLumaMax = 235;
+
+ unsigned char* pYData;
+ uint32_t mStride;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ unsigned char mSymbolWidth;
+ unsigned char mSymbolHeight;
+
+ struct Cursor {
+ Cursor(uint32_t x, uint32_t y):
+ x(x), y(y) {}
+ uint32_t x;
+ uint32_t y;
+ } mCursor;
+};
+
+}
+
+#endif
+
diff --git a/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp
new file mode 100644
index 000000000..3d7e2d6dc
--- /dev/null
+++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "CSFLog.h"
+#include "base/basictypes.h"
+
+#include <map>
+#include "prrwlock.h"
+#include "prthread.h"
+#include "nsThreadUtils.h"
+
+#include "mozilla/Logging.h"
+#include "mozilla/Sprintf.h"
+
+static PRLogModuleInfo *gLogModuleInfo = nullptr;
+
+PRLogModuleInfo *GetSignalingLogInfo()
+{
+ if (gLogModuleInfo == nullptr)
+ gLogModuleInfo = PR_NewLogModule("signaling");
+
+ return gLogModuleInfo;
+}
+
+static PRLogModuleInfo *gWebRTCLogModuleInfo = nullptr;
+
+PRLogModuleInfo *GetWebRTCLogInfo()
+{
+ if (gWebRTCLogModuleInfo == nullptr)
+ gWebRTCLogModuleInfo = PR_NewLogModule("webrtc_trace");
+
+ return gWebRTCLogModuleInfo;
+}
+
+
+void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args)
+{
+#ifdef STDOUT_LOGGING
+ printf("%s\n:",tag);
+ vprintf(format, args);
+#else
+
+ mozilla::LogLevel level = static_cast<mozilla::LogLevel>(priority);
+
+ GetSignalingLogInfo();
+
+ // Skip doing any of this work if we're not logging the indicated level...
+ if (!MOZ_LOG_TEST(gLogModuleInfo,level)) {
+ return;
+ }
+
+ // Trim the path component from the filename
+ const char *lastSlash = sourceFile;
+ while (*sourceFile) {
+ if (*sourceFile == '/' || *sourceFile == '\\') {
+ lastSlash = sourceFile;
+ }
+ sourceFile++;
+ }
+ sourceFile = lastSlash;
+ if (*sourceFile == '/' || *sourceFile == '\\') {
+ sourceFile++;
+ }
+
+#define MAX_MESSAGE_LENGTH 1024
+ char message[MAX_MESSAGE_LENGTH];
+
+ const char *threadName = NULL;
+
+ // Check if we're the main thread...
+ if (NS_IsMainThread()) {
+ threadName = "main";
+ } else {
+ threadName = PR_GetThreadName(PR_GetCurrentThread());
+ }
+
+ // If we can't find it anywhere, use a blank string
+ if (!threadName) {
+ threadName = "";
+ }
+
+ VsprintfLiteral(message, format, args);
+ MOZ_LOG(gLogModuleInfo, level, ("[%s|%s] %s:%d: %s",
+ threadName, tag, sourceFile, sourceLine,
+ message));
+#endif
+
+}
+
+void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+
+ CSFLogV(priority, sourceFile, sourceLine, tag, format, ap);
+ va_end(ap);
+}
+
diff --git a/media/webrtc/signaling/src/common/browser_logging/CSFLog.h b/media/webrtc/signaling/src/common/browser_logging/CSFLog.h
new file mode 100644
index 000000000..a20157992
--- /dev/null
+++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.h
@@ -0,0 +1,50 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CSFLOG_H
+#define CSFLOG_H
+
+#include <stdarg.h>
+
+struct PRLogModuleInfo;
+
+typedef enum{
+ CSF_LOG_ERROR = 1,
+ CSF_LOG_WARNING,
+ CSF_LOG_INFO,
+ CSF_LOG_DEBUG,
+ CSF_LOG_VERBOSE,
+} CSFLogLevel;
+
+#define CSFLogError(tag , format, ...) CSFLog( CSF_LOG_ERROR, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ )
+#define CSFLogErrorV(tag , format, va_list_arg) CSFLogV(CSF_LOG_ERROR, __FILE__ , __LINE__ , tag , format , va_list_arg )
+#define CSFLogWarn(tag , format, ...) CSFLog( CSF_LOG_WARNING, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ )
+#define CSFLogWarnV(tag , format, va_list_arg) CSFLogV(CSF_LOG_WARNING, __FILE__ , __LINE__ , tag , format , va_list_arg )
+#define CSFLogInfo(tag , format, ...) CSFLog( CSF_LOG_INFO, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ )
+#define CSFLogInfoV(tag , format, va_list_arg) CSFLogV(CSF_LOG_INFO, __FILE__ , __LINE__ , tag , format , va_list_arg )
+#define CSFLogDebug(tag , format, ...) CSFLog(CSF_LOG_DEBUG, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ )
+#define CSFLogDebugV(tag , format, va_list_arg) CSFLogV(CSF_LOG_DEBUG, __FILE__ , __LINE__ , tag , format , va_list_arg )
+#define CSFLogVerbose(tag , format, ...) CSFLog(CSF_LOG_VERBOSE, __FILE__ , __LINE__ , tag , format , ## __VA_ARGS__ )
+#define CSFLogVerboseV(tag , format, va_list_arg) CSFLogV(CSF_LOG_VERBOSE, __FILE__ , __LINE__ , tag , format , va_list_arg )
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 5, 6)))
+#endif
+;
+
+void CSFLogV( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args);
+
+struct PRLogModuleInfo *GetSignalingLogInfo();
+struct PRLogModuleInfo *GetWebRTCLogInfo();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
new file mode 100644
index 000000000..875e0ed2c
--- /dev/null
+++ b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
@@ -0,0 +1,258 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebRtcLog.h"
+
+#include "mozilla/Logging.h"
+#include "prenv.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+
+#include "nscore.h"
+#ifdef MOZILLA_INTERNAL_API
+#include "nsString.h"
+#include "nsXULAppAPI.h"
+#include "mozilla/Preferences.h"
+#else
+#include "nsStringAPI.h"
+#endif
+
+#include "nsIFile.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsDirectoryServiceDefs.h"
+
+using mozilla::LogLevel;
+
+static int gWebRtcTraceLoggingOn = 0;
+
+
+#if defined(ANDROID)
+static const char *default_tmp_dir = "/dev/null";
+static const char *default_log_name = "nspr";
+#else // Assume a POSIX environment
+NS_NAMED_LITERAL_CSTRING(default_log_name, "WebRTC.log");
+#endif
+
+static PRLogModuleInfo* GetWebRtcTraceLog()
+{
+ static PRLogModuleInfo *sLog;
+ if (!sLog) {
+ sLog = PR_NewLogModule("webrtc_trace");
+ }
+ return sLog;
+}
+
+static PRLogModuleInfo* GetWebRtcAECLog()
+{
+ static PRLogModuleInfo *sLog;
+ if (!sLog) {
+ sLog = PR_NewLogModule("AEC");
+ }
+ return sLog;
+}
+
+class WebRtcTraceCallback: public webrtc::TraceCallback
+{
+public:
+ void Print(webrtc::TraceLevel level, const char* message, int length)
+ {
+ PRLogModuleInfo *log = GetWebRtcTraceLog();
+ MOZ_LOG(log, LogLevel::Debug, ("%s", message));
+ }
+};
+
+static WebRtcTraceCallback gWebRtcCallback;
+
+#ifdef MOZILLA_INTERNAL_API
+void GetWebRtcLogPrefs(uint32_t *aTraceMask, nsACString* aLogFile, nsACString *aAECLogDir, bool *aMultiLog)
+{
+ *aMultiLog = mozilla::Preferences::GetBool("media.webrtc.debug.multi_log");
+ *aTraceMask = mozilla::Preferences::GetUint("media.webrtc.debug.trace_mask");
+ mozilla::Preferences::GetCString("media.webrtc.debug.log_file", aLogFile);
+ mozilla::Preferences::GetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
+ webrtc::Trace::set_aec_debug_size(mozilla::Preferences::GetUint("media.webrtc.debug.aec_dump_max_size"));
+}
+#endif
+
+void CheckOverrides(uint32_t *aTraceMask, nsACString *aLogFile, bool *aMultiLog)
+{
+ if (!aTraceMask || !aLogFile || !aMultiLog) {
+ return;
+ }
+
+ // Override or fill in attributes from the environment if possible.
+
+ PRLogModuleInfo *log_info = GetWebRtcTraceLog();
+ /* When webrtc_trace:x is not part of the NSPR_LOG_MODULES var the structure returned from
+ the GetWebRTCLogInfo call will be non-null and show a level of 0. This cannot
+ be reliably used to turn off the trace and override a log level from about:config as
+ there is no way to differentiate between NSPR_LOG_MODULES=webrtc_trace:0 and the complete
+ absense of the webrtc_trace in the environment string at all.
+ */
+ if (log_info && (log_info->level != 0)) {
+ *aTraceMask = log_info->level;
+ }
+
+ log_info = GetWebRtcAECLog();
+ if (log_info && (log_info->level != 0)) {
+ webrtc::Trace::set_aec_debug(true);
+ }
+
+ const char *file_name = PR_GetEnv("WEBRTC_TRACE_FILE");
+ if (file_name) {
+ aLogFile->Assign(file_name);
+ }
+}
+
+void ConfigWebRtcLog(uint32_t trace_mask, nsCString &aLogFile, nsCString &aAECLogDir, bool multi_log)
+{
+ if (gWebRtcTraceLoggingOn) {
+ return;
+ }
+
+#if defined(ANDROID)
+ // Special case: use callback to pipe to NSPR logging.
+ aLogFile.Assign(default_log_name);
+#else
+
+ webrtc::Trace::set_level_filter(trace_mask);
+
+ if (trace_mask != 0) {
+ if (aLogFile.EqualsLiteral("nspr")) {
+ webrtc::Trace::SetTraceCallback(&gWebRtcCallback);
+ } else {
+ webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log);
+ }
+ }
+
+ if (aLogFile.IsEmpty()) {
+ nsCOMPtr<nsIFile> tempDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
+ if (NS_SUCCEEDED(rv)) {
+ tempDir->AppendNative(default_log_name);
+ tempDir->GetNativePath(aLogFile);
+ }
+ }
+#endif
+
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+ if (XRE_IsParentProcess()) {
+ // Capture the final choice for the trace setting.
+ mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile);
+ }
+#endif
+ return;
+}
+
+void StartWebRtcLog(uint32_t log_level)
+{
+ if (gWebRtcTraceLoggingOn && log_level != 0) {
+ return;
+ }
+
+ if (log_level == 0) {
+ if (gWebRtcTraceLoggingOn) {
+ gWebRtcTraceLoggingOn = false;
+ webrtc::Trace::set_level_filter(webrtc::kTraceNone);
+ }
+ return;
+ }
+
+ uint32_t trace_mask = 0;
+ bool multi_log = false;
+ nsAutoCString log_file;
+ nsAutoCString aec_log_dir;
+
+#ifdef MOZILLA_INTERNAL_API
+ GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+#endif
+ CheckOverrides(&trace_mask, &log_file, &multi_log);
+
+ if (trace_mask == 0) {
+ trace_mask = log_level;
+ }
+
+ ConfigWebRtcLog(trace_mask, log_file, aec_log_dir, multi_log);
+ return;
+
+}
+
+void EnableWebRtcLog()
+{
+ if (gWebRtcTraceLoggingOn) {
+ return;
+ }
+
+ uint32_t trace_mask = 0;
+ bool multi_log = false;
+ nsAutoCString log_file;
+ nsAutoCString aec_log_dir;
+
+#ifdef MOZILLA_INTERNAL_API
+ GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+#endif
+ CheckOverrides(&trace_mask, &log_file, &multi_log);
+ ConfigWebRtcLog(trace_mask, log_file, aec_log_dir, multi_log);
+ return;
+}
+
+void StopWebRtcLog()
+{
+ // TODO(NG) strip/fix gWebRtcTraceLoggingOn which is never set to true
+ webrtc::Trace::set_level_filter(webrtc::kTraceNone);
+ webrtc::Trace::SetTraceCallback(nullptr);
+ webrtc::Trace::SetTraceFile(nullptr);
+}
+
+void ConfigAecLog(nsCString &aAECLogDir) {
+ if (webrtc::Trace::aec_debug()) {
+ return;
+ }
+#if defined(ANDROID)
+ // For AEC, do not use a default value: force the user to specify a directory.
+ if (aAECLogDir.IsEmpty()) {
+ aAECLogDir.Assign(default_tmp_dir);
+ }
+#else
+ if (aAECLogDir.IsEmpty()) {
+ nsCOMPtr<nsIFile> tempDir;
+ nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tempDir));
+ if (NS_SUCCEEDED(rv)) {
+ if (aAECLogDir.IsEmpty()) {
+ tempDir->GetNativePath(aAECLogDir);
+ }
+ }
+ }
+#endif
+ webrtc::Trace::set_aec_debug_filename(aAECLogDir.get());
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+ if (XRE_IsParentProcess()) {
+ // Capture the final choice for the aec_log_dir setting.
+ mozilla::Preferences::SetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
+ }
+#endif
+}
+
+void StartAecLog()
+{
+ if (webrtc::Trace::aec_debug()) {
+ return;
+ }
+ uint32_t trace_mask = 0;
+ bool multi_log = false;
+ nsAutoCString log_file;
+ nsAutoCString aec_log_dir;
+
+#ifdef MOZILLA_INTERNAL_API
+ GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
+#endif
+ CheckOverrides(&trace_mask, &log_file, &multi_log);
+ ConfigAecLog(aec_log_dir);
+
+ webrtc::Trace::set_aec_debug(true);
+}
+
+void StopAecLog()
+{
+ webrtc::Trace::set_aec_debug(false);
+}
diff --git a/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.h b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.h
new file mode 100644
index 000000000..58a824bee
--- /dev/null
+++ b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.h
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WEBRTCLOG_H_
+#define WEBRTCLOG_H_
+
+#include "webrtc/common_types.h"
+
+void StartAecLog();
+void StopAecLog();
+void StartWebRtcLog(uint32_t log_level = webrtc::kTraceDefault);
+void EnableWebRtcLog();
+void StopWebRtcLog();
+
+#endif
diff --git a/media/webrtc/signaling/src/common/csf_common.h b/media/webrtc/signaling/src/common/csf_common.h
new file mode 100644
index 000000000..f46abf69e
--- /dev/null
+++ b/media/webrtc/signaling/src/common/csf_common.h
@@ -0,0 +1,79 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _CSF_COMMON_E58E5677_950A_424c_B6C2_CA180092E6A2_H
+#define _CSF_COMMON_E58E5677_950A_424c_B6C2_CA180092E6A2_H
+
+#include <assert.h>
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+/*
+
+This header file defines:
+
+csf_countof
+csf_sprintf
+csf_vsprintf
+
+*/
+
+/*
+ General security tip: Ensure that "format" is never a user-defined string. Format should ALWAYS be something that's built into your code, not
+ user supplied. For example: never write:
+
+ csf_sprintf(buffer, csf_countof(buffer), pUserSuppliedString);
+
+ Instead write:
+
+ csf_sprintf(buffer, csf_countof(buffer), "%s", pUserSuppliedString);
+
+*/
+
+#ifdef WIN32
+ #if !defined(_countof)
+ #if !defined(__cplusplus)
+ #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+ #else
+ extern "C++"
+ {
+ template <typename _CountofType, size_t _SizeOfArray>
+ char (*_csf_countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
+ #define _countof(_Array) sizeof(*_csf_countof_helper(_Array))
+ }
+ #endif
+ #endif
+#else
+ #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#endif
+//csf_countof
+
+#define csf_countof(anArray) _countof(anArray)
+
+//csf_sprintf
+
+#ifdef _WIN32
+ //Unlike snprintf, sprintf_s guarantees that the buffer will be null-terminated (unless the buffer size is zero).
+ #define csf_sprintf(/* char* */ buffer, /* size_t */ sizeOfBufferInCharsInclNullTerm, /* const char * */ format, ...)\
+ _snprintf_s (buffer, sizeOfBufferInCharsInclNullTerm, _TRUNCATE, format, __VA_ARGS__)
+#else
+ #define csf_sprintf(/* char */ buffer, /* size_t */ sizeOfBufferInCharsInclNullTerm, /* const char * */ format, ...)\
+ snprintf (buffer, sizeOfBufferInCharsInclNullTerm, format, __VA_ARGS__);\
+ buffer[sizeOfBufferInCharsInclNullTerm-1] = '\0'
+#endif
+
+//csf_vsprintf
+
+#ifdef _WIN32
+ #define csf_vsprintf(/* char* */ buffer, /* size_t */ sizeOfBufferInCharsInclNullTerm, /* const char * */ format, /* va_list */ vaList)\
+ vsnprintf_s (buffer, sizeOfBufferInCharsInclNullTerm, _TRUNCATE, format, vaList);\
+ buffer[sizeOfBufferInCharsInclNullTerm-1] = '\0'
+#else
+ #define csf_vsprintf(/* char */ buffer, /* size_t */ sizeOfBufferInCharsInclNullTerm, /* const char * */ format, /* va_list */ vaList)\
+ vsprintf (buffer, format, vaList);\
+ buffer[sizeOfBufferInCharsInclNullTerm-1] = '\0'
+#endif
+
+#endif
diff --git a/media/webrtc/signaling/src/common/time_profiling/timecard.c b/media/webrtc/signaling/src/common/time_profiling/timecard.c
new file mode 100644
index 000000000..e56377534
--- /dev/null
+++ b/media/webrtc/signaling/src/common/time_profiling/timecard.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdio.h>
+#include "timecard.h"
+#include "mozilla/mozalloc.h"
+
+Timecard *
+create_timecard()
+{
+ Timecard *tc = moz_xcalloc(1,sizeof(Timecard));
+ tc->entries_allocated = TIMECARD_INITIAL_TABLE_SIZE;
+ tc->entries = moz_xcalloc(tc->entries_allocated, sizeof(TimecardEntry));
+ tc->start_time = PR_Now();
+ return tc;
+}
+
+void
+destroy_timecard(Timecard *tc)
+{
+ free(tc->entries);
+ free(tc);
+}
+
+void
+stamp_timecard(Timecard *tc,
+ const char *event,
+ const char *file,
+ unsigned int line,
+ const char *function)
+{
+ TimecardEntry *entry = NULL;
+
+ /* Trim the path component from the filename */
+ const char *last_slash = file;
+ while (*file) {
+ if (*file == '/' || *file == '\\') {
+ last_slash = file;
+ }
+ file++;
+ }
+ file = last_slash;
+ if (*file == '/' || *file == '\\') {
+ file++;
+ }
+
+ /* Ensure there is enough space left in the entries list */
+ if (tc->curr_entry == tc->entries_allocated) {
+ tc->entries_allocated *= 2;
+ tc->entries = moz_xrealloc(tc->entries,
+ tc->entries_allocated * sizeof(TimecardEntry));
+ }
+
+ /* Record the data into the timecard entry */
+ entry = &tc->entries[tc->curr_entry];
+ entry->timestamp = PR_Now();
+ entry->event = event;
+ entry->file = file;
+ entry->line = line;
+ entry->function = function;
+ tc->curr_entry++;
+}
+
+void
+print_timecard(Timecard *tc)
+{
+ size_t i;
+ TimecardEntry *entry;
+ size_t event_width = 5;
+ size_t file_width = 4;
+ size_t function_width = 8;
+ size_t line_width;
+ PRTime offset, delta;
+
+ for (i = 0; i < tc->curr_entry; i++) {
+ entry = &tc->entries[i];
+ if (strlen(entry->event) > event_width) {
+ event_width = strlen(entry->event);
+ }
+ if (strlen(entry->file) > file_width) {
+ file_width = strlen(entry->file);
+ }
+ if (strlen(entry->function) > function_width) {
+ function_width = strlen(entry->function);
+ }
+ }
+
+ printf("\nTimecard created %4ld.%6.6ld\n\n",
+ (long)(tc->start_time / PR_USEC_PER_SEC),
+ (long)(tc->start_time % PR_USEC_PER_SEC));
+
+ line_width = 1 + 11 + 11 + event_width + file_width + 6 +
+ function_width + (4 * 3);
+
+ printf(" %-11s | %-11s | %-*s | %-*s | %-*s\n",
+ "Timestamp", "Delta",
+ (int)event_width, "Event",
+ (int)file_width + 6, "File",
+ (int)function_width, "Function");
+
+ for (i = 0; i <= line_width; i++) {
+ printf("=");
+ }
+ printf("\n");
+
+ for (i = 0; i < tc->curr_entry; i++) {
+ entry = &tc->entries[i];
+ offset = entry->timestamp - tc->start_time;
+ if (i > 0) {
+ delta = entry->timestamp - tc->entries[i-1].timestamp;
+ } else {
+ delta = entry->timestamp - tc->start_time;
+ }
+ printf(" %4ld.%6.6ld | %4ld.%6.6ld | %-*s | %*s:%-5d | %-*s\n",
+ (long)(offset / PR_USEC_PER_SEC), (long)(offset % PR_USEC_PER_SEC),
+ (long)(delta / PR_USEC_PER_SEC), (long)(delta % PR_USEC_PER_SEC),
+ (int)event_width, entry->event,
+ (int)file_width, entry->file, entry->line,
+ (int)function_width, entry->function);
+ }
+ printf("\n");
+}
diff --git a/media/webrtc/signaling/src/common/time_profiling/timecard.h b/media/webrtc/signaling/src/common/time_profiling/timecard.h
new file mode 100644
index 000000000..ca53b8dfe
--- /dev/null
+++ b/media/webrtc/signaling/src/common/time_profiling/timecard.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef timecard_h__
+#define timecard_h__
+
+#include <stdlib.h>
+#include "prtime.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define STAMP_TIMECARD(card,event) \
+ do { \
+ if (card) { \
+ stamp_timecard((card), (event), __FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while (0)
+
+#define TIMECARD_INITIAL_TABLE_SIZE 16
+
+/*
+ * The "const char *" members of this structure point to static strings.
+ * We do not own them, and should not attempt to deallocate them.
+ */
+
+typedef struct {
+ PRTime timestamp;
+ const char *event;
+ const char *file;
+ unsigned int line;
+ const char *function;
+} TimecardEntry;
+
+typedef struct Timecard {
+ size_t curr_entry;
+ size_t entries_allocated;
+ TimecardEntry *entries;
+ PRTime start_time;
+} Timecard;
+
+/**
+ * Creates a new Timecard structure for tracking events.
+ */
+Timecard *
+create_timecard();
+
+/**
+ * Frees the memory associated with a timecard. After returning, the
+ * timecard pointed to by tc is no longer valid.
+ */
+void
+destroy_timecard(Timecard *tc);
+
+/**
+ * Records a new event in the indicated timecard. This should not be
+ * called directly; code should instead use the STAMP_TIMECARD macro,
+ * above.
+ */
+void
+stamp_timecard(Timecard *tc,
+ const char *event,
+ const char *file,
+ unsigned int line,
+ const char *function);
+
+/**
+ * Formats and outputs the contents of a timecard onto stdout.
+ */
+void
+print_timecard(Timecard *tc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif