mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
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:
@@ -34,6 +34,7 @@ ostream
|
||||
set
|
||||
stack
|
||||
string
|
||||
type_traits
|
||||
utility
|
||||
vector
|
||||
cassert
|
||||
|
||||
@@ -1114,6 +1114,7 @@ ToolUtils.h
|
||||
tr1/functional
|
||||
trace.h
|
||||
Traps.h
|
||||
type_traits
|
||||
typeinfo
|
||||
types.h
|
||||
Types.h
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
@@ -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,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,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);
|
||||
|
||||
@@ -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,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,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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
let gActiveListeners = {};
|
||||
var gActiveListeners = {};
|
||||
|
||||
function registerPopupEventHandler(eventName, callback) {
|
||||
gActiveListeners[eventName] = function (event) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include "GMPCallbackBase.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
class nsCString;
|
||||
|
||||
class GMPVideoDecoderCallbackProxy : public GMPCallbackBase,
|
||||
public GMPVideoDecoderCallback
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,5 +14,3 @@ LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul-gtest'
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
@@ -38,4 +38,7 @@ TEST_DIRS += [
|
||||
'gtest',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_GONK_MEDIACODEC']:
|
||||
DEFINES['MOZ_GONK_MEDIACODEC'] = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Cache-Control: no-store
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Cache-Control: no-store
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
Cache-Control: no-store
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +283,6 @@ private:
|
||||
*/
|
||||
class OMXVideoEncoder final : public OMXCodecWrapper
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OMXVideoEncoder)
|
||||
public:
|
||||
// Types of output blob format.
|
||||
enum BlobFormat {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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'
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user