Changeset 242734 in webkit
- Timestamp:
- Mar 11, 2019, 1:19:49 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 28 edited
-
ChangeLog (modified) (1 diff)
-
Modules/webaudio/AudioBasicInspectorNode.cpp (modified) (1 diff)
-
Modules/webaudio/AudioBufferSourceNode.cpp (modified) (2 diffs)
-
Modules/webaudio/AudioContext.cpp (modified) (26 diffs)
-
Modules/webaudio/AudioContext.h (modified) (5 diffs)
-
Modules/webaudio/AudioDestinationNode.cpp (modified) (1 diff)
-
Modules/webaudio/AudioNode.cpp (modified) (14 diffs)
-
Modules/webaudio/AudioNode.h (modified) (6 diffs)
-
Modules/webaudio/AudioParam.cpp (modified) (6 diffs)
-
Modules/webaudio/AudioParam.h (modified) (5 diffs)
-
Modules/webaudio/AudioScheduledSourceNode.cpp (modified) (2 diffs)
-
Modules/webaudio/BiquadFilterNode.cpp (modified) (1 diff)
-
Modules/webaudio/ChannelMergerNode.cpp (modified) (2 diffs)
-
Modules/webaudio/ChannelSplitterNode.cpp (modified) (2 diffs)
-
Modules/webaudio/ConvolverNode.cpp (modified) (2 diffs)
-
Modules/webaudio/DefaultAudioDestinationNode.cpp (modified) (4 diffs)
-
Modules/webaudio/DelayNode.cpp (modified) (1 diff)
-
Modules/webaudio/DynamicsCompressorNode.cpp (modified) (1 diff)
-
Modules/webaudio/GainNode.cpp (modified) (1 diff)
-
Modules/webaudio/MediaElementAudioSourceNode.cpp (modified) (1 diff)
-
Modules/webaudio/MediaStreamAudioSourceNode.cpp (modified) (2 diffs)
-
Modules/webaudio/OfflineAudioDestinationNode.cpp (modified) (1 diff)
-
Modules/webaudio/OscillatorNode.cpp (modified) (2 diffs)
-
Modules/webaudio/OscillatorNode.h (modified) (1 diff)
-
Modules/webaudio/PannerNode.cpp (modified) (2 diffs)
-
Modules/webaudio/ScriptProcessorNode.cpp (modified) (1 diff)
-
Modules/webaudio/WaveShaperNode.cpp (modified) (3 diffs)
-
Modules/webaudio/WaveShaperNode.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r242729 r242734 1 2019-03-11 Eric Carlson <eric.carlson@apple.com> 2 3 Add web audio release logging 4 https://bugs.webkit.org/show_bug.cgi?id=195554 5 <rdar://problem/48767211> 6 7 Reviewed by Jer Noble. 8 9 No new tests, no functional change. 10 11 * Modules/webaudio/AudioBasicInspectorNode.cpp: 12 (WebCore::AudioBasicInspectorNode::AudioBasicInspectorNode): 13 * Modules/webaudio/AudioBufferSourceNode.cpp: 14 (WebCore::AudioBufferSourceNode::setBuffer): 15 (WebCore::AudioBufferSourceNode::startPlaying): 16 * Modules/webaudio/AudioContext.cpp: 17 (WebCore::nextLogIdentifier): 18 (WebCore::AudioContext::AudioContext): 19 (WebCore::AudioContext::uninitialize): 20 (WebCore::AudioContext::stop): 21 (WebCore::AudioContext::createBufferSource): 22 (WebCore::AudioContext::createMediaElementSource): 23 (WebCore::AudioContext::createMediaStreamSource): 24 (WebCore::AudioContext::createScriptProcessor): 25 (WebCore::AudioContext::createBiquadFilter): 26 (WebCore::AudioContext::createWaveShaper): 27 (WebCore::AudioContext::createPanner): 28 (WebCore::AudioContext::createConvolver): 29 (WebCore::AudioContext::createDynamicsCompressor): 30 (WebCore::AudioContext::createAnalyser): 31 (WebCore::AudioContext::createGain): 32 (WebCore::AudioContext::createDelay): 33 (WebCore::AudioContext::createChannelSplitter): 34 (WebCore::AudioContext::createChannelMerger): 35 (WebCore::AudioContext::createOscillator): 36 (WebCore::AudioContext::createPeriodicWave): 37 (WebCore::AudioContext::willBeginPlayback): 38 (WebCore::AudioContext::startRendering): 39 (WebCore::AudioContext::fireCompletionEvent): 40 (WebCore::AudioContext::logChannel const): 41 * Modules/webaudio/AudioContext.h: 42 (WebCore::AudioContext::nextAudioNodeLogIdentifier): 43 (WebCore::AudioContext::nextAudioParameterLogIdentifier): 44 * Modules/webaudio/AudioDestinationNode.cpp: 45 (WebCore::AudioDestinationNode::AudioDestinationNode): 46 * Modules/webaudio/AudioNode.cpp: 47 (WebCore::convertEnumerationToString): 48 (WebCore::AudioNode::AudioNode): 49 (WebCore::AudioNode::~AudioNode): 50 (WebCore::AudioNode::setNodeType): 51 (WebCore::AudioNode::addInput): 52 (WebCore::AudioNode::addOutput): 53 (WebCore::AudioNode::connect): 54 (WebCore::AudioNode::disconnect): 55 (WebCore::AudioNode::setChannelCount): 56 (WebCore::AudioNode::setChannelCountMode): 57 (WebCore::AudioNode::setChannelInterpretation): 58 (WebCore::AudioNode::logChannel const): 59 * Modules/webaudio/AudioNode.h: 60 (WTF::LogArgument<WebCore::AudioNode::NodeType>::toString): 61 * Modules/webaudio/AudioParam.cpp: 62 (WebCore::AudioParam::AudioParam): 63 (WebCore::AudioParam::setValue): 64 (WebCore::AudioParam::connect): 65 (WebCore::AudioParam::disconnect): 66 (WebCore::AudioParam::logChannel const): 67 * Modules/webaudio/AudioParam.h: 68 * Modules/webaudio/AudioScheduledSourceNode.cpp: 69 (WebCore::AudioScheduledSourceNode::start): 70 (WebCore::AudioScheduledSourceNode::stop): 71 * Modules/webaudio/BiquadFilterNode.cpp: 72 (WebCore::BiquadFilterNode::BiquadFilterNode): 73 * Modules/webaudio/ChannelMergerNode.cpp: 74 (WebCore::ChannelMergerNode::ChannelMergerNode): 75 * Modules/webaudio/ChannelSplitterNode.cpp: 76 (WebCore::ChannelSplitterNode::ChannelSplitterNode): 77 * Modules/webaudio/ConvolverNode.cpp: 78 (WebCore::ConvolverNode::ConvolverNode): 79 * Modules/webaudio/DefaultAudioDestinationNode.cpp: 80 (WebCore::DefaultAudioDestinationNode::initialize): 81 (WebCore::DefaultAudioDestinationNode::uninitialize): 82 (WebCore::DefaultAudioDestinationNode::enableInput): 83 (WebCore::DefaultAudioDestinationNode::setChannelCount): 84 * Modules/webaudio/DelayNode.cpp: 85 (WebCore::DelayNode::DelayNode): 86 * Modules/webaudio/DynamicsCompressorNode.cpp: 87 (WebCore::DynamicsCompressorNode::DynamicsCompressorNode): 88 * Modules/webaudio/GainNode.cpp: 89 (WebCore::GainNode::GainNode): 90 * Modules/webaudio/MediaElementAudioSourceNode.cpp: 91 (WebCore::MediaElementAudioSourceNode::MediaElementAudioSourceNode): 92 * Modules/webaudio/MediaStreamAudioSourceNode.cpp: 93 (WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode): 94 * Modules/webaudio/OfflineAudioDestinationNode.cpp: 95 (WebCore::OfflineAudioDestinationNode::startRendering): 96 * Modules/webaudio/OscillatorNode.cpp: 97 (WebCore::OscillatorNode::setType): 98 (WebCore::OscillatorNode::setPeriodicWave): 99 * Modules/webaudio/OscillatorNode.h: 100 (WTF::LogArgument<WebCore::OscillatorNode::Type>::toString): 101 * Modules/webaudio/PannerNode.cpp: 102 (WebCore::PannerNode::PannerNode): 103 * Modules/webaudio/ScriptProcessorNode.cpp: 104 (WebCore::ScriptProcessorNode::ScriptProcessorNode): 105 * Modules/webaudio/WaveShaperNode.cpp: 106 (WebCore::WaveShaperNode::WaveShaperNode): 107 (WebCore::WaveShaperNode::setCurve): 108 (WebCore::WaveShaperNode::setOversample): 109 * Modules/webaudio/WaveShaperNode.h: 110 (WTF::LogArgument<WebCore::WaveShaperNode::OverSampleType>::toString): 111 1 112 2019-03-11 Youenn Fablet <youenn@apple.com> 2 113 -
trunk/Source/WebCore/Modules/webaudio/AudioBasicInspectorNode.cpp
r240237 r242734 37 37 : AudioNode(context, sampleRate) 38 38 { 39 setNodeType(NodeTypeBasicInspector); 39 40 addInput(std::make_unique<AudioNodeInput>(this)); 40 41 addOutput(std::make_unique<AudioNodeOutput>(this, outputChannelCount)); -
trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
r239427 r242734 408 408 { 409 409 ASSERT(isMainThread()); 410 410 DEBUG_LOG(LOGIDENTIFIER); 411 411 412 // The context must be locked since changing the buffer can re-configure the number of channels that are output. 412 413 AudioContext::AutoLocker contextLocker(context()); … … 452 453 { 453 454 ASSERT(isMainThread()); 455 ALWAYS_LOG(LOGIDENTIFIER, "when = ", when, ", offset = ", grainOffset, ", duration = ", grainDuration); 454 456 455 457 context().nodeWillBeginPlayback(); -
trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp
r241130 r242734 107 107 #define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(document()->page() && document()->page()->isAlwaysOnLoggingAllowed(), Media, "%p - AudioContext::" fmt, this, ##__VA_ARGS__) 108 108 109 #if !RELEASE_LOG_DISABLED 110 static const void* nextLogIdentifier() 111 { 112 static uint64_t logIdentifier = cryptographicallyRandomNumber(); 113 return reinterpret_cast<const void*>(++logIdentifier); 114 } 115 #endif 116 109 117 bool AudioContext::isSampleRateRangeGood(float sampleRate) 110 118 { … … 132 140 AudioContext::AudioContext(Document& document) 133 141 : ActiveDOMObject(document) 142 #if !RELEASE_LOG_DISABLED 143 , m_logger(document.logger()) 144 , m_logIdentifier(nextLogIdentifier()) 145 #endif 134 146 , m_mediaSession(PlatformMediaSession::create(*this)) 135 147 , m_eventQueue(std::make_unique<GenericEventQueue>(*this)) … … 146 158 AudioContext::AudioContext(Document& document, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) 147 159 : ActiveDOMObject(document) 160 #if !RELEASE_LOG_DISABLED 161 , m_logger(document.logger()) 162 , m_logIdentifier(nextLogIdentifier()) 163 #endif 148 164 , m_isOfflineContext(true) 149 165 , m_mediaSession(PlatformMediaSession::create(*this)) … … 241 257 void AudioContext::uninitialize() 242 258 { 259 ALWAYS_LOG(LOGIDENTIFIER); 260 243 261 ASSERT(isMainThread()); 244 262 … … 304 322 void AudioContext::stop() 305 323 { 324 ALWAYS_LOG(LOGIDENTIFIER); 325 306 326 ASSERT(isMainThread()); 307 327 … … 414 434 Ref<AudioBufferSourceNode> AudioContext::createBufferSource() 415 435 { 436 ALWAYS_LOG(LOGIDENTIFIER); 437 416 438 ASSERT(isMainThread()); 417 439 lazyInitialize(); … … 429 451 ExceptionOr<Ref<MediaElementAudioSourceNode>> AudioContext::createMediaElementSource(HTMLMediaElement& mediaElement) 430 452 { 453 ALWAYS_LOG(LOGIDENTIFIER); 454 431 455 ASSERT(isMainThread()); 432 456 lazyInitialize(); … … 449 473 ExceptionOr<Ref<MediaStreamAudioSourceNode>> AudioContext::createMediaStreamSource(MediaStream& mediaStream) 450 474 { 475 ALWAYS_LOG(LOGIDENTIFIER); 476 451 477 ASSERT(isMainThread()); 452 478 … … 485 511 ExceptionOr<Ref<ScriptProcessorNode>> AudioContext::createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels) 486 512 { 513 ALWAYS_LOG(LOGIDENTIFIER); 514 487 515 ASSERT(isMainThread()); 488 516 lazyInitialize(); … … 543 571 Ref<BiquadFilterNode> AudioContext::createBiquadFilter() 544 572 { 573 ALWAYS_LOG(LOGIDENTIFIER); 574 545 575 ASSERT(isMainThread()); 546 576 lazyInitialize(); … … 550 580 Ref<WaveShaperNode> AudioContext::createWaveShaper() 551 581 { 582 ALWAYS_LOG(LOGIDENTIFIER); 583 552 584 ASSERT(isMainThread()); 553 585 lazyInitialize(); … … 557 589 Ref<PannerNode> AudioContext::createPanner() 558 590 { 591 ALWAYS_LOG(LOGIDENTIFIER); 592 559 593 ASSERT(isMainThread()); 560 594 lazyInitialize(); … … 564 598 Ref<ConvolverNode> AudioContext::createConvolver() 565 599 { 600 ALWAYS_LOG(LOGIDENTIFIER); 601 566 602 ASSERT(isMainThread()); 567 603 lazyInitialize(); … … 571 607 Ref<DynamicsCompressorNode> AudioContext::createDynamicsCompressor() 572 608 { 609 ALWAYS_LOG(LOGIDENTIFIER); 610 573 611 ASSERT(isMainThread()); 574 612 lazyInitialize(); … … 578 616 Ref<AnalyserNode> AudioContext::createAnalyser() 579 617 { 618 ALWAYS_LOG(LOGIDENTIFIER); 619 580 620 ASSERT(isMainThread()); 581 621 lazyInitialize(); … … 585 625 Ref<GainNode> AudioContext::createGain() 586 626 { 627 ALWAYS_LOG(LOGIDENTIFIER); 628 587 629 ASSERT(isMainThread()); 588 630 lazyInitialize(); … … 592 634 ExceptionOr<Ref<DelayNode>> AudioContext::createDelay(double maxDelayTime) 593 635 { 636 ALWAYS_LOG(LOGIDENTIFIER); 637 594 638 ASSERT(isMainThread()); 595 639 lazyInitialize(); … … 599 643 ExceptionOr<Ref<ChannelSplitterNode>> AudioContext::createChannelSplitter(size_t numberOfOutputs) 600 644 { 645 ALWAYS_LOG(LOGIDENTIFIER); 646 601 647 ASSERT(isMainThread()); 602 648 lazyInitialize(); … … 609 655 ExceptionOr<Ref<ChannelMergerNode>> AudioContext::createChannelMerger(size_t numberOfInputs) 610 656 { 657 ALWAYS_LOG(LOGIDENTIFIER); 658 611 659 ASSERT(isMainThread()); 612 660 lazyInitialize(); … … 619 667 Ref<OscillatorNode> AudioContext::createOscillator() 620 668 { 669 ALWAYS_LOG(LOGIDENTIFIER); 670 621 671 ASSERT(isMainThread()); 622 672 lazyInitialize(); … … 633 683 ExceptionOr<Ref<PeriodicWave>> AudioContext::createPeriodicWave(Float32Array& real, Float32Array& imaginary) 634 684 { 685 ALWAYS_LOG(LOGIDENTIFIER); 686 635 687 ASSERT(isMainThread()); 636 688 if (real.length() != imaginary.length() || (real.length() > MaxPeriodicWaveLength) || !real.length()) … … 982 1034 { 983 1035 if (userGestureRequiredForAudioStart()) { 984 if (!processingUserGestureForMedia() && !document()->isCapturing()) 1036 if (!processingUserGestureForMedia() && !document()->isCapturing()) { 1037 ALWAYS_LOG(LOGIDENTIFIER, "returning false, not processing user gesture or capturing"); 1038 return false; 1039 } 1040 removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction); 1041 } 1042 1043 if (pageConsentRequiredForAudioStart()) { 1044 Page* page = document()->page(); 1045 if (page && !page->canStartMedia()) { 1046 document()->addMediaCanStartListener(*this); 1047 ALWAYS_LOG(LOGIDENTIFIER, "returning false, page doesn't allow media to start"); 1048 return false; 1049 } 1050 removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction); 1051 } 1052 1053 auto willBegin = m_mediaSession->clientWillBeginPlayback(); 1054 ALWAYS_LOG(LOGIDENTIFIER, "returning ", willBegin); 1055 1056 return willBegin; 1057 } 1058 1059 bool AudioContext::willPausePlayback() 1060 { 1061 if (userGestureRequiredForAudioStart()) { 1062 if (!processingUserGestureForMedia()) 985 1063 return false; 986 1064 removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction); … … 995 1073 removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction); 996 1074 } 997 998 return m_mediaSession->clientWillBeginPlayback();999 }1000 1001 bool AudioContext::willPausePlayback()1002 {1003 if (userGestureRequiredForAudioStart()) {1004 if (!processingUserGestureForMedia())1005 return false;1006 removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);1007 }1008 1009 if (pageConsentRequiredForAudioStart()) {1010 Page* page = document()->page();1011 if (page && !page->canStartMedia()) {1012 document()->addMediaCanStartListener(*this);1013 return false;1014 }1015 removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction);1016 }1017 1075 1018 1076 return m_mediaSession->clientWillPausePlayback(); … … 1021 1079 void AudioContext::startRendering() 1022 1080 { 1081 ALWAYS_LOG(LOGIDENTIFIER); 1023 1082 if (!willBeginPlayback()) 1024 1083 return; … … 1064 1123 if (!isMainThread()) 1065 1124 return; 1066 1125 1126 ALWAYS_LOG(LOGIDENTIFIER); 1127 1067 1128 AudioBuffer* renderedBuffer = m_renderTarget.get(); 1068 1129 setState(State::Closed); … … 1209 1270 } 1210 1271 1272 #if !RELEASE_LOG_DISABLED 1273 WTFLogChannel& AudioContext::logChannel() const 1274 { 1275 return LogMedia; 1276 } 1277 #endif 1211 1278 1212 1279 } // namespace WebCore -
trunk/Source/WebCore/Modules/webaudio/AudioContext.h
r240237 r242734 1 1 /* 2 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2016 Apple Inc. All rights reserved.3 * Copyright (C) 2016-2019 Apple Inc. All rights reserved. 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 39 39 #include <atomic> 40 40 #include <wtf/HashSet.h> 41 #include <wtf/LoggerHelper.h> 41 42 #include <wtf/MainThread.h> 42 43 #include <wtf/RefPtr.h> … … 77 78 // For thread safety between the audio thread and the main thread, it has a rendering graph locking mechanism. 78 79 79 class AudioContext : public ActiveDOMObject, public ThreadSafeRefCounted<AudioContext>, public EventTargetWithInlineData, public MediaCanStartListener, public MediaProducer, private PlatformMediaSessionClient, private VisibilityChangeClient { 80 class AudioContext 81 : public ActiveDOMObject 82 , public ThreadSafeRefCounted<AudioContext> 83 , public EventTargetWithInlineData 84 , public MediaCanStartListener 85 , public MediaProducer 86 , private PlatformMediaSessionClient 87 , private VisibilityChangeClient 88 #if !RELEASE_LOG_DISABLED 89 , private LoggerHelper 90 #endif 91 { 80 92 public: 81 93 // Create an AudioContext for rendering to the audio hardware. … … 264 276 void nodeWillBeginPlayback(); 265 277 278 #if !RELEASE_LOG_DISABLED 279 const Logger& logger() const final { return m_logger.get(); } 280 const void* logIdentifier() const final { return m_logIdentifier; } 281 WTFLogChannel& logChannel() const final; 282 const void* nextAudioNodeLogIdentifier() { return childLogIdentifier(++m_nextAudioNodeIdentifier); } 283 const void* nextAudioParameterLogIdentifier() { return childLogIdentifier(++m_nextAudioParameterIdentifier); } 284 #endif 285 266 286 protected: 267 287 explicit AudioContext(Document&); … … 337 357 void updateAutomaticPullNodes(); 338 358 359 #if !RELEASE_LOG_DISABLED 360 const char* logClassName() const final { return "AudioContext"; } 361 362 Ref<Logger> m_logger; 363 const void* m_logIdentifier; 364 uint64_t m_nextAudioNodeIdentifier { 0 }; 365 uint64_t m_nextAudioParameterIdentifier { 0 }; 366 #endif 367 339 368 // Only accessed in the audio thread. 340 369 Vector<AudioNode*> m_finishedNodes; -
trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp
r225470 r242734 44 44 , m_muted(false) 45 45 { 46 setNodeType(NodeTypeDestination); 46 47 addInput(std::make_unique<AudioNodeInput>(this)); 47 48 setNodeType(NodeTypeDestination);49 48 } 50 49 -
trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp
r240237 r242734 33 33 #include "AudioNodeOutput.h" 34 34 #include "AudioParam.h" 35 #include "Logging.h" 35 36 #include <wtf/Atomics.h> 36 37 #include <wtf/MainThread.h> … … 41 42 42 43 namespace WebCore { 44 45 String convertEnumerationToString(AudioNode::NodeType enumerationValue) 46 { 47 static const NeverDestroyed<String> values[] = { 48 MAKE_STATIC_STRING_IMPL("NodeTypeUnknown"), 49 MAKE_STATIC_STRING_IMPL("NodeTypeDestination"), 50 MAKE_STATIC_STRING_IMPL("NodeTypeOscillator"), 51 MAKE_STATIC_STRING_IMPL("NodeTypeAudioBufferSource"), 52 MAKE_STATIC_STRING_IMPL("NodeTypeMediaElementAudioSource"), 53 MAKE_STATIC_STRING_IMPL("NodeTypeMediaStreamAudioDestination"), 54 MAKE_STATIC_STRING_IMPL("NodeTypeMediaStreamAudioSource"), 55 MAKE_STATIC_STRING_IMPL("NodeTypeJavaScript"), 56 MAKE_STATIC_STRING_IMPL("NodeTypeBiquadFilter"), 57 MAKE_STATIC_STRING_IMPL("NodeTypePanner"), 58 MAKE_STATIC_STRING_IMPL("NodeTypeConvolver"), 59 MAKE_STATIC_STRING_IMPL("NodeTypeDelay"), 60 MAKE_STATIC_STRING_IMPL("NodeTypeGain"), 61 MAKE_STATIC_STRING_IMPL("NodeTypeChannelSplitter"), 62 MAKE_STATIC_STRING_IMPL("NodeTypeChannelMerger"), 63 MAKE_STATIC_STRING_IMPL("NodeTypeAnalyser"), 64 MAKE_STATIC_STRING_IMPL("NodeTypeDynamicsCompressor"), 65 MAKE_STATIC_STRING_IMPL("NodeTypeWaveShaper"), 66 MAKE_STATIC_STRING_IMPL("NodeTypeBasicInspector"), 67 MAKE_STATIC_STRING_IMPL("NodeTypeEnd"), 68 }; 69 static_assert(static_cast<size_t>(AudioNode::NodeTypeUnknown) == 0, "AudioNode::NodeTypeUnknown is not 0 as expected"); 70 static_assert(static_cast<size_t>(AudioNode::NodeTypeDestination) == 1, "AudioNode::NodeTypeDestination is not 1 as expected"); 71 static_assert(static_cast<size_t>(AudioNode::NodeTypeOscillator) == 2, "AudioNode::NodeTypeOscillator is not 2 as expected"); 72 static_assert(static_cast<size_t>(AudioNode::NodeTypeAudioBufferSource) == 3, "AudioNode::NodeTypeAudioBufferSource is not 3 as expected"); 73 static_assert(static_cast<size_t>(AudioNode::NodeTypeMediaElementAudioSource) == 4, "AudioNode::NodeTypeMediaElementAudioSource is not 4 as expected"); 74 static_assert(static_cast<size_t>(AudioNode::NodeTypeMediaStreamAudioDestination) == 5, "AudioNode::NodeTypeMediaStreamAudioDestination is not 5 as expected"); 75 static_assert(static_cast<size_t>(AudioNode::NodeTypeMediaStreamAudioSource) == 6, "AudioNode::NodeTypeMediaStreamAudioSource is not 6 as expected"); 76 static_assert(static_cast<size_t>(AudioNode::NodeTypeJavaScript) == 7, "AudioNode::NodeTypeJavaScript is not 7 as expected"); 77 static_assert(static_cast<size_t>(AudioNode::NodeTypeBiquadFilter) == 8, "AudioNode::NodeTypeBiquadFilter is not 8 as expected"); 78 static_assert(static_cast<size_t>(AudioNode::NodeTypePanner) == 9, "AudioNode::NodeTypePanner is not 9 as expected"); 79 static_assert(static_cast<size_t>(AudioNode::NodeTypeConvolver) == 10, "AudioNode::NodeTypeConvolver is not 10 as expected"); 80 static_assert(static_cast<size_t>(AudioNode::NodeTypeDelay) == 11, "AudioNode::NodeTypeDelay is not 11 as expected"); 81 static_assert(static_cast<size_t>(AudioNode::NodeTypeGain) == 12, "AudioNode::NodeTypeGain is not 12 as expected"); 82 static_assert(static_cast<size_t>(AudioNode::NodeTypeChannelSplitter) == 13, "AudioNode::NodeTypeChannelSplitter is not 13 as expected"); 83 static_assert(static_cast<size_t>(AudioNode::NodeTypeChannelMerger) == 14, "AudioNode::NodeTypeChannelMerger is not 14 as expected"); 84 static_assert(static_cast<size_t>(AudioNode::NodeTypeAnalyser) == 15, "AudioNode::NodeTypeAnalyser is not 15 as expected"); 85 static_assert(static_cast<size_t>(AudioNode::NodeTypeDynamicsCompressor) == 16, "AudioNode::NodeTypeDynamicsCompressor is not 16 as expected"); 86 static_assert(static_cast<size_t>(AudioNode::NodeTypeWaveShaper) == 17, "AudioNode::NodeTypeWaveShaper is not 17 as expected"); 87 static_assert(static_cast<size_t>(AudioNode::NodeTypeBasicInspector) == 18, "AudioNode::NodeTypeBasicInspector is not 18 as expected"); 88 static_assert(static_cast<size_t>(AudioNode::NodeTypeEnd) == 19, "AudioNode::NodeTypeEnd is not 19 as expected"); 89 90 ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values)); 91 92 return values[static_cast<size_t>(enumerationValue)]; 93 } 43 94 44 95 AudioNode::AudioNode(AudioContext& context, float sampleRate) … … 53 104 , m_isMarkedForDeletion(false) 54 105 , m_isDisabled(false) 106 #if !RELEASE_LOG_DISABLED 107 , m_logger(context.logger()) 108 , m_logIdentifier(context.nextAudioNodeLogIdentifier()) 109 #endif 55 110 , m_channelCount(2) 56 111 , m_channelCountMode(Max) 57 112 , m_channelInterpretation(AudioBus::Speakers) 58 113 { 114 ALWAYS_LOG(LOGIDENTIFIER); 115 59 116 #if DEBUG_AUDIONODE_REFERENCES 60 117 if (!s_isNodeCountInitialized) { … … 67 124 AudioNode::~AudioNode() 68 125 { 126 ALWAYS_LOG(LOGIDENTIFIER); 127 69 128 ASSERT(isMainThread()); 70 129 #if DEBUG_AUDIONODE_REFERENCES … … 86 145 void AudioNode::setNodeType(NodeType type) 87 146 { 147 ASSERT(isMainThread()); 148 ALWAYS_LOG(LOGIDENTIFIER, type); 149 88 150 m_nodeType = type; 89 151 … … 101 163 void AudioNode::addInput(std::unique_ptr<AudioNodeInput> input) 102 164 { 165 ASSERT(isMainThread()); 166 DEBUG_LOG(LOGIDENTIFIER, input->node()->nodeType()); 103 167 m_inputs.append(WTFMove(input)); 104 168 } … … 106 170 void AudioNode::addOutput(std::unique_ptr<AudioNodeOutput> output) 107 171 { 172 ASSERT(isMainThread()); 173 DEBUG_LOG(LOGIDENTIFIER, output->node()->nodeType()); 108 174 m_outputs.append(WTFMove(output)); 109 175 } … … 125 191 ExceptionOr<void> AudioNode::connect(AudioNode& destination, unsigned outputIndex, unsigned inputIndex) 126 192 { 127 ASSERT(isMainThread()); 193 ASSERT(isMainThread()); 128 194 AudioContext::AutoLocker locker(context()); 129 195 196 ALWAYS_LOG(LOGIDENTIFIER, destination.nodeType(), ", output = ", outputIndex, ", input = ", inputIndex); 197 130 198 // Sanity check input and output indices. 131 199 if (outputIndex >= numberOfOutputs()) … … 150 218 ExceptionOr<void> AudioNode::connect(AudioParam& param, unsigned outputIndex) 151 219 { 152 ASSERT(isMainThread());153 220 AudioContext::AutoLocker locker(context()); 221 222 ASSERT(isMainThread()); 223 224 DEBUG_LOG(LOGIDENTIFIER, param.name(), ", output = ", outputIndex); 154 225 155 226 if (outputIndex >= numberOfOutputs()) … … 175 246 176 247 auto* output = this->output(outputIndex); 248 DEBUG_LOG(LOGIDENTIFIER, output->node()->nodeType()); 249 177 250 output->disconnectAll(); 178 251 … … 190 263 AudioContext::AutoLocker locker(context()); 191 264 265 ALWAYS_LOG(LOGIDENTIFIER, channelCount); 266 192 267 if (!(channelCount > 0 && channelCount <= AudioContext::maxNumberOfChannels())) 193 268 return Exception { InvalidStateError }; … … 221 296 AudioContext::AutoLocker locker(context()); 222 297 298 ALWAYS_LOG(LOGIDENTIFIER, mode); 299 223 300 ChannelCountMode oldMode = m_channelCountMode; 224 301 … … 255 332 AudioContext::AutoLocker locker(context()); 256 333 334 ALWAYS_LOG(LOGIDENTIFIER, interpretation); 335 257 336 if (interpretation == "speakers") 258 337 m_channelInterpretation = AudioBus::Speakers; … … 506 585 #endif // DEBUG_AUDIONODE_REFERENCES 507 586 587 #if !RELEASE_LOG_DISABLED 588 WTFLogChannel& AudioNode::logChannel() const 589 { 590 return LogMedia; 591 } 592 #endif 593 508 594 } // namespace WebCore 509 595 -
trunk/Source/WebCore/Modules/webaudio/AudioNode.h
r236831 r242734 29 29 #include "ExceptionOr.h" 30 30 #include <wtf/Forward.h> 31 #include <wtf/LoggerHelper.h> 31 32 32 33 #define DEBUG_AUDIONODE_REFERENCES 0 … … 45 46 // Most processing nodes such as filters will have one input and one output, although multiple inputs and outputs are possible. 46 47 47 class AudioNode : public EventTargetWithInlineData { 48 class AudioNode 49 : public EventTargetWithInlineData 50 #if !RELEASE_LOG_DISABLED 51 , private LoggerHelper 52 #endif 53 { 48 54 WTF_MAKE_NONCOPYABLE(AudioNode); 49 55 WTF_MAKE_FAST_ALLOCATED; … … 76 82 NodeTypeDynamicsCompressor, 77 83 NodeTypeWaveShaper, 84 NodeTypeBasicInspector, 78 85 NodeTypeEnd 79 86 }; … … 192 199 void updateChannelsForInputs(); 193 200 201 #if !RELEASE_LOG_DISABLED 202 const Logger& logger() const final { return m_logger.get(); } 203 const void* logIdentifier() const final { return m_logIdentifier; } 204 const char* logClassName() const final { return "AudioNode"; } 205 WTFLogChannel& logChannel() const final; 206 #endif 207 194 208 private: 195 209 volatile bool m_isInitialized; … … 218 232 void derefEventTarget() override { deref(); } 219 233 234 #if !RELEASE_LOG_DISABLED 235 mutable Ref<const Logger> m_logger; 236 const void* m_logIdentifier; 237 #endif 238 220 239 protected: 221 240 unsigned m_channelCount; … … 224 243 }; 225 244 245 String convertEnumerationToString(AudioNode::NodeType); 246 226 247 } // namespace WebCore 248 249 namespace WTF { 250 251 template<> struct LogArgument<WebCore::AudioNode::NodeType> { 252 static String toString(WebCore::AudioNode::NodeType type) { return convertEnumerationToString(type); } 253 }; 254 255 } // namespace WTF -
trunk/Source/WebCore/Modules/webaudio/AudioParam.cpp
r239535 r242734 34 34 #include "AudioUtilities.h" 35 35 #include "FloatConversion.h" 36 #include "Logging.h" 36 37 #include <wtf/MathExtras.h> 37 38 … … 40 41 const double AudioParam::DefaultSmoothingConstant = 0.05; 41 42 const double AudioParam::SnapThreshold = 0.001; 43 44 AudioParam::AudioParam(AudioContext& context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units) 45 : AudioSummingJunction(context) 46 , m_name(name) 47 , m_value(defaultValue) 48 , m_defaultValue(defaultValue) 49 , m_minValue(minValue) 50 , m_maxValue(maxValue) 51 , m_units(units) 52 , m_smoothedValue(defaultValue) 53 , m_smoothingConstant(DefaultSmoothingConstant) 54 #if !RELEASE_LOG_DISABLED 55 , m_logger(context.logger()) 56 , m_logIdentifier(context.nextAudioParameterLogIdentifier()) 57 #endif 58 { 59 ALWAYS_LOG(LOGIDENTIFIER, "name = ", m_name, ", value = ", m_value, ", default = ", m_defaultValue, ", min = ", m_minValue, ", max = ", m_maxValue, ", units = ", m_units); 60 } 42 61 43 62 float AudioParam::value() … … 57 76 void AudioParam::setValue(float value) 58 77 { 78 DEBUG_LOG(LOGIDENTIFIER, value); 79 59 80 // Check against JavaScript giving us bogus floating-point values. 60 81 // Don't ASSERT, since this can happen if somebody writes bad JS. … … 174 195 return; 175 196 197 DEBUG_LOG(LOGIDENTIFIER, output->node()->nodeType()); 198 176 199 output->addParam(this); 177 200 changedOutputs(); … … 185 208 if (!output) 186 209 return; 210 211 DEBUG_LOG(LOGIDENTIFIER, output->node()->nodeType()); 187 212 188 213 if (m_outputs.remove(output)) { … … 192 217 } 193 218 219 #if !RELEASE_LOG_DISABLED 220 WTFLogChannel& AudioParam::logChannel() const 221 { 222 return LogMedia; 223 } 224 #endif 225 226 194 227 } // namespace WebCore 195 228 -
trunk/Source/WebCore/Modules/webaudio/AudioParam.h
r233650 r242734 34 34 #include <JavaScriptCore/Float32Array.h> 35 35 #include <sys/types.h> 36 #include <wtf/LoggerHelper.h> 36 37 #include <wtf/RefCounted.h> 37 38 #include <wtf/text/WTFString.h> … … 41 42 class AudioNodeOutput; 42 43 43 class AudioParam final : public AudioSummingJunction, public RefCounted<AudioParam> { 44 class AudioParam final 45 : public AudioSummingJunction 46 , public RefCounted<AudioParam> 47 #if !RELEASE_LOG_DISABLED 48 , private LoggerHelper 49 #endif 50 { 44 51 public: 45 52 static const double DefaultSmoothingConstant; … … 102 109 103 110 protected: 104 AudioParam(AudioContext& context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0) 105 : AudioSummingJunction(context) 106 , m_name(name) 107 , m_value(defaultValue) 108 , m_defaultValue(defaultValue) 109 , m_minValue(minValue) 110 , m_maxValue(maxValue) 111 , m_units(units) 112 , m_smoothedValue(defaultValue) 113 , m_smoothingConstant(DefaultSmoothingConstant) 114 { 115 } 111 AudioParam(AudioContext&, const String&, double defaultValue, double minValue, double maxValue, unsigned units = 0); 116 112 117 113 private: … … 120 116 void calculateTimelineValues(float* values, unsigned numberOfValues); 121 117 118 #if !RELEASE_LOG_DISABLED 119 const Logger& logger() const final { return m_logger.get(); } 120 const void* logIdentifier() const final { return m_logIdentifier; } 121 const char* logClassName() const final { return "AudioParam"; } 122 WTFLogChannel& logChannel() const final; 123 #endif 124 122 125 String m_name; 123 126 double m_value; … … 132 135 133 136 AudioParamTimeline m_timeline; 137 138 #if !RELEASE_LOG_DISABLED 139 mutable Ref<const Logger> m_logger; 140 const void* m_logIdentifier; 141 #endif 134 142 }; 135 143 -
trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp
r238291 r242734 133 133 { 134 134 ASSERT(isMainThread()); 135 ALWAYS_LOG(LOGIDENTIFIER, when); 135 136 136 137 context().nodeWillBeginPlayback(); … … 150 151 { 151 152 ASSERT(isMainThread()); 153 ALWAYS_LOG(LOGIDENTIFIER, when); 152 154 153 155 if (m_playbackState == UNSCHEDULED_STATE || m_endTime != UnknownTime) -
trunk/Source/WebCore/Modules/webaudio/BiquadFilterNode.cpp
r208688 r242734 34 34 : AudioBasicProcessorNode(context, sampleRate) 35 35 { 36 setNodeType(NodeTypeBiquadFilter); 37 36 38 // Initially setup as lowpass filter. 37 39 m_processor = std::make_unique<BiquadProcessor>(context, sampleRate, 1, false); 38 setNodeType(NodeTypeBiquadFilter);39 40 } 40 41 -
trunk/Source/WebCore/Modules/webaudio/ChannelMergerNode.cpp
r196603 r242734 53 53 , m_desiredNumberOfOutputChannels(DefaultNumberOfOutputChannels) 54 54 { 55 setNodeType(NodeTypeChannelMerger); 56 55 57 // Create the requested number of inputs. 56 58 for (unsigned i = 0; i < numberOfInputs; ++i) … … 58 60 59 61 addOutput(std::make_unique<AudioNodeOutput>(this, 1)); 60 61 setNodeType(NodeTypeChannelMerger);62 62 63 63 initialize(); -
trunk/Source/WebCore/Modules/webaudio/ChannelSplitterNode.cpp
r196603 r242734 46 46 : AudioNode(context, sampleRate) 47 47 { 48 setNodeType(NodeTypeChannelSplitter); 49 48 50 addInput(std::make_unique<AudioNodeInput>(this)); 49 51 … … 51 53 for (unsigned i = 0; i < numberOfOutputs; ++i) 52 54 addOutput(std::make_unique<AudioNodeOutput>(this, 1)); 53 54 setNodeType(NodeTypeChannelSplitter);55 55 56 56 initialize(); -
trunk/Source/WebCore/Modules/webaudio/ConvolverNode.cpp
r219856 r242734 48 48 : AudioNode(context, sampleRate) 49 49 { 50 setNodeType(NodeTypeConvolver); 51 50 52 addInput(std::make_unique<AudioNodeInput>(this)); 51 53 addOutput(std::make_unique<AudioNodeOutput>(this, 2)); … … 55 57 m_channelCountMode = ClampedMax; 56 58 m_channelInterpretation = AudioBus::Speakers; 57 58 setNodeType(NodeTypeConvolver);59 59 60 60 initialize(); -
trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp
r240143 r242734 58 58 if (isInitialized()) 59 59 return; 60 ALWAYS_LOG(LOGIDENTIFIER); 60 61 61 62 createDestination(); … … 69 70 return; 70 71 72 ALWAYS_LOG(LOGIDENTIFIER); 71 73 m_destination->stop(); 72 74 m_destination = nullptr; … … 86 88 void DefaultAudioDestinationNode::enableInput(const String& inputDeviceId) 87 89 { 90 ALWAYS_LOG(LOGIDENTIFIER); 91 88 92 ASSERT(isMainThread()); 89 93 if (m_numberOfInputChannels != EnabledInputChannels) { … … 145 149 146 150 ASSERT(isMainThread()); 151 ALWAYS_LOG(LOGIDENTIFIER, channelCount); 147 152 148 153 if (!maxChannelCount() || channelCount > maxChannelCount()) -
trunk/Source/WebCore/Modules/webaudio/DelayNode.cpp
r219856 r242734 38 38 : AudioBasicProcessorNode(context, sampleRate) 39 39 { 40 setNodeType(NodeTypeDelay); 40 41 m_processor = std::make_unique<DelayProcessor>(context, sampleRate, 1, maxDelayTime); 41 setNodeType(NodeTypeDelay);42 42 } 43 43 -
trunk/Source/WebCore/Modules/webaudio/DynamicsCompressorNode.cpp
r196603 r242734 42 42 : AudioNode(context, sampleRate) 43 43 { 44 setNodeType(NodeTypeDynamicsCompressor); 45 44 46 addInput(std::make_unique<AudioNodeInput>(this)); 45 47 addOutput(std::make_unique<AudioNodeOutput>(this, defaultNumberOfOutputChannels)); 46 47 setNodeType(NodeTypeDynamicsCompressor);48 48 49 49 m_threshold = AudioParam::create(context, "threshold", -24, -100, 0); -
trunk/Source/WebCore/Modules/webaudio/GainNode.cpp
r214505 r242734 40 40 , m_sampleAccurateGainValues(AudioNode::ProcessingSizeInFrames) // FIXME: can probably share temp buffer in context 41 41 { 42 setNodeType(NodeTypeGain); 43 42 44 m_gain = AudioParam::create(context, "gain", 1.0, 0.0, 1.0); 43 45 44 46 addInput(std::make_unique<AudioNodeInput>(this)); 45 47 addOutput(std::make_unique<AudioNodeOutput>(this, 1)); 46 47 setNodeType(NodeTypeGain);48 48 49 49 initialize(); -
trunk/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp
r234055 r242734 52 52 , m_sourceSampleRate(0) 53 53 { 54 setNodeType(NodeTypeMediaElementAudioSource); 55 54 56 // Default to stereo. This could change depending on what the media element .src is set to. 55 57 addOutput(std::make_unique<AudioNodeOutput>(this, 2)); 56 57 setNodeType(NodeTypeMediaElementAudioSource);58 58 59 59 initialize(); -
trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp
r213080 r242734 46 46 , m_audioTrack(audioTrack) 47 47 { 48 setNodeType(NodeTypeMediaStreamAudioSource); 49 48 50 AudioSourceProvider* audioSourceProvider = m_audioTrack->audioSourceProvider(); 49 51 ASSERT(audioSourceProvider); … … 53 55 // Default to stereo. This could change depending on the format of the MediaStream's audio track. 54 56 addOutput(std::make_unique<AudioNodeOutput>(this, 2)); 55 56 setNodeType(NodeTypeMediaStreamAudioSource);57 57 58 58 initialize(); -
trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp
r218816 r242734 75 75 void OfflineAudioDestinationNode::startRendering() 76 76 { 77 ALWAYS_LOG(LOGIDENTIFIER); 78 77 79 ASSERT(isMainThread()); 78 80 ASSERT(m_renderTarget.get()); -
trunk/Source/WebCore/Modules/webaudio/OscillatorNode.cpp
r238291 r242734 79 79 { 80 80 PeriodicWave* periodicWave = nullptr; 81 82 ALWAYS_LOG(LOGIDENTIFIER, type); 81 83 82 84 switch (type) { … … 298 300 void OscillatorNode::setPeriodicWave(PeriodicWave* periodicWave) 299 301 { 302 ALWAYS_LOG(LOGIDENTIFIER, "sample rate = ", periodicWave ? periodicWave->sampleRate() : 0, ", wave size = ", periodicWave ? periodicWave->periodicWaveSize() : 0, ", rate scale = ", periodicWave ? periodicWave->rateScale() : 0); 300 303 ASSERT(isMainThread()); 301 304 302 305 // This synchronizes with process(). 303 306 std::lock_guard<Lock> lock(m_processMutex); -
trunk/Source/WebCore/Modules/webaudio/OscillatorNode.h
r207050 r242734 102 102 }; 103 103 104 String convertEnumerationToString(OscillatorNode::Type); // In JSOscillatorNode.cpp 105 104 106 } // namespace WebCore 107 108 namespace WTF { 109 110 template<> struct LogArgument<WebCore::OscillatorNode::Type> { 111 static String toString(WebCore::OscillatorNode::Type type) { return convertEnumerationToString(type); } 112 }; 113 114 } // namespace WTF -
trunk/Source/WebCore/Modules/webaudio/PannerNode.cpp
r208688 r242734 51 51 , m_connectionCount(0) 52 52 { 53 setNodeType(NodeTypePanner); 54 53 55 // Load the HRTF database asynchronously so we don't block the Javascript thread while creating the HRTF database. 54 56 m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(context.sampleRate()); … … 68 70 m_orientation = FloatPoint3D(1, 0, 0); 69 71 m_velocity = FloatPoint3D(0, 0, 0); 70 71 setNodeType(NodeTypePanner);72 72 73 73 initialize(); -
trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp
r239535 r242734 65 65 ASSERT(numberOfInputChannels <= AudioContext::maxNumberOfChannels()); 66 66 67 setNodeType(NodeTypeJavaScript); 67 68 addInput(std::make_unique<AudioNodeInput>(this)); 68 69 addOutput(std::make_unique<AudioNodeOutput>(this, numberOfOutputChannels)); 69 70 setNodeType(NodeTypeJavaScript);71 70 72 71 initialize(); -
trunk/Source/WebCore/Modules/webaudio/WaveShaperNode.cpp
r209153 r242734 33 33 namespace WebCore { 34 34 35 35 36 WaveShaperNode::WaveShaperNode(AudioContext& context) 36 37 : AudioBasicProcessorNode(context, context.sampleRate()) 37 38 { 39 setNodeType(NodeTypeWaveShaper); 38 40 m_processor = std::make_unique<WaveShaperProcessor>(context.sampleRate(), 1); 39 setNodeType(NodeTypeWaveShaper);40 41 41 42 initialize(); … … 45 46 { 46 47 ASSERT(isMainThread()); 48 DEBUG_LOG(LOGIDENTIFIER); 47 49 waveShaperProcessor()->setCurve(&curve); 48 50 } … … 70 72 { 71 73 ASSERT(isMainThread()); 74 DEBUG_LOG(LOGIDENTIFIER, type); 72 75 73 76 // Synchronize with any graph changes or changes to channel configuration. -
trunk/Source/WebCore/Modules/webaudio/WaveShaperNode.h
r209153 r242734 54 54 }; 55 55 56 String convertEnumerationToString(WebCore::WaveShaperNode::OverSampleType); // in JSWaveShaperNode.cpp 57 56 58 } // namespace WebCore 59 60 namespace WTF { 61 62 template<> struct LogArgument<WebCore::WaveShaperNode::OverSampleType> { 63 static String toString(WebCore::WaveShaperNode::OverSampleType type) { return convertEnumerationToString(type); } 64 }; 65 66 } // namespace WTF
Note:
See TracChangeset
for help on using the changeset viewer.