Bug 1025176: Save AEC dumps in a specified directory depending on platform/pref r=pkerr a=lmandel
authorRandell Jesup <rjesup@jesup.org>
Mon, 16 Jun 2014 15:51:45 -0400
changeset 207570 d59ee55bd050794d52f3d8f6ab17dec123e57045
parent 207569 5ddb3118d9ae531b2b6d784dd829a88dd5daea66
child 207571 b09992eb15735789a229d029a4947207e73be127
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspkerr, lmandel
bugs1025176
milestone32.0a2
Bug 1025176: Save AEC dumps in a specified directory depending on platform/pref r=pkerr a=lmandel
media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
media/webrtc/trunk/webrtc/modules/audio_processing/aec/aec_core.c
media/webrtc/trunk/webrtc/modules/audio_processing/aec/echo_cancellation.c
media/webrtc/trunk/webrtc/system_wrappers/interface/trace.h
media/webrtc/trunk/webrtc/system_wrappers/source/trace_impl.cc
modules/libpref/src/init/all.js
--- a/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
+++ b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
@@ -46,21 +46,22 @@ public:
     PR_LOG(log, PR_LOG_DEBUG, ("%s", message));
     return;
   }
 };
 
 static WebRtcTraceCallback gWebRtcCallback;
 
 #ifdef MOZILLA_INTERNAL_API
-void GetWebRtcLogPrefs(uint32_t *aTraceMask, nsACString* aLogFile, bool *aMultiLog)
+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;
@@ -85,95 +86,108 @@ void CheckOverrides(uint32_t *aTraceMask
   }
 
   const char *file_name = PR_GetEnv("WEBRTC_TRACE_FILE");
   if (file_name) {
     aLogFile->Assign(file_name);
   }
 }
 
-void ConfigWebRtcLog(uint32_t trace_mask, nsCString &aLogFile, bool multi_log)
+void ConfigWebRtcLog(uint32_t trace_mask, nsCString &aLogFile, nsCString &aAECLogDir, bool multi_log)
 {
-  if (gWebRtcTraceLoggingOn || trace_mask == 0) {
+  if (gWebRtcTraceLoggingOn) {
     return;
   }
 
-  if (aLogFile.IsEmpty()) {
+  nsCString logFile;
+  nsCString aecLogDir;
 #if defined(XP_WIN)
-    // Use the Windows TEMP environment variable as part of the default location.
-    const char *temp_dir = PR_GetEnv("TEMP");
-    if (!temp_dir) {
-      aLogFile.Assign(default_log);
-    } else {
-      aLogFile.Assign(temp_dir);
-      aLogFile.Append('/');
-      aLogFile.Append(default_log);
-    }
+  // Use the Windows TEMP environment variable as part of the default location.
+  const char *temp_dir = PR_GetEnv("TEMP");
+  if (!temp_dir) {
+    logFile.Assign(default_log);
+  } else {
+    logFile.Assign(temp_dir);
+    logFile.Append('/');
+    aecLogDir = logFile;
+    logFile.Append(default_log);
+  }
 #elif defined(ANDROID)
-    // Special case: use callback to pipe to NSPR logging.
-    aLogFile.Assign("nspr");
+  // Special case: use callback to pipe to NSPR logging.
+  logFile.Assign("nspr");
+  // for AEC, force the user to specify a directory
+  aecLogDir.Assign("/dev/null");
 #else
-    // UNIX-like place for the others
-    aLogFile.Assign("/tmp/");
-    aLogFile.Append(default_log);
+  // UNIX-like place for the others
+  logFile.Assign("/tmp/");
+  aecLogDir = logFile;
+  logFile.Append(default_log);
 #endif
+  if (aLogFile.IsEmpty()) {
+    aLogFile = logFile;
+  }
+  if (aAECLogDir.IsEmpty()) {
+    aAECLogDir = aecLogDir;
   }
 
   webrtc::Trace::set_level_filter(trace_mask);
-  if (aLogFile.EqualsLiteral("nspr")) {
-    webrtc::Trace::SetTraceCallback(&gWebRtcCallback);
-  } else {
-    webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log);
+  webrtc::Trace::set_aec_debug_filename(aAECLogDir.get());
+  if (trace_mask != 0) {
+    if (aLogFile.EqualsLiteral("nspr")) {
+      webrtc::Trace::SetTraceCallback(&gWebRtcCallback);
+    } else {
+      webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log);
+    }
   }
-
   return;
 }
 
 void StartWebRtcLog(uint32_t log_level)
 {
   if (gWebRtcTraceLoggingOn && log_level != 0) {
     return;
   }
 
-  if (log_level == 0) { 
+  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, &multi_log);
+  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, multi_log);
+  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, &multi_log);
+  GetWebRtcLogPrefs(&trace_mask, &log_file, &aec_log_dir, &multi_log);
 #endif
   CheckOverrides(&trace_mask, &log_file, &multi_log);
-  ConfigWebRtcLog(trace_mask, log_file, multi_log);
+  ConfigWebRtcLog(trace_mask, log_file, aec_log_dir, multi_log);
   return;
 }
-
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -247,16 +247,17 @@ int32_t
 WebrtcGlobalInformation::DebugLevel(const GlobalObject& aGlobal)
 {
   return sLastSetLevel;
 }
 
 void
 WebrtcGlobalInformation::SetAecDebug(const GlobalObject& aGlobal, bool aEnable)
 {
+  StartWebRtcLog(sLastSetLevel); // to make it read the aec path
   webrtc::Trace::set_aec_debug(aEnable);
   sLastAECDebug = aEnable;
 }
 
 bool
 WebrtcGlobalInformation::AecDebug(const GlobalObject& aGlobal)
 {
   return sLastAECDebug;
--- a/media/webrtc/trunk/webrtc/modules/audio_processing/aec/aec_core.c
+++ b/media/webrtc/trunk/webrtc/modules/audio_processing/aec/aec_core.c
@@ -26,16 +26,17 @@
 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
 #include "webrtc/modules/audio_processing/utility/ring_buffer.h"
 #include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
 #include "webrtc/typedefs.h"
 
 extern int AECDebug();
 extern uint32_t AECDebugMaxSize();
 extern void AECDebugEnable(uint32_t enable);
+extern void AECDebugFilenameBase(char *buffer, size_t size);
 static void OpenCoreDebugFiles(AecCore* aec, int *instance_count);
 
 // Buffer size (samples)
 static const size_t kBufSizePartitions = 250;  // 1 second of audio in 16 kHz.
 
 // Metrics
 static const int subCountLen = 4;
 static const int countLen = 50;
@@ -1725,26 +1726,44 @@ static void TimeToFrequency(float time_d
 static void
 OpenCoreDebugFiles(AecCore* aec,
                    int *instance_count)
 {
   int error = 0;
   // XXX  If this impacts performance (opening files here), move file open
   // to Trace::set_aec_debug(), and just grab them here
   if (AECDebug() && !aec->farFile) {
-    char filename[128];
     if (!aec->farFile) {
+      char path[1024];
+      char *filename;
+      path[0] = '\0';
+      AECDebugFilenameBase(path, sizeof(path));
+      filename = path + strlen(path);
+      if (&path[sizeof(path)] - filename < 128) {
+        return; // avoid a lot of snprintf's and checks lower
+      }
+      if (filename > path) {
+#ifdef XP_WIN
+        if (*(filename-1) != '\\') {
+          *filename++ = '\\';
+        }
+#else
+        if (*(filename-1) != '/') {
+          *filename++ = '/';
+        }
+#endif
+      }
       sprintf(filename, "aec_far%d.pcm", webrtc_aec_instance_count);
-      aec->farFile = fopen(filename, "wb");
+      aec->farFile = fopen(path, "wb");
       sprintf(filename, "aec_near%d.pcm", webrtc_aec_instance_count);
-      aec->nearFile = fopen(filename, "wb");
+      aec->nearFile = fopen(path, "wb");
       sprintf(filename, "aec_out%d.pcm", webrtc_aec_instance_count);
-      aec->outFile = fopen(filename, "wb");
+      aec->outFile = fopen(path, "wb");
       sprintf(filename, "aec_out_linear%d.pcm", webrtc_aec_instance_count);
-      aec->outLinearFile = fopen(filename, "wb");
+      aec->outLinearFile = fopen(path, "wb");
       aec->debugWritten = 0;
       if (!aec->outLinearFile || !aec->outFile || !aec->nearFile || !aec->farFile) {
         error = 1;
       }
     }
   }
   if (error ||
       (!AECDebug() && aec->farFile)) {
--- a/media/webrtc/trunk/webrtc/modules/audio_processing/aec/echo_cancellation.c
+++ b/media/webrtc/trunk/webrtc/modules/audio_processing/aec/echo_cancellation.c
@@ -25,16 +25,17 @@
 #include "webrtc/modules/audio_processing/aec/aec_resampler.h"
 #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h"
 #include "webrtc/modules/audio_processing/utility/ring_buffer.h"
 #include "webrtc/typedefs.h"
 
 extern int AECDebug();
 extern uint32_t AECDebugMaxSize();
 extern void AECDebugEnable(uint32_t enable);
+extern void AECDebugFilenameBase(char *buffer, size_t size);
 static void OpenDebugFiles(aecpc_t* aecpc, int *instance_count);
 
 // Measured delays [ms]
 // Device                Chrome  GTP
 // MacBook Air           10
 // MacBook Retina        10      100
 // MacPro                30?
 //
@@ -980,23 +981,41 @@ static void EstBufDelayExtended(aecpc_t*
 static void
 OpenDebugFiles(aecpc_t* aecpc,
                int *instance_count)
 {
   int error = 0;
   // XXX  If this impacts performance (opening files here), move file open
   // to Trace::set_aec_debug(), and just grab them here
   if (AECDebug() && !aecpc->bufFile) {
-    char filename[128];
+    char path[1024];
+    char *filename;
+    path[0] = '\0';
+    AECDebugFilenameBase(path, sizeof(path));
+    filename = path + strlen(path);
+    if (&path[sizeof(path)] - filename < 128) {
+      return; // avoid a lot of snprintf's and checks lower
+    }
+    if (filename > path) {
+#ifdef XP_WIN
+      if (*(filename-1) != '\\') {
+        *filename++ = '\\';
+      }
+#else
+      if (*(filename-1) != '/') {
+        *filename++ = '/';
+      }
+#endif
+    }
     sprintf(filename, "aec_buf%d.dat", *instance_count);
-    aecpc->bufFile = fopen(filename, "wb");
+    aecpc->bufFile = fopen(path, "wb");
     sprintf(filename, "aec_skew%d.dat", *instance_count);
-    aecpc->skewFile = fopen(filename, "wb");
+    aecpc->skewFile = fopen(path, "wb");
     sprintf(filename, "aec_delay%d.dat", *instance_count);
-    aecpc->delayFile = fopen(filename, "wb");
+    aecpc->delayFile = fopen(path, "wb");
 
     if (!aecpc->bufFile || !aecpc->skewFile || !aecpc->delayFile) {
       error = 1;
     } else {
       (*instance_count)++;
     }
   }
   if (error ||
--- a/media/webrtc/trunk/webrtc/system_wrappers/interface/trace.h
+++ b/media/webrtc/trunk/webrtc/system_wrappers/interface/trace.h
@@ -13,16 +13,17 @@
  *  messages. Apply filtering to avoid that.
  */
 
 #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
 
 #include "webrtc/common_types.h"
 #include "webrtc/typedefs.h"
+#include <string>
 
 namespace webrtc {
 
 #if defined(WEBRTC_RESTRICT_LOGGING)
 // Disable all TRACE macros. The LOG macro is still functional.
 #define WEBRTC_TRACE true ? (void) 0 : Trace::Add
 #else
 #define WEBRTC_TRACE Trace::Add
@@ -54,16 +55,20 @@ class Trace {
   // Returns what type of messages are written to the trace file.
   static uint32_t level_filter() { return level_filter_; }
 
   // Enable dumping of AEC inputs and outputs.  Can be changed in mid-call
   static void set_aec_debug(bool enable) { aec_debug_ = enable; }
   static void set_aec_debug_size(uint32_t size) { aec_debug_size_ = size; }
   static bool aec_debug() { return aec_debug_; }
   static uint32_t aec_debug_size() { return aec_debug_size_; }
+  static void aec_debug_filename(char *buffer, size_t size);
+  static void set_aec_debug_filename(const char* filename) {
+    aec_filename_base_ = filename;
+  }
 
   // Sets the file name. If add_file_counter is false the same file will be
   // reused when it fills up. If it's true a new file with incremented name
   // will be used.
   static int32_t SetTraceFile(const char* file_name,
                               const bool add_file_counter = false);
 
   // Returns the name of the file that the trace is currently writing to.
@@ -88,19 +93,21 @@ class Trace {
                   const TraceModule module,
                   const int32_t id,
                   const char* msg, ...);
 
  private:
   static uint32_t level_filter_;
   static bool aec_debug_;
   static uint32_t aec_debug_size_;
+  static std::string aec_filename_base_;
 };
 
 }  // namespace webrtc
 
 extern "C" {
   extern int AECDebug();
   extern uint32_t AECDebugMaxSize();
   extern void AECDebugEnable(uint32_t enable);
+  extern void AECDebugFilenameBase(char *buffer, size_t size);
 }
 
 #endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
--- a/media/webrtc/trunk/webrtc/system_wrappers/source/trace_impl.cc
+++ b/media/webrtc/trunk/webrtc/system_wrappers/source/trace_impl.cc
@@ -28,26 +28,35 @@
 #ifdef _WIN32
 #pragma warning(disable:4355)
 #endif  // _WIN32
 
 extern "C" {
   int AECDebug() { return (int) webrtc::Trace::aec_debug(); }
   uint32_t AECDebugMaxSize() { return webrtc::Trace::aec_debug_size(); }
   void AECDebugEnable(uint32_t enable) { webrtc::Trace::set_aec_debug(!!enable); }
+  void AECDebugFilenameBase(char *buffer, size_t size) {
+    webrtc::Trace::aec_debug_filename(buffer, size);
+  }
 }
 
 namespace webrtc {
 
 const int Trace::kBoilerplateLength = 71;
 const int Trace::kTimestampPosition = 13;
 const int Trace::kTimestampLength = 12;
 uint32_t Trace::level_filter_ = kTraceDefault;
 bool Trace::aec_debug_ = false;
 uint32_t Trace::aec_debug_size_ = 4*1024*1024;
+std::string Trace::aec_filename_base_;
+
+void Trace::aec_debug_filename(char *buffer, size_t size) {
+  strncpy(buffer, aec_filename_base_.c_str(), size-1);
+  buffer[size-1] = '\0';
+}
 
 // Construct On First Use idiom. Avoids "static initialization order fiasco".
 TraceImpl* TraceImpl::StaticInstance(CountOperation count_operation,
                                      const TraceLevel level) {
   // Sanities to avoid taking lock unless absolutely necessary (for
   // performance reasons). count_operation == kAddRefNoCreate implies that a
   // message will be written to file.
   if ((level != kTraceAll) && (count_operation == kAddRefNoCreate)) {
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -255,21 +255,18 @@ pref("media.navigator.load_adapt.measure
 pref("media.navigator.load_adapt.avg_seconds",3);
 pref("media.navigator.load_adapt.high_load","0.90");
 pref("media.navigator.load_adapt.low_load","0.40");
 pref("media.navigator.video.default_fps",30);
 pref("media.navigator.video.default_minfps",10);
 
 pref("media.webrtc.debug.trace_mask", 0);
 pref("media.webrtc.debug.multi_log", false);
-#if defined(ANDROID) || defined(XP_WIN)
+pref("media.webrtc.debug.aec_log_dir", "");
 pref("media.webrtc.debug.log_file", "");
-#else
-pref("media.webrtc.debug.log_file", "/tmp/WebRTC.log");
-#endif
 pref("media.webrtc.debug.aec_dump_max_size", 4194304); // 4MB
 
 #ifdef MOZ_WIDGET_GONK
 pref("media.navigator.video.default_width",320);
 pref("media.navigator.video.default_height",240);
 pref("media.peerconnection.enabled", true);
 pref("media.peerconnection.video.enabled", true);
 pref("media.navigator.video.max_fs", 1200); // 640x480 == 1200mb