Implement standalone event tracing in AppRTCDemo.
Logs tracing events (TRACE_EVENT0 and friends) to storage in a format compatible with chrome://tracing which can be used for performance evaluation, finding lock contention and other sweet things). Tracing is still basic and doesn't contain thread metadata or logging of tracing arguments. BUG=webrtc:5158 R=tommi@webrtc.org Review URL: https://codereview.webrtc.org/1457383002 . Cr-Commit-Position: refs/heads/master@{#10921}
This commit is contained in:
@ -74,10 +74,11 @@
|
|||||||
#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
|
#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
|
||||||
#include "webrtc/base/bind.h"
|
#include "webrtc/base/bind.h"
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
|
#include "webrtc/base/event_tracer.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/base/logsinks.h"
|
#include "webrtc/base/logsinks.h"
|
||||||
#include "webrtc/base/networkmonitor.h"
|
|
||||||
#include "webrtc/base/messagequeue.h"
|
#include "webrtc/base/messagequeue.h"
|
||||||
|
#include "webrtc/base/networkmonitor.h"
|
||||||
#include "webrtc/base/ssladapter.h"
|
#include "webrtc/base/ssladapter.h"
|
||||||
#include "webrtc/base/stringutils.h"
|
#include "webrtc/base/stringutils.h"
|
||||||
#include "webrtc/system_wrappers/include/field_trial_default.h"
|
#include "webrtc/system_wrappers/include/field_trial_default.h"
|
||||||
@ -1054,6 +1055,32 @@ JOW(void, PeerConnectionFactory_initializeFieldTrials)(
|
|||||||
webrtc::field_trial::InitFieldTrialsFromString(field_trials_init_string);
|
webrtc::field_trial::InitFieldTrialsFromString(field_trials_init_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JOW(void, PeerConnectionFactory_initializeInternalTracer)(JNIEnv* jni, jclass) {
|
||||||
|
rtc::tracing::SetupInternalTracer();
|
||||||
|
}
|
||||||
|
|
||||||
|
JOW(jboolean, PeerConnectionFactory_startInternalTracingCapture)(
|
||||||
|
JNIEnv* jni, jclass, jstring j_event_tracing_filename) {
|
||||||
|
if (!j_event_tracing_filename)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const char* init_string =
|
||||||
|
jni->GetStringUTFChars(j_event_tracing_filename, NULL);
|
||||||
|
LOG(LS_INFO) << "Starting internal tracing to: " << init_string;
|
||||||
|
bool ret = rtc::tracing::StartInternalCapture(init_string);
|
||||||
|
jni->ReleaseStringUTFChars(j_event_tracing_filename, init_string);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
JOW(void, PeerConnectionFactory_stopInternalTracingCapture)(
|
||||||
|
JNIEnv* jni, jclass) {
|
||||||
|
rtc::tracing::StopInternalCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
JOW(void, PeerConnectionFactory_shutdownInternalTracer)(JNIEnv* jni, jclass) {
|
||||||
|
rtc::tracing::ShutdownInternalTracer();
|
||||||
|
}
|
||||||
|
|
||||||
// Helper struct for working around the fact that CreatePeerConnectionFactory()
|
// Helper struct for working around the fact that CreatePeerConnectionFactory()
|
||||||
// comes in two flavors: either entirely automagical (constructing its own
|
// comes in two flavors: either entirely automagical (constructing its own
|
||||||
// threads and deleting them on teardown, but no external codec factory support)
|
// threads and deleting them on teardown, but no external codec factory support)
|
||||||
|
|||||||
@ -73,6 +73,15 @@ public class PeerConnectionFactory {
|
|||||||
// Field trial initialization. Must be called before PeerConnectionFactory
|
// Field trial initialization. Must be called before PeerConnectionFactory
|
||||||
// is created.
|
// is created.
|
||||||
public static native void initializeFieldTrials(String fieldTrialsInitString);
|
public static native void initializeFieldTrials(String fieldTrialsInitString);
|
||||||
|
// Internal tracing initialization. Must be called before PeerConnectionFactory is created to
|
||||||
|
// prevent racing with tracing code.
|
||||||
|
public static native void initializeInternalTracer();
|
||||||
|
// Internal tracing shutdown, called to prevent resource leaks. Must be called after
|
||||||
|
// PeerConnectionFactory is gone to prevent races with code performing tracing.
|
||||||
|
public static native void shutdownInternalTracer();
|
||||||
|
// Start/stop internal capturing of internal tracing.
|
||||||
|
public static native boolean startInternalTracingCapture(String tracing_filename);
|
||||||
|
public static native void stopInternalTracingCapture();
|
||||||
|
|
||||||
public PeerConnectionFactory() {
|
public PeerConnectionFactory() {
|
||||||
nativeFactory = nativeCreatePeerConnectionFactory();
|
nativeFactory = nativeCreatePeerConnectionFactory();
|
||||||
|
|||||||
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "talk/media/base/constants.h"
|
#include "talk/media/base/constants.h"
|
||||||
#include "talk/media/base/rtputils.h"
|
#include "talk/media/base/rtputils.h"
|
||||||
#include "webrtc/p2p/base/transportchannel.h"
|
|
||||||
#include "talk/session/media/channelmanager.h"
|
#include "talk/session/media/channelmanager.h"
|
||||||
#include "webrtc/base/bind.h"
|
#include "webrtc/base/bind.h"
|
||||||
#include "webrtc/base/buffer.h"
|
#include "webrtc/base/buffer.h"
|
||||||
@ -37,6 +36,8 @@
|
|||||||
#include "webrtc/base/common.h"
|
#include "webrtc/base/common.h"
|
||||||
#include "webrtc/base/dscp.h"
|
#include "webrtc/base/dscp.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/base/trace_event.h"
|
||||||
|
#include "webrtc/p2p/base/transportchannel.h"
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
@ -471,6 +472,7 @@ void BaseChannel::OnChannelRead(TransportChannel* channel,
|
|||||||
const char* data, size_t len,
|
const char* data, size_t len,
|
||||||
const rtc::PacketTime& packet_time,
|
const rtc::PacketTime& packet_time,
|
||||||
int flags) {
|
int flags) {
|
||||||
|
TRACE_EVENT0("webrtc", "BaseChannel::OnChannelRead");
|
||||||
// OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
|
// OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
|
||||||
ASSERT(worker_thread_ == rtc::Thread::Current());
|
ASSERT(worker_thread_ == rtc::Thread::Current());
|
||||||
|
|
||||||
@ -1272,6 +1274,7 @@ void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseChannel::OnMessage(rtc::Message *pmsg) {
|
void BaseChannel::OnMessage(rtc::Message *pmsg) {
|
||||||
|
TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
|
||||||
switch (pmsg->message_id) {
|
switch (pmsg->message_id) {
|
||||||
case MSG_RTPPACKET:
|
case MSG_RTPPACKET:
|
||||||
case MSG_RTCPPACKET: {
|
case MSG_RTCPPACKET: {
|
||||||
|
|||||||
@ -43,6 +43,16 @@ class AtomicOps {
|
|||||||
new_value,
|
new_value,
|
||||||
old_value);
|
old_value);
|
||||||
}
|
}
|
||||||
|
// Pointer variants.
|
||||||
|
template <typename T>
|
||||||
|
static T* AtomicLoadPtr(T* volatile* ptr) {
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
|
||||||
|
return static_cast<T*>(::InterlockedCompareExchangePointer(
|
||||||
|
reinterpret_cast<PVOID volatile*>(ptr), old_value, new_value));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static int Increment(volatile int* i) {
|
static int Increment(volatile int* i) {
|
||||||
return __sync_add_and_fetch(i, 1);
|
return __sync_add_and_fetch(i, 1);
|
||||||
@ -59,6 +69,15 @@ class AtomicOps {
|
|||||||
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
|
static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
|
||||||
return __sync_val_compare_and_swap(i, old_value, new_value);
|
return __sync_val_compare_and_swap(i, old_value, new_value);
|
||||||
}
|
}
|
||||||
|
// Pointer variants.
|
||||||
|
template <typename T>
|
||||||
|
static T* AtomicLoadPtr(T* volatile* ptr) {
|
||||||
|
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
|
||||||
|
return __sync_val_compare_and_swap(ptr, old_value, new_value);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,15 +7,26 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "webrtc/base/event_tracer.h"
|
#include "webrtc/base/event_tracer.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
|
#include "webrtc/base/criticalsection.h"
|
||||||
|
#include "webrtc/base/event.h"
|
||||||
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/base/platform_thread.h"
|
||||||
|
#include "webrtc/base/timeutils.h"
|
||||||
|
#include "webrtc/base/trace_event.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
GetCategoryEnabledPtr g_get_category_enabled_ptr = 0;
|
GetCategoryEnabledPtr g_get_category_enabled_ptr = nullptr;
|
||||||
AddTraceEventPtr g_add_trace_event_ptr = 0;
|
AddTraceEventPtr g_add_trace_event_ptr = nullptr;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -25,7 +36,6 @@ void SetupEventTracer(GetCategoryEnabledPtr get_category_enabled_ptr,
|
|||||||
g_add_trace_event_ptr = add_trace_event_ptr;
|
g_add_trace_event_ptr = add_trace_event_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
const unsigned char* EventTracer::GetCategoryEnabled(const char* name) {
|
const unsigned char* EventTracer::GetCategoryEnabled(const char* name) {
|
||||||
if (g_get_category_enabled_ptr)
|
if (g_get_category_enabled_ptr)
|
||||||
return g_get_category_enabled_ptr(name);
|
return g_get_category_enabled_ptr(name);
|
||||||
@ -34,7 +44,8 @@ const unsigned char* EventTracer::GetCategoryEnabled(const char* name) {
|
|||||||
return reinterpret_cast<const unsigned char*>("\0");
|
return reinterpret_cast<const unsigned char*>("\0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// Arguments to this function (phase, etc.) are as defined in
|
||||||
|
// webrtc/base/trace_event.h.
|
||||||
void EventTracer::AddTraceEvent(char phase,
|
void EventTracer::AddTraceEvent(char phase,
|
||||||
const unsigned char* category_enabled,
|
const unsigned char* category_enabled,
|
||||||
const char* name,
|
const char* name,
|
||||||
@ -58,3 +69,197 @@ void EventTracer::AddTraceEvent(char phase,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
namespace tracing {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static bool EventTracingThreadFunc(void* params);
|
||||||
|
|
||||||
|
// Atomic-int fast path for avoiding logging when disabled.
|
||||||
|
static volatile int g_event_logging_active = 0;
|
||||||
|
|
||||||
|
// TODO(pbos): Log metadata for all threads, etc.
|
||||||
|
class EventLogger final {
|
||||||
|
public:
|
||||||
|
EventLogger()
|
||||||
|
: logging_thread_(EventTracingThreadFunc, this, "EventTracingThread"),
|
||||||
|
shutdown_event_(false, false) {}
|
||||||
|
~EventLogger() { RTC_DCHECK(thread_checker_.CalledOnValidThread()); }
|
||||||
|
|
||||||
|
void AddTraceEvent(const char* name,
|
||||||
|
const unsigned char* category_enabled,
|
||||||
|
char phase,
|
||||||
|
uint64_t timestamp,
|
||||||
|
int pid,
|
||||||
|
rtc::PlatformThreadId thread_id) {
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
trace_events_.push_back(
|
||||||
|
{name, category_enabled, phase, timestamp, 1, thread_id});
|
||||||
|
}
|
||||||
|
|
||||||
|
// The TraceEvent format is documented here:
|
||||||
|
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
|
||||||
|
void Log() {
|
||||||
|
RTC_DCHECK(output_file_);
|
||||||
|
static const int kLoggingIntervalMs = 100;
|
||||||
|
fprintf(output_file_, "{ \"traceEvents\": [\n");
|
||||||
|
bool has_logged_event = false;
|
||||||
|
while (true) {
|
||||||
|
bool shutting_down = shutdown_event_.Wait(kLoggingIntervalMs);
|
||||||
|
std::vector<TraceEvent> events;
|
||||||
|
{
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
trace_events_.swap(events);
|
||||||
|
}
|
||||||
|
for (const TraceEvent& e : events) {
|
||||||
|
fprintf(output_file_,
|
||||||
|
"%s{ \"name\": \"%s\""
|
||||||
|
", \"cat\": \"%s\""
|
||||||
|
", \"ph\": \"%c\""
|
||||||
|
", \"ts\": %" PRIu64
|
||||||
|
", \"pid\": %d"
|
||||||
|
", \"tid\": %d}\n",
|
||||||
|
has_logged_event ? "," : " ", e.name, e.category_enabled,
|
||||||
|
e.phase, e.timestamp, e.pid, e.tid);
|
||||||
|
has_logged_event = true;
|
||||||
|
}
|
||||||
|
if (shutting_down)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(output_file_, "]}\n");
|
||||||
|
if (output_file_owned_)
|
||||||
|
fclose(output_file_);
|
||||||
|
output_file_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start(FILE* file, bool owned) {
|
||||||
|
RTC_DCHECK(file);
|
||||||
|
RTC_DCHECK(!output_file_);
|
||||||
|
output_file_ = file;
|
||||||
|
output_file_owned_ = owned;
|
||||||
|
{
|
||||||
|
rtc::CritScope lock(&crit_);
|
||||||
|
// Since the atomic fast-path for adding events to the queue can be
|
||||||
|
// bypassed while the logging thread is shutting down there may be some
|
||||||
|
// stale events in the queue, hence the vector needs to be cleared to not
|
||||||
|
// log events from a previous logging session (which may be days old).
|
||||||
|
trace_events_.clear();
|
||||||
|
}
|
||||||
|
// Enable event logging (fast-path). This should be disabled since starting
|
||||||
|
// shouldn't be done twice.
|
||||||
|
RTC_CHECK_EQ(0,
|
||||||
|
rtc::AtomicOps::CompareAndSwap(&g_event_logging_active, 0, 1));
|
||||||
|
|
||||||
|
// Finally start, everything should be set up now.
|
||||||
|
logging_thread_.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
// Try to stop. Abort if we're not currently logging.
|
||||||
|
if (rtc::AtomicOps::CompareAndSwap(&g_event_logging_active, 1, 0) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Wake up logging thread to finish writing.
|
||||||
|
shutdown_event_.Set();
|
||||||
|
// Join the logging thread.
|
||||||
|
logging_thread_.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct TraceEvent {
|
||||||
|
const char* name;
|
||||||
|
const unsigned char* category_enabled;
|
||||||
|
char phase;
|
||||||
|
uint64_t timestamp;
|
||||||
|
int pid;
|
||||||
|
rtc::PlatformThreadId tid;
|
||||||
|
};
|
||||||
|
|
||||||
|
rtc::CriticalSection crit_;
|
||||||
|
std::vector<TraceEvent> trace_events_ GUARDED_BY(crit_);
|
||||||
|
rtc::PlatformThread logging_thread_;
|
||||||
|
rtc::Event shutdown_event_;
|
||||||
|
rtc::ThreadChecker thread_checker_;
|
||||||
|
FILE* output_file_ = nullptr;
|
||||||
|
bool output_file_owned_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool EventTracingThreadFunc(void* params) {
|
||||||
|
static_cast<EventLogger*>(params)->Log();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EventLogger* volatile g_event_logger = nullptr;
|
||||||
|
static const char* const kDisabledTracePrefix = TRACE_DISABLED_BY_DEFAULT("");
|
||||||
|
const unsigned char* InternalGetCategoryEnabled(const char* name) {
|
||||||
|
const char* prefix_ptr = &kDisabledTracePrefix[0];
|
||||||
|
const char* name_ptr = name;
|
||||||
|
// Check whether name contains the default-disabled prefix.
|
||||||
|
while (*prefix_ptr == *name_ptr && *prefix_ptr != '\0') {
|
||||||
|
++prefix_ptr;
|
||||||
|
++name_ptr;
|
||||||
|
}
|
||||||
|
return reinterpret_cast<const unsigned char*>(*prefix_ptr == '\0' ? ""
|
||||||
|
: name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalAddTraceEvent(char phase,
|
||||||
|
const unsigned char* category_enabled,
|
||||||
|
const char* name,
|
||||||
|
unsigned long long id,
|
||||||
|
int num_args,
|
||||||
|
const char** arg_names,
|
||||||
|
const unsigned char* arg_types,
|
||||||
|
const unsigned long long* arg_values,
|
||||||
|
unsigned char flags) {
|
||||||
|
// Fast path for when event tracing is inactive.
|
||||||
|
if (rtc::AtomicOps::AcquireLoad(&g_event_logging_active) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_event_logger->AddTraceEvent(name, category_enabled, phase,
|
||||||
|
rtc::TimeMicros(), 1, rtc::CurrentThreadId());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void SetupInternalTracer() {
|
||||||
|
RTC_CHECK(rtc::AtomicOps::CompareAndSwapPtr(
|
||||||
|
&g_event_logger, static_cast<EventLogger*>(nullptr),
|
||||||
|
new EventLogger()) == nullptr);
|
||||||
|
g_event_logger = new EventLogger();
|
||||||
|
webrtc::SetupEventTracer(InternalGetCategoryEnabled, InternalAddTraceEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartInternalCaptureToFile(FILE* file) {
|
||||||
|
g_event_logger->Start(file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartInternalCapture(const char* filename) {
|
||||||
|
FILE* file = fopen(filename, "w");
|
||||||
|
if (!file) {
|
||||||
|
LOG(LS_ERROR) << "Failed to open trace file '" << filename
|
||||||
|
<< "' for writing.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
g_event_logger->Start(file, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopInternalCapture() {
|
||||||
|
g_event_logger->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutdownInternalTracer() {
|
||||||
|
StopInternalCapture();
|
||||||
|
EventLogger* old_logger = rtc::AtomicOps::AtomicLoadPtr(&g_event_logger);
|
||||||
|
RTC_DCHECK(old_logger);
|
||||||
|
RTC_CHECK(rtc::AtomicOps::CompareAndSwapPtr(
|
||||||
|
&g_event_logger, old_logger,
|
||||||
|
static_cast<EventLogger*>(nullptr)) == old_logger);
|
||||||
|
delete old_logger;
|
||||||
|
webrtc::SetupEventTracer(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tracing
|
||||||
|
} // namespace rtc
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
#ifndef WEBRTC_BASE_EVENT_TRACER_H_
|
#ifndef WEBRTC_BASE_EVENT_TRACER_H_
|
||||||
#define WEBRTC_BASE_EVENT_TRACER_H_
|
#define WEBRTC_BASE_EVENT_TRACER_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
typedef const unsigned char* (*GetCategoryEnabledPtr)(const char* name);
|
typedef const unsigned char* (*GetCategoryEnabledPtr)(const char* name);
|
||||||
@ -68,4 +70,16 @@ class EventTracer {
|
|||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
namespace rtc {
|
||||||
|
namespace tracing {
|
||||||
|
// Set up internal event tracer.
|
||||||
|
void SetupInternalTracer();
|
||||||
|
bool StartInternalCapture(const char* filename);
|
||||||
|
void StartInternalCaptureToFile(FILE* file);
|
||||||
|
void StopInternalCapture();
|
||||||
|
// Make sure we run this, this will tear down the internal tracing.
|
||||||
|
void ShutdownInternalTracer();
|
||||||
|
} // namespace tracing
|
||||||
|
} // namespace rtc
|
||||||
|
|
||||||
#endif // WEBRTC_BASE_EVENT_TRACER_H_
|
#endif // WEBRTC_BASE_EVENT_TRACER_H_
|
||||||
|
|||||||
@ -655,6 +655,7 @@ void Call::ConfigureSync(const std::string& sync_group) {
|
|||||||
PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
|
PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
|
||||||
const uint8_t* packet,
|
const uint8_t* packet,
|
||||||
size_t length) {
|
size_t length) {
|
||||||
|
TRACE_EVENT0("webrtc", "Call::DeliverRtcp");
|
||||||
// TODO(pbos): Figure out what channel needs it actually.
|
// TODO(pbos): Figure out what channel needs it actually.
|
||||||
// Do NOT broadcast! Also make sure it's a valid packet.
|
// Do NOT broadcast! Also make sure it's a valid packet.
|
||||||
// Return DELIVERY_UNKNOWN_SSRC if it can be determined that
|
// Return DELIVERY_UNKNOWN_SSRC if it can be determined that
|
||||||
@ -688,6 +689,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
|
|||||||
const uint8_t* packet,
|
const uint8_t* packet,
|
||||||
size_t length,
|
size_t length,
|
||||||
const PacketTime& packet_time) {
|
const PacketTime& packet_time) {
|
||||||
|
TRACE_EVENT0("webrtc", "Call::DeliverRtp");
|
||||||
// Minimum RTP header size.
|
// Minimum RTP header size.
|
||||||
if (length < 12)
|
if (length < 12)
|
||||||
return DELIVERY_PACKET_ERROR;
|
return DELIVERY_PACKET_ERROR;
|
||||||
|
|||||||
@ -120,4 +120,9 @@
|
|||||||
<string name="pref_displayhud_dlg">Display call statistics.</string>
|
<string name="pref_displayhud_dlg">Display call statistics.</string>
|
||||||
<string name="pref_displayhud_default" translatable="false">false</string>
|
<string name="pref_displayhud_default" translatable="false">false</string>
|
||||||
|
|
||||||
|
<string name="pref_tracing_key">tracing_preference</string>
|
||||||
|
<string name="pref_tracing_title">Debug performance tracing.</string>
|
||||||
|
<string name="pref_tracing_dlg">Debug performance tracing.</string>
|
||||||
|
<string name="pref_tracing_default" translatable="false">false</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -124,6 +124,12 @@
|
|||||||
android:title="@string/pref_displayhud_title"
|
android:title="@string/pref_displayhud_title"
|
||||||
android:dialogTitle="@string/pref_displayhud_dlg"
|
android:dialogTitle="@string/pref_displayhud_dlg"
|
||||||
android:defaultValue="@string/pref_displayhud_default" />
|
android:defaultValue="@string/pref_displayhud_default" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="@string/pref_tracing_key"
|
||||||
|
android:title="@string/pref_tracing_title"
|
||||||
|
android:dialogTitle="@string/pref_tracing_dlg"
|
||||||
|
android:defaultValue="@string/pref_tracing_default" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
@ -78,6 +78,7 @@ public class CallActivity extends Activity
|
|||||||
"org.appspot.apprtc.OPENSLES";
|
"org.appspot.apprtc.OPENSLES";
|
||||||
public static final String EXTRA_DISPLAY_HUD =
|
public static final String EXTRA_DISPLAY_HUD =
|
||||||
"org.appspot.apprtc.DISPLAY_HUD";
|
"org.appspot.apprtc.DISPLAY_HUD";
|
||||||
|
public static final String EXTRA_TRACING = "org.appspot.apprtc.TRACING";
|
||||||
public static final String EXTRA_CMDLINE =
|
public static final String EXTRA_CMDLINE =
|
||||||
"org.appspot.apprtc.CMDLINE";
|
"org.appspot.apprtc.CMDLINE";
|
||||||
public static final String EXTRA_RUNTIME =
|
public static final String EXTRA_RUNTIME =
|
||||||
@ -213,9 +214,11 @@ public class CallActivity extends Activity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean loopback = intent.getBooleanExtra(EXTRA_LOOPBACK, false);
|
boolean loopback = intent.getBooleanExtra(EXTRA_LOOPBACK, false);
|
||||||
|
boolean tracing = intent.getBooleanExtra(EXTRA_TRACING, false);
|
||||||
peerConnectionParameters = new PeerConnectionParameters(
|
peerConnectionParameters = new PeerConnectionParameters(
|
||||||
intent.getBooleanExtra(EXTRA_VIDEO_CALL, true),
|
intent.getBooleanExtra(EXTRA_VIDEO_CALL, true),
|
||||||
loopback,
|
loopback,
|
||||||
|
tracing,
|
||||||
intent.getIntExtra(EXTRA_VIDEO_WIDTH, 0),
|
intent.getIntExtra(EXTRA_VIDEO_WIDTH, 0),
|
||||||
intent.getIntExtra(EXTRA_VIDEO_HEIGHT, 0),
|
intent.getIntExtra(EXTRA_VIDEO_HEIGHT, 0),
|
||||||
intent.getIntExtra(EXTRA_VIDEO_FPS, 0),
|
intent.getIntExtra(EXTRA_VIDEO_FPS, 0),
|
||||||
|
|||||||
@ -69,6 +69,7 @@ public class ConnectActivity extends Activity {
|
|||||||
private String keyprefNoAudioProcessingPipeline;
|
private String keyprefNoAudioProcessingPipeline;
|
||||||
private String keyprefOpenSLES;
|
private String keyprefOpenSLES;
|
||||||
private String keyprefDisplayHud;
|
private String keyprefDisplayHud;
|
||||||
|
private String keyprefTracing;
|
||||||
private String keyprefRoomServerUrl;
|
private String keyprefRoomServerUrl;
|
||||||
private String keyprefRoom;
|
private String keyprefRoom;
|
||||||
private String keyprefRoomList;
|
private String keyprefRoomList;
|
||||||
@ -97,6 +98,7 @@ public class ConnectActivity extends Activity {
|
|||||||
keyprefNoAudioProcessingPipeline = getString(R.string.pref_noaudioprocessing_key);
|
keyprefNoAudioProcessingPipeline = getString(R.string.pref_noaudioprocessing_key);
|
||||||
keyprefOpenSLES = getString(R.string.pref_opensles_key);
|
keyprefOpenSLES = getString(R.string.pref_opensles_key);
|
||||||
keyprefDisplayHud = getString(R.string.pref_displayhud_key);
|
keyprefDisplayHud = getString(R.string.pref_displayhud_key);
|
||||||
|
keyprefTracing = getString(R.string.pref_tracing_key);
|
||||||
keyprefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
keyprefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
||||||
keyprefRoom = getString(R.string.pref_room_key);
|
keyprefRoom = getString(R.string.pref_room_key);
|
||||||
keyprefRoomList = getString(R.string.pref_room_list_key);
|
keyprefRoomList = getString(R.string.pref_room_list_key);
|
||||||
@ -328,6 +330,9 @@ public class ConnectActivity extends Activity {
|
|||||||
boolean displayHud = sharedPref.getBoolean(keyprefDisplayHud,
|
boolean displayHud = sharedPref.getBoolean(keyprefDisplayHud,
|
||||||
Boolean.valueOf(getString(R.string.pref_displayhud_default)));
|
Boolean.valueOf(getString(R.string.pref_displayhud_default)));
|
||||||
|
|
||||||
|
boolean tracing = sharedPref.getBoolean(
|
||||||
|
keyprefTracing, Boolean.valueOf(getString(R.string.pref_tracing_default)));
|
||||||
|
|
||||||
// Start AppRTCDemo activity.
|
// Start AppRTCDemo activity.
|
||||||
Log.d(TAG, "Connecting to room " + roomId + " at URL " + roomUrl);
|
Log.d(TAG, "Connecting to room " + roomId + " at URL " + roomUrl);
|
||||||
if (validateUrl(roomUrl)) {
|
if (validateUrl(roomUrl)) {
|
||||||
@ -352,6 +357,7 @@ public class ConnectActivity extends Activity {
|
|||||||
intent.putExtra(CallActivity.EXTRA_AUDIO_BITRATE, audioStartBitrate);
|
intent.putExtra(CallActivity.EXTRA_AUDIO_BITRATE, audioStartBitrate);
|
||||||
intent.putExtra(CallActivity.EXTRA_AUDIOCODEC, audioCodec);
|
intent.putExtra(CallActivity.EXTRA_AUDIOCODEC, audioCodec);
|
||||||
intent.putExtra(CallActivity.EXTRA_DISPLAY_HUD, displayHud);
|
intent.putExtra(CallActivity.EXTRA_DISPLAY_HUD, displayHud);
|
||||||
|
intent.putExtra(CallActivity.EXTRA_TRACING, tracing);
|
||||||
intent.putExtra(CallActivity.EXTRA_CMDLINE, commandLineRun);
|
intent.putExtra(CallActivity.EXTRA_CMDLINE, commandLineRun);
|
||||||
intent.putExtra(CallActivity.EXTRA_RUNTIME, runTimeMs);
|
intent.putExtra(CallActivity.EXTRA_RUNTIME, runTimeMs);
|
||||||
|
|
||||||
|
|||||||
@ -128,6 +128,7 @@ public class PeerConnectionClient {
|
|||||||
public static class PeerConnectionParameters {
|
public static class PeerConnectionParameters {
|
||||||
public final boolean videoCallEnabled;
|
public final boolean videoCallEnabled;
|
||||||
public final boolean loopback;
|
public final boolean loopback;
|
||||||
|
public final boolean tracing;
|
||||||
public final int videoWidth;
|
public final int videoWidth;
|
||||||
public final int videoHeight;
|
public final int videoHeight;
|
||||||
public final int videoFps;
|
public final int videoFps;
|
||||||
@ -141,13 +142,14 @@ public class PeerConnectionClient {
|
|||||||
public final boolean useOpenSLES;
|
public final boolean useOpenSLES;
|
||||||
|
|
||||||
public PeerConnectionParameters(
|
public PeerConnectionParameters(
|
||||||
boolean videoCallEnabled, boolean loopback,
|
boolean videoCallEnabled, boolean loopback, boolean tracing,
|
||||||
int videoWidth, int videoHeight, int videoFps, int videoStartBitrate,
|
int videoWidth, int videoHeight, int videoFps, int videoStartBitrate,
|
||||||
String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTexture,
|
String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTexture,
|
||||||
int audioStartBitrate, String audioCodec,
|
int audioStartBitrate, String audioCodec,
|
||||||
boolean noAudioProcessing, boolean useOpenSLES) {
|
boolean noAudioProcessing, boolean useOpenSLES) {
|
||||||
this.videoCallEnabled = videoCallEnabled;
|
this.videoCallEnabled = videoCallEnabled;
|
||||||
this.loopback = loopback;
|
this.loopback = loopback;
|
||||||
|
this.tracing = tracing;
|
||||||
this.videoWidth = videoWidth;
|
this.videoWidth = videoWidth;
|
||||||
this.videoHeight = videoHeight;
|
this.videoHeight = videoHeight;
|
||||||
this.videoFps = videoFps;
|
this.videoFps = videoFps;
|
||||||
@ -285,6 +287,10 @@ public class PeerConnectionClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createPeerConnectionFactoryInternal(Context context) {
|
private void createPeerConnectionFactoryInternal(Context context) {
|
||||||
|
PeerConnectionFactory.initializeInternalTracer();
|
||||||
|
if (peerConnectionParameters.tracing) {
|
||||||
|
PeerConnectionFactory.startInternalTracingCapture("/mnt/sdcard/webrtc-trace.txt");
|
||||||
|
}
|
||||||
Log.d(TAG, "Create peer connection factory. Use video: " +
|
Log.d(TAG, "Create peer connection factory. Use video: " +
|
||||||
peerConnectionParameters.videoCallEnabled);
|
peerConnectionParameters.videoCallEnabled);
|
||||||
isError = false;
|
isError = false;
|
||||||
@ -502,6 +508,8 @@ public class PeerConnectionClient {
|
|||||||
options = null;
|
options = null;
|
||||||
Log.d(TAG, "Closing peer connection done.");
|
Log.d(TAG, "Closing peer connection done.");
|
||||||
events.onPeerConnectionClosed();
|
events.onPeerConnectionClosed();
|
||||||
|
PeerConnectionFactory.stopInternalTracingCapture();
|
||||||
|
PeerConnectionFactory.shutdownInternalTracer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHDVideo() {
|
public boolean isHDVideo() {
|
||||||
|
|||||||
@ -40,6 +40,7 @@ public class SettingsActivity extends Activity
|
|||||||
|
|
||||||
private String keyPrefRoomServerUrl;
|
private String keyPrefRoomServerUrl;
|
||||||
private String keyPrefDisplayHud;
|
private String keyPrefDisplayHud;
|
||||||
|
private String keyPrefTracing;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -62,6 +63,7 @@ public class SettingsActivity extends Activity
|
|||||||
|
|
||||||
keyPrefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
keyPrefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
||||||
keyPrefDisplayHud = getString(R.string.pref_displayhud_key);
|
keyPrefDisplayHud = getString(R.string.pref_displayhud_key);
|
||||||
|
keyPrefTracing = getString(R.string.pref_tracing_key);
|
||||||
|
|
||||||
// Display the fragment as the main content.
|
// Display the fragment as the main content.
|
||||||
settingsFragment = new SettingsFragment();
|
settingsFragment = new SettingsFragment();
|
||||||
@ -97,6 +99,7 @@ public class SettingsActivity extends Activity
|
|||||||
|
|
||||||
updateSummary(sharedPreferences, keyPrefRoomServerUrl);
|
updateSummary(sharedPreferences, keyPrefRoomServerUrl);
|
||||||
updateSummaryB(sharedPreferences, keyPrefDisplayHud);
|
updateSummaryB(sharedPreferences, keyPrefDisplayHud);
|
||||||
|
updateSummaryB(sharedPreferences, keyPrefTracing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -122,6 +125,7 @@ public class SettingsActivity extends Activity
|
|||||||
|| key.equals(keyprefStartAudioBitrateValue)) {
|
|| key.equals(keyprefStartAudioBitrateValue)) {
|
||||||
updateSummaryBitrate(sharedPreferences, key);
|
updateSummaryBitrate(sharedPreferences, key);
|
||||||
} else if (key.equals(keyprefVideoCall)
|
} else if (key.equals(keyprefVideoCall)
|
||||||
|
|| key.equals(keyPrefTracing)
|
||||||
|| key.equals(keyprefCaptureQualitySlider)
|
|| key.equals(keyprefCaptureQualitySlider)
|
||||||
|| key.equals(keyprefHwCodec)
|
|| key.equals(keyprefHwCodec)
|
||||||
|| key.equals(keyprefCaptureToTexture)
|
|| key.equals(keyprefCaptureToTexture)
|
||||||
|
|||||||
@ -249,7 +249,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
|
|||||||
private PeerConnectionParameters createParametersForAudioCall() {
|
private PeerConnectionParameters createParametersForAudioCall() {
|
||||||
PeerConnectionParameters peerConnectionParameters =
|
PeerConnectionParameters peerConnectionParameters =
|
||||||
new PeerConnectionParameters(
|
new PeerConnectionParameters(
|
||||||
false, true, // videoCallEnabled, loopback.
|
false, true, false, // videoCallEnabled, loopback, tracing.
|
||||||
0, 0, 0, 0, "", true, false, // video codec parameters.
|
0, 0, 0, 0, "", true, false, // video codec parameters.
|
||||||
0, "OPUS", false, false); // audio codec parameters.
|
0, "OPUS", false, false); // audio codec parameters.
|
||||||
return peerConnectionParameters;
|
return peerConnectionParameters;
|
||||||
@ -259,7 +259,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
|
|||||||
String videoCodec, boolean captureToTexture) {
|
String videoCodec, boolean captureToTexture) {
|
||||||
PeerConnectionParameters peerConnectionParameters =
|
PeerConnectionParameters peerConnectionParameters =
|
||||||
new PeerConnectionParameters(
|
new PeerConnectionParameters(
|
||||||
true, true, // videoCallEnabled, loopback.
|
true, true, false, // videoCallEnabled, loopback, tracing.
|
||||||
0, 0, 0, 0, videoCodec, true, captureToTexture, // video codec parameters.
|
0, 0, 0, 0, videoCodec, true, captureToTexture, // video codec parameters.
|
||||||
0, "OPUS", false, false); // audio codec parameters.
|
0, "OPUS", false, false); // audio codec parameters.
|
||||||
return peerConnectionParameters;
|
return peerConnectionParameters;
|
||||||
|
|||||||
Reference in New Issue
Block a user