diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc index eea5fbd841..f80f5766e8 100644 --- a/talk/app/webrtc/java/jni/peerconnection_jni.cc +++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc @@ -1306,11 +1306,12 @@ JOW(jlong, PeerConnectionFactory_nativeCreateAudioTrack)( } JOW(jboolean, PeerConnectionFactory_nativeStartAecDump)( - JNIEnv* jni, jclass, jlong native_factory, jint file) { + JNIEnv* jni, jclass, jlong native_factory, jint file, + jint filesize_limit_bytes) { #if defined(ANDROID) rtc::scoped_refptr factory( factoryFromJava(native_factory)); - return factory->StartAecDump(file); + return factory->StartAecDump(file, filesize_limit_bytes); #else return false; #endif diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java index 37f0bee7ed..6ee062b14d 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java @@ -148,8 +148,8 @@ public class PeerConnectionFactory { // Starts recording an AEC dump. Ownership of the file is transfered to the // native code. If an AEC dump is already in progress, it will be stopped and // a new one will start using the provided file. - public boolean startAecDump(int file_descriptor) { - return nativeStartAecDump(nativeFactory, file_descriptor); + public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) { + return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes); } // Stops recording an AEC dump. If no AEC dump is currently being recorded, @@ -256,7 +256,8 @@ public class PeerConnectionFactory { private static native long nativeCreateAudioTrack( long nativeFactory, String id, long nativeSource); - private static native boolean nativeStartAecDump(long nativeFactory, int file_descriptor); + private static native boolean nativeStartAecDump( + long nativeFactory, int file_descriptor, int filesize_limit_bytes); private static native void nativeStopAecDump(long nativeFactory); diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc index c58f88cb41..ab8fdf5b25 100644 --- a/talk/app/webrtc/peerconnectionfactory.cc +++ b/talk/app/webrtc/peerconnectionfactory.cc @@ -225,9 +225,10 @@ PeerConnectionFactory::CreateVideoSource( return VideoSourceProxy::Create(signaling_thread_, source); } -bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) { +bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file, + int64_t max_size_bytes) { RTC_DCHECK(signaling_thread_->IsCurrent()); - return channel_manager_->StartAecDump(file); + return channel_manager_->StartAecDump(file, max_size_bytes); } void PeerConnectionFactory::StopAecDump() { diff --git a/talk/app/webrtc/peerconnectionfactory.h b/talk/app/webrtc/peerconnectionfactory.h index 8b274e118c..a38218aebe 100644 --- a/talk/app/webrtc/peerconnectionfactory.h +++ b/talk/app/webrtc/peerconnectionfactory.h @@ -82,7 +82,7 @@ class PeerConnectionFactory : public PeerConnectionFactoryInterface { CreateAudioTrack(const std::string& id, AudioSourceInterface* audio_source) override; - bool StartAecDump(rtc::PlatformFile file) override; + bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) override; void StopAecDump() override; bool StartRtcEventLog(rtc::PlatformFile file) override; void StopRtcEventLog() override; diff --git a/talk/app/webrtc/peerconnectionfactoryproxy.h b/talk/app/webrtc/peerconnectionfactoryproxy.h index 714ce6b7eb..1d0b6aab5a 100644 --- a/talk/app/webrtc/peerconnectionfactoryproxy.h +++ b/talk/app/webrtc/peerconnectionfactoryproxy.h @@ -62,7 +62,7 @@ BEGIN_PROXY_MAP(PeerConnectionFactory) CreateVideoTrack, const std::string&, VideoSourceInterface*) PROXY_METHOD2(rtc::scoped_refptr, CreateAudioTrack, const std::string&, AudioSourceInterface*) - PROXY_METHOD1(bool, StartAecDump, rtc::PlatformFile) + PROXY_METHOD2(bool, StartAecDump, rtc::PlatformFile, int64_t) PROXY_METHOD0(void, StopAecDump) PROXY_METHOD1(bool, StartRtcEventLog, rtc::PlatformFile) PROXY_METHOD0(void, StopRtcEventLog) diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h index da99a7b876..e449dc4721 100644 --- a/talk/app/webrtc/peerconnectioninterface.h +++ b/talk/app/webrtc/peerconnectioninterface.h @@ -578,9 +578,11 @@ class PeerConnectionFactoryInterface : public rtc::RefCountInterface { // Starts AEC dump using existing file. Takes ownership of |file| and passes // it on to VoiceEngine (via other objects) immediately, which will take // the ownerhip. If the operation fails, the file will be closed. - // TODO(grunell): Remove when Chromium has started to use AEC in each source. - // http://crbug.com/264611. - virtual bool StartAecDump(rtc::PlatformFile file) = 0; + // A maximum file size in bytes can be specified. When the file size limit is + // reached, logging is stopped automatically. If max_size_bytes is set to a + // value <= 0, no limit will be used, and logging will continue until the + // StopAecDump function is called. + virtual bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) = 0; // Stops logging the AEC dump. virtual void StopAecDump() = 0; diff --git a/talk/media/base/fakemediaengine.h b/talk/media/base/fakemediaengine.h index 149704f92d..c17ab28b1b 100644 --- a/talk/media/base/fakemediaengine.h +++ b/talk/media/base/fakemediaengine.h @@ -762,7 +762,9 @@ class FakeVoiceEngine : public FakeBaseEngine { int GetInputLevel() { return 0; } - bool StartAecDump(rtc::PlatformFile file) { return false; } + bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) { + return false; + } void StopAecDump() {} diff --git a/talk/media/base/mediaengine.h b/talk/media/base/mediaengine.h index 467614bb3e..3f7eec239b 100644 --- a/talk/media/base/mediaengine.h +++ b/talk/media/base/mediaengine.h @@ -102,8 +102,10 @@ class MediaEngineInterface { virtual const std::vector& video_codecs() = 0; virtual RtpCapabilities GetVideoCapabilities() = 0; - // Starts AEC dump using existing file. - virtual bool StartAecDump(rtc::PlatformFile file) = 0; + // Starts AEC dump using existing file, a maximum file size in bytes can be + // specified. Logging is stopped just before the size limit is exceeded. + // If max_size_bytes is set to a value <= 0, no limit will be used. + virtual bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) = 0; // Stops recording AEC dump. virtual void StopAecDump() = 0; @@ -185,8 +187,8 @@ class CompositeMediaEngine : public MediaEngineInterface { return video_.GetCapabilities(); } - virtual bool StartAecDump(rtc::PlatformFile file) { - return voice_.StartAecDump(file); + virtual bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) { + return voice_.StartAecDump(file, max_size_bytes); } virtual void StopAecDump() { diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h index 65ba927cc5..4c6c016a38 100644 --- a/talk/media/webrtc/fakewebrtcvoiceengine.h +++ b/talk/media/webrtc/fakewebrtcvoiceengine.h @@ -114,8 +114,9 @@ class FakeAudioProcessing : public webrtc::AudioProcessing { WEBRTC_VOID_STUB(set_stream_key_pressed, (bool key_pressed)); WEBRTC_VOID_STUB(set_delay_offset_ms, (int offset)); WEBRTC_STUB_CONST(delay_offset_ms, ()); - WEBRTC_STUB(StartDebugRecording, (const char filename[kMaxFilenameSize])); - WEBRTC_STUB(StartDebugRecording, (FILE* handle)); + WEBRTC_STUB(StartDebugRecording, + (const char filename[kMaxFilenameSize], int64_t max_size_bytes)); + WEBRTC_STUB(StartDebugRecording, (FILE * handle, int64_t max_size_bytes)); WEBRTC_STUB(StopDebugRecording, ()); WEBRTC_VOID_STUB(UpdateHistogramsOnCallEnd, ()); webrtc::EchoCancellation* echo_cancellation() const override { return NULL; } diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc index 4285af3549..6c07ff4154 100644 --- a/talk/media/webrtc/webrtcvoiceengine.cc +++ b/talk/media/webrtc/webrtcvoiceengine.cc @@ -1014,7 +1014,8 @@ bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm) { return true; } -bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file) { +bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file, + int64_t max_size_bytes) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); if (!aec_dump_file_stream) { @@ -1024,7 +1025,8 @@ bool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file) { return false; } StopAecDump(); - if (voe_wrapper_->processing()->StartDebugRecording(aec_dump_file_stream) != + if (voe_wrapper_->base()->audio_processing()->StartDebugRecording( + aec_dump_file_stream, max_size_bytes) != webrtc::AudioProcessing::kNoError) { LOG_RTCERR0(StartDebugRecording); fclose(aec_dump_file_stream); @@ -1038,8 +1040,8 @@ void WebRtcVoiceEngine::StartAecDump(const std::string& filename) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); if (!is_dumping_aec_) { // Start dumping AEC when we are not dumping. - if (voe_wrapper_->processing()->StartDebugRecording( - filename.c_str()) != webrtc::AudioProcessing::kNoError) { + if (voe_wrapper_->base()->audio_processing()->StartDebugRecording( + filename.c_str(), -1) != webrtc::AudioProcessing::kNoError) { LOG_RTCERR1(StartDebugRecording, filename.c_str()); } else { is_dumping_aec_ = true; @@ -1051,7 +1053,7 @@ void WebRtcVoiceEngine::StopAecDump() { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); if (is_dumping_aec_) { // Stop dumping AEC when we are dumping. - if (voe_wrapper_->processing()->StopDebugRecording() != + if (voe_wrapper_->base()->audio_processing()->StopDebugRecording() != webrtc::AudioProcessing::kNoError) { LOG_RTCERR0(StopDebugRecording); } diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h index 0f2f59e492..ce3bdf3ed7 100644 --- a/talk/media/webrtc/webrtcvoiceengine.h +++ b/talk/media/webrtc/webrtcvoiceengine.h @@ -94,8 +94,11 @@ class WebRtcVoiceEngine final : public webrtc::TraceCallback { // Set the external ADM. This can only be called before Init. bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm); - // Starts AEC dump using existing file. - bool StartAecDump(rtc::PlatformFile file); + // Starts AEC dump using an existing file. A maximum file size in bytes can be + // specified. When the maximum file size is reached, logging is stopped and + // the file is closed. If max_size_bytes is set to <= 0, no limit will be + // used. + bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes); // Stops AEC dump. void StopAecDump(); diff --git a/talk/session/media/channelmanager.cc b/talk/session/media/channelmanager.cc index e7a4b8bddb..bd89a41328 100644 --- a/talk/session/media/channelmanager.cc +++ b/talk/session/media/channelmanager.cc @@ -550,9 +550,11 @@ void ChannelManager::OnMessage(rtc::Message* message) { } } -bool ChannelManager::StartAecDump(rtc::PlatformFile file) { - return worker_thread_->Invoke( - Bind(&MediaEngineInterface::StartAecDump, media_engine_.get(), file)); +bool ChannelManager::StartAecDump(rtc::PlatformFile file, + int64_t max_size_bytes) { + return worker_thread_->Invoke(Bind(&MediaEngineInterface::StartAecDump, + media_engine_.get(), file, + max_size_bytes)); } void ChannelManager::StopAecDump() { diff --git a/talk/session/media/channelmanager.h b/talk/session/media/channelmanager.h index 2bc516bfaa..f69bf9a293 100644 --- a/talk/session/media/channelmanager.h +++ b/talk/session/media/channelmanager.h @@ -162,8 +162,10 @@ class ChannelManager : public rtc::MessageHandler, // The operations below occur on the main thread. - // Starts AEC dump using existing file. - bool StartAecDump(rtc::PlatformFile file); + // Starts AEC dump using existing file, with a specified maximum file size in + // bytes. When the limit is reached, logging will stop and the file will be + // closed. If max_size_bytes is set to <= 0, no limit will be used. + bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes); // Stops recording AEC dump. void StopAecDump(); diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java index 75ff245c6d..eb4d959067 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java @@ -498,7 +498,7 @@ public class PeerConnectionClient { ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_TRUNCATE); - factory.startAecDump(aecDumpFileDescriptor.getFd()); + factory.startAecDump(aecDumpFileDescriptor.getFd(), -1); } catch(IOException e) { Log.e(TAG, "Can not open aecdump file", e); } diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc index 744309c774..0934b1e4af 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl.cc +++ b/webrtc/modules/audio_processing/audio_processing_impl.cc @@ -647,6 +647,7 @@ int AudioProcessingImpl::ProcessStream(const float* const* src, ++i) msg->add_output_channel(dest[i], channel_size); RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.capture)); } #endif @@ -734,6 +735,7 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; msg->set_output_data(frame->data_, data_size); RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.capture)); } #endif @@ -901,6 +903,7 @@ int AudioProcessingImpl::AnalyzeReverseStreamLocked( i < formats_.api_format.reverse_input_stream().num_channels(); ++i) msg->add_channel(src[i], channel_size); RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.render)); } #endif @@ -969,6 +972,7 @@ int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; msg->set_data(frame->data_, data_size); RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.render)); } #endif @@ -1054,7 +1058,8 @@ int AudioProcessingImpl::delay_offset_ms() const { } int AudioProcessingImpl::StartDebugRecording( - const char filename[AudioProcessing::kMaxFilenameSize]) { + const char filename[AudioProcessing::kMaxFilenameSize], + int64_t max_log_size_bytes) { // Run in a single-threaded manner. rtc::CritScope cs_render(&crit_render_); rtc::CritScope cs_capture(&crit_capture_); @@ -1065,6 +1070,7 @@ int AudioProcessingImpl::StartDebugRecording( } #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP + debug_dump_.num_bytes_left_for_log_ = max_log_size_bytes; // Stop any ongoing recording. if (debug_dump_.debug_file->Open()) { if (debug_dump_.debug_file->CloseFile() == -1) { @@ -1085,7 +1091,8 @@ int AudioProcessingImpl::StartDebugRecording( #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP } -int AudioProcessingImpl::StartDebugRecording(FILE* handle) { +int AudioProcessingImpl::StartDebugRecording(FILE* handle, + int64_t max_log_size_bytes) { // Run in a single-threaded manner. rtc::CritScope cs_render(&crit_render_); rtc::CritScope cs_capture(&crit_capture_); @@ -1095,6 +1102,8 @@ int AudioProcessingImpl::StartDebugRecording(FILE* handle) { } #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP + debug_dump_.num_bytes_left_for_log_ = max_log_size_bytes; + // Stop any ongoing recording. if (debug_dump_.debug_file->Open()) { if (debug_dump_.debug_file->CloseFile() == -1) { @@ -1120,7 +1129,7 @@ int AudioProcessingImpl::StartDebugRecordingForPlatformFile( rtc::CritScope cs_render(&crit_render_); rtc::CritScope cs_capture(&crit_capture_); FILE* stream = rtc::FdopenPlatformFileForWriting(handle); - return StartDebugRecording(stream); + return StartDebugRecording(stream, -1); } int AudioProcessingImpl::StopDebugRecording() { @@ -1416,6 +1425,7 @@ void AudioProcessingImpl::UpdateHistogramsOnCallEnd() { #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP int AudioProcessingImpl::WriteMessageToDebugFile( FileWrapper* debug_file, + int64_t* filesize_limit_bytes, rtc::CriticalSection* crit_debug, ApmDebugDumpThreadState* debug_state) { int32_t size = debug_state->event_msg->ByteSize(); @@ -1433,7 +1443,19 @@ int AudioProcessingImpl::WriteMessageToDebugFile( { // Ensure atomic writes of the message. - rtc::CritScope cs_capture(crit_debug); + rtc::CritScope cs_debug(crit_debug); + + RTC_DCHECK(debug_file->Open()); + // Update the byte counter. + if (*filesize_limit_bytes >= 0) { + *filesize_limit_bytes -= + (sizeof(int32_t) + debug_state->event_str.length()); + if (*filesize_limit_bytes < 0) { + // Not enough bytes are left to write this message, so stop logging. + debug_file->CloseFile(); + return kNoError; + } + } // Write message preceded by its size. if (!debug_file->Write(&size, sizeof(int32_t))) { return kFileError; @@ -1468,6 +1490,7 @@ int AudioProcessingImpl::WriteInitMessage() { // debug_dump_.capture.event_msg. RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.capture)); return kNoError; } @@ -1520,6 +1543,7 @@ int AudioProcessingImpl::WriteConfigMessage(bool forced) { debug_dump_.capture.event_msg->mutable_config()->CopyFrom(config); RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), + &debug_dump_.num_bytes_left_for_log_, &crit_debug_, &debug_dump_.capture)); return kNoError; } diff --git a/webrtc/modules/audio_processing/audio_processing_impl.h b/webrtc/modules/audio_processing/audio_processing_impl.h index b310896903..fbb9b6e7cc 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl.h +++ b/webrtc/modules/audio_processing/audio_processing_impl.h @@ -57,8 +57,10 @@ class AudioProcessingImpl : public AudioProcessing { int Initialize(const ProcessingConfig& processing_config) override; void SetExtraOptions(const Config& config) override; void UpdateHistogramsOnCallEnd() override; - int StartDebugRecording(const char filename[kMaxFilenameSize]) override; - int StartDebugRecording(FILE* handle) override; + int StartDebugRecording(const char filename[kMaxFilenameSize], + int64_t max_log_size_bytes) override; + int StartDebugRecording(FILE* handle, int64_t max_log_size_bytes) override; + int StartDebugRecordingForPlatformFile(rtc::PlatformFile handle) override; int StopDebugRecording() override; @@ -144,6 +146,9 @@ class AudioProcessingImpl : public AudioProcessing { struct ApmDebugDumpState { ApmDebugDumpState() : debug_file(FileWrapper::Create()) {} + // Number of bytes that can still be written to the log before the maximum + // size is reached. A value of <= 0 indicates that no limit is used. + int64_t num_bytes_left_for_log_ = -1; rtc::scoped_ptr debug_file; ApmDebugDumpThreadState render; ApmDebugDumpThreadState capture; @@ -222,6 +227,7 @@ class AudioProcessingImpl : public AudioProcessing { // TODO(andrew): make this more graceful. Ideally we would split this stuff // out into a separate class with an "enabled" and "disabled" implementation. static int WriteMessageToDebugFile(FileWrapper* debug_file, + int64_t* filesize_limit_bytes, rtc::CriticalSection* crit_debug, ApmDebugDumpThreadState* debug_state); int WriteInitMessage() EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_); diff --git a/webrtc/modules/audio_processing/include/audio_processing.h b/webrtc/modules/audio_processing/include/audio_processing.h index 9a3a4b32d5..bf3565d9ff 100644 --- a/webrtc/modules/audio_processing/include/audio_processing.h +++ b/webrtc/modules/audio_processing/include/audio_processing.h @@ -415,13 +415,22 @@ class AudioProcessing { // Starts recording debugging information to a file specified by |filename|, // a NULL-terminated string. If there is an ongoing recording, the old file // will be closed, and recording will continue in the newly specified file. - // An already existing file will be overwritten without warning. + // An already existing file will be overwritten without warning. A maximum + // file size (in bytes) for the log can be specified. The logging is stopped + // once the limit has been reached. If max_log_size_bytes is set to a value + // <= 0, no limit will be used. static const size_t kMaxFilenameSize = 1024; - virtual int StartDebugRecording(const char filename[kMaxFilenameSize]) = 0; + virtual int StartDebugRecording(const char filename[kMaxFilenameSize], + int64_t max_log_size_bytes) = 0; // Same as above but uses an existing file handle. Takes ownership // of |handle| and closes it at StopDebugRecording(). - virtual int StartDebugRecording(FILE* handle) = 0; + virtual int StartDebugRecording(FILE* handle, int64_t max_log_size_bytes) = 0; + + // TODO(ivoc): Remove this function after Chrome stops using it. + int StartDebugRecording(FILE* handle) { + return StartDebugRecording(handle, -1); + } // Same as above but uses an existing PlatformFile handle. Takes ownership // of |handle| and closes it at StopDebugRecording(). diff --git a/webrtc/modules/audio_processing/include/mock_audio_processing.h b/webrtc/modules/audio_processing/include/mock_audio_processing.h index 9e1f2d5861..3a7e3087cf 100644 --- a/webrtc/modules/audio_processing/include/mock_audio_processing.h +++ b/webrtc/modules/audio_processing/include/mock_audio_processing.h @@ -250,10 +250,11 @@ class MockAudioProcessing : public AudioProcessing { void(int offset)); MOCK_CONST_METHOD0(delay_offset_ms, int()); - MOCK_METHOD1(StartDebugRecording, - int(const char filename[kMaxFilenameSize])); - MOCK_METHOD1(StartDebugRecording, - int(FILE* handle)); + MOCK_METHOD2(StartDebugRecording, + int(const char filename[kMaxFilenameSize], + int64_t max_log_size_bytes)); + MOCK_METHOD2(StartDebugRecording, + int(FILE* handle, int64_t max_log_size_bytes)); MOCK_METHOD0(StopDebugRecording, int()); MOCK_METHOD0(UpdateHistogramsOnCallEnd, void()); diff --git a/webrtc/modules/audio_processing/test/audio_processing_unittest.cc b/webrtc/modules/audio_processing/test/audio_processing_unittest.cc index 94aea17277..1b37120456 100644 --- a/webrtc/modules/audio_processing/test/audio_processing_unittest.cc +++ b/webrtc/modules/audio_processing/test/audio_processing_unittest.cc @@ -383,7 +383,8 @@ class ApmTest : public ::testing::Test { int AnalyzeReverseStreamChooser(Format format); void ProcessDebugDump(const std::string& in_filename, const std::string& out_filename, - Format format); + Format format, + int max_size_bytes); void VerifyDebugDumpTest(Format format); const std::string output_path_; @@ -1706,7 +1707,8 @@ TEST_F(ApmTest, SplittingFilter) { #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP void ApmTest::ProcessDebugDump(const std::string& in_filename, const std::string& out_filename, - Format format) { + Format format, + int max_size_bytes) { FILE* in_file = fopen(in_filename.c_str(), "rb"); ASSERT_TRUE(in_file != NULL); audioproc::Event event_msg; @@ -1734,7 +1736,8 @@ void ApmTest::ProcessDebugDump(const std::string& in_filename, if (first_init) { // StartDebugRecording() writes an additional init message. Don't start // recording until after the first init to avoid the extra message. - EXPECT_NOERR(apm_->StartDebugRecording(out_filename.c_str())); + EXPECT_NOERR( + apm_->StartDebugRecording(out_filename.c_str(), max_size_bytes)); first_init = false; } @@ -1809,34 +1812,54 @@ void ApmTest::VerifyDebugDumpTest(Format format) { test::OutputPath(), std::string("ref") + format_string + "_aecdump"); const std::string out_filename = test::TempFilename( test::OutputPath(), std::string("out") + format_string + "_aecdump"); + const std::string limited_filename = test::TempFilename( + test::OutputPath(), std::string("limited") + format_string + "_aecdump"); + const size_t logging_limit_bytes = 100000; + // We expect at least this many bytes in the created logfile. + const size_t logging_expected_bytes = 95000; EnableAllComponents(); - ProcessDebugDump(in_filename, ref_filename, format); - ProcessDebugDump(ref_filename, out_filename, format); + ProcessDebugDump(in_filename, ref_filename, format, -1); + ProcessDebugDump(ref_filename, out_filename, format, -1); + ProcessDebugDump(ref_filename, limited_filename, format, logging_limit_bytes); FILE* ref_file = fopen(ref_filename.c_str(), "rb"); FILE* out_file = fopen(out_filename.c_str(), "rb"); + FILE* limited_file = fopen(limited_filename.c_str(), "rb"); ASSERT_TRUE(ref_file != NULL); ASSERT_TRUE(out_file != NULL); + ASSERT_TRUE(limited_file != NULL); rtc::scoped_ptr ref_bytes; rtc::scoped_ptr out_bytes; + rtc::scoped_ptr limited_bytes; size_t ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes); size_t out_size = ReadMessageBytesFromFile(out_file, &out_bytes); + size_t limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes); size_t bytes_read = 0; + size_t bytes_read_limited = 0; while (ref_size > 0 && out_size > 0) { bytes_read += ref_size; + bytes_read_limited += limited_size; EXPECT_EQ(ref_size, out_size); + EXPECT_GE(ref_size, limited_size); EXPECT_EQ(0, memcmp(ref_bytes.get(), out_bytes.get(), ref_size)); + EXPECT_EQ(0, memcmp(ref_bytes.get(), limited_bytes.get(), limited_size)); ref_size = ReadMessageBytesFromFile(ref_file, &ref_bytes); out_size = ReadMessageBytesFromFile(out_file, &out_bytes); + limited_size = ReadMessageBytesFromFile(limited_file, &limited_bytes); } EXPECT_GT(bytes_read, 0u); + EXPECT_GT(bytes_read_limited, logging_expected_bytes); + EXPECT_LE(bytes_read_limited, logging_limit_bytes); EXPECT_NE(0, feof(ref_file)); EXPECT_NE(0, feof(out_file)); + EXPECT_NE(0, feof(limited_file)); ASSERT_EQ(0, fclose(ref_file)); ASSERT_EQ(0, fclose(out_file)); + ASSERT_EQ(0, fclose(limited_file)); remove(ref_filename.c_str()); remove(out_filename.c_str()); + remove(limited_filename.c_str()); } TEST_F(ApmTest, VerifyDebugDumpInt) { @@ -1853,13 +1876,13 @@ TEST_F(ApmTest, DebugDump) { const std::string filename = test::TempFilename(test::OutputPath(), "debug_aec"); EXPECT_EQ(apm_->kNullPointerError, - apm_->StartDebugRecording(static_cast(NULL))); + apm_->StartDebugRecording(static_cast(NULL), -1)); #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP // Stopping without having started should be OK. EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording()); - EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str())); + EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(filename.c_str(), -1)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_)); EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording()); @@ -1873,7 +1896,7 @@ TEST_F(ApmTest, DebugDump) { ASSERT_EQ(0, remove(filename.c_str())); #else EXPECT_EQ(apm_->kUnsupportedFunctionError, - apm_->StartDebugRecording(filename.c_str())); + apm_->StartDebugRecording(filename.c_str(), -1)); EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording()); // Verify the file has NOT been written. @@ -1884,7 +1907,7 @@ TEST_F(ApmTest, DebugDump) { // TODO(andrew): expand test to verify output. TEST_F(ApmTest, DebugDumpFromFileHandle) { FILE* fid = NULL; - EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(fid)); + EXPECT_EQ(apm_->kNullPointerError, apm_->StartDebugRecording(fid, -1)); const std::string filename = test::TempFilename(test::OutputPath(), "debug_aec"); fid = fopen(filename.c_str(), "w"); @@ -1894,7 +1917,7 @@ TEST_F(ApmTest, DebugDumpFromFileHandle) { // Stopping without having started should be OK. EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording()); - EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(fid)); + EXPECT_EQ(apm_->kNoError, apm_->StartDebugRecording(fid, -1)); EXPECT_EQ(apm_->kNoError, apm_->AnalyzeReverseStream(revframe_)); EXPECT_EQ(apm_->kNoError, apm_->ProcessStream(frame_)); EXPECT_EQ(apm_->kNoError, apm_->StopDebugRecording()); @@ -1908,7 +1931,7 @@ TEST_F(ApmTest, DebugDumpFromFileHandle) { ASSERT_EQ(0, remove(filename.c_str())); #else EXPECT_EQ(apm_->kUnsupportedFunctionError, - apm_->StartDebugRecording(fid)); + apm_->StartDebugRecording(fid, -1)); EXPECT_EQ(apm_->kUnsupportedFunctionError, apm_->StopDebugRecording()); ASSERT_EQ(0, fclose(fid)); diff --git a/webrtc/modules/audio_processing/test/debug_dump_test.cc b/webrtc/modules/audio_processing/test/debug_dump_test.cc index 005faa0f44..306e9e7f57 100644 --- a/webrtc/modules/audio_processing/test/debug_dump_test.cc +++ b/webrtc/modules/audio_processing/test/debug_dump_test.cc @@ -181,7 +181,7 @@ void DebugDumpGenerator::SetOutputChannels(int channels) { } void DebugDumpGenerator::StartRecording() { - apm_->StartDebugRecording(dump_file_name_.c_str()); + apm_->StartDebugRecording(dump_file_name_.c_str(), -1); } void DebugDumpGenerator::Process(size_t num_blocks) { diff --git a/webrtc/modules/audio_processing/test/process_test.cc b/webrtc/modules/audio_processing/test/process_test.cc index 6e20a787e7..d987307f19 100644 --- a/webrtc/modules/audio_processing/test/process_test.cc +++ b/webrtc/modules/audio_processing/test/process_test.cc @@ -435,7 +435,7 @@ void void_main(int argc, char* argv[]) { } else if (strcmp(argv[i], "--debug_file") == 0) { i++; ASSERT_LT(i, argc) << "Specify filename after --debug_file"; - ASSERT_EQ(apm->kNoError, apm->StartDebugRecording(argv[i])); + ASSERT_EQ(apm->kNoError, apm->StartDebugRecording(argv[i], -1)); } else { FAIL() << "Unrecognized argument " << argv[i]; } diff --git a/webrtc/voice_engine/voe_audio_processing_impl.cc b/webrtc/voice_engine/voe_audio_processing_impl.cc index c95726339c..4479fe0a8f 100644 --- a/webrtc/voice_engine/voe_audio_processing_impl.cc +++ b/webrtc/voice_engine/voe_audio_processing_impl.cc @@ -924,7 +924,7 @@ int VoEAudioProcessingImpl::StartDebugRecording(const char* fileNameUTF8) { return -1; } - return _shared->audio_processing()->StartDebugRecording(fileNameUTF8); + return _shared->audio_processing()->StartDebugRecording(fileNameUTF8, -1); } int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) { @@ -935,7 +935,7 @@ int VoEAudioProcessingImpl::StartDebugRecording(FILE* file_handle) { return -1; } - return _shared->audio_processing()->StartDebugRecording(file_handle); + return _shared->audio_processing()->StartDebugRecording(file_handle, -1); } int VoEAudioProcessingImpl::StopDebugRecording() {