content/media/test/manifest.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 // In each list of tests below, test file types that are not supported should
     2 // be ignored. To make sure tests respect that, we include a file of type
     3 // "bogus/duh" in each list.
     5 // These are small test files, good for just seeing if something loads. We
     6 // really only need one test file per backend here.
     7 var gSmallTests = [
     8   { name:"small-shot.ogg", type:"audio/ogg", duration:0.276 },
     9   { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
    10   { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
    11   { name:"small-shot-mp3.mp4", type:"audio/mp4; codecs=mp3", duration:0.34 },
    12   { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
    13   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
    14   { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
    15   { name:"vp9.webm", type:"video/webm", width:320, height:240, duration:4 },
    16   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
    17   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
    18   { name:"bogus.duh", type:"bogus/duh" }
    19 ];
    21 // Used by test_bug654550.html, for videoStats preference
    22 var gVideoTests = [
    23   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
    24   { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
    25   { name:"bogus.duh", type:"bogus/duh" }
    26 ];
    28 // Used by test_progress to ensure we get the correct progress information
    29 // during resource download.
    30 var gProgressTests = [
    31   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0, size:11069 },
    32   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
    33   { name:"seek.ogv", type:"video/ogg", duration:3.966, size:285310 },
    34   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942 },
    35   { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
    36   { name:"gizmo.mp4", type:"video/mp4", duration:5.56, size:383631 },
    37   { name:"bogus.duh", type:"bogus/duh" }
    38 ];
    40 // Used by test_played.html
    41 var gPlayedTests = [
    42   { name:"big.wav", type:"audio/x-wav", duration:9.0 },
    43   { name:"seek.ogv", type:"video/ogg", duration:3.966 },
    44   { name:"seek.webm", type:"video/webm", duration:3.966 },
    45   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
    46   { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
    47   { name:"vbr.mp3", type:"audio/mpeg", duration:10.0 },
    48   { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 }
    49 ];
    51 // Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
    52 // anything for testing clone-specific bugs.
    53 var cloneKey = Math.floor(Math.random()*100000000);
    54 var gCloneTests = gSmallTests.concat([
    55   // Actual duration is ~200ms, we have Content-Duration lie about it.
    56   { name:"bug520908.ogv", type:"video/ogg", duration:9000 },
    57   // short-video is more like 1s, so if you load this twice you'll get an unexpected duration
    58   { name:"dynamic_resource.sjs?key=" + cloneKey + "&res1=320x240.ogv&res2=short-video.ogv",
    59     type:"video/ogg", duration:0.266 },
    60 ]);
    62 // Used by test_play_twice.  Need one test file per decoder backend, plus
    63 // anything for testing bugs that occur when replying a played file.
    64 var gReplayTests = gSmallTests.concat([
    65   { name:"bug533822.ogg", type:"audio/ogg" },
    66 ]);
    68 // Used by test_paused_after_ended. Need one test file per decoder backend, plus
    69 // anything for testing bugs that occur when replying a played file.
    70 var gPausedAfterEndedTests = gSmallTests.concat([
    71   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
    72   { name:"small-shot.ogg", type:"video/ogg", duration:0.276 }
    73 ]);
    75 // Test the mozHasAudio property, and APIs that detect different kinds of
    76 // tracks
    77 var gTrackTests = [
    78   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444, hasAudio:true, hasVideo:false },
    79   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942, hasAudio:false, hasVideo:true },
    80   { name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true, hasVideo:true },
    81   { name:"seek.webm", type:"video/webm", duration:3.966, size:215529, hasAudio:false, hasVideo:true },
    82   { name:"bogus.duh", type:"bogus/duh" }
    83 ];
    85 // Used by any media recorder test. Need one test file per decoder backend
    86 // currently supported by the media encoder.
    87 var gMediaRecorderTests = [
    88   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 }
    89 ];
    91 // These are files that we want to make sure we can play through.  We can
    92 // also check metadata.  Put files of the same type together in this list so if
    93 // something crashes we have some idea of which backend is responsible.
    94 // Used by test_playback, which expects no error event and one ended event.
    95 var gPlayTests = [
    96   // 8-bit samples
    97   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
    98   // 8-bit samples, file is truncated
    99   { name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
   100   // file has trailing non-PCM data
   101   { name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
   102   // file with list chunk
   103   { name:"r16000_u8_c1_list.wav", type:"audio/x-wav", duration:4.2 },
   105   // Ogg stream without eof marker
   106   { name:"bug461281.ogg", type:"application/ogg", duration:2.208 },
   108   // oggz-chop stream
   109   { name:"bug482461.ogv", type:"video/ogg", duration:4.34 },
   110   // Theora only oggz-chop stream
   111   { name:"bug482461-theora.ogv", type:"video/ogg", duration:4.138 },
   112   // With first frame a "duplicate" (empty) frame.
   113   { name:"bug500311.ogv", type:"video/ogg", duration:1.96 },
   114   // Small audio file
   115   { name:"small-shot.ogg", type:"video/ogg", duration:0.276 },
   116   // More audio in file than video.
   117   { name:"short-video.ogv", type:"video/ogg", duration:1.081 },
   118   // First Theora data packet is zero bytes.
   119   { name:"bug504613.ogv", type:"video/ogg", duration:Number.NaN },
   120   // Multiple audio streams.
   121   { name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
   122   // oggz-chop with non-keyframe as first frame
   123   { name:"bug556821.ogv", type:"video/ogg", duration:2.551 },
   125   // Encoded with vorbis beta1, includes unusually sized codebooks
   126   { name:"beta-phrasebook.ogg", type:"audio/ogg", duration:4.01 },
   127   // Small file, only 1 frame with audio only.
   128   { name:"bug520493.ogg", type:"audio/ogg", duration:0.458 },
   129   // Small file with vorbis comments with 0 length values and names.
   130   { name:"bug520500.ogg", type:"audio/ogg", duration:0.123 },
   132   // Various weirdly formed Ogg files
   133   { name:"bug499519.ogv", type:"video/ogg", duration:0.24 },
   134   { name:"bug506094.ogv", type:"video/ogg", duration:0 },
   135   { name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
   136   { name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
   137   { name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
   138   { name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
   139   { name:"chain.ogv", type:"video/ogg", duration:Number.NaN },
   140   { name:"bug523816.ogv", type:"video/ogg", duration:0.533 },
   141   { name:"bug495129.ogv", type:"video/ogg", duration:2.41 },
   142   { name:"bug498380.ogv", type:"video/ogg", duration:0.533 },
   143   { name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
   144   { name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
   145   { name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
   146   { name:"audio-overhang.ogg", type:"audio/ogg", duration:2.3 },
   147   { name:"video-overhang.ogg", type:"audio/ogg", duration:3.966 },
   149   // bug461281.ogg with the middle second chopped out.
   150   { name:"audio-gaps.ogg", type:"audio/ogg", duration:2.208 },
   152   // Test playback/metadata work after a redirect
   153   { name:"redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
   154     type:"video/ogg", duration:0.266 },
   156   // Test playback of a webm file
   157   { name:"seek.webm", type:"video/webm", duration:3.966 },
   159   // Test playback of a WebM file with non-zero start time.
   160   { name:"split.webm", type:"video/webm", duration:1.967 },
   162   // Test playback of a WebM file with vp9 video
   163   //{ name:"vp9.webm", type:"video/webm", duration:4 },
   164   { name:"vp9cake.webm", type:"video/webm", duration:7.966 },
   166   // Test playback of a raw file
   167   { name:"seek.yuv", type:"video/x-raw-yuv", duration:1.833 },
   169   // A really short, low sample rate, single channel file. This tests whether
   170   // we can handle playing files when only push very little audio data to the
   171   // hardware.
   172   { name:"spacestorm-1000Hz-100ms.ogg", type:"audio/ogg", duration:0.099 },
   174   // Opus data in an ogg container
   175   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   176   // Opus data in a webm container
   177   { name:"detodos.webm", type:"audio/webm; codecs=opus", duration:2.9135 },
   179   // Multichannel Opus in an ogg container
   180   { name:"test-1-mono.opus", type:"audio/ogg; codecs=opus", duration:1.044 },
   181   { name:"test-2-stereo.opus", type:"audio/ogg; codecs=opus", duration:2.925 },
   182   { name:"test-3-LCR.opus", type:"audio/ogg; codecs=opus", duration:4.214 },
   183   { name:"test-4-quad.opus", type:"audio/ogg; codecs=opus", duration:6.234 },
   184   { name:"test-5-5.0.opus", type:"audio/ogg; codecs=opus", duration:7.558 },
   185   { name:"test-6-5.1.opus", type:"audio/ogg; codecs=opus", duration:10.333 },
   186   { name:"test-7-6.1.opus", type:"audio/ogg; codecs=opus", duration:11.690 },
   187   { name:"test-8-7.1.opus", type:"audio/ogg; codecs=opus", duration:13.478 },
   189   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   191   { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
   192   { name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
   193   { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   194   // owl.mp3 as above, but with something funny going on in the ID3v2 tag
   195   // that causes DirectShow to fail.
   196   { name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.29 },
   197   // owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
   198   // that causes DirectShow to fail.
   199   { name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.29 },
   200   // One second of silence with ~140KB of ID3 tags. Usually when the first MP3
   201   // frame is at such a high offset into the file, MP3FrameParser will give up
   202   // and report that the stream is not MP3. However, it does not count ID3 tags
   203   // in that offset. This test case makes sure that ID3 exclusion holds.
   204   { name:"huge-id3.mp3", type:"audio/mpeg", duration:1.00 },
   205   // A truncated VBR MP3 with just enough frames to keep most decoders happy.
   206   // The Xing header reports the length of the file to be around 10 seconds, but
   207   // there is really only one second worth of data. We want MP3FrameParser to
   208   // trust the header, so this should be reported as 10 seconds.
   209   { name:"vbr-head.mp3", type:"audio/mpeg", duration:10.00 },
   211   // Invalid file
   212   { name:"bogus.duh", type:"bogus/duh", duration:Number.NaN }
   213 ];
   215 // A file for each type we can support.
   216 var gSnifferTests = [
   217   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
   218   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
   219   { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
   220   { name:"gizmo.mp4", type:"video/mp4", duration:5.56, size:383631 },
   221   // A mp3 file with id3 tags.
   222   { name:"id3tags.mp3", type:"audio/mpeg", duration:0.28, size:3530},
   223   { name:"bogus.duh", type:"bogus/duh" }
   224 ];
   226 // Files we must reject as invalid.
   227 var gInvalidTests = [
   228   { name:"invalid-m0c0.opus", type:"audio/ogg; codecs=opus"},
   229   { name:"invalid-m0c3.opus", type:"audio/ogg; codecs=opus"},
   230   { name:"invalid-m1c0.opus", type:"audio/ogg; codecs=opus"},
   231   { name:"invalid-m1c9.opus", type:"audio/ogg; codecs=opus"},
   232   { name:"invalid-m2c0.opus", type:"audio/ogg; codecs=opus"},
   233   { name:"invalid-m2c1.opus", type:"audio/ogg; codecs=opus"},
   234   { name:"invalid-cmap-short.opus", type:"audio/ogg; codecs=opus"},
   235   { name:"invalid-cmap-s0c0.opus", type:"audio/ogg; codecs=opus"},
   236   { name:"invalid-cmap-s0c2.opus", type:"audio/ogg; codecs=opus"},
   237   { name:"invalid-cmap-s1c2.opus", type:"audio/ogg; codecs=opus"},
   238   { name:"invalid-preskip.webm", type:"audio/webm; codecs=opus"},
   239 ];
   241 // Converts a path/filename to a file:// URI which we can load from disk.
   242 // Optionally checks whether the file actually exists on disk at the location
   243 // we've specified.
   244 function fileUriToSrc(path, mustExist) {
   245   // android mochitest doesn't support file://
   246   if (navigator.appVersion.indexOf("Android") != -1 || SpecialPowers.Services.appinfo.name == "B2G")
   247     return path;
   249   const Ci = SpecialPowers.Ci;
   250   const Cc = SpecialPowers.Cc;
   251   const Cr = SpecialPowers.Cr;
   252   var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
   253                getService(Ci.nsIProperties);
   254   var f = dirSvc.get("CurWorkD", Ci.nsILocalFile);
   255   var split = path.split("/");
   256   for(var i = 0; i < split.length; ++i) {
   257     f.append(split[i]);
   258   }
   259   if (mustExist && !f.exists()) {
   260     ok(false, "We expected '" + path + "' to exist, but it doesn't!");
   261   }
   262   return f.path;
   263 }
   265 // Returns true if two TimeRanges are equal, false otherwise
   266 function range_equals(r1, r2) {
   267   if (r1.length != r2.length) {
   268     return false;
   269   }
   270   for (var i = 0; i < r1.length; i++) {
   271     if (r1.start(i) != r2.start(i) || r1.end(i) != r2.end(i)) {
   272       return false;
   273     }
   274   }
   275   return true;
   276 }
   278 // These are URIs to files that we use to check that we don't leak any state
   279 // or other information such that script can determine stuff about a user's
   280 // environment. Used by test_info_leak.
   281 var gInfoLeakTests = [
   282   {
   283     type: 'video/ogg',
   284     src: fileUriToSrc("tests/content/media/test/320x240.ogv", true),
   285   },{
   286     type: 'video/ogg',
   287     src: fileUriToSrc("tests/content/media/test/404.ogv", false),
   288   }, {
   289     type: 'audio/x-wav',
   290     src: fileUriToSrc("tests/content/media/test/r11025_s16_c1.wav", true),
   291   }, {
   292     type: 'audio/x-wav',
   293     src: fileUriToSrc("tests/content/media/test/404.wav", false),
   294   }, {
   295     type: 'audio/ogg',
   296     src: fileUriToSrc("tests/content/media/test/bug461281.ogg", true),
   297   }, {
   298     type: 'audio/ogg',
   299     src: fileUriToSrc("tests/content/media/test/404.ogg", false),
   300   }, {
   301     type: 'video/webm',
   302     src: fileUriToSrc("tests/content/media/test/seek.webm", true),
   303   }, {
   304     type: 'video/webm',
   305     src: fileUriToSrc("tests/content/media/test/404.webm", false),
   306   }, {
   307     type: 'video/ogg',
   308     src: 'http://localhost/404.ogv',
   309   }, {
   310     type: 'audio/x-wav',
   311     src: 'http://localhost/404.wav',
   312   }, {
   313     type: 'video/webm',
   314     src: 'http://localhost/404.webm',
   315   }, {
   316     type: 'video/ogg',
   317     src: 'http://example.com/tests/content/media/test/test_info_leak.html'
   318   }, {
   319     type: 'audio/ogg',
   320     src: 'http://example.com/tests/content/media/test/test_info_leak.html'
   321   }
   322 ];
   324 // These are files that must fire an error during load or playback, and do not
   325 // cause a crash.  Put files of the same type together in this list so if
   326 // something crashes we have some idea of which backend is responsible.  Used
   327 // by test_playback_errors, which expects one error event and no ended event.
   328 // Put files of the same type together in this list so if something crashes
   329 // we have some idea of which backend is responsible.
   330 var gErrorTests = [
   331   { name:"bogus.wav", type:"audio/x-wav" },
   332   { name:"bogus.ogv", type:"video/ogg" },
   333   { name:"448636.ogv", type:"video/ogg" },
   334   { name:"bug504843.ogv", type:"video/ogg" },
   335   { name:"bug501279.ogg", type:"audio/ogg" },
   336   { name:"bug580982.webm", type:"video/webm" },
   337   { name:"bug603918.webm", type:"video/webm" },
   338   { name:"bug604067.webm", type:"video/webm" },
   339   { name:"bogus.duh", type:"bogus/duh" }
   340 ];
   342 // These are files that have nontrivial duration and are useful for seeking within.
   343 var gSeekTests = [
   344   { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   345   { name:"audio.wav", type:"audio/x-wav", duration:0.031247 },
   346   { name:"seek.ogv", type:"video/ogg", duration:3.966 },
   347   { name:"320x240.ogv", type:"video/ogg", duration:0.266 },
   348   { name:"seek.webm", type:"video/webm", duration:3.966 },
   349   { name:"bug516323.indexed.ogv", type:"video/ogg", duration:4.208333 },
   350   { name:"split.webm", type:"video/webm", duration:1.967 },
   351   { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
   352   { name:"gizmo.mp4", type:"video/mp4", duration:5.56 },
   353   { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   354   { name:"bogus.duh", type:"bogus/duh", duration:123 }
   355 ];
   357 var gFastSeekTests = [
   358   { name:"gizmo.mp4", type:"video/mp4", keyframes:[0, 1.0, 2.0, 3.0, 4.0, 5.0 ] },
   359   // Note: Not all keyframes in the file are actually referenced in the Cues in this file.
   360   { name:"seek.webm", type:"video/webm", keyframes:[0, 0.8, 1.6, 2.4, 3.2]},
   361   // Note: the sync points are the points on both the audio and video streams
   362   // before the keyframes. You can't just assume that the keyframes are the sync
   363   // points, as the audio required for that sync point may be before the keyframe.
   364   { name:"bug516323.indexed.ogv", type:"video/ogg", keyframes:[0, 0.46, 3.06] },
   365 ];
   367 function IsWindows8OrLater() {
   368   var re = /Windows NT (\d.\d)/;
   369   var winver = navigator.userAgent.match(re);
   370   return winver && winver.length == 2 && parseFloat(winver[1]) >= 6.2;
   371 }
   373 // These are files that are non seekable, due to problems with the media,
   374 // for example broken or missing indexes.
   375 var gUnseekableTests = [
   376   { name:"no-cues.webm", type:"video/webm" },
   377   { name:"bogus.duh", type:"bogus/duh"}
   378 ];
   379 // Unfortunately big-buck-bunny-unseekable.mp4 is doesn't play on Windows 7, so
   380 // only include it in the unseekable tests if we're on later versions of Windows. 
   381 // This test actually only passes on win8 at the moment.
   382 if (navigator.userAgent.indexOf("Windows") != -1 && IsWindows8OrLater()) {
   383   gUnseekableTests = gUnseekableTests.concat([
   384     { name:"big-buck-bunny-unseekable.mp4", type:"video/mp4" }
   385   ]);
   386 }
   387 // Android supports fragmented MP4 playback from 4.3.
   388 var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
   389                                   .getService(SpecialPowers.Ci.nsIPropertyBag2)
   390                                   .getProperty('version');
   391 // Fragmented MP4.
   392 if (navigator.userAgent.indexOf("Mobile") != -1 && androidVersion >= 18) {
   393   gUnseekableTests = gUnseekableTests.concat([
   394     { name:"street.mp4", type:"video/mp4" }
   395   ]);
   396 }
   398 // These are files suitable for using with a "new Audio" constructor.
   399 var gAudioTests = [
   400   { name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
   401   { name:"sound.ogg", type:"audio/ogg" },
   402   { name:"owl.mp3", type:"audio/mpeg", duration:3.29 },
   403   { name:"small-shot.m4a", type:"audio/mp4", duration:0.29 },
   404   { name:"bogus.duh", type:"bogus/duh", duration:123 }
   405 ];
   407 // These files ensure our handling of 404 errors is consistent across the
   408 // various backends.
   409 var g404Tests = [
   410   { name:"404.wav", type:"audio/x-wav" },
   411   { name:"404.ogv", type:"video/ogg" },
   412   { name:"404.oga", type:"audio/ogg" },
   413   { name:"404.webm", type:"video/webm" },
   414   { name:"bogus.duh", type:"bogus/duh" }
   415 ];
   417 // These are files suitable for testing various decoder failures that are
   418 // expected to fire MEDIA_ERR_DECODE.  Used by test_decode_error, which expects
   419 // an error and emptied event, and no loadedmetadata or ended event.
   420 var gDecodeErrorTests = [
   421   // Valid files with unsupported codecs
   422   { name:"r11025_msadpcm_c1.wav", type:"audio/x-wav" },
   423   { name:"dirac.ogg", type:"video/ogg" },
   424   // Invalid files
   425   { name:"bogus.wav", type:"audio/x-wav" },
   426   { name:"bogus.ogv", type:"video/ogg" },
   428   { name:"bogus.duh", type:"bogus/duh" }
   429 ];
   431 // These are files that are used for media fragments tests
   432 var gFragmentTests = [
   433   { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 }
   434 ];
   436 // Used by test_chaining.html. The |links| attributes is the number of links in
   437 // this file that we should be able to play.
   438 var gChainingTests = [
   439   // Vorbis and Opus chained file. They have user comments |index=n| where `n`
   440   // is the index of this segment in the file, 0 indexed.
   441   { name:"chain.ogg", type:"audio/ogg", links: 4},
   442   { name:"chain.opus", type:"audio/ogg; codec=opus", links: 4},
   443   // Those files are chained files with a different number of channels in each
   444   // part. This is not supported and should stop playing after the first part.
   445   { name:"variable-channel.ogg", type:"audio/ogg", links: 1 },
   446   { name:"variable-channel.opus", type:"audio/ogg; codec=opus", links: 1 },
   447   // Those files are chained files with a different sample rate in each
   448   // part. This is not supported and should stop playing after the first part.
   449   { name:"variable-samplerate.ogg", type:"audio/ogg", links: 1 },
   450   // Opus decoding in Firefox outputs 48 kHz PCM despite having a different
   451   // original sample rate, so we can safely play Opus chained media that have
   452   // different samplerate accross links.
   453   { name:"variable-samplerate.opus", type:"audio/ogg; codec=opus", links: 2 },
   454   // A chained video file. We don't support those, so only one link should be
   455   // reported.
   456   { name:"chained-video.ogv", type:"video/ogg", links: 1 },
   457   // A file that consist in 4 links of audio, then another link that has video.
   458   // We should stop right after the 4 audio links.
   459   { name:"chained-audio-video.ogg", type:"video/ogg", links: 4 },
   460   // An opus file that has two links, with a different preskip value for each
   461   // link. We should be able to play both links.
   462   { name:"variable-preskip.opus", type:"audio/ogg; codec=opus", links: 2 },
   463   { name:"bogus.duh", type:"bogus/duh" }
   464 ];
   466 // Videos with an aspect ratio. Used for testing that displaying frames
   467 // on a canvas works correctly in the case of non-standard aspect ratios.
   468 // See bug 874897 for an example.
   469 var gAspectRatioTests = [
   470   { name:"VID_0001.ogg", type:"video/ogg", duration:19.966 }
   471 ];
   473 // These are files with non-trivial tag sets.
   474 // Used by test_metadata.html.
   475 var gMetadataTests = [
   476   // Ogg Vorbis files
   477   { name:"short-video.ogv", tags: {
   478       TITLE:"Lepidoptera",
   479       ARTIST:"Epoq",
   480       ALBUM:"Kahvi Collective",
   481       DATE:"2002",
   482       COMMENT:"http://www.kahvi.org",
   483     }
   484   },
   485   { name:"bug516323.ogv", tags: {
   486       GENRE:"Open Movie",
   487       ENCODER:"Audacity",
   488       TITLE:"Elephants Dream",
   489       ARTIST:"Silvia Pfeiffer",
   490       COMMENTS:"Audio Description"
   491     }
   492   },
   493   { name:"bug516323.indexed.ogv", tags: {
   494       GENRE:"Open Movie",
   495       ENCODER:"Audacity",
   496       TITLE:"Elephants Dream",
   497       ARTIST:"Silvia Pfeiffer",
   498       COMMENTS:"Audio Description"
   499     }
   500   },
   501   { name:"detodos.opus", tags: {
   502       title:"De todos. Para todos.",
   503       artist:"Mozilla.org"
   504     }
   505   },
   506   { name:"sound.ogg", tags: { } },
   507   { name:"small-shot.ogg", tags: {
   508       title:"Pew SFX"
   509     }
   510   },
   511   { name:"badtags.ogg", tags: {
   512       // We list only the valid tags here, and verify
   513       // the invalid ones are filtered out.
   514       title:"Invalid comments test file",
   515       empty:"",
   516       "":"empty",
   517       "{- [(`!@\"#$%^&')] -}":"valid tag name, surprisingly"
   518       // The file also includes the following invalid tags.
   519       // "A description with no separator is a common problem.",
   520       // "雨":"Likely, but an invalid key (non-ascii).",
   521       // "not\nval\x1fid":"invalid tag name",
   522       // "not~valid":"this isn't a valid name either",
   523       // "not-utf-8":"invalid sequences: \xff\xfe\xfa\xfb\0eol"
   524     }
   525   },
   526   { name:"wave_metadata.wav", tags: {
   527       name:"Track Title",
   528       artist:"Artist Name",
   529       comments:"Comments",
   530     }
   531   },
   532   { name:"wave_metadata_utf8.wav", tags: {
   533       name:"歌曲名稱",
   534       artist:"作曲者",
   535       comments:"註解",
   536     }
   537   },
   538   { name:"wave_metadata_unknown_tag.wav", tags: {
   539       name:"Track Title",
   540       comments:"Comments",
   541     }
   542   },
   543   { name:"wave_metadata_bad_len.wav", tags: {
   544       name:"Track Title",
   545       artist:"Artist Name",
   546     }
   547   },
   548   { name:"wave_metadata_bad_no_null.wav", tags: {
   549       name:"Track Title",
   550       artist:"Artist Name",
   551       comments:"Comments!!",
   552     }
   553   },
   554   { name:"wave_metadata_bad_utf8.wav", tags: {
   555       name:"歌曲名稱",
   556       comments:"註解",
   557     }
   558   },
   559   { name:"wavedata_u8.wav", tags: { }
   560   },
   561 ];
   563 function checkMetadata(msg, e, test) {
   564   if (test.width) {
   565     is(e.videoWidth, test.width, msg + " video width");
   566   }
   567   if (test.height) {
   568     is(e.videoHeight, test.height, msg + " video height");
   569   }
   570   if (test.duration) {
   571     ok(Math.abs(e.duration - test.duration) < 0.1,
   572        msg + " duration (" + e.duration + ") should be around " + test.duration);
   573   }
   574 }
   576 // Returns the first test from candidates array which we can play with the
   577 // installed video backends.
   578 function getPlayableVideo(candidates) {
   579   var v = document.createElement("video");
   580   var resources = candidates.filter(function(x){return /^video/.test(x.type) && v.canPlayType(x.type);});
   581   if (resources.length > 0)
   582     return resources[0];
   583   return null;
   584 }
   586 function getPlayableAudio(candidates) {
   587   var v = document.createElement("audio");
   588   var resources = candidates.filter(function(x){return /^audio/.test(x.type) && v.canPlayType(x.type);});
   589   if (resources.length > 0)
   590     return resources[0];
   591   return null;
   592 }
   594 // Returns the type of element that should be created for the given mimetype.
   595 function getMajorMimeType(mimetype) {
   596   if (/^video/.test(mimetype)) {
   597     return "video";
   598   } else {
   599     return "audio";
   600   }
   601 }
   603 function removeNodeAndSource(n) {
   604   n.remove();
   605   // force release of underlying decoder
   606   n.src = "";
   607   while (n.firstChild) {
   608     n.removeChild(n.firstChild);
   609   }
   610 }
   612 // Number of tests to run in parallel. Warning: Each media element requires
   613 // at least 3 threads (4 on Linux), and on Linux each thread uses 10MB of
   614 // virtual address space. Beware!
   615 var PARALLEL_TESTS = 2;
   617 // When true, we'll loop forever on whatever test we run. Use this to debug
   618 // intermittent test failures.
   619 const DEBUG_TEST_LOOP_FOREVER = false;
   621 // Manages a run of media tests. Runs them in chunks in order to limit
   622 // the number of media elements/threads running in parallel. This limits peak
   623 // memory use, particularly on Linux x86 where thread stacks use 10MB of
   624 // virtual address space.
   625 // Usage:
   626 //   1. Create a new MediaTestManager object.
   627 //   2. Create a test startTest function. This takes a test object and a token,
   628 //      and performs anything necessary to start the test. The test object is an
   629 //      element in one of the g*Tests above. Your startTest function must call
   630 //      MediaTestManager.start(token) if it starts a test. The test object is
   631 //      guaranteed to be playable by our supported decoders; you don't need to
   632 //      check canPlayType.
   633 //   3. When your tests finishes, call MediaTestManager.finished(), passing
   634 //      the token back to the manager. The manager may either start the next run
   635 //      or end the mochitest if all the tests are done.
   636 function MediaTestManager() {
   638   // Sets up a MediaTestManager to runs through the 'tests' array, which needs
   639   // to be one of, or have the same fields as, the g*Test arrays of tests. Uses
   640   // the user supplied 'startTest' function to initialize the test. This
   641   // function must accept two arguments, the test entry from the 'tests' array,
   642   // and a token. Call MediaTestManager.started(token) if you start the test,
   643   // and MediaTestManager.finished(token) when the test finishes. You don't have
   644   // to start every test, but if you call started() you *must* call finish()
   645   // else you'll timeout.
   646   this.runTests = function(tests, startTest) {
   647     this.startTime = new Date();
   648     SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
   649     this.testNum = 0;
   650     this.tests = tests;
   651     this.startTest = startTest;
   652     this.tokens = [];
   653     this.isShutdown = false;
   654     this.numTestsRunning = 0;
   655     // Always wait for explicit finish.
   656     SimpleTest.waitForExplicitFinish();
   657     this.nextTest();
   658   }
   660   // Registers that the test corresponding to 'token' has been started.
   661   // Don't call more than once per token.
   662   this.started = function(token) {
   663     this.tokens.push(token);
   664     this.numTestsRunning++;
   665     is(this.numTestsRunning, this.tokens.length, "[started " + token + "] Length of array should match number of running tests");
   666   }
   668   // Registers that the test corresponding to 'token' has finished. Call when
   669   // you've finished your test. If all tests are complete this will finish the
   670   // run, otherwise it may start up the next run. It's ok to call multiple times
   671   // per token.
   672   this.finished = function(token) {
   673     var i = this.tokens.indexOf(token);
   674     if (i != -1) {
   675       // Remove the element from the list of running tests.
   676       this.tokens.splice(i, 1);
   677     }
   678     this.numTestsRunning--;
   679     is(this.numTestsRunning, this.tokens.length, "[finished " + token + "] Length of array should match number of running tests");
   680     if (this.tokens.length < PARALLEL_TESTS) {
   681       this.nextTest();
   682     }
   683   }
   685   // Starts the next batch of tests, or finishes if they're all done.
   686   // Don't call this directly, call finished(token) when you're done.
   687   this.nextTest = function() {
   688     // Force an exact  GC after every completed testcase. This ensures that any
   689     // decoders with live threads waiting for the GC are killed promptly, to free
   690     // up the thread stacks' address space, and destroy decoder resources.
   691     SpecialPowers.exactGC(window, function(){
   692       while (this.testNum < this.tests.length && this.tokens.length < PARALLEL_TESTS) {
   693         var test = this.tests[this.testNum];
   694         var token = (test.name ? (test.name + "-"): "") + this.testNum;
   695         this.testNum++;
   697         if (DEBUG_TEST_LOOP_FOREVER && this.testNum == this.tests.length) {
   698           this.testNum = 0;
   699         }
   701         // Ensure we can play the resource type.
   702         if (test.type && !document.createElement('video').canPlayType(test.type))
   703           continue;
   705         // Do the init. This should start the test.
   706         this.startTest(test, token);
   707       }
   709       if (this.testNum == this.tests.length &&
   710           !DEBUG_TEST_LOOP_FOREVER &&
   711           this.tokens.length == 0 &&
   712           !this.isShutdown)
   713       {
   714         this.isShutdown = true;
   715         if (this.onFinished) {
   716           this.onFinished();
   717         }
   718         mediaTestCleanup();
   719         var end = new Date();
   720         SimpleTest.info("Finished at " + end + " (" + (end.getTime() / 1000) + "s)");
   721         SimpleTest.info("Running time: " + (end.getTime() - this.startTime.getTime())/1000 + "s");
   722         SimpleTest.finish();
   723         return;
   724       }
   725     }.bind(this));
   726   }
   727 }
   729 // Ensures we've got no active video or audio elements in the document, and
   730 // forces a GC to release the address space reserved by the decoders' threads'
   731 // stacks.
   732 function mediaTestCleanup() {
   733     var V = document.getElementsByTagName("video");
   734     for (i=0; i<V.length; i++) {
   735       removeNodeAndSource(V[i]);
   736       V[i] = null;
   737     }
   738     var A = document.getElementsByTagName("audio");
   739     for (i=0; i<A.length; i++) {
   740       removeNodeAndSource(A[i]);
   741       A[i] = null;
   742     }
   743     SpecialPowers.forceGC();
   744 }
   746 (function() {
   747   // Ensure that preload preferences are comsistent
   748   var prefService = SpecialPowers.wrap(SpecialPowers.Components)
   749                                  .classes["@mozilla.org/preferences-service;1"]
   750                                  .getService(SpecialPowers.Ci.nsIPrefService);
   751   var branch = prefService.getBranch("media.");
   752   var oldDefault = 2;
   753   var oldAuto = 3;
   754   var oldAppleMedia = undefined;
   755   var oldGStreamer = undefined;
   756   var oldOpus = undefined;
   758   try { oldAppleMedia = SpecialPowers.getBoolPref("media.apple.mp3.enabled"); } catch(ex) { }
   759   try { oldGStreamer = SpecialPowers.getBoolPref("media.gstreamer.enabled"); } catch(ex) { }
   760   try { oldDefault   = SpecialPowers.getIntPref("media.preload.default"); } catch(ex) { }
   761   try { oldAuto      = SpecialPowers.getIntPref("media.preload.auto"); } catch(ex) { }
   762   try { oldOpus      = SpecialPowers.getBoolPref("media.opus.enabled"); } catch(ex) { }
   764   SpecialPowers.setIntPref("media.preload.default", 2); // preload_metadata
   765   SpecialPowers.setIntPref("media.preload.auto", 3); // preload_enough
   766   // test opus playback iff the pref exists
   767   if (oldOpus !== undefined)
   768     SpecialPowers.setBoolPref("media.opus.enabled", true);
   769   if (oldGStreamer !== undefined)
   770     SpecialPowers.setBoolPref("media.gstreamer.enabled", true);
   771   if (oldAppleMedia !== undefined)
   772     SpecialPowers.setBoolPref("media.apple.mp3.enabled", true);
   774   window.addEventListener("unload", function() {
   775     if (oldGStreamer !== undefined)
   776       SpecialPowers.setBoolPref("media.gstreamer.enabled", oldGStreamer);
   777     if (oldAppleMedia !== undefined)
   778       SpecialPowers.setBoolPref("media.apple.mp3.enabled", oldAppleMedia);
   779     SpecialPowers.setIntPref("media.preload.default", oldDefault);
   780     SpecialPowers.setIntPref("media.preload.auto", oldAuto);
   781     if (oldOpus !== undefined)
   782       SpecialPowers.setBoolPref("media.opus.enabled", oldOpus);
   783   }, false);
   784  })();

mercurial