Граф коммитов

59 Коммитов

Автор SHA1 Сообщение Дата
Andreas Pehrson 626de4fb8d Bug 1536156 - Let cloneElementVisually() return a promise that resolves when frames have been rendered. r=alwu,mconley,bzbarsky
This patch does the following:
- Makes cloneElementVisually() return a promise
- Plumbs an event from the MediaDecoderStateMachine's VideoSink to
  HTMLVideoElement
- Hooks the event up to resolve the promise from cloneElementVisually()
- Updates tests and their expectations.

Differential Revision: https://phabricator.services.mozilla.com/D53831

--HG--
extra : moz-landing-system : lando
2019-11-22 12:52:48 +00:00
Daniel Varga af05b317ec Backed out 7 changesets (bug 1597216, bug 1596777, bug 1536156) for reftest failures at reftest/bipbop_300_215kbps.mp4.lastframe.htm. On a CLOSED TREE
Backed out changeset a3fa99d936f3 (bug 1536156)
Backed out changeset 29dd64930421 (bug 1536156)
Backed out changeset 77c16444e714 (bug 1536156)
Backed out changeset d540f1802ff6 (bug 1536156)
Backed out changeset 8283eed414d2 (bug 1536156)
Backed out changeset 01d2c84810f0 (bug 1597216)
Backed out changeset e0184916cf37 (bug 1596777)
2019-11-22 01:58:42 +02:00
Andreas Pehrson 1052205963 Bug 1536156 - Let cloneElementVisually() return a promise that resolves when frames have been rendered. r=alwu,mconley,bzbarsky
This patch does the following:
- Makes cloneElementVisually() return a promise
- Plumbs an event from the MediaDecoderStateMachine's VideoSink to
  HTMLVideoElement
- Hooks the event up to resolve the promise from cloneElementVisually()
- Updates tests and their expectations.

Differential Revision: https://phabricator.services.mozilla.com/D53831

--HG--
extra : moz-landing-system : lando
2019-11-20 21:51:48 +00:00
Andreas Pehrson e324229af5 Bug 1172394 - Make dom::MediaTrack lifetime spec compliant. r=bryce
This makes us forget tracks at the right times. The spec also says no
removetrack events should be fired because of this, yet it seems to be something
other user agents do:
https://wpt.fyi/results/media-source/mediasource-avtracks.html

This is of low importance however, since MediaTracks are prefed off by default.

Differential Revision: https://phabricator.services.mozilla.com/D52038

--HG--
extra : moz-landing-system : lando
2019-11-13 22:40:12 +00:00
Csoregi Natalia 6ba30843e8 Backed out 15 changesets (bug 1500049, bug 1172394, bug 1546756, bug 1302379) for failures on browser_disabledForMediaStreamVideos.js. CLOSED TREE
Backed out changeset 355f090421a6 (bug 1500049)
Backed out changeset 306341d0b586 (bug 1302379)
Backed out changeset 3ff0d72d23a2 (bug 1546756)
Backed out changeset a4f256e68cef (bug 1172394)
Backed out changeset d0aa43657e8c (bug 1172394)
Backed out changeset edff95b6f724 (bug 1172394)
Backed out changeset 94bd21d9b396 (bug 1172394)
Backed out changeset 7e7baa73e1ef (bug 1172394)
Backed out changeset c3bd415507e8 (bug 1172394)
Backed out changeset 1c45b135318d (bug 1172394)
Backed out changeset c57c41e8c39e (bug 1172394)
Backed out changeset a796541fe5ef (bug 1172394)
Backed out changeset 89ad0b553b0f (bug 1172394)
Backed out changeset 744fb77a5833 (bug 1172394)
Backed out changeset afb4b226ff04 (bug 1172394)
2019-11-14 00:32:51 +02:00
Andreas Pehrson ed705988de Bug 1172394 - Make dom::MediaTrack lifetime spec compliant. r=bryce
This makes us forget tracks at the right times. The spec also says no
removetrack events should be fired because of this, yet it seems to be something
other user agents do:
https://wpt.fyi/results/media-source/mediasource-avtracks.html

This is of low importance however, since MediaTracks are prefed off by default.

Differential Revision: https://phabricator.services.mozilla.com/D52038

--HG--
extra : moz-landing-system : lando
2019-11-13 08:48:16 +00:00
Andreas Pehrson 9ed4e1aa58 Bug 1454998 - Move TrackInfo::mTrackId away from TrackID as they're independent. r=karlt
TrackID has been used to denote tracks that are part of MediaStreams in the
MediaStreamGraph. The TrackInfo::mTrackId IDs are no longer used in the
MediaStream APIs and as such it's not necessary that they have the type TrackID.

This patch changes TrackInfo::mTrackId to be of type uint32_t instead, as that
is the type of Mp4parseTrackInfo::track_id, which is assigned to
TrackInfo::mTrackId as the sole remaining non-static user.

Other users set a static trackId of `1` or `2`, and as such remain supported by
this change.

Differential Revision: https://phabricator.services.mozilla.com/D46763

--HG--
extra : moz-landing-system : lando
2019-10-02 10:22:46 +00:00
Gurzau Raul 40dae37e00 Backed out 7 changesets (bug 1454998) for build bustages at MediaTrackGraph.h on a CLOSED TREE.
Backed out changeset 80417bdfa721 (bug 1454998)
Backed out changeset 8ff03f2f4ca2 (bug 1454998)
Backed out changeset ae6056b748d1 (bug 1454998)
Backed out changeset ab721cb2066b (bug 1454998)
Backed out changeset d0e8d413cd1c (bug 1454998)
Backed out changeset 3ce4dc7e9ae2 (bug 1454998)
Backed out changeset 6105a4176729 (bug 1454998)

--HG--
rename : dom/media/AudioCaptureTrack.cpp => dom/media/AudioCaptureStream.cpp
rename : dom/media/AudioCaptureTrack.h => dom/media/AudioCaptureStream.h
rename : dom/media/MediaTrackGraph.cpp => dom/media/MediaStreamGraph.cpp
rename : dom/media/MediaTrackGraph.h => dom/media/MediaStreamGraph.h
rename : dom/media/MediaTrackGraphImpl.h => dom/media/MediaStreamGraphImpl.h
rename : dom/media/MediaTrackListener.cpp => dom/media/MediaStreamListener.cpp
rename : dom/media/MediaTrackListener.h => dom/media/MediaStreamListener.h
rename : dom/media/ForwardedInputTrack.cpp => dom/media/TrackUnionStream.cpp
rename : dom/media/ForwardedInputTrack.h => dom/media/TrackUnionStream.h
rename : dom/media/webaudio/AudioNodeExternalInputTrack.cpp => dom/media/webaudio/AudioNodeExternalInputStream.cpp
rename : dom/media/webaudio/AudioNodeExternalInputTrack.h => dom/media/webaudio/AudioNodeExternalInputStream.h
rename : dom/media/webaudio/AudioNodeTrack.cpp => dom/media/webaudio/AudioNodeStream.cpp
rename : dom/media/webaudio/AudioNodeTrack.h => dom/media/webaudio/AudioNodeStream.h
2019-10-02 11:46:23 +03:00
Andreas Pehrson e3f878ed79 Bug 1454998 - Move TrackInfo::mTrackId away from TrackID as they're independent. r=karlt
TrackID has been used to denote tracks that are part of MediaStreams in the
MediaStreamGraph. The TrackInfo::mTrackId IDs are no longer used in the
MediaStream APIs and as such it's not necessary that they have the type TrackID.

This patch changes TrackInfo::mTrackId to be of type uint32_t instead, as that
is the type of Mp4parseTrackInfo::track_id, which is assigned to
TrackInfo::mTrackId as the sole remaining non-static user.

Other users set a static trackId of `1` or `2`, and as such remain supported by
this change.

Differential Revision: https://phabricator.services.mozilla.com/D46763

--HG--
extra : moz-landing-system : lando
2019-10-02 08:12:09 +00:00
Andreas Pehrson 46f4203220 Bug 1507193 - Don't leave dangling js promises after seeking. r=jya
Only SeekToNextFrame cares about promises, but prior to this patch the common
method HTMLMediaElement::Seek() would always return a promise.

When the caller was not SeekToNextFrame (e.g., SetCurrentTime, FastSeek), the
promise would end up *not* being exposed. When later rejected, we would catch
this and write an error to the js console.

This patch lifts the handling of the promise out of Seek() and into
SeekToNextFrame() so that we avoid creating promises that would not get exposed
to js.

Differential Revision: https://phabricator.services.mozilla.com/D42511

--HG--
extra : moz-landing-system : lando
2019-08-29 14:30:06 +00:00
Coroiu Cristina 57a229355c Backed out changeset dd79fbdfac8d (bug 1507193) for wpt failures at media-source/mediasource-seek-beyond-duration.html on a CLOSED TREE 2019-08-28 20:40:18 +03:00
Andreas Pehrson c1e8b487e0 Bug 1507193 - Don't leave dangling js promises after seeking. r=jya
Only SeekToNextFrame cares about promises, but prior to this patch the common
method HTMLMediaElement::Seek() would always return a promise.

When the caller was not SeekToNextFrame (e.g., SetCurrentTime, FastSeek), the
promise would end up *not* being exposed. When later rejected, we would catch
this and write an error to the js console.

This patch lifts the handling of the promise out of Seek() and into
SeekToNextFrame() so that we avoid creating promises that would not get exposed
to js.

Differential Revision: https://phabricator.services.mozilla.com/D42511

--HG--
extra : moz-landing-system : lando
2019-08-28 14:57:13 +00:00
Emilio Cobos Álvarez d2ed260822 Bug 1517241 - Rename nsIDocument to mozilla::dom::Document. r=smaug
Summary: Really sorry for the size of the patch. It's mostly automatic
s/nsIDocument/Document/ but I had to fix up in a bunch of places manually to
add the right namespacing and such.

Overall it's not a very interesting patch I think.

nsDocument.cpp turns into Document.cpp, nsIDocument.h into Document.h and
nsIDocumentInlines.h into DocumentInlines.h.

I also changed a bunch of nsCOMPtr usage to RefPtr, but not all of it.

While fixing up some of the bits I also removed some unneeded OwnerDoc() null
checks and such, but I didn't do anything riskier than that.
2019-01-03 17:48:33 +01:00
Andreas Pehrson 4213b7db86 Bug 1423241 - Refactor DecodedStream. r=jya
This removes DecodedStream's use of MediaStreamListener in favor of
MediaStreamTrackListener. This change has however rippled through to a lot
more cleanup, per below.

This moves the MediaStreamTrack lifetime ownership for captured
HTMLMediaElements from the media element to DecodedStream, where the
MediaStreamGraph-side tracks are already created and ended today.

This makes MediaStreamTrack creation explicit across the entire codebase and
lets us remove the MediaStreamTrackSourceGetter class and the infrastructure
of adding MediaStreamTracks after they've already been created in the graph
from DOMMediaStream.

With track ownership, and thus TrackID allocation ownership, happening
exclusively in DecodedStream for its output tracks, we also stop throwing
away and recreating the SourceMediaStream to which we feed data on seek.
This is one step closer to fixing bug 1172394 and spec compliance of
HTMLMediaElement.captureStream().

Differential Revision: https://phabricator.services.mozilla.com/D12273

--HG--
extra : moz-landing-system : lando
2018-11-23 15:02:03 +00:00
Sylvestre Ledru 804b8b8883 Bug 1204606 - Reformat of dom/media r=jya
# skip-blame

Differential Revision: https://phabricator.services.mozilla.com/D12251

--HG--
extra : moz-landing-system : lando
2018-11-19 13:25:37 +00:00
JW Wang 1f62c1d92b Bug 1417869. P3 - pass descriptive messages to NetworkError(). r=jya
MozReview-Commit-ID: 6yaFJvXG3g8

--HG--
extra : rebase_source : 2d1c851098be7eb880a01432c504c6db96d86756
extra : source : a30f9699f49687b23d4ccf955d7a0af8ce0c7653
2017-11-17 11:07:30 +08:00
Chris Pearce 8bddf869cf Bug 1416663 - Move Gecko/HTMLMediaElement specific stuff out of VideoFrameContainer. r=jwwang
MozReview-Commit-ID: 4giNMi8qsTZ

--HG--
extra : rebase_source : 0f9e33c3704aa3925635d2290a5e18f9eebd2b74
2017-11-13 16:09:23 +13:00
Chris Pearce ed7f41cdf7 Bug 1414680 - Make MediaDecoderOwner::DispatchAsyncEvent() return void. r=jwwang
The return value is unchecked in MediaDecoder, and we only ever returned
NS_OK anyway. And we if the dispatch fails, we can't really do anything;
dispatching an "error" event probably won't work.

MozReview-Commit-ID: 67K6Mjft6tY

--HG--
extra : rebase_source : ad644e8b97fc11488983bc05e18c9941b3c5b062
2017-11-05 09:12:44 +01:00
Chris Pearce d716365ee0 Bug 1414680 - Remove IsActive() and IsHidden() from MediaDecoderOwner as they're unused by MediaDecoder. r=jwwang
MozReview-Commit-ID: 7NaPBmQJVQC

--HG--
extra : rebase_source : 0cfe05a1aefb23a4070b2855569110e7a4ab6b2c
2017-11-05 09:11:09 +01:00
JW Wang 1a47dd3c0c Bug 1397708 - remove HTMLMediaElement::mBegun. See comment 12 for the root cause. r=cpearce
When network state is changed to IDLE, mBegun is also set to false. [1]
And then when HTMLMediaElement::DownloadResumed(false) is called, network
state is not changed to LOADING for mBegun is false [2]. This prevents us
from firing 'progress' events for the network state is IDLE.

See comment 12 for more details.

[1] http://searchfox.org/mozilla-central/rev/b53e29293c9e9a2905f4849f4e3c415e2013f0cb/dom/html/HTMLMediaElement.cpp#6077
[2] http://searchfox.org/mozilla-central/rev/b53e29293c9e9a2905f4849f4e3c415e2013f0cb/dom/html/HTMLMediaElement.cpp#5673

MozReview-Commit-ID: DOfqKZXAqaz

--HG--
extra : rebase_source : 881b632447d4a78461c235fffad37595f44cc095
extra : source : 2c01d77d3a7e605bf060e17d41afa86ee0f46396
2017-10-10 07:04:18 +08:00
JW Wang 3c7ce1ac45 Bug 1394316 - provide default implementation to MediaDecoderOwner methods that involve Gecko specific types. r=cpearce
MozReview-Commit-ID: 7hhJgeYH7ys

--HG--
extra : rebase_source : bc8ad684bae13e9cd4a45ba73cea92b5214ae157
2017-08-28 14:36:00 +08:00
JW Wang f8f989dd93 Bug 1394313 - replace use of nsAutoPtr with UniquePtr in MediaDecoderOwner.h. r=cpearce
MozReview-Commit-ID: 49lyvMzg7oY

--HG--
extra : rebase_source : b83cd03b0026c73d0293ef937a3c2544349f464d
2017-08-28 14:10:35 +08:00
JW Wang c62c2c21b4 Bug 1392919. P3 - remove unused code and fix naming. r=gerald
MozReview-Commit-ID: 36PqGtOpAbf

--HG--
extra : rebase_source : 9ff9234f1f5db9151808d9a2ee33ced6d9e089c6
2017-08-23 14:42:25 +08:00
JW Wang 30093548fb Bug 1378295. P6 - remove AbstractMediaDecoder and fix includes. r=jya
MozReview-Commit-ID: xN1Ywo9VDY

--HG--
extra : rebase_source : 9aee1697b5299e43eb35450a20015c08a11bdea6
extra : intermediate-source : 3095884f04356d0d2c3c34843098a0a8b23211b8
extra : source : ef0f7e5300060b7888b961596a32a8fbf483ebd2
2017-07-13 17:39:42 +08:00
JW Wang 5cf374a225 Bug 1380569. P1 - rename CannotDecryptWaitingForKey() to NotifyWaitingForKey() and add the function to MediaDecoderOwner. r=gerald
We will use MediaEventSource to plumb the event from MFR to the media element.

MozReview-Commit-ID: 4gaEx7vYybE

--HG--
extra : rebase_source : fd595399e2db4e76ad117636768e160c2f054775
extra : intermediate-source : 1fc86c40dc83e79306c721b1acb0f31803181509
extra : source : d24b62a6041966b2639e5543c9ecccc4f7656a0d
2017-07-13 14:41:09 +08:00
Kaku Kuo b06e8a5370 Bug 1344357 P1 - move the MediaDecoder::mSeekDOMPromise to HTMLMediaElement; r=jwwang
There was a cycle amoung a window object -> a HTMLMediaElement -> a MediaDecoder -> a Promise (-> back to the window object).
And we have no way to break the cycle since the MediaDecoder does not participate into the collection.

By moving the Promise form MediaDecoder to HTMLMediaElement, we will be able to break the cycle since the HTMLMediaElement is in the collection.

We'll implement the cycle collection in the next patch.

MozReview-Commit-ID: CyVXBl6IMI3

--HG--
extra : rebase_source : 195a322ce3e6fe933e72be4aec5d2ebfa1f54865
2017-04-17 18:25:26 +08:00
Kaku Kuo 0d5f3a200f Bug 1347402 part 5 - create MediaElementGMPCrashHelper in HTMLMediaElement.cpp; r=cpearce,jwwang
Move the creation of MediaElementGMPCrashHelper out from MediaDecoder.cpp
which reduces the dependency of MediaDecoder to HTMLMediaElement.

MozReview-Commit-ID: E60aMfcFr7V

--HG--
extra : rebase_source : f50a8ee6f2fbec0bdf117eb1217066bc9c701745
extra : source : dd4e52da6d0d6205fe61d0caba44bbff008fd21a
2017-03-16 11:16:15 +08:00
Kaku Kuo b7fee84e84 Bug 1347402 part 4 - move ConstructMediaTracks/RemoveMediaTracks to HTMLMediaElemnt; r=jwwang
ConstructMediaTracks and RemoveMediaTracks are actually HTMLMediaElement's responsibilities.

MozReview-Commit-ID: 8lOdzD4pN7N

--HG--
extra : rebase_source : 7159d2c62b77429e5b2305b9e3eb7a0020a3b52c
extra : source : 0467c059be3cd8f066da5fc912b7738a5b9c4dd9
2017-03-15 17:33:21 +08:00
Kaku Kuo a71c156f34 Bug 1347402 part 2 - open a GetOwnerDoc() interface at the MediaDecoderOwner; r=jwwang
Open a GetOwnerDoc() method to the MediaDecoderOwner interface and then we can get the
owner document via a pointer to MediaDecoderOwner in MediaDecoder.

MozReview-Commit-ID: JCzQDLx1MsU

--HG--
extra : rebase_source : e194c95cb1513046ec7aa19d6c6e9f8231971a2d
extra : source : 1b9c45911a036e3677b6636cda84a636681d71de
2017-03-15 11:40:37 +08:00
Gerald Squelart 418963d5c8 Bug 1343161 - MediaDecoderOwner::DecodeWarning and HTMLMediaElement implementation - r=jya
Similar to DecodeError, except we allow decoding to continue.

MozReview-Commit-ID: FN9m03o6GXV

--HG--
extra : rebase_source : a6ca0cc28d2990ab143676758cd880baaca7bcb7
2017-02-27 12:12:37 +11:00
JW Wang f40aaeaffc Bug 1336356 - Ensure MediaDecode::Shutdown() is called by MediaShutdownManager::BlockShutdown(). r=gerald
MozReview-Commit-ID: 80AFMafXoeB

--HG--
extra : rebase_source : 8b51b6c9fe4b83b4639c7ae081854307c4308391
extra : source : 7ca33be035c12485e0d6529c529b0cda914fd405
2017-02-03 17:12:38 +08:00
Bevis Tseng f2bdbd8fd1 Bug 1314833 - Part 2.1: Factor out AbstractThread::MainThread() used in Media Playback. r=billm,jwwang
MozReview-Commit-ID: 9yJi3iDtVZG

--HG--
extra : rebase_source : 39c720ccc576ed9247b5e8abb70d99d7873b3ad6
2016-11-29 13:03:36 +08:00
James Cheng 48efb9caad Bug 1300654 Part1-Remove MOZ_EME from code base. r=cpearce,smaug
MozReview-Commit-ID: JboGO0w4tcE

--HG--
extra : rebase_source : abfe53f30081f74fc39c900cab48d08c7574bfec
2016-09-08 18:06:20 +08:00
Jean-Yves Avenard 6a25692b20 Bug 1299072: P10. Pass decoding error details to media element's error attribute. r=jwwang
MozReview-Commit-ID: 49DurV9WI5S

--HG--
extra : rebase_source : 469e6ed4e222fb6d6ac34843c3c3346a044c6023
2016-09-11 00:56:09 +10:00
bechen 931402dd2f Bug 1291629 - Remove RTSP code. r=jwwang
MozReview-Commit-ID: AxaLwO4rTuY

--HG--
extra : rebase_source : f8a5de1be1471238d62b6bbc419b3a45f2590da6
2016-08-10 10:32:25 +08:00
JW Wang 65db31d2a5 Bug 1289649 - HTMLMediaElement should clear mDecoder when XPCOM shutdown begins. r=gerald
MozReview-Commit-ID: A3ECReCgiD7

--HG--
extra : rebase_source : 452e156b9ecb449f311bd47f0afcc3a4bd03e10e
2016-07-27 10:26:21 +08:00
JW Wang 8e6ae76d98 Bug 1289334 - HTMLMediaElement::ResetConnectionState() should shut down the decoder. r=cpearce
MozReview-Commit-ID: 7IZ2Y4Da7xZ

--HG--
extra : rebase_source : 492b0caa52fca17d2c399c2f0e2c426c6f55872f
2016-07-26 16:37:45 +08:00
JW Wang a2a7e29ce7 Bug 1289301 - Remove the call to Shutdown() from MediaDecoder::NetworkError(). r=cpearce
MozReview-Commit-ID: EuDKW2KZQ9n

--HG--
extra : rebase_source : 7330327d6194a6fa45905d1ff52d258e58b96a4b
2016-07-26 14:33:16 +08:00
JW Wang 4d7a72bc94 Bug 1289295 - Remove the call to Shutdown() from MediaDecoder::DecodeError(). r=cpearce
MozReview-Commit-ID: DcpaEFEsaWD

--HG--
extra : rebase_source : fd63ff2faa79911b9ccfeed55d9e7348674ed1dc
2016-07-26 14:18:47 +08:00
Jonathan Watt b15368cfcb Bug 1279451 - Remove a lot of unnecessary includes of nsAutoPtr.h. rs=sparky 2016-06-07 21:10:18 +01:00
Alastor Wu 9771068fea Bug 1235612 - Part 5: Rename NotifyAudibleStateChanged. r=jwwang
MozReview-Commit-ID: LRikTbqoOch

--HG--
extra : rebase_source : 1d69b9d55c232d2723cf9f7159087ec6795b6e19
2016-05-03 17:59:43 +08:00
Jean-Yves Avenard 722e4fee21 Bug 1246521: P1. Add MediaDecoderOwner::HasError method. r=gerald 2016-02-08 16:31:42 +11:00
Alastor Wu abde274a94 Bug 1238906 - part2 : notify audible state from MDSM to ME. r=jwwang
--HG--
extra : rebase_source : 74629c314b3d828a5d9b514bf6cca87f7c1f57de
2016-01-21 10:27:38 +08:00
Sebastian Hengst 9249e58bdf Backed out 2 changesets (bug 1238906) for bustage in M(2) on OSX and Windows. r=bustage
Backed out changeset e729b30ba7b4 (bug 1238906)
Backed out changeset 1857bca40ac4 (bug 1238906)
2016-01-18 13:11:43 +01:00
Alastor Wu bbcb84cc7b Bug 1238906 - part2 : notify audible state from MDSM to ME. r=jwwang
--HG--
extra : transplant_source : %A6I%CA%AC%95%AD%0C%7D%40K%8C_%8B%3D%15%BC%F7%FB%86%27
2016-01-18 10:50:47 +08:00
Andrea Marchesini f44bf80ff9 Bug 1213154 - tab-sound-icon should be supported by bfcache, r=roc 2015-11-23 11:35:14 +00:00
Birunthan Mohanathas a8939590de Bug 1182996 - Fix and add missing namespace comments. rs=ehsan
The bulk of this commit was generated by running:

  run-clang-tidy.py \
    -checks='-*,llvm-namespace-comment' \
    -header-filter=^/.../mozilla-central/.* \
    -fix
2015-07-13 08:25:42 -07:00
Bobby Holley 7ed6ae7327 Bug 1159558 - Redesign watching to use a manager. r=jww 2015-04-30 12:46:40 -07:00
Bobby Holley fbc2c98020 Bug 1144481 - Use state mirroring for NextFrameStatus. r=jww 2015-04-23 11:55:14 -07:00
Gerald Squelart 9c87262f4f Bug 1144409 - Encrypted event should be fired once per initData. r=cpearce 2015-04-01 03:36:00 -04:00