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

81 Коммитов

Автор SHA1 Сообщение Дата
Andreas Pehrson 649925ecff Bug 1500049 - Wait for MediaCacheStreams to close properly before finishing MediaDecoder shutdown. r=bryce
Differential Revision: https://phabricator.services.mozilla.com/D52052

--HG--
extra : moz-landing-system : lando
2019-11-13 22:40:14 +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 4c3bf72271 Bug 1500049 - Wait for MediaCacheStreams to close properly before finishing MediaDecoder shutdown. r=bryce
Differential Revision: https://phabricator.services.mozilla.com/D52052

--HG--
extra : moz-landing-system : lando
2019-11-13 08:58:34 +00:00
Tarek Ziadé c48befbb9c Bug 1542674 - Make Media debug info machine parsable r=padenot,smaug,jya
This patch structurizes the media debug information via webidl dictionaries
that are returned by HTMLMediaElement::GetMozRequestDebugInfo() and
MediaSource::GetMozDebugReaderData().

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

--HG--
extra : moz-landing-system : lando
2019-05-27 16:15:33 +00:00
shindli 9134ad98fa Backed out changeset c386ebfd9c6b (bug 1542674) as per tarek's request on IRC 2019-05-07 15:07:27 +03:00
Tarek Ziadé 446d5cdff7 Bug 1542674 - Make Media debug info machine parsable r=padenot,smaug
This patch structurizes the media debug information via webidl dictionaries
that are returned by HTMLMediaElement::GetMozRequestDebugInfo() and
MediaSource::GetMozDebugReaderData().

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

--HG--
extra : moz-landing-system : lando
2019-05-06 16:39:58 +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
Andi-Bogdan Postelnicu 60732a90a5 Bug 1453795 - DOM/Media - Initialize member fields in classes/ structures. r=jyavenard
--HG--
extra : rebase_source : 0c785260497fadf98cf3cff8b9fcae8ea699c2c1
2018-06-15 10:25:02 +03:00
Jean-Yves Avenard 15d6ce1610 Bug 1450607 - P3. Remove unused argument. r=gerald
MozReview-Commit-ID: 6NU9BLJi6kl

--HG--
extra : rebase_source : a9fca396ca5c353be979196dde4b1b02137cc9ca
2018-05-24 17:38:02 +02:00
Jean-Yves Avenard f1f3bc2758 Bug 1450607 - P2. Synchronously seek to prepare for resuming following stop request. r=gerald
Bug 1415090 attempted to remove the need to access from the MediaResource members of MediaCacheStream from the main thread.
However, by doing so the logic flow for resuming the channel changed from a synchronous access to an asynchronous one.
This changed some assumptions and allowed the ChannelMediaResource to be used before the Seek call completed.

For now, re-add a cross thread access to the MediaCacheStream. A more elegant fix will be worked on in bug 1464045

MozReview-Commit-ID: 2xBTjDEqrkI

--HG--
extra : rebase_source : 0aa3cfcb8371d5147cbed746d9200dd22df4821b
2018-05-24 14:36:58 +02:00
Jean-Yves Avenard 1d73f87b45 Bug 1450607 - P1. Fix constness. r=gerald
MozReview-Commit-ID: CeftB0qmzTf

--HG--
extra : rebase_source : 7d8a75754990fd6cab1ad8f620d5d5675c46ea88
2018-05-23 21:27:31 +02:00
Sebastian Hengst 0819f35e51 Backed out 4 changesets (bug 525063) on request from Andi. a=backout
Backed out changeset 516c4fb1e4b8 (bug 525063)
Backed out changeset 6ff8aaef2866 (bug 525063)
Backed out changeset bf13e4103150 (bug 525063)
Backed out changeset d7d2f08e051c (bug 525063)
2018-04-13 16:01:28 +03:00
Tristan Bourvon a3a77c0312 Bug 525063 - Initialize uninitialized class attributes in m-c. r=ehsan 2018-04-10 21:11:02 +02:00
JW Wang 5f75454142 Bug 1428242. P3 - use a non-reentrant monitor. r=bechen,gerald
MozReview-Commit-ID: GCXBHugTLJV

--HG--
extra : rebase_source : 099334dd48b7aa2817578f618d3ab12e1b01cf8f
2018-01-05 10:49:38 +08:00
JW Wang ea7483e4ce Bug 1426578. P4 - offload InitAsClone() to another thread. r=bechen,gerald
MozReview-Commit-ID: H8bQRmkJ8jU

--HG--
extra : rebase_source : a6fd3ec4d48974a36c0eec24503d10258ed5f5d4
extra : source : 2ffac43de24706551d3e183072d4e53c137ecb5f
2017-12-19 17:32:55 +08:00
JW Wang e43ca27ba0 Bug 1426578. P3 - make MediaCacheStream::InitAsClone() infallible. r=bechen,gerald
It must be infallible for there is no way to propagate the error back to the
main thread when part of the init functions run on another thread. It is OK to
clone a stream that ends abnormally as long as we don't copy the error status
of EOS. The cloned stream will open a new channel when necessary.

Note we also copy the partial block from the original stream to get as much
data as possible and thus reducing the chance of reopening the channel.

MozReview-Commit-ID: 37iYQonFdBU

--HG--
extra : rebase_source : 6bb9983bc8d1f2675557a14acf1824dba4a98fff
extra : intermediate-source : a20ff9a873db93c85750bb2af5bf05c27c9da3c3
extra : source : 0763fb0e7b4ed1096e406dadccb3ca698f39b207
2017-12-16 23:50:07 +08:00
JW Wang 61603d61fe Bug 1426061. P2 - offload MediaCacheStream::Close() to another thread. r=bechen,gerald
So we won't take the cache lock on the main thread.

MozReview-Commit-ID: KYSB0vonOZ2

--HG--
extra : rebase_source : 142884bb450a5469b2634a676ce2d4f3c1790954
extra : intermediate-source : 0911c55511374cd19719743531c136fc122e4ab0
extra : source : 2f46a7eddea484fc5dec773d9d57896e524e014d
2017-12-15 10:29:29 +08:00
JW Wang 32de19ef80 Bug 1426061. P1 - always access MediaCacheStream::mClosed while holding the lock. r=bechen,gerald
We will offload MediaCacheStream::Close() to another thread and need to access
mClosed off the main thread.

MozReview-Commit-ID: 891rzC8dOON

--HG--
extra : rebase_source : 5cf18c4cdfe32dcc1894d5849b74a16582dcde51
extra : intermediate-source : 77febb3f2ca53cd5bb4834b110a4ff44a21556b0
extra : source : b4513de1038e6413477d09ef531f076ecb3955b3
2017-12-14 16:22:53 +08:00
JW Wang 37e466a4bf Bug 1426056. P2 - remove unused members. r=bechen,gerald
MozReview-Commit-ID: 6CjxrFzutkP

--HG--
extra : rebase_source : b9c9a858e08ea0aa35c074ac7734d62b1d8fe219
extra : intermediate-source : ce131c8c66ef1dc89c69fd0e2332b838419a3cc3
extra : source : e6ece8e702100d23540caf9fbcfea561dcb3e172
2017-12-07 15:45:15 +08:00
JW Wang 313522ae1f Bug 1426056. P1 - move the decision of resuming download to another thread. r=bechen,gerald
So we won't access mStreamLength/mChannelOffset (which are protected by the
cache monitor) on the main thread.

MozReview-Commit-ID: 2pKEttZOfB9

--HG--
extra : rebase_source : a683d7297e241f2aeaf60ba9ad558763d17ee094
extra : intermediate-source : 0a6c10e10d1e558b19799b720935bbdaa56728bf
extra : source : 282de2a9189e5e05f5f817174ebcffe1b592bb1a
2017-12-07 15:43:36 +08:00
JW Wang a6dc3c33c1 Bug 1425170. P2 - remove unused members. r=bechen,gerald
MozReview-Commit-ID: TJZzVuEI8J

--HG--
extra : rebase_source : 3f6208a74c2a2d88373936a3dc4ee5c873fc297a
2017-12-14 10:19:41 +08:00
Gerald Squelart 1b357db99b Bug 1407810 - Use DDLogger in media stack - r=jwwang
Mostly-mechanical additions:
- Log constructions&destructions, usually by just inheriting from
  DecoderDoctorLifeLogger, otherwise with explicit log commands (for internal
  classes for which DecoderDoctorTraits can't be specialized),
- Log links between most objects, e.g.: Media element -> decoder -> state
  machine -> reader -> demuxer -> resource, etc.

And logging some important properties and events (JS events, duration change,
frames being decoded, etc.)

More will be added later on, from just converting MOZ_LOGs, and as needed.

MozReview-Commit-ID: KgNhHSz35t0

--HG--
extra : rebase_source : dd7206e350e32671adc6f3b9e54ebf777251de2c
2017-10-10 17:55:27 +11:00
JW Wang 0d7066652a Bug 1421864 - move mChannelStatistics from ChannelMediaResource to MediaCacheStream. r=bechen,gerald
So it is callable from non-main thread.

MozReview-Commit-ID: atYmz4u2c9

--HG--
extra : rebase_source : 2e10064730b3e7e1ecb1a4fd65cf2e2da0390290
extra : source : 5680a6942f6985f9c6bbf284a9768ab910b37804
2017-11-29 16:49:54 +08:00
JW Wang 1ae4603e61 Bug 1421134. P1 - default MediaCacheStream::mCurrentMode to MODE_METADATA. r=bechen,gerald
We always read metadata when decoding starts. This allows us to remove the call
to mResource->SetReadMode(MediaCacheStream::MODE_METADATA) in ChannelMediaDecoder::Load().

MozReview-Commit-ID: AQMq4HxDZdT

--HG--
extra : rebase_source : 141c43bb93f274d8320a270b5c7289bd1eab134d
extra : source : 7de3d88ddb5c99352f4b5bd0b5e648a52a4a67a5
2017-11-28 10:43:50 +08:00
JW Wang 99bc08968c Bug 1420798 - apply the 'ProofOfLock' pattern to MediaCache. r=bechen,gerald
See comment 0 for the detail.

We will replace ReentrantMonitor with Monitor in the future.

MozReview-Commit-ID: 63ygEFWXHZd

--HG--
extra : rebase_source : 71d1049663e5af5ca178402f84fabdc4ab0f8758
extra : intermediate-source : 20d349df7c16227b6fa1cd3c1d38b1065c93da8c
extra : source : 9cdcfd446686eace7258d18262d8dd92c0f70331
2017-11-22 17:14:02 +08:00
JW Wang 106e488634 Bug 1418918. P1 - remove unused FlushPartialBlock(). r=bechen,gerald
MozReview-Commit-ID: GSda1KfPWXE

--HG--
extra : rebase_source : 8bb0b962e6fec586dd68587d6e43b542d37f6a2d
extra : intermediate-source : d58472fa128100ed3bbc8e07d4e72ac7cc5bfe09
extra : source : e3925d43d873e20ad95a48550f271b832f852b7d
2017-11-20 16:00:22 +08:00
JW Wang e672887f6f Bug 1418917. P1 - run some functions off the main thread. r=bechen,gerald
MozReview-Commit-ID: Fn9OveV69hX

--HG--
extra : rebase_source : 36ed72bea695f07694d83c418ba45d89cf1f03be
extra : intermediate-source : e25c80e8ea6991b4f06bc4305b602c792a5b1e8a
extra : source : d20765cfa8575943c62b933563e36ee9ffa4e765
2017-11-16 15:41:36 +08:00
JW Wang a920cf49b3 Bug 1418219 - merge NotifyDataLength() and NotifyDataStarted(). r=bechen,gerald
MozReview-Commit-ID: g857eQ4YVK

--HG--
extra : rebase_source : 45e71baa300772442bba43f39eacefb571a523c9
extra : intermediate-source : d674e5a676212dae59b12e8173802be40de77bf7
extra : source : 21f73b0a0e59b7575794b317719abe7a39a984e0
2017-11-16 12:05:19 +08:00
JW Wang b3feb3794f Bug 1415090. P5 - remove MediaCacheStream::NotifyChannelRecreated(). r=bechen,gerald
NotifyDataEnded() runs off the main thread which might set mChannelEnded
wrongly after NotifyChannelRecreated reset it on the main thread.

We should reset the flags in NotifyDataStarted() which indicate a new load has begun.

MozReview-Commit-ID: Gi6PFXwMJqc

--HG--
extra : rebase_source : 85bb2c25a55cce4b3c3f023bf4c02fe5d1de7552
extra : source : 2f8c5518bf615f9190f87032568fc53037bc6fc1
2017-11-16 14:50:49 +08:00
JW Wang 187b5299fb Bug 1415090. P3 - run MediaCacheStream::NotifyDataEnded() off the main thread. r=bechen,gerald
Since NotifyDataEnded() run its code asynchronously, it is possible that a new
channel is created and NotifyDataStarted() is called before NotifyDataEndedInternal()
has a chance to run. We check the load ID to exit the function if necessary.

We also need to fix data races when running NotifyDataEndedInternal() off the
main thread in next patches.

MozReview-Commit-ID: IIAc7dxHike

--HG--
extra : rebase_source : 58e45f924058a986b8d86bfaeff2791ee8a5f4bc
extra : intermediate-source : b2a7fa7514723e214b8da40cfc0ec40b1de9a345
extra : source : 1ff93dc8f8c451b804133c780cedef2ee3d348e5
2017-11-10 15:06:39 +08:00
JW Wang 54de8d43d3 Bug 1415090. P2 - move the "reopen on error" code from ChannelMediaResource::OnStopRequest() to MediaCacheStream::NotifyDataEnded(). r=bechen,gerald
MozReview-Commit-ID: BA1tSk6ZqPS

--HG--
extra : rebase_source : 7434d1052be71bdb3cd24f430081fe57e86c4c6d
extra : intermediate-source : eef8f69c9c0f6e50d20ae9c7e46396d597eef425
extra : source : 95f24d107ce05b1b69e5a5f269c50670c7a31bf1
2017-11-10 14:40:22 +08:00
JW Wang 5a99c6b197 Bug 1417774 - remove unused MediaResource::Tell(). r=bechen
MozReview-Commit-ID: 3qlP4sSh9kM

--HG--
extra : rebase_source : 4002fec6f8c43abb640f9206cd715f3ecb02b373
2017-11-15 17:18:52 +08:00
JW Wang ecbca6c33e Bug 1416643. P2 - always access mDidNotifyDataEnded within the lock. r=bechen,gerald
MozReview-Commit-ID: 3us659lCEZE

--HG--
extra : rebase_source : 9deace7a2e83ae42132f593bb7c638c5e2977638
2017-11-15 15:24:26 +08:00
JW Wang b88c401e49 Bug 1416643. P1 - remove checks for mDidNotifyDataEnded/mNotifyDataEndedStatus from IsAvailableForSharing(). r=bechen,gerald
We will need to modify these members off the main thead while IsAvailableForSharing()
is a main thread only function.

InitAsClone() will return an error if the original stream ends abnormally.

MozReview-Commit-ID: 1qRyboca2YZ

--HG--
extra : rebase_source : 4617a911a1de052833bd0085b883a8ae4d639c7d
2017-11-15 15:14:21 +08:00
JW Wang 3f7e23ff46 Bug 1416085 - use Span<> to replace low level pointer arithmetic in Read(). r=bechen,gerald
MozReview-Commit-ID: 6l7cG2Xn0R7

--HG--
extra : rebase_source : ce80c480f03cfbe170a7c5340cbac526aa4f7a23
extra : intermediate-source : f02f1542258668ea47203a51f807ece6429f0ace
extra : source : 28c38703128e47ee7808e68550d7fca9b2558d0a
2017-11-03 16:56:58 +08:00
JW Wang 1e7878c69a Bug 1415069 - Add a member to ChannelMediaResource to remember seekability of the channel. r=bechen,gerald
So it doesn't need to call mCacheStream.IsTransportSeekable() which needs to
take the lock and might block the main thread.

MozReview-Commit-ID: 99QVcSxzjCz

--HG--
extra : rebase_source : be71b065ce0334987efbfb67a5cf010ab0373d80
extra : source : 2de3f0baf1475e8ae3228a33cf4cf139cf923c37
2017-11-07 14:26:10 +08:00
JW Wang c51610e0e4 Bug 1415766. P2 - move Seek() to private and tighten up some assertions. r=bechen,gerald
MozReview-Commit-ID: BBsXqKUrOi1

--HG--
extra : rebase_source : 1b785f50254ba824037b983896fc40e91eff801a
extra : intermediate-source : 6971ed66e78c4e1956bf0e382a04c1c8816dbaf8
extra : source : 6590c3f4691e9730858689839a5eb7b7143ceafb
2017-11-02 14:46:24 +08:00
JW Wang cd5164d38d Bug 1415766. P1 - we never pass anything other than NS_SEEK_SET to Seek(). r=bechen,gerald
MozReview-Commit-ID: AgvapCwwSpr

--HG--
extra : rebase_source : 2ba05b44f228c3d9a9440202c024abbd5487282f
extra : intermediate-source : f2ec0fec7c544171e7567beed322349dfb8e59a8
extra : source : 8e34a87b250f800897a761d2ccd408959007d02b
2017-11-02 14:26:24 +08:00
JW Wang f9f14101f3 Bug 1415397 - use Span<> to replace low level pointer arithmetic in ReadFromCache(). r=bechen,gerald
MozReview-Commit-ID: HH6KXtMfSIJ

--HG--
extra : rebase_source : 4d08fa14e2e218ad3e6b45ef240f3ced75321bd4
extra : intermediate-source : 6c2577bd71024ad031a86836c9c604bfef726b5a
extra : source : 1f0e76b45b7d89bcc10d59e302fe4b08e87cc96c
2017-11-02 11:36:56 +08:00
Sebastian Hengst c99d035f00 Backed out changeset 3e95c596ad5b (bug 1415397) because backed out (bug 1412737 depended on it. a=backout on a CLOSED TREE 2017-11-08 19:31:20 +02:00
JW Wang f53f02fb3e Bug 1415397 - use Span<> to replace low level pointer arithmetic in ReadFromCache(). r=bechen,gerald
MozReview-Commit-ID: HH6KXtMfSIJ

--HG--
extra : rebase_source : a6fe803e3e89a0f89c225e2415a233a945a6a716
extra : intermediate-source : 8c37409d77f675c89fd9b2fb276aa80c57d4eb7f
extra : source : 1f0e76b45b7d89bcc10d59e302fe4b08e87cc96c
2017-11-02 11:36:56 +08:00
JW Wang 605a0bdc18 Bug 1414709 - use Span<> to replace low level pointer arithmetic in MediaCacheStream::NotifyDataReceived(). r=bechen,gerald
MozReview-Commit-ID: KIwws0qiCVK

--HG--
extra : rebase_source : 3e50c2047703b01f006cfec65c4b0667b47906af
extra : intermediate-source : fbb2cf22b5028b57762ce7e7e9f56526ad5e9727
extra : source : 4bfb8f2ed2afb6f74cae0caf34dd34b0a818a45a
2017-11-01 23:20:11 +08:00
JW Wang 0dc60230e2 Bug 1411808. P3 - InitAsClone() shouldn't call |mMediaCache->OpenStream(this)| until initialization is done. r=gerald
We don't want MediaCache to use a half-initialized stream.

MozReview-Commit-ID: LjPLOYwy0Wd

--HG--
extra : rebase_source : a52a23fc6dce2a87ef2829254dcabe8176b2c28c
extra : intermediate-source : eb9c3d068ff4c3496831d80398012daebe8a5d52
extra : source : d980eb79f7a5219651ef710630cdf6dc3bd96195
2017-10-26 11:13:38 +08:00
JW Wang 68005e8e16 Bug 1411808. P2 - don't call mClient->IsSuspended() off the main thread in Update(). r=gerald
By mirroring the suspend status of the client, Update() is able to make
decisions on reading streams without calling mClient->IsSuspended().

MozReview-Commit-ID: G4gS2VGiMjj

--HG--
extra : rebase_source : bcdc1010fce47965c999df61666983c87e189670
extra : intermediate-source : 9dd8cfb80e29677e8cae866b2326dfb0aec5b6ae
extra : source : d20f640bf99478c9ba581e4979ec8091ef94e0f3
2017-10-24 11:25:41 +08:00
JW Wang 8715833c55 Bug 1411504. P7 - don't change mChannelOffset in MediaCache::Update(). r=gerald
This is a fix to P3.

Since seek is performed asynchronously by CacheClientSeek(), it is possible
for OnStopRequest() to come before Seek(). Changing mChannelOffset will
cause MediaCacheStream::NotifyDataEnded() to update mStreamLength incorrectly.

mChannelOffset should only be changed in response to channel activities such
as NotifyDataStarted() and NotifyDataReceived().

However, if MediaCache::Update() calls CacheClientSeek() without updating
mChannelOffset, next Update() might make a wrong decision and call CacheClientSeek()
again which is bad. So we add a member mSeekTarget to track if there is a pending
seek on which the stream reading decisions will be made.

MozReview-Commit-ID: VWP0vdlEYM

--HG--
extra : rebase_source : ea0d85bcbcc5d14f1554ebff3d10981a5b17e18a
extra : source : 339b9323b583849ac88e39da19670f6b26772877
2017-10-25 09:37:58 +08:00
JW Wang c4b8566c71 Bug 1411504. P2 - merge NotifyDataStarted() and SetTransportSeekable(). r=gerald
SetTransportSeekable() is always called after NotifyDataStarted().
This is slightly more efficient for we don't acquire the lock twice.

MozReview-Commit-ID: 9myolomriIQ

--HG--
extra : rebase_source : f33c3be978edacf45d8144af43f45c8ad5e7b53e
extra : source : 2cefaeb1adae7238b77d5e2d1287ae0d96d9f671
2017-10-23 17:00:57 +08:00
JW Wang da256ca76e Bug 1411476. P5 - dump debug info for ChannelMediaResource. r=gerald
MozReview-Commit-ID: GjdtrlNb948

--HG--
extra : rebase_source : 248f4926435118ddc8baa0f901c5e4ec3f699c64
2017-10-25 13:57:39 +08:00
JW Wang b2cbe2833f Bug 1405962. P1 - give MediaCache a thread on which we will run data callbacks from the HTTP channel. r=gerald
MozReview-Commit-ID: Av7bFGx9SW

--HG--
extra : rebase_source : 296a6137ee63328e11eb11a8ee3430979cf8e5a8
extra : intermediate-source : 9634a9cd63e188799fe691cfe7108a173db503d5
extra : source : 43860a593eb810088adac150c0fa85cf8133ce17
2017-09-13 16:51:12 +08:00
JW Wang 23e496f3ed Bug 1404771. P3 - constify some members and fix comments. r=gerald
MozReview-Commit-ID: CMJgmY9Al0k

--HG--
extra : rebase_source : 4bacbc52a0bab984d43802c0a93078297423eaf5
extra : intermediate-source : e19cd1f94a3f876cf9763e4296ca8f145897040f
extra : source : 7da3a65c6620166a88367dc6d1f92184fa07f515
2017-09-20 16:43:19 +08:00
JW Wang ad01d1a091 Bug 1404771. P2 - always access mThrottleReadahead within the lock. r=gerald
So it is easier to run Update() loops off the main thread in the future.

MozReview-Commit-ID: LdxzQf6B3GK

--HG--
extra : rebase_source : 157984edf8ea08270fe61376e67183715b5bd4d4
extra : intermediate-source : f4045ce626977d392c799fae8f3d4f19efe3039f
extra : source : 778256b7055f4a470889eeae063660595d34337f
2017-09-20 16:37:32 +08:00