import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1263951 - Avoid trying to initialize new GMP instances once the browser enters shutdown. r=cpearce (3ca153c7f4)
- Bug 1268714 - Check for failure result or a failed nsresult from SendLoadGMP. r=mccr8 (928546a72a)
- remove redundant decl (0c7c81e384)
- Bug 1161339 - Add gtest calling rust code. r=cajbir (9c0a4982d7)
- Bug 1269249: [MSE] P1. Clamp range to media source duration when media source is ended. r=jwwang (dfc42686b5)
- Bug 1269178: P4. Add mochitest. r=gerald (37fe5f9232)
- Bug 1269249: [MSE] P2. Add mochitest verifying behavior. r=jwwang (f50fb0d648)
- Bug 1245052 - various media b2g build errors r=jya (1fc0f3b8f1)
- Bug 1239598 - Fix potential deadlock and race condition r=bechen (dfebc1b9c5)
- Bug 1185931 - Add assert(mDecoderStateMachine). r=jwwang (16a79dd863)
- bits of Bug 1160695 (a595535a04)
- Bug 1205209 - Check whether mStreamSource is null in MediaOmxReader. r=bechen (3e380b282d)
- Bug 1210286 - Fall back to converting SourceSurfaces (RGB) to NV12 in OMXCodecWrapper. r=jolin (b9e26a43ee)
- Bug 1090015 - Suppress multichar warnings in the OMX code. r=kinetik (13cea78721)
- missing bit of Bug 1137151: Remove ref-counting from |OMXVideoEncoder| (0abf3cccf3)
- Bug 1239610 - Remove GonkNativeWindowClient usage from OmxDecoder r=jolin (a1ccc2a40e)
- missing bit of 1198576 (c3284a3002)
- Bug 1267637: P1. Consider invalid an AudioData with more than 8 audio channels. r=gerald (9bacf3fa8d)
- Bug 1267637: P2. Ignore outright audio track considered invalid. r=gerald (d34b468c87)
- Bug 1267637: [opus] P3. Reject audio data with unsupported audio configuration. r=gerald (90be7f8e3a)
- Bug 1267637: [vorbis] P4. Reject audio data with unsupported audio configuration. r=gerald (2321df4669)
- Bug 1267637: [AT] P6. Reject audio data with unsupported channel configuration. r=gerald (48756a764b)
- Bug 1267637: [ffmpeg] P7. Reject audio data with unsupported channel configuration. r=gerald (bbf90018b5)
- Bug 1267637: [gonk] P8. Reject audio data with unsupported channel configuration. r=gerald (44043594f0)
- Bug 1199809 - Remove all references to unused task queue. r=jya (829bb54ce7)
- Bug 1199809 - Don't schedule decoder I/O task when there will be more input. r=bwu (284c8b28d4)
- Bug 1215441 - Skip flush before Init() is completed. r=sotaro (f59f4ae450)
- Bug 1207214 - Assert decoder attaches EOS flag to final output buffer. r=sotaro (da0fc1f41b)
- Bug 1217220 - use output timestamp to decide which item needs to be removed from waiting list. r=jya (b056c21000)
- Bug 1222919 - Make ProcessFlush() virtual. r=jya (bea87e8e8a)
- Bug 1259366 - Flush after eos of android::MediaCodec r=jolin (c8e1e038ad)
- Bug 1199809 - Reset last decoded frame time on looper thread to avoid race condition. r=jya (1d56c95439)
- cleanup (83701e29ea)
- Bug 1267637: [wmf] P9. Reject audio data with unsupported channel configuration. r=gerald (c1f32cf152)
- Bug 1264925: Force D3D9 when attempting to decode VP8 or VP9. r=mattwoodrow (2a7d853fe6)
- Bug 1162899 - Use sync message for in-process mozHasPendingMessage. r=fabrice (d28430d0b2)
- Bug 1235484 - Part 1: Refine radio state check in MmsService. r=bevistseng (5f00e3ec79)
- remove android, fix some missing tests (01b371eb39)
- Bug 1259148 - Notify content when the notification permission pop-up is dismissed by the user. r=past,wchen (ca2dfbf92f)
- Bug 1267357 Cycle collect NotificationPermissionRequest::mCallback. r=mccr8 (6d0086af08)
- Bug 1265828 - Remove persistent notifications from storage. r=wchen (230d6f8458)
- Bug 1254816 - Use IgnoredErrorResult instead of ErrorResult for rv in nsDOMOfflineResourceList::Length(). r=bz (581f5c69db)
- Bug 1140478: Free the string returned by PrintJSStack(), in android shutdown logging function. r=jorendorff (ebf6ef80d1)
- Bug 1191137 - fix Mulet and responsive design mode to send key events properly r=ochameau,jryans (d47db5bf2b)
- Bug 1267096 - Return early if we have no global when creating a Promise. r=smaug (d4075f38fe)
- Bug 1146418 - Promise API entry points should use NS_ASSERT_OWNINGTHREAD, r=baku (a43b49c451)
- Bug 1262069: Wrap promise resolution values before storing. r=bz (66ebb63ce1)
- Bug 1246073 - Fix unique constraint errors in the H2 backend when resubscribing. r=dragana (43c67dc6bc)
- Bug 1266433 - Clean up nsIPushNotifier static casts. r=dragana (eef5497c75)
- Bug 1266433 - Update the comments in the Push XPIDL interfaces. r=me (35cd32c385)
- Bug 1266433 - Indicate push subscriptions created by privileged code. r=dragana (824381dd69)
- Bug 1242436 - default value of ok = true in order to check the return of SendPush and SendPushSubscriptionChange. r=kitcambridge (da55effde0)
- Bug 1267889 - Always steal the error result in PushMessage::Json. r=dragana (a66bf171b6)
- Bug 1243778 - PushRecord::getLastVisit cannot rely on the Places url index anymore. r=kitcambridge (07c3bdc4db)
- Bug 1260499 - Handle incoming messages before push service is initialized. r=nalexander,jchen (d60ccda56b)
- Bug 1265915 - Remove adaptive pings from the Push WebSocket backend. r=dragana (c8de7d5dd3)
- Bug 1262559: Fix misspelled comment in dom/push/PushServiceWebSocket.jsm; r=jdm (a9d869773d)
- Bug 1265914 - Remove Push UDP wake-up. r=dragana (128cf912bb)
- Bug 1261634 - Update whitespace skipping for meta csp. r=dveditz (c6abb5c502)
- Bug 1227813 - CSP: Ignore unsafe-inline within style-src if hash or nonce specified. r=kmckinley (ab1db6e779)
- Bug 1192840 - Fix CSP report content-type. r=ckerschb (81c55b28f0)
- Bug 1262635 - Don't strip URIs of ftp: when sending reports. r=dveditz (77e9aacac1)
- Bug 1216365 - nsMixedContentBlocker should use innerMostURI for aContentLocation. r=tanvi (9134c28268)
- Bug 1260153 - remove unreachable code in nsMixedContentBlocker. if/else blocks above all return. r=ckerschb (da297bf7ff)
- Bug 1202374 - "Can't open apps any more". r=lissyx+mozillians (ed090dbfce)
- Bug 1216498 - Bump SettinsDB version in order to enable pin the web. r=mhenretty (e2d0e9986f)
- Bug 1226906 - Bump Settings BD version. r=gwagner (e063a2d482)
- Bug 1119727 - Make Settings Soft Lockup threshold configurable. r=gwagner (1f5d9d3a50)
- var-let (48c1155a0e)
- bit of Backed out 2 changesets (bug 1202902) (828b6981a8)
- Bug 1228673 - Clean-up 'Then' before ~MediaTimer. r=jya (e51663a94b)
- align tests (0fbfa6f14b)
- Bug 1152236: OMX codec should use AnnexB as input format. r=jya (fc7ed581ac)
- Bug 1153895 - Support audio AMR-WB for Gonk in MP4Reader. r=jya (d9a530979e)
- Bug 1174623 - Support mp3 in Gonk PDM. r=sotaro (1f6efd4397)
- Bug 1174166 - Support H.263 in Gonk PDM. r=sotaro (5634e66ce3)
- Bug 1251155 - Remove GLContext from VideoDataDecoder r=snorp (814629fcd9)
- Bug 1262456 - [2.1] Replace queue adapter with deque. r=snorp (80587b789d)
- Bug 1262456 - [1.1] Prevent interruption of the decoder shutdown procedure and early shutdown return. r=snorp (98b97f0b48)
- Bug 1248792 - [1.2] Replace MediaRawData raw pointers with RefPtr. r=snorp (c1c62c4dc6)
- Bug 1226730 - [1.1] Provide sample rate instead of bit depth in audio format creation. r=snorp (86e50d757f)
- Bug 1244292 - [1.2] Release decoder on init failure. r=snorp (48b18cf8dd)
- Bug 1267637: [android] P5. Reject audio data with unsupported audio configuration. r=gerald (cf74f43c71)
- Bug 1230784 - Don't copy SurfaceTexture contents when presenting video on Android r=esawin,jya (fbd0ffd1ea)
- Bug 1230768. r=jesup (1619923f64)
- Bug 1205164 - Make sure ShmemPool high water mark is logged in all allocators. r=jesup (1fa4710751)
- Bug 1205164 - Fix ShmemPool detection of failed allocations. r=jesup (070327ef38)
- Bug 1247933 - do not perform null check on aClient since we know for sure it's a valid pointert. r=sotaro (1ac12b4091)
- Bug 1200903 - Fix MediaSystemResourceService::RemoveRequests() r=cpearce (13676b47c7)
- Bug 1250083 - make sure value attributed to usPerDataChunk is floating point value. r=cpearce (af9c3bd65d)
- Bug 1250497: Initalised Values used in WaveDemuxer.cpp. r=cpearce (36a24774ed)
- Bug 1250293 - Fixed Coverity warning in WaveDemuxer.cpp. r=cpearce (f5a690fac4)
- bug 1220042 make AlignedTArray base class inheritance private r=jwwang (3dd9efaa68)
- Bug 877662 - Add AlignmentUtils.h r=padenot (82b7563dd7)
- bug 930257 schedule Analyser inactive check when sending last null chunk r=padenot (61e9b5cf0f)
- bug 1197028 add MOZ_IMPLICIT for AudioBlock constructor from base AudioChunk on CLOSED TREE (0e2a86c6b5)
- bug 1203380 add custom AudioBlock copy constructor and make AudioChunk conversion constructor explicit r=padenot (56f2e37d5b)
- bug 1205540 initialize mBufferFormat when constructing silent block r=padenot (078feb4af4)
- bug 1203380 ClearDownstreamMark() before returning AsMutableChunk() r=padenot (56ea1f589f)
- bug 1203380 tighten not-sharing assertion in ChannelFloatsForWrite() r=padenot (368e354a06)
- bug 1203380 add custom assignment operator to AudioBlock r=padenot (31f9f914d1)
- Bug 877662 - Align audio buffer allocations to 16 byte boundaries r=padenot (5f33e9dd0e)
- Bug 1173016 - Bustage fix: mark BasicWaveformCache's ctor as `explicit`, on a CLOSED TREE. (bb28bb93fc)
- Bug 1265397 - Add a length attribute to OfflineAudioContext. r=smaug (3c2cf2aee6)
- bug 1255618 remove AudioContext from global window at unlink r=Ehsan (5332c8b42b)
- bug 1222202 implement query interface to nsIMemoryReporter r=bz (e6662d2ba8)
- Bug 1259831 - Remove the auto-suspend logic for AudioContext. r=karlt (3376fb3209)
- Bug 1232326 - Uninitialised value use in AudioBufferInPlaceScale. r=dminor. (548cbbfa52)
- Bug 1240054 - Only rebuild BandLimitedTables if more partials are required r=padenot (39bf05e142)
- Bug 1216081 - OscillatorNodeEngine::mFinalFrequency is used uninitialised. r=padenot. (5989729ec6)
- Bug 1265405 - Use a dictionary to specify how PeriodicWave should be normalized (or not); r=padenot (f43e3f17ba)
- Bug 1267096 - Check the return value of Promise::Create in AudioContext::StartRendering. r=smaug (5efca6cfe8)
- Bug 1267579 - Unexpected result when using OscillatorNode with custom wave shape; r=padenot (ed62d1b496)
- Bug 1209904 - Optimize OscillatorNode when its frequency is not changin and it's using ::ComputeCustom. r=karlt (9a2246cc3f)
- Bug 877662 - Use SSE2 versions of AudioNodeEngine functions r=padenot (1efa0b2cf3)
- Bug 877662 - Add an SSE2 implementation of AudioNodeEngine.cpp functions. r=ehsan (ce5ff146e5)
- Bug 877662 - Update SSE2 versions of AudioNodeEngine functions r=padenot (ded51f436e)
- Bug 1266405 - AudioBufferSourceNode::CopyFromBuffer should not borrow unaligned buffers; r=padenot (a2880e5c97)
- bug 1227411 add some initial logging of AudioNode API use r=padenot (6d0febaf34)
- bug 1199561 delay offline buffer allocation until non-null input is received r=padenot (38d56f3e89)
- Bug 1110344 - Replace float by double in AudioTimelineEvent ctor to prevent a rounding issue. r=padenot (c358371cfa)
- Bug 1231124 - addded mCurve to constructor. r=smaug (572fed89d6)
- Bug 1232646 - initialize 3 variables: mCurve, mTimeConstant, mDuration. r=cpearce (e36b3dbb71)
- Bug 1069825 - Check if we compare two automation curves occuring at the same time during overlap checking. r=padenot (35624be622)
- bug 1227411 add WEB_AUDIO_API_LOG r=padenot (89de67e91b)
- bug 1189168 avoid main thread assertion accessing mNode in SizeOfIncludingThis() r=padenot (370df2ff5b)
- Bug 1266047 - Fix crash in mozilla::AudioBufferAddWithScale_SSE r=padenot (388de2edf6)
- Bug 1266772 - Unbreak FreeBSD build after bug 881587. r=dminor (e194878792)
- Bug 1266112 - Remove unnecessary alignment checks from AudioNodeEngine.cpp; r=padenot (284ac98016)
- Bug 881587 - Add SSE2 version of AudioNodeEngine.cpp routines added in bug 815643. r=tterribe (5532515d07)
- Bug 881587 - Use SSE2 version of AudioNodeEngine.cpp routines added in bug 815643. r=padenot (82100493a4)
- Bug 1105513 - Add a NEON version for AudioBlockPanStereoToStereo when aIsOnTheLeft is an array r=padenot (b102beb60d)
- Bug 1203836 - Properly handle silent chunks in AudioNodeExternalInputStream. r=karlt (0597e5c122)
- Bug 1265131, part 1 - update moz.build for Skia m51. r=jrmuizel (745537cf9b)
- Bug 1265131, part 2 - update SkiaGLGlue for Skia m51. r=jrmuizel (71a3ffc91e)
- Bug 1265131, part 3 - update Moz2d for Skia m51. r=jrmuizel (2129a455cb)
- Bug 1262745 - Fix tests for Canvas CSS/SVG Filters. r=mstange (93d3652ac0)
- Bug 1265131, part 4 - fix tests for Skia m51 update. r=jrmuizel (964ea5c037)
- Bug 1265131, part 5 - update Skia to m51 branch. r=jrmuizel (42da76e40e)
- Bug 1268816 - allow Skia to use C++11 features on platforms that have them. r=froydnj (ff7d9e46b6)
- Bug 1268816 - follow-up to fix #ifdef -> #if. r=me (b81d86c173)
- Bug 1267180. Don't draw emojis as paths when they are too big. r=lsalzman (61c3bd732c)
- Bug 1269247 - check that SkPaint has a typeface before using it. r=mchang (cf873c19b0)
- bug 1249738 - make sScreenConfigurationObservers a function static r=dhylands (ab698385c4)
- bug 1249738 - make sBatteryObservers a function static r=dhylands (eb205b1b64)
- bits of Bug 1265131, part 5 (1340103927)
- Bug 1248224 - backport of Skia GrPathUtils::QuadUVMatrix assertion fix. r=jrmuizel (bcf81bf241)
- bug 1249738 - make sNetworkObservers a function static r=dhylands (a5d03d4425)
This commit is contained in:
2024-09-18 09:50:59 +08:00
parent 5e324904fd
commit 116abd772d
1654 changed files with 56451 additions and 49941 deletions
+1
View File
@@ -34,6 +34,7 @@ ostream
set
stack
string
type_traits
utility
vector
cassert
+1
View File
@@ -1114,6 +1114,7 @@ ToolUtils.h
tr1/functional
trace.h
Traps.h
type_traits
typeinfo
types.h
Types.h
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--
user_pref("browser.send_pings", true);
-->
<script>
function boom() {
var aLink = document.createElement('a');
document.body.appendChild(aLink);
aLink.ping = "ping";
aLink.href = "href";
aLink.click();
var baseElement = document.createElement('base');
baseElement.setAttribute("href", "javascript:void 0");
document.head.appendChild(baseElement);
}
</script>
</head>
<body onload="boom();"></body>
</html>
+1
View File
@@ -12,3 +12,4 @@ load 514779-1.xhtml
load 614499-1.html
load 678872-1.html
skip-if(Android||B2G) pref(dom.disable_open_during_load,false) load 914521.html
pref(browser.send_pings,true) load 1257730-1.html
+1 -1
View File
@@ -18,7 +18,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
this.EXPORTED_SYMBOLS = ["Langpacks"];
let debug;
var debug;
function debugPrefObserver() {
debug = Services.prefs.getBoolPref("dom.mozApps.debug")
? (aMsg) => {
+36
View File
@@ -0,0 +1,36 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<script>
<![CDATA[
function boom()
{
var d = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
d.setAttributeNS(null, "contenteditable", "true");
var s = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
d.appendChild(s);
document.documentElement.appendChild(d);
var textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
var t1 = document.createTextNode("A");
textarea.appendChild(t1);
var t2 = document.createTextNode("B");
textarea.appendChild(t2);
document.documentElement.appendChild(textarea);
document.documentElement.offsetHeight;
d.removeChild(s);
textarea.removeChild(t2);
document.documentElement.appendChild(document.createTextNode(" C "));
document.documentElement.appendChild(t2);
}
window.addEventListener("load", boom, false);
]]>
</script>
<!-- no body -->
</html>
+1
View File
@@ -148,6 +148,7 @@ load 709954.html
load 713417-1.html
load 713417-2.html
load 715056.html
load 729431-1.xhtml
load 741163-1.html
load 745495.html
load 752226-1.html
+2 -2
View File
@@ -172,7 +172,7 @@ var check_use_counter_iframe = Task.async(function* (file, use_counter_middlefix
}
});
let check_use_counter_img = Task.async(function* (file, use_counter_middlefix) {
var check_use_counter_img = Task.async(function* (file, use_counter_middlefix) {
info("checking " + file + " as image with histogram " + use_counter_middlefix);
let newTab = gBrowser.addTab("about:blank");
@@ -230,7 +230,7 @@ let check_use_counter_img = Task.async(function* (file, use_counter_middlefix) {
"document counts " + use_counter_middlefix + " after are correct");
});
let check_use_counter_direct = Task.async(function* (file, use_counter_middlefix, xfail=false) {
var check_use_counter_direct = Task.async(function* (file, use_counter_middlefix, xfail=false) {
info("checking " + file + " with histogram " + use_counter_middlefix);
let newTab = gBrowser.addTab( "about:blank");
@@ -7,7 +7,7 @@
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.filter = 'drop-shadow(0 10px black)';
ctx.filter = 'drop-shadow(0 10px #000)';
ctx.globalAlpha = 0.5;
ctx.fillStyle = '#0f0';
ctx.fillRect(25, 25, 50, 40);
+1 -1
View File
@@ -3,7 +3,7 @@ default-preferences pref(canvas.filters.enabled,true)
== default-color.html ref.html
== drop-shadow.html ref.html
== drop-shadow-transformed.html ref.html
== global-alpha.html global-alpha-ref.html
fuzzy-if(azureSkia,1,1500) == global-alpha.html global-alpha-ref.html
== global-composite-operation.html global-composite-operation-ref.html
== liveness.html ref.html
== multiple-drop-shadows.html shadow-ref.html
@@ -10,8 +10,12 @@ var ctx = canvas.getContext('2d');
ctx.font = '20px sans-serif';
ctx.filter = 'drop-shadow(0 .5em black)';
ctx.fillStyle = '#0f0';
ctx.fillRect(25, 25, 25, 40);
ctx.fillRect(25, 25, 50, 40);
canvas.style.fontSize = '5px';
ctx.font = '4em sans-serif';
ctx.filter = 'drop-shadow(0 .5em black)';
</script>
</body>
</html>
+75 -73
View File
@@ -20,16 +20,15 @@ pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback wrappe
== webgl-resize-test.html wrapper.html?green.png
# Check that captureStream() displays in a local video element
skip-if(winWidget&&layersGPUAccelerated&&d2d) == webgl-capturestream-test.html?preserve wrapper.html?green.png
== webgl-capturestream-test.html?preserve wrapper.html?green.png
# Some of the failure conditions are a little crazy. I'm (jgilbert) setting these based on
# failures encountered when running on Try, and then targetting the Try config by
# differences in the `sandbox` contents. That is, I'm labeling based on symptoms rather
# than cause.
# Lin-R-e10s: gtkWidget && browserIsRemote
# WinXP-R: winWidget && layersGPUAccelerated && !d2d
# Win7+-R: winWidget && layersGPUAccelerated && d2d
# Win7+-Ru: winWidget && !layersGPUAccelerated
# WinXP R: winWidget && layersGPUAccelerated && !d3d11
# Win7+ R: winWidget && layersGPUAccelerated && d3d11
# Win7+ Ru: winWidget && !layersGPUAccelerated && d3d11
# (Note that we have to remove spaces when used below)
# IMPORTANT: Expected outcomes are evaluated left-to-right, and they replace eachother.
@@ -42,73 +41,73 @@ skip-if(winWidget&&layersGPUAccelerated&&d2d) == webgl-capturestream-test.html?p
# Does we draw the correct colors in the correct places?
# Combinations: PowerSet([readback, aa, preserve, premult, alpha]) x [frame=1,frame=6]
# This is 2^6 = 64 combinations.
== webgl-color-test.html?frame=1&__&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
== webgl-color-test.html?frame=1&__&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&aa&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&__&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=1&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
== webgl-color-test.html?frame=1&__&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&aa&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&(!layersGPUAccelerated||!d3d11)) == webgl-color-test.html?frame=6&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
== webgl-color-test.html?frame=6&__&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&aa&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
== webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) == webgl-color-test.html?frame=6&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
== webgl-color-test.html?frame=6&__&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&aa&________&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
== webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&(!layersGPUAccelerated||!d3d11)) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
# Check for hanging bindings/state settings:
== webgl-hanging-fb-test.html?__&________ wrapper.html?green.png
@@ -153,10 +152,13 @@ skip-if(!winWidget) pref(webgl.disable-angle,true) == webgl-color-test.html?nat
== stroketext-shadow.html stroketext-shadow-ref.html
# focus rings
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(Android) skip-if(winWidget) fuzzy-if(gtkWidget,64,410) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
# Check that captureStream() displays in a local video element
skip-if(winWidget&&layersGPUAccelerated&&d2d) == capturestream.html wrapper.html?green.png
== capturestream.html wrapper.html?green.png
fuzzy-if(Android,3,40) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
fuzzy-if(azureSkia,16,2) fuzzy-if(Android,3,40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
# Canvas Filter Reftests
include filters/reftest.list
+2 -10
View File
@@ -14366,11 +14366,7 @@ ctx.lineTo(50, 25);
ctx.closePath();
ctx.stroke();
if (IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
</script>
@@ -14507,11 +14503,7 @@ ctx.stroke();
ctx.strokeRect(50, 25, 0, 0);
if (IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
</script>
+3 -3
View File
@@ -5,9 +5,9 @@
*/
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let imports = {};
var imports = {};
Cu.import("resource://gre/modules/ContactDB.jsm", imports);
Cu.import("resource://gre/modules/ContactService.jsm", imports);
@@ -28,7 +28,7 @@ Object.defineProperty(this, "Promise", {
value: imports.Promise, writable: false, configurable: false
});
let DEBUG = false;
var DEBUG = false;
function debug(str) {
if (DEBUG){
dump("-*- TestMigrationChromeScript: " + str + "\n");
+1 -1
View File
@@ -1,5 +1,5 @@
[DEFAULT]
skip-if = (buildapp == 'b2g' || buildapp == 'mulet')
skip-if = (buildapp == 'b2g' || os == 'android')
[test_app_permissions.html]
[test_fs_app_permissions.html]
-2
View File
@@ -1,5 +1,4 @@
[DEFAULT]
skip-if = (toolkit == 'android' && processor == 'x86') # Android: bug 781789 & bug 782275
support-files = devicestorage_common.js
remove_testing_directory.js
@@ -10,7 +9,6 @@ support-files = devicestorage_common.js
[test_available.html]
[test_basic.html]
[test_dirs.html]
skip-if = e10s # Bug 1063569.
# [test_diskSpace.html]
# Possible race between the time we write a file, and the
# time it takes to be reflected by statfs(). Bug # 791287
+1 -1
View File
@@ -161,7 +161,7 @@ function testNextRemove() {
ok(navigator.getDeviceStorage, "Should have getDeviceStorage.");
let gStorage = navigator.getDeviceStorage("pictures");
gStorage = navigator.getDeviceStorage("pictures");
ok(gStorage, "Should have gotten a storage.");
// Test "removeDeep" first.
+2 -2
View File
@@ -1,5 +1,5 @@
== bug863728-1.html bug863728-1-ref.html
== bug863728-2.html bug863728-2-ref.html
fuzzy-if(skiaContent,1,10) == bug863728-2.html bug863728-2-ref.html
== bug863728-3.html bug863728-3-ref.html
== bug945215-1.html bug945215-1-ref.html
== bug945215-2.html bug945215-2-ref.html
fuzzy-if(skiaContent,1,10) == bug945215-2.html bug945215-2-ref.html
+1 -1
View File
@@ -79,7 +79,7 @@ function assert_throws(ex, func) {
Components.stack.caller, false);
}
let tests = [];
var tests = [];
function test(func, msg) {
tests.push({msg: msg, func: func,
+7
View File
@@ -0,0 +1,7 @@
<html hidden>
<script>
function a(){document.getElementById('id1').click();}
window.onload = a;
</script>
<applet <ol onclick='' contenteditable='true' onended='' oncanplay=''>
<article id='id1'></article>
+1
View File
@@ -5,6 +5,7 @@ load 422009-1.xhtml
load 457776-1.html
load 496308-1.html
load 682637-1.html
load 938341.html
load 1033343.html
load 1035654-1.html
load 1035654-2.html
+1 -1
View File
@@ -1,7 +1,7 @@
SimpleTest.waitForExplicitFinish();
// The main testing function.
let test = function (isContent) {
var test = function (isContent) {
// Each definition is [eventType, prefSetting]
// Where we are setting the "privacy.resistFingerprinting" pref.
let eventDefs = [["mousedown", true],
+1 -1
View File
@@ -1,6 +1,6 @@
// This test is useful because mochitest-browser runs as an addon, so we test
// addon-scope paths here.
let ifr;
var ifr;
function test() {
ifr = document.createElement('iframe');
document.getElementById('main-window').appendChild(ifr);
+2 -2
View File
@@ -4,8 +4,8 @@
var testPath = "http://mochi.test:8888/browser/dom/html/test/";
var popup;
let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null);
let {Services} = Cu.import("resource://gre/modules/Services.jsm", null);
var {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null);
var {Services} = Cu.import("resource://gre/modules/Services.jsm", null);
function checkCache(url, inMemory, shouldExist, cb)
{
+1 -1
View File
@@ -1,4 +1,4 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.importGlobalProperties(["File"]);
addMessageListener("files.open", function (message) {
+3 -3
View File
@@ -3,10 +3,10 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
let testGenerator = testSteps();
var testGenerator = testSteps();
let testResult;
let testException;
var testResult;
var testException;
function testFinishedCallback(result, exception)
{
+3 -3
View File
@@ -2,9 +2,9 @@
* 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/. */
let gTestRoot = getRootDirectory(gTestPath);
let gBugWindow = null;
let gIterations = 5;
var gTestRoot = getRootDirectory(gTestPath);
var gBugWindow = null;
var gIterations = 5;
function onLoad() {
gBugWindow.close();
+2 -2
View File
@@ -3,9 +3,9 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const { 'classes': Cc, 'interfaces': Ci, 'utils': Cu } = Components;
var { 'classes': Cc, 'interfaces': Ci, 'utils': Cu } = Components;
let testGenerator = testSteps();
var testGenerator = testSteps();
if (!window.runTest) {
window.runTest = function()
+1 -1
View File
@@ -3,7 +3,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
let gActiveListeners = {};
var gActiveListeners = {};
function registerPopupEventHandler(eventName, callback) {
gActiveListeners[eventName] = function (event) {
+2 -3
View File
@@ -9,8 +9,7 @@
interface nsIPushErrorReporter : nsISupports
{
/**
* Ack status codes, reported when the Push service acknowledges an incoming
* message.
* Ack types, reported when the Push service acknowledges an incoming message.
*
* Acks are sent before the message is dispatched to the service worker,
* since the server delays new messages until all outstanding ones have been
@@ -39,7 +38,7 @@ interface nsIPushErrorReporter : nsISupports
/**
* Reports a `push` event handler error to the Push service. |messageId| is
* an opaque string passed to `nsIPushNotifier.notifyPush{WithData}`.
* |status| is a delivery error reason.
* |reason| is a delivery error reason.
*/
void reportDeliveryError(in DOMString messageId,
[optional] in uint16_t reason);
+62 -5
View File
@@ -5,23 +5,53 @@
#include "nsISupports.idl"
%{C++
#include "nsTArray.h"
#include "mozilla/Maybe.h"
#define PUSHNOTIFIER_CONTRACTID \
"@mozilla.org/push/Notifier;1"
// These constants are duplicated in `PushComponents.js`.
#define OBSERVER_TOPIC_PUSH "push-message"
#define OBSERVER_TOPIC_SUBSCRIPTION_CHANGE "push-subscription-change"
#define OBSERVER_TOPIC_SUBSCRIPTION_LOST "push-subscription-lost"
%}
interface nsIPrincipal;
[ref] native MaybeData(const mozilla::Maybe<nsTArray<uint8_t>>);
/**
* Fires service worker events for push messages sent to content subscriptions,
* and XPCOM observer notifications for system subscriptions.
* Fires XPCOM observer notifications and service worker events for
* messages sent to push subscriptions.
*/
[scriptable, builtinclass, uuid(b00dfdeb-14e5-425b-adc7-b531442e3216)]
interface nsIPushNotifier : nsISupports
{
/**
* Fires a `push-message` observer notification, and sends a `push` event to
* the service worker registered for the |scope|. |messageId| is an opaque ID
* used to report errors if the worker fails to handle the message.
*/
void notifyPush(in ACString scope, in nsIPrincipal principal,
in DOMString messageId);
/**
* Same as `notifyPush`, except the subject of the observer notification
* receives an `nsIPushMessage` instance containing the |data|. Service
* workers can access the |data| via the `PushMessageData` WebIDL interface.
*/
void notifyPushWithData(in ACString scope, in nsIPrincipal principal,
in DOMString messageId,
[optional] in uint32_t dataLen,
[array, size_is(dataLen)] in uint8_t data);
/**
* Fires a `push-subscription-change` observer notification, and sends a
* `pushsubscriptionchange` event to the service worker registered for the
* |scope|.
*/
void notifySubscriptionChange(in ACString scope, in nsIPrincipal principal);
/**
@@ -41,12 +71,39 @@ interface nsIPushNotifier : nsISupports
void notifyError(in ACString scope, in nsIPrincipal principal,
in DOMString message, in uint32_t flags);
/**
* Internal methods used to fire service worker events and observer
* notifications. These are not exposed to JavaScript.
*/
[noscript, nostdcall]
void notifyPushWorkers(in ACString scope,
in nsIPrincipal principal,
in DOMString messageId,
in MaybeData data);
[noscript, nostdcall]
void notifyPushObservers(in ACString scope, in MaybeData data);
[noscript, nostdcall]
void notifySubscriptionChangeWorkers(in ACString scope,
in nsIPrincipal principal);
[noscript, nostdcall]
void notifySubscriptionChangeObservers(in ACString scope);
[noscript, nostdcall]
void notifySubscriptionLostObservers(in ACString scope, in uint16_t reason);
[noscript, nostdcall, notxpcom]
void notifyErrorWorkers(in ACString scope, in DOMString message,
in uint32_t flags);
};
/**
* A push message sent to a system subscription, used as the subject of a
* `push-message` observer notification. System subscriptions are created by
* the system principal, and do not use worker events.
* A push message sent to a subscription, used as the subject of a
* `push-message` observer notification.
*
* This interface resembles the `PushMessageData` WebIDL interface.
*/
+1
View File
@@ -18,6 +18,7 @@ interface nsIPushSubscription : nsISupports
readonly attribute long long pushCount;
readonly attribute long long lastPush;
readonly attribute long quota;
readonly attribute bool isSystemSubscription;
bool quotaApplies();
bool isExpired();
+9 -17
View File
@@ -166,7 +166,7 @@
#endif
#ifndef MOZ_SIMPLEPUSH
#include "mozilla/dom/PushNotifier.h"
#include "nsIPushNotifier.h"
#endif
#include "mozilla/dom/File.h"
@@ -3196,13 +3196,11 @@ ContentChild::RecvPush(const nsCString& aScope,
const nsString& aMessageId)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifyPushObservers(aScope, Nothing());
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -3221,13 +3219,11 @@ ContentChild::RecvPushWithData(const nsCString& aScope,
InfallibleTArray<uint8_t>&& aData)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifyPushObservers(aScope, Some(aData));
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -3244,13 +3240,11 @@ ContentChild::RecvPushSubscriptionChange(const nsCString& aScope,
const IPC::Principal& aPrincipal)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifySubscriptionChangeObservers(aScope);
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -3266,13 +3260,11 @@ ContentChild::RecvPushError(const nsCString& aScope, const nsString& aMessage,
const uint32_t& aFlags)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
pushNotifier->NotifyErrorWorkers(aScope, aMessage, aFlags);
#endif
return true;
+9 -17
View File
@@ -260,7 +260,7 @@ using namespace mozilla::system;
#endif
#ifndef MOZ_SIMPLEPUSH
#include "mozilla/dom/PushNotifier.h"
#include "nsIPushNotifier.h"
#endif
#ifdef XP_WIN
@@ -5832,13 +5832,11 @@ ContentParent::RecvNotifyPushObservers(const nsCString& aScope,
const nsString& aMessageId)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifyPushObservers(aScope, Nothing());
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -5852,13 +5850,11 @@ ContentParent::RecvNotifyPushObserversWithData(const nsCString& aScope,
InfallibleTArray<uint8_t>&& aData)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifyPushObservers(aScope, Some(aData));
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -5870,13 +5866,11 @@ bool
ContentParent::RecvNotifyPushSubscriptionChangeObservers(const nsCString& aScope)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifySubscriptionChangeObservers(aScope);
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -5889,13 +5883,11 @@ ContentParent::RecvNotifyPushSubscriptionLostObservers(const nsCString& aScope,
const uint16_t& aReason)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
nsCOMPtr<nsIPushNotifier> pushNotifier =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
if (NS_WARN_IF(!pushNotifier)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifySubscriptionLostObservers(aScope, aReason);
Unused << NS_WARN_IF(NS_FAILED(rv));
@@ -35,10 +35,10 @@ ignoringDuplicateSrc = Ignoring duplicate source %1$S
# LOCALIZATION NOTE (ignoringSrcFromMetaCSP):
# %1$S defines the ignored src
ignoringSrcFromMetaCSP = Ignoring source '%1$S' (Not supported when delivered via meta element).
# LOCALIZATION NOTE (ignoringSrcWithinScriptSrc):
# LOCALIZATION NOTE (ignoringSrcWithinScriptStyleSrc):
# %1$S is the ignored src
# script-src is a directive name and should not be localized
ignoringSrcWithinScriptSrc = Ignoring "%1$S" within script-src: nonce-source or hash-source specified
# script-src and style-src are directive names and should not be localized
ignoringSrcWithinScriptStyleSrc = Ignoring "%1$S" within script-src or style-src: nonce-source or hash-source specified
# LOCALIZATION NOTE (reportURInotHttpsOrHttp2):
# %1$S is the ETLD of the report URI that is not HTTP or HTTPS
reportURInotHttpsOrHttp2 = The report URI (%1$S) should be an HTTP or HTTPS URI.
+3 -1
View File
@@ -1,5 +1,4 @@
[DEFAULT]
support-files =
common.js
resource.sjs
@@ -7,6 +6,7 @@ support-files =
[test_ImageObjectProcessor_sizes.html]
[test_ImageObjectProcessor_src.html]
[test_ImageObjectProcessor_type.html]
[test_ManifestProcessor_background_color.html]
[test_ManifestProcessor_dir.html]
[test_ManifestProcessor_display.html]
[test_ManifestProcessor_icons.html]
@@ -16,3 +16,5 @@ support-files =
[test_ManifestProcessor_orientation.html]
[test_ManifestProcessor_scope.html]
[test_ManifestProcessor_start_url.html]
[test_ManifestProcessor_theme_color.html]
[test_ManifestProcessor_warnings.html]
@@ -35,7 +35,7 @@ var noSrc = {
var expected = `Expect icons without a src prop to be filtered out.`;
data.jsonText = JSON.stringify(noSrc);
var result = processor.process(data);
ise(result.icons.length, 0, expected);
is(result.icons.length, 0, expected);
var invalidSrc = {
icons: [{
@@ -56,7 +56,7 @@ var invalidSrc = {
var expected = `Expect icons with invalid src prop to be filtered out.`;
data.jsonText = JSON.stringify(noSrc);
var result = processor.process(data);
ise(result.icons.length, 0, expected);
is(result.icons.length, 0, expected);
var expected = `Expect icon's src to be a string.`;
var withSrc = {
@@ -66,7 +66,7 @@ var withSrc = {
};
data.jsonText = JSON.stringify(withSrc);
var result = processor.process(data);
ise(typeof result.icons[0].src, "string", expected);
is(typeof result.icons[0].src, "string", expected);
var expected = `Expect only icons with a src prop to be kept.`;
var withSrc = {
@@ -80,12 +80,12 @@ var withSrc = {
};
data.jsonText = JSON.stringify(withSrc);
var result = processor.process(data);
ise(result.icons.length, 2, expected);
is(result.icons.length, 2, expected);
var expectedURL = new URL('pass', manifestURL);
for (var icon of result.icons) {
var expected = `Expect src prop to be ${expectedURL.toString()}`;
ise(icon.src.toString(), expectedURL.toString(), expected);
is(icon.src.toString(), expectedURL.toString(), expected);
}
//Resolve URLs relative to manfiest
@@ -100,7 +100,7 @@ URLs.forEach((url) => {
});
var absURL = new URL(url, manifestURL).toString();
var result = processor.process(data);
ise(result.icons[0].src.toString(), absURL, expected);
is(result.icons[0].src.toString(), absURL, expected);
});
</script>
</head>
@@ -35,7 +35,7 @@ invalidMimeTypes.forEach((invalidMime) => {
testIcon.icons[0].type = invalidMime;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].type, undefined, expected);
is(result.icons[0].type, undefined, expected);
});
var validTypes = [
@@ -51,7 +51,7 @@ validTypes.forEach((validMime) => {
testIcon.icons[0].type = validMime;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].type, 'image/jpeg', expected);
is(result.icons[0].type, 'image/jpeg', expected);
});
</script>
</head>
@@ -0,0 +1,94 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1195018
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1195018</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* background_color member
* https://w3c.github.io/manifest/#background_color-member
**/
'use strict';
typeTests.forEach(type => {
data.jsonText = JSON.stringify({
background_color: type
});
var result = processor.process(data);
is(result.background_color, undefined, `Expect non-string background_color to be undefined: ${typeof type}.`);
});
var validThemeColors = [
'maroon',
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(300,0,0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)',
];
validThemeColors.forEach(background_color => {
data.jsonText = JSON.stringify({
background_color: background_color
});
var result = processor.process(data);
is(result.background_color, background_color, `Expect background_color to be returned: ${background_color}.`);
});
var invalidThemeColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}',
]
invalidThemeColors.forEach(background_color => {
data.jsonText = JSON.stringify({
background_color: background_color
});
var result = processor.process(data);
is(result.background_color, undefined, `Expect background_color to be undefined: ${background_color}.`);
});
// Trim tests
validThemeColors.forEach(background_color => {
var expandedThemeColor = `${seperators}${lineTerminators}${background_color}${lineTerminators}${seperators}`;
data.jsonText = JSON.stringify({
background_color: expandedThemeColor
});
var result = processor.process(data);
is(result.background_color, background_color, `Expect trimmed background_color to be returned.`);
});
</script>
</head>
@@ -0,0 +1,94 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1195018
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1195018</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* theme_color member
* https://w3c.github.io/manifest/#theme_color-member
**/
'use strict';
typeTests.forEach(type => {
data.jsonText = JSON.stringify({
theme_color: type
});
var result = processor.process(data);
is(result.theme_color, undefined, `Expect non-string theme_color to be undefined: ${typeof type}.`);
});
var validThemeColors = [
'maroon',
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(300,0,0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)',
];
validThemeColors.forEach(theme_color => {
data.jsonText = JSON.stringify({
theme_color: theme_color
});
var result = processor.process(data);
is(result.theme_color, theme_color, `Expect theme_color to be returned: ${theme_color}.`);
});
var invalidThemeColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}',
]
invalidThemeColors.forEach(theme_color => {
data.jsonText = JSON.stringify({
theme_color: theme_color
});
var result = processor.process(data);
is(result.theme_color, undefined, `Expect theme_color to be undefined: ${theme_color}.`);
});
// Trim tests
validThemeColors.forEach(theme_color => {
var expandedThemeColor = `${seperators}${lineTerminators}${theme_color}${lineTerminators}${seperators}`;
data.jsonText = JSON.stringify({
theme_color: expandedThemeColor
});
var result = processor.process(data);
is(result.theme_color, theme_color, `Expect trimmed theme_color to be returned.`);
});
</script>
</head>
@@ -0,0 +1,90 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1086997
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1086997</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
'use strict';
const {
ConsoleAPI
} = SpecialPowers.Cu.import('resource://gre/modules/Console.jsm');
var warning = null;
var originalWarn = ConsoleAPI.prototype.warn;
ConsoleAPI.prototype.warn = function(aWarning) {
warning = aWarning;
};
[
{
func: () => data.jsonText = JSON.stringify(1),
warning: 'Manifest should be an object.',
},
{
func: () => data.jsonText = JSON.stringify(null),
warning: 'Manifest should be an object.',
},
{
func: () => data.jsonText = JSON.stringify('a string'),
warning: 'Manifest should be an object.',
},
{
func: () => data.jsonText = JSON.stringify({
scope: 'https://www.mozilla.org',
}),
warning: 'The scope URL must be same origin as document.',
},
{
func: () => data.jsonText = JSON.stringify({
scope: 'foo',
start_url: 'bar',
}),
warning: 'The start URL is outside the scope, so the scope is invalid.',
},
{
func: () => data.jsonText = JSON.stringify({
start_url: 'https://www.mozilla.org',
}),
warning: 'The start URL must be same origin as document.',
},
{
func: () => data.jsonText = JSON.stringify({
start_url: 42,
}),
warning: 'Expected the manifest\u2019s start_url member to be a string.',
},
{
func: () => data.jsonText = JSON.stringify({
theme_color: '42',
}),
warning: 'theme_color: 42 is not a valid CSS color.',
},
{
func: () => data.jsonText = JSON.stringify({
background_color: '42',
}),
warning: 'background_color: 42 is not a valid CSS color.',
},
].forEach(function(test) {
test.func();
processor.process(data);
is(warning, test.warning, 'Correct warning.');
warning = null;
data.manifestURL = manifestURL;
data.docURL = docURL;
});
ConsoleAPI.prototype.warn = originalWarn;
</script>
</head>
+14 -7
View File
@@ -303,14 +303,21 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
return;
}
mInfo.mAudio = *mAudio.mTrackDemuxer->GetInfo()->GetAsAudioInfo();
UniquePtr<TrackInfo> info(mAudio.mTrackDemuxer->GetInfo());
for (const MetadataTag& tag : info->mTags) {
tags->Put(tag.mKey, tag.mValue);
UniquePtr<TrackInfo> audioInfo = mAudio.mTrackDemuxer->GetInfo();
// We actively ignore audio tracks that we know we can't play.
audioActive = audioInfo && audioInfo->IsValid();
if (audioActive) {
mInfo.mAudio = *audioInfo->GetAsAudioInfo();
for (const MetadataTag& tag : audioInfo->mTags) {
tags->Put(tag.mKey, tag.mValue);
}
mAudio.mCallback = new DecoderCallback(this, TrackInfo::kAudioTrack);
mAudio.mTimeRanges = mAudio.mTrackDemuxer->GetBuffered();
mTrackDemuxersMayBlock |= mAudio.mTrackDemuxer->GetSamplesMayBlock();
} else {
mAudio.mTrackDemuxer->BreakCycles();
mAudio.mTrackDemuxer = nullptr;
}
mAudio.mCallback = new DecoderCallback(this, TrackInfo::kAudioTrack);
mAudio.mTimeRanges = mAudio.mTrackDemuxer->GetBuffered();
mTrackDemuxersMayBlock |= mAudio.mTrackDemuxer->GetSamplesMayBlock();
}
UniquePtr<EncryptionInfo> crypto = mDemuxer->GetCrypto();
+9 -4
View File
@@ -34,6 +34,9 @@ public:
nsCString mValue;
};
// Maximum channel number we can currently handle (7.1)
#define MAX_AUDIO_CHANNELS 8
class TrackInfo {
public:
enum TrackType {
@@ -331,7 +334,7 @@ public:
bool IsValid() const override
{
return mChannels > 0 && mRate > 0;
return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS && mRate > 0;
}
AudioInfo* GetAsAudioInfo() override
@@ -543,9 +546,6 @@ public:
const nsCString& mMimeType;
};
// Maximum channel number we can currently handle (7.1)
#define MAX_AUDIO_CHANNELS 8
class AudioConfig {
public:
enum Channel {
@@ -685,6 +685,11 @@ public:
return !(*this == aOther);
}
bool IsValid() const
{
return mChannelLayout.IsValid() && Format() != FORMAT_NONE && Rate() > 0;
}
static const char* FormatToString(SampleFormat aFormat);
static uint32_t SampleSize(SampleFormat aFormat);
static uint32_t FormatToBits(SampleFormat aFormat);
+3 -2
View File
@@ -72,10 +72,11 @@ public:
base::ProcessId otherProcess;
nsCString displayName;
uint32_t pluginId;
nsresult rv;
bool ok = aGMPServiceChild->SendLoadGMP(mNodeId, mAPI, mTags,
alreadyBridgedTo, &otherProcess,
&displayName, &pluginId);
if (!ok) {
&displayName, &pluginId, &rv);
if (!ok || rv == NS_ERROR_ILLEGAL_DURING_SHUTDOWN) {
mCallback->Done(nullptr);
return;
}
+15 -1
View File
@@ -685,6 +685,13 @@ GeckoMediaPluginServiceParent::NotifySyncShutdownComplete()
mWaitingForPluginsSyncShutdown = false;
}
bool
GeckoMediaPluginServiceParent::IsShuttingDown()
{
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
return mShuttingDownOnGMPThread;
}
void
GeckoMediaPluginServiceParent::UnloadPlugins()
{
@@ -1785,8 +1792,15 @@ GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
nsTArray<ProcessId>&& aAlreadyBridgedTo,
ProcessId* aId,
nsCString* aDisplayName,
uint32_t* aPluginId)
uint32_t* aPluginId,
nsresult* aRv)
{
*aRv = NS_OK;
if (mService->IsShuttingDown()) {
*aRv = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
return true;
}
RefPtr<GMPParent> gmp = mService->SelectPluginForAPI(aNodeId, aAPI, aTags);
nsCString api = aTags[0];
+5 -1
View File
@@ -59,6 +59,9 @@ public:
RefPtr<GenericPromise> EnsureInitialized();
RefPtr<GenericPromise> AsyncAddPluginDirectory(const nsAString& aDirectory);
// GMP thread access only
bool IsShuttingDown();
private:
friend class GMPServiceParent;
@@ -221,7 +224,8 @@ public:
nsTArray<ProcessId>&& aAlreadyBridgedTo,
base::ProcessId* aID,
nsCString* aDisplayName,
uint32_t* aPluginId) override;
uint32_t* aPluginId,
nsresult* aRv) override;
bool RecvGetGMPNodeId(const nsString& aOrigin,
const nsString& aTopLevelOrigin,
const nsString& aGMPName,
-2
View File
@@ -14,8 +14,6 @@
#include "GMPCallbackBase.h"
#include "GMPUtils.h"
class nsCString;
class GMPVideoDecoderCallbackProxy : public GMPCallbackBase,
public GMPVideoDecoderCallback
{
+2 -1
View File
@@ -17,7 +17,8 @@ sync protocol PGMPService
parent:
sync LoadGMP(nsCString nodeId, nsCString api, nsCString[] tags,
ProcessId[] alreadyBridgedTo)
returns (ProcessId id, nsCString displayName, uint32_t pluginId);
returns (ProcessId id, nsCString displayName, uint32_t pluginId,
nsresult aResult);
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin,
nsString gmpName,
bool inPrivateBrowsing)
+8
View File
@@ -0,0 +1,8 @@
#include <stdint.h>
extern "C" uint8_t* test_rust();
TEST(rust, CallFromCpp) {
auto greeting = test_rust();
EXPECT_STREQ(reinterpret_cast<char*>(greeting), "hello from rust.");
}
+6
View File
@@ -0,0 +1,6 @@
#[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()
}
+5
View File
@@ -29,6 +29,11 @@ if CONFIG['MOZ_WEBM_ENCODER']:
'TestWebMWriter.cpp',
]
if CONFIG['MOZ_RUST']:
SOURCES += ['hello.rs',]
UNIFIED_SOURCES += ['TestRust.cpp',]
TEST_HARNESS_FILES.gtest += [
'../test/gizmo-frag.mp4',
'../test/gizmo.mp4',
+12 -2
View File
@@ -283,7 +283,7 @@ MediaSourceDecoder::NextFrameBufferedStatus()
TimeInterval interval(currentPosition,
currentPosition + media::TimeUnit::FromMicroseconds(DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED),
MediaSourceDemuxer::EOS_FUZZ);
return GetBuffered().Contains(interval)
return GetBuffered().Contains(ClampIntervalToEnd(interval))
? MediaDecoderOwner::NEXT_FRAME_AVAILABLE
: MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
}
@@ -313,7 +313,17 @@ MediaSourceDecoder::CanPlayThrough()
TimeInterval interval(currentPosition,
timeAhead,
MediaSourceDemuxer::EOS_FUZZ);
return GetBuffered().Contains(interval);
return GetBuffered().Contains(ClampIntervalToEnd(interval));
}
TimeInterval
MediaSourceDecoder::ClampIntervalToEnd(const TimeInterval& aInterval)
{
if (!mEnded) {
return aInterval;
}
TimeInterval interval(TimeUnit(), TimeUnit::FromSeconds(GetDuration()));
return aInterval.Intersection(interval);
}
#undef MSE_DEBUG
@@ -83,6 +83,7 @@ public:
private:
void DoSetMediaSourceDuration(double aDuration);
media::TimeInterval ClampIntervalToEnd(const media::TimeInterval& aInterval);
// The owning MediaSource holds a strong reference to this decoder, and
// calls Attach/DetachMediaSource on this decoder to set and clear
-2
View File
@@ -14,5 +14,3 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul-gtest'
FAIL_ON_WARNINGS = True
+3
View File
@@ -38,4 +38,7 @@ TEST_DIRS += [
'gtest',
]
if CONFIG['MOZ_GONK_MEDIACODEC']:
DEFINES['MOZ_GONK_MEDIACODEC'] = True
FINAL_LIBRARY = 'xul'
@@ -0,0 +1 @@
Cache-Control: no-store
@@ -0,0 +1 @@
Cache-Control: no-store
@@ -0,0 +1 @@
Cache-Control: no-store
+16 -3
View File
@@ -54,8 +54,8 @@ function range(start, end) {
function once(target, name, cb) {
var p = new Promise(function(resolve, reject) {
target.addEventListener(name, function() {
target.removeEventListener(name, arguments.callee);
target.addEventListener(name, function onceEvent() {
target.removeEventListener(name, onceEvent);
resolve();
});
});
@@ -115,4 +115,17 @@ SimpleTest.registerTimeoutFunction(function() {
for (var a of document.getElementsByTagName("audio")) {
a.mozDumpDebugInfo();
}
});
});
function waitUntilTime(target, targetTime) {
return new Promise(function(resolve, reject) {
target.addEventListener("waiting", function onwaiting() {
info("Got a waiting event at " + target.currentTime);
if (target.currentTime >= targetTime) {
ok(true, "Reached target time of: " + targetTime);
target.removeEventListener("waiting", onwaiting);
resolve();
}
});
});
}
+60 -41
View File
@@ -1,5 +1,6 @@
[DEFAULT]
skip-if = e10s || buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
skip-if = buildapp == 'b2g' # b2g( ReferenceError: MediaSource is not defined)
subsuite = media
support-files =
mediasource.js
seek.webm seek.webm^headers^
@@ -19,89 +20,107 @@ support-files =
bipbop/bipbop11.m4s bipbop/bipbop_audio11.m4s bipbop/bipbop_video11.m4s
bipbop/bipbop12.m4s bipbop/bipbop_video12.m4s
bipbop/bipbop13.m4s bipbop/bipbop_video13.m4s
bipbop/bipbopinit.mp4^headers^ bipbop/bipbop_audioinit.mp4^headers^ bipbop/bipbop_videoinit.mp4^headers^
bipbop/bipbop1.m4s^headers^ bipbop/bipbop_audio1.m4s^headers^ bipbop/bipbop_video1.m4s^headers^
bipbop/bipbop2.m4s^headers^ bipbop/bipbop_audio2.m4s^headers^ bipbop/bipbop_video2.m4s^headers^
bipbop/bipbop3.m4s^headers^ bipbop/bipbop_audio3.m4s^headers^ bipbop/bipbop_video3.m4s^headers^
bipbop/bipbop4.m4s^headers^ bipbop/bipbop_audio4.m4s^headers^ bipbop/bipbop_video4.m4s^headers^
bipbop/bipbop5.m4s^headers^ bipbop/bipbop_audio5.m4s^headers^ bipbop/bipbop_video5.m4s^headers^
bipbop/bipbop6.m4s^headers^ bipbop/bipbop_audio6.m4s^headers^ bipbop/bipbop_video6.m4s^headers^
bipbop/bipbop7.m4s^headers^ bipbop/bipbop_audio7.m4s^headers^ bipbop/bipbop_video7.m4s^headers^
bipbop/bipbop8.m4s^headers^ bipbop/bipbop_audio8.m4s^headers^ bipbop/bipbop_video8.m4s^headers^
bipbop/bipbop9.m4s^headers^ bipbop/bipbop_audio9.m4s^headers^ bipbop/bipbop_video9.m4s^headers^
bipbop/bipbop10.m4s^headers^ bipbop/bipbop_audio10.m4s^headers^ bipbop/bipbop_video10.m4s^headers^
bipbop/bipbop11.m4s^headers^ bipbop/bipbop_audio11.m4s^headers^ bipbop/bipbop_video11.m4s^headers^
bipbop/bipbop12.m4s^headers^ bipbop/bipbop_video12.m4s^headers^
bipbop/bipbop13.m4s^headers^ bipbop/bipbop_video13.m4s^headers^
aac20-48000-64000-init.mp4 aac20-48000-64000-init.mp4^headers^
aac20-48000-64000-1.m4s aac20-48000-64000-1.m4s^headers^
aac20-48000-64000-2.m4s aac20-48000-64000-2.m4s^headers^
aac51-48000-128000-init.mp4 aac51-48000-128000-init.mp4^headers^
aac51-48000-128000-1.m4s aac51-48000-128000-1.m4s^headers^
aac51-48000-128000-2.m4s aac51-48000-128000-2.m4s^headers^
bipbop/bipbop_480_624kbps-videoinit.mp4 bipbop/bipbop_480_624kbps-videoinit.mp4^headers^
bipbop/bipbop_480_624kbps-video1.m4s bipbop/bipbop_480_624kbps-video1.m4s^headers^
bipbop/bipbop_480_624kbps-video2.m4s bipbop/bipbop_480_624kbps-video2.m4s^headers^
[test_AudioChange_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_BufferedSeek.html]
skip-if = true # bug 1182946
[test_BufferedSeek_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_BufferingWait.html]
skip-if = true # bug 1182946
skip-if = toolkit == 'android' #timeout android bug 1199531
[test_BufferingWait_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_DrainOnMissingData_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_EndOfStream.html]
skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
[test_EndOfStream_mp4.html]
skip-if = (toolkit == 'android' || buildapp == 'mulet') || ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android' || buildapp == 'mulet')) # Not supported on xp and android 2.3
[test_DurationUpdated.html]
skip-if = true # bug 1182946
[test_DurationUpdated_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_FrameSelection.html]
skip-if = true # bug 1182946
[test_FrameSelection_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_HaveMetadataUnbufferedSeek.html]
skip-if = true # bug 1182946
[test_HaveMetadataUnbufferedSeek_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_LoadedDataFired_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
[test_LiveSeekable.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_LoadedMetadataFired.html]
skip-if = true # bug 1182946
[test_LoadedMetadataFired_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_MediaSource.html]
skip-if = true # bug 1182946
[test_MediaSource_memory_reporting.html]
[test_MediaSource_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_MediaSource_disabled.html]
[test_OnEvents.html]
[test_MultipleInitSegments.html]
[test_MultipleInitSegments_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_PlayEvents.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_ResumeAfterClearing_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekableAfterEndOfStream.html]
skip-if = true # bug 1182946
[test_SeekableAfterEndOfStream_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekableAfterEndOfStreamSplit.html]
skip-if = true # bug 1182946
[test_SeekableAfterEndOfStreamSplit_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekableBeforeEndOfStream.html]
skip-if = true # bug 1182946
[test_SeekableBeforeEndOfStream_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekableBeforeEndOfStreamSplit.html]
skip-if = true # bug 1182946
[test_SeekableBeforeEndOfStreamSplit_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekNoData_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekedEvent_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SeekTwice_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_Sequence_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SetModeThrows.html]
skip-if = true # bug 1182946
[test_SplitAppendDelay.html]
skip-if = true # bug 1182946
[test_SplitAppendDelay_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_SplitAppend.html]
skip-if = true # bug 1182946
[test_SplitAppend_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_TimestampOffset_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_TruncatedDuration.html]
skip-if = true # bug 1182946
[test_TruncatedDuration_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_WaitingOnMissingData.html]
skip-if = true # Disabled due to bug 1124493 and friends. WebM MSE is deprioritized.
[test_WaitingOnMissingData_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
[test_WaitingToEndedTransition_mp4.html]
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
@@ -0,0 +1,72 @@
<!DOCTYPE HTML>
<html>
<head>
<title>MSE: basic functionality</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test checks loading a stereo segment, followed by a 5.1 segment plays without error.
runWithMSE(function(ms, el) {
el.controls = true;
once(ms, 'sourceopen').then(function() {
// Log events for debugging.
var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
"loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
"waiting", "pause", "durationchange", "seeking", "seeked"];
function logEvent(e) {
var v = e.target;
info("got " + e.type + " event");
}
events.forEach(function(e) {
el.addEventListener(e, logEvent, false);
});
ok(true, "Receive a sourceopen event");
var audiosb = ms.addSourceBuffer("audio/mp4");
el.addEventListener("error", function(e) {
ok(false, "should not fire '" + e.type + "' event");
SimpleTest.finish();
});
is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
fetchAndLoad(audiosb, 'aac20-48000-64000-', ['init'], '.mp4')
.then(once.bind(null, el, 'loadedmetadata'))
.then(function() {
ok(true, "got loadedmetadata event");
var promises = [];
promises.push(once(el, 'loadeddata'));
promises.push(once(el, 'canplay'));
promises.push(fetchAndLoad(audiosb, 'aac20-48000-64000-', ['1'], '.m4s'));
return Promise.all(promises);
})
.then(function() {
ok(true, "got canplay event");
el.play();
return fetchAndLoad(audiosb, 'aac51-48000-128000-', ['init'], '.mp4');
})
.then(fetchAndLoad.bind(null, audiosb, 'aac51-48000-128000-', ['2'], '.m4s'))
.then(function() {
var promises = [];
ms.endOfStream();
promises.push(once(el, 'ended'));
promises.push(once(audiosb, 'updateend'));
return Promise.all(promises);
})
.then(function() {
ok(el.currentTime >= 6, "played to the end");
SimpleTest.finish();
})
});
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<title>MSE: Don't get stuck buffering for too long when we have frames to show</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// This test loads partial video, plays and waits until playback stalls.
// It then loads only 3 frames of a video at higher resolution.
var receivedSourceOpen = false;
runWithMSE(function(ms, v) {
ms.addEventListener("sourceopen", function() {
ok(true, "Receive a sourceopen event");
ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
receivedSourceOpen = true;
var sb = ms.addSourceBuffer("video/mp4");
ok(sb, "Create a SourceBuffer");
// Log events for debugging.
var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
"loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
"waiting", "pause", "durationchange", "seeking", "seeked"];
function logEvent(e) {
var v = e.target;
info("got " + e.type + " event");
}
events.forEach(function(e) {
v.addEventListener(e, logEvent, false);
});
sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
.then(function() {
var promises = [];
promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
promises.push(once(v, "loadeddata"));
return Promise.all(promises);
}).then(function() {
is(sb.buffered.length, 1, "continuous range");
v.play();
// We have nothing to play, waiting will be fired.
return waitUntilTime(v, 1.5);
}).then(function() {
return fetchAndLoad(sb, 'bipbop/bipbop_480_624kbps-video', ['init'], '.mp4');
}).then(function() {
sb.timestampOffset = 1.601666; // End of the video track buffered - time of first video sample (0.095).
sb.appendWindowEnd = 1.796677; // Only allow room for three extra video frames (we need 3 as this video has b-frames).
return fetchAndLoad(sb, 'bipbop/bipbop_480_624kbps-video', ['1'], '.m4s');
}).then(function() {
ms.endOfStream();
var promises = [];
promises.push(once(ms, "sourceended"));
promises.push(once(v, "playing"));
promises.push(once(v, "ended"));
return Promise.all(promises);
}).then(function() {
if(v.width, 640, "has proper width");
if(v.height, 480, "has proper height");
SimpleTest.finish();
});
});
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<title>MSE: Append buffer with multiple init segments</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
runWithMSE(function (ms, v) {
ms.addEventListener("sourceopen", function () {
var sb = ms.addSourceBuffer("video/webm");
fetchWithXHR("seek_lowres.webm", function (seek_lowres) {
fetchWithXHR("seek.webm", function (seek) {
var data = [
[seek_lowres, 0, 438], // lowres init segment
[seek_lowres, 438, 25950], // lowres media segment 0-1
[seek, 0, 318], // init segment
[seek, 46712, 67833] // media segment 0.8-1.201
];
var length = data.map(d => d[2] - d[1]).reduce((a, b) => a + b);
var arrayBuffer = new Uint8Array(length);
var pos = 0;
data.forEach(function(d) {
var buffer = new Uint8Array(d[0], d[1], d[2]-d[1]);
arrayBuffer.set(buffer, pos);
pos += buffer.byteLength;
});
loadSegment.bind(null, sb, arrayBuffer)().then(function() {
// Since we are passing multiple segments in one buffer,
// the first durationchange event from parsing the init
// segment will be fired before updateend.
v.addEventListener("durationchange", function () {
ok(v.duration, 1.201);
SimpleTest.finish();
});
ms.endOfStream();
});
});
});
});
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<title>MSE: Append buffer with multiple init segments</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
runWithMSE(function (ms, v) {
ms.addEventListener("sourceopen", function () {
var sb = ms.addSourceBuffer("video/mp4");
fetchWithXHR("bipbop/bipbop_videoinit.mp4", function (init) {
init = new Uint8Array(init);
fetchWithXHR("bipbop/bipbop_video1.m4s", function (segment1) {
segment1 = new Uint8Array(segment1);
fetchWithXHR("bipbop/bipbop_video2.m4s", function (segment2) {
segment2 = new Uint8Array(segment2);
var data = [init, segment1, init, segment2];
var length = data.map(d => d.byteLength).reduce((a, b) => a + b);
var arrayBuffer = new Uint8Array(length);
var pos = 0;
data.forEach(function(buffer) {
arrayBuffer.set(buffer, pos);
pos += buffer.byteLength;
});
loadSegment.bind(null, sb, arrayBuffer)().then(function() {
// Since we are passing multiple segments in one buffer,
// the first durationchange event from parsing the init
// segment will be fired before updateend.
v.addEventListener("durationchange", function () {
ok(v.duration, 1.601666);
SimpleTest.finish();
});
ms.endOfStream();
});
});
});
});
});
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<title>MSE: Don't get stuck buffering for too long when we have frames to show</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var receivedSourceOpen = false;
runWithMSE(function(ms, v) {
ms.addEventListener("sourceopen", function() {
ok(true, "Receive a sourceopen event");
ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
receivedSourceOpen = true;
var sb = ms.addSourceBuffer("video/mp4");
ok(sb, "Create a SourceBuffer");
sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
.then(function() {
var promises = [];
promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
promises.push(once(v, "loadeddata"));
return Promise.all(promises);
}).then(function() {
// clear the entire sourcebuffer.
sb.remove(0, 5);
return once(sb, "updateend");
}).then(function() {
v.play();
// We have nothing to play, waiting will be fired.
return once(v, "waiting");
}).then(function() {
var promises = [];
promises.push(once(v, "playing"));
promises.push(fetchAndLoad(sb, 'bipbop/bipbop', range(1,3), '.m4s'));
return Promise.all(promises);
}).then(function() {
ms.endOfStream();
var promises = [];
promises.push(once(ms, "sourceended"));
promises.push(once(v, "ended"));
return Promise.all(promises);
}).then(SimpleTest.finish.bind(SimpleTest));
});
});
</script>
</pre>
</body>
</html>
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<title>MSE: Don't get stuck buffering for too long when we have frames to show</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mediasource.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test"><script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var receivedSourceOpen = false;
runWithMSE(function(ms, v) {
ms.addEventListener("sourceopen", function() {
ok(true, "Receive a sourceopen event");
ok(!receivedSourceOpen, "Should only receive one sourceopen for this test");
receivedSourceOpen = true;
var sb = ms.addSourceBuffer("video/mp4");
ok(sb, "Create a SourceBuffer");
sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
sb.mode = 'sequence';
fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
.then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['2'], '.m4s'))
.then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['5'], '.m4s'))
.then(function() {
is(v.buffered.length, 1, "Continuous buffered range");
is(v.buffered.start(0), 0, "Buffered range starts at 0");
ok(sb.timestampOffset < 0, "SourceBuffer.timestampOffset set to allow continuous range");
SimpleTest.finish();
});
});
});
</script>
</pre>
</body>
</html>
+2 -4
View File
@@ -346,7 +346,7 @@ status_t AudioOffloadPlayer::DoSeek()
CHECK(mAudioSink.get());
AUDIO_OFFLOAD_LOG(LogLevel::Debug,
"DoSeek ( %lld )", mSeekTarget.GetTime().ToMicroseconds());
("DoSeek ( %lld )", mSeekTarget.GetTime().ToMicroseconds()));
mReachedEOS = false;
mPositionTimeMediaUs = -1;
@@ -502,7 +502,6 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
while (sizeRemaining > 0) {
MediaSource::ReadOptions options;
bool refreshSeekTime = false;
{
android::Mutex::Autolock autoLock(mLock);
@@ -519,7 +518,6 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
}
if (!mInputBuffer) {
status_t err;
err = mSource->read(&mInputBuffer, &options);
@@ -573,7 +571,7 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
AUDIO_OFFLOAD_LOG(LogLevel::Debug, ("seek is updated during unlocking mLock"));
}
if (refreshSeekTime) {
if (refreshSeekTime) {
NotifyPositionChanged();
// need to adjust the mStartPosUs for offload decoding since parser
+11 -23
View File
@@ -90,10 +90,10 @@ MediaCodecProxy::MediaCodecProxy(sp<ALooper> aLooper,
: mCodecLooper(aLooper)
, mCodecMime(aMime)
, mCodecEncoder(aEncoder)
, mMediaCodecLock("MediaCodecProxy::mMediaCodecLock")
, mPendingRequestMediaResource(false)
, mPromiseMonitor("MediaCodecProxy::mPromiseMonitor")
{
MOZ_ASSERT(mCodecLooper != nullptr, "ALooper should not be nullptr.");
mCodecPromise.SetMonitor(&mPromiseMonitor);
}
MediaCodecProxy::~MediaCodecProxy()
@@ -134,6 +134,7 @@ MediaCodecProxy::AsyncAllocateVideoMediaCodec()
mResourceClient->SetListener(this);
mResourceClient->Acquire();
mozilla::MonitorAutoLock lock(mPromiseMonitor);
RefPtr<CodecPromise> p = mCodecPromise.Ensure(__func__);
return p.forget();
}
@@ -141,23 +142,16 @@ MediaCodecProxy::AsyncAllocateVideoMediaCodec()
void
MediaCodecProxy::ReleaseMediaCodec()
{
mCodecPromise.RejectIfExists(true, __func__);
releaseCodec();
if (!mResourceClient) {
return;
}
mozilla::MonitorAutoLock mon(mMediaCodecLock);
if (mPendingRequestMediaResource) {
mPendingRequestMediaResource = false;
mon.NotifyAll();
}
// At first, release mResourceClient's resource to prevent a conflict with
// mResourceClient's callback.
if (mResourceClient) {
mResourceClient->ReleaseResource();
mResourceClient = nullptr;
}
mozilla::MonitorAutoLock lock(mPromiseMonitor);
mCodecPromise.RejectIfExists(true, __func__);
releaseCodec();
}
bool
@@ -473,18 +467,12 @@ void
MediaCodecProxy::ResourceReserved()
{
MCP_LOG("resourceReserved");
mozilla::MonitorAutoLock lock(mPromiseMonitor);
// Create MediaCodec
if (!allocateCodec()) {
ReleaseMediaCodec();
mCodecPromise.RejectIfExists(true, __func__);
return;
}
// Notify initialization waiting.
mozilla::MonitorAutoLock mon(mMediaCodecLock);
mPendingRequestMediaResource = false;
mon.NotifyAll();
mCodecPromise.ResolveIfExists(true, __func__);
}
@@ -492,7 +480,7 @@ MediaCodecProxy::ResourceReserved()
void
MediaCodecProxy::ResourceReserveFailed()
{
ReleaseMediaCodec();
mozilla::MonitorAutoLock lock(mPromiseMonitor);
mCodecPromise.RejectIfExists(true, __func__);
}
+2 -3
View File
@@ -163,6 +163,8 @@ private:
bool mCodecEncoder;
mozilla::MozPromiseHolder<CodecPromise> mCodecPromise;
// When mPromiseMonitor is held, mResourceClient's functions should not be called.
mozilla::Monitor mPromiseMonitor;
// Media Resource Management
RefPtr<mozilla::MediaSystemResourceClient> mResourceClient;
@@ -174,9 +176,6 @@ private:
//MediaCodec buffers to hold input/output data.
Vector<sp<ABuffer> > mInputBuffers;
Vector<sp<ABuffer> > mOutputBuffers;
mozilla::Monitor mMediaCodecLock;
bool mPendingRequestMediaResource;
};
} // namespace android
+2 -9
View File
@@ -107,7 +107,6 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
DisableStateMachineAudioOffloading();
return;
}
PauseStateMachine();
if (mLogicallySeeking) {
SeekTarget target = SeekTarget(mLogicalPosition,
@@ -128,13 +127,7 @@ MediaOmxCommonDecoder::PauseStateMachine()
MOZ_ASSERT(NS_IsMainThread());
DECODER_LOG(LogLevel::Debug, ("%s", __PRETTY_FUNCTION__));
if (mShuttingDown) {
return;
}
if (!GetStateMachine()) {
return;
}
MOZ_ASSERT(GetStateMachine());
// enter dormant state
GetStateMachine()->DispatchSetDormant(true);
}
@@ -232,7 +225,7 @@ MediaOmxCommonDecoder::ChangeState(PlayState aState)
}
void
MediaOmxCommonDecoder::CallSeek(SeekTarget aTarget)
MediaOmxCommonDecoder::CallSeek(const SeekTarget& aTarget)
{
if (!mAudioOffloadPlayer) {
MediaDecoder::CallSeek(aTarget);
+1 -1
View File
@@ -26,7 +26,7 @@ public:
void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoderEventVisibility aEventVisibility) override;
void ChangeState(PlayState aState) override;
void CallSeek(SeekTarget aTarget) override;
void CallSeek(const SeekTarget& aTarget) override;
void SetVolume(double aVolume) override;
int64_t CurrentPosition() override;
MediaDecoderOwner::NextFrameStatus NextFrameStatus() override;
+5 -8
View File
@@ -266,8 +266,7 @@ void MediaOmxReader::HandleResourceAllocated()
if (mLastParserDuration >= 0) {
// Prefer the parser duration if we have it.
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->SetMediaDuration(mLastParserDuration);
mInfo.mMetadataDuration = Some(TimeUnit::FromMicroseconds(mLastParserDuration));
} else {
// MP3 parser failed to find a duration.
// Set the total duration (the max of the audio and video track).
@@ -381,9 +380,8 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
picture.height = (frame.Y.mHeight * mPicture.height) / mInitialFrame.height;
}
MOZ_ASSERT(mStreamSource);
// This is the approximate byte position in the stream.
int64_t pos = mStreamSource->Tell();
int64_t pos = mStreamSource ? mStreamSource->Tell() : 0;
RefPtr<VideoData> v;
if (!frame.mGraphicBuffer) {
@@ -496,9 +494,8 @@ bool MediaOmxReader::DecodeAudioData()
MOZ_ASSERT(OnTaskQueue());
EnsureActive();
MOZ_ASSERT(mStreamSource);
// This is the approximate byte position in the stream.
int64_t pos = mStreamSource->Tell();
int64_t pos = mStreamSource ? mStreamSource->Tell() : 0;
// Read next frame
MPAPI::AudioFrame source;
@@ -542,7 +539,7 @@ MediaOmxReader::Seek(SeekTarget aTarget, int64_t aEndTime)
// 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.mTime;
mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
RefPtr<MediaOmxReader> self = this;
mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
@@ -555,7 +552,7 @@ MediaOmxReader::Seek(SeekTarget aTarget, int64_t aEndTime)
self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
}));
} else {
mAudioSeekTimeUs = mVideoSeekTimeUs = GetTime().ToMicroseconds();
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
mSeekPromise.Resolve(aTarget.GetTime(), __func__);
}
+7 -5
View File
@@ -64,6 +64,13 @@ OMXCodecProxy::OMXCodecProxy(
OMXCodecProxy::~OMXCodecProxy()
{
// At first, release mResourceClient's resource to prevent a conflict with
// mResourceClient's callback.
if (mResourceClient) {
mResourceClient->ReleaseResource();
mResourceClient = nullptr;
}
mState = ResourceState::END;
mCodecPromise.RejectIfExists(true, __func__);
@@ -78,11 +85,6 @@ OMXCodecProxy::~OMXCodecProxy()
// Complete all pending Binder ipc transactions
IPCThreadState::self()->flushCommands();
if (mResourceClient) {
mResourceClient->ReleaseResource();
mResourceClient = nullptr;
}
mSource.clear();
free(mComponentName);
mComponentName = nullptr;
+75 -3
View File
@@ -17,7 +17,10 @@
#include "AudioChannelFormat.h"
#include "GrallocImages.h"
#include "LayersLogging.h"
#include "libyuv.h"
#include "mozilla/Monitor.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/GrallocTextureClient.h"
using namespace mozilla;
@@ -407,6 +410,67 @@ ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
graphicBuffer->unlock();
}
static nsresult
ConvertSourceSurfaceToNV12(const RefPtr<SourceSurface>& aSurface, uint8_t* aDestination)
{
uint32_t width = aSurface->GetSize().width;
uint32_t height = aSurface->GetSize().height;
uint8_t* y = aDestination;
int yStride = width;
uint8_t* uv = y + (yStride * height);
int uvStride = width / 2;
SurfaceFormat format = aSurface->GetFormat();
if (!aSurface) {
CODEC_ERROR("Getting surface %s from image failed", Stringify(format).c_str());
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
if (!data) {
CODEC_ERROR("Getting data surface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(aSurface->GetType()).c_str(),
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
if (!map.IsMapped()) {
CODEC_ERROR("Reading DataSourceSurface from %s image with %s (%s) surface failed",
Stringify(format).c_str(), Stringify(aSurface->GetType()).c_str(),
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
int rv;
switch (aSurface->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
rv = libyuv::ARGBToNV12(static_cast<uint8*>(map.GetData()),
map.GetStride(),
y, yStride,
uv, uvStride,
width, height);
break;
default:
CODEC_ERROR("Unsupported SourceSurface format %s",
Stringify(aSurface->GetFormat()).c_str());
NS_ASSERTION(false, "Unsupported SourceSurface format");
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {
CODEC_ERROR("%s to I420 conversion failed",
Stringify(aSurface->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
int64_t aTimestamp, int aInputFlags, bool* aSendEOS)
@@ -437,9 +501,10 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
halFormat == GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS,
NS_ERROR_INVALID_ARG);
} else {
// TODO: support RGB to YUV color conversion.
NS_ERROR("Unsupported input image type.");
return NS_ERROR_INVALID_ARG;
RefPtr<SourceSurface> surface = img->GetAsSourceSurface();
NS_ENSURE_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8A8 ||
surface->GetFormat() == SurfaceFormat::B8G8R8X8,
NS_ERROR_INVALID_ARG);
}
}
@@ -477,6 +542,13 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
} else if (format == ImageFormat::PLANAR_YCBCR) {
ConvertPlanarYCbCrToNV12(static_cast<PlanarYCbCrImage*>(img)->GetData(),
dst);
} else {
RefPtr<SourceSurface> surface = img->GetAsSourceSurface();
nsresult rv = ConvertSourceSurfaceToNV12(surface, dst);
if (rv != NS_OK) {
return NS_ERROR_FAILURE;
}
}
}
-1
View File
@@ -283,7 +283,6 @@ private:
*/
class OMXVideoEncoder final : public OMXCodecWrapper
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OMXVideoEncoder)
public:
// Types of output blob format.
enum BlobFormat {
+9 -3
View File
@@ -19,6 +19,12 @@
#include <ui/Fence.h>
#endif
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <gui/Surface.h>
#else
#include <gui/SurfaceTextureClient.h>
#endif
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/Preferences.h"
@@ -230,11 +236,11 @@ OmxDecoder::AllocateMediaResources()
#endif
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
mNativeWindowClient = new GonkNativeWindowClient(producer);
mNativeWindowClient = new Surface(producer);
#elif defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
mNativeWindowClient = new GonkNativeWindowClient(mNativeWindow->getBufferQueue());
mNativeWindowClient = new Surface(mNativeWindow->getBufferQueue());
#else
mNativeWindowClient = new GonkNativeWindowClient(mNativeWindow);
mNativeWindowClient = new SurfaceTextureClient(mNativeWindow);
#endif
// Experience with OMX codecs is that only the HW decoders are
+2 -2
View File
@@ -6,7 +6,6 @@
#include <stagefright/MediaExtractor.h>
#include "GonkNativeWindow.h"
#include "GonkNativeWindowClient.h"
#include "mozilla/layers/FenceUtils.h"
#include "MP3FrameParser.h"
#include "MPAPI.h"
@@ -42,7 +41,8 @@ class OmxDecoder : public RefBase {
AbstractMediaDecoder *mDecoder;
sp<GonkNativeWindow> mNativeWindow;
sp<GonkNativeWindowClient> mNativeWindowClient;
sp<ANativeWindow> mNativeWindowClient;
sp<MediaSource> mVideoTrack;
sp<OMXCodecProxy> mVideoSource;
sp<MediaSource> mAudioOffloadTrack;
-56
View File
@@ -1,56 +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 "RtspMediaCodecDecoder.h"
#include "MediaDecoderStateMachine.h"
#include "RtspMediaResource.h"
#include "RtspMediaCodecReader.h"
namespace mozilla {
MediaDecoder*
RtspMediaCodecDecoder::Clone(MediaDecoderOwner* aOwner)
{
return new RtspMediaCodecDecoder(aOwner);
}
MediaOmxCommonReader*
RtspMediaCodecDecoder::CreateReader()
{
return new RtspMediaCodecReader(this);
}
MediaDecoderStateMachine*
RtspMediaCodecDecoder::CreateStateMachineFromReader(MediaOmxCommonReader* aReader)
{
return new MediaDecoderStateMachine(this, aReader,
mResource->IsRealTime());
}
void
RtspMediaCodecDecoder::ChangeState(PlayState aState)
{
MOZ_ASSERT(NS_IsMainThread());
MediaDecoder::ChangeState(aState);
// Notify RTSP controller if the play state is ended.
// This is necessary for RTSP controller to transit its own state.
if (mPlayState == PLAY_STATE_ENDED) {
RefPtr<RtspMediaResource> resource = mResource->GetRtspPointer();
if (resource) {
nsIStreamingProtocolController* controller =
resource->GetMediaStreamController();
if (controller) {
controller->PlaybackEnded();
}
}
}
}
} // namespace mozilla
-31
View File
@@ -1,31 +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(RtspMediaCodecDecoder_h_)
#define RtspMediaCodecDecoder_h_
#include "MediaOmxCommonDecoder.h"
namespace mozilla {
class RtspMediaCodecDecoder final : public MediaOmxCommonDecoder
{
public:
explicit RtspMediaCodecDecoder(MediaDecoderOwner* aOwner)
: MediaOmxCommonDecoder(aOwner) {}
MediaDecoder* Clone(MediaDecoderOwner* aOwner) override;
MediaOmxCommonReader* CreateReader() override;
MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) override;
void ChangeState(PlayState aState) override;
};
} // namespace mozilla
#endif
+3 -1
View File
@@ -41,6 +41,7 @@ if CONFIG['MOZ_OMX_ENCODER']:
'OMXCodecDescriptorUtil.cpp',
'OMXCodecWrapper.cpp',
]
LOCAL_INCLUDES += ['/media/libyuv/include']
if 'rtsp' in CONFIG['NECKO_PROTOCOLS']:
EXPORTS += [
@@ -70,10 +71,11 @@ include('/ipc/chromium/chromium-config.mozbuild')
# - about attributes on forward declarations for types that are already
# defined, which complains about an important MOZ_EXPORT for android::AString
# - about multi-character constants which are used in codec-related code
# and are part of Android's libstagefright API style.
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
CXXFLAGS += [
'-Wno-error=attributes',
'-Wno-error=multichar'
'-Wno-multichar'
]
FINAL_LIBRARY = 'xul'
+4 -4
View File
@@ -103,10 +103,10 @@ OpusDataDecoder::DecodeHeader(const unsigned char* aData, size_t aLength)
return NS_ERROR_FAILURE;
}
int channels = mOpusParser->mChannels;
// No channel mapping for more than 8 channels.
if (channels > 8) {
OPUS_DEBUG("No channel mapping for more than 8 channels. Source is %d channels",
channels);
AudioConfig::ChannelLayout layout(channels);
if (!layout.IsValid()) {
OPUS_DEBUG("Invalid channel mapping. Source is %d channels", channels);
return NS_ERROR_FAILURE;
}
@@ -105,6 +105,11 @@ VorbisDataDecoder::Init()
("Invalid Vorbis header: container and codec channels do not match!"));
}
AudioConfig::ChannelLayout layout(mVorbisDsp.vi->channels);
if (!layout.IsValid()) {
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
return InitPromise::CreateAndResolve(TrackInfo::kAudioTrack, __func__);
}
@@ -223,6 +228,9 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
AudioConfig in(AudioConfig::ChannelLayout(channels, VorbisLayout(channels)),
rate);
AudioConfig out(channels, rate);
if (!in.IsValid() || !out.IsValid()) {
return -1;
}
mAudioConverter = MakeUnique<AudioConverter>(in, out);
}
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
@@ -4,12 +4,8 @@
#include "AndroidDecoderModule.h"
#include "AndroidBridge.h"
#include "GLBlitHelper.h"
#include "GLContext.h"
#include "GLContextEGL.h"
#include "GLContextProvider.h"
#include "AndroidSurfaceTexture.h"
#include "GLImages.h"
#include "GLLibraryEGL.h"
#include "MediaData.h"
#include "MediaInfo.h"
@@ -121,7 +117,6 @@ public:
void Cleanup() override
{
mGLContext = nullptr;
}
nsresult Input(MediaRawData* aSample) override
@@ -129,79 +124,13 @@ public:
return MediaCodecDataDecoder::Input(aSample);
}
bool WantCopy() const
{
// Allocating a texture is incredibly slow on PowerVR and may fail on
// emulators, see bug 1190379.
return mGLContext->Vendor() != GLVendor::Imagination &&
mGLContext->Renderer() != GLRenderer::AndroidEmulator;
}
EGLImage CopySurface(layers::Image* img)
{
mGLContext->MakeCurrent();
GLuint tex = CreateTextureForOffscreen(mGLContext, mGLContext->GetGLFormats(),
img->GetSize());
auto helper = mGLContext->BlitHelper();
const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
if (!helper->BlitImageToTexture(img, img->GetSize(), tex,
LOCAL_GL_TEXTURE_2D, destOrigin))
{
mGLContext->fDeleteTextures(1, &tex);
return nullptr;
}
EGLint attribs[] = {
LOCAL_EGL_IMAGE_PRESERVED_KHR, LOCAL_EGL_TRUE,
LOCAL_EGL_NONE, LOCAL_EGL_NONE
};
EGLContext eglContext = static_cast<GLContextEGL*>(mGLContext.get())->GetEGLContext();
EGLImage eglImage = sEGLLibrary.fCreateImage(
EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D_KHR,
reinterpret_cast<EGLClientBuffer>(tex), attribs);
mGLContext->fDeleteTextures(1, &tex);
return eglImage;
}
nsresult PostOutput(BufferInfo::Param aInfo, MediaFormat::Param aFormat,
const TimeUnit& aDuration) override
{
if (!EnsureGLContext()) {
return NS_ERROR_FAILURE;
}
RefPtr<layers::Image> img =
new SurfaceTextureImage(mSurfaceTexture.get(), mConfig.mDisplay,
gl::OriginPos::BottomLeft);
if (WantCopy()) {
EGLImage eglImage = CopySurface(img);
if (!eglImage) {
return NS_ERROR_FAILURE;
}
EGLSync eglSync = nullptr;
if (sEGLLibrary.IsExtensionSupported(GLLibraryEGL::KHR_fence_sync) &&
mGLContext->IsExtensionSupported(GLContext::OES_EGL_sync))
{
MOZ_ASSERT(mGLContext->IsCurrent());
eglSync = sEGLLibrary.fCreateSync(EGL_DISPLAY(),
LOCAL_EGL_SYNC_FENCE,
nullptr);
MOZ_ASSERT(eglSync);
mGLContext->fFlush();
} else {
NS_WARNING("No EGL fence support detected, rendering artifacts may occur!");
}
img = new layers::EGLImageImage(eglImage, eglSync, mConfig.mDisplay,
gl::OriginPos::TopLeft, true /* owns */);
}
nsresult rv;
int32_t flags;
NS_ENSURE_SUCCESS(rv = aInfo->Flags(&flags), rv);
@@ -231,20 +160,9 @@ public:
}
protected:
bool EnsureGLContext()
{
if (mGLContext) {
return true;
}
mGLContext = GLContextProvider::CreateHeadless(CreateContextFlags::NONE);
return mGLContext;
}
layers::ImageContainer* mImageContainer;
const VideoInfo& mConfig;
RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
RefPtr<GLContext> mGLContext;
};
class AudioDataDecoder : public MediaCodecDataDecoder
@@ -283,6 +201,10 @@ public:
int32_t numChannels;
NS_ENSURE_SUCCESS(rv =
aFormat->GetInteger(NS_LITERAL_STRING("channel-count"), &numChannels), rv);
AudioConfig::ChannelLayout layout(numChannels);
if (!layout.IsValid()) {
return NS_ERROR_FAILURE;
}
int32_t sampleRate;
NS_ENSURE_SUCCESS(rv =
@@ -391,9 +313,12 @@ AndroidDecoderModule::CreateAudioDecoder(
MediaFormat::LocalRef format;
LOG("CreateAudioFormat with mimeType=%s, mRate=%d, channels=%d",
aConfig.mMimeType.Data(), aConfig.mRate, aConfig.mChannels);
NS_ENSURE_SUCCESS(MediaFormat::CreateAudioFormat(
aConfig.mMimeType,
aConfig.mBitDepth,
aConfig.mRate,
aConfig.mChannels,
&format), nullptr);
@@ -464,10 +389,11 @@ MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
NS_ENSURE_SUCCESS(rv = ResetOutputBuffers(), rv);
NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread),
NS_NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop));
rv = NS_NewNamedThread(
"MC Decoder", getter_AddRefs(mThread),
NS_NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop));
return NS_OK;
return rv;
}
// This is in usec, so that's 10ms.
@@ -522,7 +448,7 @@ MediaCodecDataDecoder::WaitForInput()
}
MediaRawData*
already_AddRefed<MediaRawData>
MediaCodecDataDecoder::PeekNextSample()
{
MonitorAutoLock lock(mMonitor);
@@ -543,7 +469,7 @@ MediaCodecDataDecoder::PeekNextSample()
}
// We're not stopping or flushing, so try to get a sample.
return mQueue.front();
return RefPtr<MediaRawData>(mQueue.front()).forget();
}
nsresult
@@ -584,7 +510,7 @@ MediaCodecDataDecoder::QueueSample(const MediaRawData* aSample)
return res;
}
mDurations.push(TimeUnit::FromMicroseconds(aSample->mDuration));
mDurations.push_back(TimeUnit::FromMicroseconds(aSample->mDuration));
return NS_OK;
}
@@ -629,7 +555,7 @@ MediaCodecDataDecoder::GetOutputDuration()
{
MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued");
const TimeUnit duration = mDurations.front();
mDurations.pop();
mDurations.pop_front();
return duration;
}
@@ -661,12 +587,11 @@ MediaCodecDataDecoder::DecoderLoop()
{
bool isOutputDone = false;
AutoLocalJNIFrame frame(jni::GetEnvForThread(), 1);
RefPtr<MediaRawData> sample;
MediaFormat::LocalRef outputFormat(frame.GetEnv());
nsresult res = NS_OK;
while (WaitForInput()) {
sample = PeekNextSample();
RefPtr<MediaRawData> sample = PeekNextSample();
{
MonitorAutoLock lock(mMonitor);
@@ -682,7 +607,8 @@ MediaCodecDataDecoder::DecoderLoop()
if (NS_SUCCEEDED(res)) {
// We've fed this into the decoder, so remove it from the queue.
MonitorAutoLock lock(mMonitor);
mQueue.pop();
MOZ_RELEASE_ASSERT(mQueue.size(), "Queue may not be empty");
mQueue.pop_front();
isOutputDone = false;
}
}
@@ -757,18 +683,27 @@ MediaCodecDataDecoder::State() const
return mState;
}
void
bool
MediaCodecDataDecoder::State(ModuleState aState)
{
LOG("%s -> %s", ModuleStateStr(mState), ModuleStateStr(aState));
bool ok = true;
if (aState == kDrainDecoder) {
MOZ_ASSERT(mState == kDrainQueue);
if (mState == kShutdown) {
ok = false;
} else if (mState == kStopping) {
ok = aState == kShutdown;
} else if (aState == kDrainDecoder) {
ok = mState == kDrainQueue;
} else if (aState == kDrainWaitEOS) {
MOZ_ASSERT(mState == kDrainDecoder);
ok = mState == kDrainDecoder;
}
mState = aState;
if (ok) {
LOG("%s -> %s", ModuleStateStr(mState), ModuleStateStr(aState));
mState = aState;
}
return ok;
}
void
@@ -776,19 +711,15 @@ MediaCodecDataDecoder::ClearQueue()
{
mMonitor.AssertCurrentThreadOwns();
while (!mQueue.empty()) {
mQueue.pop();
}
while (!mDurations.empty()) {
mDurations.pop();
}
mQueue.clear();
mDurations.clear();
}
nsresult
MediaCodecDataDecoder::Input(MediaRawData* aSample)
{
MonitorAutoLock lock(mMonitor);
mQueue.push(aSample);
mQueue.push_back(aSample);
lock.NotifyAll();
return NS_OK;
@@ -810,7 +741,9 @@ nsresult
MediaCodecDataDecoder::Flush()
{
MonitorAutoLock lock(mMonitor);
State(kFlushing);
if (!State(kFlushing)) {
return NS_OK;
}
lock.Notify();
while (State() == kFlushing) {
@@ -840,23 +773,23 @@ MediaCodecDataDecoder::Shutdown()
{
MonitorAutoLock lock(mMonitor);
if (!mThread || State() == kStopping) {
// Already shutdown or in the process of doing so
return NS_OK;
}
State(kStopping);
lock.Notify();
while (State() == kStopping) {
while (mThread && State() != kShutdown) {
lock.Wait();
}
mThread->Shutdown();
mThread = nullptr;
if (mThread) {
mThread->Shutdown();
mThread = nullptr;
}
mDecoder->Stop();
mDecoder->Release();
if (mDecoder) {
mDecoder->Stop();
mDecoder->Release();
mDecoder = nullptr;
}
return NS_OK;
}
@@ -6,17 +6,17 @@
#define AndroidDecoderModule_h_
#include "PlatformDecoderModule.h"
#include "AndroidSurfaceTexture.h"
#include "MediaCodec.h"
#include "SurfaceTexture.h"
#include "TimeUnits.h"
#include "mozilla/Monitor.h"
#include <queue>
#include <deque>
namespace mozilla {
typedef std::queue<RefPtr<MediaRawData>> SampleQueue;
typedef std::deque<RefPtr<MediaRawData>> SampleQueue;
class AndroidDecoderModule : public PlatformDecoderModule {
public:
@@ -101,7 +101,7 @@ protected:
nsresult GetInputBuffer(JNIEnv* env, int index, jni::Object::LocalRef* buffer);
bool WaitForInput();
MediaRawData* PeekNextSample();
already_AddRefed<MediaRawData> PeekNextSample();
nsresult QueueSample(const MediaRawData* aSample);
nsresult QueueEOS();
void HandleEOS(int32_t aOutputStatus);
@@ -110,7 +110,8 @@ protected:
widget::sdk::MediaFormat::Param aFormat,
int32_t aStatus);
ModuleState State() const;
void State(ModuleState aState);
// Sets decoder state and returns whether the new state has become effective.
bool State(ModuleState aState);
void DecoderLoop();
virtual void ClearQueue();
@@ -136,7 +137,7 @@ protected:
SampleQueue mQueue;
// Durations are stored in microseconds.
std::queue<media::TimeUnit> mDurations;
std::deque<media::TimeUnit> mDurations;
};
} // namespace mozilla
@@ -283,6 +283,9 @@ AppleATDecoder::DecodeSample(MediaRawData* aSample)
if (mChannelLayout && !mAudioConverter) {
AudioConfig in(*mChannelLayout.get(), rate);
AudioConfig out(channels, rate);
if (!in.IsValid() || !out.IsValid()) {
return NS_ERROR_FAILURE;
}
mAudioConverter = MakeUnique<AudioConverter>(in, out);
}
if (mAudioConverter) {
@@ -185,6 +185,12 @@ FFmpegAudioDecoder<LIBAV_VER>::DecodePacket(MediaRawData* aSample)
if (decoded) {
uint32_t numChannels = mCodecContext->channels;
AudioConfig::ChannelLayout layout(numChannels);
if (!layout.IsValid()) {
mCallback->Error();
return;
}
uint32_t samplingRate = mCodecContext->sample_rate;
AlignedAudioBuffer audio =
@@ -197,6 +197,10 @@ GonkAudioDecoderManager::Output(int64_t aStreamOffset,
}
// Update AudioInfo
AudioConfig::ChannelLayout layout(codec_channel_count);
if (!layout.IsValid()) {
return NS_ERROR_FAILURE;
}
mAudioChannels = codec_channel_count;
mAudioRate = codec_sample_rate;
@@ -244,13 +248,22 @@ GonkAudioDecoderManager::Output(int64_t aStreamOffset,
return NS_ERROR_NOT_AVAILABLE;
}
nsresult
GonkAudioDecoderManager::Flush()
void
GonkAudioDecoderManager::ProcessFlush()
{
GADM_LOG("FLUSH<<<");
mAudioQueue.Reset();
GADM_LOG(">>>FLUSH");
return GonkDecoderManager::Flush();
GonkDecoderManager::ProcessFlush();
}
void
GonkAudioDecoderManager::ResetEOS()
{
GADM_LOG("ResetEOS(<<<");
mAudioQueue.Reset();
GADM_LOG(">>>ResetEOS(");
GonkDecoderManager::ResetEOS();
}
} // namespace mozilla
@@ -31,7 +31,8 @@ public:
nsresult Output(int64_t aStreamOffset,
RefPtr<MediaData>& aOutput) override;
virtual nsresult Flush() override;
void ProcessFlush() override;
virtual void ResetEOS() override;
const char* GetDescriptionName() const override
{
@@ -56,7 +56,7 @@ PlatformDecoderModule::ConversionRequired
GonkDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
{
if (aConfig.IsVideo()) {
return kNeedAVCC;
return kNeedAnnexB;
} else {
return kNeedNone;
}
@@ -68,10 +68,12 @@ GonkDecoderModule::SupportsMimeType(const nsACString& aMimeType,
{
return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/3gpp") ||
aMimeType.EqualsLiteral("audio/amr-wb") ||
aMimeType.EqualsLiteral("audio/mpeg") ||
aMimeType.EqualsLiteral("video/mp4") ||
aMimeType.EqualsLiteral("video/mp4v-es") ||
aMimeType.EqualsLiteral("video/avc");
aMimeType.EqualsLiteral("video/avc") ||
aMimeType.EqualsLiteral("video/3gpp");
}
} // namespace mozilla
@@ -27,12 +27,6 @@ using namespace android;
namespace mozilla {
GonkDecoderManager::GonkDecoderManager(MediaTaskQueue* aTaskQueue)
: mMonitor("GonkDecoderManager")
, mTaskQueue(aTaskQueue)
{
}
bool
GonkDecoderManager::InitLoopers(MediaData::Type aType)
{
@@ -92,15 +86,15 @@ GonkDecoderManager::ProcessQueuedSamples()
status_t rv;
while (mQueuedSamples.Length()) {
RefPtr<MediaRawData> data = mQueuedSamples.ElementAt(0);
{
rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->Data()),
data->Size(),
data->mTime,
0,
INPUT_TIMEOUT_US);
}
rv = mDecoder->Input(reinterpret_cast<const uint8_t*>(data->Data()),
data->Size(),
data->mTime,
0,
INPUT_TIMEOUT_US);
if (rv == OK) {
mQueuedSamples.RemoveElementAt(0);
mWaitOutput.AppendElement(WaitOutputInfo(data->mOffset, data->mTime,
/* eos */ data->Data() == nullptr));
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
// buffer on time.
@@ -119,13 +113,16 @@ GonkDecoderManager::Flush()
GMDD_LOG("Decoder is not initialized");
return NS_ERROR_UNEXPECTED;
}
if (!mInitPromise.IsEmpty()) {
return NS_OK;
}
{
MutexAutoLock lock(mMutex);
mQueuedSamples.Clear();
}
mLastTime = 0;
MonitorAutoLock lock(mFlushMonitor);
mIsFlushing = true;
sp<AMessage> flush = new AMessage(kNotifyProcessFlush, id());
@@ -136,56 +133,6 @@ GonkDecoderManager::Flush()
return NS_OK;
}
nsresult
GonkDecoderManager::Input(MediaRawData* aSample)
{
ReentrantMonitorAutoEnter mon(mMonitor);
nsRefPtr<MediaRawData> sample;
if (!aSample) {
// It means EOS with empty sample.
sample = new MediaRawData();
} else {
sample = aSample;
if (!PerformFormatSpecificProcess(sample)) {
return NS_ERROR_FAILURE;
}
}
mQueueSample.AppendElement(sample);
status_t rv;
while (mQueueSample.Length()) {
nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
{
ReentrantMonitorAutoExit mon_exit(mMonitor);
rv = SendSampleToOMX(data);
}
if (rv == OK) {
mQueueSample.RemoveElementAt(0);
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
// buffer on time.
return NS_OK;
} else {
return NS_ERROR_UNEXPECTED;
}
}
return NS_OK;
}
nsresult
GonkMediaDataDecoder::Init()
{
sp<MediaCodecProxy> decoder;
decoder = mManager->Init(mCallback);
mDecoder = decoder;
mDrainComplete = false;
return NS_OK;
}
nsresult
GonkDecoderManager::Shutdown()
{
@@ -200,8 +147,8 @@ GonkDecoderManager::Shutdown()
return NS_OK;
}
bool
GonkDecoderManager::HasQueuedSample()
size_t
GonkDecoderManager::NumQueuedSamples()
{
MutexAutoLock lock(mMutex);
return mQueuedSamples.Length();
@@ -224,6 +171,8 @@ GonkDecoderManager::ProcessInput(bool aEndOfStream)
mToDo->setInt32("input-eos", 1);
}
mDecoder->requestActivityNotification(mToDo);
} else if (aEndOfStream) {
mToDo->setInt32("input-eos", 1);
}
} else {
GMDD_LOG("input processed: error#%d", rv);
@@ -276,35 +225,30 @@ GonkDecoderManager::ProcessToDo(bool aEndOfStream)
MOZ_ASSERT(mToDo.get() != nullptr);
mToDo.clear();
if (HasQueuedSample()) {
status_t pendingInput = ProcessQueuedSamples();
if (pendingInput < 0) {
mDecodeCallback->Error();
return;
}
if (!aEndOfStream && pendingInput <= MIN_QUEUED_SAMPLES) {
mDecodeCallback->InputExhausted();
}
if (NumQueuedSamples() > 0 && ProcessQueuedSamples() < 0) {
mDecodeCallback->Error();
return;
}
nsresult rv = NS_OK;
while (mWaitOutput.Length() > 0) {
nsRefPtr<MediaData> output;
int64_t offset = mWaitOutput.ElementAt(0);
rv = Output(offset, output);
RefPtr<MediaData> output;
WaitOutputInfo wait = mWaitOutput.ElementAt(0);
nsresult rv = Output(wait.mOffset, output);
if (rv == NS_OK) {
mWaitOutput.RemoveElementAt(0);
MOZ_ASSERT(output);
mDecodeCallback->Output(output);
UpdateWaitingList(output->mTime);
} else if (rv == NS_ERROR_ABORT) {
GMDD_LOG("eos output");
mWaitOutput.RemoveElementAt(0);
MOZ_ASSERT(mQueuedSamples.IsEmpty());
MOZ_ASSERT(mWaitOutput.IsEmpty());
// EOS
MOZ_ASSERT(mQueuedSamples.IsEmpty());
if (output) {
mDecodeCallback->Output(output);
UpdateWaitingList(output->mTime);
}
MOZ_ASSERT(mWaitOutput.Length() == 1);
mWaitOutput.RemoveElementAt(0);
mDecodeCallback->DrainComplete();
ResetEOS();
return;
} else if (rv == NS_ERROR_NOT_AVAILABLE) {
break;
@@ -314,12 +258,33 @@ GonkDecoderManager::ProcessToDo(bool aEndOfStream)
}
}
if (HasQueuedSample() || mWaitOutput.Length() > 0) {
if (!aEndOfStream && NumQueuedSamples() <= MIN_QUEUED_SAMPLES) {
mDecodeCallback->InputExhausted();
// No need to shedule todo task this time because InputExhausted() will
// cause Input() to be invoked and do it for us.
return;
}
if (NumQueuedSamples() || mWaitOutput.Length() > 0) {
mToDo = new AMessage(kNotifyDecoderActivity, id());
if (aEndOfStream) {
mToDo->setInt32("input-eos", 1);
}
mDecoder->requestActivityNotification(mToDo);
}
}
void
GonkDecoderManager::ResetEOS()
{
// After eos, android::MediaCodec needs to be flushed to receive next input
mWaitOutput.Clear();
if (mDecoder->flush() != OK) {
GMDD_LOG("flush error");
mDecodeCallback->Error();
}
}
void
GonkDecoderManager::onMessageReceived(const sp<AMessage> &aMessage)
{
@@ -368,8 +333,7 @@ GonkDecoderManager::OnTaskLooper()
GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
: mTaskQueue(aTaskQueue)
, mManager(aManager)
: mManager(aManager)
{
MOZ_COUNT_CTOR(GonkMediaDataDecoder);
mManager->SetDecodeCallback(aCallback);
@@ -408,11 +372,6 @@ GonkMediaDataDecoder::Input(MediaRawData* aSample)
nsresult
GonkMediaDataDecoder::Flush()
{
// Flush the input task queue. This cancels all pending Decode() calls.
// Note this blocks until the task queue finishes its current job, if
// it's executing at all. Note the MP4Reader ignores all output while
// flushing.
mTaskQueue->Flush();
return mManager->Flush();
}
@@ -40,8 +40,8 @@ public:
// Shutdown decoder and rejects the init promise.
virtual nsresult Shutdown();
// True if sample is queued.
bool HasQueuedSample();
// How many samples are waiting for processing.
size_t NumQueuedSamples();
// Set callback for decoder events, such as requesting more input,
// returning output, or reporting error.
@@ -53,7 +53,7 @@ public:
protected:
GonkDecoderManager()
: mMutex("GonkDecoderManager")
, mLastTime(0)
, mLastTime(INT64_MIN)
, mFlushMonitor("GonkDecoderManager::Flush")
, mIsFlushing(false)
, mDecodeCallback(nullptr)
@@ -75,8 +75,9 @@ protected:
int32_t ProcessQueuedSamples();
void ProcessInput(bool aEndOfStream);
void ProcessFlush();
virtual void ProcessFlush();
void ProcessToDo(bool aEndOfStream);
virtual void ResetEOS();
RefPtr<MediaByteBuffer> mCodecSpecificData;
@@ -122,8 +123,19 @@ protected:
// forbidden by mDecoder.
android::sp<android::AMessage> mToDo;
// Stores the offset of every output that needs to be read from mDecoder.
nsTArray<int64_t> mWaitOutput;
// Stores sample info for output buffer processing later.
struct WaitOutputInfo {
WaitOutputInfo(int64_t aOffset, int64_t aTimestamp, bool aEOS)
: mOffset(aOffset)
, mTimestamp(aTimestamp)
, mEOS(aEOS)
{}
const int64_t mOffset;
const int64_t mTimestamp;
const bool mEOS;
};
nsTArray<WaitOutputInfo> mWaitOutput;
MediaDataDecoderCallback* mDecodeCallback; // Reports decoder output or error.
@@ -195,7 +207,6 @@ public:
}
private:
RefPtr<FlushableTaskQueue> mTaskQueue;
android::sp<GonkDecoderManager> mManager;
};
@@ -49,16 +49,6 @@ public:
nsresult Shutdown() override;
// Bug 1199809: workaround to avoid sending the graphic buffer by making a
// copy of output buffer after calling flush(). Bug 1203859 was created to
// reimplementing Gonk PDM on top of OpenMax IL directly. Its buffer
// management will work better with Gecko and solve problems like this.
nsresult Flush() override
{
mNeedsCopyBuffer = true;
return GonkDecoderManager::Flush();
}
const char* GetDescriptionName() const override
{
return "gonk video decoder";
@@ -66,6 +56,17 @@ public:
static void RecycleCallback(TextureClient* aClient, void* aClosure);
protected:
// Bug 1199809: workaround to avoid sending the graphic buffer by making a
// copy of output buffer after calling flush(). Bug 1203859 was created to
// reimplementing Gonk PDM on top of OpenMax IL directly. Its buffer
// management will work better with Gecko and solve problems like this.
void ProcessFlush() override
{
mNeedsCopyBuffer = true;
GonkDecoderManager::ProcessFlush();
}
private:
struct FrameInfo
{
@@ -195,6 +195,11 @@ WMFAudioMFTManager::UpdateOutputType()
hr = type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &mAudioChannels);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
AudioConfig::ChannelLayout layout(mAudioChannels);
if (!layout.IsValid()) {
return E_FAIL;
}
return S_OK;
}
@@ -186,7 +186,7 @@ WMFMediaDataDecoder::Drain()
MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessDrain);
NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessDrain);
mTaskQueue->Dispatch(runnable.forget());
return NS_OK;
}
@@ -235,7 +235,8 @@ bool
WMFVideoMFTManager::InitInternal(bool aForceD3D9)
{
mUseHwAccel = false; // default value; changed if D3D setup succeeds.
bool useDxva = InitializeDXVA(aForceD3D9);
bool useDxva = InitializeDXVA(aForceD3D9 ||
mStreamType == VP8 || mStreamType == VP9);
RefPtr<MFTDecoder> decoder(new MFTDecoder());
@@ -50,11 +50,12 @@ DecoderFuzzingWrapper::Input(MediaRawData* aData)
nsresult
DecoderFuzzingWrapper::Flush()
{
DFW_LOGV("");
DFW_LOGV("Calling mDecoder[%p]->Flush()", mDecoder.get());
MOZ_ASSERT(mDecoder);
// Flush may output some frames (though unlikely).
// Flush may block a bit, it's ok if we output some frames in the meantime.
nsresult result = mDecoder->Flush();
DFW_LOGV("mDecoder[%p]->Flush() -> result=%u", mDecoder.get(), uint32_t(result));
// Clear any delayed output we may have.
mCallbackWrapper->ClearDelayedOutput();
return result;
@@ -254,13 +255,28 @@ void
DecoderCallbackFuzzingWrapper::ScheduleOutputDelayedFrame()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mDelayedOutputRequest.Exists()) {
// A delayed output is already scheduled, no need for more than one timer.
return;
}
RefPtr<DecoderCallbackFuzzingWrapper> self = this;
mDelayedOutputTimer->WaitUntil(
mPreviousOutput + mFrameOutputMinimumInterval,
__func__)
->Then(mTaskQueue, __func__,
[self] () -> void { self->OutputDelayedFrame(); },
[self] () -> void { self->OutputDelayedFrame(); });
mDelayedOutputRequest.Begin(
mDelayedOutputTimer->WaitUntil(
mPreviousOutput + mFrameOutputMinimumInterval,
__func__)
->Then(mTaskQueue, __func__,
[self] () -> void {
if (self->mDelayedOutputRequest.Exists()) {
self->mDelayedOutputRequest.Complete();
self->OutputDelayedFrame();
}
},
[self] () -> void {
if (self->mDelayedOutputRequest.Exists()) {
self->mDelayedOutputRequest.Complete();
self->ClearDelayedOutput();
}
}));
}
void
@@ -300,11 +316,16 @@ void
DecoderCallbackFuzzingWrapper::ClearDelayedOutput()
{
if (!mTaskQueue->IsCurrentThreadIn()) {
DFW_LOGV("(dispatching self)");
nsCOMPtr<nsIRunnable> task =
NS_NewRunnableMethod(this, &DecoderCallbackFuzzingWrapper::ClearDelayedOutput);
mTaskQueue->Dispatch(task.forget());
return;
}
DFW_LOGV("");
// In case a timer hasn't lapsed yet, before destroying the timer and its
// attached waitUntil() promise, the 'Then' request must be disconnected.
mDelayedOutputRequest.DisconnectIfExists();
mDelayedOutputTimer = nullptr;
mDelayedOutput.clear();
}
@@ -312,10 +333,16 @@ DecoderCallbackFuzzingWrapper::ClearDelayedOutput()
void
DecoderCallbackFuzzingWrapper::Shutdown()
{
DFW_LOGV("Shutting down mTaskQueue");
CFW_LOGV("Clear delayed output (if any) before shutting down mTaskQueue");
ClearDelayedOutput();
// Await idle here, so that 'ClearDelayedOutput' runs to completion before
// the task queue is shutdown (and tasks can't be queued anymore).
mTaskQueue->AwaitIdle();
CFW_LOGV("Shutting down mTaskQueue");
mTaskQueue->BeginShutdown();
mTaskQueue->AwaitIdle();
DFW_LOGV("mTaskQueue shut down");
CFW_LOGV("mTaskQueue shut down");
}
} // namespace mozilla
@@ -81,6 +81,7 @@ private:
typedef Pair<RefPtr<MediaData>, bool> MediaDataAndInputExhausted;
std::deque<MediaDataAndInputExhausted> mDelayedOutput;
RefPtr<MediaTimer> mDelayedOutputTimer;
MozPromiseRequestHolder<MediaTimerPromise> mDelayedOutputRequest;
// If draining, a 'DrainComplete' will be sent after all delayed frames have
// been output.
bool mDraining;

Some files were not shown because too many files have changed in this diff Show More