summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/base/DOMIntersectionObserver.cpp114
-rw-r--r--dom/base/DOMIntersectionObserver.h13
-rw-r--r--dom/base/Element.cpp9
-rw-r--r--dom/base/Element.h3
-rw-r--r--dom/base/FragmentOrElement.cpp6
-rw-r--r--dom/base/FragmentOrElement.h3
-rw-r--r--dom/base/Location.cpp31
-rw-r--r--dom/base/Navigator.cpp80
-rw-r--r--dom/base/Navigator.h7
-rw-r--r--dom/base/nsCCUncollectableMarker.cpp40
-rw-r--r--dom/base/nsContentUtils.cpp71
-rw-r--r--dom/base/nsContentUtils.h15
-rw-r--r--dom/base/nsDOMClassInfo.cpp4
-rw-r--r--dom/base/nsDOMNavigationTiming.cpp7
-rw-r--r--dom/base/nsDeprecatedOperationList.h1
-rw-r--r--dom/base/nsDocument.cpp120
-rw-r--r--dom/base/nsDocument.h5
-rw-r--r--dom/base/nsFrameLoader.cpp3
-rw-r--r--dom/base/nsFrameMessageManager.cpp8
-rw-r--r--dom/base/nsGlobalWindow.cpp98
-rw-r--r--dom/base/nsGlobalWindow.h24
-rw-r--r--dom/base/nsIDocument.h18
-rw-r--r--dom/base/nsINode.cpp49
-rw-r--r--dom/base/nsJSEnvironment.cpp15
-rw-r--r--dom/base/nsNodeInfoManager.cpp3
-rw-r--r--dom/base/nsObjectLoadingContent.cpp9
-rw-r--r--dom/base/nsScriptLoader.cpp12
-rw-r--r--dom/bindings/BindingUtils.cpp4
-rw-r--r--dom/bindings/BindingUtils.h2
-rw-r--r--dom/bindings/Bindings.conf5
-rw-r--r--dom/bindings/ErrorResult.h2
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp13
-rw-r--r--dom/canvas/CanvasRenderingContextHelper.cpp14
-rw-r--r--dom/canvas/WebGL1Context.cpp3
-rw-r--r--dom/canvas/WebGLContext.cpp103
-rw-r--r--dom/canvas/WebGLContext.h3
-rw-r--r--dom/canvas/WebGLContextExtensions.cpp8
-rw-r--r--dom/canvas/WebGLContextState.cpp12
-rw-r--r--dom/canvas/WebGLContextUtils.cpp12
-rw-r--r--dom/canvas/WebGLContextUtils.h2
-rw-r--r--dom/canvas/WebGLExtensionDebugGet.cpp79
-rw-r--r--dom/canvas/WebGLExtensions.h14
-rw-r--r--dom/canvas/WebGLTypes.h1
-rw-r--r--dom/canvas/moz.build1
-rw-r--r--dom/crypto/WebCryptoTask.cpp46
-rw-r--r--dom/events/EventDispatcher.cpp48
-rw-r--r--dom/events/EventStateManager.cpp6
-rw-r--r--dom/events/EventStateManager.h3
-rw-r--r--dom/fetch/Fetch.cpp7
-rw-r--r--dom/fetch/FetchConsumer.cpp10
-rw-r--r--dom/fetch/FetchDriver.cpp3
-rw-r--r--dom/gamepad/GamepadManager.cpp18
-rw-r--r--dom/gamepad/GamepadManager.h6
-rw-r--r--dom/gamepad/ipc/GamepadServiceType.h4
-rw-r--r--dom/geolocation/nsGeolocation.cpp39
-rw-r--r--dom/html/HTMLCanvasElement.cpp41
-rw-r--r--dom/html/HTMLCanvasElement.h4
-rw-r--r--dom/html/HTMLFormElement.cpp8
-rw-r--r--dom/html/HTMLInputElement.cpp10
-rw-r--r--dom/html/HTMLMediaElement.cpp130
-rw-r--r--dom/html/HTMLOptionsCollection.cpp51
-rw-r--r--dom/html/HTMLOptionsCollection.h9
-rw-r--r--dom/html/HTMLSelectElement.cpp5
-rw-r--r--dom/html/HTMLSelectElement.h2
-rw-r--r--dom/html/ImageDocument.cpp17
-rw-r--r--dom/html/ImageDocument.h3
-rw-r--r--dom/html/TextTrackManager.cpp25
-rw-r--r--dom/html/TextTrackManager.h8
-rw-r--r--dom/html/nsTextEditorState.cpp13
-rw-r--r--dom/indexedDB/ActorsParent.cpp35
-rw-r--r--dom/indexedDB/IDBFactory.cpp18
-rw-r--r--dom/indexedDB/KeyPath.cpp77
-rw-r--r--dom/ipc/ContentChild.cpp9
-rw-r--r--dom/ipc/ContentChild.h6
-rw-r--r--dom/ipc/ContentParent.cpp13
-rw-r--r--dom/ipc/PContent.ipdl3
-rw-r--r--dom/ipc/TabChild.cpp3
-rw-r--r--dom/locales/en-US/chrome/dom/dom.properties2
-rw-r--r--dom/locales/en-US/chrome/security/security.properties1
-rw-r--r--dom/media/AudioStream.cpp6
-rw-r--r--dom/media/Benchmark.cpp2
-rw-r--r--dom/media/CubebUtils.cpp33
-rw-r--r--dom/media/CubebUtils.h2
-rw-r--r--dom/media/DecoderTraits.cpp96
-rw-r--r--dom/media/GraphDriver.cpp20
-rw-r--r--dom/media/GraphDriver.h6
-rw-r--r--dom/media/MP3FrameParser.cpp591
-rw-r--r--dom/media/MP3FrameParser.h219
-rw-r--r--dom/media/MediaData.h3
-rw-r--r--dom/media/MediaDecoder.cpp15
-rw-r--r--dom/media/MediaDecoder.h4
-rw-r--r--dom/media/MediaDecoderStateMachine.cpp35
-rw-r--r--dom/media/MediaFormatReader.cpp4
-rw-r--r--dom/media/MediaManager.cpp27
-rw-r--r--dom/media/MediaPrefs.h6
-rw-r--r--dom/media/MediaStreamGraph.cpp3
-rw-r--r--dom/media/ThreadPoolCOMListener.h4
-rw-r--r--dom/media/VideoUtils.cpp56
-rw-r--r--dom/media/VideoUtils.h5
-rw-r--r--dom/media/WebVTTListener.h1
-rw-r--r--dom/media/android/AndroidMediaDecoder.cpp25
-rw-r--r--dom/media/android/AndroidMediaDecoder.h28
-rw-r--r--dom/media/android/AndroidMediaPluginHost.cpp305
-rw-r--r--dom/media/android/AndroidMediaPluginHost.h41
-rw-r--r--dom/media/android/AndroidMediaReader.cpp449
-rw-r--r--dom/media/android/AndroidMediaReader.h75
-rw-r--r--dom/media/android/AndroidMediaResourceServer.cpp503
-rw-r--r--dom/media/android/AndroidMediaResourceServer.h96
-rw-r--r--dom/media/android/MPAPI.h165
-rw-r--r--dom/media/android/moz.build27
-rw-r--r--dom/media/directshow/AudioSinkFilter.cpp285
-rw-r--r--dom/media/directshow/AudioSinkFilter.h95
-rw-r--r--dom/media/directshow/AudioSinkInputPin.cpp195
-rw-r--r--dom/media/directshow/AudioSinkInputPin.h76
-rw-r--r--dom/media/directshow/DirectShowDecoder.cpp65
-rw-r--r--dom/media/directshow/DirectShowDecoder.h45
-rw-r--r--dom/media/directshow/DirectShowReader.cpp360
-rw-r--r--dom/media/directshow/DirectShowReader.h110
-rw-r--r--dom/media/directshow/DirectShowUtils.cpp369
-rw-r--r--dom/media/directshow/DirectShowUtils.h125
-rw-r--r--dom/media/directshow/SampleSink.cpp159
-rw-r--r--dom/media/directshow/SampleSink.h67
-rw-r--r--dom/media/directshow/SourceFilter.cpp683
-rw-r--r--dom/media/directshow/SourceFilter.h75
-rw-r--r--dom/media/directshow/moz.build41
-rw-r--r--dom/media/eme/DetailedPromise.cpp3
-rw-r--r--dom/media/eme/MediaKeySession.cpp3
-rw-r--r--dom/media/eme/MediaKeys.cpp2
-rw-r--r--dom/media/fmp4/MP4Decoder.cpp12
-rw-r--r--dom/media/fmp4/MP4Demuxer.cpp26
-rw-r--r--dom/media/fmp4/MP4Stream.cpp3
-rw-r--r--dom/media/fmp4/moz.build3
-rw-r--r--dom/media/gmp/GMPParent.cpp3
-rw-r--r--dom/media/gtest/Cargo.toml7
-rw-r--r--dom/media/gtest/TestMP3Demuxer.cpp1
-rw-r--r--dom/media/gtest/TestMP4Reader.cpp217
-rw-r--r--dom/media/gtest/TestRust.cpp9
-rw-r--r--dom/media/gtest/hello.rs6
-rw-r--r--dom/media/gtest/moz.build1
-rw-r--r--dom/media/mediasource/MediaSource.cpp2
-rw-r--r--dom/media/mediasource/moz.build3
-rw-r--r--dom/media/moz.build18
-rw-r--r--dom/media/mp3/MP3Decoder.cpp (renamed from dom/media/MP3Decoder.cpp)2
-rw-r--r--dom/media/mp3/MP3Decoder.h (renamed from dom/media/MP3Decoder.h)0
-rw-r--r--dom/media/mp3/MP3Demuxer.cpp (renamed from dom/media/MP3Demuxer.cpp)2
-rw-r--r--dom/media/mp3/MP3Demuxer.h (renamed from dom/media/MP3Demuxer.h)2
-rw-r--r--dom/media/mp3/moz.build17
-rw-r--r--dom/media/ogg/OggDemuxer.cpp2
-rw-r--r--dom/media/platforms/MediaTelemetryConstants.h22
-rw-r--r--dom/media/platforms/PDMFactory.cpp9
-rw-r--r--dom/media/platforms/agnostic/AOMDecoder.cpp332
-rw-r--r--dom/media/platforms/agnostic/AOMDecoder.h62
-rw-r--r--dom/media/platforms/agnostic/AgnosticDecoderModule.cpp19
-rw-r--r--dom/media/platforms/agnostic/VPXDecoder.cpp53
-rw-r--r--dom/media/platforms/agnostic/VPXDecoder.h12
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp18
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp3
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegLibWrapper.h7
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp75
-rw-r--r--dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h1
-rw-r--r--dom/media/platforms/ffmpeg/ffvpx/moz.build2
-rw-r--r--dom/media/platforms/moz.build9
-rw-r--r--dom/media/platforms/omx/OmxPlatformLayer.cpp23
-rw-r--r--dom/media/platforms/wmf/DXVA2Manager.cpp8
-rw-r--r--dom/media/platforms/wmf/WMFAudioMFTManager.cpp1
-rw-r--r--dom/media/platforms/wmf/WMFDecoderModule.h6
-rw-r--r--dom/media/platforms/wmf/WMFMediaDataDecoder.cpp3
-rw-r--r--dom/media/platforms/wmf/WMFMediaDataDecoder.h2
-rw-r--r--dom/media/platforms/wmf/WMFVideoMFTManager.cpp4
-rw-r--r--dom/media/systemservices/LoadManager.cpp18
-rw-r--r--dom/media/test/bug1377278.webm (renamed from dom/media/test/bug580982.webm)bin215594 -> 215594 bytes
-rw-r--r--dom/media/test/bug1377278.webm^headers^ (renamed from dom/media/test/bug580982.webm^headers^)0
-rw-r--r--dom/media/test/manifest.js8
-rw-r--r--dom/media/test/mochitest.ini4
-rw-r--r--dom/media/test/test_can_play_type_mpeg.html3
-rw-r--r--dom/media/webaudio/MediaBufferDecoder.cpp2
-rw-r--r--dom/media/webm/WebMDecoder.cpp9
-rw-r--r--dom/media/webm/WebMDemuxer.cpp166
-rw-r--r--dom/media/webm/WebMDemuxer.h18
-rw-r--r--dom/media/webrtc/RTCCertificate.cpp2
-rw-r--r--dom/moz.build1
-rw-r--r--dom/notification/Notification.cpp45
-rw-r--r--dom/plugins/base/nsPluginHost.cpp9
-rw-r--r--dom/plugins/ipc/PluginAsyncSurrogate.cpp2
-rw-r--r--dom/plugins/ipc/PluginHangUIParent.cpp9
-rw-r--r--dom/plugins/ipc/PluginInstanceParent.cpp13
-rwxr-xr-xdom/plugins/ipc/PluginModuleParent.cpp48
-rw-r--r--dom/presentation/provider/PresentationControlService.js1
-rw-r--r--dom/security/nsMixedContentBlocker.cpp41
-rw-r--r--dom/security/test/cors/test_CrossSiteXHR.html2
-rw-r--r--dom/storage/DOMStorageCache.cpp5
-rw-r--r--dom/storage/DOMStorageDBThread.cpp2
-rw-r--r--dom/svg/SVGUseElement.cpp9
-rw-r--r--dom/svg/test/reftest_viewport_noninteger.html175
-rw-r--r--dom/system/mac/CoreLocationLocationProvider.mm3
-rw-r--r--dom/system/windows/WindowsLocationProvider.cpp4
-rw-r--r--dom/vr/VRDisplay.cpp802
-rw-r--r--dom/vr/VRDisplay.h362
-rw-r--r--dom/vr/VREventObserver.cpp79
-rw-r--r--dom/vr/VREventObserver.h33
-rw-r--r--dom/vr/moz.build22
-rw-r--r--dom/webidl/CommandEvent.webidl6
-rw-r--r--dom/webidl/CompositionEvent.webidl10
-rw-r--r--dom/webidl/CustomEvent.webidl6
-rw-r--r--dom/webidl/DeviceMotionEvent.webidl12
-rw-r--r--dom/webidl/DeviceOrientationEvent.webidl12
-rw-r--r--dom/webidl/DragEvent.webidl30
-rw-r--r--dom/webidl/Event.webidl4
-rw-r--r--dom/webidl/HashChangeEvent.webidl8
-rw-r--r--dom/webidl/KeyEvent.webidl18
-rw-r--r--dom/webidl/MessageEvent.webidl12
-rw-r--r--dom/webidl/MouseEvent.webidl64
-rw-r--r--dom/webidl/MouseScrollEvent.webidl30
-rw-r--r--dom/webidl/MutationEvent.webidl14
-rw-r--r--dom/webidl/Navigator.webidl8
-rw-r--r--dom/webidl/ScrollAreaEvent.webidl16
-rw-r--r--dom/webidl/SimpleGestureEvent.webidl36
-rw-r--r--dom/webidl/StorageEvent.webidl14
-rw-r--r--dom/webidl/TimeEvent.webidl4
-rw-r--r--dom/webidl/TouchEvent.webidl22
-rw-r--r--dom/webidl/UIEvent.webidl8
-rw-r--r--dom/webidl/VRDisplay.webidl286
-rw-r--r--dom/webidl/WebGLRenderingContext.webidl9
-rw-r--r--dom/webidl/XULCommandEvent.webidl18
-rw-r--r--dom/webidl/moz.build1
-rw-r--r--dom/workers/RuntimeService.cpp13
-rw-r--r--dom/workers/ServiceWorkerClient.cpp2
-rw-r--r--dom/workers/ServiceWorkerClients.cpp8
-rw-r--r--dom/workers/ServiceWorkerEvents.cpp20
-rw-r--r--dom/workers/ServiceWorkerManager.cpp3
-rw-r--r--dom/workers/ServiceWorkerPrivate.cpp15
-rw-r--r--dom/workers/ServiceWorkerRegistrar.cpp3
-rw-r--r--dom/workers/ServiceWorkerRegistration.cpp8
-rw-r--r--dom/workers/ServiceWorkerUpdateJob.cpp2
-rw-r--r--dom/workers/ServiceWorkerWindowClient.cpp4
-rw-r--r--dom/workers/SharedWorker.cpp3
-rw-r--r--dom/workers/WorkerPrivate.cpp10
-rw-r--r--dom/workers/WorkerRunnable.cpp25
-rw-r--r--dom/workers/WorkerScope.cpp2
-rw-r--r--dom/xbl/nsXBLBinding.cpp3
-rw-r--r--dom/xbl/nsXBLProtoImpl.cpp12
-rw-r--r--dom/xhr/XMLHttpRequestMainThread.cpp11
-rw-r--r--dom/xhr/XMLHttpRequestWorker.cpp2
-rw-r--r--dom/xul/nsXULPrototypeCache.cpp6
244 files changed, 1842 insertions, 9201 deletions
diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp
index e39abf1a6..e7b3cd0da 100644
--- a/dom/base/DOMIntersectionObserver.cpp
+++ b/dom/base/DOMIntersectionObserver.cpp
@@ -43,16 +43,18 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+ tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries)
- tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries)
@@ -153,30 +155,29 @@ DOMIntersectionObserver::Observe(Element& aTarget)
return;
}
aTarget.RegisterIntersectionObserver(this);
- mObservationTargets.PutEntry(&aTarget);
+ mObservationTargets.AppendElement(&aTarget);
Connect();
}
void
DOMIntersectionObserver::Unobserve(Element& aTarget)
{
- if (UnlinkTarget(aTarget)) {
- aTarget.UnregisterIntersectionObserver(this);
+ if (mObservationTargets.Length() == 1) {
+ Disconnect();
+ return;
}
+
+ mObservationTargets.RemoveElement(&aTarget);
+ aTarget.UnregisterIntersectionObserver(this);
}
-bool
+void
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
{
- if (!mObservationTargets.Contains(&aTarget)) {
- return false;
- }
- if (mObservationTargets.Count() == 1) {
- Disconnect();
- return false;
- }
- mObservationTargets.RemoveEntry(&aTarget);
- return true;
+ mObservationTargets.RemoveElement(&aTarget);
+ if (mObservationTargets.Length() == 0) {
+ Disconnect();
+ }
}
void
@@ -185,10 +186,11 @@ DOMIntersectionObserver::Connect()
if (mConnected) {
return;
}
+
mConnected = true;
-
- nsIDocument* document = mOwner->GetExtantDoc();
- document->AddIntersectionObserver(this);
+ if(mDocument) {
+ mDocument->AddIntersectionObserver(this);
+ }
}
void
@@ -197,18 +199,17 @@ DOMIntersectionObserver::Disconnect()
if (!mConnected) {
return;
}
- for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
- Element* target = iter.Get()->GetKey();
+
+ mConnected = false;
+
+ for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
+ Element* target = mObservationTargets.ElementAt(i);
target->UnregisterIntersectionObserver(this);
}
mObservationTargets.Clear();
- if (mOwner) {
- nsIDocument* document = mOwner->GetExtantDoc();
- if (document) {
- document->RemoveIntersectionObserver(this);
- }
+ if (mDocument) {
+ mDocument->RemoveIntersectionObserver(this);
}
- mConnected = false;
}
void
@@ -269,17 +270,21 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
root = mRoot;
rootFrame = root->GetPrimaryFrame();
if (rootFrame) {
+ nsRect rootRectRelativeToRootFrame;
if (rootFrame->GetType() == nsGkAtoms::scrollFrame) {
+ // rootRectRelativeToRootFrame should be the content rect of rootFrame, not including the scrollbars.
nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame);
- rootRect = nsLayoutUtils::TransformFrameRectToAncestor(
- rootFrame,
- rootFrame->GetContentRectRelativeToSelf(),
- scrollFrame->GetScrolledFrame());
+ rootRectRelativeToRootFrame = scrollFrame->GetScrollPortRect();
} else {
- rootRect = nsLayoutUtils::GetAllInFlowRectsUnion(rootFrame,
- nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
- nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+ // rootRectRelativeToRootFrame should be the border rect of rootFrame.
+ rootRectRelativeToRootFrame = rootFrame->GetRectRelativeToSelf();
}
+ nsIFrame* containingBlock =
+ nsLayoutUtils::GetContainingBlockForClientRect(rootFrame);
+ rootRect =
+ nsLayoutUtils::TransformFrameRectToAncestor(rootFrame,
+ rootRectRelativeToRootFrame,
+ containingBlock);
}
} else {
nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell();
@@ -314,11 +319,12 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord);
}
- for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) {
- Element* target = iter.Get()->GetKey();
+ for (size_t i = 0; i < mObservationTargets.Length(); ++i) {
+ Element* target = mObservationTargets.ElementAt(i);
nsIFrame* targetFrame = target->GetPrimaryFrame();
nsRect targetRect;
Maybe<nsRect> intersectionRect;
+ bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc();
if (rootFrame && targetFrame) {
// If mRoot is set we are testing intersection with a container element
@@ -327,7 +333,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
// Skip further processing of this target if it is not in the same
// Document as the intersection root, e.g. if root is an element of
// the main document and target an element from an embedded iframe.
- if (target->GetComposedDoc() != root->GetComposedDoc()) {
+ if (!isSameDoc) {
continue;
}
// Skip further processing of this target if is not a descendant of the
@@ -344,7 +350,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
nsLayoutUtils::GetContainingBlockForClientRect(targetFrame),
nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS
);
- intersectionRect = Some(targetFrame->GetVisualOverflowRect());
+ intersectionRect = Some(targetFrame->GetRectRelativeToSelf());
nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame);
while (containerFrame && containerFrame != rootFrame) {
@@ -399,29 +405,37 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time
intersectionRectRelativeToRoot,
rootIntersectionRect
);
- if (intersectionRect.isSome()) {
- intersectionRect = Some(nsLayoutUtils::TransformFrameRectToAncestor(
- nsLayoutUtils::GetContainingBlockForClientRect(rootFrame),
- intersectionRect.value(),
- targetFrame->PresContext()->PresShell()->GetRootScrollFrame()
- ));
+ if (intersectionRect.isSome() && !isSameDoc) {
+ nsRect rect = intersectionRect.value();
+ nsPresContext* presContext = targetFrame->PresContext();
+ nsLayoutUtils::TransformRect(rootFrame,
+ presContext->PresShell()->GetRootScrollFrame(), rect);
+ intersectionRect = Some(rect);
}
}
- double targetArea = targetRect.width * targetRect.height;
- double intersectionArea = !intersectionRect ?
- 0 : intersectionRect->width * intersectionRect->height;
- double intersectionRatio = targetArea > 0.0 ? intersectionArea / targetArea : 0.0;
+ int64_t targetArea =
+ (int64_t) targetRect.Width() * (int64_t) targetRect.Height();
+ int64_t intersectionArea = !intersectionRect ? 0 :
+ (int64_t) intersectionRect->Width() *
+ (int64_t) intersectionRect->Height();
+
+ double intersectionRatio;
+ if (targetArea > 0.0) {
+ intersectionRatio = (double) intersectionArea / (double) targetArea;
+ } else {
+ intersectionRatio = intersectionRect.isSome() ? 1.0 : 0.0;
+ }
- size_t threshold = -1;
+ int32_t threshold = -1;
if (intersectionRatio > 0.0) {
if (intersectionRatio >= 1.0) {
intersectionRatio = 1.0;
- threshold = mThresholds.Length();
+ threshold = (int32_t)mThresholds.Length();
} else {
for (size_t k = 0; k < mThresholds.Length(); ++k) {
if (mThresholds[k] <= intersectionRatio) {
- threshold = k + 1;
+ threshold = (int32_t)k + 1;
} else {
break;
}
@@ -480,7 +494,7 @@ DOMIntersectionObserver::Notify()
}
mozilla::dom::Sequence<mozilla::OwningNonNull<DOMIntersectionObserverEntry>> entries;
if (entries.SetCapacity(mQueuedEntries.Length(), mozilla::fallible)) {
- for (uint32_t i = 0; i < mQueuedEntries.Length(); ++i) {
+ for (size_t i = 0; i < mQueuedEntries.Length(); ++i) {
RefPtr<DOMIntersectionObserverEntry> next = mQueuedEntries[i];
*entries.AppendElement(mozilla::fallible) = next;
}
diff --git a/dom/base/DOMIntersectionObserver.h b/dom/base/DOMIntersectionObserver.h
index 8144fc5c5..9c8ebf5b1 100644
--- a/dom/base/DOMIntersectionObserver.h
+++ b/dom/base/DOMIntersectionObserver.h
@@ -106,7 +106,10 @@ class DOMIntersectionObserver final : public nsISupports,
public:
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
mozilla::dom::IntersectionCallback& aCb)
- : mOwner(aOwner), mCallback(&aCb), mConnected(false)
+ : mOwner(aOwner)
+ , mDocument(mOwner->GetExtantDoc())
+ , mCallback(&aCb)
+ , mConnected(false)
{
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -142,7 +145,7 @@ public:
void Observe(Element& aTarget);
void Unobserve(Element& aTarget);
- bool UnlinkTarget(Element& aTarget);
+ void UnlinkTarget(Element& aTarget);
void Disconnect();
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
@@ -164,11 +167,15 @@ protected:
double aIntersectionRatio);
nsCOMPtr<nsPIDOMWindowInner> mOwner;
+ RefPtr<nsIDocument> mDocument;
RefPtr<mozilla::dom::IntersectionCallback> mCallback;
RefPtr<Element> mRoot;
nsCSSRect mRootMargin;
nsTArray<double> mThresholds;
- nsTHashtable<nsPtrHashKey<Element>> mObservationTargets;
+
+ // Holds raw pointers which are explicitly cleared by UnlinkTarget().
+ nsTArray<Element*> mObservationTargets;
+
nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
bool mConnected;
};
diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp
index 79b36a314..67759fdb2 100644
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -145,7 +145,6 @@
#include "mozilla/dom/KeyframeEffectBinding.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
-#include "mozilla/dom/VRDisplay.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Preferences.h"
#include "nsComputedDOMStyle.h"
@@ -3948,7 +3947,7 @@ Element::ClearDataset()
slots->mDataset = nullptr;
}
-nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>*
+nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
Element::RegisteredIntersectionObservers()
{
nsDOMSlots* slots = DOMSlots();
@@ -3963,7 +3962,7 @@ enum nsPreviousIntersectionThreshold {
void
Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (observers->Contains(aObserver)) {
return;
@@ -3980,7 +3979,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
void
Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
observers->Remove(aObserver);
}
@@ -3988,7 +3987,7 @@ Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver)
bool
Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold)
{
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers =
RegisteredIntersectionObservers();
if (!observers->Contains(aObserver)) {
return false;
diff --git a/dom/base/Element.h b/dom/base/Element.h
index c269ab14a..ef57a6466 100644
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1382,7 +1382,8 @@ protected:
nsDOMTokenList* GetTokenList(nsIAtom* aAtom,
const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* RegisteredIntersectionObservers();
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>*
+ RegisteredIntersectionObservers();
private:
/**
diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp
index fde983e7c..13ba19c8c 100644
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -585,6 +585,12 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb,
mCustomElementData->mCallbackQueue[i]->Traverse(cb);
}
}
+
+ for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Key();
+ NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]");
+ cb.NoteXPCOMChild(observer);
+ }
}
void
diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h
index 7c74e9cd4..f0cc29f22 100644
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -354,7 +354,8 @@ public:
/**
* Registered Intersection Observers on the element.
*/
- nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t> mRegisteredIntersectionObservers;
+ nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
+ mRegisteredIntersectionObservers;
};
protected:
diff --git a/dom/base/Location.cpp b/dom/base/Location.cpp
index 7b3722f09..e312cffe0 100644
--- a/dom/base/Location.cpp
+++ b/dom/base/Location.cpp
@@ -33,6 +33,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsNullPrincipal.h"
#include "ScriptSettings.h"
+#include "mozilla/Unused.h"
#include "mozilla/dom/LocationBinding.h"
namespace mozilla {
@@ -716,9 +717,15 @@ Location::SetProtocol(const nsAString& aProtocol)
return rv;
}
- rv = uri->SetScheme(NS_ConvertUTF16toUTF8(aProtocol));
+ nsAString::const_iterator start, end;
+ aProtocol.BeginReading(start);
+ aProtocol.EndReading(end);
+ nsAString::const_iterator iter(start);
+ Unused << FindCharInReadable(':', iter, end);
+
+ rv = uri->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)));
if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+ return NS_ERROR_DOM_SYNTAX_ERR;
}
nsAutoCString newSpec;
rv = uri->GetSpec(newSpec);
@@ -728,8 +735,28 @@ Location::SetProtocol(const nsAString& aProtocol)
// We may want a new URI class for the new URI, so recreate it:
rv = NS_NewURI(getter_AddRefs(uri), newSpec);
if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_MALFORMED_URI) {
+ rv = NS_ERROR_DOM_SYNTAX_ERR;
+ }
return rv;
}
+
+ bool isHttp;
+ rv = uri->SchemeIs("http", &isHttp);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ bool isHttps;
+ rv = uri->SchemeIs("https", &isHttps);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ if (!isHttp && !isHttps) {
+ // No-op, per spec.
+ return NS_OK;
+ }
return SetURI(uri);
}
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index ed96ee23b..286cd0e79 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -44,7 +44,6 @@
#include "mozilla/dom/ServiceWorkerContainer.h"
#include "mozilla/dom/StorageManager.h"
#include "mozilla/dom/TCPSocket.h"
-#include "mozilla/dom/VRDisplay.h"
#include "mozilla/dom/workers/RuntimeService.h"
#include "mozilla/Hal.h"
#include "nsISiteSpecificUserAgent.h"
@@ -684,8 +683,6 @@ Navigator::GetDoNotTrack(nsAString &aResult)
bool
Navigator::JavaEnabled(ErrorResult& aRv)
{
- Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
-
// Return true if we have a handler for the java mime
nsAdoptingString javaMIME = Preferences::GetString("plugin.java.mime");
NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false);
@@ -1473,83 +1470,6 @@ Navigator::RequestGamepadServiceTest()
}
#endif
-already_AddRefed<Promise>
-Navigator::GetVRDisplays(ErrorResult& aRv)
-{
- if (!mWindow || !mWindow->GetDocShell()) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
- win->NotifyVREventListenerAdded();
-
- nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
- RefPtr<Promise> p = Promise::Create(go, aRv);
- if (aRv.Failed()) {
- return nullptr;
- }
-
- // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will
- // be called asynchronously, resolving the promises in mVRGetDisplaysPromises.
- if (!VRDisplay::RefreshVRDisplays(win->WindowID())) {
- p->MaybeReject(NS_ERROR_FAILURE);
- return p.forget();
- }
-
- mVRGetDisplaysPromises.AppendElement(p);
- return p.forget();
-}
-
-void
-Navigator::GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const
-{
- /**
- * Get only the active VR displays.
- * Callers do not wish to VRDisplay::RefreshVRDisplays, as the enumeration may
- * activate hardware that is not yet intended to be used.
- */
- if (!mWindow || !mWindow->GetDocShell()) {
- return;
- }
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
- win->NotifyVREventListenerAdded();
- nsTArray<RefPtr<VRDisplay>> displays;
- if (win->UpdateVRDisplays(displays)) {
- for (auto display : displays) {
- if (display->IsPresenting()) {
- aDisplays.AppendElement(display);
- }
- }
- }
-}
-
-void
-Navigator::NotifyVRDisplaysUpdated()
-{
- // Synchronize the VR devices and resolve the promises in
- // mVRGetDisplaysPromises
- nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow);
-
- nsTArray<RefPtr<VRDisplay>> vrDisplays;
- if (win->UpdateVRDisplays(vrDisplays)) {
- for (auto p : mVRGetDisplaysPromises) {
- p->MaybeResolve(vrDisplays);
- }
- } else {
- for (auto p : mVRGetDisplaysPromises) {
- p->MaybeReject(NS_ERROR_FAILURE);
- }
- }
- mVRGetDisplaysPromises.Clear();
-}
-
-void
-Navigator::NotifyActiveVRDisplaysChanged()
-{
- NavigatorBinding::ClearCachedActiveVRDisplaysValue(this);
-}
-
//*****************************************************************************
// Navigator::nsIMozNavigatorNetwork
//*****************************************************************************
diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h
index d47a80bc1..91b7fc15c 100644
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -76,7 +76,6 @@ class Connection;
class PowerManager;
class Presentation;
class LegacyMozTCPSocket;
-class VRDisplay;
class StorageManager;
namespace time {
@@ -204,8 +203,6 @@ public:
void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
GamepadServiceTest* RequestGamepadServiceTest();
#endif // MOZ_GAMEPAD
- already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv);
- void GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const;
#ifdef MOZ_TIME_MANAGER
time::TimeManager* GetMozTime(ErrorResult& aRv);
#endif // MOZ_TIME_MANAGER
@@ -269,10 +266,6 @@ private:
RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager;
#endif
-public:
- void NotifyVRDisplaysUpdated();
- void NotifyActiveVRDisplaysChanged();
-
private:
virtual ~Navigator();
diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp
index 861cda521..db4d0d351 100644
--- a/dom/base/nsCCUncollectableMarker.cpp
+++ b/dom/base/nsCCUncollectableMarker.cpp
@@ -188,23 +188,20 @@ MarkMessageManagers()
}
void
-MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
- bool aPrepareForCC)
+MarkDocument(nsIDocument* aDoc, bool aCleanupJS, bool aPrepareForCC)
{
- if (!aViewer) {
+ if (!aDoc) {
return;
}
- nsIDocument *doc = aViewer->GetDocument();
- if (doc &&
- doc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) {
- doc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ if (aDoc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) {
+ aDoc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
if (aCleanupJS) {
- EventListenerManager* elm = doc->GetExistingListenerManager();
+ EventListenerManager* elm = aDoc->GetExistingListenerManager();
if (elm) {
elm->MarkForCC();
}
- nsCOMPtr<EventTarget> win = do_QueryInterface(doc->GetInnerWindow());
+ nsCOMPtr<EventTarget> win = do_QueryInterface(aDoc->GetInnerWindow());
if (win) {
elm = win->GetExistingListenerManager();
if (elm) {
@@ -215,18 +212,27 @@ MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
} else if (aPrepareForCC) {
// Unfortunately we need to still mark user data just before running CC so
// that it has the right generation.
- doc->PropertyTable(DOM_USER_DATA)->
+ aDoc->PropertyTable(DOM_USER_DATA)->
EnumerateAll(MarkUserData, &nsCCUncollectableMarker::sGeneration);
}
}
- if (doc) {
- if (nsPIDOMWindowInner* inner = doc->GetInnerWindow()) {
- inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
- }
- if (nsPIDOMWindowOuter* outer = doc->GetWindow()) {
- outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
- }
+ if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) {
+ inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ }
+ if (nsPIDOMWindowOuter* outer = aDoc->GetWindow()) {
+ outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration);
+ }
+}
+
+void
+MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
+ bool aPrepareForCC)
+{
+ if (!aViewer) {
+ return;
}
+
+ MarkDocument(aViewer->GetDocument(), aCleanupJS, aPrepareForCC);
}
void MarkDocShell(nsIDocShellTreeItem* aNode, bool aCleanupJS,
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 34c7d23b8..3696195dd 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -7597,6 +7597,24 @@ nsContentUtils::IsFileImage(nsIFile* aFile, nsACString& aType)
}
nsresult
+nsContentUtils::CalculateBufferSizeForImage(const uint32_t& aStride,
+ const IntSize& aImageSize,
+ const SurfaceFormat& aFormat,
+ size_t* aMaxBufferSize,
+ size_t* aUsedBufferSize)
+{
+ CheckedInt32 requiredBytes =
+ CheckedInt32(aStride) * CheckedInt32(aImageSize.height);
+ if (!requiredBytes.isValid()) {
+ return NS_ERROR_FAILURE;
+ }
+ *aMaxBufferSize = requiredBytes.value();
+ *aUsedBufferSize = *aMaxBufferSize - aStride +
+ (aImageSize.width * BytesPerPixel(aFormat));
+ return NS_OK;
+}
+
+nsresult
nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
imgIContainer** aContainer)
{
@@ -7611,6 +7629,22 @@ nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
Shmem data = aItem.data().get_Shmem();
+ // Validate shared memory buffer size
+ size_t imageBufLen = 0;
+ size_t maxBufLen = 0;
+ nsresult rv = CalculateBufferSizeForImage(imageDetails.stride(),
+ size,
+ static_cast<SurfaceFormat>(
+ imageDetails.format()),
+ &maxBufLen,
+ &imageBufLen);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ if (imageBufLen > data.Size<uint8_t>()) {
+ return NS_ERROR_FAILURE;
+ }
+
RefPtr<DataSourceSurface> image =
CreateDataSourceSurfaceFromData(size,
static_cast<SurfaceFormat>(imageDetails.format()),
@@ -7950,20 +7984,19 @@ GetSurfaceDataImpl(mozilla::gfx::DataSourceSurface* aSurface,
return GetSurfaceDataContext::NullValue();
}
- mozilla::gfx::IntSize size = aSurface->GetSize();
- mozilla::CheckedInt32 requiredBytes =
- mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
- if (!requiredBytes.isValid()) {
+ size_t bufLen = 0;
+ size_t maxBufLen = 0;
+ nsresult rv = nsContentUtils::CalculateBufferSizeForImage(map.mStride,
+ aSurface->GetSize(),
+ aSurface->GetFormat(),
+ &maxBufLen,
+ &bufLen);
+ if (NS_FAILED(rv)) {
+ // Release mapped memory
+ aSurface->Unmap();
return GetSurfaceDataContext::NullValue();
}
- size_t maxBufLen = requiredBytes.value();
- mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
-
- // Surface data handling is totally nuts. This is the magic one needs to
- // know to access the data.
- size_t bufLen = maxBufLen - map.mStride + (size.width * BytesPerPixel(format));
-
// nsDependentCString wants null-terminated string.
typename GetSurfaceDataContext::ReturnType surfaceData = aContext.Allocate(maxBufLen + 1);
if (GetSurfaceDataContext::GetBuffer(surfaceData)) {
@@ -9787,3 +9820,19 @@ nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel)
return reloadSucceeded;
}
+
+/* static */ bool
+nsContentUtils::IsLocalRefURL(const nsString& aString)
+{
+ // Find the first non-"C0 controls + space" character.
+ const char16_t* current = aString.get();
+ for (; *current != '\0'; current++) {
+ if (*current > 0x20) {
+ // if the first non-"C0 controls + space" character is '#', this is a
+ // local-ref URL.
+ return *current == '#';
+ }
+ }
+
+ return false;
+} \ No newline at end of file
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 9ae6d2155..98df92efb 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -975,11 +975,17 @@ public:
static bool PrefetchEnabled(nsIDocShell* aDocShell);
+ static nsresult CalculateBufferSizeForImage(const uint32_t& aStride,
+ const mozilla::gfx::IntSize& aImageSize,
+ const mozilla::gfx::SurfaceFormat& aFormat,
+ size_t* aMaxBufferSize,
+ size_t* aUsedBufferSize);
+
+private:
/**
* Fill (with the parameters given) the localized string named |aKey| in
* properties file |aFile|.
*/
-private:
static nsresult FormatLocalizedString(PropertiesFile aFile,
const char* aKey,
const char16_t** aParams,
@@ -2730,6 +2736,13 @@ public:
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
+ /**
+ * Detect whether a string is a (CSS) local-url.
+ * https://drafts.csswg.org/css-values/#local-urls
+ */
+ static bool
+ IsLocalRefURL(const nsString& aString);
+
private:
static bool InitializeEventTable();
diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp
index d125e5ad1..1cfde6e1b 100644
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -49,7 +49,6 @@
#include "nsContentUtils.h"
#include "nsIDOMGlobalPropertyInitializer.h"
#include "mozilla/Attributes.h"
-#include "mozilla/Telemetry.h"
// Window scriptable helper includes
#include "nsScriptNameSpaceManager.h"
@@ -1903,9 +1902,6 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
nsPIDOMWindowInner *win,
JS::MutableHandle<JS::PropertyDescriptor> desc)
{
- // Keep track of how often this happens.
- Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
-
// Warn once.
nsCOMPtr<nsIDocument> doc = win->GetExtantDoc();
if (doc) {
diff --git a/dom/base/nsDOMNavigationTiming.cpp b/dom/base/nsDOMNavigationTiming.cpp
index 32ce8a8cb..9c732f2d8 100644
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -15,7 +15,6 @@
#include "nsPrintfCString.h"
#include "mozilla/dom/PerformanceNavigation.h"
#include "mozilla/TimeStamp.h"
-#include "mozilla/Telemetry.h"
using namespace mozilla;
@@ -203,12 +202,6 @@ nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument()
mDocShellHasBeenActiveSinceNavigationStart ? "foreground tab" : "this tab was inactive some of the time between navigation start and first non-blank paint");
PROFILER_MARKER(marker.get());
}
-
- if (mDocShellHasBeenActiveSinceNavigationStart) {
- Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_NON_BLANK_PAINT_MS,
- mNavigationStart,
- mNonBlankPaint);
- }
}
void
diff --git a/dom/base/nsDeprecatedOperationList.h b/dom/base/nsDeprecatedOperationList.h
index 8fb381d9d..ea4b05289 100644
--- a/dom/base/nsDeprecatedOperationList.h
+++ b/dom/base/nsDeprecatedOperationList.h
@@ -44,7 +44,6 @@ DEPRECATED_OPERATION(PannerNodeDoppler)
DEPRECATED_OPERATION(NavigatorGetUserMedia)
DEPRECATED_OPERATION(WebrtcDeprecatedPrefix)
DEPRECATED_OPERATION(RTCPeerConnectionGetStreams)
-DEPRECATED_OPERATION(AppCache)
DEPRECATED_OPERATION(PrefixedImageSmoothingEnabled)
DEPRECATED_OPERATION(PrefixedFullscreenAPI)
DEPRECATED_OPERATION(LenientSetter)
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 8acfd901a..e779c060c 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -25,7 +25,6 @@
#include "plstr.h"
#include "mozilla/Sprintf.h"
-#include "mozilla/Telemetry.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
@@ -1737,8 +1736,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntersectionObservers)
-
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks)
for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
@@ -12370,115 +12367,21 @@ MightBeAboutOrChromeScheme(nsIURI* aURI)
void
nsDocument::ReportUseCounters()
{
- static const bool sDebugUseCounters = false;
- if (mReportedUseCounters) {
- return;
- }
-
- mReportedUseCounters = true;
-
- if (Telemetry::HistogramUseCounterCount > 0 &&
- (IsContentDocument() || IsResourceDoc())) {
- nsCOMPtr<nsIURI> uri;
- NodePrincipal()->GetURI(getter_AddRefs(uri));
- if (!uri || MightBeAboutOrChromeScheme(uri)) {
- return;
- }
-
- if (sDebugUseCounters) {
- nsCString spec = uri->GetSpecOrDefault();
-
- // URIs can be rather long for data documents, so truncate them to
- // some reasonable length.
- spec.Truncate(std::min(128U, spec.Length()));
- printf("-- Use counters for %s --\n", spec.get());
- }
-
- // We keep separate counts for individual documents and top-level
- // pages to more accurately track how many web pages might break if
- // certain features were removed. Consider the case of a single
- // HTML document with several SVG images and/or iframes with
- // sub-documents of their own. If we maintained a single set of use
- // counters and all the sub-documents use a particular feature, then
- // telemetry would indicate that we would be breaking N documents if
- // that feature were removed. Whereas with a document/top-level
- // page split, we can see that N documents would be affected, but
- // only a single web page would be affected.
-
- // The difference between the values of these two histograms and the
- // related use counters below tell us how many pages did *not* use
- // the feature in question. For instance, if we see that a given
- // session has destroyed 30 content documents, but a particular use
- // counter shows only a count of 5, we can infer that the use
- // counter was *not* used in 25 of those 30 documents.
- //
- // We do things this way, rather than accumulating a boolean flag
- // for each use counter, to avoid sending histograms for features
- // that don't get widely used. Doing things in this fashion means
- // smaller telemetry payloads and faster processing on the server
- // side.
- Telemetry::Accumulate(Telemetry::CONTENT_DOCUMENTS_DESTROYED, 1);
- if (IsTopLevelContentDocument()) {
- Telemetry::Accumulate(Telemetry::TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED, 1);
- }
-
- for (int32_t c = 0;
- c < eUseCounter_Count; ++c) {
- UseCounter uc = static_cast<UseCounter>(c);
-
- Telemetry::ID id =
- static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter + uc * 2);
- bool value = GetUseCounter(uc);
-
- if (value) {
- if (sDebugUseCounters) {
- const char* name = Telemetry::GetHistogramName(id);
- if (name) {
- printf(" %s", name);
- } else {
- printf(" #%d", id);
- }
- printf(": %d\n", value);
- }
-
- Telemetry::Accumulate(id, 1);
- }
-
- if (IsTopLevelContentDocument()) {
- id = static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter +
- uc * 2 + 1);
- value = GetUseCounter(uc) || GetChildDocumentUseCounter(uc);
-
- if (value) {
- if (sDebugUseCounters) {
- const char* name = Telemetry::GetHistogramName(id);
- if (name) {
- printf(" %s", name);
- } else {
- printf(" #%d", id);
- }
- printf(": %d\n", value);
- }
-
- Telemetry::Accumulate(id, 1);
- }
- }
- }
- }
+/* STUB */
}
void
nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- NS_ASSERTION(mIntersectionObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex,
- "Intersection observer already in the list");
- mIntersectionObservers.AppendElement(aObserver);
+ MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
+ "Intersection observer already in the list");
+ mIntersectionObservers.PutEntry(aObserver);
}
void
nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver)
{
- mIntersectionObservers.RemoveElement(aObserver);
+ mIntersectionObservers.RemoveEntry(aObserver);
}
void
@@ -12491,7 +12394,8 @@ nsDocument::UpdateIntersectionObservations()
time = perf->Now();
}
}
- for (const auto& observer : mIntersectionObservers) {
+ for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Get()->GetKey();
observer->Update(this, time);
}
}
@@ -12499,6 +12403,10 @@ nsDocument::UpdateIntersectionObservations()
void
nsDocument::ScheduleIntersectionObserverNotification()
{
+ if (mIntersectionObservers.IsEmpty()) {
+ return;
+ }
+
nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this,
&nsDocument::NotifyIntersectionObservers);
NS_DispatchToCurrentThread(notification);
@@ -12507,7 +12415,11 @@ nsDocument::ScheduleIntersectionObserverNotification()
void
nsDocument::NotifyIntersectionObservers()
{
- nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers);
+ nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
+ for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
+ DOMIntersectionObserver* observer = iter.Get()->GetKey();
+ observers.AppendElement(observer);
+ }
for (const auto& observer : observers) {
observer->Notify();
}
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 3725b3c18..d2f97a33e 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1341,8 +1341,9 @@ protected:
// Array of observers
nsTObserverArray<nsIDocumentObserver*> mObservers;
- // Array of intersection observers
- nsTArray<RefPtr<mozilla::dom::DOMIntersectionObserver>> mIntersectionObservers;
+ // Hashtable of intersection observers
+ nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
+ mIntersectionObservers;
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp
index 23067becd..2804f2d4c 100644
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -588,6 +588,9 @@ nsFrameLoader::ReallyStartLoadingInternal()
flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL;
}
+
+ // Notify that this load resulted from attribute changes.
+ loadInfo->SetIsFromProcessingFrameAttributes(true);
// Kick off the load...
bool tmpState = mNeedsAsyncDestroy;
diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp
index 6fffd376b..f173678b7 100644
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -32,7 +32,6 @@
#include "mozilla/CycleCollectedJSContext.h"
#include "mozilla/IntentionalCrash.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/nsIContentParent.h"
@@ -716,9 +715,6 @@ AllowMessage(size_t aDataLength, const nsAString& aMessageName)
NS_ConvertUTF16toUTF8 messageName(aMessageName);
messageName.StripChars("0123456789");
- Telemetry::Accumulate(Telemetry::MESSAGE_MANAGER_MESSAGE_SIZE2, messageName,
- aDataLength);
-
// A message includes more than structured clone data, so subtract
// 20KB to make it more likely that a message within this bound won't
// result in an overly large IPC message.
@@ -727,9 +723,6 @@ AllowMessage(size_t aDataLength, const nsAString& aMessageName)
return true;
}
- Telemetry::Accumulate(Telemetry::REJECTED_MESSAGE_MANAGER_MESSAGE,
- messageName);
-
return false;
}
@@ -2248,7 +2241,6 @@ nsSameProcessAsyncMessageBase::Init(const nsAString& aMessage,
nsIPrincipal* aPrincipal)
{
if (!mData.Copy(aData)) {
- Telemetry::Accumulate(Telemetry::IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB, aData.DataLength());
return NS_ERROR_OUT_OF_MEMORY;
}
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index 884ad69ca..677e1a0ea 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -202,16 +202,12 @@
#include "mozilla/dom/GamepadManager.h"
#endif
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/dom/VREventObserver.h"
-
#include "nsRefreshDriver.h"
#include "Layers.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/Location.h"
#include "nsHTMLDocument.h"
#include "nsWrapperCacheInlines.h"
@@ -1533,7 +1529,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mShowFocusRingForContent(false),
mFocusByKeyOccurred(false),
mHasGamepad(false),
- mHasVREvents(false),
#ifdef MOZ_GAMEPAD
mHasSeenGamepadInput(false),
#endif
@@ -1759,9 +1754,6 @@ nsGlobalWindow::~nsGlobalWindow()
DropOuterWindowDocs();
} else {
- Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
- mMutationBits ? 1 : 0);
-
if (mListenerManager) {
mListenerManager->Disconnect();
mListenerManager = nullptr;
@@ -1971,12 +1963,9 @@ nsGlobalWindow::CleanUp()
if (IsInnerWindow()) {
DisableGamepadUpdates();
mHasGamepad = false;
- DisableVRUpdates();
- mHasVREvents = false;
DisableIdleCallbackRequests();
} else {
MOZ_ASSERT(!mHasGamepad);
- MOZ_ASSERT(!mHasVREvents);
}
if (mCleanMessageManager) {
@@ -2027,7 +2016,7 @@ nsGlobalWindow::ClearControllers()
}
void
-nsGlobalWindow::FreeInnerObjects()
+nsGlobalWindow::FreeInnerObjects(bool aForDocumentOpen)
{
NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
@@ -2086,8 +2075,10 @@ nsGlobalWindow::FreeInnerObjects()
mDocumentURI = mDoc->GetDocumentURI();
mDocBaseURI = mDoc->GetDocBaseURI();
- while (mDoc->EventHandlingSuppressed()) {
- mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
+ if (!aForDocumentOpen) {
+ while (mDoc->EventHandlingSuppressed()) {
+ mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
+ }
}
// Note: we don't have to worry about eAnimationsOnly suppressions because
@@ -2120,9 +2111,6 @@ nsGlobalWindow::FreeInnerObjects()
mHasGamepad = false;
mGamepads.Clear();
#endif
- DisableVRUpdates();
- mHasVREvents = false;
- mVRDisplays.Clear();
}
//*****************************************************************************
@@ -2277,7 +2265,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)
// Traverse stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
@@ -2354,7 +2341,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
#endif
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)
// Unlink stuff from nsPIDOMWindow
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
@@ -2695,7 +2681,6 @@ TreatAsRemoteXUL(nsIPrincipal* aPrincipal)
static bool
EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp)
{
- Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true);
return xpc::EnableUniversalXPConnect(cx);
}
@@ -3005,6 +2990,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
+ bool handleDocumentOpen = false;
+
JS::Rooted<JSObject*> newInnerGlobal(cx);
if (reUseInnerWindow) {
// We're reusing the current inner window.
@@ -3096,6 +3083,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (currentInner && currentInner->GetWrapperPreserveColor()) {
if (oldDoc == aDocument) {
+ handleDocumentOpen = true;
// Move the navigator from the old inner window to the new one since
// this is a document.write. This is safe from a same-origin point of
// view because document.write can only be used by the same origin.
@@ -3120,7 +3108,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// Don't free objects on our current inner window if it's going to be
// held in the bfcache.
if (!currentInner->IsFrozen()) {
- currentInner->FreeInnerObjects();
+ currentInner->FreeInnerObjects(handleDocumentOpen);
}
}
@@ -3389,9 +3377,6 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
mLastOpenedURI = aDocument->GetDocumentURI();
#endif
- Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS,
- mMutationBits ? 1 : 0);
-
// Clear our mutation bitfield.
mMutationBits = 0;
}
@@ -6848,8 +6833,6 @@ FullscreenTransitionTask::Run()
Preferences::GetUint("full-screen-api.transition.timeout", 1000);
mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT);
} else if (stage == eAfterToggle) {
- Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS,
- mFullscreenChangeStartTime);
mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle,
mDuration.mFadeOut, mTransitionData,
this);
@@ -10513,24 +10496,6 @@ nsGlobalWindow::DisableGamepadUpdates()
}
void
-nsGlobalWindow::EnableVRUpdates()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- if (mHasVREvents && !mVREventObserver) {
- mVREventObserver = new VREventObserver(this);
- }
-}
-
-void
-nsGlobalWindow::DisableVRUpdates()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- mVREventObserver = nullptr;
-}
-
-void
nsGlobalWindow::SetChromeEventHandler(EventTarget* aChromeEventHandler)
{
MOZ_ASSERT(IsOuterWindow());
@@ -11577,11 +11542,6 @@ nsGlobalWindow::ShowSlowScriptDialog()
unsigned lineno;
bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);
- // Record the slow script event if we haven't done so already for this inner window
- // (which represents a particular page to the user).
- if (!mHasHadSlowScript) {
- Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_PAGE_COUNT, 1);
- }
mHasHadSlowScript = true;
if (XRE_IsContentProcess() &&
@@ -11613,10 +11573,6 @@ nsGlobalWindow::ShowSlowScriptDialog()
return ContinueSlowScriptAndKeepNotifying;
}
- // Reached only on non-e10s - once per slow script dialog.
- // On e10s - we probe once at ProcessHangsMonitor.jsm
- Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_NOTICE_COUNT, 1);
-
// Get the nsIPrompt interface from the docshell
nsCOMPtr<nsIDocShell> ds = GetDocShell();
NS_ENSURE_TRUE(ds, KillSlowScript);
@@ -12224,7 +12180,6 @@ nsGlobalWindow::Suspend()
ac->RemoveWindowListener(mEnabledSensors[i], this);
}
DisableGamepadUpdates();
- DisableVRUpdates();
mozilla::dom::workers::SuspendWorkersForWindow(AsInner());
@@ -12288,7 +12243,6 @@ nsGlobalWindow::Resume()
ac->AddWindowListener(mEnabledSensors[i], this);
}
EnableGamepadUpdates();
- EnableVRUpdates();
// Resume all of the AudioContexts for this window
for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
@@ -14044,19 +13998,6 @@ nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/)
void
nsGlobalWindow::EventListenerAdded(nsIAtom* aType)
{
- if (aType == nsGkAtoms::onvrdisplayconnect ||
- aType == nsGkAtoms::onvrdisplaydisconnect ||
- aType == nsGkAtoms::onvrdisplaypresentchange) {
- NotifyVREventListenerAdded();
- }
-}
-
-void
-nsGlobalWindow::NotifyVREventListenerAdded()
-{
- MOZ_ASSERT(IsInnerWindow());
- mHasVREvents = true;
- EnableVRUpdates();
}
void
@@ -14201,27 +14142,6 @@ nsGlobalWindow::SyncGamepadState()
}
#endif // MOZ_GAMEPAD
-bool
-nsGlobalWindow::UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices)
-{
- FORWARD_TO_INNER(UpdateVRDisplays, (aDevices), false);
-
- VRDisplay::UpdateVRDisplays(mVRDisplays, AsInner());
- aDevices = mVRDisplays;
- return true;
-}
-
-void
-nsGlobalWindow::NotifyActiveVRDisplaysChanged()
-{
- MOZ_ASSERT(IsInnerWindow());
-
- if (mNavigator) {
- mNavigator->NotifyActiveVRDisplaysChanged();
- }
-}
-
-
// nsGlobalChromeWindow implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
index 467bc6796..1cb825a77 100644
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -135,8 +135,6 @@ class SpeechSynthesis;
class TabGroup;
class Timeout;
class U2F;
-class VRDisplay;
-class VREventObserver;
class WakeLock;
#if defined(MOZ_WIDGET_ANDROID)
class WindowOrientationObserver;
@@ -745,18 +743,6 @@ public:
void EnableGamepadUpdates();
void DisableGamepadUpdates();
- // Inner windows only.
- // Enable/disable updates for VR
- void EnableVRUpdates();
- void DisableVRUpdates();
-
- // Update the VR displays for this window
- bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays);
-
- // Inner windows only.
- // Called to inform that the set of active VR displays has changed.
- void NotifyActiveVRDisplaysChanged();
-
#define EVENT(name_, id_, type_, struct_) \
mozilla::dom::EventHandlerNonNull* GetOn##name_() \
{ \
@@ -1380,7 +1366,7 @@ protected:
}
}
- void FreeInnerObjects();
+ void FreeInnerObjects(bool aForDocumentOpen = false);
nsGlobalWindow *CallerInnerWindow();
// Only to be called on an inner window.
@@ -1832,9 +1818,6 @@ protected:
// Indicates whether this window wants gamepad input events
bool mHasGamepad : 1;
- // Inner windows only.
- // Indicates whether this window wants VR events
- bool mHasVREvents : 1;
#ifdef MOZ_GAMEPAD
nsCheapSet<nsUint32HashKey> mGamepadIndexSet;
nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads;
@@ -1989,11 +1972,6 @@ protected:
// This is the CC generation the last time we called CanSkip.
uint32_t mCanSkipCCGeneration;
- // The VR Displays for this window
- nsTArray<RefPtr<mozilla::dom::VRDisplay>> mVRDisplays;
-
- nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver;
-
friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils;
friend class mozilla::dom::PostMessageEvent;
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 7a73fae71..e5d12ab8f 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3439,13 +3439,29 @@ nsINode::OwnerDocAsNode() const
return OwnerDoc();
}
+// ShouldUseXBLScope is defined here as a template so that we can get the faster
+// version of IsInAnonymousSubtree if we're statically known to be an
+// nsIContent. we could try defining ShouldUseXBLScope separately on nsINode
+// and nsIContent, but then we couldn't put its nsINode implementation here
+// (because this header does not include nsIContent) and we can't put it in
+// nsIContent.h, because the definition of nsIContent::IsInAnonymousSubtree is
+// in nsIContentInlines.h. And then we get include hell from people trying to
+// call nsINode::GetParentObject but not including nsIContentInlines.h and with
+// no really good way to include it.
+template<typename T>
+inline bool ShouldUseXBLScope(const T* aNode)
+{
+ return aNode->IsInAnonymousSubtree() &&
+ !aNode->IsAnonymousContentInSVGUseSubtree();
+}
+
inline mozilla::dom::ParentObject
nsINode::GetParentObject() const
{
mozilla::dom::ParentObject p(OwnerDoc());
// Note that mUseXBLScope is a no-op for chrome, and other places where we
// don't use XBL scopes.
- p.mUseXBLScope = IsInAnonymousSubtree() && !IsAnonymousContentInSVGUseSubtree();
+ p.mUseXBLScope = ShouldUseXBLScope(this);
return p;
}
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
index 09e848710..ca507a5fc 100644
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -27,6 +27,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/ShadowRoot.h"
+#include "mozilla/dom/ScriptSettings.h"
#include "nsAttrValueOrString.h"
#include "nsBindingManager.h"
#include "nsCCUncollectableMarker.h"
@@ -1569,6 +1570,48 @@ CheckForOutdatedParent(nsINode* aParent, nsINode* aNode)
return NS_OK;
}
+static nsresult
+ReparentWrappersInSubtree(nsIContent* aRoot)
+{
+ MOZ_ASSERT(ShouldUseXBLScope(aRoot));
+ // Start off with no global so we don't fire any error events on failure.
+ AutoJSAPI jsapi;
+ jsapi.Init();
+
+ JSContext* cx = jsapi.cx();
+
+ nsIGlobalObject* docGlobal = aRoot->OwnerDoc()->GetScopeObject();
+ if (NS_WARN_IF(!docGlobal)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ JS::Rooted<JSObject*> rootedGlobal(cx, docGlobal->GetGlobalJSObject());
+ if (NS_WARN_IF(!rootedGlobal)) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rootedGlobal = xpc::GetXBLScope(cx, rootedGlobal);
+
+ nsresult rv;
+ JS::Rooted<JSObject*> reflector(cx);
+ for (nsIContent* cur = aRoot; cur; cur = cur->GetNextNode(aRoot)) {
+ if ((reflector = cur->GetWrapper())) {
+ JSAutoCompartment ac(cx, reflector);
+ rv = ReparentWrapper(cx, reflector);
+ if NS_FAILED(rv) {
+ // We _could_ consider BlastSubtreeToPieces here, but it's not really
+ // needed. Having some nodes in here accessible to content while others
+ // are not is probably OK. We just need to fail out of the actual
+ // insertion, so they're not in the DOM. Returning a failure here will
+ // do that.
+ return rv;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
nsresult
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
bool aNotify, nsAttrAndChildArray& aChildArray)
@@ -1606,9 +1649,15 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
nsIContent* parent =
IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this);
+ bool wasInXBLScope = ShouldUseXBLScope(aKid);
rv = aKid->BindToTree(doc, parent,
parent ? parent->GetBindingParent() : nullptr,
true);
+ if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) {
+ MOZ_ASSERT(ShouldUseXBLScope(this),
+ "Why does the kid need to use an XBL scope?");
+ rv = ReparentWrappersInSubtree(aKid);
+ }
if (NS_FAILED(rv)) {
if (GetFirstChild() == aKid) {
mFirstChild = aKid->GetNextSibling();
diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp
index 3be1a6d2f..4a984d294 100644
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -70,7 +70,6 @@
#include "prthread.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
@@ -1477,22 +1476,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration));
}
- // Log information about the CC via telemetry, JSON and the console.
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, gCCStats.mAnyLockedOut);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE, gCCStats.mRanSyncForgetSkippable);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration);
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE, gCCStats.mMaxSliceTime);
-
- if (!sLastCCEndTime.IsNull()) {
- // TimeBetween returns milliseconds, but we want to report seconds.
- uint32_t timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime) / 1000;
- Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween);
- }
sLastCCEndTime = endCCTimeStamp;
- Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
- sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
-
PRTime delta = GetCollectionTimeDelta();
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp
index 66c8c84cf..80f0aa786 100644
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -392,9 +392,6 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal)
NS_ASSERTION(aPrincipal, "Must have principal by this point!");
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsExpandedPrincipal(aPrincipal),
"Documents shouldn't have an expanded principal");
- if (nsContentUtils::IsExpandedPrincipal(aPrincipal)) {
- Telemetry::Accumulate(Telemetry::DOCUMENT_WITH_EXPANDED_PRINCIPAL, 1);
- }
mPrincipal = aPrincipal;
}
diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
index 9e9dacf01..709c7aa56 100644
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -85,7 +85,6 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStates.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#include "nsChannelClassifier.h"
@@ -1149,7 +1148,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist.");
console->LogStringMessage(message.get());
}
- Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1);
mContentBlockingEnabled = true;
return NS_ERROR_FAILURE;
} else if (status == NS_ERROR_TRACKING_URI) {
@@ -1565,7 +1563,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI,
}
if (uri.Find("enablejsapi=1", true, 0, -1) != kNotFound) {
- Telemetry::Accumulate(Telemetry::YOUTUBE_NONREWRITABLE_EMBED_SEEN, 1);
return;
}
@@ -1585,10 +1582,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI,
}
}
- // If we've made it this far, we've got a rewritable embed. Log it in
- // telemetry.
- Telemetry::Accumulate(Telemetry::YOUTUBE_REWRITABLE_EMBED_SEEN, 1);
-
// If we're pref'd off, return after telemetry has been logged.
if (!Preferences::GetBool(kPrefYoutubeRewrite)) {
return;
@@ -3800,8 +3793,6 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
aRv.Throw(NS_ERROR_FAILURE);
return;
}
-
- Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
}
void
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index a6d20e363..0eb5bbf31 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -81,11 +81,19 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptLoadRequest)
NS_INTERFACE_MAP_END
-NS_IMPL_CYCLE_COLLECTION_0(nsScriptLoadRequest)
-
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptLoadRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptLoadRequest)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptLoadRequest)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptLoadRequest)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptLoadRequest)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
nsScriptLoadRequest::~nsScriptLoadRequest()
{
js_free(mScriptTextBuf);
diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp
index 7056658a7..323feca52 100644
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -119,7 +119,7 @@ ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE;
MOZ_RELEASE_ASSERT(GetErrorArgCount(errorNumber) <= 2);
JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr,
- static_cast<const unsigned>(errorNumber),
+ static_cast<unsigned>(errorNumber),
funcNameStr.get(), ifaceName.get());
return false;
}
@@ -226,7 +226,7 @@ TErrorResult<CleanupPolicy>::SetPendingExceptionWithMessage(JSContext* aCx)
args[argCount] = nullptr;
JS_ReportErrorNumberUCArray(aCx, dom::GetErrorMessage, nullptr,
- static_cast<const unsigned>(message->mErrorNumber),
+ static_cast<unsigned>(message->mErrorNumber),
argCount > 0 ? args : nullptr);
ClearMessage();
diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h
index 3e58390c9..24b47a545 100644
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -515,7 +515,7 @@ class ProtoAndIfaceCache
{
public:
PageTableCache() {
- memset(&mPages, 0, sizeof(mPages));
+ memset(mPages.begin(), 0, sizeof(mPages));
}
~PageTableCache() {
diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
index aa7f26ad6..6f9733c5f 100644
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1222,6 +1222,11 @@ DOMInterfaces = {
'headerFile': 'WebGLExtensions.h'
},
+'MOZ_debug_get': {
+ 'nativeType': 'mozilla::WebGLExtensionDebugGet',
+ 'headerFile': 'WebGLExtensions.h'
+},
+
'WebGLFramebuffer': {
'nativeType': 'mozilla::WebGLFramebuffer',
'headerFile': 'WebGLFramebuffer.h'
diff --git a/dom/bindings/ErrorResult.h b/dom/bindings/ErrorResult.h
index 7c3fc9e2f..da7ec30e7 100644
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -75,7 +75,7 @@ template<typename... Ts>
inline bool
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, Ts&&... aArgs)
{
- binding_detail::ThrowErrorMessage(aCx, static_cast<const unsigned>(aErrorNumber),
+ binding_detail::ThrowErrorMessage(aCx, static_cast<unsigned>(aErrorNumber),
mozilla::Forward<Ts>(aArgs)...);
return false;
}
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index 18af28e9f..e3406fc02 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -783,6 +783,15 @@ public:
: mCanvas(aCanvas)
{}
+ void OnShutdown() {
+ if(!mCanvas) {
+ return;
+ }
+
+ mCanvas = nullptr;
+ nsContentUtils::UnregisterShutdownObserver(this);
+ }
+
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
@@ -800,7 +809,7 @@ CanvasShutdownObserver::Observe(nsISupports* aSubject,
{
if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mCanvas->OnShutdown();
- nsContentUtils::UnregisterShutdownObserver(this);
+ OnShutdown();
}
return NS_OK;
@@ -1218,7 +1227,7 @@ void
CanvasRenderingContext2D::RemoveShutdownObserver()
{
if (mShutdownObserver) {
- nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
+ mShutdownObserver->OnShutdown();
mShutdownObserver = nullptr;
}
}
diff --git a/dom/canvas/CanvasRenderingContextHelper.cpp b/dom/canvas/CanvasRenderingContextHelper.cpp
index 3000e59bd..61317fb51 100644
--- a/dom/canvas/CanvasRenderingContextHelper.cpp
+++ b/dom/canvas/CanvasRenderingContextHelper.cpp
@@ -7,7 +7,6 @@
#include "ImageBitmapRenderingContext.h"
#include "ImageEncoder.h"
#include "mozilla/dom/CanvasRenderingContext2D.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "nsContentUtils.h"
#include "nsDOMJSUtils.h"
@@ -138,13 +137,10 @@ CanvasRenderingContextHelper::CreateContextHelper(CanvasContextType aContextType
break;
case CanvasContextType::Canvas2D:
- Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
ret = new CanvasRenderingContext2D(aCompositorBackend);
break;
case CanvasContextType::WebGL1:
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
-
ret = WebGL1Context::Create();
if (!ret)
return nullptr;
@@ -152,8 +148,6 @@ CanvasRenderingContextHelper::CreateContextHelper(CanvasContextType aContextType
break;
case CanvasContextType::WebGL2:
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
-
ret = WebGL2Context::Create();
if (!ret)
return nullptr;
@@ -205,16 +199,8 @@ CanvasRenderingContextHelper::GetContext(JSContext* aCx,
// See bug 645792 and bug 1215072.
// We want to throw only if dictionary initialization fails,
// so only in case aRv has been set to some error value.
- if (contextType == CanvasContextType::WebGL1)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 0);
- else if (contextType == CanvasContextType::WebGL2)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 0);
return nullptr;
}
- if (contextType == CanvasContextType::WebGL1)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 1);
- else if (contextType == CanvasContextType::WebGL2)
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 1);
} else {
// We already have a context of some type.
if (contextType != mCurrentContextType)
diff --git a/dom/canvas/WebGL1Context.cpp b/dom/canvas/WebGL1Context.cpp
index c1818a3f9..e82cafbe5 100644
--- a/dom/canvas/WebGL1Context.cpp
+++ b/dom/canvas/WebGL1Context.cpp
@@ -6,7 +6,6 @@
#include "WebGL1Context.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
-#include "mozilla/Telemetry.h"
#include "WebGLFormats.h"
namespace mozilla {
@@ -43,8 +42,6 @@ WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
nsresult
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
{
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::CANVAS_WEBGL_USED, 1);
-
nsIDOMWebGLRenderingContext* ctx = mozilla::WebGL1Context::Create();
NS_ADDREF(*out_result = ctx);
diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp
index 32eed6354..e2e05e5fd 100644
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -47,7 +47,6 @@
#include "nsSVGEffects.h"
#include "prenv.h"
#include "ScopedGLHelpers.h"
-#include "VRManagerChild.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
// Local
@@ -825,10 +824,6 @@ NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
{
if (signedWidth < 0 || signedHeight < 0) {
- if (!gl) {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
- NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SIZE"));
- }
GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -884,12 +879,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
return NS_OK;
}
- nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
- auto autoTelemetry = mozilla::MakeScopeExit([&] {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID,
- failureId);
- });
-
// End of early return cases.
// At this point we know that we're not just resizing an existing context,
// we are initializing a new context.
@@ -911,7 +900,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
// resource handles created from older context generations.
if (!(mGeneration + 1).isValid()) {
// exit without changing the value of mGeneration
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY");
const nsLiteralCString text("Too many WebGL contexts created this run.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -928,11 +916,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
disabled |= gfxPlatform::InSafeMode();
if (disabled) {
- if (gfxPlatform::InSafeMode()) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_SAFEMODE");
- } else {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DISABLED");
- }
const nsLiteralCString text("WebGL is currently disabled.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -945,7 +928,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (mOptions.failIfMajorPerformanceCaveat) {
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (!HasAcceleratedLayers(gfxInfo)) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_CAVEAT");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Compositor is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@@ -961,12 +943,9 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (!CreateAndInitGL(forceEnabled, &failReasons)) {
nsCString text("WebGL creation failed: ");
for (const auto& cur : failReasons) {
- Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_FAILURE_ID, cur.key);
-
text.AppendASCII("\n* ");
text.Append(cur.info);
}
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_REASON");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
}
@@ -978,7 +957,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_PERF_WARP");
const nsLiteralCString text("failIfMajorPerformanceCaveat: Driver is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
@@ -992,7 +970,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
DestroyResourcesAndContext();
MOZ_ASSERT(!gl);
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -1001,7 +978,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
}
if (!ResizeBackbuffer(width, height)) {
- failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
const nsLiteralCString text("Initializing WebGL backbuffer failed.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
@@ -1085,7 +1061,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
//////
- failureId = NS_LITERAL_CSTRING("SUCCESS");
return NS_OK;
}
@@ -2263,84 +2238,6 @@ WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width, uint32_t height,
return totalBytes;
}
-already_AddRefed<layers::SharedSurfaceTextureClient>
-WebGLContext::GetVRFrame()
-{
- if (!mLayerIsMirror) {
- /**
- * Do not allow VR frame submission until a mirroring canvas layer has
- * been returned by GetCanvasLayer
- */
- return nullptr;
- }
-
- VRManagerChild* vrmc = VRManagerChild::Get();
- if (!vrmc) {
- return nullptr;
- }
-
- /**
- * Swap buffers as though composition has occurred.
- * We will then share the resulting front buffer to be submitted to the VR
- * compositor.
- */
- BeginComposition();
- EndComposition();
-
- gl::GLScreenBuffer* screen = gl->Screen();
- if (!screen) {
- return nullptr;
- }
-
- RefPtr<SharedSurfaceTextureClient> sharedSurface = screen->Front();
- if (!sharedSurface) {
- return nullptr;
- }
-
- if (sharedSurface && sharedSurface->GetAllocator() != vrmc) {
- RefPtr<SharedSurfaceTextureClient> dest =
- screen->Factory()->NewTexClient(sharedSurface->GetSize());
- if (!dest) {
- return nullptr;
- }
- gl::SharedSurface* destSurf = dest->Surf();
- destSurf->ProducerAcquire();
- SharedSurface::ProdCopy(sharedSurface->Surf(), dest->Surf(),
- screen->Factory());
- destSurf->ProducerRelease();
-
- return dest.forget();
- }
-
- return sharedSurface.forget();
-}
-
-bool
-WebGLContext::StartVRPresentation()
-{
- VRManagerChild* vrmc = VRManagerChild::Get();
- if (!vrmc) {
- return false;
- }
- gl::GLScreenBuffer* screen = gl->Screen();
- if (!screen) {
- return false;
- }
- gl::SurfaceCaps caps = screen->mCaps;
-
- UniquePtr<gl::SurfaceFactory> factory =
- gl::GLScreenBuffer::CreateFactory(gl,
- caps,
- vrmc,
- vrmc->GetBackendType(),
- TextureFlags::ORIGIN_BOTTOM_LEFT);
-
- if (factory) {
- screen->Morph(Move(factory));
- }
- return true;
-}
-
////////////////////////////////////////////////////////////////////////////////
static inline size_t
diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h
index b4d416a33..3ec307b00 100644
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -656,9 +656,6 @@ public:
void PixelStorei(GLenum pname, GLint param);
void PolygonOffset(GLfloat factor, GLfloat units);
- already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
- bool StartVRPresentation();
-
////
webgl::PackingInfo
diff --git a/dom/canvas/WebGLContextExtensions.cpp b/dom/canvas/WebGLContextExtensions.cpp
index 4a5a23274..7f338b4e9 100644
--- a/dom/canvas/WebGLContextExtensions.cpp
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -40,6 +40,7 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext)
WEBGL_EXTENSION_IDENTIFIER(EXT_sRGB)
WEBGL_EXTENSION_IDENTIFIER(EXT_texture_filter_anisotropic)
WEBGL_EXTENSION_IDENTIFIER(EXT_disjoint_timer_query)
+ WEBGL_EXTENSION_IDENTIFIER(MOZ_debug_get)
WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
WEBGL_EXTENSION_IDENTIFIER(OES_standard_derivatives)
WEBGL_EXTENSION_IDENTIFIER(OES_texture_float)
@@ -91,6 +92,8 @@ bool WebGLContext::IsExtensionSupported(dom::CallerType callerType,
switch (ext) {
case WebGLExtensionID::EXT_disjoint_timer_query:
return WebGLExtensionDisjointTimerQuery::IsSupported(this);
+ case WebGLExtensionID::MOZ_debug_get:
+ return true;
case WebGLExtensionID::WEBGL_debug_renderer_info:
return true;
case WebGLExtensionID::WEBGL_debug_shaders:
@@ -372,6 +375,11 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
obj = new WebGLExtensionTextureFilterAnisotropic(this);
break;
+ // MOZ_
+ case WebGLExtensionID::MOZ_debug_get:
+ obj = new WebGLExtensionDebugGet(this);
+ break;
+
// OES_
case WebGLExtensionID::OES_element_index_uint:
obj = new WebGLExtensionElementIndexUint(this);
diff --git a/dom/canvas/WebGLContextState.cpp b/dom/canvas/WebGLContextState.cpp
index e0234f5c6..c2f4c1a75 100644
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -61,18 +61,6 @@ WebGLContext::Enable(GLenum cap)
gl->fEnable(cap);
}
-static JS::Value
-StringValue(JSContext* cx, const nsAString& str, ErrorResult& rv)
-{
- JSString* jsStr = JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length());
- if (!jsStr) {
- rv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return JS::NullValue();
- }
-
- return JS::StringValue(jsStr);
-}
-
bool
WebGLContext::GetStencilBits(GLint* const out_stencilBits)
{
diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp
index 9c0d34939..3fd32eb30 100644
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -874,4 +874,16 @@ InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims)
}
}
+JS::Value
+StringValue(JSContext* cx, const nsAString& str, ErrorResult& er)
+{
+ JSString* jsStr = JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length());
+ if (!jsStr) {
+ er.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return JS::NullValue();
+ }
+
+ return JS::StringValue(jsStr);
+}
+
} // namespace mozilla
diff --git a/dom/canvas/WebGLContextUtils.h b/dom/canvas/WebGLContextUtils.h
index 5401fc878..1d06659b1 100644
--- a/dom/canvas/WebGLContextUtils.h
+++ b/dom/canvas/WebGLContextUtils.h
@@ -94,6 +94,8 @@ WebGLContext::WebGLObjectAsJSObject(JSContext* cx,
*/
const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims);
+JS::Value StringValue(JSContext* cx, const nsAString& str, ErrorResult& er);
+
} // namespace mozilla
#endif // WEBGL_CONTEXT_UTILS_H_
diff --git a/dom/canvas/WebGLExtensionDebugGet.cpp b/dom/canvas/WebGLExtensionDebugGet.cpp
new file mode 100644
index 000000000..39bb3c57a
--- /dev/null
+++ b/dom/canvas/WebGLExtensionDebugGet.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLExtensions.h"
+
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "WebGLContext.h"
+#include "WebGLContextUtils.h"
+
+namespace mozilla {
+
+WebGLExtensionDebugGet::WebGLExtensionDebugGet(WebGLContext* webgl)
+ : WebGLExtensionBase(webgl)
+{
+}
+
+WebGLExtensionDebugGet::~WebGLExtensionDebugGet()
+{
+}
+
+void
+WebGLExtensionDebugGet::GetParameter(JSContext* cx, GLenum pname,
+ JS::MutableHandle<JS::Value> retval,
+ ErrorResult& er) const
+{
+ const auto& gl = mContext->gl;
+ gl->MakeCurrent();
+
+ switch (pname) {
+ case LOCAL_GL_EXTENSIONS:
+ {
+ nsString ret;
+ if (!gl->IsCoreProfile()) {
+ const auto rawExts = (const char*)gl->fGetString(LOCAL_GL_EXTENSIONS);
+ ret = NS_ConvertUTF8toUTF16(rawExts);
+ } else {
+ const auto& numExts = gl->GetIntAs<GLuint>(LOCAL_GL_NUM_EXTENSIONS);
+ for (GLuint i = 0; i < numExts; i++) {
+ const auto rawExt = (const char*)gl->fGetStringi(LOCAL_GL_EXTENSIONS,
+ i);
+ if (i > 0) {
+ ret.AppendLiteral(" ");
+ }
+ ret.Append(NS_ConvertUTF8toUTF16(rawExt));
+ }
+ }
+ retval.set(StringValue(cx, ret, er));
+ return;
+ }
+
+ case LOCAL_GL_RENDERER:
+ case LOCAL_GL_VENDOR:
+ case LOCAL_GL_VERSION:
+ {
+ const auto raw = (const char*)gl->fGetString(pname);
+ retval.set(StringValue(cx, NS_ConvertUTF8toUTF16(raw), er));
+ return;
+ }
+
+ case 0x10000: // "WSI_INFO"
+ {
+ nsCString info;
+ gl->GetWSIInfo(&info);
+ retval.set(StringValue(cx, NS_ConvertUTF8toUTF16(info), er));
+ return;
+ }
+
+ default:
+ mContext->ErrorInvalidEnumArg("MOZ_debug_get.getParameter", "pname", pname);
+ retval.set(JS::NullValue());
+ return;
+ }
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugGet, MOZ_debug_get)
+
+} // namespace mozilla
diff --git a/dom/canvas/WebGLExtensions.h b/dom/canvas/WebGLExtensions.h
index 741f6997f..7b6b6b54b 100644
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -12,6 +12,7 @@
#include "WebGLTypes.h"
namespace mozilla {
+class ErrorResult;
namespace dom {
template<typename T>
@@ -385,6 +386,19 @@ public:
DECL_WEBGL_EXTENSION_GOOP
};
+class WebGLExtensionDebugGet final
+ : public WebGLExtensionBase
+{
+public:
+ explicit WebGLExtensionDebugGet(WebGLContext* webgl);
+ virtual ~WebGLExtensionDebugGet();
+
+ void GetParameter(JSContext* cx, GLenum pname,
+ JS::MutableHandle<JS::Value> retval, ErrorResult& er) const;
+
+ DECL_WEBGL_EXTENSION_GOOP
+};
+
} // namespace mozilla
#endif // WEBGL_EXTENSIONS_H_
diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h
index 42b8701f3..2f4a4368a 100644
--- a/dom/canvas/WebGLTypes.h
+++ b/dom/canvas/WebGLTypes.h
@@ -149,6 +149,7 @@ enum class WebGLExtensionID : uint8_t {
EXT_shader_texture_lod,
EXT_texture_filter_anisotropic,
EXT_disjoint_timer_query,
+ MOZ_debug_get,
OES_element_index_uint,
OES_standard_derivatives,
OES_texture_float,
diff --git a/dom/canvas/moz.build b/dom/canvas/moz.build
index f7555b33d..6d5e2756f 100644
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -105,6 +105,7 @@ UNIFIED_SOURCES += [
'WebGLExtensionCompressedTextureETC1.cpp',
'WebGLExtensionCompressedTexturePVRTC.cpp',
'WebGLExtensionCompressedTextureS3TC.cpp',
+ 'WebGLExtensionDebugGet.cpp',
'WebGLExtensionDebugRendererInfo.cpp',
'WebGLExtensionDebugShaders.cpp',
'WebGLExtensionDepthTexture.cpp',
diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp
index f5fc7b5bc..e5f5882e9 100644
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -452,7 +452,6 @@ void
WebCryptoTask::FailWithError(nsresult aRv)
{
MOZ_ASSERT(IsOnOriginalThread());
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_RESOLVED, false);
// Blindly convert nsresult to DOMException
// Individual tasks must ensure they pass the right values
@@ -491,7 +490,6 @@ WebCryptoTask::CallCallback(nsresult rv)
}
Resolve();
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_RESOLVED, true);
// Manually release mResultPromise while we're on the main thread
mResultPromise = nullptr;
@@ -586,7 +584,7 @@ public:
mMechanism = CKM_AES_CBC_PAD;
telemetryAlg = TA_AES_CBC;
- AesCbcParams params;
+ RootedDictionary<AesCbcParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_INVALID_ACCESS_ERR;
@@ -603,7 +601,7 @@ public:
mMechanism = CKM_AES_CTR;
telemetryAlg = TA_AES_CTR;
- AesCtrParams params;
+ RootedDictionary<AesCtrParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
@@ -622,7 +620,7 @@ public:
mMechanism = CKM_AES_GCM;
telemetryAlg = TA_AES_GCM;
- AesGcmParams params;
+ RootedDictionary<AesGcmParams> params(aCx);
nsresult rv = Coerce(aCx, params, aAlgorithm);
if (NS_FAILED(rv)) {
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
@@ -650,7 +648,6 @@ public:
mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
}
private:
@@ -794,7 +791,6 @@ public:
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_AES_KW);
}
private:
@@ -908,8 +904,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm,
CryptoKey& aKey, bool aEncrypt)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSA_OAEP);
-
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSA_OAEP);
if (mEncrypt) {
@@ -1049,7 +1043,6 @@ public:
case CKM_SHA512_HMAC: telemetryAlg = TA_HMAC_SHA_512; break;
default: telemetryAlg = TA_UNKNOWN;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
}
private:
@@ -1158,12 +1151,10 @@ public:
if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
mAlgorithm = Algorithm::RSA_PKCS1;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSASSA_PKCS1);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSASSA_PKCS1);
hashAlgName = aKey.Algorithm().mRsa.mHash.mName;
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_RSA_PSS)) {
mAlgorithm = Algorithm::RSA_PSS;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_RSA_PSS);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_RSA_PSS);
KeyAlgorithm& hashAlg = aKey.Algorithm().mRsa.mHash;
@@ -1188,7 +1179,6 @@ public:
mSaltLength = params.mSaltLength;
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_ECDSA)) {
mAlgorithm = Algorithm::ECDSA;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_ECDSA);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_ECDSA);
// For ECDSA, the hash name comes from the algorithm parameter
@@ -1356,7 +1346,6 @@ public:
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
return;
}
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, telemetryAlg);
mOidTag = MapHashAlgorithmNameToOID(algName);
}
@@ -2656,7 +2645,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_HKDF);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_HKDF);
// Check that we have a key.
@@ -2806,7 +2794,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_PBKDF2);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_PBKDF2);
// Check that we got a symmetric key
@@ -2981,7 +2968,6 @@ public:
void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_ECDH);
CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_ECDH);
// Check that we have a private key.
@@ -3277,10 +3263,6 @@ WebCryptoTask::CreateEncryptDecryptTask(JSContext* aCx,
const CryptoOperationData& aData,
bool aEncrypt)
{
- TelemetryMethod method = (aEncrypt)? TM_ENCRYPT : TM_DECRYPT;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, method);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_ENC, aKey.Extractable());
-
// Ensure key is usable for this operation
if ((aEncrypt && !aKey.HasUsage(CryptoKey::ENCRYPT)) ||
(!aEncrypt && !aKey.HasUsage(CryptoKey::DECRYPT))) {
@@ -3312,10 +3294,6 @@ WebCryptoTask::CreateSignVerifyTask(JSContext* aCx,
const CryptoOperationData& aData,
bool aSign)
{
- TelemetryMethod method = (aSign)? TM_SIGN : TM_VERIFY;
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, method);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_SIG, aKey.Extractable());
-
// Ensure key is usable for this operation
if ((aSign && !aKey.HasUsage(CryptoKey::SIGN)) ||
(!aSign && !aKey.HasUsage(CryptoKey::VERIFY))) {
@@ -3345,8 +3323,6 @@ WebCryptoTask::CreateDigestTask(JSContext* aCx,
const ObjectOrString& aAlgorithm,
const CryptoOperationData& aData)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DIGEST);
-
nsString algName;
nsresult rv = GetAlgorithmName(aCx, aAlgorithm, algName);
if (NS_FAILED(rv)) {
@@ -3372,9 +3348,6 @@ WebCryptoTask::CreateImportKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_IMPORTKEY);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_IMPORT, aExtractable);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3426,8 +3399,6 @@ WebCryptoTask*
WebCryptoTask::CreateExportKeyTask(const nsAString& aFormat,
CryptoKey& aKey)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_EXPORTKEY);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3470,9 +3441,6 @@ WebCryptoTask::CreateGenerateKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_GENERATEKEY);
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_EXTRACTABLE_GENERATE, aExtractable);
-
// Verify that aKeyUsages does not contain an unrecognized value
// SPEC-BUG: Spec says that this should be InvalidAccessError, but that
// is inconsistent with other analogous points in the spec
@@ -3515,8 +3483,6 @@ WebCryptoTask::CreateDeriveKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DERIVEKEY);
-
// Ensure baseKey is usable for this operation
if (!aBaseKey.HasUsage(CryptoKey::DERIVEKEY)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@@ -3560,8 +3526,6 @@ WebCryptoTask::CreateDeriveBitsTask(JSContext* aCx,
CryptoKey& aKey,
uint32_t aLength)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_DERIVEBITS);
-
// Ensure baseKey is usable for this operation
if (!aKey.HasUsage(CryptoKey::DERIVEBITS)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
@@ -3599,8 +3563,6 @@ WebCryptoTask::CreateWrapKeyTask(JSContext* aCx,
CryptoKey& aWrappingKey,
const ObjectOrString& aWrapAlgorithm)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_WRAPKEY);
-
// Verify that the format is recognized
if (!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) &&
!aFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) &&
@@ -3652,8 +3614,6 @@ WebCryptoTask::CreateUnwrapKeyTask(nsIGlobalObject* aGlobal,
bool aExtractable,
const Sequence<nsString>& aKeyUsages)
{
- Telemetry::Accumulate(Telemetry::WEBCRYPTO_METHOD, TM_UNWRAPKEY);
-
// Ensure key is usable for this operation
if (!aUnwrappingKey.HasUsage(CryptoKey::UNWRAPKEY)) {
return new FailureTask(NS_ERROR_DOM_INVALID_ACCESS_ERR);
diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp
index 65f01844b..1d4dfd7d9 100644
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -858,63 +858,46 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
// And if we didn't get an event, check the type argument.
-#define LOG_EVENT_CREATION(name) mozilla::Telemetry::Accumulate( \
- mozilla::Telemetry::CREATE_EVENT_##name, true);
-
if (aEventType.LowerCaseEqualsLiteral("mouseevent")) {
- LOG_EVENT_CREATION(MOUSEEVENT);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mouseevents")) {
- LOG_EVENT_CREATION(MOUSEEVENTS);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("popupevents")) {
- LOG_EVENT_CREATION(POPUPEVENTS);
return NS_NewDOMMouseEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mousescrollevents")) {
- LOG_EVENT_CREATION(MOUSESCROLLEVENTS);
return NS_NewDOMMouseScrollEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("dragevent")) {
- LOG_EVENT_CREATION(DRAGEVENT);
return NS_NewDOMDragEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("dragevents")) {
- LOG_EVENT_CREATION(DRAGEVENTS);
return NS_NewDOMDragEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("keyboardevent")) {
- LOG_EVENT_CREATION(KEYBOARDEVENT);
return NS_NewDOMKeyboardEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("keyevents")) {
- LOG_EVENT_CREATION(KEYEVENTS);
return NS_NewDOMKeyboardEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("compositionevent")) {
- LOG_EVENT_CREATION(COMPOSITIONEVENT);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("textevent")) {
- LOG_EVENT_CREATION(TEXTEVENT);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("textevents")) {
- LOG_EVENT_CREATION(TEXTEVENTS);
return NS_NewDOMCompositionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mutationevent")) {
- LOG_EVENT_CREATION(MUTATIONEVENT);
return NS_NewDOMMutationEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("mutationevents")) {
- LOG_EVENT_CREATION(MUTATIONEVENTS);
return NS_NewDOMMutationEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent")) {
- LOG_EVENT_CREATION(DEVICEORIENTATIONEVENT);
DeviceOrientationEventInit init;
RefPtr<Event> event =
DeviceOrientationEvent::Constructor(aOwner, EmptyString(), init);
@@ -922,97 +905,74 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("devicemotionevent")) {
- LOG_EVENT_CREATION(DEVICEMOTIONEVENT);
return NS_NewDOMDeviceMotionEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("uievent")) {
- LOG_EVENT_CREATION(UIEVENT);
return NS_NewDOMUIEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("uievents")) {
- LOG_EVENT_CREATION(UIEVENTS);
return NS_NewDOMUIEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("event")) {
- LOG_EVENT_CREATION(EVENT);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("events")) {
- LOG_EVENT_CREATION(EVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("htmlevents")) {
- LOG_EVENT_CREATION(HTMLEVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgevent")) {
- LOG_EVENT_CREATION(SVGEVENT);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgevents")) {
- LOG_EVENT_CREATION(SVGEVENTS);
return NS_NewDOMEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgzoomevent")) {
- LOG_EVENT_CREATION(SVGZOOMEVENT);
return NS_NewDOMSVGZoomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("svgzoomevents")) {
- LOG_EVENT_CREATION(SVGZOOMEVENTS);
return NS_NewDOMSVGZoomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("timeevent")) {
- LOG_EVENT_CREATION(TIMEEVENT);
return NS_NewDOMTimeEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("timeevents")) {
- LOG_EVENT_CREATION(TIMEEVENTS);
return NS_NewDOMTimeEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("xulcommandevent")) {
- LOG_EVENT_CREATION(XULCOMMANDEVENT);
return NS_NewDOMXULCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("xulcommandevents")) {
- LOG_EVENT_CREATION(XULCOMMANDEVENTS);
return NS_NewDOMXULCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("commandevent")) {
- LOG_EVENT_CREATION(COMMANDEVENT);
return NS_NewDOMCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("commandevents")) {
- LOG_EVENT_CREATION(COMMANDEVENTS);
return NS_NewDOMCommandEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("datacontainerevent")) {
- LOG_EVENT_CREATION(DATACONTAINEREVENT);
return NS_NewDOMDataContainerEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("datacontainerevents")) {
- LOG_EVENT_CREATION(DATACONTAINEREVENTS);
return NS_NewDOMDataContainerEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("messageevent")) {
- LOG_EVENT_CREATION(MESSAGEEVENT);
RefPtr<Event> event = new MessageEvent(aOwner, aPresContext, nullptr);
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("notifypaintevent")) {
- LOG_EVENT_CREATION(NOTIFYPAINTEVENT);
return NS_NewDOMNotifyPaintEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("simplegestureevent")) {
- LOG_EVENT_CREATION(SIMPLEGESTUREEVENT);
return NS_NewDOMSimpleGestureEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("beforeunloadevent")) {
- LOG_EVENT_CREATION(BEFOREUNLOADEVENT);
return NS_NewDOMBeforeUnloadEvent(aOwner, aPresContext, nullptr);
}
// XXXkhuey this is broken
if (aEventType.LowerCaseEqualsLiteral("pagetransition")) {
- LOG_EVENT_CREATION(PAGETRANSITION);
PageTransitionEventInit init;
RefPtr<Event> event =
PageTransitionEvent::Constructor(aOwner, EmptyString(), init);
@@ -1020,14 +980,12 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("scrollareaevent")) {
- LOG_EVENT_CREATION(SCROLLAREAEVENT);
return NS_NewDOMScrollAreaEvent(aOwner, aPresContext, nullptr);
}
// XXXkhuey Chrome supports popstateevent here, even though it provides no
// initPopStateEvent method. This is nuts ... but copying it is unlikely to
// break the web.
if (aEventType.LowerCaseEqualsLiteral("popstateevent")) {
- LOG_EVENT_CREATION(POPSTATEEVENT);
AutoJSContext cx;
RootedDictionary<PopStateEventInit> init(cx);
RefPtr<Event> event =
@@ -1037,11 +995,9 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
}
if (aEventType.LowerCaseEqualsLiteral("touchevent") &&
TouchEvent::PrefEnabled(nsContentUtils::GetDocShellForEventTarget(aOwner))) {
- LOG_EVENT_CREATION(TOUCHEVENT);
return NS_NewDOMTouchEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("hashchangeevent")) {
- LOG_EVENT_CREATION(HASHCHANGEEVENT);
HashChangeEventInit init;
RefPtr<Event> event =
HashChangeEvent::Constructor(aOwner, EmptyString(), init);
@@ -1049,11 +1005,9 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
if (aEventType.LowerCaseEqualsLiteral("customevent")) {
- LOG_EVENT_CREATION(CUSTOMEVENT);
return NS_NewDOMCustomEvent(aOwner, aPresContext, nullptr);
}
if (aEventType.LowerCaseEqualsLiteral("storageevent")) {
- LOG_EVENT_CREATION(STORAGEEVENT);
return NS_NewDOMStorageEvent(aOwner);
}
if (aEventType.LowerCaseEqualsLiteral("focusevent")) {
@@ -1062,8 +1016,6 @@ EventDispatcher::CreateEvent(EventTarget* aOwner,
return event.forget();
}
-#undef LOG_EVENT_CREATION
-
// NEW EVENT TYPES SHOULD NOT BE ADDED HERE; THEY SHOULD USE ONLY EVENT
// CONSTRUCTORS
diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp
index 7bbfe21b7..e16d68c81 100644
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3240,6 +3240,12 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
}
switch (action) {
+ case WheelPrefs::ACTION_HSCROLL: {
+ // Swap axes and fall through
+ double deltaX = wheelEvent->mDeltaX;
+ wheelEvent->mDeltaX = wheelEvent->mDeltaY;
+ wheelEvent->mDeltaY = deltaX;
+ }
case WheelPrefs::ACTION_SCROLL: {
// For scrolling of default action, we should honor the mouse wheel
// transaction.
diff --git a/dom/events/EventStateManager.h b/dom/events/EventStateManager.h
index d0461e7fa..95ce9a907 100644
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -513,7 +513,8 @@ protected:
ACTION_SCROLL,
ACTION_HISTORY,
ACTION_ZOOM,
- ACTION_LAST = ACTION_ZOOM,
+ ACTION_HSCROLL,
+ ACTION_LAST = ACTION_HSCROLL,
// Following actions are used only by internal processing. So, cannot
// specified by prefs.
ACTION_SEND_TO_PLUGIN
diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp
index 5c05f3602..f944352e3 100644
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -38,7 +38,6 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/URLSearchParams.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
-#include "mozilla/Telemetry.h"
#include "InternalRequest.h"
#include "InternalResponse.h"
@@ -237,8 +236,6 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
}
}
- Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 1);
-
RefPtr<MainThreadFetchResolver> resolver = new MainThreadFetchResolver(p);
RefPtr<FetchDriver> fetch = new FetchDriver(r, principal, loadGroup);
fetch->SetDocument(doc);
@@ -251,8 +248,6 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
- Telemetry::Accumulate(Telemetry::FETCH_IS_MAINTHREAD, 0);
-
if (worker->IsServiceWorker()) {
r->SetSkipServiceWorker();
}
@@ -265,7 +260,7 @@ FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
}
RefPtr<MainThreadFetchRunnable> run = new MainThreadFetchRunnable(resolver, r);
- worker->DispatchToMainThread(run.forget());
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(run));
}
return p.forget();
diff --git a/dom/fetch/FetchConsumer.cpp b/dom/fetch/FetchConsumer.cpp
index 42dfcbaba..e82e5ec51 100644
--- a/dom/fetch/FetchConsumer.cpp
+++ b/dom/fetch/FetchConsumer.cpp
@@ -339,11 +339,7 @@ FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
nsCOMPtr<nsIRunnable> r = new BeginConsumeBodyRunnable<Derived>(consumer);
- if (workerPrivate) {
- aRv = workerPrivate->DispatchToMainThread(r.forget());
- } else {
- aRv = NS_DispatchToMainThread(r.forget());
- }
+ aRv = NS_DispatchToMainThread(r.forget());
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
@@ -655,9 +651,7 @@ FetchBodyConsumer<Derived>::ShutDownMainThreadConsuming()
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
[self] () { self->ShutDownMainThreadConsuming(); });
- WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
- MOZ_ASSERT(workerPrivate);
- workerPrivate->DispatchToMainThread(r.forget());
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
return;
}
diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
index aac79b829..1791399b7 100644
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -77,9 +77,6 @@ FetchDriver::Fetch(FetchDriverObserver* aObserver)
mObserver = aObserver;
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REQUEST_PASSTHROUGH,
- mRequest->WasCreatedByFetchEvent());
-
// FIXME(nsm): Deal with HSTS.
MOZ_RELEASE_ASSERT(!mRequest->IsSynchronous(),
diff --git a/dom/gamepad/GamepadManager.cpp b/dom/gamepad/GamepadManager.cpp
index dde71dd0a..e17829652 100644
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -28,7 +28,6 @@
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "nsThreadUtils.h"
-#include "VRManagerChild.h"
#include "mozilla/Services.h"
#include "mozilla/Unused.h"
@@ -110,11 +109,6 @@ GamepadManager::StopMonitoring()
}
mChannelChildren.Clear();
mGamepads.Clear();
-
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
- mVRChannelChild = gfx::VRManagerChild::Get();
- mVRChannelChild->SendControllerListenerRemoved();
-#endif
}
void
@@ -211,11 +205,6 @@ uint32_t GamepadManager::GetGamepadIndexWithServiceType(uint32_t aIndex,
newIndex = aIndex;
break;
}
- case GamepadServiceType::VR:
- {
- newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
- break;
- }
default:
MOZ_ASSERT(false);
break;
@@ -679,13 +668,6 @@ GamepadManager::ActorCreated(PBackgroundChild *aActor)
MOZ_ASSERT(initedChild == child);
child->SendGamepadListenerAdded();
mChannelChildren.AppendElement(child);
-
-#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
- // Construct VRManagerChannel and ask adding the connected
- // VR controllers to GamepadManager
- mVRChannelChild = gfx::VRManagerChild::Get();
- mVRChannelChild->SendControllerListenerAdded();
-#endif
}
//Override nsIIPCBackgroundChildCreateCallback
diff --git a/dom/gamepad/GamepadManager.h b/dom/gamepad/GamepadManager.h
index 1bb437d8f..a772221ca 100644
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -16,9 +16,6 @@
class nsGlobalWindow;
namespace mozilla {
-namespace gfx {
-class VRManagerChild;
-} // namespace gfx
namespace dom {
class EventTarget;
@@ -123,7 +120,6 @@ class GamepadManager final : public nsIObserver,
// will be destroyed during the IPDL shutdown chain, so we
// don't need to refcount it here.
nsTArray<GamepadEventChannelChild *> mChannelChildren;
- gfx::VRManagerChild* mVRChannelChild;
private:
@@ -138,8 +134,6 @@ class GamepadManager final : public nsIObserver,
// Indicate that a window has received data from a gamepad.
void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex,
bool aHasSeen = true);
- // Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
- // is from VRManager.
uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
// Gamepads connected to the system. Copies of these are handed out
diff --git a/dom/gamepad/ipc/GamepadServiceType.h b/dom/gamepad/ipc/GamepadServiceType.h
index acc0967d1..6200cdfa9 100644
--- a/dom/gamepad/ipc/GamepadServiceType.h
+++ b/dom/gamepad/ipc/GamepadServiceType.h
@@ -6,11 +6,9 @@ namespace mozilla{
namespace dom{
// Standard channel is used for managing gamepads that
-// are from GamepadPlatformService. VR channel
-// is for gamepads that are from VRManagerChild.
+// are from GamepadPlatformService.
enum class GamepadServiceType : uint16_t {
Standard,
- VR,
NumGamepadServiceType
};
diff --git a/dom/geolocation/nsGeolocation.cpp b/dom/geolocation/nsGeolocation.cpp
index 2d84a3e11..244018ee8 100644
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -382,13 +382,6 @@ nsGeolocationRequest::GetElement(nsIDOMElement * *aRequestingElement)
NS_IMETHODIMP
nsGeolocationRequest::Cancel()
{
- if (mRequester) {
- // Record the number of denied requests for regular web content.
- // This method is only called when the user explicitly denies the request,
- // and is not called when the page is simply unloaded, or similar.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType);
- }
-
if (mLocator->ClearPendingRequest(this)) {
return NS_OK;
}
@@ -402,27 +395,6 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
{
MOZ_ASSERT(aChoices.isUndefined());
- if (mRequester) {
- // Record the number of granted requests for regular web content.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType + 10);
-
- // Record whether a location callback is fulfilled while the owner window
- // is not visible.
- bool isVisible = false;
- nsCOMPtr<nsPIDOMWindowInner> window = mLocator->GetParentObject();
-
- if (window) {
- nsCOMPtr<nsIDocument> doc = window->GetDoc();
- isVisible = doc && !doc->Hidden();
- }
-
- if (IsWatch()) {
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_WATCHPOSITION_VISIBLE, isVisible);
- } else {
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_GETCURRENTPOSITION_VISIBLE, isVisible);
- }
- }
-
if (mLocator->ClearPendingRequest(this)) {
return NS_OK;
}
@@ -1110,7 +1082,6 @@ Geolocation::Update(nsIDOMGeoPosition *aSomewhere)
if (coords) {
double accuracy = -1;
coords->GetAccuracy(&accuracy);
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_ACCURACY_EXPONENTIAL, accuracy);
}
}
@@ -1135,8 +1106,6 @@ Geolocation::NotifyError(uint16_t aErrorCode)
return NS_OK;
}
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_ERROR, true);
-
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
mPendingCallbacks[i-1]->NotifyErrorAndShutdown(aErrorCode);
//NotifyErrorAndShutdown() removes the request from the array
@@ -1214,10 +1183,6 @@ Geolocation::GetCurrentPosition(GeoPositionCallback callback,
// After this we hand over ownership of options to our nsGeolocationRequest.
- // Count the number of requests per protocol/scheme.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
- static_cast<uint8_t>(mProtocolType));
-
RefPtr<nsGeolocationRequest> request =
new nsGeolocationRequest(this, Move(callback), Move(errorCallback),
Move(options), static_cast<uint8_t>(mProtocolType),
@@ -1292,10 +1257,6 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
return NS_ERROR_NOT_AVAILABLE;
}
- // Count the number of requests per protocol/scheme.
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN,
- static_cast<uint8_t>(mProtocolType));
-
// The watch ID:
*aRv = mLastWatchId++;
diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp
index 88b41bce0..527135a80 100644
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -42,7 +42,6 @@
#include "nsRefreshDriver.h"
#include "nsStreamUtils.h"
#include "ActiveLayerTracker.h"
-#include "VRManagerChild.h"
#include "WebGL1Context.h"
#include "WebGL2Context.h"
@@ -358,7 +357,6 @@ NS_IMPL_ISUPPORTS(HTMLCanvasElementObserver, nsIObserver)
HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
mResetLayer(true) ,
- mVRPresentationActive(false),
mWriteOnly(false)
{}
@@ -1111,7 +1109,7 @@ HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
static uint8_t sOffscreenCanvasLayerUserDataDummy = 0;
if (mCurrentContext) {
- return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager, mVRPresentationActive);
+ return mCurrentContext->GetCanvasLayer(aBuilder, aOldLayer, aManager);
}
if (mOffscreenCanvas) {
@@ -1441,42 +1439,5 @@ HTMLCanvasElement::InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRende
element->InvalidateCanvasContent(nullptr);
}
-void
-HTMLCanvasElement::StartVRPresentation()
-{
- WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
- if (!webgl) {
- return;
- }
-
- if (!webgl->StartVRPresentation()) {
- return;
- }
-
- mVRPresentationActive = true;
-}
-
-void
-HTMLCanvasElement::StopVRPresentation()
-{
- mVRPresentationActive = false;
-}
-
-already_AddRefed<layers::SharedSurfaceTextureClient>
-HTMLCanvasElement::GetVRFrame()
-{
- if (GetCurrentContextType() != CanvasContextType::WebGL1 &&
- GetCurrentContextType() != CanvasContextType::WebGL2) {
- return nullptr;
- }
-
- WebGLContext* webgl = static_cast<WebGLContext*>(GetContextAtIndex(0));
- if (!webgl) {
- return nullptr;
- }
-
- return webgl->GetVRFrame();
-}
-
} // namespace dom
} // namespace mozilla
diff --git a/dom/html/HTMLCanvasElement.h b/dom/html/HTMLCanvasElement.h
index 81c141d3c..746fab198 100644
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -350,10 +350,6 @@ public:
static void SetAttrFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
static void InvalidateFromAsyncCanvasRenderer(AsyncCanvasRenderer *aRenderer);
- void StartVRPresentation();
- void StopVRPresentation();
- already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
-
protected:
virtual ~HTMLCanvasElement();
diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp
index 5164391f8..0393ed3e0 100644
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -38,7 +38,6 @@
// form submission
#include "HTMLFormSubmissionConstants.h"
#include "mozilla/dom/FormData.h"
-#include "mozilla/Telemetry.h"
#include "nsIFormSubmitObserver.h"
#include "nsIObserverService.h"
#include "nsICategoryManager.h"
@@ -957,13 +956,6 @@ HTMLFormElement::DoSecureToInsecureSubmitCheck(nsIURI* aActionURL,
*aCancelSubmit = (buttonPressed == 1);
uint32_t telemetryBucket =
nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI,
- telemetryBucket);
- if (!*aCancelSubmit) {
- // The user opted to continue, so note that in the next telemetry bucket.
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI,
- telemetryBucket + 1);
- }
return NS_OK;
}
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index e9086933b..0b879bb9b 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -24,7 +24,6 @@
#include "nsIPhonetic.h"
#include "HTMLFormSubmissionConstants.h"
-#include "mozilla/Telemetry.h"
#include "nsIControllers.h"
#include "nsIStringBundle.h"
#include "nsFocusManager.h"
@@ -1275,10 +1274,6 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
container->RadioRequiredWillChange(name, !!aValue);
}
}
-
- if (aName == nsGkAtoms::webkitdirectory) {
- Telemetry::Accumulate(Telemetry::WEBKIT_DIRECTORY_USED, true);
- }
}
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
@@ -4989,10 +4984,6 @@ HTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
true);
dispatcher->PostDOMEvent();
}
-
-#ifdef EARLY_BETA_OR_EARLIER
- Telemetry::Accumulate(Telemetry::PWMGR_PASSWORD_INPUT_IN_FORM, !!mForm);
-#endif
}
return rv;
@@ -8863,7 +8854,6 @@ HTMLInputElement::UpdateEntries(const nsTArray<OwningFileOrDirectory>& aFilesOrD
void
HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence)
{
- Telemetry::Accumulate(Telemetry::BLINK_FILESYSTEM_USED, true);
aSequence.AppendElements(mEntries);
}
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 3954e6208..6171e1766 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -92,7 +92,6 @@
#include "mozilla/dom/VideoTrackList.h"
#include "mozilla/dom/TextTrack.h"
#include "nsIContentPolicy.h"
-#include "mozilla/Telemetry.h"
#include "DecoderDoctorDiagnostics.h"
#include "DecoderTraits.h"
#include "MediaContentType.h"
@@ -1902,7 +1901,6 @@ void
HTMLMediaElement::FastSeek(double aTime, ErrorResult& aRv)
{
LOG(LogLevel::Debug, ("Reporting telemetry VIDEO_FASTSEEK_USED"));
- Telemetry::Accumulate(Telemetry::VIDEO_FASTSEEK_USED, 1);
RefPtr<Promise> tobeDropped = Seek(aTime, SeekTarget::PrevSyncPoint, aRv);
}
@@ -3693,7 +3691,6 @@ HTMLMediaElement::ReportEMETelemetry()
// Report telemetry for EME videos when a page is unloaded.
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
if (mIsEncrypted && Preferences::GetBool("media.eme.enabled")) {
- Telemetry::Accumulate(Telemetry::VIDEO_EME_PLAY_SUCCESS, mLoadedDataFired);
LOG(LogLevel::Debug, ("%p VIDEO_EME_PLAY_SUCCESS = %s",
this, mLoadedDataFired ? "true" : "false"));
}
@@ -3745,7 +3742,6 @@ HTMLMediaElement::ReportTelemetry()
}
}
- Telemetry::Accumulate(Telemetry::VIDEO_UNLOAD_STATE, state);
LOG(LogLevel::Debug, ("%p VIDEO_UNLOAD_STATE = %d", this, state));
FrameStatisticsData data;
@@ -3761,8 +3757,6 @@ HTMLMediaElement::ReportTelemetry()
uint32_t percentage = 100 * data.mDroppedFrames / data.mParsedFrames;
LOG(LogLevel::Debug,
("Reporting telemetry DROPPED_FRAMES_IN_VIDEO_PLAYBACK"));
- Telemetry::Accumulate(Telemetry::VIDEO_DROPPED_FRAMES_PROPORTION,
- percentage);
}
}
}
@@ -3774,10 +3768,8 @@ HTMLMediaElement::ReportTelemetry()
double hiddenPlayTime = mHiddenPlayTime.Total();
double videoDecodeSuspendTime = mVideoDecodeSuspendTime.Total();
- Telemetry::Accumulate(Telemetry::VIDEO_PLAY_TIME_MS, SECONDS_TO_MS(playTime));
LOG(LogLevel::Debug, ("%p VIDEO_PLAY_TIME_MS = %f", this, playTime));
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_MS, SECONDS_TO_MS(hiddenPlayTime));
LOG(LogLevel::Debug, ("%p VIDEO_HIDDEN_PLAY_TIME_MS = %f", this, hiddenPlayTime));
if (playTime > 0.0) {
@@ -3804,24 +3796,11 @@ HTMLMediaElement::ReportTelemetry()
key.AppendASCII(resolution);
uint32_t hiddenPercentage = uint32_t(hiddenPlayTime / playTime * 100.0 + 0.5);
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE,
- key,
- hiddenPercentage);
- // Also accumulate all percentages in an "All" key.
- Telemetry::Accumulate(Telemetry::VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE,
- NS_LITERAL_CSTRING("All"),
- hiddenPercentage);
LOG(LogLevel::Debug, ("%p VIDEO_HIDDEN_PLAY_TIME_PERCENTAGE = %u, keys: '%s' and 'All'",
this, hiddenPercentage, key.get()));
uint32_t videoDecodeSuspendPercentage =
uint32_t(videoDecodeSuspendTime / playTime * 100.0 + 0.5);
- Telemetry::Accumulate(Telemetry::VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE,
- key,
- videoDecodeSuspendPercentage);
- Telemetry::Accumulate(Telemetry::VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE,
- NS_LITERAL_CSTRING("All"),
- videoDecodeSuspendPercentage);
LOG(LogLevel::Debug, ("%p VIDEO_INFERRED_DECODE_SUSPEND_PERCENTAGE = %u, keys: '%s' and 'All'",
this, videoDecodeSuspendPercentage, key.get()));
@@ -3832,24 +3811,12 @@ HTMLMediaElement::ReportTelemetry()
/ 1000.0
+ 0.5,
UINT32_MAX));
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_AVERAGE_MS,
- key,
- average_ms);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_AVERAGE_MS,
- NS_LITERAL_CSTRING("All"),
- average_ms);
LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_AVERAGE_MS = %u, keys: '%s' and 'All'",
this, average_ms, key.get()));
uint32_t max_ms =
uint32_t(std::min<uint64_t>((data.mInterKeyFrameMax_us + 500) / 1000,
UINT32_MAX));
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- key,
- max_ms);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- NS_LITERAL_CSTRING("All"),
- max_ms);
LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_MAX_MS = %u, keys: '%s' and 'All'",
this, max_ms, key.get()));
} else {
@@ -3858,12 +3825,6 @@ HTMLMediaElement::ReportTelemetry()
// decode-suspend delay (showing recovery would be difficult).
uint32_t suspendDelay_ms = MediaPrefs::MDSMSuspendBackgroundVideoDelay();
if (uint32_t(playTime * 1000.0) > suspendDelay_ms) {
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- key,
- 0);
- Telemetry::Accumulate(Telemetry::VIDEO_INTER_KEYFRAME_MAX_MS,
- NS_LITERAL_CSTRING("All"),
- 0);
LOG(LogLevel::Debug, ("%p VIDEO_INTER_KEYFRAME_MAX_MS = 0 (only 1 keyframe), keys: '%s' and 'All'",
this, key.get()));
}
@@ -6860,97 +6821,6 @@ HTMLMediaElement::MarkAsContentSource(CallerAPI aAPI)
{
const bool isVisible = mVisibilityState != Visibility::APPROXIMATELY_NONVISIBLE;
- if (isVisible) {
- // 0 = ALL_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 0);
- } else {
- // 1 = ALL_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 1);
-
- if (IsInUncomposedDoc()) {
- // 0 = ALL_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 0);
- } else {
- // 1 = ALL_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 1);
- }
- }
-
- switch (aAPI) {
- case CallerAPI::DRAW_IMAGE: {
- if (isVisible) {
- // 2 = drawImage_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 2);
- } else {
- // 3 = drawImage_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 3);
-
- if (IsInUncomposedDoc()) {
- // 2 = drawImage_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 2);
- } else {
- // 3 = drawImage_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 3);
- }
- }
- break;
- }
- case CallerAPI::CREATE_PATTERN: {
- if (isVisible) {
- // 4 = createPattern_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 4);
- } else {
- // 5 = createPattern_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 5);
-
- if (IsInUncomposedDoc()) {
- // 4 = createPattern_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 4);
- } else {
- // 5 = createPattern_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 5);
- }
- }
- break;
- }
- case CallerAPI::CREATE_IMAGEBITMAP: {
- if (isVisible) {
- // 6 = createImageBitmap_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 6);
- } else {
- // 7 = createImageBitmap_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 7);
-
- if (IsInUncomposedDoc()) {
- // 6 = createImageBitmap_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 6);
- } else {
- // 7 = createImageBitmap_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 7);
- }
- }
- break;
- }
- case CallerAPI::CAPTURE_STREAM: {
- if (isVisible) {
- // 8 = captureStream_VISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 8);
- } else {
- // 9 = captureStream_INVISIBLE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE, 9);
-
- if (IsInUncomposedDoc()) {
- // 8 = captureStream_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 8);
- } else {
- // 9 = captureStream_NOT_IN_TREE
- Telemetry::Accumulate(Telemetry::VIDEO_AS_CONTENT_SOURCE_IN_TREE_OR_NOT, 9);
- }
- }
- break;
- }
- }
-
LOG(LogLevel::Debug,
("%p Log VIDEO_AS_CONTENT_SOURCE: visibility = %u, API: '%d' and 'All'",
this, isVisible, aAPI));
diff --git a/dom/html/HTMLOptionsCollection.cpp b/dom/html/HTMLOptionsCollection.cpp
index 294493c0c..67de97fc4 100644
--- a/dom/html/HTMLOptionsCollection.cpp
+++ b/dom/html/HTMLOptionsCollection.cpp
@@ -35,23 +35,8 @@ namespace mozilla {
namespace dom {
HTMLOptionsCollection::HTMLOptionsCollection(HTMLSelectElement* aSelect)
-{
- // Do not maintain a reference counted reference. When
- // the select goes away, it will let us know.
- mSelect = aSelect;
-}
-
-HTMLOptionsCollection::~HTMLOptionsCollection()
-{
- DropReference();
-}
-
-void
-HTMLOptionsCollection::DropReference()
-{
- // Drop our (non ref-counted) reference
- mSelect = nullptr;
-}
+ : mSelect(aSelect)
+{}
nsresult
HTMLOptionsCollection::GetOptionIndex(Element* aOption,
@@ -88,7 +73,9 @@ HTMLOptionsCollection::GetOptionIndex(Element* aOption,
}
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLOptionsCollection, mElements)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HTMLOptionsCollection,
+ mElements,
+ mSelect)
// nsISupports
@@ -124,10 +111,6 @@ HTMLOptionsCollection::GetLength(uint32_t* aLength)
NS_IMETHODIMP
HTMLOptionsCollection::SetLength(uint32_t aLength)
{
- if (!mSelect) {
- return NS_ERROR_UNEXPECTED;
- }
-
return mSelect->SetLength(aLength);
}
@@ -135,10 +118,6 @@ NS_IMETHODIMP
HTMLOptionsCollection::SetOption(uint32_t aIndex,
nsIDOMHTMLOptionElement* aOption)
{
- if (!mSelect) {
- return NS_OK;
- }
-
// if the new option is null, just remove this option. Note that it's safe
// to pass a too-large aIndex in here.
if (!aOption) {
@@ -187,11 +166,6 @@ HTMLOptionsCollection::SetOption(uint32_t aIndex,
int32_t
HTMLOptionsCollection::GetSelectedIndex(ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return 0;
- }
-
int32_t selectedIndex;
aError = mSelect->GetSelectedIndex(&selectedIndex);
return selectedIndex;
@@ -209,11 +183,6 @@ void
HTMLOptionsCollection::SetSelectedIndex(int32_t aSelectedIndex,
ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
aError = mSelect->SetSelectedIndex(aSelectedIndex);
}
@@ -339,22 +308,12 @@ HTMLOptionsCollection::Add(const HTMLOptionOrOptGroupElement& aElement,
const Nullable<HTMLElementOrLong>& aBefore,
ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_NOT_INITIALIZED);
- return;
- }
-
mSelect->Add(aElement, aBefore, aError);
}
void
HTMLOptionsCollection::Remove(int32_t aIndex, ErrorResult& aError)
{
- if (!mSelect) {
- aError.Throw(NS_ERROR_UNEXPECTED);
- return;
- }
-
uint32_t len = 0;
mSelect->GetLength(&len);
if (aIndex < 0 || (uint32_t)aIndex >= len)
diff --git a/dom/html/HTMLOptionsCollection.h b/dom/html/HTMLOptionsCollection.h
index 21123b3d2..496919555 100644
--- a/dom/html/HTMLOptionsCollection.h
+++ b/dom/html/HTMLOptionsCollection.h
@@ -46,7 +46,7 @@ public:
using nsWrapperCache::GetWrapper;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
protected:
- virtual ~HTMLOptionsCollection();
+ virtual ~HTMLOptionsCollection() = default;
virtual JSObject* GetWrapperPreserveColorInternal() override
{
@@ -113,11 +113,6 @@ public:
}
/**
- * Drop the reference to the select. Called during select destruction.
- */
- void DropReference();
-
- /**
* Finds the index of a given option element.
* If the option isn't part of the collection, return NS_ERROR_FAILURE
* without setting aIndex.
@@ -161,7 +156,7 @@ private:
* various members such as InsertOptionAt are also infallible. */
nsTArray<RefPtr<mozilla::dom::HTMLOptionElement> > mElements;
/** The select element that contains this array */
- HTMLSelectElement* mSelect;
+ RefPtr<HTMLSelectElement> mSelect;
};
} // namespace dom
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 53f42317a..9ba0a1efe 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -130,11 +130,6 @@ HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& a
NS_EVENT_STATE_VALID);
}
-HTMLSelectElement::~HTMLSelectElement()
-{
- mOptions->DropReference();
-}
-
// ISupports
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLSelectElement)
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index 8a25385de..dc1075cd7 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -436,7 +436,7 @@ public:
void SetOpenInParentProcess(bool aVal);
protected:
- virtual ~HTMLSelectElement();
+ virtual ~HTMLSelectElement() = default;
friend class SafeOptionListMutation;
diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp
index 200bb5d46..f83a804be 100644
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -40,12 +40,14 @@
#include "nsThreadUtils.h"
#include "nsIScrollableFrame.h"
#include "nsContentUtils.h"
+#include "nsCSSParser.h" // for CSS colors on the background
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
#include <algorithm>
#define AUTOMATIC_IMAGE_RESIZING_PREF "browser.enable_automatic_image_resizing"
#define CLICK_IMAGE_RESIZING_PREF "browser.enable_click_image_resizing"
+#define STANDALONE_IMAGE_BACKGROUND_COLOR_PREF "browser.display.standalone_images.background_color"
//XXX A hack needed for Firefox's site specific zoom.
#define SITE_SPECIFIC_ZOOM "browser.zoom.siteSpecific"
@@ -170,6 +172,8 @@ ImageDocument::Init()
mClickResizingEnabled = Preferences::GetBool(CLICK_IMAGE_RESIZING_PREF);
mShouldResize = mResizeImageByDefault;
mFirstResize = true;
+
+ mBackgroundColor = Preferences::GetString(STANDALONE_IMAGE_BACKGROUND_COLOR_PREF);
return NS_OK;
}
@@ -682,9 +686,22 @@ ImageDocument::CreateSyntheticDocument()
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::src, srcString, false);
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::alt, srcString, false);
+ // Implement mechanism for custom background color from pref.
+ if (!mBackgroundColor.IsEmpty()) {
+ nsCSSValue color;
+ nsCSSParser parser;
+ if (parser.ParseColorString(mBackgroundColor, nullptr, 0, color)) {
+ nsAutoString styleAttr(NS_LITERAL_STRING("background-color: "));
+ styleAttr.Append(mBackgroundColor);
+ body->SetAttr(kNameSpaceID_None, nsGkAtoms::style, styleAttr, false);
+ }
+ }
+
body->AppendChildTo(mImageContent, false);
imageLoader->SetLoadingEnabled(true);
+ UpdateTitleAndCharset();
+
return NS_OK;
}
diff --git a/dom/html/ImageDocument.h b/dom/html/ImageDocument.h
index fdf2a00a8..945317314 100644
--- a/dom/html/ImageDocument.h
+++ b/dom/html/ImageDocument.h
@@ -112,6 +112,9 @@ protected:
float mVisibleHeight;
int32_t mImageWidth;
int32_t mImageHeight;
+
+ // Holds the custom background color for stand-alone images
+ nsAutoString mBackgroundColor;
bool mResizeImageByDefault;
bool mClickResizingEnabled;
diff --git a/dom/html/TextTrackManager.cpp b/dom/html/TextTrackManager.cpp
index 8110dab29..cc14858b6 100644
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -12,7 +12,6 @@
#include "mozilla/dom/TextTrackCue.h"
#include "mozilla/dom/Event.h"
#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/Telemetry.h"
#include "nsComponentManagerUtils.h"
#include "nsVariant.h"
#include "nsVideoFrame.h"
@@ -30,6 +29,13 @@ namespace dom {
NS_IMPL_ISUPPORTS(TextTrackManager::ShutdownObserverProxy, nsIObserver);
+void
+TextTrackManager::ShutdownObserverProxy::Unregister()
+{
+ nsContentUtils::UnregisterShutdownObserver(this);
+ mManager = nullptr;
+}
+
CompareTextTracks::CompareTextTracks(HTMLMediaElement* aMediaElement)
{
mMediaElement = aMediaElement;
@@ -138,7 +144,7 @@ TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
TextTrackManager::~TextTrackManager()
{
WEBVTT_LOG("%p ~TextTrackManager",this);
- nsContentUtils::UnregisterShutdownObserver(mShutdownProxy);
+ mShutdownProxy->Unregister();
}
TextTrackList*
@@ -824,24 +830,13 @@ TextTrackManager::NotifyReset()
void
TextTrackManager::ReportTelemetryForTrack(TextTrack* aTextTrack) const
{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(aTextTrack);
- MOZ_ASSERT(mTextTracks->Length() > 0);
-
- TextTrackKind kind = aTextTrack->Kind();
- Telemetry::Accumulate(Telemetry::WEBVTT_TRACK_KINDS, uint32_t(kind));
+/* STUB */
}
void
TextTrackManager::ReportTelemetryForCue()
{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!mNewCues->IsEmpty() || !mLastActiveCues->IsEmpty());
-
- if (!mCueTelemetryReported) {
- Telemetry::Accumulate(Telemetry::WEBVTT_USED_VTT_CUES, 1);
- mCueTelemetryReported = true;
- }
+/* STUB */
}
} // namespace dom
diff --git a/dom/html/TextTrackManager.h b/dom/html/TextTrackManager.h
index d20707346..4ad1a57a7 100644
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -170,11 +170,15 @@ private:
{
MOZ_ASSERT(NS_IsMainThread());
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
- nsContentUtils::UnregisterShutdownObserver(this);
- mManager->NotifyShutdown();
+ if (mManager) {
+ mManager->NotifyShutdown();
+ }
+ Unregister();
}
return NS_OK;
}
+
+ void Unregister();
private:
~ShutdownObserverProxy() {};
diff --git a/dom/html/nsTextEditorState.cpp b/dom/html/nsTextEditorState.cpp
index 187afb66d..0b4cb1920 100644
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -47,7 +47,6 @@
#include "mozilla/dom/HTMLInputElement.h"
#include "nsNumberControlFrame.h"
#include "nsFrameSelection.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/layers/ScrollInputMethods.h"
using namespace mozilla;
@@ -585,9 +584,6 @@ nsTextInputSelectionImpl::CompleteScroll(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadCompleteScroll);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::WHOLE,
nsIScrollableFrame::INSTANT);
@@ -640,9 +636,6 @@ nsTextInputSelectionImpl::ScrollPage(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollPage);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::PAGES,
nsIScrollableFrame::SMOOTH);
@@ -655,9 +648,6 @@ nsTextInputSelectionImpl::ScrollLine(bool aForward)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollLine);
-
mScrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
@@ -670,9 +660,6 @@ nsTextInputSelectionImpl::ScrollCharacter(bool aRight)
if (!mScrollFrame)
return NS_ERROR_NOT_INITIALIZED;
- mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
- (uint32_t) ScrollInputMethod::MainThreadScrollCharacter);
-
mScrollFrame->ScrollBy(nsIntPoint(aRight ? 1 : -1, 0),
nsIScrollableFrame::LINES,
nsIScrollableFrame::SMOOTH);
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
index e6fe9e2a8..58c113058 100644
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -23,6 +23,7 @@
#include "mozilla/AppProcessChecker.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/Casting.h"
+#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/LazyIdleThread.h"
@@ -249,8 +250,6 @@ const char kSQLiteJournalSuffix[] = ".sqlite-journal";
const char kSQLiteSHMSuffix[] = ".sqlite-shm";
const char kSQLiteWALSuffix[] = ".sqlite-wal";
-const char kPrefIndexedDBEnabled[] = "dom.indexedDB.enabled";
-
const char kPrefFileHandleEnabled[] = "dom.fileHandle.enabled";
#define IDB_PREFIX "indexedDB"
@@ -784,29 +783,25 @@ MakeCompressedIndexDataValues(
MOZ_ASSERT(!keyBuffer.IsEmpty());
- // Don't let |infoLength| overflow.
- if (NS_WARN_IF(UINT32_MAX - keyBuffer.Length() <
- CompressedByteCountForIndexId(info.mIndexId) +
- CompressedByteCountForNumber(keyBufferLength) +
- CompressedByteCountForNumber(sortKeyBufferLength))) {
- IDB_REPORT_INTERNAL_ERR();
- return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
- }
-
- const uint32_t infoLength =
- CompressedByteCountForIndexId(info.mIndexId) +
+ const CheckedUint32 infoLength =
+ CheckedUint32(CompressedByteCountForIndexId(info.mIndexId)) +
CompressedByteCountForNumber(keyBufferLength) +
CompressedByteCountForNumber(sortKeyBufferLength) +
keyBufferLength +
sortKeyBufferLength;
+ // Don't let |infoLength| overflow.
+ if (NS_WARN_IF(!infoLength.isValid())) {
+ IDB_REPORT_INTERNAL_ERR();
+ return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
+ }
// Don't let |blobDataLength| overflow.
- if (NS_WARN_IF(UINT32_MAX - infoLength < blobDataLength)) {
+ if (NS_WARN_IF(UINT32_MAX - infoLength.value() < blobDataLength)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
- blobDataLength += infoLength;
+ blobDataLength += infoLength.value();
}
UniqueFreePtr<uint8_t> blobData(
@@ -21172,16 +21167,6 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
- if (NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- if (aContentParent) {
- // The DOM in the other process should have kept us from receiving any
- // indexedDB messages so assume that the child is misbehaving.
- aContentParent->KillHard("IndexedDB CheckPermission 1");
- }
-
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
const ContentPrincipalInfo& contentPrincipalInfo =
principalInfo.get_ContentPrincipalInfo();
if (contentPrincipalInfo.attrs().mPrivateBrowsingId != 0) {
diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp
index 663828978..825d2ac36 100644
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -47,12 +47,6 @@ namespace dom {
using namespace mozilla::dom::quota;
using namespace mozilla::ipc;
-namespace {
-
-const char kPrefIndexedDBEnabled[] = "dom.indexedDB.enabled";
-
-} // namespace
-
class IDBFactory::BackgroundCreateCallback final
: public nsIIPCBackgroundChildCreateCallback
{
@@ -130,12 +124,6 @@ IDBFactory::CreateForWindow(nsPIDOMWindowInner* aWindow,
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = AllowedForWindowInternal(aWindow, getter_AddRefs(principal));
- if (!(NS_SUCCEEDED(rv) && nsContentUtils::IsSystemPrincipal(principal)) &&
- NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- *aFactory = nullptr;
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
if (rv == NS_ERROR_DOM_NOT_SUPPORTED_ERR) {
NS_WARNING("IndexedDB is not permitted in a third-party window.");
*aFactory = nullptr;
@@ -246,12 +234,6 @@ IDBFactory::CreateForMainThreadJSInternal(
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPrincipalInfo);
- if (aPrincipalInfo->type() != PrincipalInfo::TSystemPrincipalInfo &&
- NS_WARN_IF(!Preferences::GetBool(kPrefIndexedDBEnabled, false))) {
- *aFactory = nullptr;
- return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
- }
-
IndexedDatabaseManager* mgr = IndexedDatabaseManager::GetOrCreate();
if (NS_WARN_IF(!mgr)) {
IDB_REPORT_INTERNAL_ERR();
diff --git a/dom/indexedDB/KeyPath.cpp b/dom/indexedDB/KeyPath.cpp
index dc8d10668..30edd8cd7 100644
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -14,6 +14,7 @@
#include "xpcpublic.h"
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/IDBObjectStoreBinding.h"
namespace mozilla {
@@ -100,7 +101,6 @@ GetJSValFromKeyPathString(JSContext* aCx,
const char16_t* keyPathChars = token.BeginReading();
const size_t keyPathLen = token.Length();
- bool hasProp;
if (!targetObject) {
// We're still walking the chain of existing objects
// http://w3c.github.io/IndexedDB/#dfn-evaluate-a-key-path-on-a-value
@@ -116,16 +116,77 @@ GetJSValFromKeyPathString(JSContext* aCx,
}
obj = &currentVal.toObject();
- bool ok = JS_HasUCProperty(aCx, obj, keyPathChars, keyPathLen,
- &hasProp);
+ // We call JS_GetOwnUCPropertyDescriptor on purpose (as opposed to
+ // JS_GetUCPropertyDescriptor) to avoid searching the prototype chain.
+ JS::Rooted<JS::PropertyDescriptor> desc(aCx);
+ bool ok = JS_GetOwnUCPropertyDescriptor(aCx, obj, keyPathChars,
+ keyPathLen, &desc);
IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
- if (hasProp) {
- // Get if the property exists...
- JS::Rooted<JS::Value> intermediate(aCx);
- bool ok = JS_GetUCProperty(aCx, obj, keyPathChars, keyPathLen, &intermediate);
- IDB_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
+ JS::Rooted<JS::Value> intermediate(aCx);
+ bool hasProp = false;
+
+ if (desc.object()) {
+ intermediate = desc.value();
+ hasProp = true;
+ } else {
+ // If we get here it means the object doesn't have the property or the
+ // property is available throuch a getter. We don't want to call any
+ // getters to avoid potential re-entrancy.
+ // The blob object is special since its properties are available
+ // only through getters but we still want to support them for key
+ // extraction. So they need to be handled manually.
+ Blob* blob;
+ if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
+ if (token.EqualsLiteral("size")) {
+ ErrorResult rv;
+ uint64_t size = blob->GetSize(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ intermediate = JS_NumberValue(size);
+ hasProp = true;
+ } else if (token.EqualsLiteral("type")) {
+ nsString type;
+ blob->GetType(type);
+
+ JSString* string =
+ JS_NewUCStringCopyN(aCx, type.get(), type.Length());
+
+ intermediate = JS::StringValue(string);
+ hasProp = true;
+ } else {
+ RefPtr<File> file = blob->ToFile();
+ if (file) {
+ if (token.EqualsLiteral("name")) {
+ nsString name;
+ file->GetName(name);
+
+ JSString* string =
+ JS_NewUCStringCopyN(aCx, name.get(), name.Length());
+
+ intermediate = JS::StringValue(string);
+ hasProp = true;
+ } else if (token.EqualsLiteral("lastModified")) {
+ ErrorResult rv;
+ int64_t lastModifiedDate = file->GetLastModified(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ intermediate = JS_NumberValue(lastModifiedDate);
+ hasProp = true;
+ } else if (token.EqualsLiteral("lastModifiedDate")) {
+ ErrorResult rv;
+ Date lastModifiedDate = file->GetLastModifiedDate(rv);
+ MOZ_ALWAYS_TRUE(!rv.Failed());
+
+ lastModifiedDate.ToDateObject(aCx, &intermediate);
+ hasProp = true;
+ }
+ }
+ }
+ }
+ }
+ if (hasProp) {
// Treat explicitly undefined as an error.
if (intermediate.isUndefined()) {
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index fc288e2c5..fdf0fcf3e 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -171,7 +171,6 @@
#include "GMPServiceChild.h"
#include "gfxPlatform.h"
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
-#include "VRManagerChild.h"
using namespace mozilla;
using namespace mozilla::docshell;
@@ -1148,7 +1147,6 @@ ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
bool
ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
if (!CompositorBridgeChild::InitForContent(Move(aCompositor))) {
@@ -1157,9 +1155,6 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
if (!ImageBridgeChild::InitForContent(Move(aImageBridge))) {
return false;
}
- if (!gfx::VRManagerChild::InitForContent(Move(aVRBridge))) {
- return false;
- }
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
return true;
}
@@ -1167,7 +1162,6 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
bool
ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
@@ -1186,9 +1180,6 @@ ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor
if (!ImageBridgeChild::ReinitForContent(Move(aImageBridge))) {
return false;
}
- if (!gfx::VRManagerChild::ReinitForContent(Move(aVRBridge))) {
- return false;
- }
// Establish new PLayerTransactions.
for (const auto& tabChild : tabs) {
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index ba590b58e..f29d17e7f 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -152,15 +152,13 @@ public:
RecvInitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
- Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
+ Endpoint<PVideoDecoderManagerChild>&& aVideoManager);
bool
RecvReinitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
- Endpoint<PVRManagerChild>&& aVRBridge,
- Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
+ Endpoint<PVideoDecoderManagerChild>&& aVideoManager);
PProcessHangMonitorChild*
AllocPProcessHangMonitorChild(Transport* aTransport,
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index 0a07147bf..417420ecb 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1718,9 +1718,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
if (AbnormalShutdown == why) {
- Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
- NS_LITERAL_CSTRING("content"), 1);
-
props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
}
nsAutoString cpId;
@@ -2076,21 +2073,18 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
- &vrBridge,
&videoManager);
MOZ_ASSERT(opened);
Unused << SendInitRendering(
Move(compositor),
Move(imageBridge),
- Move(vrBridge),
Move(videoManager));
gpm->AddListener(this);
@@ -2204,21 +2198,18 @@ ContentParent::OnCompositorUnexpectedShutdown()
Endpoint<PCompositorBridgeChild> compositor;
Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVRManagerChild> vrBridge;
Endpoint<PVideoDecoderManagerChild> videoManager;
DebugOnly<bool> opened = gpm->CreateContentBridges(
OtherPid(),
&compositor,
&imageBridge,
- &vrBridge,
&videoManager);
MOZ_ASSERT(opened);
Unused << SendReinitRendering(
Move(compositor),
Move(imageBridge),
- Move(vrBridge),
Move(videoManager));
}
@@ -4778,7 +4769,7 @@ bool
ContentParent::RecvAccumulateChildHistogram(
InfallibleTArray<Accumulation>&& aAccumulations)
{
- Telemetry::AccumulateChild(GeckoProcessType_Content, aAccumulations);
+ /* STUB */
return true;
}
@@ -4786,6 +4777,6 @@ bool
ContentParent::RecvAccumulateChildKeyedHistogram(
InfallibleTArray<KeyedAccumulation>&& aAccumulations)
{
- Telemetry::AccumulateChildKeyed(GeckoProcessType_Content, aAccumulations);
+ /* STUB */
return true;
}
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index c01ad59c1..9298f9d02 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -44,7 +44,6 @@ include protocol PRemoteSpellcheckEngine;
include protocol PWebBrowserPersistDocument;
include protocol PWebrtcGlobal;
include protocol PPresentation;
-include protocol PVRManager;
include protocol PVideoDecoderManager;
include protocol PFlyWebPublishedServer;
include DOMTypes;
@@ -311,7 +310,6 @@ child:
async InitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> imageBridge,
- Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
// Re-create the rendering stack using the given endpoints. This is sent
@@ -320,7 +318,6 @@ child:
async ReinitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> bridge,
- Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
/**
diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp
index 705799c54..3fe94001e 100644
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -107,7 +107,6 @@
#include "nsDeviceContext.h"
#include "nsSandboxFlags.h"
#include "FrameLayerBuilder.h"
-#include "VRManagerChild.h"
#include "nsICommandParams.h"
#include "nsISHistory.h"
#include "nsQueryObject.h"
@@ -2395,7 +2394,6 @@ TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
root->SchedulePaint();
}
- Telemetry::AutoTimer<Telemetry::TABCHILD_PAINT_TIME> timer;
// If we need to repaint, let's do that right away. No sense waiting until
// we get back to the event loop again. We suppress the display port so that
// we only paint what's visible. This ensures that the tab we're switching
@@ -2566,7 +2564,6 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
lf->SetShadowManager(shadowManager);
lf->IdentifyTextureHost(mTextureFactoryIdentifier);
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
- gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
}
mRemoteFrame = remoteFrame;
diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties
index ec0356c04..0472979d7 100644
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -195,8 +195,6 @@ IgnoringWillChangeOverBudgetWarning=Will-change memory consumption is too high.
HittingMaxWorkersPerDomain2=A Worker could not be started immediately because other documents in the same origin are already using the maximum number of workers. The Worker is now queued and will be started after some of the other workers have completed.
# LOCALIZATION NOTE: Do not translate "setVelocity", "PannerNode", "AudioListener", "speedOfSound" and "dopplerFactor"
PannerNodeDopplerWarning=Use of setVelocity on the PannerNode and AudioListener, and speedOfSound and dopplerFactor on the AudioListener are deprecated and those members will be removed. For more help https://developer.mozilla.org/en-US/docs/Web/API/AudioListener#Deprecated_features
-# LOCALIZATION NOTE: Do not translate "Application Cache API", "AppCache" and "ServiceWorker".
-AppCacheWarning=The Application Cache API (AppCache) is deprecated and will be removed at a future date. Please consider using ServiceWorker for offline support.
# LOCALIZATION NOTE: Do not translate "Worker".
EmptyWorkerSourceWarning=Attempting to create a Worker from an empty source. This is probably unintentional.
WebrtcDeprecatedPrefixWarning=WebRTC interfaces with the “moz” prefix (mozRTCPeerConnection, mozRTCSessionDescription, mozRTCIceCandidate) have been deprecated.
diff --git a/dom/locales/en-US/chrome/security/security.properties b/dom/locales/en-US/chrome/security/security.properties
index c0b80996c..8efdb0a6d 100644
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -8,6 +8,7 @@ BlockMixedActiveContent = Blocked loading mixed active content “%1$S”
CORSDisabled=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS disabled).
CORSRequestNotHttp=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS request not http).
CORSMissingAllowOrigin=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
+CORSMultipleAllowOriginNotAllowed=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: Multiple CORS headers ‘Access-Control-Allow-Origin’ not allowed).
CORSAllowOriginNotMatchingOrigin=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘%2$S’).
CORSNotSupportingCredentials=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ‘%1$S’. (Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’).
CORSMethodNotFound=Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at %1$S. (Reason: Did not find method in CORS header ‘Access-Control-Allow-Methods’).
diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp
index 54cf7b965..4b1d82c37 100644
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -14,7 +14,6 @@
#include "mozilla/Mutex.h"
#include "mozilla/Sprintf.h"
#include <algorithm>
-#include "mozilla/Telemetry.h"
#include "CubebUtils.h"
#include "nsPrintfCString.h"
#include "gfxPrefs.h"
@@ -346,7 +345,6 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Can't get cubeb context!");
- CubebUtils::ReportCubebStreamInitFailure(true);
return NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR;
}
@@ -368,18 +366,14 @@ AudioStream::OpenCubeb(cubeb* aContext, cubeb_stream_params& aParams,
latency_frames,
DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
mCubebStream.reset(stream);
- CubebUtils::ReportCubebBackendUsed();
} else {
NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
- CubebUtils::ReportCubebStreamInitFailure(aIsFirst);
return NS_ERROR_FAILURE;
}
TimeDuration timeDelta = TimeStamp::Now() - aStartTime;
LOG("creation time %sfirst: %u ms", aIsFirst ? "" : "not ",
(uint32_t) timeDelta.ToMilliseconds());
- Telemetry::Accumulate(aIsFirst ? Telemetry::AUDIOSTREAM_FIRST_OPEN_MS :
- Telemetry::AUDIOSTREAM_LATER_OPEN_MS, timeDelta.ToMilliseconds());
return NS_OK;
}
diff --git a/dom/media/Benchmark.cpp b/dom/media/Benchmark.cpp
index fdbedeca5..7394f8036 100644
--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -11,7 +11,6 @@
#include "PDMFactory.h"
#include "WebMDemuxer.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/ContentChild.h"
#ifndef MOZ_WIDGET_ANDROID
@@ -68,7 +67,6 @@ VP9Benchmark::IsVP9DecodeFast()
Preferences::SetUint(sBenchmarkFpsPref, aDecodeFps);
Preferences::SetUint(sBenchmarkFpsVersionCheck, sBenchmarkVersionID);
}
- Telemetry::Accumulate(Telemetry::ID::VIDEO_VP9_BENCHMARK_FPS, aDecodeFps);
},
[]() { });
}
diff --git a/dom/media/CubebUtils.cpp b/dom/media/CubebUtils.cpp
index fe94264ee..0f0167d9c 100644
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -239,39 +239,6 @@ cubeb* GetCubebContextUnlocked()
return sCubebContext;
}
-void ReportCubebBackendUsed()
-{
- StaticMutexAutoLock lock(sMutex);
-
- sAudioStreamInitEverSucceeded = true;
-
- bool foundBackend = false;
- for (uint32_t i = 0; i < ArrayLength(AUDIOSTREAM_BACKEND_ID_STR); i++) {
- if (!strcmp(cubeb_get_backend_id(sCubebContext), AUDIOSTREAM_BACKEND_ID_STR[i])) {
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED, i);
- foundBackend = true;
- }
- }
- if (!foundBackend) {
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED,
- CUBEB_BACKEND_UNKNOWN);
- }
-}
-
-void ReportCubebStreamInitFailure(bool aIsFirst)
-{
- StaticMutexAutoLock lock(sMutex);
- if (!aIsFirst && !sAudioStreamInitEverSucceeded) {
- // This machine has no audio hardware, or it's in really bad shape, don't
- // send this info, since we want CUBEB_BACKEND_INIT_FAILURE_OTHER to detect
- // failures to open multiple streams in a process over time.
- return;
- }
- Telemetry::Accumulate(Telemetry::AUDIOSTREAM_BACKEND_USED,
- aIsFirst ? CUBEB_BACKEND_INIT_FAILURE_FIRST
- : CUBEB_BACKEND_INIT_FAILURE_OTHER);
-}
-
uint32_t GetCubebPlaybackLatencyInMilliseconds()
{
StaticMutexAutoLock lock(sMutex);
diff --git a/dom/media/CubebUtils.h b/dom/media/CubebUtils.h
index fa5fc2294..f43492374 100644
--- a/dom/media/CubebUtils.h
+++ b/dom/media/CubebUtils.h
@@ -35,8 +35,6 @@ double GetVolumeScale();
bool GetFirstStream();
cubeb* GetCubebContext();
cubeb* GetCubebContextUnlocked();
-void ReportCubebStreamInitFailure(bool aIsFirstStream);
-void ReportCubebBackendUsed();
uint32_t GetCubebPlaybackLatencyInMilliseconds();
Maybe<uint32_t> GetCubebMSGLatencyInFrames();
bool CubebLatencyPrefSet();
diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp
index ddd35fe0d..f8cb4fd0e 100644
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -18,15 +18,6 @@
#include "WebMDecoder.h"
#include "WebMDemuxer.h"
-#ifdef MOZ_ANDROID_OMX
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaReader.h"
-#include "AndroidMediaPluginHost.h"
-#endif
-#ifdef MOZ_DIRECTSHOW
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#endif
#ifdef MOZ_FMP4
#include "MP4Decoder.h"
#include "MP4Demuxer.h"
@@ -110,29 +101,6 @@ IsHttpLiveStreamingType(const nsACString& aType)
return CodecListContains(gHttpLiveStreamingTypes, aType);
}
-#ifdef MOZ_ANDROID_OMX
-static bool
-IsAndroidMediaType(const nsACString& aType)
-{
- if (!MediaDecoder::IsAndroidMediaPluginEnabled()) {
- return false;
- }
-
- static const char* supportedTypes[] = {
- "audio/mpeg", "audio/mp4", "video/mp4", "video/x-m4v", nullptr
- };
- return CodecListContains(supportedTypes, aType);
-}
-#endif
-
-#ifdef MOZ_DIRECTSHOW
-static bool
-IsDirectShowSupportedType(const nsACString& aType)
-{
- return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
-}
-#endif
-
#ifdef MOZ_FMP4
static bool
IsMP4SupportedType(const MediaContentType& aParsedType,
@@ -247,14 +215,6 @@ CanHandleCodecsType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType(), aType.GetCodecs())) {
return CANPLAY_YES;
}
-#ifdef MOZ_DIRECTSHOW
- DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), &codecList);
-#endif
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled()) {
- EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), &codecList);
- }
-#endif
if (!codecList) {
return CANPLAY_MAYBE;
}
@@ -288,7 +248,7 @@ CanHandleMediaType(const MediaContentType& aType,
MOZ_ASSERT(NS_IsMainThread());
if (IsHttpLiveStreamingType(aType.GetMIMEType())) {
- Telemetry::Accumulate(Telemetry::MEDIA_HLS_CANPLAY_REQUESTED, true);
+ /* Telemetry STUB */
}
if (aType.HaveCodecs()) {
@@ -320,17 +280,6 @@ CanHandleMediaType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType())) {
return CANPLAY_MAYBE;
}
-#ifdef MOZ_DIRECTSHOW
- if (DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), nullptr)) {
- return CANPLAY_MAYBE;
- }
-#endif
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), nullptr)) {
- return CANPLAY_MAYBE;
- }
-#endif
return CANPLAY_NO;
}
@@ -411,33 +360,12 @@ InstantiateDecoder(const nsACString& aType,
decoder = new FlacDecoder(aOwner);
return decoder.forget();
}
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
- decoder = new AndroidMediaDecoder(aOwner, aType);
- return decoder.forget();
- }
-#endif
if (IsWebMSupportedType(aType)) {
decoder = new WebMDecoder(aOwner);
return decoder.forget();
}
-#ifdef MOZ_DIRECTSHOW
- // Note: DirectShow should come before WMF, so that we prefer DirectShow's
- // MP3 support over WMF's.
- if (IsDirectShowSupportedType(aType)) {
- decoder = new DirectShowDecoder(aOwner);
- return decoder.forget();
- }
-#endif
-
- if (IsHttpLiveStreamingType(aType)) {
- // We don't have an HLS decoder.
- Telemetry::Accumulate(Telemetry::MEDIA_HLS_DECODER_SUCCESS, false);
- }
-
return nullptr;
}
@@ -466,7 +394,7 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
} else
#endif
if (IsMP3SupportedType(aType)) {
- decoderReader = new MediaFormatReader(aDecoder, new mp3::MP3Demuxer(aDecoder->GetResource()));
+ decoderReader = new MediaFormatReader(aDecoder, new MP3Demuxer(aDecoder->GetResource()));
} else
if (IsAACSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
@@ -480,22 +408,10 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
if (IsOggSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new OggDemuxer(aDecoder->GetResource()));
} else
-#ifdef MOZ_ANDROID_OMX
- if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
- EnsureAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
- decoderReader = new AndroidMediaReader(aDecoder, aType);
- } else
-#endif
if (IsWebMSupportedType(aType)) {
decoderReader =
new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
- } else
-#ifdef MOZ_DIRECTSHOW
- if (IsDirectShowSupportedType(aType)) {
- decoderReader = new DirectShowReader(aDecoder);
- } else
-#endif
- if (false) {} // dummy if to take care of the dangling else
+ }
return decoderReader;
}
@@ -514,18 +430,12 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
return
IsOggSupportedType(aType) ||
IsWebMSupportedType(aType) ||
-#ifdef MOZ_ANDROID_OMX
- (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
-#endif
#ifdef MOZ_FMP4
IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
#endif
IsMP3SupportedType(aType) ||
IsAACSupportedType(aType) ||
IsFlacSupportedType(aType) ||
-#ifdef MOZ_DIRECTSHOW
- IsDirectShowSupportedType(aType) ||
-#endif
false;
}
diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp
index cae15eb8c..b60dfee9d 100644
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -200,7 +200,7 @@ public:
STREAM_LOG(LogLevel::Debug, ("Starting system thread"));
profiler_register_thread("MediaStreamGraph", &aLocal);
LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
- mDriver->mGraphImpl);
+ mDriver->mGraphImpl.get());
RefPtr<GraphDriver> previousDriver;
{
@@ -236,7 +236,7 @@ private:
void
ThreadedDriver::Start()
{
- LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl);
+ LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl.get());
Unused << NS_WARN_IF(mThread);
if (!mThread) { // Ensure we haven't already started it
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
@@ -623,9 +623,6 @@ AudioCallbackDriver::Init()
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Could not get cubeb context.");
- if (!mFromFallback) {
- CubebUtils::ReportCubebStreamInitFailure(true);
- }
return;
}
@@ -710,18 +707,11 @@ AudioCallbackDriver::Init()
NS_WARNING_ASSERTION(
rv == CUBEB_OK,
"Could not set the audio stream volume in GraphDriver.cpp");
- CubebUtils::ReportCubebBackendUsed();
} else {
#ifdef MOZ_WEBRTC
StaticMutexAutoUnlock unlock(AudioInputCubeb::Mutex());
#endif
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
- // Only report failures when we're not coming from a driver that was
- // created itself as a fallback driver because of a previous audio driver
- // failure.
- if (!mFromFallback) {
- CubebUtils::ReportCubebStreamInitFailure(firstStream);
- }
// Fall back to a driver using a normal thread. If needed,
// the graph will try to re-open an audio stream later.
MonitorAutoLock lock(GraphImpl()->GetMonitor());
@@ -761,7 +751,7 @@ AudioCallbackDriver::Destroy()
void
AudioCallbackDriver::Resume()
{
- STREAM_LOG(LogLevel::Debug, ("Resuming audio threads for MediaStreamGraph %p", mGraphImpl));
+ STREAM_LOG(LogLevel::Debug, ("Resuming audio threads for MediaStreamGraph %p", mGraphImpl.get()));
if (cubeb_stream_start(mAudioStream) != CUBEB_OK) {
NS_WARNING("Could not start cubeb stream for MSG.");
}
@@ -830,7 +820,9 @@ AudioCallbackDriver::Revive()
mGraphImpl->SetCurrentDriver(NextDriver());
NextDriver()->Start();
} else {
- STREAM_LOG(LogLevel::Debug, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl));
+ STREAM_LOG(LogLevel::Debug,
+ ("Starting audio threads for MediaStreamGraph %p from a new thread.",
+ mGraphImpl.get()));
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(this, AsyncCubebOperation::INIT);
initEvent->Dispatch();
diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h
index 411e175d3..bb4f2689b 100644
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -210,10 +210,8 @@ protected:
// Time of the end of this graph iteration. This must be accessed while having
// the monitor.
GraphTime mIterationEnd;
- // The MediaStreamGraphImpl that owns this driver. This has a lifetime longer
- // than the driver, and will never be null. Hence, it can be accesed without
- // monitor.
- MediaStreamGraphImpl* mGraphImpl;
+ // The MediaStreamGraphImpl associated with this driver.
+ const RefPtr<MediaStreamGraphImpl> mGraphImpl;
// This enum specifies the wait state of the driver.
enum WaitState {
diff --git a/dom/media/MP3FrameParser.cpp b/dom/media/MP3FrameParser.cpp
deleted file mode 100644
index 242e3df00..000000000
--- a/dom/media/MP3FrameParser.cpp
+++ /dev/null
@@ -1,591 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <algorithm>
-
-#include "nsMemory.h"
-#include "MP3FrameParser.h"
-#include "VideoUtils.h"
-
-
-#define FROM_BIG_ENDIAN(X) ((uint32_t)((uint8_t)(X)[0] << 24 | (uint8_t)(X)[1] << 16 | \
- (uint8_t)(X)[2] << 8 | (uint8_t)(X)[3]))
-
-
-namespace mozilla {
-
-/*
- * Following code taken from http://www.hydrogenaudio.org/forums/index.php?showtopic=85125
- * with permission from the author, Nick Wallette <sirnickity@gmail.com>.
- */
-
-/* BEGIN shameless copy and paste */
-
-// Bitrates - use [version][layer][bitrate]
-const uint16_t mpeg_bitrates[4][4][16] = {
- { // Version 2.5
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1
- },
- { // Reserved
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Invalid
- },
- { // Version 2
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 3
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // Layer 2
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 } // Layer 1
- },
- { // Version 1
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Reserved
- { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 }, // Layer 3
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, // Layer 2
- { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // Layer 1
- }
-};
-
-// Sample rates - use [version][srate]
-const uint16_t mpeg_srates[4][4] = {
- { 11025, 12000, 8000, 0 }, // MPEG 2.5
- { 0, 0, 0, 0 }, // Reserved
- { 22050, 24000, 16000, 0 }, // MPEG 2
- { 44100, 48000, 32000, 0 } // MPEG 1
-};
-
-// Samples per frame - use [version][layer]
-const uint16_t mpeg_frame_samples[4][4] = {
-// Rsvd 3 2 1 < Layer v Version
- { 0, 576, 1152, 384 }, // 2.5
- { 0, 0, 0, 0 }, // Reserved
- { 0, 576, 1152, 384 }, // 2
- { 0, 1152, 1152, 384 } // 1
-};
-
-// Slot size (MPEG unit of measurement) - use [layer]
-const uint8_t mpeg_slot_size[4] = { 0, 1, 1, 4 }; // Rsvd, 3, 2, 1
-
-uint16_t
-MP3Frame::CalculateLength()
-{
- // Lookup real values of these fields
- uint32_t bitrate = mpeg_bitrates[mVersion][mLayer][mBitrate] * 1000;
- uint32_t samprate = mpeg_srates[mVersion][mSampleRate];
- uint16_t samples = mpeg_frame_samples[mVersion][mLayer];
- uint8_t slot_size = mpeg_slot_size[mLayer];
-
- // In-between calculations
- float bps = (float)samples / 8.0;
- float fsize = ( (bps * (float)bitrate) / (float)samprate )
- + ( (mPad) ? slot_size : 0 );
-
- // Frame sizes are truncated integers
- return (uint16_t)fsize;
-}
-
-/* END shameless copy and paste */
-
-
-/** MP3Parser methods **/
-
-MP3Parser::MP3Parser()
- : mCurrentChar(0)
-{ }
-
-void
-MP3Parser::Reset()
-{
- mCurrentChar = 0;
-}
-
-uint16_t
-MP3Parser::ParseFrameLength(uint8_t ch)
-{
- mData.mRaw[mCurrentChar] = ch;
-
- MP3Frame &frame = mData.mFrame;
-
- // Validate MP3 header as we read. We can't mistake the start of an MP3 frame
- // for the middle of another frame due to the sync byte at the beginning
- // of the frame.
-
- // The only valid position for an all-high byte is the sync byte at the
- // beginning of the frame.
- if (ch == 0xff) {
- mCurrentChar = 0;
- }
-
- // Make sure the current byte is valid in context. If not, reset the parser.
- if (mCurrentChar == 2) {
- if (frame.mBitrate == 0x0f) {
- goto fail;
- }
- } else if (mCurrentChar == 1) {
- if (frame.mSync2 != 0x07
- || frame.mVersion == 0x01
- || frame.mLayer == 0x00) {
- goto fail;
- }
- }
-
- // The only valid character at the beginning of the header is 0xff. Fail if
- // it's different.
- if (mCurrentChar == 0 && frame.mSync1 != 0xff) {
- // Couldn't find the sync byte. Fail.
- return 0;
- }
-
- mCurrentChar++;
- MOZ_ASSERT(mCurrentChar <= sizeof(MP3Frame));
-
- // Don't have a full header yet.
- if (mCurrentChar < sizeof(MP3Frame)) {
- return 0;
- }
-
- // Woo, valid header. Return the length.
- mCurrentChar = 0;
- return frame.CalculateLength();
-
-fail:
- Reset();
- return 0;
-}
-
-uint32_t
-MP3Parser::GetSampleRate()
-{
- MP3Frame &frame = mData.mFrame;
- return mpeg_srates[frame.mVersion][frame.mSampleRate];
-}
-
-uint32_t
-MP3Parser::GetSamplesPerFrame()
-{
- MP3Frame &frame = mData.mFrame;
- return mpeg_frame_samples[frame.mVersion][frame.mLayer];
-}
-
-
-/** ID3Parser methods **/
-
-const char sID3Head[3] = { 'I', 'D', '3' };
-const uint32_t ID3_HEADER_LENGTH = 10;
-const uint32_t ID3_FOOTER_LENGTH = 10;
-const uint8_t ID3_FOOTER_PRESENT = 0x10;
-
-ID3Parser::ID3Parser()
- : mCurrentChar(0)
- , mVersion(0)
- , mFlags(0)
- , mHeaderLength(0)
-{ }
-
-void
-ID3Parser::Reset()
-{
- mCurrentChar = mVersion = mFlags = mHeaderLength = 0;
-}
-
-bool
-ID3Parser::ParseChar(char ch)
-{
- switch (mCurrentChar) {
- // The first three bytes of an ID3v2 header must match the string "ID3".
- case 0: case 1: case 2:
- if (ch != sID3Head[mCurrentChar]) {
- goto fail;
- }
- break;
- // The fourth and fifth bytes give the version, between 2 and 4.
- case 3:
- if (ch < '\2' || ch > '\4') {
- goto fail;
- }
- mVersion = uint8_t(ch);
- break;
- case 4:
- if (ch != '\0') {
- goto fail;
- }
- break;
- // The sixth byte gives the flags; valid flags depend on the version.
- case 5:
- if ((ch & (0xff >> mVersion)) != '\0') {
- goto fail;
- }
- mFlags = uint8_t(ch);
- break;
- // Bytes seven through ten give the sum of the byte length of the extended
- // header, the padding and the frames after unsynchronisation.
- // These bytes form a 28-bit integer, with the high bit of each byte unset.
- case 6: case 7: case 8: case 9:
- if (ch & 0x80) {
- goto fail;
- }
- mHeaderLength <<= 7;
- mHeaderLength |= ch;
- if (mCurrentChar == 9) {
- mHeaderLength += ID3_HEADER_LENGTH;
- mHeaderLength += (mFlags & ID3_FOOTER_PRESENT) ? ID3_FOOTER_LENGTH : 0;
- }
- break;
- default:
- MOZ_CRASH("Header already fully parsed!");
- }
-
- mCurrentChar++;
-
- return IsParsed();
-
-fail:
- if (mCurrentChar) {
- Reset();
- return ParseChar(ch);
- }
- Reset();
- return false;
-}
-
-bool
-ID3Parser::IsParsed() const
-{
- return mCurrentChar >= ID3_HEADER_LENGTH;
-}
-
-uint32_t
-ID3Parser::GetHeaderLength() const
-{
- MOZ_ASSERT(IsParsed(),
- "Queried length of ID3 header before parsing finished.");
- return mHeaderLength;
-}
-
-
-/** VBR header helper stuff **/
-
-// Helper function to find a VBR header in an MP3 frame.
-// Based on information from
-// http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
-
-const uint32_t VBRI_TAG = FROM_BIG_ENDIAN("VBRI");
-const uint32_t VBRI_OFFSET = 32 - sizeof(MP3Frame);
-const uint32_t VBRI_FRAME_COUNT_OFFSET = VBRI_OFFSET + 14;
-const uint32_t VBRI_MIN_FRAME_SIZE = VBRI_OFFSET + 26;
-
-const uint32_t XING_TAG = FROM_BIG_ENDIAN("Xing");
-enum XingFlags {
- XING_HAS_NUM_FRAMES = 0x01,
- XING_HAS_NUM_BYTES = 0x02,
- XING_HAS_TOC = 0x04,
- XING_HAS_VBR_SCALE = 0x08
-};
-
-static int64_t
-ParseXing(const char *aBuffer)
-{
- uint32_t flags = FROM_BIG_ENDIAN(aBuffer + 4);
-
- if (!(flags & XING_HAS_NUM_FRAMES)) {
- NS_WARNING("VBR file without frame count. Duration estimation likely to "
- "be totally wrong.");
- return -1;
- }
-
- int64_t numFrames = -1;
- if (flags & XING_HAS_NUM_FRAMES) {
- numFrames = FROM_BIG_ENDIAN(aBuffer + 8);
- }
-
- return numFrames;
-}
-
-static int64_t
-FindNumVBRFrames(const nsCString& aFrame)
-{
- const char *buffer = aFrame.get();
- const char *bufferEnd = aFrame.get() + aFrame.Length();
-
- // VBRI header is nice and well-defined; let's try to find that first.
- if (aFrame.Length() > VBRI_MIN_FRAME_SIZE &&
- FROM_BIG_ENDIAN(buffer + VBRI_OFFSET) == VBRI_TAG) {
- return FROM_BIG_ENDIAN(buffer + VBRI_FRAME_COUNT_OFFSET);
- }
-
- // We have to search for the Xing header as its position can change.
- for (; buffer + sizeof(XING_TAG) < bufferEnd; buffer++) {
- if (FROM_BIG_ENDIAN(buffer) == XING_TAG) {
- return ParseXing(buffer);
- }
- }
-
- return -1;
-}
-
-
-/** MP3FrameParser methods **/
-
-// Some MP3's have large ID3v2 tags, up to 150KB, so we allow lots of
-// skipped bytes to be read, just in case, before we give up and assume
-// we're not parsing an MP3 stream.
-static const uint32_t MAX_SKIPPED_BYTES = 4096;
-
-enum {
- MP3_HEADER_LENGTH = 4,
-};
-
-MP3FrameParser::MP3FrameParser(int64_t aLength)
-: mLock("MP3FrameParser.mLock"),
- mTotalID3Size(0),
- mTotalFrameSize(0),
- mFrameCount(0),
- mOffset(0),
- mLength(aLength),
- mMP3Offset(-1),
- mSamplesPerSecond(0),
- mFirstFrameEnd(-1),
- mIsMP3(MAYBE_MP3)
-{ }
-
-nsresult MP3FrameParser::ParseBuffer(const uint8_t* aBuffer,
- uint32_t aLength,
- int64_t aStreamOffset,
- uint32_t* aOutBytesRead)
-{
- // Iterate forwards over the buffer, looking for ID3 tag, or MP3
- // Frame headers.
- const uint8_t *buffer = aBuffer;
- const uint8_t *bufferEnd = aBuffer + aLength;
-
- // If we haven't found any MP3 frame data yet, there might be ID3 headers
- // we can skip over.
- if (mMP3Offset < 0) {
- for (const uint8_t *ch = buffer; ch < bufferEnd; ch++) {
- if (mID3Parser.ParseChar(*ch)) {
- // Found an ID3 header. We don't care about the body of the header, so
- // just skip past.
- buffer = ch + mID3Parser.GetHeaderLength() - (ID3_HEADER_LENGTH - 1);
-
- if (buffer <= ch) {
- return NS_ERROR_FAILURE;
- }
-
- ch = buffer;
-
- mTotalID3Size += mID3Parser.GetHeaderLength();
-
- // Yes, this is an MP3!
- mIsMP3 = DEFINITELY_MP3;
-
- mID3Parser.Reset();
- }
- }
- }
-
- // The first MP3 frame in a variable bitrate stream can contain metadata
- // for duration estimation and seeking, so we buffer that first frame here.
- if (aStreamOffset < mFirstFrameEnd) {
- uint64_t copyLen = std::min((int64_t)aLength, mFirstFrameEnd - aStreamOffset);
- mFirstFrame.Append((const char *)buffer, copyLen);
- buffer += copyLen;
- }
-
- while (buffer < bufferEnd) {
- uint16_t frameLen = mMP3Parser.ParseFrameLength(*buffer);
-
- if (frameLen) {
- // We've found an MP3 frame!
- // This is the first frame (and the only one we'll bother parsing), so:
- // * Mark this stream as MP3;
- // * Store the offset at which the MP3 data started; and
- // * Start buffering the frame, as it might contain handy metadata.
-
- // We're now sure this is an MP3 stream.
- mIsMP3 = DEFINITELY_MP3;
-
- // We need to know these to convert the number of frames in the stream
- // to the length of the stream in seconds.
- mSamplesPerSecond = mMP3Parser.GetSampleRate();
- mSamplesPerFrame = mMP3Parser.GetSamplesPerFrame();
-
- // If the stream has a constant bitrate, we should only need the length
- // of the first frame and the length (in bytes) of the stream to
- // estimate the length (in seconds).
- mTotalFrameSize += frameLen;
- mFrameCount++;
-
- // If |mMP3Offset| isn't set then this is the first MP3 frame we have
- // seen in the stream, which is useful for duration estimation.
- if (mMP3Offset > -1) {
- uint16_t skip = frameLen - sizeof(MP3Frame);
- buffer += skip ? skip : 1;
- continue;
- }
-
- // Remember the offset of the MP3 stream.
- // We're at the last byte of an MP3Frame, so MP3 data started
- // sizeof(MP3Frame) - 1 bytes ago.
- mMP3Offset = aStreamOffset
- + (buffer - aBuffer)
- - (sizeof(MP3Frame) - 1);
-
- buffer++;
-
- // If the stream has a variable bitrate, the first frame has metadata
- // we need for duration estimation and seeking. Start buffering it so we
- // can parse it later.
- mFirstFrameEnd = mMP3Offset + frameLen;
- uint64_t currOffset = buffer - aBuffer + aStreamOffset;
- uint64_t copyLen = std::min(mFirstFrameEnd - currOffset,
- (uint64_t)(bufferEnd - buffer));
- mFirstFrame.Append((const char *)buffer, copyLen);
-
- buffer += copyLen;
-
- } else {
- // Nothing to see here. Move along.
- buffer++;
- }
- }
-
- *aOutBytesRead = buffer - aBuffer;
-
- if (mFirstFrameEnd > -1 && mFirstFrameEnd <= aStreamOffset + buffer - aBuffer) {
- // We have our whole first frame. Try to find a VBR header.
- mNumFrames = FindNumVBRFrames(mFirstFrame);
- mFirstFrameEnd = -1;
- }
-
- return NS_OK;
-}
-
-void MP3FrameParser::Parse(const uint8_t* aBuffer, uint32_t aLength, uint64_t aOffset)
-{
- MutexAutoLock mon(mLock);
-
- if (HasExactDuration()) {
- // We know the duration; nothing to do here.
- return;
- }
-
- const uint8_t* buffer = aBuffer;
- int32_t length = aLength;
- uint64_t offset = aOffset;
-
- // Got some data we have seen already. Skip forward to what we need.
- if (aOffset < mOffset) {
- buffer += mOffset - aOffset;
- length -= mOffset - aOffset;
- offset = mOffset;
-
- if (length <= 0) {
- return;
- }
- }
-
- // If there is a discontinuity in the input stream, reset the state of the
- // parsers so we don't get any partial headers.
- if (mOffset < aOffset) {
- if (!mID3Parser.IsParsed()) {
- // Only reset this if it hasn't finished yet.
- mID3Parser.Reset();
- }
-
- if (mFirstFrameEnd > -1) {
- NS_WARNING("Discontinuity in input while buffering first frame.");
- mFirstFrameEnd = -1;
- }
-
- mMP3Parser.Reset();
- }
-
- uint32_t bytesRead = 0;
- if (NS_FAILED(ParseBuffer(buffer,
- length,
- offset,
- &bytesRead))) {
- return;
- }
-
- MOZ_ASSERT(length <= (int)bytesRead, "All bytes should have been consumed");
-
- // Update next data offset
- mOffset = offset + bytesRead;
-
- // If we've parsed lots of data and we still have nothing, just give up.
- // We don't count ID3 headers towards the skipped bytes count, as MP3 files
- // can have massive ID3 sections.
- if (!mID3Parser.IsParsed() && mMP3Offset < 0 &&
- mOffset - mTotalID3Size > MAX_SKIPPED_BYTES) {
- mIsMP3 = NOT_MP3;
- }
-}
-
-int64_t MP3FrameParser::GetDuration()
-{
- MutexAutoLock mon(mLock);
-
- if (!ParsedHeaders() || !mSamplesPerSecond) {
- // Not a single frame decoded yet.
- return -1;
- }
-
- MOZ_ASSERT(mFrameCount > 0 && mTotalFrameSize > 0,
- "Frame parser should have seen at least one MP3 frame of positive length.");
-
- if (!mFrameCount || !mTotalFrameSize) {
- // This should never happen.
- return -1;
- }
-
- double frames;
- if (mNumFrames < 0) {
- // Estimate the number of frames in the stream based on the average frame
- // size and the length of the MP3 file.
- double frameSize = (double)mTotalFrameSize / mFrameCount;
- frames = (double)(mLength - mMP3Offset) / frameSize;
- } else {
- // We know the exact number of frames from the VBR header.
- frames = mNumFrames;
- }
-
- // The duration of each frame is constant over a given stream.
- double usPerFrame = USECS_PER_S * mSamplesPerFrame / mSamplesPerSecond;
-
- return frames * usPerFrame;
-}
-
-int64_t MP3FrameParser::GetMP3Offset()
-{
- MutexAutoLock mon(mLock);
- return mMP3Offset;
-}
-
-bool MP3FrameParser::ParsedHeaders()
-{
- // We have seen both the beginning and the end of the first MP3 frame in the
- // stream.
- return mMP3Offset > -1 && mFirstFrameEnd < 0;
-}
-
-bool MP3FrameParser::HasExactDuration()
-{
- return ParsedHeaders() && mNumFrames > -1;
-}
-
-bool MP3FrameParser::NeedsData()
-{
- // If we don't know the duration exactly then either:
- // - we're still waiting for a VBR header; or
- // - we look at all frames to constantly update our duration estimate.
- return IsMP3() && !HasExactDuration();
-}
-
-} // namespace mozilla
diff --git a/dom/media/MP3FrameParser.h b/dom/media/MP3FrameParser.h
deleted file mode 100644
index d2ba791fd..000000000
--- a/dom/media/MP3FrameParser.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MP3FrameParser_h
-#define MP3FrameParser_h
-
-#include <stdint.h>
-
-#include "mozilla/Mutex.h"
-#include "nsString.h"
-#include "Intervals.h"
-
-namespace mozilla {
-
-// Simple parser to tell whether we've found an ID3 header and how long it is,
-// so that we can skip it.
-// XXX maybe actually parse this stuff?
-class ID3Parser
-{
-public:
- ID3Parser();
-
- void Reset();
- bool ParseChar(char ch);
- bool IsParsed() const;
- uint32_t GetHeaderLength() const;
-
-private:
- uint32_t mCurrentChar;
- uint8_t mVersion;
- uint8_t mFlags;
- uint32_t mHeaderLength;
-};
-
-struct MP3Frame {
- uint16_t mSync1 : 8; // Always all set
- uint16_t mProtected : 1; // Ignored
- uint16_t mLayer : 2;
- uint16_t mVersion : 2;
- uint16_t mSync2 : 3; // Always all set
- uint16_t mPrivate : 1; // Ignored
- uint16_t mPad : 1;
- uint16_t mSampleRate : 2; // Index into mpeg_srates above
- uint16_t mBitrate : 4; // Index into mpeg_bitrates above
-
- uint16_t CalculateLength();
-};
-
-// Buffering parser for MP3 frames.
-class MP3Parser
-{
-public:
- MP3Parser();
-
- // Forget all data the parser has seen so far.
- void Reset();
-
- // Parse the given byte. If we have found a frame header, return the length of
- // the frame.
- uint16_t ParseFrameLength(uint8_t ch);
-
- // Get the sample rate from the current header.
- uint32_t GetSampleRate();
-
- // Get the number of samples per frame.
- uint32_t GetSamplesPerFrame();
-
-private:
- uint32_t mCurrentChar;
- union {
- uint8_t mRaw[3];
- MP3Frame mFrame;
- } mData;
-};
-
-
-// A description of the MP3 format and its extensions is available at
-//
-// http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
-//
-// The data in MP3 streams is split into small frames, with each frame
-// containing a fixed number of samples. The duration of a frame depends
-// on the frame's bit rate and sample rate. Both values can vary among
-// frames, so it is necessary to examine each individual frame of an MP3
-// stream to calculate the stream's overall duration.
-//
-// The MP3 frame parser extracts information from an MP3 data stream. It
-// accepts a range of frames of an MP3 stream as input, and parses all
-// frames for their duration. Callers can query the stream's overall
-// duration from the parser.
-//
-// Call the methods NotifyDataArrived or Parse to add new data. If you added
-// information for a certain stream position, you cannot go back to previous
-// positions. The parser will simply ignore the input. If you skip stream
-// positions, the duration of the related MP3 frames will be estimated from
-// the stream's average.
-//
-// The method GetDuration returns calculated duration of the stream, including
-// estimates for skipped ranges.
-//
-// All public methods are thread-safe.
-
-class MP3FrameParser
-{
-public:
- explicit MP3FrameParser(int64_t aLength=-1);
-
- bool IsMP3() {
- MutexAutoLock mon(mLock);
- return mIsMP3 != NOT_MP3;
- }
-
- void Parse(const uint8_t* aBuffer, uint32_t aLength, uint64_t aStreamOffset);
-
- // Returns the duration, in microseconds. If the entire stream has not
- // been parsed yet, this is an estimate based on the bitrate of the
- // frames parsed so far.
- int64_t GetDuration();
-
- // Returns the offset of the first MP3 frame in the stream, or -1 of
- // no MP3 frame has been detected yet.
- int64_t GetMP3Offset();
-
- // Returns true if we've seen the whole first frame of the MP3 stream, and
- // therefore can make an estimate on the stream duration.
- // Otherwise, returns false.
- bool ParsedHeaders();
-
- // Returns true if we know the exact duration of the MP3 stream;
- // false otherwise.
- bool HasExactDuration();
-
- // Returns true if the parser needs more data for duration estimation.
- bool NeedsData();
- // Assign the total lenght of this mp3 stream
- void SetLength(int64_t aLength) {
- MutexAutoLock mon(mLock);
- mLength = aLength;
- }
-private:
-
- // Parses aBuffer, starting at offset 0. Returns the number of bytes
- // parsed, relative to the start of the buffer. Note this may be
- // greater than aLength if the headers in the buffer indicate that
- // the frame or ID3 tag extends outside of aBuffer. Returns failure
- // if too many non-MP3 bytes are parsed.
- nsresult ParseBuffer(const uint8_t* aBuffer,
- uint32_t aLength,
- int64_t aStreamOffset,
- uint32_t* aOutBytesRead);
-
- // A low-contention lock for protecting the parser results
- Mutex mLock;
-
- // ID3 header parser. Keeps state between reads in case the header falls
- // in between.
- ID3Parser mID3Parser;
-
- // MP3 frame header parser.
- MP3Parser mMP3Parser;
-
- // If we read |MAX_SKIPPED_BYTES| from the stream without finding any MP3
- // frames, we give up and report |NOT_MP3|. Here we track the cumulative size
- // of any ID3 headers we've seen so big ID3 sections aren't counted towards
- // skipped bytes.
- uint32_t mTotalID3Size;
-
- // All fields below are protected by mLock
-
- // We keep stats on the size of all the frames we've seen, as well as how many
- // so that we can estimate the duration of the rest of the stream.
- uint64_t mTotalFrameSize;
- uint64_t mFrameCount;
-
- // Offset of the last data parsed. This is the end offset of the last data
- // block parsed, so it's the start offset we expect to get on the next
- // call to Parse().
- uint64_t mOffset;
-
- // Total length of the stream in bytes.
- int64_t mLength;
-
- // Offset of first MP3 frame in the bitstream. Has value -1 until the
- // first MP3 frame is found.
- int64_t mMP3Offset;
-
- // The exact number of frames in this stream, if we know it. -1 otherwise.
- int64_t mNumFrames;
-
- // Number of audio samples per second and per frame. Fixed through the whole
- // file. If we know these variables as well as the number of frames in the
- // file, we can get an exact duration for the stream.
- uint16_t mSamplesPerSecond;
- uint16_t mSamplesPerFrame;
-
- // If the MP3 has a variable bitrate, then there *should* be metadata about
- // the encoding in the first frame. We buffer the first frame here.
- nsCString mFirstFrame;
-
- // While we are reading the first frame, this is the stream offset of the
- // last byte of that frame. -1 at all other times.
- int64_t mFirstFrameEnd;
-
- enum eIsMP3 {
- MAYBE_MP3, // We're giving the stream the benefit of the doubt...
- DEFINITELY_MP3, // We've hit at least one ID3 tag or MP3 frame.
- NOT_MP3 // Not found any evidence of the stream being MP3.
- };
-
- eIsMP3 mIsMP3;
-
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h
index a79aac6ed..905b4c1d9 100644
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -14,6 +14,7 @@
#include "nsIMemoryReporter.h"
#include "SharedBuffer.h"
#include "mozilla/RefPtr.h"
+#include "mozilla/Span.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsTArray.h"
@@ -631,6 +632,8 @@ public:
{
return sizeof(*this) + mBuffer.ComputedSizeOfExcludingThis();
}
+ // Access the buffer as a Span.
+ operator Span<const uint8_t>() { return MakeSpan(Data(), Size()); }
const CryptoSample& mCrypto;
RefPtr<MediaByteBuffer> mExtraData;
diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp
index 9334d1bcb..cf2266bf6 100644
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -35,10 +35,6 @@
#include "Layers.h"
#include "mozilla/layers/ShadowLayers.h"
-#ifdef MOZ_ANDROID_OMX
-#include "AndroidBridge.h"
-#endif
-
using namespace mozilla::dom;
using namespace mozilla::layers;
using namespace mozilla::media;
@@ -877,7 +873,6 @@ MediaDecoder::EnsureTelemetryReported()
}
for (const nsCString& codec : codecs) {
DECODER_LOG("Telemetry MEDIA_CODEC_USED= '%s'", codec.get());
- Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
}
mTelemetryReported = true;
@@ -1618,16 +1613,6 @@ MediaDecoder::IsWebMEnabled()
return Preferences::GetBool("media.webm.enabled");
}
-#ifdef MOZ_ANDROID_OMX
-bool
-MediaDecoder::IsAndroidMediaPluginEnabled()
-{
- return AndroidBridge::Bridge() &&
- AndroidBridge::Bridge()->GetAPIVersion() < 16 &&
- Preferences::GetBool("media.plugins.enabled");
-}
-#endif
-
NS_IMETHODIMP
MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h
index a4edcbe72..7e93de044 100644
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -447,10 +447,6 @@ private:
static bool IsWaveEnabled();
static bool IsWebMEnabled();
-#ifdef MOZ_ANDROID_OMX
- static bool IsAndroidMediaPluginEnabled();
-#endif
-
#ifdef MOZ_WMF
static bool IsWMFEnabled();
#endif
diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp
index c586139ad..5bc1d95ef 100644
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1178,40 +1178,7 @@ ReportRecoveryTelemetry(const TimeStamp& aRecoveryStart,
const MediaInfo& aMediaInfo,
bool aIsHardwareAccelerated)
{
- MOZ_ASSERT(NS_IsMainThread());
- if (!aMediaInfo.HasVideo()) {
- return;
- }
-
- // Keyed by audio+video or video alone, hardware acceleration,
- // and by a resolution range.
- nsCString key(aMediaInfo.HasAudio() ? "AV" : "V");
- key.AppendASCII(aIsHardwareAccelerated ? "(hw)," : ",");
- static const struct { int32_t mH; const char* mRes; } sResolutions[] = {
- { 240, "0-240" },
- { 480, "241-480" },
- { 720, "481-720" },
- { 1080, "721-1080" },
- { 2160, "1081-2160" }
- };
- const char* resolution = "2161+";
- int32_t height = aMediaInfo.mVideo.mImage.height;
- for (const auto& res : sResolutions) {
- if (height <= res.mH) {
- resolution = res.mRes;
- break;
- }
- }
- key.AppendASCII(resolution);
-
- TimeDuration duration = TimeStamp::Now() - aRecoveryStart;
- double duration_ms = duration.ToMilliseconds();
- Telemetry::Accumulate(Telemetry::VIDEO_SUSPEND_RECOVERY_TIME_MS,
- key,
- uint32_t(duration_ms + 0.5));
- Telemetry::Accumulate(Telemetry::VIDEO_SUSPEND_RECOVERY_TIME_MS,
- NS_LITERAL_CSTRING("All"),
- uint32_t(duration_ms + 0.5));
+/* STUB */
}
void
diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp
index 06e8b963b..773434710 100644
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -32,6 +32,10 @@ using mozilla::layers::Image;
using mozilla::layers::LayerManager;
using mozilla::layers::LayersBackend;
+// avoid redefined macro warning in unified builds
+#undef LOG
+#undef LOGV
+
static mozilla::LazyLogModule sFormatDecoderLog("MediaFormatReader");
mozilla::LazyLogModule gMediaDemuxerLog("MediaDemuxer");
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index ba6b4cd47..baaf45416 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -32,7 +32,6 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsIInputStream.h"
#include "nsILineInputStream.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Types.h"
#include "mozilla/PeerIdentity.h"
#include "mozilla/dom/ContentChild.h"
@@ -2058,28 +2057,6 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
host.LowerCaseEqualsLiteral("127.0.0.1") ||
host.LowerCaseEqualsLiteral("::1"));
- // Record telemetry about whether the source of the call was secure, i.e.,
- // privileged or HTTPS. We may handle other cases
-if (privileged) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Privileged);
- } else if (isHTTPS) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::HTTPS);
- } else if (isFile) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::File);
- } else if (isApp) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::App);
- } else if (isLocalhost) {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Localhost);
- } else {
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_SECURE_ORIGIN,
- (uint32_t) GetUserMediaSecurityState::Other);
- }
-
nsCString origin;
rv = nsPrincipal::GetOriginForURI(docURI, origin);
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -2098,8 +2075,6 @@ if (privileged) {
videoType = StringToEnum(dom::MediaSourceEnumValues::strings,
vc.mMediaSource,
MediaSourceEnum::Other);
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
- (uint32_t) videoType);
switch (videoType) {
case MediaSourceEnum::Camera:
break;
@@ -2182,8 +2157,6 @@ if (privileged) {
ac.mMediaSource.AssignASCII(EnumToASCII(dom::MediaSourceEnumValues::strings,
audioType));
}
- Telemetry::Accumulate(Telemetry::WEBRTC_GET_USER_MEDIA_TYPE,
- (uint32_t) audioType);
switch (audioType) {
case MediaSourceEnum::Microphone:
diff --git a/dom/media/MediaPrefs.h b/dom/media/MediaPrefs.h
index b237ecd3d..c67a89989 100644
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -105,9 +105,6 @@ private:
DECL_MEDIA_PREF("media.eme.enabled", EMEEnabled, bool, false);
DECL_MEDIA_PREF("media.use-blank-decoder", PDMUseBlankDecoder, bool, false);
DECL_MEDIA_PREF("media.gpu-process-decoder", PDMUseGPUDecoder, bool, false);
-#ifdef MOZ_GONK_MEDIACODEC
- DECL_MEDIA_PREF("media.gonk.enabled", PDMGonkDecoderEnabled, bool, true);
-#endif
#ifdef MOZ_WIDGET_ANDROID
DECL_MEDIA_PREF("media.android-media-codec.enabled", PDMAndroidMediaCodecEnabled, bool, false);
DECL_MEDIA_PREF("media.android-media-codec.preferred", PDMAndroidMediaCodecPreferred, bool, false);
@@ -120,6 +117,9 @@ private:
#ifdef MOZ_FFVPX
DECL_MEDIA_PREF("media.ffvpx.enabled", PDMFFVPXEnabled, bool, true);
#endif
+#ifdef MOZ_AV1
+ DECL_MEDIA_PREF("media.av1.enabled", AV1Enabled, bool, false);
+#endif
#ifdef XP_WIN
DECL_MEDIA_PREF("media.wmf.enabled", PDMWMFEnabled, bool, true);
DECL_MEDIA_PREF("media.wmf.skip-blacklist", PDMWMFSkipBlacklist, bool, false);
diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp
index e2934cbb2..1b9e4f674 100644
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -3371,7 +3371,8 @@ MediaStreamGraphImpl::Destroy()
// First unregister from memory reporting.
UnregisterWeakMemoryReporter(this);
- // Clear the self reference which will destroy this instance.
+ // Clear the self reference which will destroy this instance if all
+ // associated GraphDrivers are destroyed.
mSelfRef = nullptr;
}
diff --git a/dom/media/ThreadPoolCOMListener.h b/dom/media/ThreadPoolCOMListener.h
index 881013a78..424ca65d2 100644
--- a/dom/media/ThreadPoolCOMListener.h
+++ b/dom/media/ThreadPoolCOMListener.h
@@ -13,8 +13,8 @@
namespace mozilla {
// Thread pool listener which ensures that MSCOM is initialized and
-// deinitialized on the thread pool thread. We may call into WMF or
-// DirectShow on this thread, so we need MSCOM working.
+// deinitialized on the thread pool thread. We may call into WMF on
+// this thread, so we need MSCOM working.
class MSCOMInitThreadPoolListener final : public nsIThreadPoolListener {
~MSCOMInitThreadPoolListener() {}
public:
diff --git a/dom/media/VideoUtils.cpp b/dom/media/VideoUtils.cpp
index 5c00e54bc..c06ba9070 100644
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -6,7 +6,6 @@
#include "mozilla/Base64.h"
#include "mozilla/TaskQueue.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Function.h"
#include "MediaContentType.h"
@@ -208,8 +207,20 @@ already_AddRefed<SharedThreadPool> GetMediaThreadPool(MediaThreadType aType)
name = "MediaPlayback";
break;
}
- return SharedThreadPool::
+ RefPtr<SharedThreadPool> pool = SharedThreadPool::
Get(nsDependentCString(name), MediaPrefs::MediaThreadPoolDefaultCount());
+
+ // Ensure a larger stack for platform decoder threads
+ if (aType == MediaThreadType::PLATFORM_DECODER) {
+ const uint32_t minStackSize = 512*1024;
+ uint32_t stackSize;
+ MOZ_ALWAYS_SUCCEEDS(pool->GetThreadStackSize(&stackSize));
+ if (stackSize < minStackSize) {
+ MOZ_ALWAYS_SUCCEEDS(pool->SetThreadStackSize(minStackSize));
+ }
+ }
+
+ return pool.forget();
}
bool
@@ -248,24 +259,6 @@ ExtractH264CodecDetails(const nsAString& aCodec,
aLevel *= 10;
}
- // Capture the constraint_set flag value for the purpose of Telemetry.
- // We don't NS_ENSURE_SUCCESS here because ExtractH264CodecDetails doesn't
- // care about this, but we make sure constraints is above 4 (constraint_set5_flag)
- // otherwise collect 0 for unknown.
- uint8_t constraints = PromiseFlatString(Substring(aCodec, 7, 2)).ToInteger(&rv, 16);
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_CONSTRAINT_SET_FLAG,
- constraints >= 4 ? constraints : 0);
-
- // 244 is the highest meaningful profile value (High 4:4:4 Intra Profile)
- // that can be represented as single hex byte, otherwise collect 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_PROFILE,
- aProfile <= 244 ? aProfile : 0);
-
- // Make sure aLevel represents a value between levels 1 and 5.2,
- // otherwise collect 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_CANPLAYTYPE_H264_LEVEL,
- (aLevel >= 10 && aLevel <= 52) ? aLevel : 0);
-
return true;
}
@@ -445,6 +438,16 @@ ParseMIMETypeString(const nsAString& aMIMEType,
return ParseCodecsString(codecsStr, aOutCodecs);
}
+template <int N>
+static bool
+StartsWith(const nsACString& string, const char (&prefix)[N])
+{
+ if (N - 1 > string.Length()) {
+ return false;
+ }
+ return memcmp(string.Data(), prefix, N - 1) == 0;
+}
+
bool
IsH264CodecString(const nsAString& aCodec)
{
@@ -477,15 +480,14 @@ IsVP9CodecString(const nsAString& aCodec)
aCodec.EqualsLiteral("vp9.0");
}
-template <int N>
-static bool
-StartsWith(const nsACString& string, const char (&prefix)[N])
+#ifdef MOZ_AV1
+bool
+IsAV1CodecString(const nsAString& aCodec)
{
- if (N - 1 > string.Length()) {
- return false;
- }
- return memcmp(string.Data(), prefix, N - 1) == 0;
+ return aCodec.EqualsLiteral("av1") ||
+ StartsWith(NS_ConvertUTF16toUTF8(aCodec), "av01");
}
+#endif
UniquePtr<TrackInfo>
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType)
diff --git a/dom/media/VideoUtils.h b/dom/media/VideoUtils.h
index 441b63792..aaf0e9903 100644
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -345,6 +345,11 @@ IsVP8CodecString(const nsAString& aCodec);
bool
IsVP9CodecString(const nsAString& aCodec);
+#ifdef MOZ_AV1
+bool
+IsAV1CodecString(const nsAString& aCodec);
+#endif
+
// Try and create a TrackInfo with a given codec MIME type.
UniquePtr<TrackInfo>
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType);
diff --git a/dom/media/WebVTTListener.h b/dom/media/WebVTTListener.h
index 67271664a..461d7f00d 100644
--- a/dom/media/WebVTTListener.h
+++ b/dom/media/WebVTTListener.h
@@ -10,6 +10,7 @@
#include "nsIStreamListener.h"
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
+#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsIWebVTTParserWrapper;
diff --git a/dom/media/android/AndroidMediaDecoder.cpp b/dom/media/android/AndroidMediaDecoder.cpp
deleted file mode 100644
index 41ef3fcb0..000000000
--- a/dom/media/android/AndroidMediaDecoder.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "MediaDecoderStateMachine.h"
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaReader.h"
-
-namespace mozilla {
-
-AndroidMediaDecoder::AndroidMediaDecoder(MediaDecoderOwner* aOwner,
- const nsACString& aType)
- : MediaDecoder(aOwner), mType(aType)
-{
-}
-
-MediaDecoderStateMachine* AndroidMediaDecoder::CreateStateMachine()
-{
- return new MediaDecoderStateMachine(this, new AndroidMediaReader(this, mType));
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/android/AndroidMediaDecoder.h b/dom/media/android/AndroidMediaDecoder.h
deleted file mode 100644
index 88b5a243f..000000000
--- a/dom/media/android/AndroidMediaDecoder.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaDecoder_h_)
-#define AndroidMediaDecoder_h_
-
-#include "MediaDecoder.h"
-#include "AndroidMediaDecoder.h"
-
-namespace mozilla {
-
-class AndroidMediaDecoder : public MediaDecoder
-{
- nsCString mType;
-public:
- AndroidMediaDecoder(MediaDecoderOwner* aOwner, const nsACString& aType);
-
- MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
- return new AndroidMediaDecoder(aOwner, mType);
- }
- MediaDecoderStateMachine* CreateStateMachine() override;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaPluginHost.cpp b/dom/media/android/AndroidMediaPluginHost.cpp
deleted file mode 100644
index d4c4fc59e..000000000
--- a/dom/media/android/AndroidMediaPluginHost.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "mozilla/Preferences.h"
-#include "MediaResource.h"
-#include "mozilla/dom/HTMLMediaElement.h"
-#include "mozilla/Services.h"
-#include "AndroidMediaPluginHost.h"
-#include "nsAutoPtr.h"
-#include "nsXPCOMStrings.h"
-#include "nsISeekableStream.h"
-#include "nsIGfxInfo.h"
-#include "prmem.h"
-#include "prlink.h"
-#include "AndroidMediaResourceServer.h"
-#include "nsServiceManagerUtils.h"
-
-#include "MPAPI.h"
-
-#include "nsIPropertyBag2.h"
-
-#if defined(ANDROID)
-#include "android/log.h"
-#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidMediaPluginHost" , ## args)
-#else
-#define ALOG(args...) /* do nothing */
-#endif
-
-using namespace MPAPI;
-
-Decoder::Decoder() :
- mResource(nullptr), mPrivate(nullptr)
-{
-}
-
-namespace mozilla {
-
-static char* GetResource(Decoder *aDecoder)
-{
- return static_cast<char*>(aDecoder->mResource);
-}
-
-class GetIntPrefEvent : public Runnable {
-public:
- GetIntPrefEvent(const char* aPref, int32_t* aResult)
- : mPref(aPref), mResult(aResult) {}
- NS_IMETHOD Run() override {
- return Preferences::GetInt(mPref, mResult);
- }
-private:
- const char* mPref;
- int32_t* mResult;
-};
-
-static bool GetIntPref(const char* aPref, int32_t* aResult)
-{
- // GetIntPref() is called on the decoder thread, but the Preferences API
- // can only be called on the main thread. Post a runnable and wait.
- NS_ENSURE_TRUE(aPref, false);
- NS_ENSURE_TRUE(aResult, false);
- nsCOMPtr<nsIRunnable> event = new GetIntPrefEvent(aPref, aResult);
- return NS_SUCCEEDED(NS_DispatchToMainThread(event, NS_DISPATCH_SYNC));
-}
-
-static bool
-GetSystemInfoString(const char *aKey, char *aResult, size_t aResultLength)
-{
- NS_ENSURE_TRUE(aKey, false);
- NS_ENSURE_TRUE(aResult, false);
-
- nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
- NS_ASSERTION(infoService, "Could not find a system info service");
-
- nsAutoCString key(aKey);
- nsAutoCString info;
- nsresult rv = infoService->GetPropertyAsACString(NS_ConvertUTF8toUTF16(key),
- info);
-
- NS_ENSURE_SUCCESS(rv, false);
-
- strncpy(aResult, info.get(), aResultLength);
-
- return true;
-}
-
-static PluginHost sPluginHost = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- GetIntPref,
- GetSystemInfoString
-};
-
-// Return true if Omx decoding is supported on the device. This checks the
-// built in whitelist/blacklist and preferences to see if that is overridden.
-static bool IsOmxSupported()
-{
- bool forceEnabled =
- Preferences::GetBool("stagefright.force-enabled", false);
- bool disabled =
- Preferences::GetBool("stagefright.disabled", false);
-
- if (disabled) {
- NS_WARNING("XXX stagefright disabled\n");
- return false;
- }
-
- if (!forceEnabled) {
- nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
- if (gfxInfo) {
- int32_t status;
- nsCString discardFailure;
- if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, discardFailure, &status))) {
- if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
- NS_WARNING("XXX stagefright blacklisted\n");
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-// Return the name of the shared library that implements Omx based decoding. This varies
-// depending on libstagefright version installed on the device and whether it is B2G vs Android.
-// nullptr is returned if Omx decoding is not supported on the device,
-static const char* GetOmxLibraryName()
-{
-#if defined(ANDROID)
- nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
- NS_ASSERTION(infoService, "Could not find a system info service");
-
- int32_t version;
- nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("version"), &version);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Version is: %d", version);
- }
-
- nsAutoString release_version;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("release_version"), release_version);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Release Version is: %s", NS_LossyConvertUTF16toASCII(release_version).get());
- }
-
- nsAutoString device;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"), device);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Device is: %s", NS_LossyConvertUTF16toASCII(device).get());
- }
-
- nsAutoString manufacturer;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("manufacturer"), manufacturer);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Manufacturer is: %s", NS_LossyConvertUTF16toASCII(manufacturer).get());
- }
-
- nsAutoString hardware;
- rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("hardware"), hardware);
- if (NS_SUCCEEDED(rv)) {
- ALOG("Android Hardware is: %s", NS_LossyConvertUTF16toASCII(hardware).get());
- }
-#endif
-
- if (!IsOmxSupported())
- return nullptr;
-
-#if defined(ANDROID)
- if (version >= 17) {
- return "libomxpluginkk.so";
- }
-
- // Ice Cream Sandwich and Jellybean
- return "libomxplugin.so";
-
-#else
- return nullptr;
-#endif
-}
-
-AndroidMediaPluginHost::AndroidMediaPluginHost() {
- MOZ_COUNT_CTOR(AndroidMediaPluginHost);
- MOZ_ASSERT(NS_IsMainThread());
-
- mResourceServer = AndroidMediaResourceServer::Start();
-
- const char* name = GetOmxLibraryName();
- ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
- if (name) {
- char *path = PR_GetLibraryFilePathname("libxul.so", (PRFuncPtr) GetOmxLibraryName);
- PRLibrary *lib = nullptr;
- if (path) {
- nsAutoCString libpath(path);
- PR_Free(path);
- int32_t slash = libpath.RFindChar('/');
- if (slash != kNotFound) {
- libpath.Truncate(slash + 1);
- libpath.Append(name);
- lib = PR_LoadLibrary(libpath.get());
- }
- }
- if (!lib)
- lib = PR_LoadLibrary(name);
-
- if (lib) {
- Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
- if (manifest) {
- mPlugins.AppendElement(manifest);
- ALOG("OMX plugin successfully loaded");
- }
- }
- }
-}
-
-AndroidMediaPluginHost::~AndroidMediaPluginHost() {
- mResourceServer->Stop();
- MOZ_COUNT_DTOR(AndroidMediaPluginHost);
-}
-
-bool AndroidMediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const** aCodecs)
-{
- const char *chars;
- size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
- for (size_t n = 0; n < mPlugins.Length(); ++n) {
- Manifest *plugin = mPlugins[n];
- const char* const *codecs;
- if (plugin->CanDecode(chars, len, &codecs)) {
- if (aCodecs)
- *aCodecs = codecs;
- return true;
- }
- }
- return false;
-}
-
-MPAPI::Decoder *AndroidMediaPluginHost::CreateDecoder(MediaResource *aResource, const nsACString& aMimeType)
-{
- NS_ENSURE_TRUE(aResource, nullptr);
-
- nsAutoPtr<Decoder> decoder(new Decoder());
- if (!decoder) {
- return nullptr;
- }
-
- const char *chars;
- size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
- for (size_t n = 0; n < mPlugins.Length(); ++n) {
- Manifest *plugin = mPlugins[n];
- const char* const *codecs;
- if (!plugin->CanDecode(chars, len, &codecs)) {
- continue;
- }
-
- nsCString url;
- nsresult rv = mResourceServer->AddResource(aResource, url);
- if (NS_FAILED (rv)) continue;
-
- decoder->mResource = strdup(url.get());
- if (plugin->CreateDecoder(&sPluginHost, decoder, chars, len)) {
- return decoder.forget();
- }
- }
-
- return nullptr;
-}
-
-void AndroidMediaPluginHost::DestroyDecoder(Decoder *aDecoder)
-{
- aDecoder->DestroyDecoder(aDecoder);
- char* resource = GetResource(aDecoder);
- if (resource) {
- // resource *shouldn't* be null, but check anyway just in case the plugin
- // decoder does something stupid.
- mResourceServer->RemoveResource(nsCString(resource));
- free(resource);
- }
- delete aDecoder;
-}
-
-AndroidMediaPluginHost *sAndroidMediaPluginHost = nullptr;
-AndroidMediaPluginHost *EnsureAndroidMediaPluginHost()
-{
- MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
- if (!sAndroidMediaPluginHost) {
- sAndroidMediaPluginHost = new AndroidMediaPluginHost();
- }
- return sAndroidMediaPluginHost;
-}
-
-AndroidMediaPluginHost *GetAndroidMediaPluginHost()
-{
- MOZ_ASSERT(sAndroidMediaPluginHost);
- return sAndroidMediaPluginHost;
-}
-
-void AndroidMediaPluginHost::Shutdown()
-{
- delete sAndroidMediaPluginHost;
- sAndroidMediaPluginHost = nullptr;
-}
-
-} // namespace mozilla
diff --git a/dom/media/android/AndroidMediaPluginHost.h b/dom/media/android/AndroidMediaPluginHost.h
deleted file mode 100644
index 854b7f21e..000000000
--- a/dom/media/android/AndroidMediaPluginHost.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaPluginHost_h_)
-#define AndroidMediaPluginHost_h_
-
-#include "nsTArray.h"
-#include "MediaResource.h"
-#include "MPAPI.h"
-#include "AndroidMediaResourceServer.h"
-
-namespace mozilla {
-
-class AndroidMediaPluginHost {
- RefPtr<AndroidMediaResourceServer> mResourceServer;
- nsTArray<MPAPI::Manifest *> mPlugins;
-
- MPAPI::Manifest *FindPlugin(const nsACString& aMimeType);
-public:
- AndroidMediaPluginHost();
- ~AndroidMediaPluginHost();
-
- static void Shutdown();
-
- bool FindDecoder(const nsACString& aMimeType, const char* const** aCodecs);
- MPAPI::Decoder *CreateDecoder(mozilla::MediaResource *aResource, const nsACString& aMimeType);
- void DestroyDecoder(MPAPI::Decoder *aDecoder);
-};
-
-// Must be called on the main thread. Creates the plugin host if it doesn't
-// already exist.
-AndroidMediaPluginHost *EnsureAndroidMediaPluginHost();
-
-// May be called on any thread after EnsureAndroidMediaPluginHost has been called.
-AndroidMediaPluginHost *GetAndroidMediaPluginHost();
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaReader.cpp b/dom/media/android/AndroidMediaReader.cpp
deleted file mode 100644
index 12afacbc9..000000000
--- a/dom/media/android/AndroidMediaReader.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "AndroidMediaReader.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/gfx/Point.h"
-#include "MediaResource.h"
-#include "VideoUtils.h"
-#include "AndroidMediaDecoder.h"
-#include "AndroidMediaPluginHost.h"
-#include "MediaDecoderStateMachine.h"
-#include "ImageContainer.h"
-#include "AbstractMediaDecoder.h"
-#include "gfx2DGlue.h"
-#include "VideoFrameContainer.h"
-#include "mozilla/CheckedInt.h"
-
-namespace mozilla {
-
-using namespace mozilla::gfx;
-using namespace mozilla::media;
-
-typedef mozilla::layers::Image Image;
-typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
-
-AndroidMediaReader::AndroidMediaReader(AbstractMediaDecoder *aDecoder,
- const nsACString& aContentType) :
- MediaDecoderReader(aDecoder),
- mType(aContentType),
- mPlugin(nullptr),
- mHasAudio(false),
- mHasVideo(false),
- mVideoSeekTimeUs(-1),
- mAudioSeekTimeUs(-1)
-{
-}
-
-nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- if (!mPlugin) {
- mPlugin = GetAndroidMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
- if (!mPlugin) {
- return NS_ERROR_FAILURE;
- }
- }
-
- // Set the total duration (the max of the audio and video track).
- int64_t durationUs;
- mPlugin->GetDuration(mPlugin, &durationUs);
- if (durationUs) {
- mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(durationUs));
- }
-
- if (mPlugin->HasVideo(mPlugin)) {
- int32_t width, height;
- mPlugin->GetVideoParameters(mPlugin, &width, &height);
- nsIntRect pictureRect(0, 0, width, height);
-
- // Validate the container-reported frame and pictureRect sizes. This ensures
- // that our video frame creation code doesn't overflow.
- nsIntSize displaySize(width, height);
- nsIntSize frameSize(width, height);
- if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
- return NS_ERROR_FAILURE;
- }
-
- // Video track's frame sizes will not overflow. Activate the video track.
- mHasVideo = true;
- mInfo.mVideo.mDisplay = displaySize;
- mPicture = pictureRect;
- mInitialFrame = frameSize;
- VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
- if (container) {
- container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height));
- }
- }
-
- if (mPlugin->HasAudio(mPlugin)) {
- int32_t numChannels, sampleRate;
- mPlugin->GetAudioParameters(mPlugin, &numChannels, &sampleRate);
- mHasAudio = true;
- mInfo.mAudio.mChannels = numChannels;
- mInfo.mAudio.mRate = sampleRate;
- }
-
- *aInfo = mInfo;
- *aTags = nullptr;
- return NS_OK;
-}
-
-RefPtr<ShutdownPromise>
-AndroidMediaReader::Shutdown()
-{
- ResetDecode();
- if (mPlugin) {
- GetAndroidMediaPluginHost()->DestroyDecoder(mPlugin);
- mPlugin = nullptr;
- }
-
- return MediaDecoderReader::Shutdown();
-}
-
-// Resets all state related to decoding, emptying all buffers etc.
-nsresult AndroidMediaReader::ResetDecode(TrackSet aTracks)
-{
- if (mLastVideoFrame) {
- mLastVideoFrame = nullptr;
- }
- mSeekRequest.DisconnectIfExists();
- mSeekPromise.RejectIfExists(NS_OK, __func__);
- return MediaDecoderReader::ResetDecode(aTracks);
-}
-
-bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold)
-{
- // Record number of frames decoded and parsed. Automatically update the
- // stats counters using the AutoNotifyDecoded stack-based class.
- AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
-
- // Throw away the currently buffered frame if we are seeking.
- if (mLastVideoFrame && mVideoSeekTimeUs != -1) {
- mLastVideoFrame = nullptr;
- }
-
- ImageBufferCallback bufferCallback(mDecoder->GetImageContainer());
- RefPtr<Image> currentImage;
-
- // Read next frame
- while (true) {
- MPAPI::VideoFrame frame;
- if (!mPlugin->ReadVideo(mPlugin, &frame, mVideoSeekTimeUs, &bufferCallback)) {
- // We reached the end of the video stream. If we have a buffered
- // video frame, push it the video queue using the total duration
- // of the video as the end time.
- if (mLastVideoFrame) {
- int64_t durationUs;
- mPlugin->GetDuration(mPlugin, &durationUs);
- durationUs = std::max<int64_t>(durationUs - mLastVideoFrame->mTime, 0);
- RefPtr<VideoData> data = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame,
- durationUs);
- mVideoQueue.Push(data);
- mLastVideoFrame = nullptr;
- }
- return false;
- }
- mVideoSeekTimeUs = -1;
-
- if (aKeyframeSkip) {
- // Disable keyframe skipping for now as
- // stagefright doesn't seem to be telling us
- // when a frame is a keyframe.
-#if 0
- if (!frame.mKeyFrame) {
- ++a.mStats.mParsedFrames;
- ++a.mStats.mDroppedFrames;
- continue;
- }
-#endif
- aKeyframeSkip = false;
- }
-
- if (frame.mSize == 0)
- return true;
-
- currentImage = bufferCallback.GetImage();
- int64_t pos = mDecoder->GetResource()->Tell();
- IntRect picture = mPicture;
-
- RefPtr<VideoData> v;
- if (currentImage) {
- gfx::IntSize frameSize = currentImage->GetSize();
- if (frameSize.width != mInitialFrame.width ||
- frameSize.height != mInitialFrame.height) {
- // Frame size is different from what the container reports. This is legal,
- // and we will preserve the ratio of the crop rectangle as it
- // was reported relative to the picture size reported by the container.
- picture.x = (mPicture.x * frameSize.width) / mInitialFrame.width;
- picture.y = (mPicture.y * frameSize.height) / mInitialFrame.height;
- picture.width = (frameSize.width * mPicture.width) / mInitialFrame.width;
- picture.height = (frameSize.height * mPicture.height) / mInitialFrame.height;
- }
-
- v = VideoData::CreateFromImage(mInfo.mVideo,
- pos,
- frame.mTimeUs,
- 1, // We don't know the duration yet.
- currentImage,
- frame.mKeyFrame,
- -1,
- picture);
- } else {
- // Assume YUV
- VideoData::YCbCrBuffer b;
- b.mPlanes[0].mData = static_cast<uint8_t *>(frame.Y.mData);
- b.mPlanes[0].mStride = frame.Y.mStride;
- b.mPlanes[0].mHeight = frame.Y.mHeight;
- b.mPlanes[0].mWidth = frame.Y.mWidth;
- b.mPlanes[0].mOffset = frame.Y.mOffset;
- b.mPlanes[0].mSkip = frame.Y.mSkip;
-
- b.mPlanes[1].mData = static_cast<uint8_t *>(frame.Cb.mData);
- b.mPlanes[1].mStride = frame.Cb.mStride;
- b.mPlanes[1].mHeight = frame.Cb.mHeight;
- b.mPlanes[1].mWidth = frame.Cb.mWidth;
- b.mPlanes[1].mOffset = frame.Cb.mOffset;
- b.mPlanes[1].mSkip = frame.Cb.mSkip;
-
- b.mPlanes[2].mData = static_cast<uint8_t *>(frame.Cr.mData);
- b.mPlanes[2].mStride = frame.Cr.mStride;
- b.mPlanes[2].mHeight = frame.Cr.mHeight;
- b.mPlanes[2].mWidth = frame.Cr.mWidth;
- b.mPlanes[2].mOffset = frame.Cr.mOffset;
- b.mPlanes[2].mSkip = frame.Cr.mSkip;
-
- if (frame.Y.mWidth != mInitialFrame.width ||
- frame.Y.mHeight != mInitialFrame.height) {
-
- // Frame size is different from what the container reports. This is legal,
- // and we will preserve the ratio of the crop rectangle as it
- // was reported relative to the picture size reported by the container.
- picture.x = (mPicture.x * frame.Y.mWidth) / mInitialFrame.width;
- picture.y = (mPicture.y * frame.Y.mHeight) / mInitialFrame.height;
- picture.width = (frame.Y.mWidth * mPicture.width) / mInitialFrame.width;
- picture.height = (frame.Y.mHeight * mPicture.height) / mInitialFrame.height;
- }
-
- // This is the approximate byte position in the stream.
- v = VideoData::CreateAndCopyData(mInfo.mVideo,
- mDecoder->GetImageContainer(),
- pos,
- frame.mTimeUs,
- 1, // We don't know the duration yet.
- b,
- frame.mKeyFrame,
- -1,
- picture);
- }
-
- if (!v) {
- return false;
- }
- a.mStats.mParsedFrames++;
- a.mStats.mDecodedFrames++;
- NS_ASSERTION(a.mStats.mDecodedFrames <= a.mStats.mParsedFrames, "Expect to decode fewer frames than parsed in AndroidMedia...");
-
- // Since MPAPI doesn't give us the end time of frames, we keep one frame
- // buffered in AndroidMediaReader and push it into the queue as soon
- // we read the following frame so we can use that frame's start time as
- // the end time of the buffered frame.
- if (!mLastVideoFrame) {
- mLastVideoFrame = v;
- continue;
- }
-
- // Calculate the duration as the timestamp of the current frame minus the
- // timestamp of the previous frame. We can then return the previously
- // decoded frame, and it will have a valid timestamp.
- int64_t duration = v->mTime - mLastVideoFrame->mTime;
- mLastVideoFrame = VideoData::ShallowCopyUpdateDuration(mLastVideoFrame, duration);
-
- // We have the start time of the next frame, so we can push the previous
- // frame into the queue, except if the end time is below the threshold,
- // in which case it wouldn't be displayed anyway.
- if (mLastVideoFrame->GetEndTime() < aTimeThreshold) {
- mLastVideoFrame = nullptr;
- continue;
- }
-
- // Buffer the current frame we just decoded.
- mVideoQueue.Push(mLastVideoFrame);
- mLastVideoFrame = v;
-
- break;
- }
-
- return true;
-}
-
-bool AndroidMediaReader::DecodeAudioData()
-{
- MOZ_ASSERT(OnTaskQueue());
-
- // This is the approximate byte position in the stream.
- int64_t pos = mDecoder->GetResource()->Tell();
-
- // Read next frame
- MPAPI::AudioFrame source;
- if (!mPlugin->ReadAudio(mPlugin, &source, mAudioSeekTimeUs)) {
- return false;
- }
- mAudioSeekTimeUs = -1;
-
- // Ignore empty buffers which stagefright media read will sporadically return
- if (source.mSize == 0)
- return true;
-
- uint32_t frames = source.mSize / (source.mAudioChannels *
- sizeof(AudioDataValue));
-
- typedef AudioCompactor::NativeCopy MPCopy;
- return mAudioCompactor.Push(pos,
- source.mTimeUs,
- source.mAudioSampleRate,
- frames,
- source.mAudioChannels,
- MPCopy(static_cast<uint8_t *>(source.mData),
- source.mSize,
- source.mAudioChannels));
-}
-
-RefPtr<MediaDecoderReader::SeekPromise>
-AndroidMediaReader::Seek(SeekTarget aTarget, int64_t aEndTime)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
- if (mHasAudio && mHasVideo) {
- // The decoder seeks/demuxes audio and video streams separately. So if
- // we seek both audio and video to aTarget, the audio stream can typically
- // seek closer to the seek target, since typically every audio block is
- // a sync point, whereas for video there are only keyframes once every few
- // seconds. So if we have both audio and video, we must seek the video
- // stream to the preceeding keyframe first, get the stream time, and then
- // seek the audio stream to match the video stream's time. Otherwise, the
- // audio and video streams won't be in sync after the seek.
- mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
-
- RefPtr<AndroidMediaReader> self = this;
- mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
- self->mSeekRequest.Complete();
- self->mAudioSeekTimeUs = v->mTime;
- self->mSeekPromise.Resolve(media::TimeUnit::FromMicroseconds(self->mAudioSeekTimeUs), __func__);
- }, [self, aTarget] () {
- self->mSeekRequest.Complete();
- self->mAudioSeekTimeUs = aTarget.GetTime().ToMicroseconds();
- self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
- }));
- } else {
- mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
- mSeekPromise.Resolve(aTarget.GetTime(), __func__);
- }
-
- return p;
-}
-
-AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
- mImageContainer(aImageContainer)
-{
-}
-
-void *
-AndroidMediaReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight,
- MPAPI::ColorFormat aColorFormat)
-{
- if (!mImageContainer) {
- NS_WARNING("No image container to construct an image");
- return nullptr;
- }
-
- RefPtr<Image> image;
- switch(aColorFormat) {
- case MPAPI::RGB565:
- image = mozilla::layers::CreateSharedRGBImage(mImageContainer,
- nsIntSize(aWidth, aHeight),
- SurfaceFormat::R5G6B5_UINT16);
- if (!image) {
- NS_WARNING("Could not create rgb image");
- return nullptr;
- }
-
- mImage = image;
- return image->GetBuffer();
- case MPAPI::I420:
- return CreateI420Image(aWidth, aHeight);
- default:
- NS_NOTREACHED("Color format not supported");
- return nullptr;
- }
-}
-
-uint8_t *
-AndroidMediaReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
- size_t aHeight)
-{
- RefPtr<PlanarYCbCrImage> yuvImage = mImageContainer->CreatePlanarYCbCrImage();
- mImage = yuvImage;
-
- if (!yuvImage) {
- NS_WARNING("Could not create I420 image");
- return nullptr;
- }
-
- // Use uint32_t throughout to match AllocateAndGetNewBuffer's param
- const auto checkedFrameSize =
- CheckedInt<uint32_t>(aWidth) * aHeight;
-
- // Allocate enough for one full resolution Y plane
- // and two quarter resolution Cb/Cr planes.
- const auto checkedBufferSize =
- checkedFrameSize + checkedFrameSize / 2;
-
- if (!checkedBufferSize.isValid()) { // checks checkedFrameSize too
- NS_WARNING("Could not create I420 image");
- return nullptr;
- }
-
- const auto frameSize = checkedFrameSize.value();
-
- uint8_t *buffer =
- yuvImage->AllocateAndGetNewBuffer(checkedBufferSize.value());
-
- mozilla::layers::PlanarYCbCrData frameDesc;
-
- frameDesc.mYChannel = buffer;
- frameDesc.mCbChannel = buffer + frameSize;
- frameDesc.mCrChannel = frameDesc.mCbChannel + frameSize / 4;
-
- frameDesc.mYSize = IntSize(aWidth, aHeight);
- frameDesc.mCbCrSize = IntSize(aWidth / 2, aHeight / 2);
-
- frameDesc.mYStride = aWidth;
- frameDesc.mCbCrStride = aWidth / 2;
-
- frameDesc.mYSkip = 0;
- frameDesc.mCbSkip = 0;
- frameDesc.mCrSkip = 0;
-
- frameDesc.mPicX = 0;
- frameDesc.mPicY = 0;
- frameDesc.mPicSize = IntSize(aWidth, aHeight);
-
- yuvImage->AdoptData(frameDesc);
-
- return buffer;
-}
-
-already_AddRefed<Image>
-AndroidMediaReader::ImageBufferCallback::GetImage()
-{
- return mImage.forget();
-}
-
-} // namespace mozilla
diff --git a/dom/media/android/AndroidMediaReader.h b/dom/media/android/AndroidMediaReader.h
deleted file mode 100644
index def85a343..000000000
--- a/dom/media/android/AndroidMediaReader.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaReader_h_)
-#define AndroidMediaReader_h_
-
-#include "mozilla/Attributes.h"
-#include "MediaResource.h"
-#include "MediaDecoderReader.h"
-#include "ImageContainer.h"
-#include "mozilla/layers/SharedRGBImage.h"
-
-#include "MPAPI.h"
-
-class nsACString;
-
-namespace mozilla {
-
-class AbstractMediaDecoder;
-
-namespace layers {
-class ImageContainer;
-}
-
-class AndroidMediaReader : public MediaDecoderReader
-{
- nsCString mType;
- MPAPI::Decoder *mPlugin;
- bool mHasAudio;
- bool mHasVideo;
- nsIntRect mPicture;
- nsIntSize mInitialFrame;
- int64_t mVideoSeekTimeUs;
- int64_t mAudioSeekTimeUs;
- RefPtr<VideoData> mLastVideoFrame;
- MozPromiseHolder<MediaDecoderReader::SeekPromise> mSeekPromise;
- MozPromiseRequestHolder<MediaDecoderReader::MediaDataPromise> mSeekRequest;
-public:
- AndroidMediaReader(AbstractMediaDecoder* aDecoder,
- const nsACString& aContentType);
-
- nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
- TrackInfo::kVideoTrack)) override;
-
- bool DecodeAudioData() override;
- bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
-
- nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
- RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) override;
-
- RefPtr<ShutdownPromise> Shutdown() override;
-
- class ImageBufferCallback : public MPAPI::BufferCallback {
- typedef mozilla::layers::Image Image;
-
- public:
- ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer);
- void *operator()(size_t aWidth, size_t aHeight,
- MPAPI::ColorFormat aColorFormat) override;
- already_AddRefed<Image> GetImage();
-
- private:
- uint8_t *CreateI420Image(size_t aWidth, size_t aHeight);
-
- mozilla::layers::ImageContainer *mImageContainer;
- RefPtr<Image> mImage;
- };
-
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/AndroidMediaResourceServer.cpp b/dom/media/android/AndroidMediaResourceServer.cpp
deleted file mode 100644
index bd76a8c68..000000000
--- a/dom/media/android/AndroidMediaResourceServer.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "mozilla/Assertions.h"
-#include "mozilla/Base64.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#include "mozilla/UniquePtr.h"
-#include "nsThreadUtils.h"
-#include "nsIServiceManager.h"
-#include "nsISocketTransport.h"
-#include "nsIOutputStream.h"
-#include "nsIInputStream.h"
-#include "nsIRandomGenerator.h"
-#include "nsReadLine.h"
-#include "nsNetCID.h"
-#include "VideoUtils.h"
-#include "MediaResource.h"
-#include "AndroidMediaResourceServer.h"
-
-#if defined(_MSC_VER)
-#define strtoll _strtoi64
-#endif
-
-using namespace mozilla;
-
-/*
- ReadCRLF is a variant of NS_ReadLine from nsReadLine.h that deals
- with the carriage return/line feed requirements of HTTP requests.
-*/
-template<typename CharT, class StreamType, class StringType>
-nsresult
-ReadCRLF (StreamType* aStream, nsLineBuffer<CharT> * aBuffer,
- StringType & aLine, bool *aMore)
-{
- // eollast is true if the last character in the buffer is a '\r',
- // signaling a potential '\r\n' sequence split between reads.
- bool eollast = false;
-
- aLine.Truncate();
-
- while (1) { // will be returning out of this loop on eol or eof
- if (aBuffer->start == aBuffer->end) { // buffer is empty. Read into it.
- uint32_t bytesRead;
- nsresult rv = aStream->Read(aBuffer->buf, kLineBufferSize, &bytesRead);
- if (NS_FAILED(rv) || bytesRead == 0) {
- *aMore = false;
- return rv;
- }
- aBuffer->start = aBuffer->buf;
- aBuffer->end = aBuffer->buf + bytesRead;
- *(aBuffer->end) = '\0';
- }
-
- /*
- * Walk the buffer looking for an end-of-line.
- * There are 4 cases to consider:
- * 1. the CR char is the last char in the buffer
- * 2. the CRLF sequence are the last characters in the buffer
- * 3. the CRLF sequence + one or more chars at the end of the buffer
- * we need at least one char after the first CRLF sequence to
- * set |aMore| correctly.
- * 4. The LF character is the first char in the buffer when eollast is
- * true.
- */
- CharT* current = aBuffer->start;
- if (eollast) { // Case 4
- if (*current == '\n') {
- aBuffer->start = ++current;
- *aMore = true;
- return NS_OK;
- }
- else {
- eollast = false;
- aLine.Append('\r');
- }
- }
- // Cases 2 and 3
- for ( ; current < aBuffer->end-1; ++current) {
- if (*current == '\r' && *(current+1) == '\n') {
- *current++ = '\0';
- *current++ = '\0';
- aLine.Append(aBuffer->start);
- aBuffer->start = current;
- *aMore = true;
- return NS_OK;
- }
- }
- // Case 1
- if (*current == '\r') {
- eollast = true;
- *current++ = '\0';
- }
-
- aLine.Append(aBuffer->start);
- aBuffer->start = aBuffer->end; // mark the buffer empty
- }
-}
-
-// Each client HTTP request results in a thread being spawned to process it.
-// That thread has a single event dispatched to it which handles the HTTP
-// protocol. It parses the headers and forwards data from the MediaResource
-// associated with the URL back to client. When the request is complete it will
-// shutdown the thread.
-class ServeResourceEvent : public Runnable {
-private:
- // Reading from this reads the data sent from the client.
- nsCOMPtr<nsIInputStream> mInput;
-
- // Writing to this sends data to the client.
- nsCOMPtr<nsIOutputStream> mOutput;
-
- // The AndroidMediaResourceServer that owns the MediaResource instances
- // served. This is used to lookup the MediaResource from the URL.
- RefPtr<AndroidMediaResourceServer> mServer;
-
- // Write 'aBufferLength' bytes from 'aBuffer' to 'mOutput'. This
- // method ensures all the data is written by checking the number
- // of bytes returned from the output streams 'Write' method and
- // looping until done.
- nsresult WriteAll(char const* aBuffer, int32_t aBufferLength);
-
-public:
- ServeResourceEvent(nsIInputStream* aInput, nsIOutputStream* aOutput,
- AndroidMediaResourceServer* aServer)
- : mInput(aInput), mOutput(aOutput), mServer(aServer) {}
-
- // This method runs on the thread and exits when it has completed the
- // HTTP request.
- NS_IMETHOD Run();
-
- // Given the first line of an HTTP request, parse the URL requested and
- // return the MediaResource for that URL.
- already_AddRefed<MediaResource> GetMediaResource(nsCString const& aHTTPRequest);
-
- // Gracefully shutdown the thread and cleanup resources
- void Shutdown();
-};
-
-nsresult
-ServeResourceEvent::WriteAll(char const* aBuffer, int32_t aBufferLength)
-{
- while (aBufferLength > 0) {
- uint32_t written = 0;
- nsresult rv = mOutput->Write(aBuffer, aBufferLength, &written);
- if (NS_FAILED (rv)) return rv;
-
- aBufferLength -= written;
- aBuffer += written;
- }
-
- return NS_OK;
-}
-
-already_AddRefed<MediaResource>
-ServeResourceEvent::GetMediaResource(nsCString const& aHTTPRequest)
-{
- // Check that the HTTP method is GET
- const char* HTTP_METHOD = "GET ";
- if (strncmp(aHTTPRequest.get(), HTTP_METHOD, strlen(HTTP_METHOD)) != 0) {
- return nullptr;
- }
-
- const char* url_start = strchr(aHTTPRequest.get(), ' ');
- if (!url_start) {
- return nullptr;
- }
-
- const char* url_end = strrchr(++url_start, ' ');
- if (!url_end) {
- return nullptr;
- }
-
- // The path extracted from the HTTP request is used as a key in hash
- // table. It is not related to retrieving data from the filesystem so
- // we don't need to do any sanity checking on ".." paths and similar
- // exploits.
- nsCString relative(url_start, url_end - url_start);
- RefPtr<MediaResource> resource =
- mServer->GetResource(mServer->GetURLPrefix() + relative);
- return resource.forget();
-}
-
-NS_IMETHODIMP
-ServeResourceEvent::Run() {
- bool more = false; // Are there HTTP headers to read after the first line
- nsCString line; // Contains the current line read from input stream
- nsLineBuffer<char>* buffer = new nsLineBuffer<char>();
- nsresult rv = ReadCRLF(mInput.get(), buffer, line, &more);
- if (NS_FAILED(rv)) { Shutdown(); return rv; }
-
- // First line contains the HTTP GET request. Extract the URL and obtain
- // the MediaResource for it.
- RefPtr<MediaResource> resource = GetMediaResource(line);
- if (!resource) {
- const char* response_404 = "HTTP/1.1 404 Not Found\r\n"
- "Content-Length: 0\r\n\r\n";
- rv = WriteAll(response_404, strlen(response_404));
- Shutdown();
- return rv;
- }
-
- // Offset in bytes to start reading from resource.
- // This is zero by default but can be set to another starting value if
- // this HTTP request includes a byte range request header.
- int64_t start = 0;
-
- // Keep reading lines until we get a zero length line, which is the HTTP
- // protocol's way of signifying the end of headers and start of body, or
- // until we have no more data to read.
- while (more && line.Length() > 0) {
- rv = ReadCRLF(mInput.get(), buffer, line, &more);
- if (NS_FAILED(rv)) { Shutdown(); return rv; }
-
- // Look for a byte range request header. If there is one, set the
- // media resource offset to start from to that requested. Here we
- // only check for the range request format used by Android rather
- // than implementing all possibilities in the HTTP specification.
- // That is, the range request is of the form:
- // Range: bytes=nnnn-
- // Were 'nnnn' is an integer number.
- // The end of the range is not checked, instead we return up to
- // the end of the resource and the client is informed of this via
- // the content-range header.
- NS_NAMED_LITERAL_CSTRING(byteRange, "Range: bytes=");
- const char* s = strstr(line.get(), byteRange.get());
- if (s) {
- start = strtoll(s+byteRange.Length(), nullptr, 10);
-
- // Clamp 'start' to be between 0 and the resource length.
- start = std::max(int64_t(0), std::min(resource->GetLength(), start));
- }
- }
-
- // HTTP response to use if this is a non byte range request
- const char* response_normal = "HTTP/1.1 200 OK\r\n";
-
- // HTTP response to use if this is a byte range request
- const char* response_range = "HTTP/1.1 206 Partial Content\r\n";
-
- // End of HTTP reponse headers is indicated by an empty line.
- const char* response_end = "\r\n";
-
- // If the request was a byte range request, we need to read from the
- // requested offset. If the resource is non-seekable, or the seek
- // fails, then the start offset is set back to zero. This results in all
- // HTTP response data being as if the byte range request was not made.
- if (start > 0 && !resource->IsTransportSeekable()) {
- start = 0;
- }
-
- const char* response_line = start > 0 ?
- response_range :
- response_normal;
- rv = WriteAll(response_line, strlen(response_line));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- // Buffer used for reading from the input stream and writing to
- // the output stream. The buffer size should be big enough for the
- // HTTP response headers sent below. A static_assert ensures
- // this where the buffer is used.
- const int buffer_size = 32768;
- auto b = MakeUnique<char[]>(buffer_size);
-
- // If we know the length of the resource, send a Content-Length header.
- int64_t contentlength = resource->GetLength() - start;
- if (contentlength > 0) {
- static_assert (buffer_size > 1024,
- "buffer_size must be large enough "
- "to hold response headers");
- snprintf(b.get(), buffer_size, "Content-Length: %" PRId64 "\r\n", contentlength);
- rv = WriteAll(b.get(), strlen(b.get()));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
- }
-
- // If the request was a byte range request, respond with a Content-Range
- // header which details the extent of the data returned.
- if (start > 0) {
- static_assert (buffer_size > 1024,
- "buffer_size must be large enough "
- "to hold response headers");
- snprintf(b.get(), buffer_size, "Content-Range: "
- "bytes %" PRId64 "-%" PRId64 "/%" PRId64 "\r\n",
- start, resource->GetLength() - 1, resource->GetLength());
- rv = WriteAll(b.get(), strlen(b.get()));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
- }
-
- rv = WriteAll(response_end, strlen(response_end));
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- rv = mOutput->Flush();
- if (NS_FAILED(rv)) { Shutdown(); return NS_OK; }
-
- // Read data from media resource
- uint32_t bytesRead = 0; // Number of bytes read/written to streams
- rv = resource->ReadAt(start, b.get(), buffer_size, &bytesRead);
- while (NS_SUCCEEDED(rv) && bytesRead != 0) {
- // Keep track of what we think the starting position for the next read
- // is. This is used in subsequent ReadAt calls to ensure we are reading
- // from the correct offset in the case where another thread is reading
- // from th same MediaResource.
- start += bytesRead;
-
- // Write data obtained from media resource to output stream
- rv = WriteAll(b.get(), bytesRead);
- if (NS_FAILED (rv)) break;
-
- rv = resource->ReadAt(start, b.get(), 32768, &bytesRead);
- }
-
- Shutdown();
- return NS_OK;
-}
-
-void
-ServeResourceEvent::Shutdown()
-{
- // Cleanup resources and exit.
- mInput->Close();
- mOutput->Close();
-
- // To shutdown the current thread we need to first exit this event.
- // The Shutdown event below is posted to the main thread to do this.
- nsCOMPtr<nsIRunnable> event = new ShutdownThreadEvent(NS_GetCurrentThread());
- NS_DispatchToMainThread(event);
-}
-
-/*
- This is the listener attached to the server socket. When an HTTP
- request is made by the client the OnSocketAccepted method is
- called. This method will spawn a thread to process the request.
- The thread receives a single event which does the parsing of
- the HTTP request and forwarding the data from the MediaResource
- to the output stream of the request.
-
- The MediaResource used for providing the request data is obtained
- from the AndroidMediaResourceServer that created this listener, using the
- URL the client requested.
-*/
-class ResourceSocketListener : public nsIServerSocketListener
-{
-public:
- // The AndroidMediaResourceServer used to look up the MediaResource
- // on requests.
- RefPtr<AndroidMediaResourceServer> mServer;
-
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSISERVERSOCKETLISTENER
-
- ResourceSocketListener(AndroidMediaResourceServer* aServer) :
- mServer(aServer)
- {
- }
-
-private:
- virtual ~ResourceSocketListener() { }
-};
-
-NS_IMPL_ISUPPORTS(ResourceSocketListener, nsIServerSocketListener)
-
-NS_IMETHODIMP
-ResourceSocketListener::OnSocketAccepted(nsIServerSocket* aServ,
- nsISocketTransport* aTrans)
-{
- nsCOMPtr<nsIInputStream> input;
- nsCOMPtr<nsIOutputStream> output;
- nsresult rv;
-
- rv = aTrans->OpenInputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(input));
- if (NS_FAILED(rv)) return rv;
-
- rv = aTrans->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(output));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIThread> thread;
- rv = NS_NewThread(getter_AddRefs(thread));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIRunnable> event = new ServeResourceEvent(input.get(), output.get(), mServer);
- return thread->Dispatch(event, NS_DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-ResourceSocketListener::OnStopListening(nsIServerSocket* aServ, nsresult aStatus)
-{
- return NS_OK;
-}
-
-AndroidMediaResourceServer::AndroidMediaResourceServer() :
- mMutex("AndroidMediaResourceServer")
-{
-}
-
-NS_IMETHODIMP
-AndroidMediaResourceServer::Run()
-{
- MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
- MutexAutoLock lock(mMutex);
-
- nsresult rv;
- mSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID, &rv);
- if (NS_FAILED(rv)) return rv;
-
- rv = mSocket->InitSpecialConnection(-1,
- nsIServerSocket::LoopbackOnly
- | nsIServerSocket::KeepWhenOffline,
- -1);
- if (NS_FAILED(rv)) return rv;
-
- rv = mSocket->AsyncListen(new ResourceSocketListener(this));
- if (NS_FAILED(rv)) return rv;
-
- return NS_OK;
-}
-
-/* static */
-already_AddRefed<AndroidMediaResourceServer>
-AndroidMediaResourceServer::Start()
-{
- MOZ_ASSERT(NS_IsMainThread());
- RefPtr<AndroidMediaResourceServer> server = new AndroidMediaResourceServer();
- server->Run();
- return server.forget();
-}
-
-void
-AndroidMediaResourceServer::Stop()
-{
- MutexAutoLock lock(mMutex);
- mSocket->Close();
- mSocket = nullptr;
-}
-
-nsresult
-AndroidMediaResourceServer::AppendRandomPath(nsCString& aUrl)
-{
- // Use a cryptographic quality PRNG to generate raw random bytes
- // and convert that to a base64 string for use as an URL path. This
- // is based on code from nsExternalAppHandler::SetUpTempFile.
- nsresult rv;
- nsAutoCString salt;
- rv = GenerateRandomPathName(salt, 16);
- if (NS_FAILED(rv)) return rv;
- aUrl += "/";
- aUrl += salt;
- return NS_OK;
-}
-
-nsresult
-AndroidMediaResourceServer::AddResource(mozilla::MediaResource* aResource, nsCString& aUrl)
-{
- nsCString url = GetURLPrefix();
- nsresult rv = AppendRandomPath(url);
- if (NS_FAILED (rv)) return rv;
-
- {
- MutexAutoLock lock(mMutex);
-
- // Adding a resource URL that already exists is considered an error.
- if (mResources.find(url) != mResources.end()) return NS_ERROR_FAILURE;
- mResources[url] = aResource;
- }
-
- aUrl = url;
-
- return NS_OK;
-}
-
-void
-AndroidMediaResourceServer::RemoveResource(nsCString const& aUrl)
-{
- MutexAutoLock lock(mMutex);
- mResources.erase(aUrl);
-}
-
-nsCString
-AndroidMediaResourceServer::GetURLPrefix()
-{
- MutexAutoLock lock(mMutex);
-
- int32_t port = 0;
- nsresult rv = mSocket->GetPort(&port);
- if (NS_FAILED (rv) || port < 0) {
- return nsCString("");
- }
-
- char buffer[256];
- snprintf(buffer, sizeof(buffer), "http://127.0.0.1:%d", port >= 0 ? port : 0);
- return nsCString(buffer);
-}
-
-already_AddRefed<MediaResource>
-AndroidMediaResourceServer::GetResource(nsCString const& aUrl)
-{
- MutexAutoLock lock(mMutex);
- ResourceMap::const_iterator it = mResources.find(aUrl);
- if (it == mResources.end()) return nullptr;
-
- RefPtr<MediaResource> resource = it->second;
- return resource.forget();
-}
diff --git a/dom/media/android/AndroidMediaResourceServer.h b/dom/media/android/AndroidMediaResourceServer.h
deleted file mode 100644
index 68200f9c0..000000000
--- a/dom/media/android/AndroidMediaResourceServer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(AndroidMediaResourceServer_h_)
-#define AndroidMediaResourceServer_h_
-
-#include <map>
-#include "nsIServerSocket.h"
-#include "MediaResource.h"
-
-namespace mozilla {
-
-class MediaResource;
-
-/*
- AndroidMediaResourceServer instantiates a socket server that understands
- HTTP requests for MediaResource instances. The server runs on an
- automatically selected port and MediaResource instances are registered.
- The registration returns a string URL than can be used to fetch the
- resource. That URL contains a randomly generated path to make it
- difficult for other local applications on the device to guess it.
-
- The HTTP protocol is limited in that it supports only what the
- Android DataSource implementation uses to fetch media. It
- understands HTTP GET and byte range requests.
-
- The intent of this class is to be used in Media backends that
- have a system component that does its own network requests. These
- requests are made against this server which then uses standard
- Gecko network requests and media cache usage.
-
- The AndroidMediaResourceServer can be instantiated on any thread and
- its methods are threadsafe - they can be called on any thread.
- The server socket itself is always run on the main thread and
- this is done by the Start() static method by synchronously
- dispatching to the main thread.
-*/
-class AndroidMediaResourceServer : public Runnable
-{
-private:
- // Mutex protecting private members of AndroidMediaResourceServer.
- // All member variables below this point in the class definition
- // must acquire the mutex before access.
- mozilla::Mutex mMutex;
-
- // Server socket used to listen for incoming connections
- nsCOMPtr<nsIServerSocket> mSocket;
-
- // Mapping between MediaResource URL's to the MediaResource
- // object served at that URL.
- typedef std::map<nsCString,
- RefPtr<mozilla::MediaResource> > ResourceMap;
- ResourceMap mResources;
-
- // Create a AndroidMediaResourceServer that will listen on an automatically
- // selected port when started. This is private as it should only be
- // called internally from the public 'Start' method.
- AndroidMediaResourceServer();
- NS_IMETHOD Run();
-
- // Append a random URL path to a string. This is used for creating a
- // unique URl for a resource which helps prevent malicious software
- // running on the same machine as the server from guessing the URL
- // and accessing video data.
- nsresult AppendRandomPath(nsCString& aURL);
-
-public:
- // Create a AndroidMediaResourceServer and start it listening. This call will
- // perform a synchronous request on the main thread.
- static already_AddRefed<AndroidMediaResourceServer> Start();
-
- // Stops the server from listening and accepting further connections.
- void Stop();
-
- // Add a MediaResource to be served by this server. Stores the
- // absolute URL that can be used to access the resource in 'aUrl'.
- nsresult AddResource(mozilla::MediaResource* aResource, nsCString& aUrl);
-
- // Remove a MediaResource so it is no longer served by this server.
- // The URL provided must match exactly that provided by a previous
- // call to "AddResource".
- void RemoveResource(nsCString const& aUrl);
-
- // Returns the prefix for HTTP requests to the server. This plus
- // the result of AddResource results in an Absolute URL.
- nsCString GetURLPrefix();
-
- // Returns the resource asociated with a given URL
- already_AddRefed<mozilla::MediaResource> GetResource(nsCString const& aUrl);
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/android/MPAPI.h b/dom/media/android/MPAPI.h
deleted file mode 100644
index 9b289ca09..000000000
--- a/dom/media/android/MPAPI.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-#if !defined(MPAPI_h_)
-#define MPAPI_h_
-
-#include <stdint.h>
-
-namespace MPAPI {
-
-enum ColorFormat {
- I420,
- RGB565
-};
-
-/*
- * A callback for the plugin to use to request a buffer owned by gecko. This can
- * save us a copy or two down the line.
- */
-class BufferCallback {
-public:
- virtual void *operator()(size_t aWidth, size_t aHeight,
- ColorFormat aColorFormat) = 0;
-};
-
-struct VideoPlane {
- VideoPlane() :
- mData(0),
- mStride(0),
- mWidth(0),
- mHeight(0),
- mOffset(0),
- mSkip(0)
- {}
-
- void *mData;
- int32_t mStride;
- int32_t mWidth;
- int32_t mHeight;
- int32_t mOffset;
- int32_t mSkip;
-};
-
-struct VideoFrame {
- int64_t mTimeUs;
- bool mKeyFrame;
- void *mData;
- size_t mSize;
- int32_t mStride;
- int32_t mSliceHeight;
- int32_t mRotation;
- VideoPlane Y;
- VideoPlane Cb;
- VideoPlane Cr;
-
- VideoFrame() :
- mTimeUs(0),
- mKeyFrame(false),
- mData(0),
- mSize(0),
- mStride(0),
- mSliceHeight(0),
- mRotation(0)
- {}
-
- void Set(int64_t aTimeUs, bool aKeyFrame,
- void *aData, size_t aSize, int32_t aStride, int32_t aSliceHeight, int32_t aRotation,
- void *aYData, int32_t aYStride, int32_t aYWidth, int32_t aYHeight, int32_t aYOffset, int32_t aYSkip,
- void *aCbData, int32_t aCbStride, int32_t aCbWidth, int32_t aCbHeight, int32_t aCbOffset, int32_t aCbSkip,
- void *aCrData, int32_t aCrStride, int32_t aCrWidth, int32_t aCrHeight, int32_t aCrOffset, int32_t aCrSkip)
- {
- mTimeUs = aTimeUs;
- mKeyFrame = aKeyFrame;
- mData = aData;
- mSize = aSize;
- mStride = aStride;
- mSliceHeight = aSliceHeight;
- mRotation = aRotation;
- Y.mData = aYData;
- Y.mStride = aYStride;
- Y.mWidth = aYWidth;
- Y.mHeight = aYHeight;
- Y.mOffset = aYOffset;
- Y.mSkip = aYSkip;
- Cb.mData = aCbData;
- Cb.mStride = aCbStride;
- Cb.mWidth = aCbWidth;
- Cb.mHeight = aCbHeight;
- Cb.mOffset = aCbOffset;
- Cb.mSkip = aCbSkip;
- Cr.mData = aCrData;
- Cr.mStride = aCrStride;
- Cr.mWidth = aCrWidth;
- Cr.mHeight = aCrHeight;
- Cr.mOffset = aCrOffset;
- Cr.mSkip = aCrSkip;
- }
-};
-
-struct AudioFrame {
- int64_t mTimeUs;
- void *mData; // 16PCM interleaved
- size_t mSize; // Size of mData in bytes
- int32_t mAudioChannels;
- int32_t mAudioSampleRate;
-
- AudioFrame() :
- mTimeUs(0),
- mData(0),
- mSize(0),
- mAudioChannels(0),
- mAudioSampleRate(0)
- {
- }
-
- void Set(int64_t aTimeUs,
- void *aData, size_t aSize,
- int32_t aAudioChannels, int32_t aAudioSampleRate)
- {
- mTimeUs = aTimeUs;
- mData = aData;
- mSize = aSize;
- mAudioChannels = aAudioChannels;
- mAudioSampleRate = aAudioSampleRate;
- }
-};
-
-struct Decoder;
-
-struct PluginHost {
- bool (*Read)(Decoder *aDecoder, char *aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes);
- uint64_t (*GetLength)(Decoder *aDecoder);
- void (*SetMetaDataReadMode)(Decoder *aDecoder);
- void (*SetPlaybackReadMode)(Decoder *aDecoder);
- bool (*GetIntPref)(const char *aPref, int32_t *aResult);
- bool (*GetSystemInfoString)(const char *aKey, char *aResult, size_t aResultLen);
-};
-
-struct Decoder {
- void *mResource;
- void *mPrivate;
-
- Decoder();
-
- void (*GetDuration)(Decoder *aDecoder, int64_t *durationUs);
- void (*GetVideoParameters)(Decoder *aDecoder, int32_t *aWidth, int32_t *aHeight);
- void (*GetAudioParameters)(Decoder *aDecoder, int32_t *aNumChannels, int32_t *aSampleRate);
- bool (*HasVideo)(Decoder *aDecoder);
- bool (*HasAudio)(Decoder *aDecoder);
- bool (*ReadVideo)(Decoder *aDecoder, VideoFrame *aFrame, int64_t aSeekTimeUs, BufferCallback *aBufferCallback);
- bool (*ReadAudio)(Decoder *aDecoder, AudioFrame *aFrame, int64_t aSeekTimeUs);
- void (*DestroyDecoder)(Decoder *);
-};
-
-struct Manifest {
- bool (*CanDecode)(const char *aMimeChars, size_t aMimeLen, const char* const**aCodecs);
- bool (*CreateDecoder)(PluginHost *aPluginHost, Decoder *aDecoder,
- const char *aMimeChars, size_t aMimeLen);
-};
-
-}
-
-#endif
diff --git a/dom/media/android/moz.build b/dom/media/android/moz.build
deleted file mode 100644
index 3ad43cd50..000000000
--- a/dom/media/android/moz.build
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'AndroidMediaDecoder.h',
- 'AndroidMediaPluginHost.h',
- 'AndroidMediaReader.h',
- 'AndroidMediaResourceServer.h',
- 'MPAPI.h',
-]
-
-UNIFIED_SOURCES += [
- 'AndroidMediaDecoder.cpp',
- 'AndroidMediaPluginHost.cpp',
- 'AndroidMediaReader.cpp',
- 'AndroidMediaResourceServer.cpp',
-]
-
-LOCAL_INCLUDES += [
- '/dom/base',
- '/dom/html',
-]
-
-FINAL_LIBRARY = 'xul'
diff --git a/dom/media/directshow/AudioSinkFilter.cpp b/dom/media/directshow/AudioSinkFilter.cpp
deleted file mode 100644
index 9f23c0e00..000000000
--- a/dom/media/directshow/AudioSinkFilter.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-
-#include <initguid.h>
-#include <wmsdkidl.h>
-
-#define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
-
-DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
- 0xf1, 0x33, 0x7b, 0x33);
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
- : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
- mFilterCritSec("AudioSinkFilter::mFilterCritSec")
-{
- (*aOutResult) = S_OK;
- mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
- this,
- &mFilterCritSec,
- aOutResult);
-}
-
-AudioSinkFilter::~AudioSinkFilter()
-{
-}
-
-int
-AudioSinkFilter::GetPinCount()
-{
- return 1;
-}
-
-BasePin*
-AudioSinkFilter::GetPin(int aIndex)
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
-}
-
-HRESULT
-AudioSinkFilter::Pause()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- if (mState == State_Stopped) {
- // Change the state, THEN activate the input pin.
- mState = State_Paused;
- if (mInputPin && mInputPin->IsConnected()) {
- mInputPin->Active();
- }
- } else if (mState == State_Running) {
- mState = State_Paused;
- }
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Stop()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- mState = State_Stopped;
- if (mInputPin) {
- mInputPin->Inactive();
- }
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Run(REFERENCE_TIME tStart)
-{
- LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
- RefTimeToUsecs(tStart),
- double(RefTimeToUsecs(tStart)) / USECS_PER_S);
- return media::BaseFilter::Run(tStart);
-}
-
-HRESULT
-AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
-{
- (* pCLSID) = CLSID_MozAudioSinkFilter;
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
-{
- if (aIId == IID_IMediaSeeking) {
- *aInterface = static_cast<IMediaSeeking*>(this);
- AddRef();
- return S_OK;
- }
- return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
-}
-
-ULONG
-AudioSinkFilter::AddRef()
-{
- return ::InterlockedIncrement(&mRefCnt);
-}
-
-ULONG
-AudioSinkFilter::Release()
-{
- unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
- if (!newRefCnt) {
- delete this;
- }
- return newRefCnt;
-}
-
-SampleSink*
-AudioSinkFilter::GetSampleSink()
-{
- return mInputPin->GetSampleSink();
-}
-
-
-// IMediaSeeking implementation.
-//
-// Calls to IMediaSeeking are forwarded to the output pin that the
-// AudioSinkInputPin is connected to, i.e. upstream towards the parser and
-// source filters, which actually implement seeking.
-#define ENSURE_CONNECTED_PIN_SEEKING \
- if (!mInputPin) { \
- return E_NOTIMPL; \
- } \
- RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
- if (!pinSeeking) { \
- return E_NOTIMPL; \
- }
-
-HRESULT
-AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->CheckCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsFormatSupported(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->QueryPreferredFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetTimeFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsUsingTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetDuration(LONGLONG* aDuration)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetDuration(aDuration);
-}
-
-HRESULT
-AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetStopPosition(aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCurrentPosition(aCurrent);
-}
-
-HRESULT
-AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->ConvertTimeFormat(aTarget,
- aTargetFormat,
- aSource,
- aSourceFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetPositions(aCurrent,
- aCurrentFlags,
- aStop,
- aStopFlags);
-}
-
-HRESULT
-AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPositions(aCurrent, aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetAvailable(aEarliest, aLatest);
-}
-
-HRESULT
-AudioSinkFilter::SetRate(double aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetRate(double* aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPreroll(aPreroll);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkFilter.h b/dom/media/directshow/AudioSinkFilter.h
deleted file mode 100644
index 85abdfccf..000000000
--- a/dom/media/directshow/AudioSinkFilter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkFilter_h_)
-#define AudioSinkFilter_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "nsAutoPtr.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class AudioSinkInputPin;
-class SampleSink;
-
-// Filter that acts as the end of the graph. Audio samples input into
-// this filter block the calling thread, and the calling thread is
-// unblocked when the decode thread extracts the sample. The samples
-// input into this filter are stored in the SampleSink, where the blocking
-// is implemented. The input pin owns the SampleSink.
-class AudioSinkFilter: public mozilla::media::BaseFilter,
- public IMediaSeeking
-{
-
-public:
- AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult);
- virtual ~AudioSinkFilter();
-
- // Gets the input pin's sample sink.
- SampleSink* GetSampleSink();
-
- // IUnknown implementation.
- STDMETHODIMP QueryInterface(REFIID aIId, void **aInterface);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
-
- // --------------------------------------------------------------------
- // CBaseFilter methods
- int GetPinCount ();
- mozilla::media::BasePin* GetPin ( IN int Index);
- STDMETHODIMP Pause ();
- STDMETHODIMP Stop ();
- STDMETHODIMP GetClassID ( OUT CLSID * pCLSID);
- STDMETHODIMP Run(REFERENCE_TIME tStart);
- // IMediaSeeking Methods...
-
- // We defer to SourceFilter, but we must expose the interface on
- // the output pins. Seeking commands come upstream from the renderers,
- // but they must be actioned at the source filters.
- STDMETHODIMP GetCapabilities(DWORD* aCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* aCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* aFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* aFormat);
- STDMETHODIMP GetTimeFormat(GUID* aFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* aFormat);
- STDMETHODIMP SetTimeFormat(const GUID* aFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* aCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop);
- STDMETHODIMP GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest);
- STDMETHODIMP SetRate(double aRate);
- STDMETHODIMP GetRate(double* aRate);
- STDMETHODIMP GetPreroll(LONGLONG* aPreroll);
-
- // --------------------------------------------------------------------
- // class factory calls this
- static IUnknown * CreateInstance (IN LPUNKNOWN punk, OUT HRESULT * phr);
-
-private:
- CriticalSection mFilterCritSec;
-
- // Note: The input pin defers its refcounting to the sink filter, so when
- // the input pin is addrefed, what actually happens is the sink filter is
- // addrefed.
- nsAutoPtr<AudioSinkInputPin> mInputPin;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkFilter_h_
diff --git a/dom/media/directshow/AudioSinkInputPin.cpp b/dom/media/directshow/AudioSinkInputPin.cpp
deleted file mode 100644
index 85a6e3da3..000000000
--- a/dom/media/directshow/AudioSinkInputPin.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "AudioSinkInputPin.h"
-#include "AudioSinkFilter.h"
-#include "SampleSink.h"
-#include "mozilla/Logging.h"
-
-#include <wmsdkidl.h>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkInputPin::AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult)
- : BaseInputPin(aObjectName, aFilter, aLock, aOutResult, aObjectName),
- mSegmentStartTime(0)
-{
- MOZ_COUNT_CTOR(AudioSinkInputPin);
- mSampleSink = new SampleSink();
-}
-
-AudioSinkInputPin::~AudioSinkInputPin()
-{
- MOZ_COUNT_DTOR(AudioSinkInputPin);
-}
-
-HRESULT
-AudioSinkInputPin::GetMediaType(int aPosition, MediaType* aOutMediaType)
-{
- NS_ENSURE_TRUE(aPosition >= 0, E_INVALIDARG);
- NS_ENSURE_TRUE(aOutMediaType, E_POINTER);
-
- if (aPosition > 0) {
- return S_FALSE;
- }
-
- // Note: We set output as PCM, as IEEE_FLOAT only works when using the
- // MP3 decoder as an MFT, and we can't do that while using DirectShow.
- aOutMediaType->SetType(&MEDIATYPE_Audio);
- aOutMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
- aOutMediaType->SetType(&FORMAT_WaveFormatEx);
- aOutMediaType->SetTemporalCompression(FALSE);
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::CheckMediaType(const MediaType* aMediaType)
-{
- if (!aMediaType) {
- return E_INVALIDARG;
- }
-
- GUID majorType = *aMediaType->Type();
- if (majorType != MEDIATYPE_Audio && majorType != WMMEDIATYPE_Audio) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->Subtype() != MEDIASUBTYPE_PCM) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->FormatType() != FORMAT_WaveFormatEx) {
- return E_INVALIDARG;
- }
-
- // We accept the media type, stash its layout format!
- WAVEFORMATEX* wfx = (WAVEFORMATEX*)(aMediaType->pbFormat);
- GetSampleSink()->SetAudioFormat(wfx);
-
- return S_OK;
-}
-
-AudioSinkFilter*
-AudioSinkInputPin::GetAudioSinkFilter()
-{
- return reinterpret_cast<AudioSinkFilter*>(mFilter);
-}
-
-SampleSink*
-AudioSinkInputPin::GetSampleSink()
-{
- return mSampleSink;
-}
-
-HRESULT
-AudioSinkInputPin::SetAbsoluteMediaTime(IMediaSample* aSample)
-{
- HRESULT hr;
- REFERENCE_TIME start = 0, end = 0;
- hr = aSample->GetTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- {
- CriticalSectionAutoEnter lock(*mLock);
- start += mSegmentStartTime;
- end += mSegmentStartTime;
- }
- hr = aSample->SetMediaTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::Receive(IMediaSample* aSample )
-{
- HRESULT hr;
- NS_ENSURE_TRUE(aSample, E_POINTER);
-
- hr = BaseInputPin::Receive(aSample);
- if (SUCCEEDED(hr) && hr != S_FALSE) { // S_FALSE == flushing
- // Set the timestamp of the sample after being adjusted for
- // seeking/segments in the "media time" attribute. When we seek,
- // DirectShow starts a new "segment", and starts labeling samples
- // from time=0 again, so we need to correct for this to get the
- // actual timestamps after seeking.
- hr = SetAbsoluteMediaTime(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- hr = GetSampleSink()->Receive(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- }
- return S_OK;
-}
-
-already_AddRefed<IMediaSeeking>
-AudioSinkInputPin::GetConnectedPinSeeking()
-{
- RefPtr<IPin> peer = GetConnected();
- if (!peer)
- return nullptr;
- RefPtr<IMediaSeeking> seeking;
- peer->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(seeking)));
- return seeking.forget();
-}
-
-HRESULT
-AudioSinkInputPin::BeginFlush()
-{
- HRESULT hr = media::BaseInputPin::BeginFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndFlush()
-{
- HRESULT hr = media::BaseInputPin::EndFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Reset the EOS flag, so that if we're called after a seek we still work.
- GetSampleSink()->Reset();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndOfStream(void)
-{
- HRESULT hr = media::BaseInputPin::EndOfStream();
- if (FAILED(hr) || hr == S_FALSE) {
- // Pin is stil flushing.
- return hr;
- }
- GetSampleSink()->SetEOS();
-
- return S_OK;
-}
-
-
-HRESULT
-AudioSinkInputPin::NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- CriticalSectionAutoEnter lock(*mLock);
- // Record the start time of the new segment, so that we can store the
- // correct absolute timestamp in the "media time" each incoming sample.
- mSegmentStartTime = tStart;
- return S_OK;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkInputPin.h b/dom/media/directshow/AudioSinkInputPin.h
deleted file mode 100644
index 80503c641..000000000
--- a/dom/media/directshow/AudioSinkInputPin.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkInputPin_h_)
-#define AudioSinkInputPin_h_
-
-#include "BaseInputPin.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsAutoPtr.h"
-
-namespace mozilla {
-
-namespace media {
- class MediaType;
-}
-
-class AudioSinkFilter;
-class SampleSink;
-
-
-// Input pin for capturing audio output of a DirectShow filter graph.
-// This is the input pin for the AudioSinkFilter.
-class AudioSinkInputPin: public mozilla::media::BaseInputPin
-{
-public:
- AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult);
- virtual ~AudioSinkInputPin();
-
- HRESULT GetMediaType (IN int iPos, OUT mozilla::media::MediaType * pmt);
- HRESULT CheckMediaType (IN const mozilla::media::MediaType * pmt);
- STDMETHODIMP Receive (IN IMediaSample *);
- STDMETHODIMP BeginFlush() override;
- STDMETHODIMP EndFlush() override;
-
- // Called when we start decoding a new segment, that happens directly after
- // a seek. This captures the segment's start time. Samples decoded by the
- // MP3 decoder have their timestamps offset from the segment start time.
- // Storing the segment start time enables us to set each sample's MediaTime
- // as an offset in the stream relative to the start of the stream, rather
- // than the start of the segment, i.e. its absolute time in the stream.
- STDMETHODIMP NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate) override;
-
- STDMETHODIMP EndOfStream() override;
-
- // Returns the IMediaSeeking interface of the connected output pin.
- // We forward seeking requests upstream from the sink to the source
- // filters.
- already_AddRefed<IMediaSeeking> GetConnectedPinSeeking();
-
- SampleSink* GetSampleSink();
-
-private:
- AudioSinkFilter* GetAudioSinkFilter();
-
- // Sets the media time on the media sample, relative to the segment
- // start time.
- HRESULT SetAbsoluteMediaTime(IMediaSample* aSample);
-
- nsAutoPtr<SampleSink> mSampleSink;
-
- // Synchronized by the filter lock; BaseInputPin::mLock.
- REFERENCE_TIME mSegmentStartTime;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkInputPin_h_
diff --git a/dom/media/directshow/DirectShowDecoder.cpp b/dom/media/directshow/DirectShowDecoder.cpp
deleted file mode 100644
index da68b4daa..000000000
--- a/dom/media/directshow/DirectShowDecoder.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#include "DirectShowUtils.h"
-#include "MediaDecoderStateMachine.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/WindowsVersion.h"
-
-namespace mozilla {
-
-MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
-{
- return new MediaDecoderStateMachine(this, new DirectShowReader(this));
-}
-
-/* static */
-bool
-DirectShowDecoder::GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList)
-{
- if (!IsEnabled()) {
- return false;
- }
-
- static char const *const mp3AudioCodecs[] = {
- "mp3",
- nullptr
- };
- if (aType.EqualsASCII("audio/mpeg") ||
- aType.EqualsASCII("audio/mp3")) {
- if (aCodecList) {
- *aCodecList = mp3AudioCodecs;
- }
- return true;
- }
-
- return false;
-}
-
-/* static */
-bool
-DirectShowDecoder::IsEnabled()
-{
- return CanDecodeMP3UsingDirectShow() &&
- Preferences::GetBool("media.directshow.enabled");
-}
-
-DirectShowDecoder::DirectShowDecoder(MediaDecoderOwner* aOwner)
- : MediaDecoder(aOwner)
-{
- MOZ_COUNT_CTOR(DirectShowDecoder);
-}
-
-DirectShowDecoder::~DirectShowDecoder()
-{
- MOZ_COUNT_DTOR(DirectShowDecoder);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/DirectShowDecoder.h b/dom/media/directshow/DirectShowDecoder.h
deleted file mode 100644
index c4d371fbf..000000000
--- a/dom/media/directshow/DirectShowDecoder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowDecoder_h_)
-#define DirectShowDecoder_h_
-
-#include "MediaDecoder.h"
-
-namespace mozilla {
-
-// Decoder that uses DirectShow to playback MP3 files only.
-class DirectShowDecoder : public MediaDecoder
-{
-public:
-
- explicit DirectShowDecoder(MediaDecoderOwner* aOwner);
- virtual ~DirectShowDecoder();
-
- MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
- if (!IsEnabled()) {
- return nullptr;
- }
- return new DirectShowDecoder(aOwner);
- }
-
- MediaDecoderStateMachine* CreateStateMachine() override;
-
- // Returns true if aType is a MIME type that we render with the
- // DirectShow backend. If aCodecList is non null,
- // it is filled with a (static const) null-terminated list of strings
- // denoting the codecs we'll playback. Note that playback is strictly
- // limited to MP3 only.
- static bool GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList);
-
- // Returns true if the DirectShow backend is preffed on.
- static bool IsEnabled();
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowReader.cpp b/dom/media/directshow/DirectShowReader.cpp
deleted file mode 100644
index cacf6f8de..000000000
--- a/dom/media/directshow/DirectShowReader.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowReader.h"
-#include "MediaDecoderReader.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "AudioSinkFilter.h"
-#include "SourceFilter.h"
-#include "SampleSink.h"
-#include "VideoUtils.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Windows XP's MP3 decoder filter. This is available on XP only, on Vista
-// and later we can use the DMO Wrapper filter and MP3 decoder DMO.
-const GUID DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER =
-{ 0x38BE3000, 0xDBF4, 0x11D0, {0x86, 0x0E, 0x00, 0xA0, 0x24, 0xCF, 0xEF, 0x6D} };
-
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
- : MediaDecoderReader(aDecoder),
- mMP3FrameParser(aDecoder->GetResource()->GetLength()),
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- mRotRegister(0),
-#endif
- mNumChannels(0),
- mAudioRate(0),
- mBytesPerSample(0)
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_CTOR(DirectShowReader);
-}
-
-DirectShowReader::~DirectShowReader()
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_DTOR(DirectShowReader);
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- if (mRotRegister) {
- RemoveGraphFromRunningObjectTable(mRotRegister);
- }
-#endif
-}
-
-// Try to parse the MP3 stream to make sure this is indeed an MP3, get the
-// estimated duration of the stream, and find the offset of the actual MP3
-// frames in the stream, as DirectShow doesn't like large ID3 sections.
-static nsresult
-ParseMP3Headers(MP3FrameParser *aParser, MediaResource *aResource)
-{
- const uint32_t MAX_READ_SIZE = 4096;
-
- uint64_t offset = 0;
- while (aParser->NeedsData() && !aParser->ParsedHeaders()) {
- uint32_t bytesRead;
- char buffer[MAX_READ_SIZE];
- nsresult rv = aResource->ReadAt(offset, buffer,
- MAX_READ_SIZE, &bytesRead);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!bytesRead) {
- // End of stream.
- return NS_ERROR_FAILURE;
- }
-
- aParser->Parse(reinterpret_cast<uint8_t*>(buffer), bytesRead, offset);
- offset += bytesRead;
- }
-
- return aParser->IsMP3() ? NS_OK : NS_ERROR_FAILURE;
-}
-
-nsresult
-DirectShowReader::ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags)
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
- nsresult rv;
-
- // Create the filter graph, reference it by the GraphBuilder interface,
- // to make graph building more convenient.
- hr = CoCreateInstance(CLSID_FilterGraph,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder,
- reinterpret_cast<void**>(static_cast<IGraphBuilder**>(getter_AddRefs(mGraph))));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mGraph, NS_ERROR_FAILURE);
-
- rv = ParseMP3Headers(&mMP3FrameParser, mDecoder->GetResource());
- NS_ENSURE_SUCCESS(rv, rv);
-
- #ifdef DIRECTSHOW_REGISTER_GRAPH
- hr = AddGraphToRunningObjectTable(mGraph, &mRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- #endif
-
- // Extract the interface pointers we'll need from the filter graph.
- hr = mGraph->QueryInterface(static_cast<IMediaControl**>(getter_AddRefs(mControl)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mControl, NS_ERROR_FAILURE);
-
- hr = mGraph->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(mMediaSeeking)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mMediaSeeking, NS_ERROR_FAILURE);
-
- // Build the graph. Create the filters we need, and connect them. We
- // build the entire graph ourselves to prevent other decoders installed
- // on the system being created and used.
-
- // Our source filters, wraps the MediaResource.
- mSourceFilter = new SourceFilter(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
- NS_ENSURE_TRUE(mSourceFilter, NS_ERROR_FAILURE);
-
- rv = mSourceFilter->Init(mDecoder->GetResource(), mMP3FrameParser.GetMP3Offset());
- NS_ENSURE_SUCCESS(rv, rv);
-
- hr = mGraph->AddFilter(mSourceFilter, L"MozillaDirectShowSource");
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // The MPEG demuxer.
- RefPtr<IBaseFilter> demuxer;
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG1Splitter,
- L"MPEG1Splitter",
- getter_AddRefs(demuxer));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Platform MP3 decoder.
- RefPtr<IBaseFilter> decoder;
- // Firstly try to create the MP3 decoder filter that ships with WinXP
- // directly. This filter doesn't normally exist on later versions of
- // Windows.
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG_LAYER_3_DECODER_FILTER,
- L"MPEG Layer 3 Decoder",
- getter_AddRefs(decoder));
- if (FAILED(hr)) {
- // Failed to create MP3 decoder filter. Try to instantiate
- // the MP3 decoder DMO.
- hr = AddMP3DMOWrapperFilter(mGraph, getter_AddRefs(decoder));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- }
-
- // Sink, captures audio samples and inserts them into our pipeline.
- static const wchar_t* AudioSinkFilterName = L"MozAudioSinkFilter";
- mAudioSinkFilter = new AudioSinkFilter(AudioSinkFilterName, &hr);
- NS_ENSURE_TRUE(mAudioSinkFilter && SUCCEEDED(hr), NS_ERROR_FAILURE);
- hr = mGraph->AddFilter(mAudioSinkFilter, AudioSinkFilterName);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Join the filters.
- hr = ConnectFilters(mGraph, mSourceFilter, demuxer);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, demuxer, decoder);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, decoder, mAudioSinkFilter);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- WAVEFORMATEX format;
- mAudioSinkFilter->GetSampleSink()->GetAudioFormat(&format);
- NS_ENSURE_TRUE(format.wFormatTag == WAVE_FORMAT_PCM, NS_ERROR_FAILURE);
-
- mInfo.mAudio.mChannels = mNumChannels = format.nChannels;
- mInfo.mAudio.mRate = mAudioRate = format.nSamplesPerSec;
- mInfo.mAudio.mBitDepth = format.wBitsPerSample;
- mBytesPerSample = format.wBitsPerSample / 8;
-
- // Begin decoding!
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- DWORD seekCaps = 0;
- hr = mMediaSeeking->GetCapabilities(&seekCaps);
- mInfo.mMediaSeekable = SUCCEEDED(hr) && (AM_SEEKING_CanSeekAbsolute & seekCaps);
-
- int64_t duration = mMP3FrameParser.GetDuration();
- if (SUCCEEDED(hr)) {
- mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
- }
-
- LOG("Successfully initialized DirectShow MP3 decoder.");
- LOG("Channels=%u Hz=%u duration=%lld bytesPerSample=%d",
- mInfo.mAudio.mChannels,
- mInfo.mAudio.mRate,
- RefTimeToUsecs(duration),
- mBytesPerSample);
-
- *aInfo = mInfo;
- // Note: The SourceFilter strips ID3v2 tags out of the stream.
- *aTags = nullptr;
-
- return NS_OK;
-}
-
-inline float
-UnsignedByteToAudioSample(uint8_t aValue)
-{
- return aValue * (2.0f / UINT8_MAX) - 1.0f;
-}
-
-bool
-DirectShowReader::Finish(HRESULT aStatus)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Finish(0x%x)", aStatus);
- // Notify the filter graph of end of stream.
- RefPtr<IMediaEventSink> eventSink;
- HRESULT hr = mGraph->QueryInterface(static_cast<IMediaEventSink**>(getter_AddRefs(eventSink)));
- if (SUCCEEDED(hr) && eventSink) {
- eventSink->Notify(EC_COMPLETE, aStatus, 0);
- }
- return false;
-}
-
-class DirectShowCopy
-{
-public:
- DirectShowCopy(uint8_t *aSource, uint32_t aBytesPerSample,
- uint32_t aSamples, uint32_t aChannels)
- : mSource(aSource)
- , mBytesPerSample(aBytesPerSample)
- , mSamples(aSamples)
- , mChannels(aChannels)
- , mNextSample(0)
- { }
-
- uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples)
- {
- uint32_t maxSamples = std::min(aSamples, mSamples - mNextSample);
- uint32_t frames = maxSamples / mChannels;
- size_t byteOffset = mNextSample * mBytesPerSample;
- if (mBytesPerSample == 1) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- uint8_t *sample = mSource + byteOffset;
- aBuffer[i] = UnsignedByteToAudioSample(*sample);
- byteOffset += mBytesPerSample;
- }
- } else if (mBytesPerSample == 2) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- int16_t *sample = reinterpret_cast<int16_t *>(mSource + byteOffset);
- aBuffer[i] = AudioSampleToFloat(*sample);
- byteOffset += mBytesPerSample;
- }
- }
- mNextSample += maxSamples;
- return frames;
- }
-
-private:
- uint8_t * const mSource;
- const uint32_t mBytesPerSample;
- const uint32_t mSamples;
- const uint32_t mChannels;
- uint32_t mNextSample;
-};
-
-bool
-DirectShowReader::DecodeAudioData()
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
-
- SampleSink* sink = mAudioSinkFilter->GetSampleSink();
- if (sink->AtEOS()) {
- // End of stream.
- return Finish(S_OK);
- }
-
- // Get the next chunk of audio samples. This blocks until the sample
- // arrives, or an error occurs (like the stream is shutdown).
- RefPtr<IMediaSample> sample;
- hr = sink->Extract(sample);
- if (FAILED(hr) || hr == S_FALSE) {
- return Finish(hr);
- }
-
- int64_t start = 0, end = 0;
- sample->GetMediaTime(&start, &end);
- LOG("DirectShowReader::DecodeAudioData [%4.2lf-%4.2lf]",
- RefTimeToSeconds(start),
- RefTimeToSeconds(end));
-
- LONG length = sample->GetActualDataLength();
- LONG numSamples = length / mBytesPerSample;
- LONG numFrames = length / mBytesPerSample / mNumChannels;
-
- BYTE* data = nullptr;
- hr = sample->GetPointer(&data);
- NS_ENSURE_TRUE(SUCCEEDED(hr), Finish(hr));
-
- mAudioCompactor.Push(mDecoder->GetResource()->Tell(),
- RefTimeToUsecs(start),
- mInfo.mAudio.mRate,
- numFrames,
- mNumChannels,
- DirectShowCopy(reinterpret_cast<uint8_t *>(data),
- mBytesPerSample,
- numSamples,
- mNumChannels));
- return true;
-}
-
-bool
-DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold)
-{
- MOZ_ASSERT(OnTaskQueue());
- return false;
-}
-
-RefPtr<MediaDecoderReader::SeekPromise>
-DirectShowReader::Seek(SeekTarget aTarget, int64_t aEndTime)
-{
- nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds());
- if (NS_FAILED(res)) {
- return SeekPromise::CreateAndReject(res, __func__);
- } else {
- return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
- }
-}
-
-nsresult
-DirectShowReader::SeekInternal(int64_t aTargetUs)
-{
- HRESULT hr;
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Seek() target=%lld", aTargetUs);
-
- hr = mControl->Pause();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- nsresult rv = ResetDecode();
- NS_ENSURE_SUCCESS(rv, rv);
-
- LONGLONG seekPosition = UsecsToRefTime(aTargetUs);
- hr = mMediaSeeking->SetPositions(&seekPosition,
- AM_SEEKING_AbsolutePositioning,
- nullptr,
- AM_SEEKING_NoPositioning);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-} // namespace mozilla
diff --git a/dom/media/directshow/DirectShowReader.h b/dom/media/directshow/DirectShowReader.h
deleted file mode 100644
index e1326d416..000000000
--- a/dom/media/directshow/DirectShowReader.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowReader_h_)
-#define DirectShowReader_h_
-
-#include "windows.h" // HRESULT, DWORD
-#include "MediaDecoderReader.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "MP3FrameParser.h"
-
-// Add the graph to the Running Object Table so that we can connect
-// to this graph with GraphEdit/GraphStudio. Note: on Vista and up you must
-// also regsvr32 proppage.dll from the Windows SDK.
-// See: http://msdn.microsoft.com/en-us/library/ms787252(VS.85).aspx
-// #define DIRECTSHOW_REGISTER_GRAPH
-
-struct IGraphBuilder;
-struct IMediaControl;
-struct IMediaSeeking;
-
-namespace mozilla {
-
-class AudioSinkFilter;
-class SourceFilter;
-
-// Decoder backend for decoding MP3 using DirectShow. DirectShow operates as
-// a filter graph. The basic design of the DirectShowReader is that we have
-// a SourceFilter that wraps the MediaResource that connects to the
-// MP3 decoder filter. The MP3 decoder filter "pulls" data as it requires it
-// downstream on its own thread. When the MP3 decoder has produced a block of
-// decoded samples, its thread calls downstream into our AudioSinkFilter,
-// passing the decoded buffer in. The AudioSinkFilter inserts the samples into
-// a SampleSink object. The SampleSink blocks the MP3 decoder's thread until
-// the decode thread calls DecodeAudioData(), whereupon the SampleSink
-// releases the decoded samples to the decode thread, and unblocks the MP3
-// decoder's thread. The MP3 decoder can then request more data from the
-// SourceFilter, and decode more data. If the decode thread calls
-// DecodeAudioData() and there's no decoded samples waiting to be extracted
-// in the SampleSink, the SampleSink blocks the decode thread until the MP3
-// decoder produces a decoded sample.
-class DirectShowReader : public MediaDecoderReader
-{
-public:
- DirectShowReader(AbstractMediaDecoder* aDecoder);
-
- virtual ~DirectShowReader();
-
- bool DecodeAudioData() override;
- bool DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold) override;
-
- nsresult ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags) override;
-
- RefPtr<SeekPromise>
- Seek(SeekTarget aTarget, int64_t aEndTime) override;
-
- static const GUID CLSID_MPEG_LAYER_3_DECODER_FILTER;
-
-private:
- // Notifies the filter graph that playback is complete. aStatus is
- // the code to send to the filter graph. Always returns false, so
- // that we can just "return Finish()" from DecodeAudioData().
- bool Finish(HRESULT aStatus);
-
- nsresult SeekInternal(int64_t aTime);
-
- // DirectShow filter graph, and associated playback and seeking
- // control interfaces.
- RefPtr<IGraphBuilder> mGraph;
- RefPtr<IMediaControl> mControl;
- RefPtr<IMediaSeeking> mMediaSeeking;
-
- // Wraps the MediaResource, and feeds undecoded data into the filter graph.
- RefPtr<SourceFilter> mSourceFilter;
-
- // Sits at the end of the graph, removing decoded samples from the graph.
- // The graph will block while this is blocked, i.e. it will pause decoding.
- RefPtr<AudioSinkFilter> mAudioSinkFilter;
-
- // Some MP3s are variable bitrate, so DirectShow's duration estimation
- // can make its duration estimation based on the wrong bitrate. So we parse
- // the MP3 frames to get a more accuate estimate of the duration.
- MP3FrameParser mMP3FrameParser;
-
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- // Used to add/remove the filter graph to the Running Object Table. You can
- // connect GraphEdit/GraphStudio to the graph to observe and/or debug its
- // topology and state.
- DWORD mRotRegister;
-#endif
-
- // Number of channels in the audio stream.
- uint32_t mNumChannels;
-
- // Samples per second in the audio stream.
- uint32_t mAudioRate;
-
- // Number of bytes per sample. Can be either 1 or 2.
- uint32_t mBytesPerSample;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowUtils.cpp b/dom/media/directshow/DirectShowUtils.cpp
deleted file mode 100644
index b2afa7528..000000000
--- a/dom/media/directshow/DirectShowUtils.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowUtils.h"
-#include "dmodshow.h"
-#include "wmcodecdsp.h"
-#include "dmoreg.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsPrintfCString.h"
-
-#define WARN(...) NS_WARNING(nsPrintfCString(__VA_ARGS__).get())
-
-namespace mozilla {
-
-// Create a table which maps GUIDs to a string representation of the GUID.
-// This is useful for debugging purposes, for logging the GUIDs of media types.
-// This is only available when logging is enabled, i.e. not in release builds.
-struct GuidToName {
- const char* name;
- const GUID guid;
-};
-
-#pragma push_macro("OUR_GUID_ENTRY")
-#undef OUR_GUID_ENTRY
-#define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- { #name, {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} },
-
-static const GuidToName GuidToNameTable[] = {
-#include <uuids.h>
-};
-
-#pragma pop_macro("OUR_GUID_ENTRY")
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid)
-{
- const size_t len = ArrayLength(GuidToNameTable);
- for (unsigned i = 0; i < len; i++) {
- if (IsEqualGUID(aGuid, GuidToNameTable[i].guid)) {
- return GuidToNameTable[i].name;
- }
- }
- return "Unknown";
-}
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister)
-{
- RefPtr<IRunningObjectTable> runningObjectTable;
- if (SUCCEEDED(GetRunningObjectTable(0, getter_AddRefs(runningObjectTable)))) {
- runningObjectTable->Revoke(aRotRegister);
- }
-}
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister)
-{
- HRESULT hr;
-
- RefPtr<IMoniker> moniker;
- RefPtr<IRunningObjectTable> runningObjectTable;
-
- hr = GetRunningObjectTable(0, getter_AddRefs(runningObjectTable));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- const size_t STRING_LENGTH = 256;
- WCHAR wsz[STRING_LENGTH];
-
- StringCchPrintfW(wsz,
- STRING_LENGTH,
- L"FilterGraph %08x pid %08x",
- (DWORD_PTR)aUnkGraph,
- GetCurrentProcessId());
-
- hr = CreateItemMoniker(L"!", wsz, getter_AddRefs(moniker));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- hr = runningObjectTable->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,
- aUnkGraph,
- moniker,
- aOutRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- return S_OK;
-}
-
-const char*
-GetGraphNotifyString(long evCode)
-{
-#define CASE(x) case x: return #x
- switch(evCode) {
- CASE(EC_ACTIVATE); // A video window is being activated or deactivated.
- CASE(EC_BANDWIDTHCHANGE); // Not supported.
- CASE(EC_BUFFERING_DATA); // The graph is buffering data, or has stopped buffering data.
- CASE(EC_BUILT); // Send by the Video Control when a graph has been built. Not forwarded to applications.
- CASE(EC_CLOCK_CHANGED); // The reference clock has changed.
- CASE(EC_CLOCK_UNSET); // The clock provider was disconnected.
- CASE(EC_CODECAPI_EVENT); // Sent by an encoder to signal an encoding event.
- CASE(EC_COMPLETE); // All data from a particular stream has been rendered.
- CASE(EC_CONTENTPROPERTY_CHANGED); // Not supported.
- CASE(EC_DEVICE_LOST); // A Plug and Play device was removed or has become available again.
- CASE(EC_DISPLAY_CHANGED); // The display mode has changed.
- CASE(EC_END_OF_SEGMENT); // The end of a segment has been reached.
- CASE(EC_EOS_SOON); // Not supported.
- CASE(EC_ERROR_STILLPLAYING); // An asynchronous command to run the graph has failed.
- CASE(EC_ERRORABORT); // An operation was aborted because of an error.
- CASE(EC_ERRORABORTEX); // An operation was aborted because of an error.
- CASE(EC_EXTDEVICE_MODE_CHANGE); // Not supported.
- CASE(EC_FILE_CLOSED); // The source file was closed because of an unexpected event.
- CASE(EC_FULLSCREEN_LOST); // The video renderer is switching out of full-screen mode.
- CASE(EC_GRAPH_CHANGED); // The filter graph has changed.
- CASE(EC_LENGTH_CHANGED); // The length of a source has changed.
- CASE(EC_LOADSTATUS); // Notifies the application of progress when opening a network file.
- CASE(EC_MARKER_HIT); // Not supported.
- CASE(EC_NEED_RESTART); // A filter is requesting that the graph be restarted.
- CASE(EC_NEW_PIN); // Not supported.
- CASE(EC_NOTIFY_WINDOW); // Notifies a filter of the video renderer's window.
- CASE(EC_OLE_EVENT); // A filter is passing a text string to the application.
- CASE(EC_OPENING_FILE); // The graph is opening a file, or has finished opening a file.
- CASE(EC_PALETTE_CHANGED); // The video palette has changed.
- CASE(EC_PAUSED); // A pause request has completed.
- CASE(EC_PLEASE_REOPEN); // The source file has changed.
- CASE(EC_PREPROCESS_COMPLETE); // Sent by the WM ASF Writer filter when it completes the pre-processing for multipass encoding.
- CASE(EC_PROCESSING_LATENCY); // Indicates the amount of time that a component is taking to process each sample.
- CASE(EC_QUALITY_CHANGE); // The graph is dropping samples, for quality control.
- //CASE(EC_RENDER_FINISHED); // Not supported.
- CASE(EC_REPAINT); // A video renderer requires a repaint.
- CASE(EC_SAMPLE_LATENCY); // Specifies how far behind schedule a component is for processing samples.
- //CASE(EC_SAMPLE_NEEDED); // Requests a new input sample from the Enhanced Video Renderer (EVR) filter.
- CASE(EC_SCRUB_TIME); // Specifies the time stamp for the most recent frame step.
- CASE(EC_SEGMENT_STARTED); // A new segment has started.
- CASE(EC_SHUTTING_DOWN); // The filter graph is shutting down, prior to being destroyed.
- CASE(EC_SNDDEV_IN_ERROR); // A device error has occurred in an audio capture filter.
- CASE(EC_SNDDEV_OUT_ERROR); // A device error has occurred in an audio renderer filter.
- CASE(EC_STARVATION); // A filter is not receiving enough data.
- CASE(EC_STATE_CHANGE); // The filter graph has changed state.
- CASE(EC_STATUS); // Contains two arbitrary status strings.
- CASE(EC_STEP_COMPLETE); // A filter performing frame stepping has stepped the specified number of frames.
- CASE(EC_STREAM_CONTROL_STARTED); // A stream-control start command has taken effect.
- CASE(EC_STREAM_CONTROL_STOPPED); // A stream-control stop command has taken effect.
- CASE(EC_STREAM_ERROR_STILLPLAYING); // An error has occurred in a stream. The stream is still playing.
- CASE(EC_STREAM_ERROR_STOPPED); // A stream has stopped because of an error.
- CASE(EC_TIMECODE_AVAILABLE); // Not supported.
- CASE(EC_UNBUILT); // Send by the Video Control when a graph has been torn down. Not forwarded to applications.
- CASE(EC_USERABORT); // The user has terminated playback.
- CASE(EC_VIDEO_SIZE_CHANGED); // The native video size has changed.
- CASE(EC_VIDEOFRAMEREADY); // A video frame is ready for display.
- CASE(EC_VMR_RECONNECTION_FAILED); // Sent by the VMR-7 and the VMR-9 when it was unable to accept a dynamic format change request from the upstream decoder.
- CASE(EC_VMR_RENDERDEVICE_SET); // Sent when the VMR has selected its rendering mechanism.
- CASE(EC_VMR_SURFACE_FLIPPED); // Sent when the VMR-7's allocator presenter has called the DirectDraw Flip method on the surface being presented.
- CASE(EC_WINDOW_DESTROYED); // The video renderer was destroyed or removed from the graph.
- CASE(EC_WMT_EVENT); // Sent by the WM ASF Reader filter when it reads ASF files protected by digital rights management (DRM).
- CASE(EC_WMT_INDEX_EVENT); // Sent when an application uses the WM ASF Writer to index Windows Media Video files.
- CASE(S_OK); // Success.
- CASE(VFW_S_AUDIO_NOT_RENDERED); // Partial success; the audio was not rendered.
- CASE(VFW_S_DUPLICATE_NAME); // Success; the Filter Graph Manager modified a filter name to avoid duplication.
- CASE(VFW_S_PARTIAL_RENDER); // Partial success; some of the streams in this movie are in an unsupported format.
- CASE(VFW_S_VIDEO_NOT_RENDERED); // Partial success; the video was not rendered.
- CASE(E_ABORT); // Operation aborted.
- CASE(E_OUTOFMEMORY); // Insufficient memory.
- CASE(E_POINTER); // Null pointer argument.
- CASE(VFW_E_CANNOT_CONNECT); // No combination of intermediate filters could be found to make the connection.
- CASE(VFW_E_CANNOT_RENDER); // No combination of filters could be found to render the stream.
- CASE(VFW_E_NO_ACCEPTABLE_TYPES); // There is no common media type between these pins.
- CASE(VFW_E_NOT_IN_GRAPH);
-
- default:
- return "Unknown Code";
- };
-#undef CASE
-}
-
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(aFilterClsId,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- // Object probably not available on this system.
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- hr = aGraph->AddFilter(filter, aFilterName);
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-CreateMP3DMOWrapperFilter(IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(CLSID_DMOWrapperFilter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- // Query for IDMOWrapperFilter.
- RefPtr<IDMOWrapperFilter> dmoWrapper;
- hr = filter->QueryInterface(IID_IDMOWrapperFilter,
- getter_AddRefs(dmoWrapper));
- if (FAILED(hr)) {
- WARN("QueryInterface failed, hr=%x", hr);
- return hr;
- }
-
- hr = dmoWrapper->Init(CLSID_CMP3DecMediaObject, DMOCATEGORY_AUDIO_DECODER);
- if (FAILED(hr)) {
- // Can't instantiate MP3 DMO. It doesn't exist on Windows XP, we're
- // probably hitting that. Don't log warning to console, this is an
- // expected error.
- WARN("dmoWrapper Init failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CreateMP3DMOWrapperFilter(getter_AddRefs(filter));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Add the wrapper filter to graph.
- hr = aGraph->AddFilter(filter, L"MP3 Decoder DMO");
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-bool
-CanDecodeMP3UsingDirectShow()
-{
- RefPtr<IBaseFilter> filter;
-
- // Can we create the MP3 demuxer filter?
- if (FAILED(CoCreateInstance(CLSID_MPEG1Splitter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter)))) {
- return false;
- }
-
- // Can we create either the WinXP MP3 decoder filter or the MP3 DMO decoder?
- if (FAILED(CoCreateInstance(DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter))) &&
- FAILED(CreateMP3DMOWrapperFilter(getter_AddRefs(filter)))) {
- return false;
- }
-
- // Else, we can create all of the components we need. Assume
- // DirectShow is going to work...
- return true;
-}
-
-// Match a pin by pin direction and connection state.
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches)
-{
- NS_ENSURE_TRUE(aPin, E_POINTER);
- NS_ENSURE_TRUE(aOutMatches, E_POINTER);
-
- // Ensure the pin is unconnected.
- RefPtr<IPin> peer;
- HRESULT hr = aPin->ConnectedTo(getter_AddRefs(peer));
- if (hr != VFW_E_NOT_CONNECTED) {
- *aOutMatches = false;
- return hr;
- }
-
- // Ensure the pin is of the specified direction.
- PIN_DIRECTION pinDir;
- hr = aPin->QueryDirection(&pinDir);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- *aOutMatches = (pinDir == aPinDir);
- return S_OK;
-}
-
-// Return the first unconnected input pin or output pin.
-already_AddRefed<IPin>
-GetUnconnectedPin(IBaseFilter* aFilter, PIN_DIRECTION aPinDir)
-{
- RefPtr<IEnumPins> enumPins;
-
- HRESULT hr = aFilter->EnumPins(getter_AddRefs(enumPins));
- NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
-
- // Test each pin to see if it matches the direction we're looking for.
- RefPtr<IPin> pin;
- while (S_OK == enumPins->Next(1, getter_AddRefs(pin), nullptr)) {
- bool matches = FALSE;
- if (SUCCEEDED(MatchUnconnectedPin(pin, aPinDir, &matches)) &&
- matches) {
- return pin.forget();
- }
- }
-
- return nullptr;
-}
-
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter)
-{
- RefPtr<IPin> output = GetUnconnectedPin(aOutputFilter, PINDIR_OUTPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- RefPtr<IPin> input = GetUnconnectedPin(aInputFilter, PINDIR_INPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- return aGraph->Connect(output, input);
-}
-
-} // namespace mozilla
-
-// avoid redefined macro in unified build
-#undef WARN
diff --git a/dom/media/directshow/DirectShowUtils.h b/dom/media/directshow/DirectShowUtils.h
deleted file mode 100644
index 3bbc122fc..000000000
--- a/dom/media/directshow/DirectShowUtils.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _DirectShowUtils_h_
-#define _DirectShowUtils_h_
-
-#include <stdint.h>
-#include "dshow.h"
-
-// XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
-// GetPrevSibling are macros, apparently... Eeevil. We have functions
-// called that on some classes, so undef them.
-#undef GetFirstChild
-#undef GetNextSibling
-#undef GetPrevSibling
-
-#include "DShowTools.h"
-#include "mozilla/Logging.h"
-
-namespace mozilla {
-
-// Win32 "Event" wrapper. Must be paired with a CriticalSection to create a
-// Java-style "monitor".
-class Signal {
-public:
-
- Signal(CriticalSection* aLock)
- : mLock(aLock)
- {
- CriticalSectionAutoEnter lock(*mLock);
- mEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- }
-
- ~Signal() {
- CriticalSectionAutoEnter lock(*mLock);
- CloseHandle(mEvent);
- }
-
- // Lock must be held.
- void Notify() {
- SetEvent(mEvent);
- }
-
- // Lock must be held. Check the wait condition before waiting!
- HRESULT Wait() {
- mLock->Leave();
- DWORD result = WaitForSingleObject(mEvent, INFINITE);
- mLock->Enter();
- return result == WAIT_OBJECT_0 ? S_OK : E_FAIL;
- }
-
-private:
- CriticalSection* mLock;
- HANDLE mEvent;
-};
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister);
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister);
-
-const char*
-GetGraphNotifyString(long evCode);
-
-// Creates a filter and adds it to a graph.
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter);
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter);
-
-// Connects the output pin on aOutputFilter to an input pin on
-// aInputFilter, in aGraph.
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter);
-
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches);
-
-// Converts from microseconds to DirectShow "Reference Time"
-// (hundreds of nanoseconds).
-inline int64_t
-UsecsToRefTime(const int64_t aUsecs)
-{
- return aUsecs * 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to microseconds.
-inline int64_t
-RefTimeToUsecs(const int64_t hRefTime)
-{
- return hRefTime / 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to seconds.
-inline double
-RefTimeToSeconds(const REFERENCE_TIME aRefTime)
-{
- return double(aRefTime) / 10000000;
-}
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid);
-
-// Returns true if we can instantiate an MP3 demuxer and decoder filters.
-// Use this to detect whether MP3 support is installed.
-bool
-CanDecodeMP3UsingDirectShow();
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/SampleSink.cpp b/dom/media/directshow/SampleSink.cpp
deleted file mode 100644
index fa5dc8d19..000000000
--- a/dom/media/directshow/SampleSink.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-SampleSink::SampleSink()
- : mMonitor("SampleSink"),
- mIsFlushing(false),
- mAtEOS(false)
-{
- MOZ_COUNT_CTOR(SampleSink);
-}
-
-SampleSink::~SampleSink()
-{
- MOZ_COUNT_DTOR(SampleSink);
-}
-
-void
-SampleSink::SetAudioFormat(const WAVEFORMATEX* aInFormat)
-{
- NS_ENSURE_TRUE(aInFormat, );
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(&mAudioFormat, aInFormat, sizeof(WAVEFORMATEX));
-}
-
-void
-SampleSink::GetAudioFormat(WAVEFORMATEX* aOutFormat)
-{
- MOZ_ASSERT(aOutFormat);
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(aOutFormat, &mAudioFormat, sizeof(WAVEFORMATEX));
-}
-
-HRESULT
-SampleSink::Receive(IMediaSample* aSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
-
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (!mSample) {
- break;
- }
- if (mAtEOS) {
- return E_UNEXPECTED;
- }
- // Wait until the consumer thread consumes the sample.
- mon.Wait();
- }
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- REFERENCE_TIME start = 0, end = 0;
- HRESULT hr = aSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Receive() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = aSample;
- // Notify the signal, to awaken the consumer thread in WaitForSample()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-HRESULT
-SampleSink::Extract(RefPtr<IMediaSample>& aOutSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- // Loop until we have a sample, or we should abort.
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (mSample) {
- break;
- }
- if (mAtEOS) {
- // Order is important here, if we have a sample, we should return it
- // before reporting EOS.
- return E_UNEXPECTED;
- }
- // Wait until the producer thread gives us a sample.
- mon.Wait();
- }
- aOutSample = mSample;
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- int64_t start = 0, end = 0;
- mSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Extract() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = nullptr;
- // Notify the signal, to awaken the producer thread in Receive()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-void
-SampleSink::Flush()
-{
- LOG("SampleSink::Flush()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = true;
- mSample = nullptr;
- mon.NotifyAll();
-}
-
-void
-SampleSink::Reset()
-{
- LOG("SampleSink::Reset()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = false;
- mAtEOS = false;
-}
-
-void
-SampleSink::SetEOS()
-{
- LOG("SampleSink::SetEOS()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mAtEOS = true;
- // Notify to unblock any threads waiting for samples in
- // Extract() or Receive(). Now that we're at EOS, no more samples
- // will come!
- mon.NotifyAll();
-}
-
-bool
-SampleSink::AtEOS()
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- return mAtEOS && !mSample;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/SampleSink.h b/dom/media/directshow/SampleSink.h
deleted file mode 100644
index 6a1af9fee..000000000
--- a/dom/media/directshow/SampleSink.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(SampleSink_h_)
-#define SampleSink_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/ReentrantMonitor.h"
-
-namespace mozilla {
-
-class SampleSink {
-public:
- SampleSink();
- virtual ~SampleSink();
-
- // Sets the audio format of the incoming samples. The upstream filter
- // calls this. This makes a copy.
- void SetAudioFormat(const WAVEFORMATEX* aInFormat);
-
- // Copies the format of incoming audio samples into into *aOutFormat.
- void GetAudioFormat(WAVEFORMATEX* aOutFormat);
-
- // Called when a sample is delivered by the DirectShow graph to the sink.
- // The decode thread retrieves the sample by calling WaitForSample().
- // Blocks if there's already a sample waiting to be consumed by the decode
- // thread.
- HRESULT Receive(IMediaSample* aSample);
-
- // Retrieves a sample from the sample queue, blocking until one becomes
- // available, or until an error occurs. Returns S_FALSE on EOS.
- HRESULT Extract(RefPtr<IMediaSample>& aOutSample);
-
- // Unblocks any threads waiting in GetSample().
- // Clears mSample, which unblocks upstream stream.
- void Flush();
-
- // Opens up the sink to receive more samples in PutSample().
- // Clears EOS flag.
- void Reset();
-
- // Marks that we've reacehd the end of stream.
- void SetEOS();
-
- // Returns whether we're at end of stream.
- bool AtEOS();
-
-private:
- // All data in this class is syncronized by mMonitor.
- ReentrantMonitor mMonitor;
- RefPtr<IMediaSample> mSample;
-
- // Format of the audio stream we're receiving.
- WAVEFORMATEX mAudioFormat;
-
- bool mIsFlushing;
- bool mAtEOS;
-};
-
-} // namespace mozilla
-
-#endif // SampleSink_h_
diff --git a/dom/media/directshow/SourceFilter.cpp b/dom/media/directshow/SourceFilter.cpp
deleted file mode 100644
index 4c5a0882c..000000000
--- a/dom/media/directshow/SourceFilter.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SourceFilter.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "MP3FrameParser.h"
-#include "mozilla/Logging.h"
-#include <algorithm>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Define to trace what's on...
-//#define DEBUG_SOURCE_TRACE 1
-
-#if defined (DEBUG_SOURCE_TRACE)
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define DIRECTSHOW_LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-#else
-#define DIRECTSHOW_LOG(...)
-#endif
-
-static HRESULT
-DoGetInterface(IUnknown* aUnknown, void** aInterface)
-{
- if (!aInterface)
- return E_POINTER;
- *aInterface = aUnknown;
- aUnknown->AddRef();
- return S_OK;
-}
-
-// Stores details of IAsyncReader::Request().
-class ReadRequest {
-public:
-
- ReadRequest(IMediaSample* aSample,
- DWORD_PTR aDwUser,
- uint32_t aOffset,
- uint32_t aCount)
- : mSample(aSample),
- mDwUser(aDwUser),
- mOffset(aOffset),
- mCount(aCount)
- {
- MOZ_COUNT_CTOR(ReadRequest);
- }
-
- ~ReadRequest() {
- MOZ_COUNT_DTOR(ReadRequest);
- }
-
- RefPtr<IMediaSample> mSample;
- DWORD_PTR mDwUser;
- uint32_t mOffset;
- uint32_t mCount;
-};
-
-// A wrapper around media resource that presents only a partition of the
-// underlying resource to the caller to use. The partition returned is from
-// an offset to the end of stream, and this object deals with ensuring
-// the offsets and lengths etc are translated from the reduced partition
-// exposed to the caller, to the absolute offsets of the underlying stream.
-class MediaResourcePartition {
-public:
- MediaResourcePartition(MediaResource* aResource,
- int64_t aDataStart)
- : mResource(aResource),
- mDataOffset(aDataStart)
- {}
-
- int64_t GetLength() {
- int64_t len = mResource.GetLength();
- if (len == -1) {
- return len;
- }
- return std::max<int64_t>(0, len - mDataOffset);
- }
- nsresult ReadAt(int64_t aOffset, char* aBuffer,
- uint32_t aCount, uint32_t* aBytes)
- {
- return mResource.ReadAt(aOffset + mDataOffset,
- aBuffer,
- aCount,
- aBytes);
- }
- int64_t GetCachedDataEnd() {
- int64_t tell = mResource.GetResource()->Tell();
- int64_t dataEnd =
- mResource.GetResource()->GetCachedDataEnd(tell) - mDataOffset;
- return dataEnd;
- }
-private:
- // MediaResource from which we read data.
- MediaResourceIndex mResource;
- int64_t mDataOffset;
-};
-
-
-// Output pin for SourceFilter, which implements IAsyncReader, to
-// allow downstream filters to pull/read data from it. Downstream pins
-// register to read data using Request(), and asynchronously wait for the
-// reads to complete using WaitForNext(). They may also synchronously read
-// using SyncRead(). This class is a delegate (tear off) of
-// SourceFilter.
-//
-// We can expose only a segment of the MediaResource to the filter graph.
-// This is used to strip off the ID3v2 tags from the stream, as DirectShow
-// has trouble parsing some headers.
-//
-// Implements:
-// * IAsyncReader
-// * IPin
-// * IQualityControl
-// * IUnknown
-//
-class DECLSPEC_UUID("18e5cfb2-1015-440c-a65c-e63853235894")
-OutputPin : public IAsyncReader,
- public BasePin
-{
-public:
-
- OutputPin(MediaResource* aMediaResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart);
- virtual ~OutputPin();
-
- // IUnknown
- // Defer to ref counting to BasePin, which defers to owning nsBaseFilter.
- STDMETHODIMP_(ULONG) AddRef() override { return BasePin::AddRef(); }
- STDMETHODIMP_(ULONG) Release() override { return BasePin::Release(); }
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override;
-
- // BasePin Overrides.
- // Determines if the pin accepts a specific media type.
- HRESULT CheckMediaType(const MediaType* aMediaType) override;
-
- // Retrieves a preferred media type, by index value.
- HRESULT GetMediaType(int aPosition, MediaType* aMediaType) override;
-
- // Releases the pin from a connection.
- HRESULT BreakConnect(void) override;
-
- // Determines whether a pin connection is suitable.
- HRESULT CheckConnect(IPin* aPin) override;
-
-
- // IAsyncReader overrides
-
- // The RequestAllocator method requests an allocator during the
- // pin connection.
- STDMETHODIMP RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual) override;
-
- // The Request method queues an asynchronous request for data. Downstream
- // will call WaitForNext() when they want to retrieve the result.
- STDMETHODIMP Request(IMediaSample* aSample, DWORD_PTR aUserData) override;
-
- // The WaitForNext method waits for the next pending read request
- // to complete. This method fails if the graph is flushing.
- // Defers to SyncRead/5.
- STDMETHODIMP WaitForNext(DWORD aTimeout,
- IMediaSample** aSamples,
- DWORD_PTR* aUserData) override;
-
- // The SyncReadAligned method performs a synchronous read. The method
- // blocks until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncReadAligned(IMediaSample* aSample) override;
-
- // The SyncRead method performs a synchronous read. The method blocks
- // until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncRead(LONGLONG aPosition, LONG aLength, BYTE* aBuffer) override;
-
- // The Length method retrieves the total length of the stream.
- STDMETHODIMP Length(LONGLONG* aTotal, LONGLONG* aAvailable) override;
-
- // IPin Overrides
- STDMETHODIMP BeginFlush(void) override;
- STDMETHODIMP EndFlush(void) override;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-private:
-
- // Protects thread-shared data/structures (mFlushCount, mPendingReads).
- // WaitForNext() also waits on this monitor
- CriticalSection& mPinLock;
-
- // Signal used with mPinLock to implement WaitForNext().
- Signal mSignal;
-
- // The filter that owns us. Weak reference, as we're a delegate (tear off).
- SourceFilter* mParentSource;
-
- MediaResourcePartition mResource;
-
- // Counter, inc'd in BeginFlush(), dec'd in EndFlush(). Calls to this can
- // come from multiple threads and can interleave, hence the counter.
- int32_t mFlushCount;
-
- // Number of bytes that have been read from the output pin since the last
- // time GetAndResetBytesConsumedCount() was called.
- uint32_t mBytesConsumed;
-
- // Deque of ReadRequest* for reads that are yet to be serviced.
- // nsReadRequest's are stored on the heap, popper must delete them.
- nsDeque mPendingReads;
-
- // Flags if the downstream pin has QI'd for IAsyncReader. We refuse
- // connection if they don't query, as it means they're assuming that we're
- // a push filter, and we're not.
- bool mQueriedForAsyncReader;
-
-};
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-}
-__CRT_UUID_DECL(mozilla::OutputPin, 0x18e5cfb2,0x1015,0x440c,0xa6,0x5c,0xe6,0x38,0x53,0x23,0x58,0x94);
-namespace mozilla {
-#endif
-
-OutputPin::OutputPin(MediaResource* aResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart)
- : BasePin(static_cast<BaseFilter*>(aParent),
- &aFilterLock,
- L"MozillaOutputPin",
- PINDIR_OUTPUT),
- mPinLock(aFilterLock),
- mSignal(&mPinLock),
- mParentSource(aParent),
- mResource(aResource, aMP3DataStart),
- mFlushCount(0),
- mBytesConsumed(0),
- mQueriedForAsyncReader(false)
-{
- MOZ_COUNT_CTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::OutputPin()");
-}
-
-OutputPin::~OutputPin()
-{
- MOZ_COUNT_DTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::~OutputPin()");
-}
-
-HRESULT
-OutputPin::BreakConnect()
-{
- mQueriedForAsyncReader = false;
- return BasePin::BreakConnect();
-}
-
-STDMETHODIMP
-OutputPin::QueryInterface(REFIID aIId, void** aInterface)
-{
- if (aIId == IID_IAsyncReader) {
- mQueriedForAsyncReader = true;
- return DoGetInterface(static_cast<IAsyncReader*>(this), aInterface);
- }
-
- if (aIId == __uuidof(OutputPin)) {
- AddRef();
- *aInterface = this;
- return S_OK;
- }
-
- return BasePin::QueryInterface(aIId, aInterface);
-}
-
-HRESULT
-OutputPin::CheckConnect(IPin* aPin)
-{
- // Our connection is only suitable if the downstream pin knows
- // that we're asynchronous (i.e. it queried for IAsyncReader).
- return mQueriedForAsyncReader ? S_OK : S_FALSE;
-}
-
-HRESULT
-OutputPin::CheckMediaType(const MediaType* aMediaType)
-{
- const MediaType *myMediaType = mParentSource->GetMediaType();
-
- if (IsEqualGUID(aMediaType->majortype, myMediaType->majortype) &&
- IsEqualGUID(aMediaType->subtype, myMediaType->subtype) &&
- IsEqualGUID(aMediaType->formattype, myMediaType->formattype))
- {
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_OK;
- }
-
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Failed to match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_FALSE;
-}
-
-HRESULT
-OutputPin::GetMediaType(int aPosition, MediaType* aMediaType)
-{
- if (!aMediaType)
- return E_POINTER;
-
- if (aPosition == 0) {
- aMediaType->Assign(mParentSource->GetMediaType());
- return S_OK;
- }
- return VFW_S_NO_MORE_ITEMS;
-}
-
-static inline bool
-IsPowerOf2(int32_t x) {
- return ((-x & x) != x);
-}
-
-STDMETHODIMP
-OutputPin::RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual)
-{
- // Require the downstream pin to suggest what they want...
- if (!aPreferred) return E_POINTER;
- if (!aProps) return E_POINTER;
- if (!aActual) return E_POINTER;
-
- // We only care about alignment - our allocator will reject anything
- // which isn't power-of-2 aligned, so so try a 4-byte aligned allocator.
- ALLOCATOR_PROPERTIES props;
- memcpy(&props, aProps, sizeof(ALLOCATOR_PROPERTIES));
- if (aProps->cbAlign == 0 || IsPowerOf2(aProps->cbAlign)) {
- props.cbAlign = 4;
- }
-
- // Limit allocator's number of buffers. We know that the media will most
- // likely be bound by network speed, not by decoding speed. We also
- // store the incoming data in a Gecko stream, if we don't limit buffers
- // here we'll end up duplicating a lot of storage. We must have enough
- // space for audio key frames to fit in the first batch of buffers however,
- // else pausing may fail for some downstream decoders.
- if (props.cBuffers > BaseFilter::sMaxNumBuffers) {
- props.cBuffers = BaseFilter::sMaxNumBuffers;
- }
-
- // The allocator properties that are actually used. We don't store
- // this, we need it for SetProperties() below to succeed.
- ALLOCATOR_PROPERTIES actualProps;
- HRESULT hr;
-
- if (aPreferred) {
- // Play nice and prefer the downstream pin's preferred allocator.
- hr = aPreferred->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- aPreferred->AddRef();
- *aActual = aPreferred;
- return S_OK;
- }
- }
-
- // Else downstream hasn't requested a specific allocator, so create one...
-
- // Just create a default allocator. It's highly unlikely that we'll use
- // this anyway, as most parsers insist on using their own allocators.
- RefPtr<IMemAllocator> allocator;
- hr = CoCreateInstance(CLSID_MemoryAllocator,
- 0,
- CLSCTX_INPROC_SERVER,
- IID_IMemAllocator,
- getter_AddRefs(allocator));
- if(FAILED(hr) || (allocator == nullptr)) {
- NS_WARNING("Can't create our own DirectShow allocator.");
- return hr;
- }
-
- // See if we can make it suitable
- hr = allocator->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- // We need to release our refcount on pAlloc, and addref
- // it to pass a refcount to the caller - this is a net nothing.
- allocator.forget(aActual);
- return S_OK;
- }
-
- NS_WARNING("Failed to pick an allocator");
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::Request(IMediaSample* aSample, DWORD_PTR aDwUser)
-{
- if (!aSample) return E_FAIL;
-
- CriticalSectionAutoEnter lock(*mLock);
- NS_ASSERTION(!mFlushCount, "Request() while flushing");
-
- if (mFlushCount)
- return VFW_E_WRONG_STATE;
-
- REFERENCE_TIME refStart = 0, refEnd = 0;
- if (FAILED(aSample->GetTime(&refStart, &refEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- uint32_t start = (uint32_t)(refStart / 10000000);
- uint32_t end = (uint32_t)(refEnd / 10000000);
-
- uint32_t numBytes = end - start;
-
- ReadRequest* request = new ReadRequest(aSample,
- aDwUser,
- start,
- numBytes);
- // Memory for |request| is free when it's popped from the completed
- // reads list.
-
- // Push this onto the queue of reads to be serviced.
- mPendingReads.Push(request);
-
- // Notify any threads blocked in WaitForNext() which are waiting for mPendingReads
- // to become non-empty.
- mSignal.Notify();
-
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::WaitForNext(DWORD aTimeout,
- IMediaSample** aOutSample,
- DWORD_PTR* aOutDwUser)
-{
- NS_ASSERTION(aTimeout == 0 || aTimeout == INFINITE,
- "Oops, we don't handle this!");
-
- *aOutSample = nullptr;
- *aOutDwUser = 0;
-
- LONGLONG offset = 0;
- LONG count = 0;
- BYTE* buf = nullptr;
-
- {
- CriticalSectionAutoEnter lock(*mLock);
-
- // Wait until there's a pending read to service.
- while (aTimeout && mPendingReads.GetSize() == 0 && !mFlushCount) {
- // Note: No need to guard against shutdown-during-wait here, as
- // typically the thread doing the pull will have already called
- // Request(), so we won't Wait() here anyway. SyncRead() will fail
- // on shutdown.
- mSignal.Wait();
- }
-
- nsAutoPtr<ReadRequest> request(reinterpret_cast<ReadRequest*>(mPendingReads.PopFront()));
- if (!request)
- return VFW_E_WRONG_STATE;
-
- *aOutSample = request->mSample;
- *aOutDwUser = request->mDwUser;
-
- offset = request->mOffset;
- count = request->mCount;
- buf = nullptr;
- request->mSample->GetPointer(&buf);
- NS_ASSERTION(buf != nullptr, "Invalid buffer!");
-
- if (mFlushCount) {
- return VFW_E_TIMEOUT;
- }
- }
-
- return SyncRead(offset, count, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncReadAligned(IMediaSample* aSample)
-{
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- if (!aSample)
- return E_FAIL;
-
- REFERENCE_TIME lStart = 0, lEnd = 0;
- if (FAILED(aSample->GetTime(&lStart, &lEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- int32_t start = (int32_t)(lStart / 10000000);
- int32_t end = (int32_t)(lEnd / 10000000);
-
- int32_t numBytes = end - start;
-
- // If the range extends off the end of stream, truncate to the end of stream
- // as per IAsyncReader specificiation.
- int64_t streamLength = mResource.GetLength();
- if (streamLength != -1) {
- // We know the exact length of the stream, fail if the requested offset
- // is beyond it.
- if (start > streamLength) {
- return VFW_E_BADALIGN;
- }
-
- // If the end of the chunk to read is off the end of the stream,
- // truncate it to the end of the stream.
- if ((start + numBytes) > streamLength) {
- numBytes = (uint32_t)(streamLength - start);
- }
- }
-
- BYTE* buf=0;
- aSample->GetPointer(&buf);
-
- return SyncRead(start, numBytes, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncRead(LONGLONG aPosition,
- LONG aLength,
- BYTE* aBuffer)
-{
- MOZ_ASSERT(!NS_IsMainThread());
- NS_ENSURE_TRUE(aPosition >= 0, E_FAIL);
- NS_ENSURE_TRUE(aLength > 0, E_FAIL);
- NS_ENSURE_TRUE(aBuffer, E_POINTER);
-
- DIRECTSHOW_LOG("OutputPin::SyncRead(%lld, %d)", aPosition, aLength);
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- uint32_t totalBytesRead = 0;
- nsresult rv = mResource.ReadAt(aPosition,
- reinterpret_cast<char*>(aBuffer),
- aLength,
- &totalBytesRead);
- if (NS_FAILED(rv)) {
- return E_FAIL;
- }
- if (totalBytesRead > 0) {
- CriticalSectionAutoEnter lock(*mLock);
- mBytesConsumed += totalBytesRead;
- }
- return (totalBytesRead == aLength) ? S_OK : S_FALSE;
-}
-
-STDMETHODIMP
-OutputPin::Length(LONGLONG* aTotal, LONGLONG* aAvailable)
-{
- HRESULT hr = S_OK;
- int64_t length = mResource.GetLength();
- if (length == -1) {
- hr = VFW_S_ESTIMATED;
- // Don't have a length. Just lie, it seems to work...
- *aTotal = INT32_MAX;
- } else {
- *aTotal = length;
- }
- if (aAvailable) {
- *aAvailable = mResource.GetCachedDataEnd();
- }
-
- DIRECTSHOW_LOG("OutputPin::Length() len=%lld avail=%lld", *aTotal, *aAvailable);
-
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::BeginFlush()
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount++;
- mSignal.Notify();
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::EndFlush(void)
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount--;
- return S_OK;
-}
-
-uint32_t
-OutputPin::GetAndResetBytesConsumedCount()
-{
- CriticalSectionAutoEnter lock(*mLock);
- uint32_t bytesConsumed = mBytesConsumed;
- mBytesConsumed = 0;
- return bytesConsumed;
-}
-
-SourceFilter::SourceFilter(const GUID& aMajorType,
- const GUID& aSubType)
- : BaseFilter(L"MozillaDirectShowSource", __uuidof(SourceFilter))
-{
- MOZ_COUNT_CTOR(SourceFilter);
- mMediaType.majortype = aMajorType;
- mMediaType.subtype = aSubType;
-
- DIRECTSHOW_LOG("SourceFilter Constructor(%s, %s)",
- GetDirectShowGuidName(aMajorType),
- GetDirectShowGuidName(aSubType));
-}
-
-SourceFilter::~SourceFilter()
-{
- MOZ_COUNT_DTOR(SourceFilter);
- DIRECTSHOW_LOG("SourceFilter Destructor()");
-}
-
-BasePin*
-SourceFilter::GetPin(int n)
-{
- if (n == 0) {
- NS_ASSERTION(mOutputPin != 0, "GetPin with no pin!");
- return static_cast<BasePin*>(mOutputPin);
- } else {
- return nullptr;
- }
-}
-
-// Get's the media type we're supplying.
-const MediaType*
-SourceFilter::GetMediaType() const
-{
- return &mMediaType;
-}
-
-nsresult
-SourceFilter::Init(MediaResource* aResource, int64_t aMP3Offset)
-{
- DIRECTSHOW_LOG("SourceFilter::Init()");
-
- mOutputPin = new OutputPin(aResource,
- this,
- mLock,
- aMP3Offset);
- NS_ENSURE_TRUE(mOutputPin != nullptr, NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-uint32_t
-SourceFilter::GetAndResetBytesConsumedCount()
-{
- return mOutputPin->GetAndResetBytesConsumedCount();
-}
-
-
-} // namespace mozilla
diff --git a/dom/media/directshow/SourceFilter.h b/dom/media/directshow/SourceFilter.h
deleted file mode 100644
index d5ce2770e..000000000
--- a/dom/media/directshow/SourceFilter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(nsDirectShowSource_h___)
-#define nsDirectShowSource_h___
-
-#include "BaseFilter.h"
-#include "BasePin.h"
-#include "MediaType.h"
-
-#include "nsDeque.h"
-#include "nsAutoPtr.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class MediaResource;
-class OutputPin;
-
-
-// SourceFilter is an asynchronous DirectShow source filter which
-// reads from an MediaResource, and supplies data via a pull model downstream
-// using OutputPin. It us used to supply a generic byte stream into
-// DirectShow.
-//
-// Implements:
-// * IBaseFilter
-// * IMediaFilter
-// * IPersist
-// * IUnknown
-//
-class DECLSPEC_UUID("5c2a7ad0-ba82-4659-9178-c4719a2765d6")
-SourceFilter : public media::BaseFilter
-{
-public:
-
- // Constructs source filter to deliver given media type.
- SourceFilter(const GUID& aMajorType, const GUID& aSubType);
- ~SourceFilter();
-
- nsresult Init(MediaResource *aResource, int64_t aMP3Offset);
-
- // BaseFilter overrides.
- // Only one output - the byte stream.
- int GetPinCount() override { return 1; }
-
- media::BasePin* GetPin(int n) override;
-
- // Get's the media type we're supplying.
- const media::MediaType* GetMediaType() const;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-protected:
-
- // Our async pull output pin.
- nsAutoPtr<OutputPin> mOutputPin;
-
- // Type of byte stream we output.
- media::MediaType mMediaType;
-
-};
-
-} // namespace mozilla
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(mozilla::SourceFilter, 0x5c2a7ad0,0xba82,0x4659,0x91,0x78,0xc4,0x71,0x9a,0x27,0x65,0xd6);
-#endif
-
-#endif
diff --git a/dom/media/directshow/moz.build b/dom/media/directshow/moz.build
deleted file mode 100644
index 8a9b76200..000000000
--- a/dom/media/directshow/moz.build
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'AudioSinkFilter.h',
- 'AudioSinkInputPin.h',
- 'DirectShowDecoder.h',
- 'DirectShowReader.h',
- 'DirectShowUtils.h',
-]
-
-UNIFIED_SOURCES += [
- 'DirectShowDecoder.cpp',
- 'DirectShowUtils.cpp',
- 'SourceFilter.cpp',
-]
-
-SOURCES += [
- 'AudioSinkFilter.cpp',
- 'AudioSinkInputPin.cpp',
- 'DirectShowReader.cpp',
- 'SampleSink.cpp',
-]
-
-# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
-# they're available at link time.
-if not CONFIG['MOZ_WEBRTC']:
- SOURCES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
- ]
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
-]
diff --git a/dom/media/eme/DetailedPromise.cpp b/dom/media/eme/DetailedPromise.cpp
index 5893bea2e..d443e3336 100644
--- a/dom/media/eme/DetailedPromise.cpp
+++ b/dom/media/eme/DetailedPromise.cpp
@@ -96,9 +96,6 @@ DetailedPromise::MaybeReportTelemetry(Status aStatus)
uint32_t latency = (TimeStamp::Now() - mStartTime).ToMilliseconds();
EME_LOG("%s %s latency %ums reported via telemetry", mName.get(),
((aStatus == Succeeded) ? "succcess" : "failure"), latency);
- Telemetry::ID tid = (aStatus == Succeeded) ? mSuccessLatencyProbe.Value()
- : mFailureLatencyProbe.Value();
- Telemetry::Accumulate(tid, latency);
}
} // namespace dom
diff --git a/dom/media/eme/MediaKeySession.cpp b/dom/media/eme/MediaKeySession.cpp
index d5eff3f77..9c002b5ba 100644
--- a/dom/media/eme/MediaKeySession.cpp
+++ b/dom/media/eme/MediaKeySession.cpp
@@ -315,9 +315,6 @@ MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
// Note: Remaining steps of generateRequest method continue in CDM.
- Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED,
- ToCDMTypeTelemetryEnum(mKeySystem));
-
// Convert initData to base64 for easier logging.
// Note: CreateSession() Move()s the data out of the array, so we have
// to copy it here.
diff --git a/dom/media/eme/MediaKeys.cpp b/dom/media/eme/MediaKeys.cpp
index eedd675e4..fea548698 100644
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -13,7 +13,6 @@
#include "mozilla/dom/MediaKeySession.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/UnionTypes.h"
-#include "mozilla/Telemetry.h"
#include "GMPCDMProxy.h"
#ifdef MOZ_WIDGET_ANDROID
#include "mozilla/MediaDrmCDMProxy.h"
@@ -457,7 +456,6 @@ MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t
mKeySystem,
MediaKeySystemStatus::Cdm_created);
- Telemetry::Accumulate(Telemetry::VIDEO_CDM_CREATED, ToCDMTypeTelemetryEnum(mKeySystem));
}
static bool
diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp
index fdd6f2c7e..6954e9757 100644
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -83,10 +83,6 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
const bool isMP4Audio = aType.GetMIMEType().EqualsASCII("audio/mp4") ||
aType.GetMIMEType().EqualsASCII("audio/x-m4a");
const bool isMP4Video =
- // On B2G, treat 3GPP as MP4 when Gonk PDM is available.
-#ifdef MOZ_GONK_MEDIACODEC
- aType.GetMIMEType().EqualsASCII(VIDEO_3GPP) ||
-#endif
aType.GetMIMEType().EqualsASCII("video/mp4") ||
aType.GetMIMEType().EqualsASCII("video/quicktime") ||
aType.GetMIMEType().EqualsASCII("video/x-m4v");
@@ -139,6 +135,14 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
NS_LITERAL_CSTRING("audio/flac"), aType));
continue;
}
+#ifdef MOZ_AV1
+ if (IsAV1CodecString(codec)) {
+ trackInfos.AppendElement(
+ CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
+ NS_LITERAL_CSTRING("video/av1"), aType));
+ continue;
+ }
+#endif
// Note: Only accept H.264 in a video content type, not in an audio
// content type.
if (IsWhitelistedH264Codec(codec) && isMP4Video) {
diff --git a/dom/media/fmp4/MP4Demuxer.cpp b/dom/media/fmp4/MP4Demuxer.cpp
index 646897468..5a637b003 100644
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -81,35 +81,11 @@ private:
bool
AccumulateSPSTelemetry(const MediaByteBuffer* aExtradata)
{
+ // XXX: Do we still need this without telemetry?
mp4_demuxer::SPSData spsdata;
if (mp4_demuxer::H264::DecodeSPSFromExtraData(aExtradata, spsdata)) {
- uint8_t constraints = (spsdata.constraint_set0_flag ? (1 << 0) : 0) |
- (spsdata.constraint_set1_flag ? (1 << 1) : 0) |
- (spsdata.constraint_set2_flag ? (1 << 2) : 0) |
- (spsdata.constraint_set3_flag ? (1 << 3) : 0) |
- (spsdata.constraint_set4_flag ? (1 << 4) : 0) |
- (spsdata.constraint_set5_flag ? (1 << 5) : 0);
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_CONSTRAINT_SET_FLAG,
- constraints);
-
- // Collect profile_idc values up to 244, otherwise 0 for unknown.
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_PROFILE,
- spsdata.profile_idc <= 244 ? spsdata.profile_idc : 0);
-
- // Make sure level_idc represents a value between levels 1 and 5.2,
- // otherwise collect 0 for unknown level.
- Telemetry::Accumulate(Telemetry::VIDEO_DECODED_H264_SPS_LEVEL,
- (spsdata.level_idc >= 10 && spsdata.level_idc <= 52) ?
- spsdata.level_idc : 0);
-
- // max_num_ref_frames should be between 0 and 16, anything larger will
- // be treated as invalid.
- Telemetry::Accumulate(Telemetry::VIDEO_H264_SPS_MAX_NUM_REF_FRAMES,
- std::min(spsdata.max_num_ref_frames, 17u));
-
return false;
}
-
return true;
}
diff --git a/dom/media/fmp4/MP4Stream.cpp b/dom/media/fmp4/MP4Stream.cpp
index 615a7dc01..9a79cac7a 100644
--- a/dom/media/fmp4/MP4Stream.cpp
+++ b/dom/media/fmp4/MP4Stream.cpp
@@ -48,9 +48,6 @@ MP4Stream::BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnl
return true;
}
-// We surreptitiously reimplement the supposedly-blocking ReadAt as a non-
-// blocking CachedReadAt, and record when it fails. This allows MP4Reader
-// to retry the read as an actual blocking read without holding the lock.
bool
MP4Stream::ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
size_t* aBytesRead)
diff --git a/dom/media/fmp4/moz.build b/dom/media/fmp4/moz.build
index 6a249ae3e..a79fb0229 100644
--- a/dom/media/fmp4/moz.build
+++ b/dom/media/fmp4/moz.build
@@ -20,6 +20,3 @@ SOURCES += [
]
FINAL_LIBRARY = 'xul'
-
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp
index 40c3e5141..418f14736 100644
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -516,8 +516,7 @@ GMPCapability::Supports(const nsTArray<GMPCapability>& aCapabilities,
#ifdef XP_WIN
// Clearkey on Windows advertises that it can decode in its GMP info
// file, but uses Windows Media Foundation to decode. That's not present
- // on Windows XP, and on some Vista, Windows N, and KN variants without
- // certain services packs.
+ // on Windows N and KN variants without certain services packs.
if (tag.Equals(kEMEKeySystemClearkey)) {
if (capabilities.mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
if (!WMFDecoderModule::HasH264()) {
diff --git a/dom/media/gtest/Cargo.toml b/dom/media/gtest/Cargo.toml
deleted file mode 100644
index a55f8fb68..000000000
--- a/dom/media/gtest/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "mp4parse-gtest"
-version = "0.1.0"
-authors = ["nobody@mozilla.org"]
-
-[lib]
-path = "hello.rs"
diff --git a/dom/media/gtest/TestMP3Demuxer.cpp b/dom/media/gtest/TestMP3Demuxer.cpp
index 8d2109f00..934acb60e 100644
--- a/dom/media/gtest/TestMP3Demuxer.cpp
+++ b/dom/media/gtest/TestMP3Demuxer.cpp
@@ -11,7 +11,6 @@
#include "MockMediaResource.h"
using namespace mozilla;
-using namespace mozilla::mp3;
using media::TimeUnit;
diff --git a/dom/media/gtest/TestMP4Reader.cpp b/dom/media/gtest/TestMP4Reader.cpp
deleted file mode 100644
index f08f7a40d..000000000
--- a/dom/media/gtest/TestMP4Reader.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "gtest/gtest.h"
-#include "MP4Reader.h"
-#include "MP4Decoder.h"
-#include "mozilla/SharedThreadPool.h"
-#include "MockMediaResource.h"
-#include "MockMediaDecoderOwner.h"
-#include "mozilla/Preferences.h"
-#include "TimeUnits.h"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-class TestBinding
-{
-public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestBinding);
-
- RefPtr<MP4Decoder> decoder;
- RefPtr<MockMediaResource> resource;
- RefPtr<MP4Reader> reader;
-
- explicit TestBinding(const char* aFileName = "gizmo.mp4")
- : decoder(new MP4Decoder())
- , resource(new MockMediaResource(aFileName))
- , reader(new MP4Reader(decoder))
- {
- EXPECT_EQ(NS_OK, Preferences::SetBool(
- "media.use-blank-decoder", true));
-
- EXPECT_EQ(NS_OK, resource->Open(nullptr));
- decoder->SetResource(resource);
-
- reader->Init(nullptr);
- // This needs to be done before invoking GetBuffered. This is normally
- // done by MediaDecoderStateMachine.
- reader->DispatchSetStartTime(0);
- }
-
- void Init() {
- nsCOMPtr<nsIThread> thread;
- nsCOMPtr<nsIRunnable> r = NewRunnableMethod(this, &TestBinding::ReadMetadata);
- nsresult rv = NS_NewThread(getter_AddRefs(thread), r);
- EXPECT_EQ(NS_OK, rv);
- thread->Shutdown();
- }
-
-private:
- virtual ~TestBinding()
- {
- {
- RefPtr<TaskQueue> queue = reader->OwnerThread();
- nsCOMPtr<nsIRunnable> task = NewRunnableMethod(reader, &MP4Reader::Shutdown);
- // Hackily bypass the tail dispatcher so that we can AwaitShutdownAndIdle.
- // In production code we'd use BeginShutdown + promises.
- queue->Dispatch(task.forget(), AbstractThread::AssertDispatchSuccess,
- AbstractThread::TailDispatch);
- queue->AwaitShutdownAndIdle();
- }
- decoder = nullptr;
- resource = nullptr;
- reader = nullptr;
- SharedThreadPool::SpinUntilEmpty();
- }
-
- void ReadMetadata()
- {
- MediaInfo info;
- MetadataTags* tags;
- EXPECT_EQ(NS_OK, reader->ReadMetadata(&info, &tags));
- }
-};
-
-TEST(MP4Reader, BufferedRange)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Video 3-4 sec, audio 2.986666-4.010666 sec
- b->resource->MockAddBufferedRange(248400, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(360000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, BufferedRangeMissingLastByte)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Dropping the last byte of the video
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(248400, 324912);
- b->resource->MockAddBufferedRange(324913, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000.0 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(357000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, BufferedRangeSyncFrame)
-{
- RefPtr<TestBinding> b = new TestBinding();
- b->Init();
-
- // Check that missing the first byte at 2 seconds skips right through to 3
- // seconds because of a missing sync frame
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(146336, 327455);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
- EXPECT_NEAR(270000.0 / 90000.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(360000 / 90000.0, ranges.End(0).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, CompositionOrder)
-{
- RefPtr<TestBinding> b = new TestBinding("mediasource_test.mp4");
- b->Init();
-
- // The first 5 video samples of this file are:
- // Video timescale=2500
- // Frame Start Size Time Duration Sync
- // 1 48 5455 166 83 Yes
- // 2 5503 145 249 83
- // 3 6228 575 581 83
- // 4 7383 235 415 83
- // 5 8779 183 332 83
- // 6 9543 191 498 83
- //
- // Audio timescale=44100
- // 1 5648 580 0 1024 Yes
- // 2 6803 580 1024 1058 Yes
- // 3 7618 581 2082 1014 Yes
- // 4 8199 580 3096 1015 Yes
- // 5 8962 581 4111 1014 Yes
- // 6 9734 580 5125 1014 Yes
- // 7 10314 581 6139 1059 Yes
- // 8 11207 580 7198 1014 Yes
- // 9 12035 581 8212 1014 Yes
- // 10 12616 580 9226 1015 Yes
- // 11 13220 581 10241 1014 Yes
-
- b->resource->MockClearBufferedRanges();
- // First two frames in decoding + first audio frame
- b->resource->MockAddBufferedRange(48, 5503); // Video 1
- b->resource->MockAddBufferedRange(5503, 5648); // Video 2
- b->resource->MockAddBufferedRange(6228, 6803); // Video 3
-
- // Audio - 5 frames; 0 - 139206 us
- b->resource->MockAddBufferedRange(5648, 6228);
- b->resource->MockAddBufferedRange(6803, 7383);
- b->resource->MockAddBufferedRange(7618, 8199);
- b->resource->MockAddBufferedRange(8199, 8779);
- b->resource->MockAddBufferedRange(8962, 9563);
- b->resource->MockAddBufferedRange(9734, 10314);
- b->resource->MockAddBufferedRange(10314, 10895);
- b->resource->MockAddBufferedRange(11207, 11787);
- b->resource->MockAddBufferedRange(12035, 12616);
- b->resource->MockAddBufferedRange(12616, 13196);
- b->resource->MockAddBufferedRange(13220, 13901);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(2U, ranges.Length());
-
- EXPECT_NEAR(166.0 / 2500.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(332.0 / 2500.0, ranges.End(0).ToSeconds(), 0.000001);
-
- EXPECT_NEAR(581.0 / 2500.0, ranges.Start(1).ToSeconds(), 0.000001);
- EXPECT_NEAR(11255.0 / 44100.0, ranges.End(1).ToSeconds(), 0.000001);
-}
-
-TEST(MP4Reader, Normalised)
-{
- RefPtr<TestBinding> b = new TestBinding("mediasource_test.mp4");
- b->Init();
-
- // The first 5 video samples of this file are:
- // Video timescale=2500
- // Frame Start Size Time Duration Sync
- // 1 48 5455 166 83 Yes
- // 2 5503 145 249 83
- // 3 6228 575 581 83
- // 4 7383 235 415 83
- // 5 8779 183 332 83
- // 6 9543 191 498 83
- //
- // Audio timescale=44100
- // 1 5648 580 0 1024 Yes
- // 2 6803 580 1024 1058 Yes
- // 3 7618 581 2082 1014 Yes
- // 4 8199 580 3096 1015 Yes
- // 5 8962 581 4111 1014 Yes
- // 6 9734 580 5125 1014 Yes
- // 7 10314 581 6139 1059 Yes
- // 8 11207 580 7198 1014 Yes
- // 9 12035 581 8212 1014 Yes
- // 10 12616 580 9226 1015 Yes
- // 11 13220 581 10241 1014 Yes
-
- b->resource->MockClearBufferedRanges();
- b->resource->MockAddBufferedRange(48, 13901);
-
- media::TimeIntervals ranges = b->reader->GetBuffered();
- EXPECT_EQ(1U, ranges.Length());
-
- EXPECT_NEAR(166.0 / 2500.0, ranges.Start(0).ToSeconds(), 0.000001);
- EXPECT_NEAR(11255.0 / 44100.0, ranges.End(0).ToSeconds(), 0.000001);
-}
diff --git a/dom/media/gtest/TestRust.cpp b/dom/media/gtest/TestRust.cpp
deleted file mode 100644
index 86d0e99b8..000000000
--- a/dom/media/gtest/TestRust.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <stdint.h>
-#include "gtest/gtest.h"
-
-extern "C" uint8_t* test_rust();
-
-TEST(rust, CallFromCpp) {
- auto greeting = test_rust();
- EXPECT_STREQ(reinterpret_cast<char*>(greeting), "hello from rust.");
-}
diff --git a/dom/media/gtest/hello.rs b/dom/media/gtest/hello.rs
deleted file mode 100644
index cd111882a..000000000
--- a/dom/media/gtest/hello.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[no_mangle]
-pub extern fn test_rust() -> *const u8 {
- // NB: rust &str aren't null terminated.
- let greeting = "hello from rust.\0";
- greeting.as_ptr()
-}
diff --git a/dom/media/gtest/moz.build b/dom/media/gtest/moz.build
index d5d02bced..a7ea73807 100644
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -21,7 +21,6 @@ UNIFIED_SOURCES += [
'TestMozPromise.cpp',
'TestMP3Demuxer.cpp',
'TestMP4Demuxer.cpp',
- # 'TestMP4Reader.cpp', disabled so we can turn check tests back on (bug 1175752)
'TestTrackEncoder.cpp',
'TestVideoSegment.cpp',
'TestVideoUtils.cpp',
diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp
index af541bbbb..152c0085a 100644
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -62,8 +62,6 @@ namespace mozilla {
// Returns true if we should enable MSE webm regardless of preferences.
// 1. If MP4/H264 isn't supported:
-// * Windows XP
-// * Windows Vista and Server 2008 without the optional "Platform Update Supplement"
// * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
// optional "Windows Media Feature Pack"
// 2. If H264 hardware acceleration is not available.
diff --git a/dom/media/mediasource/moz.build b/dom/media/mediasource/moz.build
index 6ded1875d..a1689c216 100644
--- a/dom/media/mediasource/moz.build
+++ b/dom/media/mediasource/moz.build
@@ -38,9 +38,6 @@ TEST_DIRS += [
'gtest',
]
-if CONFIG['MOZ_GONK_MEDIACODEC']:
- DEFINES['MOZ_GONK_MEDIACODEC'] = True
-
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
diff --git a/dom/media/moz.build b/dom/media/moz.build
index 4d036a5f6..df8cb619d 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -30,6 +30,7 @@ DIRS += [
'ipc',
'mediasink',
'mediasource',
+ 'mp3',
'ogg',
'platforms',
'systemservices',
@@ -42,12 +43,6 @@ DIRS += [
'standalone',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- DIRS += ['directshow']
-
-if CONFIG['MOZ_ANDROID_OMX']:
- DIRS += ['android']
-
if CONFIG['MOZ_FMP4']:
DIRS += ['fmp4']
@@ -128,9 +123,6 @@ EXPORTS += [
'MediaTimer.h',
'MediaTrack.h',
'MediaTrackList.h',
- 'MP3Decoder.h',
- 'MP3Demuxer.h',
- 'MP3FrameParser.h',
'NextFrameSeekTask.h',
'nsIDocumentActivity.h',
'PrincipalChangeObserver.h',
@@ -237,9 +229,6 @@ UNIFIED_SOURCES += [
'MediaTimer.cpp',
'MediaTrack.cpp',
'MediaTrackList.cpp',
- 'MP3Decoder.cpp',
- 'MP3Demuxer.cpp',
- 'MP3FrameParser.cpp',
'NextFrameSeekTask.cpp',
'QueueObject.cpp',
'SeekJob.cpp',
@@ -294,11 +283,6 @@ LOCAL_INCLUDES += [
'/netwerk/base',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
- ]
-
if CONFIG['MOZ_WEBRTC']:
LOCAL_INCLUDES += [
'/media/webrtc/signaling/src/common',
diff --git a/dom/media/MP3Decoder.cpp b/dom/media/mp3/MP3Decoder.cpp
index b71111e79..074a0866d 100644
--- a/dom/media/MP3Decoder.cpp
+++ b/dom/media/mp3/MP3Decoder.cpp
@@ -24,7 +24,7 @@ MP3Decoder::Clone(MediaDecoderOwner* aOwner) {
MediaDecoderStateMachine*
MP3Decoder::CreateStateMachine() {
RefPtr<MediaDecoderReader> reader =
- new MediaFormatReader(this, new mp3::MP3Demuxer(GetResource()));
+ new MediaFormatReader(this, new MP3Demuxer(GetResource()));
return new MediaDecoderStateMachine(this, reader);
}
diff --git a/dom/media/MP3Decoder.h b/dom/media/mp3/MP3Decoder.h
index 887251065..887251065 100644
--- a/dom/media/MP3Decoder.h
+++ b/dom/media/mp3/MP3Decoder.h
diff --git a/dom/media/MP3Demuxer.cpp b/dom/media/mp3/MP3Demuxer.cpp
index 7d478a41b..5a98cabfe 100644
--- a/dom/media/MP3Demuxer.cpp
+++ b/dom/media/mp3/MP3Demuxer.cpp
@@ -33,7 +33,6 @@ using mozilla::media::TimeIntervals;
using mp4_demuxer::ByteReader;
namespace mozilla {
-namespace mp3 {
// MP3Demuxer
@@ -1338,5 +1337,4 @@ ID3Parser::ID3Header::Update(uint8_t c) {
return IsValid(mPos++);
}
-} // namespace mp3
} // namespace mozilla
diff --git a/dom/media/MP3Demuxer.h b/dom/media/mp3/MP3Demuxer.h
index 03e67b0d9..5331c4d54 100644
--- a/dom/media/MP3Demuxer.h
+++ b/dom/media/mp3/MP3Demuxer.h
@@ -13,7 +13,6 @@
#include <vector>
namespace mozilla {
-namespace mp3 {
class MP3TrackDemuxer;
@@ -468,7 +467,6 @@ private:
UniquePtr<AudioInfo> mInfo;
};
-} // namespace mp3
} // namespace mozilla
#endif
diff --git a/dom/media/mp3/moz.build b/dom/media/mp3/moz.build
new file mode 100644
index 000000000..596d061f8
--- /dev/null
+++ b/dom/media/mp3/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS += [
+ 'MP3Decoder.h',
+ 'MP3Demuxer.h',
+]
+
+UNIFIED_SOURCES += [
+ 'MP3Decoder.cpp',
+ 'MP3Demuxer.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/dom/media/ogg/OggDemuxer.cpp b/dom/media/ogg/OggDemuxer.cpp
index 591a5248f..0cc484687 100644
--- a/dom/media/ogg/OggDemuxer.cpp
+++ b/dom/media/ogg/OggDemuxer.cpp
@@ -12,7 +12,6 @@
#include "mozilla/Atomics.h"
#include "mozilla/PodOperations.h"
#include "mozilla/SharedThreadPool.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "MediaDataDemuxer.h"
#include "nsAutoRef.h"
@@ -164,7 +163,6 @@ OggDemuxer::~OggDemuxer()
MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug,
("OggDemuxer(%p)::%s: Reporting telemetry MEDIA_OGG_LOADED_IS_CHAINED=%d",
ptr, __func__, isChained));
- Telemetry::Accumulate(Telemetry::ID::MEDIA_OGG_LOADED_IS_CHAINED, isChained);
});
AbstractThread::MainThread()->Dispatch(task.forget());
}
diff --git a/dom/media/platforms/MediaTelemetryConstants.h b/dom/media/platforms/MediaTelemetryConstants.h
deleted file mode 100644
index 5024949a8..000000000
--- a/dom/media/platforms/MediaTelemetryConstants.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef dom_media_platforms_MediaTelemetryConstants_h___
-#define dom_media_platforms_MediaTelemetryConstants_h___
-
-namespace mozilla {
-namespace media {
-
-enum class MediaDecoderBackend : uint32_t
-{
- WMFSoftware = 0,
- WMFDXVA2D3D9 = 1,
- WMFDXVA2D3D11 = 2
-};
-
-} // namespace media
-} // namespace mozilla
-
-#endif // dom_media_platforms_MediaTelemetryConstants_h___
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index c1e58fdc2..5bfdcffb7 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -19,9 +19,6 @@
#ifdef MOZ_APPLEMEDIA
#include "AppleDecoderModule.h"
#endif
-#ifdef MOZ_GONK_MEDIACODEC
-#include "GonkDecoderModule.h"
-#endif
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidDecoderModule.h"
#endif
@@ -390,12 +387,6 @@ PDMFactory::CreatePDMs()
m = new AppleDecoderModule();
StartupPDM(m);
#endif
-#ifdef MOZ_GONK_MEDIACODEC
- if (MediaPrefs::PDMGonkDecoderEnabled()) {
- m = new GonkDecoderModule();
- StartupPDM(m);
- }
-#endif
#ifdef MOZ_WIDGET_ANDROID
if(MediaPrefs::PDMAndroidMediaCodecEnabled()){
m = new AndroidDecoderModule();
diff --git a/dom/media/platforms/agnostic/AOMDecoder.cpp b/dom/media/platforms/agnostic/AOMDecoder.cpp
new file mode 100644
index 000000000..b5d21375e
--- /dev/null
+++ b/dom/media/platforms/agnostic/AOMDecoder.cpp
@@ -0,0 +1,332 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "AOMDecoder.h"
+#include "MediaResult.h"
+#include "TimeUnits.h"
+#include "aom/aomdx.h"
+#include "aom/aom_image.h"
+#include "gfx2DGlue.h"
+#include "mozilla/PodOperations.h"
+#include "mozilla/SyncRunnable.h"
+#include "nsError.h"
+#include "prsystem.h"
+
+#include <algorithm>
+
+#undef LOG
+#define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("AOMDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+
+namespace mozilla {
+
+using namespace gfx;
+using namespace layers;
+
+AOMDecoder::AOMDecoder(const CreateDecoderParams& aParams)
+ : mImageContainer(aParams.mImageContainer)
+ , mTaskQueue(aParams.mTaskQueue)
+ , mCallback(aParams.mCallback)
+ , mIsFlushing(false)
+ , mInfo(aParams.VideoConfig())
+{
+ PodZero(&mCodec);
+}
+
+AOMDecoder::~AOMDecoder()
+{
+}
+
+void
+AOMDecoder::Shutdown()
+{
+ aom_codec_destroy(&mCodec);
+}
+
+RefPtr<MediaDataDecoder::InitPromise>
+AOMDecoder::Init()
+{
+ int decode_threads = 2;
+
+ aom_codec_iface_t* dx = aom_codec_av1_dx();
+ if (mInfo.mDisplay.width >= 2048) {
+ decode_threads = 8;
+ }
+ else if (mInfo.mDisplay.width >= 1024) {
+ decode_threads = 4;
+ }
+ decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());
+
+ aom_codec_dec_cfg_t config;
+ PodZero(&config);
+ config.threads = decode_threads;
+ config.w = config.h = 0; // set after decode
+ config.allow_lowbitdepth = true;
+
+ aom_codec_flags_t flags = 0;
+
+ if (!dx || aom_codec_dec_init(&mCodec, dx, &config, flags)) {
+ return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
+ }
+ return InitPromise::CreateAndResolve(TrackInfo::kVideoTrack, __func__);
+}
+
+void
+AOMDecoder::Flush()
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mIsFlushing = true;
+ nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([this] () {
+ // nothing to do for now.
+ });
+ SyncRunnable::DispatchToThread(mTaskQueue, r);
+ mIsFlushing = false;
+}
+
+// Ported from third_party/aom/tools_common.c.
+static aom_codec_err_t
+highbd_img_downshift(aom_image_t *dst, aom_image_t *src, int down_shift) {
+ int plane;
+ if (dst->d_w != src->d_w || dst->d_h != src->d_h)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->x_chroma_shift != src->x_chroma_shift)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->y_chroma_shift != src->y_chroma_shift)
+ return AOM_CODEC_INVALID_PARAM;
+ if (dst->fmt != (src->fmt & ~AOM_IMG_FMT_HIGHBITDEPTH))
+ return AOM_CODEC_INVALID_PARAM;
+ if (down_shift < 0)
+ return AOM_CODEC_INVALID_PARAM;
+ switch (dst->fmt) {
+ case AOM_IMG_FMT_I420:
+ case AOM_IMG_FMT_I422:
+ case AOM_IMG_FMT_I444:
+ break;
+ default:
+ return AOM_CODEC_INVALID_PARAM;
+ }
+ switch (src->fmt) {
+ case AOM_IMG_FMT_I42016:
+ case AOM_IMG_FMT_I42216:
+ case AOM_IMG_FMT_I44416:
+ break;
+ default:
+ // We don't support anything that's not 16 bit
+ return AOM_CODEC_UNSUP_BITSTREAM;
+ }
+ for (plane = 0; plane < 3; plane++) {
+ int w = src->d_w;
+ int h = src->d_h;
+ int x, y;
+ if (plane) {
+ w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
+ h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
+ }
+ for (y = 0; y < h; y++) {
+ uint16_t *p_src =
+ (uint16_t *)(src->planes[plane] + y * src->stride[plane]);
+ uint8_t *p_dst =
+ dst->planes[plane] + y * dst->stride[plane];
+ for (x = 0; x < w; x++) *p_dst++ = (*p_src++ >> down_shift) & 0xFF;
+ }
+ }
+ return AOM_CODEC_OK;
+}
+
+// UniquePtr dtor wrapper for aom_image_t.
+struct AomImageFree {
+ void operator()(aom_image_t* img) { aom_img_free(img); }
+};
+
+MediaResult
+AOMDecoder::DoDecode(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+
+#if defined(DEBUG)
+ NS_ASSERTION(IsKeyframe(*aSample) == aSample->mKeyframe,
+ "AOM Decode Keyframe error sample->mKeyframe and si.si_kf out of sync");
+#endif
+
+ if (aom_codec_err_t r = aom_codec_decode(&mCodec, aSample->Data(), aSample->Size(), nullptr)) {
+ LOG("AOM Decode error: %s", aom_codec_err_to_string(r));
+ return MediaResult(
+ NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("AOM error decoding AV1 sample: %s", aom_codec_err_to_string(r)));
+ }
+
+ aom_codec_iter_t iter = nullptr;
+ aom_image_t *img;
+ UniquePtr<aom_image_t, AomImageFree> img8;
+
+ while ((img = aom_codec_get_frame(&mCodec, &iter))) {
+ // Track whether the underlying buffer is 8 or 16 bits per channel.
+ bool highbd = bool(img->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
+ if (highbd) {
+ // Downsample images with more than 8 bits per channel.
+ aom_img_fmt_t fmt8 = static_cast<aom_img_fmt_t>(img->fmt ^ AOM_IMG_FMT_HIGHBITDEPTH);
+ img8.reset(aom_img_alloc(NULL, fmt8, img->d_w, img->d_h, 16));
+ if (img8 == nullptr) {
+ LOG("Couldn't allocate bitdepth reduction target!");
+ return MediaResult(
+ NS_ERROR_OUT_OF_MEMORY,
+ RESULT_DETAIL("Couldn't allocate conversion buffer for AV1 frame"));
+ }
+ if (aom_codec_err_t r = highbd_img_downshift(img8.get(), img, img->bit_depth - 8)) {
+ return MediaResult(
+ NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("Error converting AV1 frame to 8 bits: %s",
+ aom_codec_err_to_string(r)));
+ }
+ // img normally points to storage owned by mCodec, so it is not freed.
+ // To copy out the contents of img8 we can overwrite img with an alias.
+ // Since img is assigned at the start of the while loop and img8 is held
+ // outside that loop, the alias won't outlive the storage it points to.
+ img = img8.get();
+ highbd = false;
+ }
+
+ NS_ASSERTION(img->fmt == AOM_IMG_FMT_I420 ||
+ img->fmt == AOM_IMG_FMT_I42016 ||
+ img->fmt == AOM_IMG_FMT_I444 ||
+ img->fmt == AOM_IMG_FMT_I44416,
+ "AV1 image format not I420 or I444");
+
+ // Chroma shifts are rounded down as per the decoding examples in the SDK
+ VideoData::YCbCrBuffer b;
+ b.mPlanes[0].mData = img->planes[0];
+ b.mPlanes[0].mStride = img->stride[0];
+ b.mPlanes[0].mHeight = img->d_h;
+ b.mPlanes[0].mWidth = img->d_w;
+ b.mPlanes[0].mOffset = 0;
+ b.mPlanes[0].mSkip = highbd ? 1 : 0;
+
+ b.mPlanes[1].mData = img->planes[1];
+ b.mPlanes[1].mStride = img->stride[1];
+ b.mPlanes[1].mOffset = 0;
+ b.mPlanes[1].mSkip = highbd ? 1 : 0;
+
+ b.mPlanes[2].mData = img->planes[2];
+ b.mPlanes[2].mStride = img->stride[2];
+ b.mPlanes[2].mOffset = 0;
+ b.mPlanes[2].mSkip = highbd ? 1 : 0;
+
+ if (img->fmt == AOM_IMG_FMT_I420 ||
+ img->fmt == AOM_IMG_FMT_I42016) {
+ b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+ b.mPlanes[1].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
+
+ b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+ b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
+ } else if (img->fmt == AOM_IMG_FMT_I444) {
+ b.mPlanes[1].mHeight = img->d_h;
+ b.mPlanes[1].mWidth = img->d_w;
+
+ b.mPlanes[2].mHeight = img->d_h;
+ b.mPlanes[2].mWidth = img->d_w;
+ } else {
+ LOG("AOM Unknown image format");
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("AOM Unknown image format"));
+ }
+
+ RefPtr<VideoData> v =
+ VideoData::CreateAndCopyData(mInfo,
+ mImageContainer,
+ aSample->mOffset,
+ aSample->mTime,
+ aSample->mDuration,
+ b,
+ aSample->mKeyframe,
+ aSample->mTimecode,
+ mInfo.ScaledImageRect(img->d_w,
+ img->d_h));
+
+ if (!v) {
+ LOG("Image allocation error source %ux%u display %ux%u picture %ux%u",
+ img->d_w, img->d_h, mInfo.mDisplay.width, mInfo.mDisplay.height,
+ mInfo.mImage.width, mInfo.mImage.height);
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
+ mCallback->Output(v);
+ }
+ return NS_OK;
+}
+
+void
+AOMDecoder::ProcessDecode(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+ if (mIsFlushing) {
+ return;
+ }
+ MediaResult rv = DoDecode(aSample);
+ if (NS_FAILED(rv)) {
+ mCallback->Error(rv);
+ } else {
+ mCallback->InputExhausted();
+ }
+}
+
+void
+AOMDecoder::Input(MediaRawData* aSample)
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mTaskQueue->Dispatch(NewRunnableMethod<RefPtr<MediaRawData>>(
+ this, &AOMDecoder::ProcessDecode, aSample));
+}
+
+void
+AOMDecoder::ProcessDrain()
+{
+ MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+ mCallback->DrainComplete();
+}
+
+void
+AOMDecoder::Drain()
+{
+ MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+ mTaskQueue->Dispatch(NewRunnableMethod(this, &AOMDecoder::ProcessDrain));
+}
+
+/* static */
+bool
+AOMDecoder::IsAV1(const nsACString& aMimeType)
+{
+ return aMimeType.EqualsLiteral("video/webm; codecs=av1") ||
+ aMimeType.EqualsLiteral("video/av1");
+}
+
+/* static */
+bool
+AOMDecoder::IsKeyframe(Span<const uint8_t> aBuffer) {
+ aom_codec_stream_info_t info;
+ PodZero(&info);
+
+ aom_codec_peek_stream_info(aom_codec_av1_dx(),
+ aBuffer.Elements(),
+ aBuffer.Length(),
+ &info);
+
+ return bool(info.is_kf);
+}
+
+/* static */
+nsIntSize
+AOMDecoder::GetFrameSize(Span<const uint8_t> aBuffer) {
+ aom_codec_stream_info_t info;
+ PodZero(&info);
+
+ aom_codec_peek_stream_info(aom_codec_av1_dx(),
+ aBuffer.Elements(),
+ aBuffer.Length(),
+ &info);
+
+ return nsIntSize(info.w, info.h);
+}
+
+} // namespace mozilla
+#undef LOG
diff --git a/dom/media/platforms/agnostic/AOMDecoder.h b/dom/media/platforms/agnostic/AOMDecoder.h
new file mode 100644
index 000000000..ec6b1f95a
--- /dev/null
+++ b/dom/media/platforms/agnostic/AOMDecoder.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if !defined(AOMDecoder_h_)
+#define AOMDecoder_h_
+
+#include "PlatformDecoderModule.h"
+#include "mozilla/Span.h"
+
+#include <stdint.h>
+#include "aom/aom_decoder.h"
+
+namespace mozilla {
+
+class AOMDecoder : public MediaDataDecoder
+{
+public:
+ explicit AOMDecoder(const CreateDecoderParams& aParams);
+
+ RefPtr<InitPromise> Init() override;
+ void Input(MediaRawData* aSample) override;
+ void Flush() override;
+ void Drain() override;
+ void Shutdown() override;
+ const char* GetDescriptionName() const override
+ {
+ return "libaom (AV1) video decoder";
+ }
+
+ // Return true if aMimeType is a one of the strings used
+ // by our demuxers to identify AV1 streams.
+ static bool IsAV1(const nsACString& aMimeType);
+
+ // Return true if a sample is a keyframe.
+ static bool IsKeyframe(Span<const uint8_t> aBuffer);
+
+ // Return the frame dimensions for a sample.
+ static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer);
+
+private:
+ ~AOMDecoder();
+ void ProcessDecode(MediaRawData* aSample);
+ MediaResult DoDecode(MediaRawData* aSample);
+ void ProcessDrain();
+
+ const RefPtr<layers::ImageContainer> mImageContainer;
+ const RefPtr<TaskQueue> mTaskQueue;
+ MediaDataDecoderCallback* mCallback;
+ Atomic<bool> mIsFlushing;
+
+ // AOM decoder state
+ aom_codec_ctx_t mCodec;
+
+ const VideoInfo& mInfo;
+};
+
+} // namespace mozilla
+
+#endif // AOMDecoder_h_
diff --git a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
index 7bd75b7fe..cf5ed3d22 100644
--- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp
@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AgnosticDecoderModule.h"
+#include "MediaPrefs.h"
#include "mozilla/Logging.h"
#include "OpusDecoder.h"
#include "VorbisDecoder.h"
@@ -12,6 +13,10 @@
#include "WAVDecoder.h"
#include "TheoraDecoder.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
+
namespace mozilla {
bool
@@ -24,6 +29,11 @@ AgnosticDecoderModule::SupportsMimeType(const nsACString& aMimeType,
VorbisDataDecoder::IsVorbis(aMimeType) ||
WaveDataDecoder::IsWave(aMimeType) ||
TheoraDecoder::IsTheora(aMimeType);
+#ifdef MOZ_AV1
+ if (MediaPrefs::AV1Enabled()) {
+ supports |= AOMDecoder::IsAV1(aMimeType);
+ }
+#endif
MOZ_LOG(sPDMLog, LogLevel::Debug, ("Agnostic decoder %s requested type",
supports ? "supports" : "rejects"));
return supports;
@@ -36,7 +46,14 @@ AgnosticDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) {
m = new VPXDecoder(aParams);
- } else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
+ }
+#ifdef MOZ_AV1
+ else if (AOMDecoder::IsAV1(aParams.mConfig.mMimeType) &&
+ MediaPrefs::AV1Enabled()) {
+ m = new AOMDecoder(aParams);
+ }
+#endif
+ else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) {
m = new TheoraDecoder(aParams);
}
diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp
index 77c81b51b..f2f84487f 100644
--- a/dom/media/platforms/agnostic/VPXDecoder.cpp
+++ b/dom/media/platforms/agnostic/VPXDecoder.cpp
@@ -22,7 +22,7 @@ namespace mozilla {
using namespace gfx;
using namespace layers;
-static int MimeTypeToCodec(const nsACString& aMimeType)
+static VPXDecoder::Codec MimeTypeToCodec(const nsACString& aMimeType)
{
if (aMimeType.EqualsLiteral("video/webm; codecs=vp8")) {
return VPXDecoder::Codec::VP8;
@@ -31,7 +31,7 @@ static int MimeTypeToCodec(const nsACString& aMimeType)
} else if (aMimeType.EqualsLiteral("video/vp9")) {
return VPXDecoder::Codec::VP9;
}
- return -1;
+ return VPXDecoder::Codec::Unknown;
}
VPXDecoder::VPXDecoder(const CreateDecoderParams& aParams)
@@ -101,17 +101,10 @@ MediaResult
VPXDecoder::DoDecode(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
+
#if defined(DEBUG)
- vpx_codec_stream_info_t si;
- PodZero(&si);
- si.sz = sizeof(si);
- if (mCodec == Codec::VP8) {
- vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aSample->Data(), aSample->Size(), &si);
- } else if (mCodec == Codec::VP9) {
- vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aSample->Data(), aSample->Size(), &si);
- }
- NS_ASSERTION(bool(si.is_kf) == aSample->mKeyframe,
- "VPX Decode Keyframe error sample->mKeyframe and si.si_kf out of sync");
+ NS_ASSERTION(IsKeyframe(*aSample, mCodec) == aSample->mKeyframe,
+ "VPX Decode Keyframe error sample->mKeyframe and sample data out of sync");
#endif
if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) {
@@ -249,5 +242,41 @@ VPXDecoder::IsVP9(const nsACString& aMimeType)
return IsVPX(aMimeType, VPXDecoder::VP9);
}
+/* static */
+bool
+VPXDecoder::IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec)
+{
+ vpx_codec_stream_info_t si;
+ PodZero(&si);
+ si.sz = sizeof(si);
+
+ if (aCodec == Codec::VP8) {
+ vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ return bool(si.is_kf);
+ } else if (aCodec == Codec::VP9) {
+ vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ return bool(si.is_kf);
+ }
+
+ return false;
+}
+
+/* static */
+nsIntSize
+VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
+{
+ vpx_codec_stream_info_t si;
+ PodZero(&si);
+ si.sz = sizeof(si);
+
+ if (aCodec == Codec::VP8) {
+ vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ } else if (aCodec == Codec::VP9) {
+ vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), aBuffer.Elements(), aBuffer.Length(), &si);
+ }
+
+ return nsIntSize(si.w, si.h);
+}
+
} // namespace mozilla
#undef LOG
diff --git a/dom/media/platforms/agnostic/VPXDecoder.h b/dom/media/platforms/agnostic/VPXDecoder.h
index d420ec069..4e8d83617 100644
--- a/dom/media/platforms/agnostic/VPXDecoder.h
+++ b/dom/media/platforms/agnostic/VPXDecoder.h
@@ -7,6 +7,7 @@
#define VPXDecoder_h_
#include "PlatformDecoderModule.h"
+#include "mozilla/Span.h"
#include <stdint.h>
#define VPX_DONT_DEFINE_STDINT_TYPES
@@ -36,7 +37,8 @@ public:
enum Codec: uint8_t {
VP8 = 1 << 0,
- VP9 = 1 << 1
+ VP9 = 1 << 1,
+ Unknown = 1 << 7,
};
// Return true if aMimeType is a one of the strings used by our demuxers to
@@ -46,6 +48,12 @@ public:
static bool IsVP8(const nsACString& aMimeType);
static bool IsVP9(const nsACString& aMimeType);
+ // Return true if a sample is a keyframe for the specified codec.
+ static bool IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec);
+
+ // Return the frame dimensions for a sample for the specified codec.
+ static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
+
private:
void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample);
@@ -61,7 +69,7 @@ private:
const VideoInfo& mInfo;
- const int mCodec;
+ const Codec mCodec;
};
} // namespace mozilla
diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
index 8cb5c8578..8655ce25f 100644
--- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp
@@ -69,12 +69,21 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder()
mCodecContext->extradata_size = mExtraData->Length();
// FFmpeg may use SIMD instructions to access the data which reads the
// data in 32 bytes block. Must ensure we have enough data to read.
+ uint32_t padding_size =
#if LIBAVCODEC_VERSION_MAJOR >= 58
- mExtraData->AppendElements(AV_INPUT_BUFFER_PADDING_SIZE);
+ AV_INPUT_BUFFER_PADDING_SIZE;
#else
- mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE);
+ FF_INPUT_BUFFER_PADDING_SIZE;
#endif
- mCodecContext->extradata = mExtraData->Elements();
+ mCodecContext->extradata = static_cast<uint8_t*>(
+ mLib->av_malloc(mExtraData->Length() + padding_size));
+ if (!mCodecContext->extradata) {
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY,
+ RESULT_DETAIL("Couldn't init ffmpeg extradata"));
+ }
+ memcpy(mCodecContext->extradata,
+ mExtraData->Elements(),
+ mExtraData->Length());
} else {
mCodecContext->extradata_size = 0;
}
@@ -165,6 +174,9 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessShutdown()
StaticMutexAutoLock mon(sMonitor);
if (mCodecContext) {
+ if (mCodecContext->extradata) {
+ mLib->av_freep(&mCodecContext->extradata);
+ }
mLib->avcodec_close(mCodecContext);
mLib->av_freep(&mCodecContext);
#if LIBAVCODEC_VERSION_MAJOR >= 55
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
index 6302882a6..426e9f74b 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
@@ -7,6 +7,7 @@
#include "MediaPrefs.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Types.h"
+#include "PlatformDecoderModule.h"
#include "prlink.h"
#define AV_LOG_DEBUG 48
@@ -144,6 +145,8 @@ FFmpegLibWrapper::Link()
AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54))
AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54))
AV_FUNC(avcodec_free_frame, AV_FUNC_54)
+ AV_FUNC(avcodec_send_packet, AV_FUNC_58)
+ AV_FUNC(avcodec_receive_frame, AV_FUNC_58)
AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL)
AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL)
AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL)
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
index d6944a1d8..b968edd32 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
@@ -5,6 +5,7 @@
#ifndef __FFmpegLibWrapper_h__
#define __FFmpegLibWrapper_h__
+#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
struct AVCodec;
@@ -70,6 +71,10 @@ struct FFmpegLibWrapper
// libavcodec v54 only
void (*avcodec_free_frame)(AVFrame** frame);
+ // libavcodec v58 and later only
+ int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt);
+ int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame);
+
// libavutil
void (*av_log_set_level)(int level);
void* (*av_malloc)(size_t size);
@@ -91,4 +96,4 @@ private:
} // namespace mozilla
-#endif // FFmpegLibWrapper \ No newline at end of file
+#endif // FFmpegLibWrapper
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
index aec1e9136..f3101e44c 100644
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -174,12 +174,15 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, bool* aGotFrame)
uint8_t* inputData = const_cast<uint8_t*>(aSample->Data());
size_t inputSize = aSample->Size();
-#if LIBAVCODEC_VERSION_MAJOR >= 54
+#if LIBAVCODEC_VERSION_MAJOR >= 54 && LIBAVCODEC_VERSION_MAJOR < 58
if (inputSize && mCodecParser && (mCodecID == AV_CODEC_ID_VP8
-#if LIBAVCODEC_VERSION_MAJOR >= 55
+#if LIBAVCODEC_VERSION_MAJOR >= 55 && LIBAVCODEC_VERSION_MAJOR < 58
|| mCodecID == AV_CODEC_ID_VP9
#endif
- )) {
+ ))
+#endif
+#if LIBAVCODEC_VERSION_MAJOR >= 54
+ {
while (inputSize) {
uint8_t* data = inputData;
int size = inputSize;
@@ -224,6 +227,48 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0;
packet.pos = aSample->mOffset;
+#if LIBAVCODEC_VERSION_MAJOR >= 58
+ packet.duration = aSample->mDuration;
+ int res = mLib->avcodec_send_packet(mCodecContext, &packet);
+ if (res < 0) {
+ // In theory, avcodec_send_packet could sent -EAGAIN should its internal
+ // buffers be full. In practice this can't happen as we only feed one frame
+ // at a time, and we immediately call avcodec_receive_frame right after.
+ FFMPEG_LOG("avcodec_send_packet error: %d", res);
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("avcodec_send_packet error: %d", res));
+ }
+
+ if (aGotFrame) {
+ *aGotFrame = false;
+ }
+ do {
+ if (!PrepareFrame()) {
+ NS_WARNING("FFmpeg h264 decoder failed to allocate frame.");
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
+ res = mLib->avcodec_receive_frame(mCodecContext, mFrame);
+ if (res == int(AVERROR_EOF)) {
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+ }
+ if (res == AVERROR(EAGAIN)) {
+ return NS_OK;
+ }
+ if (res < 0) {
+ FFMPEG_LOG("avcodec_receive_frame error: %d", res);
+ return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+ RESULT_DETAIL("avcodec_receive_frame error: %d", res));
+ }
+ MediaResult rv = CreateImage(mFrame->pkt_pos, mFrame->pkt_pts,
+ mFrame->pkt_duration);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ if (aGotFrame) {
+ *aGotFrame = true;
+ }
+ } while (true);
+#else
// LibAV provides no API to retrieve the decoded sample's duration.
// (FFmpeg >= 1.0 provides av_frame_get_pkt_duration)
// As such we instead use a map using the dts as key that we will retrieve
@@ -276,8 +321,21 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
// against the map becoming extremely big.
mDurationMap.Clear();
}
+
+ MediaResult rv = CreateImage(aSample->mOffset, pts, duration);
+ if (NS_SUCCEEDED(rv) && aGotFrame) {
+ *aGotFrame = true;
+ }
+ return rv;
+#endif
+}
+
+MediaResult
+FFmpegVideoDecoder<LIBAV_VER>::CreateImage(int64_t aOffset, int64_t aPts,
+ int64_t aDuration)
+{
FFMPEG_LOG("Got one frame output with pts=%lld dts=%lld duration=%lld opaque=%lld",
- pts, mFrame->pkt_dts, duration, mCodecContext->reordered_opaque);
+ aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque);
VideoData::YCbCrBuffer b;
b.mPlanes[0].mData = mFrame->data[0];
@@ -317,9 +375,9 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
RefPtr<VideoData> v =
VideoData::CreateAndCopyData(mInfo,
mImageContainer,
- aSample->mOffset,
- pts,
- duration,
+ aOffset,
+ aPts,
+ aDuration,
b,
!!mFrame->key_frame,
-1,
@@ -331,9 +389,6 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
RESULT_DETAIL("image allocation error"));
}
mCallback->Output(v);
- if (aGotFrame) {
- *aGotFrame = true;
- }
return NS_OK;
}
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
index 786df0da1..49a55e8a6 100644
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -49,6 +49,7 @@ private:
MediaResult DoDecode(MediaRawData* aSample) override;
MediaResult DoDecode(MediaRawData* aSample, bool* aGotFrame);
MediaResult DoDecode(MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame);
+ MediaResult CreateImage(int64_t aOffset, int64_t aPts, int64_t aDuration);
void ProcessDrain() override;
void ProcessFlush() override;
void OutputDelayedFrames();
diff --git a/dom/media/platforms/ffmpeg/ffvpx/moz.build b/dom/media/platforms/ffmpeg/ffvpx/moz.build
index aee58b5b0..c0041a4d4 100644
--- a/dom/media/platforms/ffmpeg/ffvpx/moz.build
+++ b/dom/media/platforms/ffmpeg/ffvpx/moz.build
@@ -20,7 +20,7 @@ SOURCES += [
]
LOCAL_INCLUDES += [
'..',
- '../ffmpeg57/include',
+ '../ffmpeg58/include',
]
if CONFIG['OS_ARCH'] == 'WINNT':
diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build
index 3fb0cc842..f5fb72c5d 100644
--- a/dom/media/platforms/moz.build
+++ b/dom/media/platforms/moz.build
@@ -10,7 +10,6 @@ EXPORTS += [
'agnostic/TheoraDecoder.h',
'agnostic/VorbisDecoder.h',
'agnostic/VPXDecoder.h',
- 'MediaTelemetryConstants.h',
'PDMFactory.h',
'PlatformDecoderModule.h',
'wrappers/FuzzingWrapper.h',
@@ -55,6 +54,14 @@ if CONFIG['MOZ_FFMPEG']:
'ffmpeg',
]
+if CONFIG['MOZ_AV1']:
+ EXPORTS += [
+ 'agnostic/AOMDecoder.h',
+ ]
+ UNIFIED_SOURCES += [
+ 'agnostic/AOMDecoder.cpp',
+ ]
+
if CONFIG['MOZ_APPLEMEDIA']:
EXPORTS += [
'apple/AppleDecoderModule.h',
diff --git a/dom/media/platforms/omx/OmxPlatformLayer.cpp b/dom/media/platforms/omx/OmxPlatformLayer.cpp
index 039b4a22f..15b3062a4 100644
--- a/dom/media/platforms/omx/OmxPlatformLayer.cpp
+++ b/dom/media/platforms/omx/OmxPlatformLayer.cpp
@@ -282,26 +282,7 @@ OmxPlatformLayer::CompressionFormat()
}
}
-// Implementations for different platforms will be defined in their own files.
-#ifdef OMX_PLATFORM_GONK
-
-bool
-OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
-{
- return GonkOmxPlatformLayer::FindComponents(aMimeType);
-}
-
-OmxPlatformLayer*
-OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
- OmxPromiseLayer* aPromiseLayer,
- TaskQueue* aTaskQueue,
- layers::ImageContainer* aImageContainer)
-{
- return new GonkOmxPlatformLayer(aDataDecoder, aPromiseLayer, aTaskQueue, aImageContainer);
-}
-
-#else // For platforms without OMX IL support.
-
+// For platforms without OMX IL support.
bool
OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
{
@@ -317,6 +298,4 @@ OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
return nullptr;
}
-#endif
-
}
diff --git a/dom/media/platforms/wmf/DXVA2Manager.cpp b/dom/media/platforms/wmf/DXVA2Manager.cpp
index 0c1734c54..69e002f7f 100644
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -14,8 +14,6 @@
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/TextureForwarder.h"
-#include "mozilla/Telemetry.h"
-#include "MediaTelemetryConstants.h"
#include "mfapi.h"
#include "gfxPrefs.h"
#include "MFTDecoder.h"
@@ -442,9 +440,6 @@ D3D9DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor,
}
mTextureClientAllocator->SetMaxPoolSize(5);
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFDXVA2D3D9));
-
return S_OK;
}
@@ -775,9 +770,6 @@ D3D11DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor,
}
mTextureClientAllocator->SetMaxPoolSize(5);
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFDXVA2D3D11));
-
return S_OK;
}
diff --git a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
index 69b62da51..3dacdf0aa 100644
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
@@ -252,7 +252,6 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
LOG("Audio MFTDecoder returned success but null output.");
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([]() -> void {
LOG("Reporting telemetry AUDIO_MFT_OUTPUT_NULL_SAMPLES");
- Telemetry::Accumulate(Telemetry::ID::AUDIO_MFT_OUTPUT_NULL_SAMPLES, 1);
});
AbstractThread::MainThread()->Dispatch(task.forget());
return E_FAIL;
diff --git a/dom/media/platforms/wmf/WMFDecoderModule.h b/dom/media/platforms/wmf/WMFDecoderModule.h
index cd7b8c660..6582f8056 100644
--- a/dom/media/platforms/wmf/WMFDecoderModule.h
+++ b/dom/media/platforms/wmf/WMFDecoderModule.h
@@ -40,10 +40,8 @@ public:
static int GetNumDecoderThreads();
// Accessors that report whether we have the required MFTs available
- // on the system to play various codecs. Windows Vista doesn't have the
- // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
- // is not installed, and Window N and KN variants also require a "Media
- // Feature Pack" to be installed. Windows XP doesn't have WMF.
+ // on the system to play various codecs. Windows N and KN variants
+ // require a "Media Feature Pack" to be installed.
static bool HasAAC();
static bool HasH264();
diff --git a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
index d2c13eac7..15e2e1097 100644
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -8,7 +8,6 @@
#include "VideoUtils.h"
#include "WMFUtils.h"
#include "nsTArray.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Logging.h"
#include "mozilla/SyncRunnable.h"
@@ -67,7 +66,7 @@ SendTelemetry(unsigned long hr)
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
[sample] {
- Telemetry::Accumulate(Telemetry::MEDIA_WMF_DECODE_ERROR, sample);
+ /* Telemetry STUB */
});
NS_DispatchToMainThread(runnable);
}
diff --git a/dom/media/platforms/wmf/WMFMediaDataDecoder.h b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
index a4dd49f56..75571d61e 100644
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.h
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.h
@@ -33,7 +33,7 @@ public:
// Returns S_OK on success, or MF_E_TRANSFORM_NEED_MORE_INPUT if there's not
// enough data to produce more output. If this returns a failure code other
// than MF_E_TRANSFORM_NEED_MORE_INPUT, an error will be reported to the
- // MP4Reader.
+ // MP4Demuxer.
virtual HRESULT Output(int64_t aStreamOffset,
RefPtr<MediaData>& aOutput) = 0;
diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
index 291bc5b74..a7633a7de 100644
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -27,7 +27,6 @@
#include "mozilla/WindowsVersion.h"
#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
-#include "MediaTelemetryConstants.h"
#include "GMPUtils.h" // For SplitAt. TODO: Move SplitAt to a central place.
#include "MP4Decoder.h"
#include "VPXDecoder.h"
@@ -128,7 +127,6 @@ WMFVideoMFTManager::~WMFVideoMFTManager()
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([=]() -> void {
LOG(nsPrintfCString("Reporting telemetry VIDEO_MFT_OUTPUT_NULL_SAMPLES=%d", telemetry).get());
- Telemetry::Accumulate(Telemetry::ID::VIDEO_MFT_OUTPUT_NULL_SAMPLES, telemetry);
});
AbstractThread::MainThread()->Dispatch(task.forget());
}
@@ -511,8 +509,6 @@ WMFVideoMFTManager::InitInternal(bool aForceD3D9)
if (mStreamType == VP9 || mStreamType == VP8) {
return false;
}
- Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED,
- uint32_t(media::MediaDecoderBackend::WMFSoftware));
}
mDecoder = decoder;
diff --git a/dom/media/systemservices/LoadManager.cpp b/dom/media/systemservices/LoadManager.cpp
index f0f4f83a7..34b8fc7e0 100644
--- a/dom/media/systemservices/LoadManager.cpp
+++ b/dom/media/systemservices/LoadManager.cpp
@@ -15,7 +15,6 @@
#include "nsThreadUtils.h"
#include "nsReadableUtils.h"
#include "nsIObserverService.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/ArrayUtils.h"
// MOZ_LOG=LoadManager:5
@@ -192,23 +191,6 @@ LoadManagerSingleton::RemoveObserver(webrtc::CPULoadStateObserver * aObserver)
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(mTimeInState); i++) {
total += mTimeInState[i];
}
- // Don't include short calls; we don't have reasonable load data, and
- // such short calls rarely reach a stable state. Keep relatively
- // short calls separate from longer ones
- bool log = total > 5*PR_MSEC_PER_SEC;
- bool small = log && total < 30*PR_MSEC_PER_SEC;
- if (log) {
- // Note: We don't care about rounding here; thus total may be < 100
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_RELAXED_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_RELAXED,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadRelaxed]/total * 100));
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_NORMAL_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_NORMAL,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadNormal]/total * 100));
- Telemetry::Accumulate(small ? Telemetry::WEBRTC_LOAD_STATE_STRESSED_SHORT :
- Telemetry::WEBRTC_LOAD_STATE_STRESSED,
- (uint32_t) (mTimeInState[webrtc::CPULoadState::kLoadStressed]/total * 100));
- }
for (auto &in_state : mTimeInState) {
in_state = 0;
}
diff --git a/dom/media/test/bug580982.webm b/dom/media/test/bug1377278.webm
index 802019f39..802019f39 100644
--- a/dom/media/test/bug580982.webm
+++ b/dom/media/test/bug1377278.webm
Binary files differ
diff --git a/dom/media/test/bug580982.webm^headers^ b/dom/media/test/bug1377278.webm^headers^
index 4030ea1d3..4030ea1d3 100644
--- a/dom/media/test/bug580982.webm^headers^
+++ b/dom/media/test/bug1377278.webm^headers^
diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js
index c6d533c1b..52e53a271 100644
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -224,6 +224,9 @@ var gPlayTests = [
// Test playback of a webm file
{ name:"seek-short.webm", type:"video/webm", duration:0.23 },
+ // Test playback of a webm file with 'matroska' doctype
+ { name:"bug1377278.webm", type:"video/webm", duration:4.0 },
+
// Test playback of a WebM file with non-zero start time.
{ name:"split.webm", type:"video/webm", duration:1.967 },
@@ -263,10 +266,10 @@ var gPlayTests = [
{ name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
{ name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something funny going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.343 },
// One second of silence with ~140KB of ID3 tags. Usually when the first MP3
// frame is at such a high offset into the file, MP3FrameParser will give up
@@ -532,7 +535,6 @@ var gErrorTests = [
{ name:"448636.ogv", type:"video/ogg" },
{ name:"bug504843.ogv", type:"video/ogg" },
{ name:"bug501279.ogg", type:"audio/ogg" },
- { name:"bug580982.webm", type:"video/webm" },
{ name:"bug603918.webm", type:"video/webm" },
{ name:"bug604067.webm", type:"video/webm" },
{ name:"bogus.duh", type:"bogus/duh" }
diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini
index ddabf78b6..742ac1b1c 100644
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -382,8 +382,6 @@ support-files =
bug556821.ogv^headers^
bug557094.ogv
bug557094.ogv^headers^
- bug580982.webm
- bug580982.webm^headers^
bug603918.webm
bug603918.webm^headers^
bug604067.webm
@@ -395,6 +393,8 @@ support-files =
bug1301226.wav^headers^
bug1301226-odd.wav
bug1301226-odd.wav^headers^
+ bug1377278.webm
+ bug1377278.webm^headers^
can_play_type_dash.js
can_play_type_ogg.js
can_play_type_wave.js
diff --git a/dom/media/test/test_can_play_type_mpeg.html b/dom/media/test/test_can_play_type_mpeg.html
index 89e5fabef..514b5cc2f 100644
--- a/dom/media/test/test_can_play_type_mpeg.html
+++ b/dom/media/test/test_can_play_type_mpeg.html
@@ -151,8 +151,7 @@ var haveMp4 = (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
check_mp4(document.getElementById('v'), haveMp4);
-var haveMp3 = getPref("media.directshow.enabled") ||
- (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
+var haveMp3 = getPref("media.wmf.enabled") ||
(IsLinux() && getPref("media.ffmpeg.enabled")) ||
(IsSupportedAndroid() &&
((IsJellyBeanOrLater() && getPref("media.android-media-codec.enabled")) ||
diff --git a/dom/media/webaudio/MediaBufferDecoder.cpp b/dom/media/webaudio/MediaBufferDecoder.cpp
index e9f1d5a47..2ee11eacd 100644
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -23,7 +23,6 @@
#include "VideoUtils.h"
#include "WebAudioUtils.h"
#include "mozilla/dom/Promise.h"
-#include "mozilla/Telemetry.h"
#include "nsPrintfCString.h"
#include "GMPService.h"
@@ -302,7 +301,6 @@ MediaDecodeTask::OnMetadataRead(MetadataHolder* aMetadata)
MOZ_LOG(gMediaDecoderLog,
LogLevel::Debug,
("Telemetry (WebAudio) MEDIA_CODEC_USED= '%s'", codec.get()));
- Telemetry::Accumulate(Telemetry::ID::MEDIA_CODEC_USED, codec);
});
AbstractThread::MainThread()->Dispatch(task.forget());
diff --git a/dom/media/webm/WebMDecoder.cpp b/dom/media/webm/WebMDecoder.cpp
index b41de6d40..9575d6e42 100644
--- a/dom/media/webm/WebMDecoder.cpp
+++ b/dom/media/webm/WebMDecoder.cpp
@@ -5,6 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Preferences.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
+#include "MediaPrefs.h"
#include "MediaDecoderStateMachine.h"
#include "WebMDemuxer.h"
#include "WebMDecoder.h"
@@ -65,6 +69,11 @@ WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
continue;
}
+#ifdef MOZ_AV1
+ if (MediaPrefs::AV1Enabled() && IsAV1CodecString(codec)) {
+ continue;
+ }
+#endif
// Some unsupported codec.
return false;
}
diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp
index 20ed71581..013da9b2c 100644
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -8,7 +8,11 @@
#include "MediaDecoderStateMachine.h"
#include "AbstractMediaDecoder.h"
#include "MediaResource.h"
+#ifdef MOZ_AV1
+#include "AOMDecoder.h"
+#endif
#include "OpusDecoder.h"
+#include "VPXDecoder.h"
#include "WebMDemuxer.h"
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
@@ -24,12 +28,9 @@
#include "mozilla/Sprintf.h"
#include <algorithm>
+#include <numeric>
#include <stdint.h>
-#define VPX_DONT_DEFINE_STDINT_TYPES
-#include "vpx/vp8dx.h"
-#include "vpx/vpx_decoder.h"
-
#define WEBM_DEBUG(arg, ...) MOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, ("WebMDemuxer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
extern mozilla::LazyLogModule gMediaDemuxerLog;
@@ -322,6 +323,9 @@ WebMDemuxer::ReadMetadata()
case NESTEGG_CODEC_VP9:
mInfo.mVideo.mMimeType = "video/webm; codecs=vp9";
break;
+ case NESTEGG_CODEC_AV1:
+ mInfo.mVideo.mMimeType = "video/webm; codecs=av1";
+ break;
default:
NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE;
@@ -549,7 +553,7 @@ WebMDemuxer::GetTrackCrypto(TrackInfo::TrackType aType, size_t aTrackNumber) {
return crypto;
}
-bool
+nsresult
WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples)
{
if (mIsMediaSource) {
@@ -557,17 +561,18 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
EnsureUpToDateIndex();
}
- RefPtr<NesteggPacketHolder> holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = NextPacket(aType, holder);
- if (!holder) {
- return false;
+ if (NS_FAILED(rv)) {
+ return rv;
}
int r = 0;
unsigned int count = 0;
r = nestegg_packet_count(holder->Packet(), &count);
if (r == -1) {
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t tstamp = holder->Timestamp();
int64_t duration = holder->Duration();
@@ -578,7 +583,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
// video frame.
int64_t next_tstamp = INT64_MIN;
if (aType == TrackInfo::kAudioTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushAudioPacket(next_holder);
@@ -593,7 +602,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
mLastAudioFrameTime = Some(tstamp);
} else if (aType == TrackInfo::kVideoTrack) {
- RefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
+ RefPtr<NesteggPacketHolder> next_holder;
+ rv = NextPacket(aType, next_holder);
+ if (NS_FAILED(rv) && rv != NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ return rv;
+ }
if (next_holder) {
next_tstamp = next_holder->Timestamp();
PushVideoPacket(next_holder);
@@ -610,7 +623,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
if (mIsMediaSource && next_tstamp == INT64_MIN) {
- return false;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
}
int64_t discardPadding = 0;
@@ -626,7 +639,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
r = nestegg_packet_data(holder->Packet(), i, &data, &length);
if (r == -1) {
WEBM_DEBUG("nestegg_packet_data failed r=%d", r);
- return false;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
bool isKeyframe = false;
if (aType == TrackInfo::kAudioTrack) {
@@ -636,29 +649,46 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
// Packet is encrypted, can't peek, use packet info
isKeyframe = nestegg_packet_has_keyframe(holder->Packet()) == NESTEGG_PACKET_HAS_KEYFRAME_TRUE;
} else {
- vpx_codec_stream_info_t si;
- PodZero(&si);
- si.sz = sizeof(si);
+ auto sample = MakeSpan(data, length);
switch (mVideoCodec) {
case NESTEGG_CODEC_VP8:
- vpx_codec_peek_stream_info(vpx_codec_vp8_dx(), data, length, &si);
+ isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP8);
break;
case NESTEGG_CODEC_VP9:
- vpx_codec_peek_stream_info(vpx_codec_vp9_dx(), data, length, &si);
+ isKeyframe = VPXDecoder::IsKeyframe(sample, VPXDecoder::Codec::VP9);
+ break;
+#ifdef MOZ_AV1
+ case NESTEGG_CODEC_AV1:
+ isKeyframe = AOMDecoder::IsKeyframe(sample);
break;
+#endif
+ default:
+ NS_WARNING("Cannot detect keyframes in unknown WebM video codec");
+ return NS_ERROR_FAILURE;
}
- isKeyframe = si.is_kf;
if (isKeyframe) {
- // We only look for resolution changes on keyframes for both VP8 and
- // VP9. Other resolution changes are invalid.
- if (mLastSeenFrameWidth.isSome() && mLastSeenFrameHeight.isSome() &&
- (si.w != mLastSeenFrameWidth.value() ||
- si.h != mLastSeenFrameHeight.value())) {
- mInfo.mVideo.mDisplay = nsIntSize(si.w, si.h);
+ // For both VP8 and VP9, we only look for resolution changes
+ // on keyframes. Other resolution changes are invalid.
+ auto dimensions = nsIntSize(0, 0);
+ switch (mVideoCodec) {
+ case NESTEGG_CODEC_VP8:
+ dimensions = VPXDecoder::GetFrameSize(sample, VPXDecoder::Codec::VP8);
+ break;
+ case NESTEGG_CODEC_VP9:
+ dimensions = VPXDecoder::GetFrameSize(sample, VPXDecoder::Codec::VP9);
+ break;
+#ifdef MOZ_AV1
+ case NESTEGG_CODEC_AV1:
+ dimensions = AOMDecoder::GetFrameSize(sample);
+ break;
+#endif
+ }
+ if (mLastSeenFrameSize.isSome()
+ && (dimensions != mLastSeenFrameSize.value())) {
+ mInfo.mVideo.mDisplay = dimensions;
mSharedVideoTrackInfo = new SharedTrackInfo(mInfo.mVideo, ++sStreamSourceID);
}
- mLastSeenFrameWidth = Some(si.w);
- mLastSeenFrameHeight = Some(si.h);
+ mLastSeenFrameSize = Some(dimensions);
}
}
}
@@ -668,7 +698,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
RefPtr<MediaRawData> sample = new MediaRawData(data, length);
if (length && !sample->Data()) {
// OOM.
- return false;
+ return NS_ERROR_OUT_OF_MEMORY;
}
sample->mTimecode = tstamp;
sample->mTime = tstamp;
@@ -721,11 +751,12 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
}
aSamples->Push(sample);
}
- return true;
+ return NS_OK;
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
bool isVideo = aType == TrackInfo::kVideoTrack;
@@ -734,56 +765,64 @@ WebMDemuxer::NextPacket(TrackInfo::TrackType aType)
bool hasType = isVideo ? mHasVideo : mHasAudio;
if (!hasType) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
// The packet queue for the type that we are interested in.
WebMPacketQueue &packets = isVideo ? mVideoPackets : mAudioPackets;
if (packets.GetSize() > 0) {
- return packets.PopFront();
+ aPacket = packets.PopFront();
+ return NS_OK;
}
// Track we are interested in
uint32_t ourTrack = isVideo ? mVideoTrack : mAudioTrack;
do {
- RefPtr<NesteggPacketHolder> holder = DemuxPacket(aType);
+ RefPtr<NesteggPacketHolder> holder;
+ nsresult rv = DemuxPacket(aType, holder);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
if (!holder) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
if (ourTrack == holder->Track()) {
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
} while (true);
}
-RefPtr<NesteggPacketHolder>
-WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType)
+nsresult
+WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket)
{
nestegg_packet* packet;
int r = nestegg_read_packet(Context(aType), &packet);
if (r == 0) {
nestegg_read_reset(Context(aType));
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_END_OF_STREAM;
} else if (r < 0) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
unsigned int track = 0;
r = nestegg_packet_track(packet, &track);
if (r == -1) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
int64_t offset = Resource(aType).Tell();
RefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder();
if (!holder->Init(packet, offset, track, false)) {
- return nullptr;
+ return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
}
- return holder;
+ aPacket = holder;
+ return NS_OK;
}
void
@@ -943,7 +982,14 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
media::TimeUnit seekTime = aTime;
mSamples.Reset();
mParent->SeekInternal(mType, aTime);
- mParent->GetNextPacket(mType, &mSamples);
+ nsresult rv = mParent->GetNextPacket(mType, &mSamples);
+ if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ // Ignore the error for now, the next GetSample will be rejected with EOS.
+ return SeekPromise::CreateAndResolve(media::TimeUnit(), __func__);
+ }
+ return SeekPromise::CreateAndReject(rv, __func__);
+ }
mNeedKeyframe = true;
// Check what time we actually seeked to.
@@ -956,15 +1002,18 @@ WebMTrackDemuxer::Seek(media::TimeUnit aTime)
return SeekPromise::CreateAndResolve(seekTime, __func__);
}
-RefPtr<MediaRawData>
-WebMTrackDemuxer::NextSample()
+nsresult
+WebMTrackDemuxer::NextSample(RefPtr<MediaRawData>& aData)
{
- while (mSamples.GetSize() < 1 && mParent->GetNextPacket(mType, &mSamples)) {
+ nsresult rv;
+ while (mSamples.GetSize() < 1 &&
+ NS_SUCCEEDED((rv = mParent->GetNextPacket(mType, &mSamples)))) {
}
if (mSamples.GetSize()) {
- return mSamples.PopFront();
+ aData = mSamples.PopFront();
+ return NS_OK;
}
- return nullptr;
+ return rv;
}
RefPtr<WebMTrackDemuxer::SamplesPromise>
@@ -973,9 +1022,12 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
RefPtr<SamplesHolder> samples = new SamplesHolder;
MOZ_ASSERT(aNumSamples);
+ nsresult rv = NS_ERROR_DOM_MEDIA_END_OF_STREAM;
+
while (aNumSamples) {
- RefPtr<MediaRawData> sample(NextSample());
- if (!sample) {
+ RefPtr<MediaRawData> sample;
+ rv = NextSample(sample);
+ if (NS_FAILED(rv)) {
break;
}
if (mNeedKeyframe && !sample->mKeyframe) {
@@ -987,7 +1039,7 @@ WebMTrackDemuxer::GetSamples(int32_t aNumSamples)
}
if (samples->mSamples.IsEmpty()) {
- return SamplesPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
+ return SamplesPromise::CreateAndReject(rv, __func__);
} else {
UpdateSamples(samples->mSamples);
return SamplesPromise::CreateAndResolve(samples, __func__);
@@ -1022,7 +1074,8 @@ WebMTrackDemuxer::SetNextKeyFrameTime()
}
// Demux and buffer frames until we find a keyframe.
RefPtr<MediaRawData> sample;
- while (!foundKeyframe && (sample = NextSample())) {
+ nsresult rv = NS_OK;
+ while (!foundKeyframe && NS_SUCCEEDED((rv = NextSample(sample)))) {
if (sample->mKeyframe) {
frameTime = sample->mTime;
foundKeyframe = true;
@@ -1104,10 +1157,11 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
uint32_t parsed = 0;
bool found = false;
RefPtr<MediaRawData> sample;
+ nsresult rv = NS_OK;
int64_t sampleTime;
WEBM_DEBUG("TimeThreshold: %f", aTimeThreshold.ToSeconds());
- while (!found && (sample = NextSample())) {
+ while (!found && NS_SUCCEEDED((rv = NextSample(sample)))) {
parsed++;
sampleTime = sample->mTime;
if (sample->mKeyframe && sampleTime >= aTimeThreshold.ToMicroseconds()) {
@@ -1116,7 +1170,9 @@ WebMTrackDemuxer::SkipToNextRandomAccessPoint(media::TimeUnit aTimeThreshold)
mSamples.PushFront(sample.forget());
}
}
- SetNextKeyFrameTime();
+ if (NS_SUCCEEDED(rv)) {
+ SetNextKeyFrameTime();
+ }
if (found) {
WEBM_DEBUG("next sample: %f (parsed: %d)",
media::TimeUnit::FromMicroseconds(sampleTime).ToSeconds(),
diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h
index 6fff38e7d..36d381e57 100644
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -8,9 +8,13 @@
#include "nsTArray.h"
#include "MediaDataDemuxer.h"
+#include "MediaResource.h"
#include "NesteggPacketHolder.h"
#include "mozilla/Move.h"
+#include <deque>
+#include <stdint.h>
+
typedef struct nestegg nestegg;
namespace mozilla {
@@ -111,7 +115,8 @@ public:
bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
// Demux next WebM packet and append samples to MediaRawDataQueue
- bool GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples);
+ nsresult GetNextPacket(TrackInfo::TrackType aType,
+ MediaRawDataQueue *aSamples);
nsresult Reset(TrackInfo::TrackType aType);
@@ -175,11 +180,13 @@ private:
// Read a packet from the nestegg file. Returns nullptr if all packets for
// the particular track have been read. Pass TrackInfo::kVideoTrack or
// TrackInfo::kVideoTrack to indicate the type of the packet we want to read.
- RefPtr<NesteggPacketHolder> NextPacket(TrackInfo::TrackType aType);
+ nsresult NextPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// Internal method that demuxes the next packet from the stream. The caller
// is responsible for making sure it doesn't get lost.
- RefPtr<NesteggPacketHolder> DemuxPacket(TrackInfo::TrackType aType);
+ nsresult DemuxPacket(TrackInfo::TrackType aType,
+ RefPtr<NesteggPacketHolder>& aPacket);
// libnestegg audio and video context for webm container.
// Access on reader's thread only.
@@ -237,8 +244,7 @@ private:
int64_t mLastWebMBlockOffset;
const bool mIsMediaSource;
- Maybe<uint32_t> mLastSeenFrameWidth;
- Maybe<uint32_t> mLastSeenFrameHeight;
+ Maybe<nsIntSize> mLastSeenFrameSize;
// This will be populated only if a resolution change occurs, otherwise it
// will be left as null so the original metadata is used
RefPtr<SharedTrackInfo> mSharedVideoTrackInfo;
@@ -276,7 +282,7 @@ private:
~WebMTrackDemuxer();
void UpdateSamples(nsTArray<RefPtr<MediaRawData>>& aSamples);
void SetNextKeyFrameTime();
- RefPtr<MediaRawData> NextSample ();
+ nsresult NextSample(RefPtr<MediaRawData>& aData);
RefPtr<WebMDemuxer> mParent;
TrackInfo::TrackType mType;
UniquePtr<TrackInfo> mInfo;
diff --git a/dom/media/webrtc/RTCCertificate.cpp b/dom/media/webrtc/RTCCertificate.cpp
index 3f778bcbb..9f5e27c56 100644
--- a/dom/media/webrtc/RTCCertificate.cpp
+++ b/dom/media/webrtc/RTCCertificate.cpp
@@ -74,7 +74,7 @@ private:
char buf[sizeof(randomName) * 2 + 4];
PL_strncpy(buf, "CN=", 3);
for (size_t i = 0; i < sizeof(randomName); ++i) {
- snprintf(&buf[i * 2 + 3], 2, "%.2x", randomName[i]);
+ snprintf(&buf[i * 2 + 3], 3, "%.2x", randomName[i]);
}
buf[sizeof(buf) - 1] = '\0';
diff --git a/dom/moz.build b/dom/moz.build
index 358fc6411..54dc0510e 100644
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -94,7 +94,6 @@ DIRS += [
'xslt',
'xul',
'manifest',
- 'vr',
'u2f',
'console',
'performance',
diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.cpp
index 1dd5724e4..71c4916b9 100644
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -642,8 +642,6 @@ NotificationPermissionRequest::ResolvePromise()
mCallback->Call(mPermission, error);
rv = error.StealNSResult();
}
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_REQUEST_PERMISSION_CALLBACK, !!mCallback);
mPromise->MaybeResolve(mPermission);
return rv;
}
@@ -750,11 +748,6 @@ NotificationTelemetryService::RecordPermissions()
if (!GetNotificationPermission(supportsPermission, &capability)) {
continue;
}
- if (capability == nsIPermissionManager::DENY_ACTION) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_PERMISSIONS, 0);
- } else if (capability == nsIPermissionManager::ALLOW_ACTION) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_PERMISSIONS, 1);
- }
}
}
@@ -800,9 +793,6 @@ NotificationTelemetryService::RecordDNDSupported()
if (NS_FAILED(rv)) {
return;
}
-
- Telemetry::Accumulate(
- Telemetry::ALERTS_SERVICE_DND_SUPPORTED_FLAG, true);
}
nsresult
@@ -819,7 +809,6 @@ NotificationTelemetryService::RecordSender(nsIPrincipal* aPrincipal)
}
if (!mOrigins.Contains(origin)) {
mOrigins.PutEntry(origin);
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_SENDERS, 1);
}
return NS_OK;
}
@@ -829,21 +818,7 @@ NotificationTelemetryService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
- uint32_t capability;
- if (strcmp("perm-changed", aTopic) ||
- !NS_strcmp(u"cleared", aData) ||
- !GetNotificationPermission(aSubject, &capability)) {
- return NS_OK;
- }
- if (!NS_strcmp(u"deleted", aData)) {
- if (capability == nsIPermissionManager::DENY_ACTION) {
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_PERMISSION_REMOVED, 0);
- } else if (capability == nsIPermissionManager::ALLOW_ACTION) {
- Telemetry::Accumulate(
- Telemetry::WEB_NOTIFICATION_PERMISSION_REMOVED, 1);
- }
- }
+ /* STUB */
return NS_OK;
}
@@ -1407,7 +1382,6 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
AssertIsOnMainThread();
if (!strcmp("alertdisablecallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_MENU, 1);
if (XRE_IsParentProcess()) {
return Notification::RemovePermission(mPrincipal);
}
@@ -1417,10 +1391,7 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
ContentChild::GetSingleton()->SendDisableNotifications(
IPC::Principal(mPrincipal));
return NS_OK;
- } else if (!strcmp("alertclickcallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_CLICKED, 1);
} else if (!strcmp("alertsettingscallback", aTopic)) {
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_MENU, 2);
if (XRE_IsParentProcess()) {
return Notification::OpenSettings(mPrincipal);
}
@@ -1433,21 +1404,7 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
!strcmp("alertfinished", aTopic)) {
RefPtr<NotificationTelemetryService> telemetry =
NotificationTelemetryService::GetInstance();
- if (telemetry) {
- // Record whether "do not disturb" is supported after the first
- // notification, to account for falling back to XUL alerts.
- telemetry->RecordDNDSupported();
- if (!mInPrivateBrowsing) {
- // Ignore senders in private windows.
- Unused << NS_WARN_IF(NS_FAILED(telemetry->RecordSender(mPrincipal)));
- }
- }
Unused << NS_WARN_IF(NS_FAILED(AdjustPushQuota(aTopic)));
-
- if (!strcmp("alertshow", aTopic)) {
- // Record notifications actually shown (e.g. don't count if DND is on).
- Telemetry::Accumulate(Telemetry::WEB_NOTIFICATION_SHOWN, 1);
- }
}
return mObserver->Observe(aSubject, aTopic, aData);
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
index 916bdea0f..c3de136d0 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2148,11 +2148,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
nsPluginInfo info;
memset(&info, 0, sizeof(info));
nsresult res;
- // Opening a block for the telemetry AutoTimer
- {
- Telemetry::AutoTimer<Telemetry::PLUGIN_LOAD_METADATA> telemetry;
- res = pluginFile.GetPluginInfo(info, &library);
- }
+ res = pluginFile.GetPluginInfo(info, &library);
// if we don't have mime type don't proceed, this is not a plugin
if (NS_FAILED(res) || !info.fMimeTypeArray) {
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
@@ -2410,8 +2406,6 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
// This is needed in ReloadPlugins to prevent possible recursive reloads
nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChanged)
{
- Telemetry::AutoTimer<Telemetry::FIND_PLUGINS> telemetry;
-
NS_ENSURE_ARG_POINTER(aPluginsChanged);
*aPluginsChanged = false;
@@ -3412,7 +3406,6 @@ nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
return NS_OK;
}
- Telemetry::AutoTimer<Telemetry::PLUGIN_SHUTDOWN_MS> timer;
aInstance->Stop();
// if the instance does not want to be 'cached' just remove it
diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
index da07116cc..3fe4c7168 100644
--- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp
+++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
@@ -504,8 +504,6 @@ PluginAsyncSurrogate::WaitForInit()
if (mAcceptCalls) {
return true;
}
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGINASYNCSURROGATE_WAITFORINIT_MS>
- timer(mParent->GetHistogramKey());
bool result = false;
MOZ_ASSERT(mParent);
if (mParent->IsChrome()) {
diff --git a/dom/plugins/ipc/PluginHangUIParent.cpp b/dom/plugins/ipc/PluginHangUIParent.cpp
index 5114f2e9a..908182a22 100644
--- a/dom/plugins/ipc/PluginHangUIParent.cpp
+++ b/dom/plugins/ipc/PluginHangUIParent.cpp
@@ -8,7 +8,6 @@
#include "PluginHangUIParent.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/plugins/PluginModuleParent.h"
@@ -48,14 +47,6 @@ public:
NS_IMETHOD
Run() override
{
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_USER_RESPONSE, mResponseCode);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_DONT_ASK, mDontAskCode);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_UI_RESPONSE_TIME, mResponseTimeMs);
- mozilla::Telemetry::Accumulate(
- mozilla::Telemetry::PLUGIN_HANG_TIME, mTimeoutMs + mResponseTimeMs);
return NS_OK;
}
diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp
index 02f0641f7..bdd15ca99 100644
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -9,7 +9,6 @@
#include "mozilla/BasicEvents.h"
#include "mozilla/Preferences.h"
-#include "mozilla/Telemetry.h"
#include "PluginInstanceParent.h"
#include "BrowserStreamParent.h"
#include "PluginAsyncSurrogate.h"
@@ -206,12 +205,8 @@ NPError
PluginInstanceParent::Destroy()
{
NPError retval;
- { // Scope for timer
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_INSTANCE_DESTROY_MS>
- timer(Module()->GetHistogramKey());
- if (!CallNPP_Destroy(&retval)) {
- retval = NPERR_GENERIC_ERROR;
- }
+ if (!CallNPP_Destroy(&retval)) {
+ retval = NPERR_GENERIC_ERROR;
}
#if defined(OS_WIN)
@@ -1786,9 +1781,6 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
return NPERR_GENERIC_ERROR;
}
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_STREAM_INIT_MS>
- timer(Module()->GetHistogramKey());
-
NPError err = NPERR_NO_ERROR;
if (mParent->IsStartingAsync()) {
MOZ_ASSERT(mSurrogate);
@@ -2504,6 +2496,5 @@ PluginInstanceParent::RecordDrawingModel()
}
MOZ_ASSERT(mode >= 0);
- Telemetry::Accumulate(Telemetry::PLUGIN_DRAWING_MODEL, mode);
mLastRecordedDrawingModel = mode;
}
diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp
index 2489baf16..300c4f621 100755
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -20,7 +20,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/Unused.h"
#include "nsAutoPtr.h"
#include "nsCRT.h"
@@ -1172,11 +1171,6 @@ PluginModuleParent::GetRunID(uint32_t* aRunID)
void
PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
{
- if (why == AbnormalShutdown) {
- Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
- NS_LITERAL_CSTRING("plugin"), 1);
- }
-
// We can't broadcast settings changes anymore.
UnregisterSettingsCallbacks();
@@ -2203,12 +2197,8 @@ public:
void
PluginModuleParent::AccumulateModuleInitBlockedTime()
{
- if (mPluginName.IsEmpty()) {
- GetPluginDetails();
- }
- Telemetry::Accumulate(Telemetry::BLOCKED_ON_PLUGIN_MODULE_INIT_MS,
- GetHistogramKey(),
- static_cast<uint32_t>(mTimeBlocked.ToMilliseconds()));
+ // XXX: mTimeBlocked can probably go if not used for anything besides
+ // telemetry.
mTimeBlocked = TimeDuration();
}
@@ -2294,27 +2284,23 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
return NS_ERROR_FAILURE;
}
- { // Scope for timer
- Telemetry::AutoTimer<Telemetry::BLOCKED_ON_PLUGIN_INSTANCE_INIT_MS>
- timer(GetHistogramKey());
- if (mIsStartingAsync) {
- MOZ_ASSERT(surrogate);
- surrogate->AsyncCallDeparting();
- if (!SendAsyncNPP_New(parentInstance)) {
+ if (mIsStartingAsync) {
+ MOZ_ASSERT(surrogate);
+ surrogate->AsyncCallDeparting();
+ if (!SendAsyncNPP_New(parentInstance)) {
+ *error = NPERR_GENERIC_ERROR;
+ return NS_ERROR_FAILURE;
+ }
+ *error = NPERR_NO_ERROR;
+ } else {
+ if (!CallSyncNPP_New(parentInstance, error)) {
+ // if IPC is down, we'll get an immediate "failed" return, but
+ // without *error being set. So make sure that the error
+ // condition is signaled to nsNPAPIPluginInstance
+ if (NPERR_NO_ERROR == *error) {
*error = NPERR_GENERIC_ERROR;
- return NS_ERROR_FAILURE;
- }
- *error = NPERR_NO_ERROR;
- } else {
- if (!CallSyncNPP_New(parentInstance, error)) {
- // if IPC is down, we'll get an immediate "failed" return, but
- // without *error being set. So make sure that the error
- // condition is signaled to nsNPAPIPluginInstance
- if (NPERR_NO_ERROR == *error) {
- *error = NPERR_GENERIC_ERROR;
- }
- return NS_ERROR_FAILURE;
}
+ return NS_ERROR_FAILURE;
}
}
diff --git a/dom/presentation/provider/PresentationControlService.js b/dom/presentation/provider/PresentationControlService.js
index fe61d26d6..e9f92247f 100644
--- a/dom/presentation/provider/PresentationControlService.js
+++ b/dom/presentation/provider/PresentationControlService.js
@@ -100,7 +100,6 @@ PresentationControlService.prototype = {
if (aCert) {
this._serverSocket.serverCert = aCert;
- this._serverSocket.setSessionCache(false);
this._serverSocket.setSessionTickets(false);
let requestCert = Ci.nsITLSServerSocket.REQUEST_NEVER;
this._serverSocket.setRequestClientCertificate(requestCert);
diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp
index c03628da0..5f41f414d 100644
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -983,44 +983,5 @@ enum MixedContentHSTSState {
void
nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive)
{
- // This method must only be called in the parent, because
- // nsSiteSecurityService is only available in the parent
- if (!XRE_IsParentProcess()) {
- MOZ_ASSERT(false);
- return;
- }
-
- bool hsts;
- nsresult rv;
- nsCOMPtr<nsISiteSecurityService> sss = do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
- if (NS_FAILED(rv)) {
- return;
- }
- rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, nullptr, &hsts);
- if (NS_FAILED(rv)) {
- return;
- }
-
- // states: would upgrade, hsts info cached
- // active, passive
- //
- if (!aActive) {
- if (!hsts) {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_PASSIVE_NO_HSTS);
- }
- else {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_PASSIVE_WITH_HSTS);
- }
- } else {
- if (!hsts) {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_ACTIVE_NO_HSTS);
- }
- else {
- Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
- MCB_HSTS_ACTIVE_WITH_HSTS);
- }
- }
+/* STUB */
} \ No newline at end of file
diff --git a/dom/security/test/cors/test_CrossSiteXHR.html b/dom/security/test/cors/test_CrossSiteXHR.html
index b3cda3b87..d9aef5c60 100644
--- a/dom/security/test/cors/test_CrossSiteXHR.html
+++ b/dom/security/test/cors/test_CrossSiteXHR.html
@@ -743,7 +743,7 @@ function runTest() {
is(res.responseHeaders[header], test.responseHeaders[header],
"|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " +
test.toSource());
- is(res.allResponseHeaders[header], test.responseHeaders[header],
+ is(res.allResponseHeaders[header.toLowerCase()], test.responseHeaders[header],
"|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " +
test.toSource());
}
diff --git a/dom/storage/DOMStorageCache.cpp b/dom/storage/DOMStorageCache.cpp
index 811f79fd3..a6aa17424 100644
--- a/dom/storage/DOMStorageCache.cpp
+++ b/dom/storage/DOMStorageCache.cpp
@@ -309,7 +309,7 @@ public:
explicit TelemetryAutoTimer(Telemetry::ID aId)
: id(aId), start(TimeStamp::Now()) {}
~TelemetryAutoTimer()
- { Telemetry::AccumulateDelta_impl<Telemetry::Millisecond>::compute(id, start); }
+ { /* STUB */ }
private:
Telemetry::ID id;
const TimeStamp start;
@@ -329,9 +329,6 @@ DOMStorageCache::WaitForPreload(Telemetry::ID aTelemetryID)
// Telemetry of rates of pending preloads
if (!mPreloadTelemetryRecorded) {
mPreloadTelemetryRecorded = true;
- Telemetry::Accumulate(
- Telemetry::LOCALDOMSTORAGE_PRELOAD_PENDING_ON_FIRST_ACCESS,
- !loaded);
}
if (loaded) {
diff --git a/dom/storage/DOMStorageDBThread.cpp b/dom/storage/DOMStorageDBThread.cpp
index 183be5c5c..f86dbad9c 100644
--- a/dom/storage/DOMStorageDBThread.cpp
+++ b/dom/storage/DOMStorageDBThread.cpp
@@ -163,8 +163,6 @@ DOMStorageDBThread::Shutdown()
return NS_ERROR_NOT_INITIALIZED;
}
- Telemetry::AutoTimer<Telemetry::LOCALDOMSTORAGE_SHUTDOWN_DATABASE_MS> timer;
-
{
MonitorAutoLock monitor(mThreadObserver->GetMonitor());
diff --git a/dom/svg/SVGUseElement.cpp b/dom/svg/SVGUseElement.cpp
index 4911e2cac..9212ab1aa 100644
--- a/dom/svg/SVGUseElement.cpp
+++ b/dom/svg/SVGUseElement.cpp
@@ -15,6 +15,7 @@
#include "mozilla/dom/Element.h"
#include "nsContentUtils.h"
#include "nsIURI.h"
+#include "nsSVGEffects.h"
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Use)
@@ -418,11 +419,15 @@ SVGUseElement::LookupHref()
return;
}
+ nsCOMPtr<nsIURI> originURI =
+ mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
+ nsCOMPtr<nsIURI> baseURI = nsContentUtils::IsLocalRefURL(href)
+ ? nsSVGEffects::GetBaseURLForLocalRef(this, originURI)
+ : originURI;
+
nsCOMPtr<nsIURI> targetURI;
- nsCOMPtr<nsIURI> baseURI = mOriginal ? mOriginal->GetBaseURI() : GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
GetComposedDoc(), baseURI);
-
mSource.Reset(this, targetURI);
}
diff --git a/dom/svg/test/reftest_viewport_noninteger.html b/dom/svg/test/reftest_viewport_noninteger.html
new file mode 100644
index 000000000..3f4852b53
--- /dev/null
+++ b/dom/svg/test/reftest_viewport_noninteger.html
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SVG size test</title>
+ <style>
+ body {
+ margin: 30px;
+ font-family: sans-serif;
+ }
+
+ #tests {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ grid-gap: 30px;
+ }
+
+ #tests div:hover {
+ opacity: 1 !important;
+ }
+
+ #tests p {
+ text-decoration: underline dotted black;
+ }
+
+ svg {
+ background: lightgrey;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>SVG size test</h1>
+
+ <p>The grey boxes below are <code>&lt;svg&gt;</code> elements.</p>
+ <p>All SVGs in each row should have the exact same size.</p>
+ <p>Each row has its own viewBox width and height: <code>viewBox="0 0 width height"</code>.</p>
+ <p>Each column has its own width/height styling. For example, <code>style="width: 200px; height: auto;"</code>.</p>
+ <p>The first column has both an explicit widht and an explicit height, so there's not much that can go wrong there. It acts as a reference.</p>
+ <p>The first row has integer viewBox width and height. Firefox then sizes all SVGs correctly.</p>
+ <p>The remaining rows have at least one non-integer viewBox width and height. Firefox then sizes the SVGs a bit wrong.</p>
+ <p>Chrome, Safari and Edge seem to pass all tests.</p>
+
+ <p id="summary"></p>
+
+ <div id="tests"></div>
+
+ <script>
+ const testsElement = document.getElementById("tests");
+ const summaryElement = document.getElementById("summary");
+
+ // Turn for instance `2.3` into `230` (px). Round to avoid floating point
+ // issues.
+ const scale = (number) => Math.round(100 * number);
+
+ const widths = [2, 2.3, 2.5, 2.8];
+ const heights = [3, 3.3, 3.5, 3.8];
+
+ let numPassed = 0;
+ let numFailed = 0;
+
+ for (const width of widths) {
+ for (const height of heights) {
+ const variations = [
+ {width, height},
+ {width: "auto", height},
+ {width, height: "auto"},
+ {width: "auto", height: "auto"},
+ ];
+
+ for (const variation of variations) {
+ const cellElement = document.createElement("div");
+
+ const titleElement = document.createElement("h2");
+ titleElement.appendChild(makeTitle(width, height, variation));
+
+ const sizeElement = document.createElement("p");
+
+ const svgWrapperElement = document.createElement("div");
+ svgWrapperElement.style.width =
+ variation.width === "auto" && variation.height === "auto"
+ ? `${scale(width)}px`
+ : "auto";
+
+ const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ svgElement.setAttribute("viewBox", `0 0 ${width} ${height}`);
+ svgElement.style.width =
+ typeof variation.width === "number"
+ ? `${scale(variation.width)}px`
+ : variation.width;
+ svgElement.style.height =
+ typeof variation.height === "number"
+ ? `${scale(variation.height)}px`
+ : variation.height;
+
+ svgWrapperElement.appendChild(svgElement);
+
+ cellElement.appendChild(titleElement);
+ cellElement.appendChild(sizeElement);
+ cellElement.appendChild(svgWrapperElement);
+
+ testsElement.appendChild(cellElement);
+
+ const rect = svgElement.getBoundingClientRect();
+ const actual = {
+ width: Math.round(rect.width),
+ height: Math.round(rect.height),
+ };
+ const expected = {
+ width: scale(width),
+ height: scale(height),
+ };
+ const passed =
+ actual.width === expected.width &&
+ actual.height === expected.height;
+
+ const icon = passed ? "✔" : "✘";
+ const iconText = passed ? "PASS" : "FAIL";
+ const expectedText = passed ? "" : `\nExpected size: ${expected.width}x${expected.height}`;
+ sizeElement.textContent = `${icon} ${actual.width}x${actual.height}`;
+ sizeElement.title = `${iconText}. Actual size, as measured by element.getBoundingClientRect().${expectedText}`;
+ sizeElement.style.color = passed ? "lime" : "red";
+ sizeElement.style.fontWeight = passed ? "normal" : "bold";
+
+ cellElement.style.opacity = passed ? 0.5 : 1;
+
+ if (passed) {
+ numPassed++;
+ } else {
+ numFailed++;
+ }
+ }
+ }
+ }
+
+ const numTotal = numPassed + numFailed;
+ const passed = numFailed === 0;
+ const icon = passed ? "✔" : "✘";
+ summaryElement.textContent = `${icon} ${numPassed}/${numTotal} tests passed.`;
+ summaryElement.style.color = passed ? "lime" : "red";
+ summaryElement.style.fontWeight = "bold";
+
+ function makeTitle(width, height, variation) {
+ const fragment = document.createDocumentFragment();
+
+ const first = document.createElement("abbr");
+ first.textContent = `${width}/${height}`;
+ first.title = `SVG viewBox width/height: viewBox="0 0 ${width} ${height}"`;
+
+ const separator = document.createTextNode(" | ");
+
+ const second = document.createElement("abbr");
+
+ const widthString = typeof variation.width === "number" ? "px" : variation.width;
+ const heightString = typeof variation.height === "number" ? "px" : variation.height;
+ second.textContent = `${widthString}/${heightString}`;
+
+ const widthExplanation =
+ typeof variation.width === "number"
+ ? "explicit width (px)"
+ : `${variation.width} width`
+ const heightExplanation =
+ typeof variation.height === "number"
+ ? "explicit height (px)"
+ : `${variation.height} height`
+ second.title = `${widthExplanation}, ${heightExplanation}`;
+
+ fragment.appendChild(first);
+ fragment.appendChild(separator);
+ fragment.appendChild(second);
+
+ return fragment;
+ }
+ </script>
+ </body>
+</html>
diff --git a/dom/system/mac/CoreLocationLocationProvider.mm b/dom/system/mac/CoreLocationLocationProvider.mm
index b39582a9e..7a3feba97 100644
--- a/dom/system/mac/CoreLocationLocationProvider.mm
+++ b/dom/system/mac/CoreLocationLocationProvider.mm
@@ -13,7 +13,6 @@
#include "CoreLocationLocationProvider.h"
#include "nsCocoaFeatures.h"
#include "prtime.h"
-#include "mozilla/Telemetry.h"
#include "MLSFallback.h"
#include <CoreLocation/CLError.h>
@@ -103,7 +102,6 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
PR_Now() / PR_USEC_PER_MSEC);
mProvider->Update(geoPosition);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, false);
}
@end
@@ -127,7 +125,6 @@ CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position)
return NS_ERROR_FAILURE;
}
mParentLocationProvider.Update(position);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_OSX_SOURCE_IS_MLS, true);
return NS_OK;
}
NS_IMETHODIMP
diff --git a/dom/system/windows/WindowsLocationProvider.cpp b/dom/system/windows/WindowsLocationProvider.cpp
index fa7f8d8be..9da7bcc30 100644
--- a/dom/system/windows/WindowsLocationProvider.cpp
+++ b/dom/system/windows/WindowsLocationProvider.cpp
@@ -10,7 +10,6 @@
#include "nsComponentManagerUtils.h"
#include "prtime.h"
#include "MLSFallback.h"
-#include "mozilla/Telemetry.h"
namespace mozilla {
namespace dom {
@@ -34,7 +33,6 @@ WindowsLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *aPosition)
if (!coords) {
return NS_ERROR_FAILURE;
}
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WIN8_SOURCE_IS_MLS, true);
return mCallback->Update(aPosition);
}
NS_IMETHODIMP
@@ -176,8 +174,6 @@ LocationEvent::OnLocationChanged(REFIID aReportType,
PR_Now() / PR_USEC_PER_MSEC);
mCallback->Update(position);
- Telemetry::Accumulate(Telemetry::GEOLOCATION_WIN8_SOURCE_IS_MLS, false);
-
return S_OK;
}
diff --git a/dom/vr/VRDisplay.cpp b/dom/vr/VRDisplay.cpp
deleted file mode 100644
index 80922422f..000000000
--- a/dom/vr/VRDisplay.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsWrapperCache.h"
-
-#include "mozilla/dom/Element.h"
-#include "mozilla/dom/ElementBinding.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/VRDisplay.h"
-#include "mozilla/HoldDropJSObjects.h"
-#include "mozilla/dom/VRDisplayBinding.h"
-#include "Navigator.h"
-#include "gfxVR.h"
-#include "VRDisplayClient.h"
-#include "VRManagerChild.h"
-#include "VRDisplayPresentation.h"
-#include "nsIObserverService.h"
-#include "nsIFrame.h"
-#include "nsISupportsPrimitives.h"
-
-using namespace mozilla::gfx;
-
-namespace mozilla {
-namespace dom {
-
-VRFieldOfView::VRFieldOfView(nsISupports* aParent,
- double aUpDegrees, double aRightDegrees,
- double aDownDegrees, double aLeftDegrees)
- : mParent(aParent)
- , mUpDegrees(aUpDegrees)
- , mRightDegrees(aRightDegrees)
- , mDownDegrees(aDownDegrees)
- , mLeftDegrees(aLeftDegrees)
-{
-}
-
-VRFieldOfView::VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
- : mParent(aParent)
- , mUpDegrees(aSrc.upDegrees)
- , mRightDegrees(aSrc.rightDegrees)
- , mDownDegrees(aSrc.downDegrees)
- , mLeftDegrees(aSrc.leftDegrees)
-{
-}
-
-bool
-VRDisplayCapabilities::HasPosition() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Position);
-}
-
-bool
-VRDisplayCapabilities::HasOrientation() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Orientation);
-}
-
-bool
-VRDisplayCapabilities::HasExternalDisplay() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_External);
-}
-
-bool
-VRDisplayCapabilities::CanPresent() const
-{
- return bool(mFlags & gfx::VRDisplayCapabilityFlags::Cap_Present);
-}
-
-uint32_t
-VRDisplayCapabilities::MaxLayers() const
-{
- return CanPresent() ? 1 : 0;
-}
-
-/*static*/ bool
-VRDisplay::RefreshVRDisplays(uint64_t aWindowId)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- return vm && vm->RefreshVRDisplaysWithCallback(aWindowId);
-}
-
-/*static*/ void
-VRDisplay::UpdateVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays, nsPIDOMWindowInner* aWindow)
-{
- nsTArray<RefPtr<VRDisplay>> displays;
-
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- nsTArray<RefPtr<gfx::VRDisplayClient>> updatedDisplays;
- if (vm && vm->GetVRDisplays(updatedDisplays)) {
- for (size_t i = 0; i < updatedDisplays.Length(); i++) {
- RefPtr<gfx::VRDisplayClient> display = updatedDisplays[i];
- bool isNewDisplay = true;
- for (size_t j = 0; j < aDisplays.Length(); j++) {
- if (aDisplays[j]->GetClient()->GetDisplayInfo() == display->GetDisplayInfo()) {
- displays.AppendElement(aDisplays[j]);
- isNewDisplay = false;
- }
- }
-
- if (isNewDisplay) {
- displays.AppendElement(new VRDisplay(aWindow, display));
- }
- }
- }
-
- aDisplays = displays;
-}
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfView, mParent)
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfView, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfView, Release)
-
-
-JSObject*
-VRFieldOfView::WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto)
-{
- return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VREyeParameters)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mFOV)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mOffset = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mFOV)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VREyeParameters)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mOffset)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
-
-VREyeParameters::VREyeParameters(nsISupports* aParent,
- const gfx::Point3D& aEyeTranslation,
- const gfx::VRFieldOfView& aFOV,
- const gfx::IntSize& aRenderSize)
- : mParent(aParent)
- , mEyeTranslation(aEyeTranslation)
- , mRenderSize(aRenderSize)
-{
- mFOV = new VRFieldOfView(aParent, aFOV);
- mozilla::HoldJSObjects(this);
-}
-
-VREyeParameters::~VREyeParameters()
-{
- mozilla::DropJSObjects(this);
-}
-
-VRFieldOfView*
-VREyeParameters::FieldOfView()
-{
- return mFOV;
-}
-
-void
-VREyeParameters::GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
-{
- if (!mOffset) {
- // Lazily create the Float32Array
- mOffset = dom::Float32Array::Create(aCx, this, 3, mEyeTranslation.components);
- if (!mOffset) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mOffset);
-}
-
-JSObject*
-VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRStageParameters::VRStageParameters(nsISupports* aParent,
- const gfx::Matrix4x4& aSittingToStandingTransform,
- const gfx::Size& aSize)
- : mParent(aParent)
- , mSittingToStandingTransform(aSittingToStandingTransform)
- , mSittingToStandingTransformArray(nullptr)
- , mSize(aSize)
-{
- mozilla::HoldJSObjects(this);
-}
-
-VRStageParameters::~VRStageParameters()
-{
- mozilla::DropJSObjects(this);
-}
-
-JSObject*
-VRStageParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRStageParametersBinding::Wrap(aCx, this, aGivenProto);
-}
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VRStageParameters)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mSittingToStandingTransformArray = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRStageParameters)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSittingToStandingTransformArray)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRStageParameters, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRStageParameters, Release)
-
-void
-VRStageParameters::GetSittingToStandingTransform(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- if (!mSittingToStandingTransformArray) {
- // Lazily create the Float32Array
- mSittingToStandingTransformArray = dom::Float32Array::Create(aCx, this, 16,
- mSittingToStandingTransform.components);
- if (!mSittingToStandingTransformArray) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- aRetval.set(mSittingToStandingTransformArray);
-}
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRDisplayCapabilities, mParent)
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRDisplayCapabilities, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRDisplayCapabilities, Release)
-
-JSObject*
-VRDisplayCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRDisplayCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
- : Pose(aParent)
- , mVRState(aState)
-{
- mFrameId = aState.inputFrameID;
- mozilla::HoldJSObjects(this);
-}
-
-VRPose::VRPose(nsISupports* aParent)
- : Pose(aParent)
-{
- mFrameId = 0;
- mVRState.Clear();
- mozilla::HoldJSObjects(this);
-}
-
-VRPose::~VRPose()
-{
- mozilla::DropJSObjects(this);
-}
-
-void
-VRPose::GetPosition(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mPosition, mVRState.position, 3,
- !mPosition && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
- aRv);
-}
-
-void
-VRPose::GetLinearVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mLinearVelocity, mVRState.linearVelocity, 3,
- !mLinearVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position),
- aRv);
-}
-
-void
-VRPose::GetLinearAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mLinearAcceleration, mVRState.linearAcceleration, 3,
- !mLinearAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_LinearAcceleration),
- aRv);
-
-}
-
-void
-VRPose::GetOrientation(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mOrientation, mVRState.orientation, 4,
- !mOrientation && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
- aRv);
-}
-
-void
-VRPose::GetAngularVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mAngularVelocity, mVRState.angularVelocity, 3,
- !mAngularVelocity && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation),
- aRv);
-}
-
-void
-VRPose::GetAngularAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- SetFloat32Array(aCx, aRetval, mAngularAcceleration, mVRState.angularAcceleration, 3,
- !mAngularAcceleration && bool(mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_AngularAcceleration),
- aRv);
-}
-
-JSObject*
-VRPose::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRPoseBinding::Wrap(aCx, this, aGivenProto);
-}
-
-/* virtual */ JSObject*
-VRDisplay::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return VRDisplayBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRDisplay::VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient)
- : DOMEventTargetHelper(aWindow)
- , mClient(aClient)
- , mDepthNear(0.01f) // Default value from WebVR Spec
- , mDepthFar(10000.0f) // Default value from WebVR Spec
-{
- const gfx::VRDisplayInfo& info = aClient->GetDisplayInfo();
- mDisplayId = info.GetDisplayID();
- mDisplayName = NS_ConvertASCIItoUTF16(info.GetDisplayName());
- mCapabilities = new VRDisplayCapabilities(aWindow, info.GetCapabilities());
- if (info.GetCapabilities() & gfx::VRDisplayCapabilityFlags::Cap_StageParameters) {
- mStageParameters = new VRStageParameters(aWindow,
- info.GetSittingToStandingTransform(),
- info.GetStageSize());
- }
- mozilla::HoldJSObjects(this);
-}
-
-VRDisplay::~VRDisplay()
-{
- ExitPresentInternal();
- mozilla::DropJSObjects(this);
-}
-
-void
-VRDisplay::LastRelease()
-{
- // We don't want to wait for the CC to free up the presentation
- // for use in other documents, so we do this in LastRelease().
- ExitPresentInternal();
-}
-
-already_AddRefed<VREyeParameters>
-VRDisplay::GetEyeParameters(VREye aEye)
-{
- gfx::VRDisplayInfo::Eye eye = aEye == VREye::Left ? gfx::VRDisplayInfo::Eye_Left : gfx::VRDisplayInfo::Eye_Right;
- RefPtr<VREyeParameters> params =
- new VREyeParameters(GetParentObject(),
- mClient->GetDisplayInfo().GetEyeTranslation(eye),
- mClient->GetDisplayInfo().GetEyeFOV(eye),
- mClient->GetDisplayInfo().SuggestedEyeResolution());
- return params.forget();
-}
-
-VRDisplayCapabilities*
-VRDisplay::Capabilities()
-{
- return mCapabilities;
-}
-
-VRStageParameters*
-VRDisplay::GetStageParameters()
-{
- return mStageParameters;
-}
-
-void
-VRDisplay::UpdateFrameInfo()
-{
- /**
- * The WebVR 1.1 spec Requires that VRDisplay.getPose and VRDisplay.getFrameData
- * must return the same values until the next VRDisplay.submitFrame.
- *
- * mFrameInfo is marked dirty at the end of the frame or start of a new
- * composition and lazily created here in order to receive mid-frame
- * pose-prediction updates while still ensuring conformance to the WebVR spec
- * requirements.
- *
- * If we are not presenting WebVR content, the frame will never end and we should
- * return the latest frame data always.
- */
- if (mFrameInfo.IsDirty() || !mPresentation) {
- gfx::VRHMDSensorState state = mClient->GetSensorState();
- const gfx::VRDisplayInfo& info = mClient->GetDisplayInfo();
- mFrameInfo.Update(info, state, mDepthNear, mDepthFar);
- }
-}
-
-bool
-VRDisplay::GetFrameData(VRFrameData& aFrameData)
-{
- UpdateFrameInfo();
- aFrameData.Update(mFrameInfo);
- return true;
-}
-
-already_AddRefed<VRPose>
-VRDisplay::GetPose()
-{
- UpdateFrameInfo();
- RefPtr<VRPose> obj = new VRPose(GetParentObject(), mFrameInfo.mVRState);
-
- return obj.forget();
-}
-
-void
-VRDisplay::ResetPose()
-{
- mClient->ZeroSensor();
-}
-
-already_AddRefed<Promise>
-VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
-
- nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
- NS_ENSURE_TRUE(obs, nullptr);
-
- if (mClient->GetIsPresenting()) {
- // Only one presentation allowed per VRDisplay
- // on a first-come-first-serve basis.
- promise->MaybeRejectWithUndefined();
- } else {
- mPresentation = mClient->BeginPresentation(aLayers);
- mFrameInfo.Clear();
-
- nsresult rv = obs->AddObserver(this, "inner-window-destroyed", false);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- mPresentation = nullptr;
- promise->MaybeRejectWithUndefined();
- } else {
- promise->MaybeResolve(JS::UndefinedHandleValue);
- }
- }
- return promise.forget();
-}
-
-NS_IMETHODIMP
-VRDisplay::Observe(nsISupports* aSubject, const char* aTopic,
- const char16_t* aData)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- if (strcmp(aTopic, "inner-window-destroyed") == 0) {
- nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
- NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
-
- uint64_t innerID;
- nsresult rv = wrapper->GetData(&innerID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!GetOwner() || GetOwner()->WindowID() == innerID) {
- ExitPresentInternal();
- }
-
- return NS_OK;
- }
-
- // This should not happen.
- return NS_ERROR_FAILURE;
-}
-
-already_AddRefed<Promise>
-VRDisplay::ExitPresent(ErrorResult& aRv)
-{
- nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
- if (!global) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
-
- RefPtr<Promise> promise = Promise::Create(global, aRv);
- NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
-
- if (!IsPresenting()) {
- // We can not exit a presentation outside of the context that
- // started the presentation.
- promise->MaybeRejectWithUndefined();
- } else {
- promise->MaybeResolve(JS::UndefinedHandleValue);
- ExitPresentInternal();
- }
-
- return promise.forget();
-}
-
-void
-VRDisplay::ExitPresentInternal()
-{
- mPresentation = nullptr;
-}
-
-void
-VRDisplay::GetLayers(nsTArray<VRLayer>& result)
-{
- if (mPresentation) {
- mPresentation->GetDOMLayers(result);
- } else {
- result = nsTArray<VRLayer>();
- }
-}
-
-void
-VRDisplay::SubmitFrame()
-{
- if (mPresentation) {
- mPresentation->SubmitFrame();
- }
- mFrameInfo.Clear();
-}
-
-int32_t
-VRDisplay::RequestAnimationFrame(FrameRequestCallback& aCallback,
-ErrorResult& aError)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
-
- int32_t handle;
- aError = vm->ScheduleFrameRequestCallback(aCallback, &handle);
- return handle;
-}
-
-void
-VRDisplay::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError)
-{
- gfx::VRManagerChild* vm = gfx::VRManagerChild::Get();
- vm->CancelFrameRequestCallback(aHandle);
-}
-
-
-bool
-VRDisplay::IsPresenting() const
-{
- // IsPresenting returns true only if this Javascript context is presenting
- // and will return false if another context is presenting.
- return mPresentation != nullptr;
-}
-
-bool
-VRDisplay::IsConnected() const
-{
- return mClient->GetIsConnected();
-}
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(VRDisplay, DOMEventTargetHelper, mCapabilities, mStageParameters)
-
-NS_IMPL_ADDREF_INHERITED(VRDisplay, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(VRDisplay, DOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(VRDisplay)
-NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(VRFrameData)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mPose)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
- tmp->mLeftProjectionMatrix = nullptr;
- tmp->mLeftViewMatrix = nullptr;
- tmp->mRightProjectionMatrix = nullptr;
- tmp->mRightViewMatrix = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mPose)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRFrameData)
- NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftProjectionMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftViewMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightProjectionMatrix)
- NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightViewMatrix)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFrameData, AddRef)
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFrameData, Release)
-
-VRFrameData::VRFrameData(nsISupports* aParent)
- : mParent(aParent)
- , mLeftProjectionMatrix(nullptr)
- , mLeftViewMatrix(nullptr)
- , mRightProjectionMatrix(nullptr)
- , mRightViewMatrix(nullptr)
-{
- mozilla::HoldJSObjects(this);
- mPose = new VRPose(aParent);
-}
-
-VRFrameData::~VRFrameData()
-{
- mozilla::DropJSObjects(this);
-}
-
-/* static */ already_AddRefed<VRFrameData>
-VRFrameData::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
-{
- RefPtr<VRFrameData> obj = new VRFrameData(aGlobal.GetAsSupports());
- return obj.forget();
-}
-
-JSObject*
-VRFrameData::WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto)
-{
- return VRFrameDataBinding::Wrap(aCx, this, aGivenProto);
-}
-
-VRPose*
-VRFrameData::Pose()
-{
- return mPose;
-}
-
-void
-VRFrameData::LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat, JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
-{
- if (!aArray) {
- // Lazily create the Float32Array
- aArray = dom::Float32Array::Create(aCx, this, 16, aMat.components);
- if (!aArray) {
- aRv.NoteJSContextException(aCx);
- return;
- }
- }
- if (aArray) {
- JS::ExposeObjectToActiveJS(aArray);
- }
- aRetval.set(aArray);
-}
-
-double
-VRFrameData::Timestamp() const
-{
- // Converting from seconds to milliseconds
- return mFrameInfo.mVRState.timestamp * 1000.0f;
-}
-
-void
-VRFrameData::GetLeftProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mLeftProjectionMatrix, mFrameInfo.mLeftProjection, aCx,
- aRetval, aRv);
-}
-
-void
-VRFrameData::GetLeftViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mLeftViewMatrix, mFrameInfo.mLeftView, aCx, aRetval, aRv);
-}
-
-void
-VRFrameData::GetRightProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mRightProjectionMatrix, mFrameInfo.mRightProjection, aCx,
- aRetval, aRv);
-}
-
-void
-VRFrameData::GetRightViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv)
-{
- LazyCreateMatrix(mRightViewMatrix, mFrameInfo.mRightView, aCx, aRetval, aRv);
-}
-
-void
-VRFrameData::Update(const VRFrameInfo& aFrameInfo)
-{
- mFrameInfo = aFrameInfo;
-
- mLeftProjectionMatrix = nullptr;
- mLeftViewMatrix = nullptr;
- mRightProjectionMatrix = nullptr;
- mRightViewMatrix = nullptr;
-
- mPose = new VRPose(GetParentObject(), mFrameInfo.mVRState);
-}
-
-void
-VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
- const gfx::VRHMDSensorState& aState,
- float aDepthNear,
- float aDepthFar)
-{
- mVRState = aState;
-
- gfx::Quaternion qt;
- if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
- qt.x = mVRState.orientation[0];
- qt.y = mVRState.orientation[1];
- qt.z = mVRState.orientation[2];
- qt.w = mVRState.orientation[3];
- }
- gfx::Point3D pos;
- if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
- pos.x = -mVRState.position[0];
- pos.y = -mVRState.position[1];
- pos.z = -mVRState.position[2];
- }
- gfx::Matrix4x4 matHead;
- matHead.SetRotationFromQuaternion(qt);
- matHead.PreTranslate(pos);
-
- mLeftView = matHead;
- mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
-
- mRightView = matHead;
- mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
-
- // Avoid division by zero within ConstructProjectionMatrix
- const float kEpsilon = 0.00001f;
- if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
- aDepthFar = aDepthNear + kEpsilon;
- }
-
- const gfx::VRFieldOfView leftFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Left];
- mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
- const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
- mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
-}
-
-VRFrameInfo::VRFrameInfo()
-{
- mVRState.Clear();
-}
-
-bool
-VRFrameInfo::IsDirty()
-{
- return mVRState.timestamp == 0;
-}
-
-void
-VRFrameInfo::Clear()
-{
- mVRState.Clear();
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/vr/VRDisplay.h b/dom/vr/VRDisplay.h
deleted file mode 100644
index d40d3d8ac..000000000
--- a/dom/vr/VRDisplay.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_VRDisplay_h_
-#define mozilla_dom_VRDisplay_h_
-
-#include <stdint.h>
-
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/TypedArray.h"
-#include "mozilla/dom/VRDisplayBinding.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/dom/DOMPoint.h"
-#include "mozilla/dom/DOMRect.h"
-#include "mozilla/dom/Pose.h"
-
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsTArray.h"
-
-#include "gfxVR.h"
-
-namespace mozilla {
-namespace gfx {
-class VRDisplayClient;
-class VRDisplayPresentation;
-struct VRFieldOfView;
-enum class VRDisplayCapabilityFlags : uint16_t;
-struct VRHMDSensorState;
-}
-namespace dom {
-class Navigator;
-
-class VRFieldOfView final : public nsWrapperCache
-{
-public:
- VRFieldOfView(nsISupports* aParent,
- double aUpDegrees, double aRightDegrees,
- double aDownDegrees, double aLeftDegrees);
- VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfView)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfView)
-
- double UpDegrees() const { return mUpDegrees; }
- double RightDegrees() const { return mRightDegrees; }
- double DownDegrees() const { return mDownDegrees; }
- double LeftDegrees() const { return mLeftDegrees; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- virtual ~VRFieldOfView() {}
-
- nsCOMPtr<nsISupports> mParent;
-
- double mUpDegrees;
- double mRightDegrees;
- double mDownDegrees;
- double mLeftDegrees;
-};
-
-class VRDisplayCapabilities final : public nsWrapperCache
-{
-public:
- VRDisplayCapabilities(nsISupports* aParent, const gfx::VRDisplayCapabilityFlags& aFlags)
- : mParent(aParent)
- , mFlags(aFlags)
- {
- }
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRDisplayCapabilities)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRDisplayCapabilities)
-
- nsISupports* GetParentObject() const
- {
- return mParent;
- }
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- bool HasPosition() const;
- bool HasOrientation() const;
- bool HasExternalDisplay() const;
- bool CanPresent() const;
- uint32_t MaxLayers() const;
-
-protected:
- ~VRDisplayCapabilities() {}
- nsCOMPtr<nsISupports> mParent;
- gfx::VRDisplayCapabilityFlags mFlags;
-};
-
-class VRPose final : public Pose
-{
-
-public:
- VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
- explicit VRPose(nsISupports* aParent);
-
- uint32_t FrameID() const { return mFrameId; }
-
- virtual void GetPosition(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetLinearVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetLinearAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetOrientation(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetAngularVelocity(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
- virtual void GetAngularAcceleration(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv) override;
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRPose();
-
- uint32_t mFrameId;
- gfx::VRHMDSensorState mVRState;
-};
-
-struct VRFrameInfo
-{
- VRFrameInfo();
-
- void Update(const gfx::VRDisplayInfo& aInfo,
- const gfx::VRHMDSensorState& aState,
- float aDepthNear,
- float aDepthFar);
-
- void Clear();
- bool IsDirty();
-
- gfx::VRHMDSensorState mVRState;
- gfx::Matrix4x4 mLeftProjection;
- gfx::Matrix4x4 mLeftView;
- gfx::Matrix4x4 mRightProjection;
- gfx::Matrix4x4 mRightView;
-
-};
-
-class VRFrameData final : public nsWrapperCache
-{
-public:
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFrameData)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFrameData)
-
- explicit VRFrameData(nsISupports* aParent);
- static already_AddRefed<VRFrameData> Constructor(const GlobalObject& aGlobal,
- ErrorResult& aRv);
-
- void Update(const VRFrameInfo& aFrameInfo);
-
- // WebIDL Members
- double Timestamp() const;
- void GetLeftProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetLeftViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetRightProjectionMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- void GetRightViewMatrix(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
-
- VRPose* Pose();
-
- // WebIDL Boilerplate
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRFrameData();
- nsCOMPtr<nsISupports> mParent;
-
- VRFrameInfo mFrameInfo;
- RefPtr<VRPose> mPose;
- JS::Heap<JSObject*> mLeftProjectionMatrix;
- JS::Heap<JSObject*> mLeftViewMatrix;
- JS::Heap<JSObject*> mRightProjectionMatrix;
- JS::Heap<JSObject*> mRightViewMatrix;
-
- void LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat,
- JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
-};
-
-class VRStageParameters final : public nsWrapperCache
-{
-public:
- VRStageParameters(nsISupports* aParent,
- const gfx::Matrix4x4& aSittingToStandingTransform,
- const gfx::Size& aSize);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRStageParameters)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRStageParameters)
-
- void GetSittingToStandingTransform(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetval,
- ErrorResult& aRv);
- float SizeX() const { return mSize.width; }
- float SizeZ() const { return mSize.height; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-protected:
- ~VRStageParameters();
-
- nsCOMPtr<nsISupports> mParent;
-
- gfx::Matrix4x4 mSittingToStandingTransform;
- JS::Heap<JSObject*> mSittingToStandingTransformArray;
- gfx::Size mSize;
-};
-
-class VREyeParameters final : public nsWrapperCache
-{
-public:
- VREyeParameters(nsISupports* aParent,
- const gfx::Point3D& aEyeTranslation,
- const gfx::VRFieldOfView& aFOV,
- const gfx::IntSize& aRenderSize);
-
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
-
- void GetOffset(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal,
- ErrorResult& aRv);
-
- VRFieldOfView* FieldOfView();
-
- uint32_t RenderWidth() const { return mRenderSize.width; }
- uint32_t RenderHeight() const { return mRenderSize.height; }
-
- nsISupports* GetParentObject() const { return mParent; }
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-protected:
- ~VREyeParameters();
-
- nsCOMPtr<nsISupports> mParent;
-
-
- gfx::Point3D mEyeTranslation;
- gfx::IntSize mRenderSize;
- JS::Heap<JSObject*> mOffset;
- RefPtr<VRFieldOfView> mFOV;
-};
-
-class VRDisplay final : public DOMEventTargetHelper
- , public nsIObserver
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSIOBSERVER
- NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(VRDisplay, DOMEventTargetHelper)
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- bool IsPresenting() const;
- bool IsConnected() const;
-
- VRDisplayCapabilities* Capabilities();
- VRStageParameters* GetStageParameters();
-
- uint32_t DisplayId() const { return mDisplayId; }
- void GetDisplayName(nsAString& aDisplayName) const { aDisplayName = mDisplayName; }
-
- static bool RefreshVRDisplays(uint64_t aWindowId);
- static void UpdateVRDisplays(nsTArray<RefPtr<VRDisplay> >& aDisplays,
- nsPIDOMWindowInner* aWindow);
-
- gfx::VRDisplayClient *GetClient() {
- return mClient;
- }
-
- virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
-
- bool GetFrameData(VRFrameData& aFrameData);
- already_AddRefed<VRPose> GetPose();
- void ResetPose();
-
- double DepthNear() {
- return mDepthNear;
- }
-
- double DepthFar() {
- return mDepthFar;
- }
-
- void SetDepthNear(double aDepthNear) {
- // XXX When we start sending depth buffers to VRLayer's we will want
- // to communicate this with the VRDisplayHost
- mDepthNear = aDepthNear;
- }
-
- void SetDepthFar(double aDepthFar) {
- // XXX When we start sending depth buffers to VRLayer's we will want
- // to communicate this with the VRDisplayHost
- mDepthFar = aDepthFar;
- }
-
- already_AddRefed<Promise> RequestPresent(const nsTArray<VRLayer>& aLayers, ErrorResult& aRv);
- already_AddRefed<Promise> ExitPresent(ErrorResult& aRv);
- void GetLayers(nsTArray<VRLayer>& result);
- void SubmitFrame();
-
- int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
- mozilla::ErrorResult& aError);
- void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
-
-protected:
- VRDisplay(nsPIDOMWindowInner* aWindow, gfx::VRDisplayClient* aClient);
- virtual ~VRDisplay();
- virtual void LastRelease() override;
-
- void ExitPresentInternal();
- void UpdateFrameInfo();
-
- RefPtr<gfx::VRDisplayClient> mClient;
-
- uint32_t mDisplayId;
- nsString mDisplayName;
-
- RefPtr<VRDisplayCapabilities> mCapabilities;
- RefPtr<VRStageParameters> mStageParameters;
-
- double mDepthNear;
- double mDepthFar;
-
- RefPtr<gfx::VRDisplayPresentation> mPresentation;
-
- /**
- * The WebVR 1.1 spec Requires that VRDisplay.getPose and VRDisplay.getFrameData
- * must return the same values until the next VRDisplay.submitFrame.
- * mFrameInfo is updated only on the first call to either function within one
- * frame. Subsequent calls before the next SubmitFrame or ExitPresent call
- * will use these cached values.
- */
- VRFrameInfo mFrameInfo;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
diff --git a/dom/vr/VREventObserver.cpp b/dom/vr/VREventObserver.cpp
deleted file mode 100644
index 1b6d1b978..000000000
--- a/dom/vr/VREventObserver.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this
-* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "VREventObserver.h"
-
-#include "nsContentUtils.h"
-#include "nsGlobalWindow.h"
-#include "VRManagerChild.h"
-
-namespace mozilla {
-namespace dom {
-
-using namespace gfx;
-
-/**
- * This class is used by nsGlobalWindow to implement window.onvrdisplayconnected,
- * window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
- */
-VREventObserver::VREventObserver(nsGlobalWindow* aGlobalWindow)
- : mWindow(aGlobalWindow)
-{
- MOZ_ASSERT(aGlobalWindow && aGlobalWindow->IsInnerWindow());
-
- VRManagerChild* vmc = VRManagerChild::Get();
- if (vmc) {
- vmc->AddListener(this);
- }
-}
-
-VREventObserver::~VREventObserver()
-{
- VRManagerChild* vmc = VRManagerChild::Get();
- if (vmc) {
- vmc->RemoveListener(this);
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayConnect()
-{
- /**
- * We do not call nsGlobalWindow::NotifyActiveVRDisplaysChanged here, as we
- * can assume that a newly enumerated display is not presenting WebVR
- * content.
- */
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplayconnected"));
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayDisconnect()
-{
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- mWindow->NotifyActiveVRDisplaysChanged();
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplaydisconnected"));
- }
-}
-
-void
-VREventObserver::NotifyVRDisplayPresentChange()
-{
- if (mWindow->AsInner()->IsCurrentInnerWindow()) {
- mWindow->NotifyActiveVRDisplaysChanged();
- MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
- mWindow->GetOuterWindow()->DispatchCustomEvent(
- NS_LITERAL_STRING("vrdisplaypresentchange"));
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/vr/VREventObserver.h b/dom/vr/VREventObserver.h
deleted file mode 100644
index a30bb5960..000000000
--- a/dom/vr/VREventObserver.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
-* License, v. 2.0. If a copy of the MPL was not distributed with this file,
-* You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_VREventObserver_h
-#define mozilla_dom_VREventObserver_h
-
-class nsGlobalWindow;
-
-namespace mozilla {
-namespace dom {
-
-class VREventObserver final
-{
-public:
- ~VREventObserver();
- explicit VREventObserver(nsGlobalWindow* aGlobalWindow);
-
- void NotifyVRDisplayConnect();
- void NotifyVRDisplayDisconnect();
- void NotifyVRDisplayPresentChange();
-
-private:
- // Weak pointer, instance is owned by mWindow.
- nsGlobalWindow* MOZ_NON_OWNING_REF mWindow;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_VREventObserver_h
diff --git a/dom/vr/moz.build b/dom/vr/moz.build
deleted file mode 100644
index a4aa8d69b..000000000
--- a/dom/vr/moz.build
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS.mozilla.dom += [
- 'VRDisplay.h',
- 'VREventObserver.h',
- ]
-
-UNIFIED_SOURCES = [
- 'VRDisplay.cpp',
- 'VREventObserver.cpp',
- ]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
- '/dom/base'
-]
diff --git a/dom/webidl/CommandEvent.webidl b/dom/webidl/CommandEvent.webidl
index 8c16e856c..9856c77c3 100644
--- a/dom/webidl/CommandEvent.webidl
+++ b/dom/webidl/CommandEvent.webidl
@@ -8,7 +8,7 @@ interface CommandEvent : Event {
readonly attribute DOMString? command;
void initCommandEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DOMString? command);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DOMString? command = null);
};
diff --git a/dom/webidl/CompositionEvent.webidl b/dom/webidl/CompositionEvent.webidl
index c293683ce..e4a54d678 100644
--- a/dom/webidl/CompositionEvent.webidl
+++ b/dom/webidl/CompositionEvent.webidl
@@ -25,9 +25,9 @@ interface CompositionEvent : UIEvent
partial interface CompositionEvent
{
void initCompositionEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- DOMString? dataArg,
- DOMString localeArg);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional DOMString? dataArg = null,
+ optional DOMString localeArg = "");
};
diff --git a/dom/webidl/CustomEvent.webidl b/dom/webidl/CustomEvent.webidl
index 299a41ec0..1ea5572b7 100644
--- a/dom/webidl/CustomEvent.webidl
+++ b/dom/webidl/CustomEvent.webidl
@@ -19,9 +19,9 @@ interface CustomEvent : Event
// initCustomEvent is a Gecko specific deprecated method.
[Throws]
void initCustomEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- any detail);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional any detail = null);
};
dictionary CustomEventInit : EventInit
diff --git a/dom/webidl/DeviceMotionEvent.webidl b/dom/webidl/DeviceMotionEvent.webidl
index fa4ecf3ca..c26ab080c 100644
--- a/dom/webidl/DeviceMotionEvent.webidl
+++ b/dom/webidl/DeviceMotionEvent.webidl
@@ -48,10 +48,10 @@ dictionary DeviceMotionEventInit : EventInit {
// Mozilla extensions.
partial interface DeviceMotionEvent {
void initDeviceMotionEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DeviceAccelerationInit acceleration,
- DeviceAccelerationInit accelerationIncludingGravity,
- DeviceRotationRateInit rotationRate,
- double? interval);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DeviceAccelerationInit acceleration,
+ optional DeviceAccelerationInit accelerationIncludingGravity,
+ optional DeviceRotationRateInit rotationRate,
+ optional double? interval = null);
};
diff --git a/dom/webidl/DeviceOrientationEvent.webidl b/dom/webidl/DeviceOrientationEvent.webidl
index 46194453e..9802b3681 100644
--- a/dom/webidl/DeviceOrientationEvent.webidl
+++ b/dom/webidl/DeviceOrientationEvent.webidl
@@ -14,12 +14,12 @@ interface DeviceOrientationEvent : Event
// initDeviceOrientationEvent is a Gecko specific deprecated method.
void initDeviceOrientationEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- double? alpha,
- double? beta,
- double? gamma,
- boolean absolute);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional double? alpha = null,
+ optional double? beta = null,
+ optional double? gamma = null,
+ optional boolean absolute = false);
};
dictionary DeviceOrientationEventInit : EventInit
diff --git a/dom/webidl/DragEvent.webidl b/dom/webidl/DragEvent.webidl
index 2cc173d5c..806177790 100644
--- a/dom/webidl/DragEvent.webidl
+++ b/dom/webidl/DragEvent.webidl
@@ -10,21 +10,21 @@ interface DragEvent : MouseEvent
readonly attribute DataTransfer? dataTransfer;
void initDragEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? aView,
- long aDetail,
- long aScreenX,
- long aScreenY,
- long aClientX,
- long aClientY,
- boolean aCtrlKey,
- boolean aAltKey,
- boolean aShiftKey,
- boolean aMetaKey,
- unsigned short aButton,
- EventTarget? aRelatedTarget,
- DataTransfer? aDataTransfer);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? aView = null,
+ optional long aDetail = 0,
+ optional long aScreenX = 0,
+ optional long aScreenY = 0,
+ optional long aClientX = 0,
+ optional long aClientY = 0,
+ optional boolean aCtrlKey = false,
+ optional boolean aAltKey = false,
+ optional boolean aShiftKey = false,
+ optional boolean aMetaKey = false,
+ optional unsigned short aButton = 0,
+ optional EventTarget? aRelatedTarget = null,
+ optional DataTransfer? aDataTransfer = null);
};
dictionary DragEventInit : MouseEventInit
diff --git a/dom/webidl/Event.webidl b/dom/webidl/Event.webidl
index 70a0ef513..a5d7da7d4 100644
--- a/dom/webidl/Event.webidl
+++ b/dom/webidl/Event.webidl
@@ -51,7 +51,9 @@ interface Event {
[Pure]
readonly attribute DOMHighResTimeStamp timeStamp;
- void initEvent(DOMString type, boolean bubbles, boolean cancelable);
+ void initEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false);
attribute boolean cancelBubble;
};
diff --git a/dom/webidl/HashChangeEvent.webidl b/dom/webidl/HashChangeEvent.webidl
index 735e8eb28..6e8be455c 100644
--- a/dom/webidl/HashChangeEvent.webidl
+++ b/dom/webidl/HashChangeEvent.webidl
@@ -11,10 +11,10 @@ interface HashChangeEvent : Event
readonly attribute DOMString newURL;
void initHashChangeEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- DOMString oldURLArg,
- DOMString newURLArg);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional DOMString oldURLArg = "",
+ optional DOMString newURLArg = "");
};
dictionary HashChangeEventInit : EventInit
diff --git a/dom/webidl/KeyEvent.webidl b/dom/webidl/KeyEvent.webidl
index 516632854..abb4b6a34 100644
--- a/dom/webidl/KeyEvent.webidl
+++ b/dom/webidl/KeyEvent.webidl
@@ -225,13 +225,13 @@ interface KeyEvent
const unsigned long DOM_VK_WIN_OEM_CLEAR = 0xFE;
void initKeyEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- unsigned long keyCode,
- unsigned long charCode);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional unsigned long keyCode = 0,
+ optional unsigned long charCode = 0);
};
diff --git a/dom/webidl/MessageEvent.webidl b/dom/webidl/MessageEvent.webidl
index 548f14520..be5022d67 100644
--- a/dom/webidl/MessageEvent.webidl
+++ b/dom/webidl/MessageEvent.webidl
@@ -43,10 +43,14 @@ interface MessageEvent : Event {
[Pure, Cached, Frozen]
readonly attribute sequence<MessagePort> ports;
- void initMessageEvent(DOMString type, boolean bubbles, boolean cancelable,
- any data, DOMString origin, DOMString lastEventId,
- (WindowProxy or MessagePort)? source,
- sequence<MessagePort> ports);
+ void initMessageEvent(DOMString type,
+ optional boolean bubbles = false,
+ optional boolean cancelable = false,
+ optional any data = null,
+ optional DOMString origin = "",
+ optional DOMString lastEventId = "",
+ optional (WindowProxy or MessagePort)? source = null,
+ optional sequence<MessagePort> ports = []);
};
dictionary MessageEventInit : EventInit {
diff --git a/dom/webidl/MouseEvent.webidl b/dom/webidl/MouseEvent.webidl
index d21354801..192519d57 100644
--- a/dom/webidl/MouseEvent.webidl
+++ b/dom/webidl/MouseEvent.webidl
@@ -32,21 +32,21 @@ interface MouseEvent : UIEvent {
readonly attribute long movementY;
// Deprecated in DOM Level 3:
- void initMouseEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- short buttonArg,
- EventTarget? relatedTargetArg);
+void initMouseEvent(DOMString typeArg,
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null);
// Introduced in DOM Level 3:
boolean getModifierState(DOMString keyArg);
};
@@ -90,23 +90,23 @@ partial interface MouseEvent
readonly attribute unsigned short mozInputSource;
- void initNSMouseEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- short buttonArg,
- EventTarget? relatedTargetArg,
- float pressure,
- unsigned short inputSourceArg);
+ void initNSMouseEvent(DOMString typeArg,
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null,
+ optional float pressure = 0,
+ optional unsigned short inputSourceArg = 0);
[ChromeOnly]
readonly attribute boolean hitCluster; // True when touch occurs in a cluster of links
diff --git a/dom/webidl/MouseScrollEvent.webidl b/dom/webidl/MouseScrollEvent.webidl
index aa9e30fd2..c1e52bd8c 100644
--- a/dom/webidl/MouseScrollEvent.webidl
+++ b/dom/webidl/MouseScrollEvent.webidl
@@ -12,19 +12,19 @@ interface MouseScrollEvent : MouseEvent
readonly attribute long axis;
void initMouseScrollEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- long screenX,
- long screenY,
- long clientX,
- long clientY,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- unsigned short button,
- EventTarget? relatedTarget,
- long axis);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional long screenX = 0,
+ optional long screenY = 0,
+ optional long clientX = 0,
+ optional long clientY = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional short button = 0,
+ optional EventTarget? relatedTarget = null,
+ optional long axis = 0);
};
diff --git a/dom/webidl/MutationEvent.webidl b/dom/webidl/MutationEvent.webidl
index 43c7b1cd0..53625b4f9 100644
--- a/dom/webidl/MutationEvent.webidl
+++ b/dom/webidl/MutationEvent.webidl
@@ -23,11 +23,11 @@ interface MutationEvent : Event
[Throws]
void initMutationEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Node? relatedNode,
- DOMString prevValue,
- DOMString newValue,
- DOMString attrName,
- unsigned short attrChange);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Node? relatedNode = null,
+ optional DOMString prevValue = "",
+ optional DOMString newValue = "",
+ optional DOMString attrName = "",
+ optional unsigned short attrChange = 0);
};
diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl
index 5452f3247..c353e8be7 100644
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -268,14 +268,6 @@ partial interface Navigator {
};
#endif // MOZ_GAMEPAD
-partial interface Navigator {
- [Throws, Pref="dom.vr.enabled"]
- Promise<sequence<VRDisplay>> getVRDisplays();
- // TODO: Use FrozenArray once available. (Bug 1236777)
- [Frozen, Cached, Pure, Pref="dom.vr.enabled"]
- readonly attribute sequence<VRDisplay> activeVRDisplays;
-};
-
#ifdef MOZ_TIME_MANAGER
// nsIDOMMozNavigatorTime
partial interface Navigator {
diff --git a/dom/webidl/ScrollAreaEvent.webidl b/dom/webidl/ScrollAreaEvent.webidl
index 0f48b4bc8..f24b7c0ad 100644
--- a/dom/webidl/ScrollAreaEvent.webidl
+++ b/dom/webidl/ScrollAreaEvent.webidl
@@ -12,12 +12,12 @@ interface ScrollAreaEvent : UIEvent
readonly attribute float height;
void initScrollAreaEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- float x,
- float y,
- float width,
- float height);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional float x = 0,
+ optional float y = 0,
+ optional float width = 0,
+ optional float height = 0);
};
diff --git a/dom/webidl/SimpleGestureEvent.webidl b/dom/webidl/SimpleGestureEvent.webidl
index 0829076dd..76d0d20f6 100644
--- a/dom/webidl/SimpleGestureEvent.webidl
+++ b/dom/webidl/SimpleGestureEvent.webidl
@@ -25,22 +25,22 @@ interface SimpleGestureEvent : MouseEvent
readonly attribute unsigned long clickCount;
void initSimpleGestureEvent(DOMString typeArg,
- boolean canBubbleArg,
- boolean cancelableArg,
- Window? viewArg,
- long detailArg,
- long screenXArg,
- long screenYArg,
- long clientXArg,
- long clientYArg,
- boolean ctrlKeyArg,
- boolean altKeyArg,
- boolean shiftKeyArg,
- boolean metaKeyArg,
- unsigned short buttonArg,
- EventTarget? relatedTargetArg,
- unsigned long allowedDirectionsArg,
- unsigned long directionArg,
- double deltaArg,
- unsigned long clickCount);
+ optional boolean canBubbleArg = false,
+ optional boolean cancelableArg = false,
+ optional Window? viewArg = null,
+ optional long detailArg = 0,
+ optional long screenXArg = 0,
+ optional long screenYArg = 0,
+ optional long clientXArg = 0,
+ optional long clientYArg = 0,
+ optional boolean ctrlKeyArg = false,
+ optional boolean altKeyArg = false,
+ optional boolean shiftKeyArg = false,
+ optional boolean metaKeyArg = false,
+ optional short buttonArg = 0,
+ optional EventTarget? relatedTargetArg = null,
+ optional unsigned long allowedDirectionsArg = 0,
+ optional unsigned long directionArg = 0,
+ optional double deltaArg = 0,
+ optional unsigned long clickCount = 0);
};
diff --git a/dom/webidl/StorageEvent.webidl b/dom/webidl/StorageEvent.webidl
index c3e9605eb..e03f8232c 100644
--- a/dom/webidl/StorageEvent.webidl
+++ b/dom/webidl/StorageEvent.webidl
@@ -21,13 +21,13 @@ interface StorageEvent : Event
// Bug 1016053 - This is not spec compliant.
void initStorageEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- DOMString? key,
- DOMString? oldValue,
- DOMString? newValue,
- DOMString? url,
- Storage? storageArea);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional DOMString? key = null,
+ optional DOMString? oldValue = null,
+ optional DOMString? newValue = null,
+ optional DOMString? url = null,
+ optional Storage? storageArea = null);
};
dictionary StorageEventInit : EventInit
diff --git a/dom/webidl/TimeEvent.webidl b/dom/webidl/TimeEvent.webidl
index 40e7a0beb..8bbe4db53 100644
--- a/dom/webidl/TimeEvent.webidl
+++ b/dom/webidl/TimeEvent.webidl
@@ -15,6 +15,6 @@ interface TimeEvent : Event
readonly attribute long detail;
readonly attribute WindowProxy? view;
void initTimeEvent(DOMString aType,
- Window? aView,
- long aDetail);
+ optional Window? aView = null,
+ optional long aDetail = 0);
};
diff --git a/dom/webidl/TouchEvent.webidl b/dom/webidl/TouchEvent.webidl
index d206fe0fb..fd677787a 100644
--- a/dom/webidl/TouchEvent.webidl
+++ b/dom/webidl/TouchEvent.webidl
@@ -23,15 +23,15 @@ interface TouchEvent : UIEvent {
readonly attribute boolean shiftKey;
void initTouchEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- TouchList? touches,
- TouchList? targetTouches,
- TouchList? changedTouches);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional TouchList? touches = null,
+ optional TouchList? targetTouches = null,
+ optional TouchList? changedTouches = null);
};
diff --git a/dom/webidl/UIEvent.webidl b/dom/webidl/UIEvent.webidl
index 9cc1d0cdf..5be6a443a 100644
--- a/dom/webidl/UIEvent.webidl
+++ b/dom/webidl/UIEvent.webidl
@@ -16,10 +16,10 @@ interface UIEvent : Event
readonly attribute WindowProxy? view;
readonly attribute long detail;
void initUIEvent(DOMString aType,
- boolean aCanBubble,
- boolean aCancelable,
- Window? aView,
- long aDetail);
+ optional boolean aCanBubble = false,
+ optional boolean aCancelable = false,
+ optional Window? aView = null,
+ optional long aDetail = 0);
};
// Additional DOM0 properties.
diff --git a/dom/webidl/VRDisplay.webidl b/dom/webidl/VRDisplay.webidl
deleted file mode 100644
index 63ebd1205..000000000
--- a/dom/webidl/VRDisplay.webidl
+++ /dev/null
@@ -1,286 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-enum VREye {
- "left",
- "right"
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRFieldOfView {
- readonly attribute double upDegrees;
- readonly attribute double rightDegrees;
- readonly attribute double downDegrees;
- readonly attribute double leftDegrees;
-};
-
-typedef (HTMLCanvasElement or OffscreenCanvas) VRSource;
-
-dictionary VRLayer {
- /**
- * XXX - When WebVR in WebWorkers is implemented, HTMLCanvasElement below
- * should be replaced with VRSource.
- */
- HTMLCanvasElement? source = null;
-
- /**
- * The left and right viewports contain 4 values defining the viewport
- * rectangles within the canvas to present to the eye in UV space.
- * [0] left offset of the viewport (0.0 - 1.0)
- * [1] top offset of the viewport (0.0 - 1.0)
- * [2] width of the viewport (0.0 - 1.0)
- * [3] height of the viewport (0.0 - 1.0)
- *
- * When no values are passed, they will be processed as though the left
- * and right sides of the viewport were passed:
- *
- * leftBounds: [0.0, 0.0, 0.5, 1.0]
- * rightBounds: [0.5, 0.0, 0.5, 1.0]
- */
- sequence<float> leftBounds = [];
- sequence<float> rightBounds = [];
-};
-
-/**
- * Values describing the capabilities of a VRDisplay.
- * These are expected to be static per-device/per-user.
- */
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRDisplayCapabilities {
- /**
- * hasPosition is true if the VRDisplay is capable of tracking its position.
- */
- readonly attribute boolean hasPosition;
-
- /**
- * hasOrientation is true if the VRDisplay is capable of tracking its orientation.
- */
- readonly attribute boolean hasOrientation;
-
- /**
- * Whether the VRDisplay is separate from the device’s
- * primary display. If presenting VR content will obscure
- * other content on the device, this should be false. When
- * false, the application should not attempt to mirror VR content
- * or update non-VR UI because that content will not be visible.
- */
- readonly attribute boolean hasExternalDisplay;
-
- /**
- * Whether the VRDisplay is capable of presenting content to an HMD or similar device.
- * Can be used to indicate “magic window” devices that are capable of 6DoF tracking but for
- * which requestPresent is not meaningful. If false then calls to requestPresent should
- * always fail, and getEyeParameters should return null.
- */
- readonly attribute boolean canPresent;
-
- /**
- * Indicates the maximum length of the array that requestPresent() will accept. MUST be 1 if
- canPresent is true, 0 otherwise.
- */
- readonly attribute unsigned long maxLayers;
-};
-
-/**
- * Values describing the the stage / play area for devices
- * that support room-scale experiences.
- */
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRStageParameters {
- /**
- * A 16-element array containing the components of a column-major 4x4
- * affine transform matrix. This matrix transforms the sitting-space position
- * returned by get{Immediate}Pose() to a standing-space position.
- */
- [Throws] readonly attribute Float32Array sittingToStandingTransform;
-
- /**
- * Dimensions of the play-area bounds. The bounds are defined
- * as an axis-aligned rectangle on the floor.
- * The center of the rectangle is at (0,0,0) in standing-space
- * coordinates.
- * These bounds are defined for safety purposes.
- * Content should not require the user to move beyond these
- * bounds; however, it is possible for the user to ignore
- * the bounds resulting in position values outside of
- * this rectangle.
- */
- readonly attribute float sizeX;
- readonly attribute float sizeZ;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRPose
-{
- /**
- * position, linearVelocity, and linearAcceleration are 3-component vectors.
- * position is relative to a sitting space. Transforming this point with
- * VRStageParameters.sittingToStandingTransform converts this to standing space.
- */
- [Constant, Throws] readonly attribute Float32Array? position;
- [Constant, Throws] readonly attribute Float32Array? linearVelocity;
- [Constant, Throws] readonly attribute Float32Array? linearAcceleration;
-
- /* orientation is a 4-entry array representing the components of a quaternion. */
- [Constant, Throws] readonly attribute Float32Array? orientation;
- /* angularVelocity and angularAcceleration are the components of 3-dimensional vectors. */
- [Constant, Throws] readonly attribute Float32Array? angularVelocity;
- [Constant, Throws] readonly attribute Float32Array? angularAcceleration;
-};
-
-[Constructor,
- Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRFrameData {
- readonly attribute DOMHighResTimeStamp timestamp;
-
- [Throws, Pure] readonly attribute Float32Array leftProjectionMatrix;
- [Throws, Pure] readonly attribute Float32Array leftViewMatrix;
-
- [Throws, Pure] readonly attribute Float32Array rightProjectionMatrix;
- [Throws, Pure] readonly attribute Float32Array rightViewMatrix;
-
- [Pure] readonly attribute VRPose pose;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VREyeParameters {
- /**
- * offset is a 3-component vector representing an offset to
- * translate the eye. This value may vary from frame
- * to frame if the user adjusts their headset ipd.
- */
- [Constant, Throws] readonly attribute Float32Array offset;
-
- /* These values may vary as the user adjusts their headset ipd. */
- [Constant] readonly attribute VRFieldOfView fieldOfView;
-
- /**
- * renderWidth and renderHeight specify the recommended render target
- * size of each eye viewport, in pixels. If multiple eyes are rendered
- * in a single render target, then the render target should be made large
- * enough to fit both viewports.
- */
- [Constant] readonly attribute unsigned long renderWidth;
- [Constant] readonly attribute unsigned long renderHeight;
-};
-
-[Pref="dom.vr.enabled",
- HeaderFile="mozilla/dom/VRDisplay.h"]
-interface VRDisplay : EventTarget {
- readonly attribute boolean isConnected;
- readonly attribute boolean isPresenting;
-
- /**
- * Dictionary of capabilities describing the VRDisplay.
- */
- [Constant] readonly attribute VRDisplayCapabilities capabilities;
-
- /**
- * If this VRDisplay supports room-scale experiences, the optional
- * stage attribute contains details on the room-scale parameters.
- */
- readonly attribute VRStageParameters? stageParameters;
-
- /* Return the current VREyeParameters for the given eye. */
- VREyeParameters getEyeParameters(VREye whichEye);
-
- /**
- * An identifier for this distinct VRDisplay. Used as an
- * association point in the Gamepad API.
- */
- [Constant] readonly attribute unsigned long displayId;
-
- /**
- * A display name, a user-readable name identifying it.
- */
- [Constant] readonly attribute DOMString displayName;
-
- /**
- * Populates the passed VRFrameData with the information required to render
- * the current frame.
- */
- boolean getFrameData(VRFrameData frameData);
-
- /**
- * Return a VRPose containing the future predicted pose of the VRDisplay
- * when the current frame will be presented. Subsequent calls to getPose()
- * MUST return a VRPose with the same values until the next call to
- * submitFrame().
- *
- * The VRPose will contain the position, orientation, velocity,
- * and acceleration of each of these properties.
- */
- [NewObject] VRPose getPose();
-
- /**
- * Reset the pose for this display, treating its current position and
- * orientation as the "origin/zero" values. VRPose.position,
- * VRPose.orientation, and VRStageParameters.sittingToStandingTransform may be
- * updated when calling resetPose(). This should be called in only
- * sitting-space experiences.
- */
- void resetPose();
-
- /**
- * z-depth defining the near plane of the eye view frustum
- * enables mapping of values in the render target depth
- * attachment to scene coordinates. Initially set to 0.01.
- */
- attribute double depthNear;
-
- /**
- * z-depth defining the far plane of the eye view frustum
- * enables mapping of values in the render target depth
- * attachment to scene coordinates. Initially set to 10000.0.
- */
- attribute double depthFar;
-
- /**
- * The callback passed to `requestAnimationFrame` will be called
- * any time a new frame should be rendered. When the VRDisplay is
- * presenting the callback will be called at the native refresh
- * rate of the HMD. When not presenting this function acts
- * identically to how window.requestAnimationFrame acts. Content should
- * make no assumptions of frame rate or vsync behavior as the HMD runs
- * asynchronously from other displays and at differing refresh rates.
- */
- [Throws] long requestAnimationFrame(FrameRequestCallback callback);
-
- /**
- * Passing the value returned by `requestAnimationFrame` to
- * `cancelAnimationFrame` will unregister the callback.
- */
- [Throws] void cancelAnimationFrame(long handle);
-
- /**
- * Begin presenting to the VRDisplay. Must be called in response to a user gesture.
- * Repeat calls while already presenting will update the VRLayers being displayed.
- */
- [Throws] Promise<void> requestPresent(sequence<VRLayer> layers);
-
- /**
- * Stops presenting to the VRDisplay.
- */
- [Throws] Promise<void> exitPresent();
-
- /**
- * Get the layers currently being presented.
- */
- sequence<VRLayer> getLayers();
-
- /**
- * The VRLayer provided to the VRDisplay will be captured and presented
- * in the HMD. Calling this function has the same effect on the source
- * canvas as any other operation that uses its source image, and canvases
- * created without preserveDrawingBuffer set to true will be cleared.
- */
- void submitFrame();
-};
diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl
index dd0e6ff69..323d23421 100644
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -1046,3 +1046,12 @@ interface EXT_disjoint_timer_query {
any getQueryEXT(GLenum target, GLenum pname);
any getQueryObjectEXT(WebGLQuery query, GLenum pname);
};
+
+[NoInterfaceObject]
+interface MOZ_debug_get {
+ const GLenum EXTENSIONS = 0x1F03;
+ const GLenum WSI_INFO = 0x10000;
+
+ [Throws]
+ any getParameter(GLenum pname);
+};
diff --git a/dom/webidl/XULCommandEvent.webidl b/dom/webidl/XULCommandEvent.webidl
index 9c024edc1..72dc3802e 100644
--- a/dom/webidl/XULCommandEvent.webidl
+++ b/dom/webidl/XULCommandEvent.webidl
@@ -15,13 +15,13 @@ interface XULCommandEvent : UIEvent
readonly attribute Event? sourceEvent;
void initCommandEvent(DOMString type,
- boolean canBubble,
- boolean cancelable,
- Window? view,
- long detail,
- boolean ctrlKey,
- boolean altKey,
- boolean shiftKey,
- boolean metaKey,
- Event? sourceEvent);
+ optional boolean canBubble = false,
+ optional boolean cancelable = false,
+ optional Window? view = null,
+ optional long detail = 0,
+ optional boolean ctrlKey = false,
+ optional boolean altKey = false,
+ optional boolean shiftKey = false,
+ optional boolean metaKey = false,
+ optional Event? sourceEvent = null);
};
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index 4c2567a1c..06fea2f20 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -555,7 +555,6 @@ WEBIDL_FILES = [
'VideoStreamTrack.webidl',
'VideoTrack.webidl',
'VideoTrackList.webidl',
- 'VRDisplay.webidl',
'VTTCue.webidl',
'VTTRegion.webidl',
'WaveShaperNode.webidl',
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index e1910536f..1f49e16dd 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -30,7 +30,6 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Atomics.h"
#include "mozilla/CycleCollectedJSContext.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h"
#include "mozilla/dom/AtomList.h"
@@ -1534,7 +1533,6 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
const bool isDedicatedWorker = aWorkerPrivate->IsDedicatedWorker();
if (isServiceWorker) {
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_SPAWN_ATTEMPTS, 1);
}
nsCString sharedWorkerScriptSpec;
@@ -1586,14 +1584,6 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
// Worker spawn gets queued due to hitting max workers per domain
// limit so let's log a warning.
WorkerPrivate::ReportErrorToConsole("HittingMaxWorkersPerDomain2");
-
- if (isServiceWorker) {
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_SPAWN_GETS_QUEUED, 1);
- } else if (isSharedWorker) {
- Telemetry::Accumulate(Telemetry::SHARED_WORKER_SPAWN_GETS_QUEUED, 1);
- } else if (isDedicatedWorker) {
- Telemetry::Accumulate(Telemetry::DEDICATED_WORKER_SPAWN_GETS_QUEUED, 1);
- }
}
else if (parent) {
domainInfo->mChildWorkerCount++;
@@ -1669,7 +1659,6 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
if (isServiceWorker) {
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_WAS_SPAWNED, 1);
}
return true;
}
@@ -1766,8 +1755,6 @@ RuntimeService::UnregisterWorker(WorkerPrivate* aWorkerPrivate)
if (aWorkerPrivate->IsServiceWorker()) {
AssertIsOnMainThread();
- Telemetry::AccumulateTimeDelta(Telemetry::SERVICE_WORKER_LIFE_TIME,
- aWorkerPrivate->CreationTimeStamp());
}
if (aWorkerPrivate->IsSharedWorker() ||
diff --git a/dom/workers/ServiceWorkerClient.cpp b/dom/workers/ServiceWorkerClient.cpp
index 660512a5f..6ed3a6ea4 100644
--- a/dom/workers/ServiceWorkerClient.cpp
+++ b/dom/workers/ServiceWorkerClient.cpp
@@ -224,7 +224,7 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
return;
}
- aRv = workerPrivate->DispatchToMainThread(runnable.forget());
+ aRv = NS_DispatchToMainThread(runnable);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
diff --git a/dom/workers/ServiceWorkerClients.cpp b/dom/workers/ServiceWorkerClients.cpp
index 11f864443..38f49e355 100644
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -753,7 +753,7 @@ ServiceWorkerClients::Get(const nsAString& aClientId, ErrorResult& aRv)
RefPtr<GetRunnable> r =
new GetRunnable(promiseProxy, aClientId);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -789,7 +789,7 @@ ServiceWorkerClients::MatchAll(const ClientQueryOptions& aOptions,
new MatchAllRunnable(promiseProxy,
NS_ConvertUTF16toUTF8(scope),
aOptions.mIncludeUncontrolled);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -830,7 +830,7 @@ ServiceWorkerClients::OpenWindow(const nsAString& aUrl,
RefPtr<OpenWindowRunnable> r = new OpenWindowRunnable(promiseProxy,
aUrl, scope);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -859,6 +859,6 @@ ServiceWorkerClients::Claim(ErrorResult& aRv)
RefPtr<ClaimRunnable> runnable =
new ClaimRunnable(promiseProxy, NS_ConvertUTF16toUTF8(scope));
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
return promise.forget();
}
diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
index 1f79e2c92..8b375c635 100644
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -400,13 +400,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
data->mScriptSpec,
data->mResponseURLSpec);
}
- // In theory this can happen after the worker thread is terminated.
- WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
- if (worker) {
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(event.forget()));
- } else {
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event.forget()));
- }
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(event));
}
namespace {
@@ -734,13 +728,7 @@ RespondWithHandler::CancelRequest(nsresult aStatus)
{
nsCOMPtr<nsIRunnable> runnable =
new CancelChannelRunnable(mInterceptedChannel, mRegistration, aStatus);
- // Note, this may run off the worker thread during worker termination.
- WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
- if (worker) {
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(runnable.forget()));
- } else {
- MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
- }
+ NS_DispatchToMainThread(runnable);
mRequestWasHandled = true;
}
@@ -873,8 +861,8 @@ public:
mColumn = column;
}
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(
- NewRunnableMethod(this, &WaitUntilHandler::ReportOnMainThread)));
+ MOZ_ALWAYS_SUCCEEDS(
+ NS_DispatchToMainThread(NewRunnableMethod(this, &WaitUntilHandler::ReportOnMainThread)));
}
void
diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp
index a66df0731..a8f191f2e 100644
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -33,7 +33,6 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/LoadContext.h"
-#include "mozilla/Telemetry.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DOMError.h"
@@ -676,7 +675,6 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow,
queue->ScheduleJob(job);
AssertIsOnMainThread();
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_REGISTRATIONS, 1);
promise.forget(aPromise);
return NS_OK;
@@ -2180,7 +2178,6 @@ ServiceWorkerManager::StartControllingADocument(ServiceWorkerRegistrationInfo* a
if (!aDocumentId.IsEmpty()) {
aDoc->SetId(aDocumentId);
}
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
}
void
diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp
index 24b2e11e6..23ae3b366 100644
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -214,7 +214,7 @@ private:
mDone = true;
#endif
mCallback->SetResult(aResult);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mCallback));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(mCallback));
}
};
@@ -500,7 +500,7 @@ public:
if (mRegistration) {
nsCOMPtr<nsIRunnable> runnable =
new RegistrationUpdateRunnable(mRegistration, true /* time check */);
- aWorkerPrivate->DispatchToMainThread(runnable.forget());
+ NS_DispatchToMainThread(runnable.forget());
}
ExtendableEventWorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
@@ -541,7 +541,7 @@ public:
Cancel() override
{
mCallback->SetResult(false);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(mCallback));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(mCallback));
return WorkerRunnable::Cancel();
}
@@ -637,7 +637,7 @@ public:
mDone = true;
mCallback->SetResult(aResult);
- nsresult rv = mWorkerPrivate->DispatchToMainThread(mCallback);
+ nsresult rv = NS_DispatchToMainThread(mCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
NS_RUNTIMEABORT("Failed to dispatch life cycle event handler.");
}
@@ -768,7 +768,6 @@ public:
void Report(uint16_t aReason = nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR)
{
- WorkerPrivate* workerPrivate = mWorkerPrivate;
mWorkerPrivate->AssertIsOnWorkerThread();
mWorkerPrivate = nullptr;
@@ -780,7 +779,7 @@ public:
NewRunnableMethod<uint16_t>(this,
&PushErrorReporter::ReportOnMainThread, aReason);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
- workerPrivate->DispatchToMainThread(runnable.forget())));
+ NS_DispatchToMainThread(runnable.forget())));
}
void ReportOnMainThread(uint16_t aReason)
@@ -1434,7 +1433,7 @@ public:
Cancel() override
{
nsCOMPtr<nsIRunnable> runnable = new ResumeRequest(mInterceptedChannel);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to resume channel on FetchEventRunnable::Cancel()!\n");
}
WorkerRunnable::Cancel();
@@ -1554,7 +1553,7 @@ private:
NS_ERROR_INTERCEPTION_FAILED);
}
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
}
RefPtr<Promise> waitUntilPromise = event->GetPromise();
diff --git a/dom/workers/ServiceWorkerRegistrar.cpp b/dom/workers/ServiceWorkerRegistrar.cpp
index a4757ea54..7df129c2b 100644
--- a/dom/workers/ServiceWorkerRegistrar.cpp
+++ b/dom/workers/ServiceWorkerRegistrar.cpp
@@ -135,9 +135,6 @@ ServiceWorkerRegistrar::GetRegistrations(
if (firstTime) {
firstTime = false;
- Telemetry::AccumulateTimeDelta(
- Telemetry::SERVICE_WORKER_REGISTRATION_LOADING,
- startTime);
}
}
diff --git a/dom/workers/ServiceWorkerRegistration.cpp b/dom/workers/ServiceWorkerRegistration.cpp
index 451bd2be9..b3cda2c10 100644
--- a/dom/workers/ServiceWorkerRegistration.cpp
+++ b/dom/workers/ServiceWorkerRegistration.cpp
@@ -1107,7 +1107,7 @@ ServiceWorkerRegistrationWorkerThread::Update(ErrorResult& aRv)
}
RefPtr<UpdateRunnable> r = new UpdateRunnable(proxy, mScope);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -1139,7 +1139,7 @@ ServiceWorkerRegistrationWorkerThread::Unregister(ErrorResult& aRv)
}
RefPtr<StartUnregisterRunnable> r = new StartUnregisterRunnable(proxy, mScope);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
return promise.forget();
}
@@ -1161,7 +1161,7 @@ ServiceWorkerRegistrationWorkerThread::InitListener()
nsCOMPtr<nsIRunnable> r =
NewRunnableMethod(mListener, &WorkerListener::StartListeningForEvents);
- MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
}
void
@@ -1183,7 +1183,7 @@ ServiceWorkerRegistrationWorkerThread::ReleaseListener()
nsCOMPtr<nsIRunnable> r =
NewRunnableMethod(mListener, &WorkerListener::StopListeningForEvents);
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
mListener = nullptr;
mWorkerPrivate = nullptr;
diff --git a/dom/workers/ServiceWorkerUpdateJob.cpp b/dom/workers/ServiceWorkerUpdateJob.cpp
index 614fe4de5..69877dfe4 100644
--- a/dom/workers/ServiceWorkerUpdateJob.cpp
+++ b/dom/workers/ServiceWorkerUpdateJob.cpp
@@ -408,8 +408,6 @@ ServiceWorkerUpdateJob::ComparisonResult(nsresult aStatus,
return;
}
- Telemetry::Accumulate(Telemetry::SERVICE_WORKER_UPDATED, 1);
-
// Begin step 7 of the Update algorithm to evaluate the new script.
RefPtr<ServiceWorkerInfo> sw =
diff --git a/dom/workers/ServiceWorkerWindowClient.cpp b/dom/workers/ServiceWorkerWindowClient.cpp
index 2ce0603cf..bae747214 100644
--- a/dom/workers/ServiceWorkerWindowClient.cpp
+++ b/dom/workers/ServiceWorkerWindowClient.cpp
@@ -183,7 +183,7 @@ ServiceWorkerWindowClient::Focus(ErrorResult& aRv) const
if (promiseProxy) {
RefPtr<ClientFocusRunnable> r = new ClientFocusRunnable(mWindowId,
promiseProxy);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
@@ -549,7 +549,7 @@ ServiceWorkerWindowClient::Navigate(const nsAString& aUrl, ErrorResult& aRv)
if (promiseProxy) {
RefPtr<ClientNavigateRunnable> r =
new ClientNavigateRunnable(mWindowId, aUrl, scope, promiseProxy);
- MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
diff --git a/dom/workers/SharedWorker.cpp b/dom/workers/SharedWorker.cpp
index b0eed2def..99bb50339 100644
--- a/dom/workers/SharedWorker.cpp
+++ b/dom/workers/SharedWorker.cpp
@@ -12,7 +12,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/SharedWorkerBinding.h"
-#include "mozilla/Telemetry.h"
#include "nsContentUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsIDOMEvent.h"
@@ -73,8 +72,6 @@ SharedWorker::Constructor(const GlobalObject& aGlobal, JSContext* aCx,
return nullptr;
}
- Telemetry::Accumulate(Telemetry::SHARED_WORKER_COUNT, 1);
-
return sharedWorker.forget();
}
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 612090027..6bc5c4f96 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -404,7 +404,7 @@ private:
RefPtr<MainThreadReleaseRunnable> runnable =
new MainThreadReleaseRunnable(doomed, loadGroupToCancel);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to dispatch, going to leak!");
}
@@ -4078,7 +4078,7 @@ WorkerDebugger::PostMessageToDebugger(const nsAString& aMessage)
RefPtr<PostDebuggerMessageRunnable> runnable =
new PostDebuggerMessageRunnable(this, aMessage);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
NS_WARNING("Failed to post message to debugger on main thread!");
}
}
@@ -4103,7 +4103,7 @@ WorkerDebugger::ReportErrorToDebugger(const nsAString& aFilename,
RefPtr<ReportDebuggerErrorRunnable> runnable =
new ReportDebuggerErrorRunnable(this, aFilename, aLineno, aMessage);
- if (NS_FAILED(mWorkerPrivate->DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
NS_WARNING("Failed to report error to debugger on main thread!");
}
}
@@ -4862,7 +4862,7 @@ WorkerPrivate::MaybeDispatchLoadFailedRunnable()
return;
}
- MOZ_ALWAYS_SUCCEEDS(DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
}
nsIEventTarget*
@@ -5083,7 +5083,7 @@ WorkerPrivate::ScheduleDeletion(WorkerRanOrNot aRanOrNot)
else {
RefPtr<TopLevelWorkerFinishedRunnable> runnable =
new TopLevelWorkerFinishedRunnable(this);
- if (NS_FAILED(DispatchToMainThread(runnable.forget()))) {
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
NS_WARNING("Failed to dispatch runnable!");
}
}
diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp
index 6bbe40f66..60d69d4e4 100644
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -15,7 +15,6 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Telemetry.h"
#include "js/RootingAPI.h"
#include "js/Value.h"
@@ -118,7 +117,10 @@ WorkerRunnable::DispatchInternal()
return NS_SUCCEEDED(parent->Dispatch(runnable.forget()));
}
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+ MOZ_ASSERT(mainThread);
+
+ return NS_SUCCEEDED(mainThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
void
@@ -554,7 +556,10 @@ WorkerControlRunnable::DispatchInternal()
return NS_SUCCEEDED(parent->DispatchControlRunnable(runnable.forget()));
}
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+ MOZ_ASSERT(mainThread);
+
+ return NS_SUCCEEDED(mainThread->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
NS_IMPL_ISUPPORTS_INHERITED0(WorkerControlRunnable, WorkerRunnable)
@@ -572,8 +577,6 @@ WorkerMainThreadRunnable::Dispatch(Status aFailStatus, ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
- TimeStamp startTime = TimeStamp::NowLoRes();
-
AutoSyncLoopHolder syncLoop(mWorkerPrivate, aFailStatus);
mSyncLoopTarget = syncLoop.GetEventTarget();
@@ -583,18 +586,16 @@ WorkerMainThreadRunnable::Dispatch(Status aFailStatus, ErrorResult& aRv)
return;
}
- DebugOnly<nsresult> rv = mWorkerPrivate->DispatchToMainThread(this);
+ RefPtr<WorkerMainThreadRunnable> runnable(this);
+
+ DebugOnly<nsresult> rv =
+ NS_DispatchToMainThread(runnable.forget(), NS_DISPATCH_NORMAL);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Should only fail after xpcom-shutdown-threads and we're gone by then");
if (!syncLoop.Run()) {
aRv.ThrowUncatchableException();
}
-
- Telemetry::Accumulate(Telemetry::SYNC_WORKER_OPERATION, mTelemetryKey,
- static_cast<uint32_t>((TimeStamp::NowLoRes() - startTime)
- .ToMilliseconds()));
- Unused << startTime; // Shut the compiler up.
}
NS_IMETHODIMP
@@ -678,7 +679,7 @@ WorkerProxyToMainThreadRunnable::Dispatch()
return false;
}
- if (NS_WARN_IF(NS_FAILED(mWorkerPrivate->DispatchToMainThread(this)))) {
+ if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(this)))) {
ReleaseWorker();
RunBackOnWorkerThread();
return false;
diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
index 54252e53b..ace1a09fc 100644
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -717,7 +717,7 @@ ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
new WorkerScopeSkipWaitingRunnable(promiseProxy,
NS_ConvertUTF16toUTF8(mScope));
- MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
+ MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
return promise.forget();
}
diff --git a/dom/xbl/nsXBLBinding.cpp b/dom/xbl/nsXBLBinding.cpp
index d9a2aacc5..b8174f6c2 100644
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -1049,7 +1049,8 @@ nsXBLBinding::DoInitJSClass(JSContext *cx,
// to create and define it.
JS::Rooted<JSObject*> proto(cx);
JS::Rooted<JS::PropertyDescriptor> desc(cx);
- if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
+ if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(),
+ aClassName.Length(), &desc)) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNew = !desc.object();
diff --git a/dom/xbl/nsXBLProtoImpl.cpp b/dom/xbl/nsXBLProtoImpl.cpp
index 4db9cabf0..5efcb71e0 100644
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -100,11 +100,15 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// end up with a different content prototype, but we'll already have a property
// holder called |foo| in the XBL scope. Check for that to avoid wasteful and
// weird property holder duplication.
- const char16_t* className = aPrototypeBinding->ClassName().get();
+ const nsString& className = aPrototypeBinding->ClassName();
+ const char16_t* classNameChars = className.get();
+ const size_t classNameLen = className.Length();
+
JS::Rooted<JSObject*> propertyHolder(cx);
JS::Rooted<JS::PropertyDescriptor> existingHolder(cx);
if (scopeObject != globalObject &&
- !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, className, &existingHolder)) {
+ !JS_GetOwnUCPropertyDescriptor(cx, scopeObject, classNameChars,
+ classNameLen, &existingHolder)) {
return NS_ERROR_FAILURE;
}
bool propertyHolderIsNew = !existingHolder.object() || !existingHolder.value().isObject();
@@ -119,8 +123,8 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// Define it as a property on the scopeObject, using the same name used on
// the content side.
- bool ok = JS_DefineUCProperty(cx, scopeObject, className, -1, propertyHolder,
- JSPROP_PERMANENT | JSPROP_READONLY,
+ bool ok = JS_DefineUCProperty(cx, scopeObject, classNameChars, classNameLen,
+ propertyHolder, JSPROP_PERMANENT | JSPROP_READONLY,
JS_STUBGETTER, JS_STUBSETTER);
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
} else {
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
index 4fd34a993..613008ad5 100644
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -757,15 +757,6 @@ XMLHttpRequestMainThread::SetResponseType(XMLHttpRequestResponseType aResponseTy
return;
}
- // We want to get rid of this moz-only types. Bug 1335365.
- if (aResponseType == XMLHttpRequestResponseType::Moz_blob) {
- Telemetry::Accumulate(Telemetry::MOZ_BLOB_IN_XHR, 1);
- } else if (aResponseType == XMLHttpRequestResponseType::Moz_chunked_text) {
- Telemetry::Accumulate(Telemetry::MOZ_CHUNKED_TEXT_IN_XHR, 1);
- } else if (aResponseType == XMLHttpRequestResponseType::Moz_chunked_arraybuffer) {
- Telemetry::Accumulate(Telemetry::MOZ_CHUNKED_ARRAYBUFFER_IN_XHR, 1);
- }
-
// Set the responseType attribute's value to the given value.
mResponseType = aResponseType;
}
@@ -1521,8 +1512,6 @@ XMLHttpRequestMainThread::Open(const nsACString& aMethod,
GetOwner()->GetExtantDoc()->WarnOnceAbout(nsIDocument::eSyncXMLHttpRequest);
}
- Telemetry::Accumulate(Telemetry::XMLHTTPREQUEST_ASYNC_OR_SYNC, aAsync ? 0 : 1);
-
// Step 1
nsCOMPtr<nsIDocument> responsibleDocument = GetDocumentIfCurrent();
if (!responsibleDocument) {
diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp
index c9e892f26..2af61bd7d 100644
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -1588,8 +1588,6 @@ XMLHttpRequestWorker::Construct(const GlobalObject& aGlobal,
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(cx);
MOZ_ASSERT(workerPrivate);
- Telemetry::Accumulate(Telemetry::XHR_IN_WORKER, 1);
-
RefPtr<XMLHttpRequestWorker> xhr = new XMLHttpRequestWorker(workerPrivate);
if (workerPrivate->XHRParamsAllowed()) {
diff --git a/dom/xul/nsXULPrototypeCache.cpp b/dom/xul/nsXULPrototypeCache.cpp
index 84a201d59..2c3454860 100644
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -45,12 +45,6 @@ UpdategDisableXULCache()
// Get the value of "nglayout.debug.disable_xul_cache" preference
gDisableXULCache =
Preferences::GetBool(kDisableXULCachePref, gDisableXULCache);
-
- // Sets the flag if the XUL cache is disabled
- if (gDisableXULCache) {
- Telemetry::Accumulate(Telemetry::XUL_CACHE_DISABLED, true);
- }
-
}
static void