content/media/test/manifest.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/test/manifest.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,784 @@
     1.4 +// In each list of tests below, test file types that are not supported should
     1.5 +// be ignored. To make sure tests respect that, we include a file of type
     1.6 +// "bogus/duh" in each list.
     1.7 +
     1.8 +// These are small test files, good for just seeing if something loads. We
     1.9 +// really only need one test file per backend here.
    1.10 +var gSmallTests = [
    1.11 +  { name:"small-shot.ogg", type:"audio/ogg", duration:0.276 },
    1.12 +  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
    1.13 +  { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
    1.14 +  { name:"small-shot-mp3.mp4", type:"audio/mp4; codecs=mp3", duration:0.34 },
    1.15 +  { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
    1.16 +  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
    1.17 +  { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
    1.18 +  { name:"vp9.webm", type:"video/webm", width:320, height:240, duration:4 },
    1.19 +  { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
    1.20 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
    1.21 +  { name:"bogus.duh", type:"bogus/duh" }
    1.22 +];
    1.23 +
    1.24 +// Used by test_bug654550.html, for videoStats preference
    1.25 +var gVideoTests = [
    1.26 +  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
    1.27 +  { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
    1.28 +  { name:"bogus.duh", type:"bogus/duh" }
    1.29 +];
    1.30 +
    1.31 +// Used by test_progress to ensure we get the correct progress information
    1.32 +// during resource download.
    1.33 +var gProgressTests = [
    1.34 +  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0, size:11069 },
    1.35 +  { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
    1.36 +  { name:"seek.ogv", type:"video/ogg", duration:3.966, size:285310 },
    1.37 +  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942 },
    1.38 +  { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
    1.39 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56, size:383631 },
    1.40 +  { name:"bogus.duh", type:"bogus/duh" }
    1.41 +];
    1.42 +
    1.43 +// Used by test_played.html
    1.44 +var gPlayedTests = [
    1.45 +  { name:"big.wav", type:"audio/x-wav", duration:9.0 },
    1.46 +  { name:"seek.ogv", type:"video/ogg", duration:3.966 },
    1.47 +  { name:"seek.webm", type:"video/webm", duration:3.966 },
    1.48 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
    1.49 +  { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
    1.50 +  { name:"vbr.mp3", type:"audio/mpeg", duration:10.0 },
    1.51 +  { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 }
    1.52 +];
    1.53 +
    1.54 +// Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
    1.55 +// anything for testing clone-specific bugs.
    1.56 +var cloneKey = Math.floor(Math.random()*100000000);
    1.57 +var gCloneTests = gSmallTests.concat([
    1.58 +  // Actual duration is ~200ms, we have Content-Duration lie about it.
    1.59 +  { name:"bug520908.ogv", type:"video/ogg", duration:9000 },
    1.60 +  // short-video is more like 1s, so if you load this twice you'll get an unexpected duration
    1.61 +  { name:"dynamic_resource.sjs?key=" + cloneKey + "&res1=320x240.ogv&res2=short-video.ogv",
    1.62 +    type:"video/ogg", duration:0.266 },
    1.63 +]);
    1.64 +
    1.65 +// Used by test_play_twice.  Need one test file per decoder backend, plus
    1.66 +// anything for testing bugs that occur when replying a played file.
    1.67 +var gReplayTests = gSmallTests.concat([
    1.68 +  { name:"bug533822.ogg", type:"audio/ogg" },
    1.69 +]);
    1.70 +
    1.71 +// Used by test_paused_after_ended. Need one test file per decoder backend, plus
    1.72 +// anything for testing bugs that occur when replying a played file.
    1.73 +var gPausedAfterEndedTests = gSmallTests.concat([
    1.74 +  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
    1.75 +  { name:"small-shot.ogg", type:"video/ogg", duration:0.276 }
    1.76 +]);
    1.77 +
    1.78 +// Test the mozHasAudio property, and APIs that detect different kinds of
    1.79 +// tracks
    1.80 +var gTrackTests = [
    1.81 +  { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444, hasAudio:true, hasVideo:false },
    1.82 +  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942, hasAudio:false, hasVideo:true },
    1.83 +  { name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true, hasVideo:true },
    1.84 +  { name:"seek.webm", type:"video/webm", duration:3.966, size:215529, hasAudio:false, hasVideo:true },
    1.85 +  { name:"bogus.duh", type:"bogus/duh" }
    1.86 +];
    1.87 +
    1.88 +// Used by any media recorder test. Need one test file per decoder backend
    1.89 +// currently supported by the media encoder.
    1.90 +var gMediaRecorderTests = [
    1.91 +  { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 }
    1.92 +];
    1.93 +
    1.94 +// These are files that we want to make sure we can play through.  We can
    1.95 +// also check metadata.  Put files of the same type together in this list so if
    1.96 +// something crashes we have some idea of which backend is responsible.
    1.97 +// Used by test_playback, which expects no error event and one ended event.
    1.98 +var gPlayTests = [
    1.99 +  // 8-bit samples
   1.100 +  { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
   1.101 +  // 8-bit samples, file is truncated
   1.102 +  { name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
   1.103 +  // file has trailing non-PCM data
   1.104 +  { name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
   1.105 +  // file with list chunk
   1.106 +  { name:"r16000_u8_c1_list.wav", type:"audio/x-wav", duration:4.2 },
   1.107 +
   1.108 +  // Ogg stream without eof marker
   1.109 +  { name:"bug461281.ogg", type:"application/ogg", duration:2.208 },
   1.110 +
   1.111 +  // oggz-chop stream
   1.112 +  { name:"bug482461.ogv", type:"video/ogg", duration:4.34 },
   1.113 +  // Theora only oggz-chop stream
   1.114 +  { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
   1.115 +  // With first frame a "duplicate" (empty) frame.
   1.116 +  { name:"bug500311.ogv", type:"video/ogg", duration:1.96 },
   1.117 +  // Small audio file
   1.118 +  { name:"small-shot.ogg", type:"video/ogg", duration:0.276 },
   1.119 +  // More audio in file than video.
   1.120 +  { name:"short-video.ogv", type:"video/ogg", duration:1.081 },
   1.121 +  // First Theora data packet is zero bytes.
   1.122 +  { name:"bug504613.ogv", type:"video/ogg", duration:Number.NaN },
   1.123 +  // Multiple audio streams.
   1.124 +  { name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
   1.125 +  // oggz-chop with non-keyframe as first frame
   1.126 +  { name:"bug556821.ogv", type:"video/ogg", duration:2.551 },
   1.127 +
   1.128 +  // Encoded with vorbis beta1, includes unusually sized codebooks
   1.129 +  { name:"beta-phrasebook.ogg", type:"audio/ogg", duration:4.01 },
   1.130 +  // Small file, only 1 frame with audio only.
   1.131 +  { name:"bug520493.ogg", type:"audio/ogg", duration:0.458 },
   1.132 +  // Small file with vorbis comments with 0 length values and names.
   1.133 +  { name:"bug520500.ogg", type:"audio/ogg", duration:0.123 },
   1.134 +
   1.135 +  // Various weirdly formed Ogg files
   1.136 +  { name:"bug499519.ogv", type:"video/ogg", duration:0.24 },
   1.137 +  { name:"bug506094.ogv", type:"video/ogg", duration:0 },
   1.138 +  { name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
   1.139 +  { name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
   1.140 +  { name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
   1.141 +  { name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
   1.142 +  { name:"chain.ogv", type:"video/ogg", duration:Number.NaN },
   1.143 +  { name:"bug523816.ogv", type:"video/ogg", duration:0.533 },
   1.144 +  { name:"bug495129.ogv", type:"video/ogg", duration:2.41 },
   1.145 +  { name:"bug498380.ogv", type:"video/ogg", duration:0.533 },
   1.146 +  { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
   1.147 +  { name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
   1.148 +  { name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
   1.149 +  { name:"audio-overhang.ogg", type:"audio/ogg", duration:2.3 },
   1.150 +  { name:"video-overhang.ogg", type:"audio/ogg", duration:3.966 },
   1.151 +
   1.152 +  // bug461281.ogg with the middle second chopped out.
   1.153 +  { name:"audio-gaps.ogg", type:"audio/ogg", duration:2.208 },
   1.154 +
   1.155 +  // Test playback/metadata work after a redirect
   1.156 +  { name:"redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
   1.157 +    type:"video/ogg", duration:0.266 },
   1.158 +
   1.159 +  // Test playback of a webm file
   1.160 +  { name:"seek.webm", type:"video/webm", duration:3.966 },
   1.161 +
   1.162 +  // Test playback of a WebM file with non-zero start time.
   1.163 +  { name:"split.webm", type:"video/webm", duration:1.967 },
   1.164 +
   1.165 +  // Test playback of a WebM file with vp9 video
   1.166 +  //{ name:"vp9.webm", type:"video/webm", duration:4 },
   1.167 +  { name:"vp9cake.webm", type:"video/webm", duration:7.966 },
   1.168 +
   1.169 +  // Test playback of a raw file
   1.170 +  { name:"seek.yuv", type:"video/x-raw-yuv", duration:1.833 },
   1.171 +
   1.172 +  // A really short, low sample rate, single channel file. This tests whether
   1.173 +  // we can handle playing files when only push very little audio data to the
   1.174 +  // hardware.
   1.175 +  { name:"spacestorm-1000Hz-100ms.ogg", type:"audio/ogg", duration:0.099 },
   1.176 +
   1.177 +  // Opus data in an ogg container
   1.178 +  { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   1.179 +  // Opus data in a webm container
   1.180 +  { name:"detodos.webm", type:"audio/webm; codecs=opus", duration:2.9135 },
   1.181 +
   1.182 +  // Multichannel Opus in an ogg container
   1.183 +  { name:"test-1-mono.opus", type:"audio/ogg; codecs=opus", duration:1.044 },
   1.184 +  { name:"test-2-stereo.opus", type:"audio/ogg; codecs=opus", duration:2.925 },
   1.185 +  { name:"test-3-LCR.opus", type:"audio/ogg; codecs=opus", duration:4.214 },
   1.186 +  { name:"test-4-quad.opus", type:"audio/ogg; codecs=opus", duration:6.234 },
   1.187 +  { name:"test-5-5.0.opus", type:"audio/ogg; codecs=opus", duration:7.558 },
   1.188 +  { name:"test-6-5.1.opus", type:"audio/ogg; codecs=opus", duration:10.333 },
   1.189 +  { name:"test-7-6.1.opus", type:"audio/ogg; codecs=opus", duration:11.690 },
   1.190 +  { name:"test-8-7.1.opus", type:"audio/ogg; codecs=opus", duration:13.478 },
   1.191 +
   1.192 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   1.193 +
   1.194 +  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
   1.195 +  { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
   1.196 +  { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   1.197 +  // owl.mp3 as above, but with something funny going on in the ID3v2 tag
   1.198 +  // that causes DirectShow to fail.
   1.199 +  { name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.29 },
   1.200 +  // owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
   1.201 +  // that causes DirectShow to fail.
   1.202 +  { name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.29 },
   1.203 +  // One second of silence with ~140KB of ID3 tags. Usually when the first MP3
   1.204 +  // frame is at such a high offset into the file, MP3FrameParser will give up
   1.205 +  // and report that the stream is not MP3. However, it does not count ID3 tags
   1.206 +  // in that offset. This test case makes sure that ID3 exclusion holds.
   1.207 +  { name:"huge-id3.mp3", type:"audio/mpeg", duration:1.00 },
   1.208 +  // A truncated VBR MP3 with just enough frames to keep most decoders happy.
   1.209 +  // The Xing header reports the length of the file to be around 10 seconds, but
   1.210 +  // there is really only one second worth of data. We want MP3FrameParser to
   1.211 +  // trust the header, so this should be reported as 10 seconds.
   1.212 +  { name:"vbr-head.mp3", type:"audio/mpeg", duration:10.00 },
   1.213 +
   1.214 +  // Invalid file
   1.215 +  { name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
   1.216 +];
   1.217 +
   1.218 +// A file for each type we can support.
   1.219 +var gSnifferTests = [
   1.220 +  { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
   1.221 +  { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
   1.222 +  { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
   1.223 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56, size:383631 },
   1.224 +  // A mp3 file with id3 tags.
   1.225 +  { name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
   1.226 +  { name:"bogus.duh", type:"bogus/duh" }
   1.227 +];
   1.228 +
   1.229 +// Files we must reject as invalid.
   1.230 +var gInvalidTests = [
   1.231 +  { name:"invalid-m0c0.opus", type:"audio/ogg; codecs=opus"},
   1.232 +  { name:"invalid-m0c3.opus", type:"audio/ogg; codecs=opus"},
   1.233 +  { name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"},
   1.234 +  { name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"},
   1.235 +  { name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"},
   1.236 +  { name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"},
   1.237 +  { name:"invalid-cmap-short.opus", type:"audio/ogg; codecs=opus"},
   1.238 +  { name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"},
   1.239 +  { name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"},
   1.240 +  { name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"},
   1.241 +  { name:"invalid-preskip.webm", type:"audio/webm; codecs=opus"},
   1.242 +];
   1.243 +
   1.244 +// Converts a path/filename to a file:// URI which we can load from disk.
   1.245 +// Optionally checks whether the file actually exists on disk at the location
   1.246 +// we've specified.
   1.247 +function fileUriToSrc(path, mustExist) {
   1.248 +  // android mochitest doesn't support file://
   1.249 +  if (navigator.appVersion.indexOf("Android") != -1 || SpecialPowers.Services.appinfo.name == "B2G")
   1.250 +    return path;
   1.251 +
   1.252 +  const Ci = SpecialPowers.Ci;
   1.253 +  const Cc = SpecialPowers.Cc;
   1.254 +  const Cr = SpecialPowers.Cr;
   1.255 +  var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
   1.256 +               getService(Ci.nsIProperties);
   1.257 +  var f = dirSvc.get("CurWorkD", Ci.nsILocalFile);
   1.258 +  var split = path.split("/");
   1.259 +  for(var i = 0; i < split.length; ++i) {
   1.260 +    f.append(split[i]);
   1.261 +  }
   1.262 +  if (mustExist && !f.exists()) {
   1.263 +    ok(false, "We expected '" + path + "' to exist, but it doesn't!");
   1.264 +  }
   1.265 +  return f.path;
   1.266 +}
   1.267 +
   1.268 +// Returns true if two TimeRanges are equal, false otherwise
   1.269 +function range_equals(r1, r2) {
   1.270 +  if (r1.length != r2.length) {
   1.271 +    return false;
   1.272 +  }
   1.273 +  for (var i = 0; i < r1.length; i++) {
   1.274 +    if (r1.start(i) != r2.start(i) || r1.end(i) != r2.end(i)) {
   1.275 +      return false;
   1.276 +    }
   1.277 +  }
   1.278 +  return true;
   1.279 +}
   1.280 +
   1.281 +// These are URIs to files that we use to check that we don't leak any state
   1.282 +// or other information such that script can determine stuff about a user's
   1.283 +// environment. Used by test_info_leak.
   1.284 +var gInfoLeakTests = [
   1.285 +  {
   1.286 +    type: 'video/ogg',
   1.287 +    src: fileUriToSrc("tests/content/media/test/320x240.ogv", true),
   1.288 +  },{
   1.289 +    type: 'video/ogg',
   1.290 +    src: fileUriToSrc("tests/content/media/test/404.ogv", false),
   1.291 +  }, {
   1.292 +    type: 'audio/x-wav',
   1.293 +    src: fileUriToSrc("tests/content/media/test/r11025_s16_c1.wav", true),
   1.294 +  }, {
   1.295 +    type: 'audio/x-wav',
   1.296 +    src: fileUriToSrc("tests/content/media/test/404.wav", false),
   1.297 +  }, {
   1.298 +    type: 'audio/ogg',
   1.299 +    src: fileUriToSrc("tests/content/media/test/bug461281.ogg", true),
   1.300 +  }, {
   1.301 +    type: 'audio/ogg',
   1.302 +    src: fileUriToSrc("tests/content/media/test/404.ogg", false),
   1.303 +  }, {
   1.304 +    type: 'video/webm',
   1.305 +    src: fileUriToSrc("tests/content/media/test/seek.webm", true),
   1.306 +  }, {
   1.307 +    type: 'video/webm',
   1.308 +    src: fileUriToSrc("tests/content/media/test/404.webm", false),
   1.309 +  }, {
   1.310 +    type: 'video/ogg',
   1.311 +    src: 'http://localhost/404.ogv',
   1.312 +  }, {
   1.313 +    type: 'audio/x-wav',
   1.314 +    src: 'http://localhost/404.wav',
   1.315 +  }, {
   1.316 +    type: 'video/webm',
   1.317 +    src: 'http://localhost/404.webm',
   1.318 +  }, {
   1.319 +    type: 'video/ogg',
   1.320 +    src: 'http://example.com/tests/content/media/test/test_info_leak.html'
   1.321 +  }, {
   1.322 +    type: 'audio/ogg',
   1.323 +    src: 'http://example.com/tests/content/media/test/test_info_leak.html'
   1.324 +  }
   1.325 +];
   1.326 +
   1.327 +// These are files that must fire an error during load or playback, and do not
   1.328 +// cause a crash.  Put files of the same type together in this list so if
   1.329 +// something crashes we have some idea of which backend is responsible.  Used
   1.330 +// by test_playback_errors, which expects one error event and no ended event.
   1.331 +// Put files of the same type together in this list so if something crashes
   1.332 +// we have some idea of which backend is responsible.
   1.333 +var gErrorTests = [
   1.334 +  { name:"bogus.wav", type:"audio/x-wav" },
   1.335 +  { name:"bogus.ogv", type:"video/ogg" },
   1.336 +  { name:"448636.ogv", type:"video/ogg" },
   1.337 +  { name:"bug504843.ogv", type:"video/ogg" },
   1.338 +  { name:"bug501279.ogg", type:"audio/ogg" },
   1.339 +  { name:"bug580982.webm", type:"video/webm" },
   1.340 +  { name:"bug603918.webm", type:"video/webm" },
   1.341 +  { name:"bug604067.webm", type:"video/webm" },
   1.342 +  { name:"bogus.duh", type:"bogus/duh" }
   1.343 +];
   1.344 +
   1.345 +// These are files that have nontrivial duration and are useful for seeking within.
   1.346 +var gSeekTests = [
   1.347 +  { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   1.348 +  { name:"audio.wav", type:"audio/x-wav", duration:0.031247 },
   1.349 +  { name:"seek.ogv", type:"video/ogg", duration:3.966 },
   1.350 +  { name:"320x240.ogv", type:"video/ogg", duration:0.266 },
   1.351 +  { name:"seek.webm", type:"video/webm", duration:3.966 },
   1.352 +  { name:"bug516323.indexed.ogv", type:"video/ogg", duration:4.208333 },
   1.353 +  { name:"split.webm", type:"video/webm", duration:1.967 },
   1.354 +  { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   1.355 +  { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   1.356 +  { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   1.357 +  { name:"bogus.duh", type:"bogus/duh", duration:123 }
   1.358 +];
   1.359 +
   1.360 +var gFastSeekTests = [
   1.361 +  { name:"gizmo.mp4", type:"video/mp4", keyframes:[0, 1.0, 2.0, 3.0, 4.0, 5.0 ] },
   1.362 +  // Note: Not all keyframes in the file are actually referenced in the Cues in this file.
   1.363 +  { name:"seek.webm", type:"video/webm", keyframes:[0, 0.8, 1.6, 2.4, 3.2]},
   1.364 +  // Note: the sync points are the points on both the audio and video streams
   1.365 +  // before the keyframes. You can't just assume that the keyframes are the sync
   1.366 +  // points, as the audio required for that sync point may be before the keyframe.
   1.367 +  { name:"bug516323.indexed.ogv", type:"video/ogg", keyframes:[0, 0.46, 3.06] },
   1.368 +];
   1.369 +
   1.370 +function IsWindows8OrLater() {
   1.371 +  var re = /Windows NT (\d.\d)/;
   1.372 +  var winver = navigator.userAgent.match(re);
   1.373 +  return winver && winver.length == 2 && parseFloat(winver[1]) >= 6.2;
   1.374 +}
   1.375 +
   1.376 +// These are files that are non seekable, due to problems with the media,
   1.377 +// for example broken or missing indexes.
   1.378 +var gUnseekableTests = [
   1.379 +  { name:"no-cues.webm", type:"video/webm" },
   1.380 +  { name:"bogus.duh", type:"bogus/duh"}
   1.381 +];
   1.382 +// Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so
   1.383 +// only include it in the unseekable tests if we're on later versions of Windows. 
   1.384 +// This test actually only passes on win8 at the moment.
   1.385 +if (navigator.userAgent.indexOf("Windows") != -1 && IsWindows8OrLater()) {
   1.386 +  gUnseekableTests = gUnseekableTests.concat([
   1.387 +    { name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" }
   1.388 +  ]);
   1.389 +}
   1.390 +// Android supports fragmented MP4 playback from 4.3.
   1.391 +var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
   1.392 +                                  .getService(SpecialPowers.Ci.nsIPropertyBag2)
   1.393 +                                  .getProperty('version');
   1.394 +// Fragmented MP4.
   1.395 +if (navigator.userAgent.indexOf("Mobile") != -1 && androidVersion >= 18) {
   1.396 +  gUnseekableTests = gUnseekableTests.concat([
   1.397 +    { name:"street.mp4", type:"video/mp4" }
   1.398 +  ]);
   1.399 +}
   1.400 +
   1.401 +// These are files suitable for using with a "new Audio" constructor.
   1.402 +var gAudioTests = [
   1.403 +  { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   1.404 +  { name:"sound.ogg", type:"audio/ogg" },
   1.405 +  { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   1.406 +  { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
   1.407 +  { name:"bogus.duh", type:"bogus/duh", duration:123 }
   1.408 +];
   1.409 +
   1.410 +// These files ensure our handling of 404 errors is consistent across the
   1.411 +// various backends.
   1.412 +var g404Tests = [
   1.413 +  { name:"404.wav", type:"audio/x-wav" },
   1.414 +  { name:"404.ogv", type:"video/ogg" },
   1.415 +  { name:"404.oga", type:"audio/ogg" },
   1.416 +  { name:"404.webm", type:"video/webm" },
   1.417 +  { name:"bogus.duh", type:"bogus/duh" }
   1.418 +];
   1.419 +
   1.420 +// These are files suitable for testing various decoder failures that are
   1.421 +// expected to fire MEDIA_ERR_DECODE.  Used by test_decode_error, which expects
   1.422 +// an error and emptied event, and no loadedmetadata or ended event.
   1.423 +var gDecodeErrorTests = [
   1.424 +  // Valid files with unsupported codecs
   1.425 +  { name:"r11025_msadpcm_c1.wav", type:"audio/x-wav" },
   1.426 +  { name:"dirac.ogg", type:"video/ogg" },
   1.427 +  // Invalid files
   1.428 +  { name:"bogus.wav", type:"audio/x-wav" },
   1.429 +  { name:"bogus.ogv", type:"video/ogg" },
   1.430 +
   1.431 +  { name:"bogus.duh", type:"bogus/duh" }
   1.432 +];
   1.433 +
   1.434 +// These are files that are used for media fragments tests
   1.435 +var gFragmentTests = [
   1.436 +  { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 }
   1.437 +];
   1.438 +
   1.439 +// Used by test_chaining.html. The |links| attributes is the number of links in
   1.440 +// this file that we should be able to play.
   1.441 +var gChainingTests = [
   1.442 +  // Vorbis and Opus chained file. They have user comments |index=n| where `n`
   1.443 +  // is the index of this segment in the file, 0 indexed.
   1.444 +  { name:"chain.ogg", type:"audio/ogg", links: 4},
   1.445 +  { name:"chain.opus", type:"audio/ogg; codec=opus", links: 4},
   1.446 +  // Those files are chained files with a different number of channels in each
   1.447 +  // part. This is not supported and should stop playing after the first part.
   1.448 +  { name:"variable-channel.ogg", type:"audio/ogg", links: 1 },
   1.449 +  { name:"variable-channel.opus", type:"audio/ogg; codec=opus", links: 1 },
   1.450 +  // Those files are chained files with a different sample rate in each
   1.451 +  // part. This is not supported and should stop playing after the first part.
   1.452 +  { name:"variable-samplerate.ogg", type:"audio/ogg", links: 1 },
   1.453 +  // Opus decoding in Firefox outputs 48 kHz PCM despite having a different
   1.454 +  // original sample rate, so we can safely play Opus chained media that have
   1.455 +  // different samplerate accross links.
   1.456 +  { name:"variable-samplerate.opus", type:"audio/ogg; codec=opus", links: 2 },
   1.457 +  // A chained video file. We don't support those, so only one link should be
   1.458 +  // reported.
   1.459 +  { name:"chained-video.ogv", type:"video/ogg", links: 1 },
   1.460 +  // A file that consist in 4 links of audio, then another link that has video.
   1.461 +  // We should stop right after the 4 audio links.
   1.462 +  { name:"chained-audio-video.ogg", type:"video/ogg", links: 4 },
   1.463 +  // An opus file that has two links, with a different preskip value for each
   1.464 +  // link. We should be able to play both links.
   1.465 +  { name:"variable-preskip.opus", type:"audio/ogg; codec=opus", links: 2 },
   1.466 +  { name:"bogus.duh", type:"bogus/duh" }
   1.467 +];
   1.468 +
   1.469 +// Videos with an aspect ratio. Used for testing that displaying frames
   1.470 +// on a canvas works correctly in the case of non-standard aspect ratios.
   1.471 +// See bug 874897 for an example.
   1.472 +var gAspectRatioTests = [
   1.473 +  { name:"VID_0001.ogg", type:"video/ogg", duration:19.966 }
   1.474 +];
   1.475 +
   1.476 +// These are files with non-trivial tag sets.
   1.477 +// Used by test_metadata.html.
   1.478 +var gMetadataTests = [
   1.479 +  // Ogg Vorbis files
   1.480 +  { name:"short-video.ogv", tags: {
   1.481 +      TITLE:"Lepidoptera",
   1.482 +      ARTIST:"Epoq",
   1.483 +      ALBUM:"Kahvi Collective",
   1.484 +      DATE:"2002",
   1.485 +      COMMENT:"http://www.kahvi.org",
   1.486 +    }
   1.487 +  },
   1.488 +  { name:"bug516323.ogv", tags: {
   1.489 +      GENRE:"Open Movie",
   1.490 +      ENCODER:"Audacity",
   1.491 +      TITLE:"Elephants Dream",
   1.492 +      ARTIST:"Silvia Pfeiffer",
   1.493 +      COMMENTS:"Audio Description"
   1.494 +    }
   1.495 +  },
   1.496 +  { name:"bug516323.indexed.ogv", tags: {
   1.497 +      GENRE:"Open Movie",
   1.498 +      ENCODER:"Audacity",
   1.499 +      TITLE:"Elephants Dream",
   1.500 +      ARTIST:"Silvia Pfeiffer",
   1.501 +      COMMENTS:"Audio Description"
   1.502 +    }
   1.503 +  },
   1.504 +  { name:"detodos.opus", tags: {
   1.505 +      title:"De todos. Para todos.",
   1.506 +      artist:"Mozilla.org"
   1.507 +    }
   1.508 +  },
   1.509 +  { name:"sound.ogg", tags: { } },
   1.510 +  { name:"small-shot.ogg", tags: {
   1.511 +      title:"Pew SFX"
   1.512 +    }
   1.513 +  },
   1.514 +  { name:"badtags.ogg", tags: {
   1.515 +      // We list only the valid tags here, and verify
   1.516 +      // the invalid ones are filtered out.
   1.517 +      title:"Invalid comments test file",
   1.518 +      empty:"",
   1.519 +      "":"empty",
   1.520 +      "{- [(`!@\"#$%^&')] -}":"valid tag name, surprisingly"
   1.521 +      // The file also includes the following invalid tags.
   1.522 +      // "A description with no separator is a common problem.",
   1.523 +      // "雨":"Likely, but an invalid key (non-ascii).",
   1.524 +      // "not\nval\x1fid":"invalid tag name",
   1.525 +      // "not~valid":"this isn't a valid name either",
   1.526 +      // "not-utf-8":"invalid sequences: \xff\xfe\xfa\xfb\0eol"
   1.527 +    }
   1.528 +  },
   1.529 +  { name:"wave_metadata.wav", tags: {
   1.530 +      name:"Track Title",
   1.531 +      artist:"Artist Name",
   1.532 +      comments:"Comments",
   1.533 +    }
   1.534 +  },
   1.535 +  { name:"wave_metadata_utf8.wav", tags: {
   1.536 +      name:"歌曲名稱",
   1.537 +      artist:"作曲者",
   1.538 +      comments:"註解",
   1.539 +    }
   1.540 +  },
   1.541 +  { name:"wave_metadata_unknown_tag.wav", tags: {
   1.542 +      name:"Track Title",
   1.543 +      comments:"Comments",
   1.544 +    }
   1.545 +  },
   1.546 +  { name:"wave_metadata_bad_len.wav", tags: {
   1.547 +      name:"Track Title",
   1.548 +      artist:"Artist Name",
   1.549 +    }
   1.550 +  },
   1.551 +  { name:"wave_metadata_bad_no_null.wav", tags: {
   1.552 +      name:"Track Title",
   1.553 +      artist:"Artist Name",
   1.554 +      comments:"Comments!!",
   1.555 +    }
   1.556 +  },
   1.557 +  { name:"wave_metadata_bad_utf8.wav", tags: {
   1.558 +      name:"歌曲名稱",
   1.559 +      comments:"註解",
   1.560 +    }
   1.561 +  },
   1.562 +  { name:"wavedata_u8.wav", tags: { }
   1.563 +  },
   1.564 +];
   1.565 +
   1.566 +function checkMetadata(msg, e, test) {
   1.567 +  if (test.width) {
   1.568 +    is(e.videoWidth, test.width, msg + " video width");
   1.569 +  }
   1.570 +  if (test.height) {
   1.571 +    is(e.videoHeight, test.height, msg + " video height");
   1.572 +  }
   1.573 +  if (test.duration) {
   1.574 +    ok(Math.abs(e.duration - test.duration) < 0.1,
   1.575 +       msg + " duration (" + e.duration + ") should be around " + test.duration);
   1.576 +  }
   1.577 +}
   1.578 +
   1.579 +// Returns the first test from candidates array which we can play with the
   1.580 +// installed video backends.
   1.581 +function getPlayableVideo(candidates) {
   1.582 +  var v = document.createElement("video");
   1.583 +  var resources = candidates.filter(function(x){return /^video/.test(x.type) && v.canPlayType(x.type);});
   1.584 +  if (resources.length > 0)
   1.585 +    return resources[0];
   1.586 +  return null;
   1.587 +}
   1.588 +
   1.589 +function getPlayableAudio(candidates) {
   1.590 +  var v = document.createElement("audio");
   1.591 +  var resources = candidates.filter(function(x){return /^audio/.test(x.type) && v.canPlayType(x.type);});
   1.592 +  if (resources.length > 0)
   1.593 +    return resources[0];
   1.594 +  return null;
   1.595 +}
   1.596 +
   1.597 +// Returns the type of element that should be created for the given mimetype.
   1.598 +function getMajorMimeType(mimetype) {
   1.599 +  if (/^video/.test(mimetype)) {
   1.600 +    return "video";
   1.601 +  } else {
   1.602 +    return "audio";
   1.603 +  }
   1.604 +}
   1.605 +
   1.606 +function removeNodeAndSource(n) {
   1.607 +  n.remove();
   1.608 +  // force release of underlying decoder
   1.609 +  n.src = "";
   1.610 +  while (n.firstChild) {
   1.611 +    n.removeChild(n.firstChild);
   1.612 +  }
   1.613 +}
   1.614 +
   1.615 +// Number of tests to run in parallel. Warning: Each media element requires
   1.616 +// at least 3 threads (4 on Linux), and on Linux each thread uses 10MB of
   1.617 +// virtual address space. Beware!
   1.618 +var PARALLEL_TESTS = 2;
   1.619 +
   1.620 +// When true, we'll loop forever on whatever test we run. Use this to debug
   1.621 +// intermittent test failures.
   1.622 +const DEBUG_TEST_LOOP_FOREVER = false;
   1.623 +
   1.624 +// Manages a run of media tests. Runs them in chunks in order to limit
   1.625 +// the number of media elements/threads running in parallel. This limits peak
   1.626 +// memory use, particularly on Linux x86 where thread stacks use 10MB of
   1.627 +// virtual address space.
   1.628 +// Usage:
   1.629 +//   1. Create a new MediaTestManager object.
   1.630 +//   2. Create a test startTest function. This takes a test object and a token,
   1.631 +//      and performs anything necessary to start the test. The test object is an
   1.632 +//      element in one of the g*Tests above. Your startTest function must call
   1.633 +//      MediaTestManager.start(token) if it starts a test. The test object is
   1.634 +//      guaranteed to be playable by our supported decoders; you don't need to
   1.635 +//      check canPlayType.
   1.636 +//   3. When your tests finishes, call MediaTestManager.finished(), passing
   1.637 +//      the token back to the manager. The manager may either start the next run
   1.638 +//      or end the mochitest if all the tests are done.
   1.639 +function MediaTestManager() {
   1.640 +
   1.641 +  // Sets up a MediaTestManager to runs through the 'tests' array, which needs
   1.642 +  // to be one of, or have the same fields as, the g*Test arrays of tests. Uses
   1.643 +  // the user supplied 'startTest' function to initialize the test. This
   1.644 +  // function must accept two arguments, the test entry from the 'tests' array,
   1.645 +  // and a token. Call MediaTestManager.started(token) if you start the test,
   1.646 +  // and MediaTestManager.finished(token) when the test finishes. You don't have
   1.647 +  // to start every test, but if you call started() you *must* call finish()
   1.648 +  // else you'll timeout.
   1.649 +  this.runTests = function(tests, startTest) {
   1.650 +    this.startTime = new Date();
   1.651 +    SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
   1.652 +    this.testNum = 0;
   1.653 +    this.tests = tests;
   1.654 +    this.startTest = startTest;
   1.655 +    this.tokens = [];
   1.656 +    this.isShutdown = false;
   1.657 +    this.numTestsRunning = 0;
   1.658 +    // Always wait for explicit finish.
   1.659 +    SimpleTest.waitForExplicitFinish();
   1.660 +    this.nextTest();
   1.661 +  }
   1.662 +
   1.663 +  // Registers that the test corresponding to 'token' has been started.
   1.664 +  // Don't call more than once per token.
   1.665 +  this.started = function(token) {
   1.666 +    this.tokens.push(token);
   1.667 +    this.numTestsRunning++;
   1.668 +    is(this.numTestsRunning, this.tokens.length, "[started " + token + "] Length of array should match number of running tests");
   1.669 +  }
   1.670 +
   1.671 +  // Registers that the test corresponding to 'token' has finished. Call when
   1.672 +  // you've finished your test. If all tests are complete this will finish the
   1.673 +  // run, otherwise it may start up the next run. It's ok to call multiple times
   1.674 +  // per token.
   1.675 +  this.finished = function(token) {
   1.676 +    var i = this.tokens.indexOf(token);
   1.677 +    if (i != -1) {
   1.678 +      // Remove the element from the list of running tests.
   1.679 +      this.tokens.splice(i, 1);
   1.680 +    }
   1.681 +    this.numTestsRunning--;
   1.682 +    is(this.numTestsRunning, this.tokens.length, "[finished " + token + "] Length of array should match number of running tests");
   1.683 +    if (this.tokens.length < PARALLEL_TESTS) {
   1.684 +      this.nextTest();
   1.685 +    }
   1.686 +  }
   1.687 +
   1.688 +  // Starts the next batch of tests, or finishes if they're all done.
   1.689 +  // Don't call this directly, call finished(token) when you're done.
   1.690 +  this.nextTest = function() {
   1.691 +    // Force an exact  GC after every completed testcase. This ensures that any
   1.692 +    // decoders with live threads waiting for the GC are killed promptly, to free
   1.693 +    // up the thread stacks' address space, and destroy decoder resources.
   1.694 +    SpecialPowers.exactGC(window, function(){
   1.695 +      while (this.testNum < this.tests.length && this.tokens.length < PARALLEL_TESTS) {
   1.696 +        var test = this.tests[this.testNum];
   1.697 +        var token = (test.name ? (test.name + "-"): "") + this.testNum;
   1.698 +        this.testNum++;
   1.699 +
   1.700 +        if (DEBUG_TEST_LOOP_FOREVER && this.testNum == this.tests.length) {
   1.701 +          this.testNum = 0;
   1.702 +        }
   1.703 +
   1.704 +        // Ensure we can play the resource type.
   1.705 +        if (test.type && !document.createElement('video').canPlayType(test.type))
   1.706 +          continue;
   1.707 +
   1.708 +        // Do the init. This should start the test.
   1.709 +        this.startTest(test, token);
   1.710 +      }
   1.711 +
   1.712 +      if (this.testNum == this.tests.length &&
   1.713 +          !DEBUG_TEST_LOOP_FOREVER &&
   1.714 +          this.tokens.length == 0 &&
   1.715 +          !this.isShutdown)
   1.716 +      {
   1.717 +        this.isShutdown = true;
   1.718 +        if (this.onFinished) {
   1.719 +          this.onFinished();
   1.720 +        }
   1.721 +        mediaTestCleanup();
   1.722 +        var end = new Date();
   1.723 +        SimpleTest.info("Finished at " + end + " (" + (end.getTime() / 1000) + "s)");
   1.724 +        SimpleTest.info("Running time: " + (end.getTime() - this.startTime.getTime())/1000 + "s");
   1.725 +        SimpleTest.finish();
   1.726 +        return;
   1.727 +      }
   1.728 +    }.bind(this));
   1.729 +  }
   1.730 +}
   1.731 +
   1.732 +// Ensures we've got no active video or audio elements in the document, and
   1.733 +// forces a GC to release the address space reserved by the decoders' threads'
   1.734 +// stacks.
   1.735 +function mediaTestCleanup() {
   1.736 +    var V = document.getElementsByTagName("video");
   1.737 +    for (i=0; i<V.length; i++) {
   1.738 +      removeNodeAndSource(V[i]);
   1.739 +      V[i] = null;
   1.740 +    }
   1.741 +    var A = document.getElementsByTagName("audio");
   1.742 +    for (i=0; i<A.length; i++) {
   1.743 +      removeNodeAndSource(A[i]);
   1.744 +      A[i] = null;
   1.745 +    }
   1.746 +    SpecialPowers.forceGC();
   1.747 +}
   1.748 +
   1.749 +(function() {
   1.750 +  // Ensure that preload preferences are comsistent
   1.751 +  var prefService = SpecialPowers.wrap(SpecialPowers.Components)
   1.752 +                                 .classes["@mozilla.org/preferences-service;1"]
   1.753 +                                 .getService(SpecialPowers.Ci.nsIPrefService);
   1.754 +  var branch = prefService.getBranch("media.");
   1.755 +  var oldDefault = 2;
   1.756 +  var oldAuto = 3;
   1.757 +  var oldAppleMedia = undefined;
   1.758 +  var oldGStreamer = undefined;
   1.759 +  var oldOpus = undefined;
   1.760 +
   1.761 +  try { oldAppleMedia = SpecialPowers.getBoolPref("media.apple.mp3.enabled"); } catch(ex) { }
   1.762 +  try { oldGStreamer = SpecialPowers.getBoolPref("media.gstreamer.enabled"); } catch(ex) { }
   1.763 +  try { oldDefault   = SpecialPowers.getIntPref("media.preload.default"); } catch(ex) { }
   1.764 +  try { oldAuto      = SpecialPowers.getIntPref("media.preload.auto"); } catch(ex) { }
   1.765 +  try { oldOpus      = SpecialPowers.getBoolPref("media.opus.enabled"); } catch(ex) { }
   1.766 +
   1.767 +  SpecialPowers.setIntPref("media.preload.default", 2); // preload_metadata
   1.768 +  SpecialPowers.setIntPref("media.preload.auto", 3); // preload_enough
   1.769 +  // test opus playback iff the pref exists
   1.770 +  if (oldOpus !== undefined)
   1.771 +    SpecialPowers.setBoolPref("media.opus.enabled", true);
   1.772 +  if (oldGStreamer !== undefined)
   1.773 +    SpecialPowers.setBoolPref("media.gstreamer.enabled", true);
   1.774 +  if (oldAppleMedia !== undefined)
   1.775 +    SpecialPowers.setBoolPref("media.apple.mp3.enabled", true);
   1.776 +
   1.777 +  window.addEventListener("unload", function() {
   1.778 +    if (oldGStreamer !== undefined)
   1.779 +      SpecialPowers.setBoolPref("media.gstreamer.enabled", oldGStreamer);
   1.780 +    if (oldAppleMedia !== undefined)
   1.781 +      SpecialPowers.setBoolPref("media.apple.mp3.enabled", oldAppleMedia);
   1.782 +    SpecialPowers.setIntPref("media.preload.default", oldDefault);
   1.783 +    SpecialPowers.setIntPref("media.preload.auto", oldAuto);
   1.784 +    if (oldOpus !== undefined)
   1.785 +      SpecialPowers.setBoolPref("media.opus.enabled", oldOpus);
   1.786 +  }, false);
   1.787 + })();

mercurial