diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /media/webrtc/signaling/src/common | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-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')
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 |