Reason for revert:
Reverting while we track down the issue on the Win10 bot.
Original issue's description:
> Split IncomingVideoStream into two implementations, with smoothing and without.
>
> This CL fixes an issue with the non-smoothing implementation where frames were delivered on the decoder thread. No-smoothing is now done in a separate class that uses a TaskQueue. The implementation may drop frames if the renderer doesn't keep up and it doesn't block the decoder thread.
>
> Further work done:
>
> * I added TODOs and documentation for VideoReceiveStream::OnFrame, where we today grab 5 locks.
>
> * I removed the Start/Stop methods from the IncomingVideoStream implementations. Now, when an instance is created, it should be considered to be "running" and when it is deleted, it's "not running". This saves on resources and also reduces the amount of locking required and I could remove one critical section altogether.
>
> * I changed the VideoStreamDecoder class to not depend on IncomingVideoStream but rather use the generic rtc::VideoSinkInterface<VideoFrame> interface. This means that any implementation of that interface can be used and the decoder can be made to just use the 'renderer' from the config. Once we do that, we can decouple the IncomingVideoStream implementations from the decoder and VideoReceiveStream implementations and leave it up to the application for how to do smoothing. The app can choose to use the Incoming* classes or roll its own (which may be preferable since applications often have their own scheduling mechanisms).
>
> * The non-smoothing IncomingVideoStream implementation currently allows only 1 outstanding pending frame. If we exceed that, the current frame won't be delivered to the renderer and instead we deliver the next one (since when this happens, the renderer is falling behind).
>
> * The lifetime of the VideoStreamDecoder instance is now bound to Start/Stop in VideoReceiveStream and not all of the lifetime of VideoReceiveStream.
>
> * Fixed VideoStreamDecoder to unregister callbacks in the dtor that were registered in the ctor. (this was open to a use-after-free regression)
>
> * Delay and callback pointers are now passed via the ctors to the IncomingVideoStream classes. The thread primitives in the IncomingVideoStream classes are also constructed/destructed at the same time as the owning object, which allowed me to remove one more lock.
>
> * Removed code in the VideoStreamDecoder that could overwrite the VideoReceiveStream render delay with a fixed value of 10ms on construction. This wasn't a problem with the previous implementation (it would be now though) but seemed to me like the wrong place to be setting that value.
>
> * Made the render delay value in VideoRenderFrames, const.
>
> BUG=
>
> Committed: https://crrev.com/1c7eef652b0aa22d8ebb0bfe2b547094a794be22
> Cr-Commit-Position: refs/heads/master@{#13129}
TBR=mflodman@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=
Review-Url: https://codereview.webrtc.org/2061363002
Cr-Commit-Position: refs/heads/master@{#13146}
Added the plumbing necessary to get two different lists of codecs from
WebRtcVoiceEngine up to MediaSessionDescriptionFactory.
This should be the last step in this set of CLs. Once
https://codereview.webrtc.org/1991233004/ has landed, it's possible to
implement the ReceiveCodecs getter with the info from the
AudioDecoderFactory. The factory needs to be updated to actually
produce the correct list, as well.
BUG=webrtc:5805
Review-Url: https://codereview.webrtc.org/2013053002
Cr-Commit-Position: refs/heads/master@{#13131}
This CL fixes an issue with the non-smoothing implementation where frames were delivered on the decoder thread. No-smoothing is now done in a separate class that uses a TaskQueue. The implementation may drop frames if the renderer doesn't keep up and it doesn't block the decoder thread.
Further work done:
* I added TODOs and documentation for VideoReceiveStream::OnFrame, where we today grab 5 locks.
* I removed the Start/Stop methods from the IncomingVideoStream implementations. Now, when an instance is created, it should be considered to be "running" and when it is deleted, it's "not running". This saves on resources and also reduces the amount of locking required and I could remove one critical section altogether.
* I changed the VideoStreamDecoder class to not depend on IncomingVideoStream but rather use the generic rtc::VideoSinkInterface<VideoFrame> interface. This means that any implementation of that interface can be used and the decoder can be made to just use the 'renderer' from the config. Once we do that, we can decouple the IncomingVideoStream implementations from the decoder and VideoReceiveStream implementations and leave it up to the application for how to do smoothing. The app can choose to use the Incoming* classes or roll its own (which may be preferable since applications often have their own scheduling mechanisms).
* The non-smoothing IncomingVideoStream implementation currently allows only 1 outstanding pending frame. If we exceed that, the current frame won't be delivered to the renderer and instead we deliver the next one (since when this happens, the renderer is falling behind).
* The lifetime of the VideoStreamDecoder instance is now bound to Start/Stop in VideoReceiveStream and not all of the lifetime of VideoReceiveStream.
* Fixed VideoStreamDecoder to unregister callbacks in the dtor that were registered in the ctor. (this was open to a use-after-free regression)
* Delay and callback pointers are now passed via the ctors to the IncomingVideoStream classes. The thread primitives in the IncomingVideoStream classes are also constructed/destructed at the same time as the owning object, which allowed me to remove one more lock.
* Removed code in the VideoStreamDecoder that could overwrite the VideoReceiveStream render delay with a fixed value of 10ms on construction. This wasn't a problem with the previous implementation (it would be now though) but seemed to me like the wrong place to be setting that value.
* Made the render delay value in VideoRenderFrames, const.
BUG=
Review-Url: https://codereview.webrtc.org/2035173002
Cr-Commit-Position: refs/heads/master@{#13129}
We were passing the pointer to the sockaddr to usrsctp_dumppacket,
instead of the pointer to the data. So we were just logging random
bytes. The dangers of void*...
NOTRY=True
TBR=pthatcher@webrtc.org
BUG=619372
Review-Url: https://codereview.webrtc.org/2061093003
Cr-Commit-Position: refs/heads/master@{#13119}
CreatePeerConnectionFactory does not yet expose the ability to set the
factory from the outside.
Added notry due to android_dbg being broken.
NOTRY=True
BUG=webrtc:5805
Review-Url: https://codereview.webrtc.org/1991233004
Cr-Commit-Position: refs/heads/master@{#13112}
Introduce a new method I420Buffer::CropAndScale, and a static
convenience helper I420Buffer::CenterCropAndScale. Use them for almost
all scaling needs.
Delete the Scaler class and the cricket::VideoFrame::Stretch* methods.
BUG=webrtc:5682
R=pbos@webrtc.org, perkj@webrtc.org, stefan@webrtc.org
Review URL: https://codereview.webrtc.org/2020593002 .
Cr-Commit-Position: refs/heads/master@{#13110}
Changes:
* Set WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE on a global scope
to match GYP.
* Enable sctpdataengine_unittest.cc for iOS, which should have
been done in https://codereview.webrtc.org/1587193006
* Renamed GN target rtc_base_test_utils -> rtc_base_tests_utils
to match GYP.
* Added dependencies on call, modules/video_coding and video for
rtc_media.
* Added dependency on audio for rtc_media_unitttests (couldn't be
added to rtc_media due to circular dependency problem).
BUG=webrtc:5949
TESTED=Built and ran the tests on Mac.
NOTRY=True
Review-Url: https://codereview.webrtc.org/2050313002
Cr-Commit-Position: refs/heads/master@{#13106}
Every message will now be traced with the location from which it was
posted, including function name, file and line number.
This CL also writes a normal LOG message when the dispatch took more
than a certain amount of time (currently 50ms).
This logging should help us identify messages that are taking
longer than expected to be dispatched.
R=pthatcher@webrtc.org, tommi@webrtc.org
Review URL: https://codereview.webrtc.org/2019423006 .
Cr-Commit-Position: refs/heads/master@{#13104}
Instead of the default copy constructor, the Copy() method has to be used. In this CL, the number of copies has been reduced significantly in production code. One case in the video engine remains, where we need to restart a video stream. Even in that case, I'm sure we could avoid it, but for this particular CL, I decided against it to keep things simple (and it's also an edge case). Most importantly, creating copies is made harder and the interface encourages ownership transfers.
R=mflodman@webrtc.org, pbos@webrtc.org
Review URL: https://codereview.webrtc.org/2042603002 .
Cr-Commit-Position: refs/heads/master@{#13102}
Reason for revert:
Plan to reland with InitToBlack kept, to be able to update Chrome to use the new I420Buffer::SetToBlack method.
Original issue's description:
> Revert of New static method I420Buffer::SetToBlack. (patchset #4 id:60001 of https://codereview.webrtc.org/2029273004/ )
>
> Reason for revert:
> Breaks chrome, in particular, the tests in
>
> media_stream_remote_video_source_unittest.cc
>
> use the InitToBlack method which is being deleted.
>
> Original issue's description:
> > New static method I420Buffer::SetToBlack.
> >
> > Replaces cricket::VideoFrame::SetToBlack and
> > cricket::WebRtcVideoFrame::InitToBlack, which are deleted.
> >
> > Refactors the black frame logic in VideoBroadcaster, and a few of the
> > tests.
> >
> > BUG=webrtc:5682
> >
> > Committed: https://crrev.com/663f9e2ddc86e813f6db04ba2cf5ac1ed9e7ef67
> > Cr-Commit-Position: refs/heads/master@{#13063}
>
> TBR=perkj@webrtc.org,pbos@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:5682
>
> Committed: https://crrev.com/271d74078894bb24f454eb31b77e4ce38097a2fa
> Cr-Commit-Position: refs/heads/master@{#13065}
TBR=perkj@webrtc.org,pbos@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/2049513005
Cr-Commit-Position: refs/heads/master@{#13083}
Reason for revert:
Breaks chrome, in particular, the tests in
media_stream_remote_video_source_unittest.cc
use the InitToBlack method which is being deleted.
Original issue's description:
> New static method I420Buffer::SetToBlack.
>
> Replaces cricket::VideoFrame::SetToBlack and
> cricket::WebRtcVideoFrame::InitToBlack, which are deleted.
>
> Refactors the black frame logic in VideoBroadcaster, and a few of the
> tests.
>
> BUG=webrtc:5682
>
> Committed: https://crrev.com/663f9e2ddc86e813f6db04ba2cf5ac1ed9e7ef67
> Cr-Commit-Position: refs/heads/master@{#13063}
TBR=perkj@webrtc.org,pbos@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/2049023002
Cr-Commit-Position: refs/heads/master@{#13065}
Replaces cricket::VideoFrame::SetToBlack and
cricket::WebRtcVideoFrame::InitToBlack, which are deleted.
Refactors the black frame logic in VideoBroadcaster, and a few of the
tests.
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/2029273004
Cr-Commit-Position: refs/heads/master@{#13063}
This CL adds support for an extension on RTP frames to allow the sender
to specify the minimum and maximum playout delay limits.
The receiver makes a best-effort attempt to keep the capture-to-render delay
within this range. This allows different types of application to specify
different end-to-end delay goals. For example gaming can support rendering
of frames as soon as received on receiver to minimize delay. A movie playback
application can specify a minimum playout delay to allow fixed buffering
in presence of network jitter.
There are no tests at this time and most of testing is done with chromium
webrtc prototype.
On chromoting performance tests, this extension helps bring down end-to-end
delay by about 150 ms on small frames.
BUG=webrtc:5895
Review-Url: https://codereview.webrtc.org/2007743003
Cr-Commit-Position: refs/heads/master@{#13059}
The only thing that differs from the previous attempt in
https://codereview.webrtc.org/1979933002/ is that none of
the new targets are not hooked up to the webrtc target in
webrtc/BUILD.gn, which should make it not break the
chromium.webrtc.fyi bots.
Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc} in
preparation for removing src/third_party/libjingle in Chromium.
Changes between previous attempt and the one before that
(https://codereview.webrtc.org/1973313002) are:
* Added libstunprober target
* Adjusted warnings for Chromium's clang plugins
* webrtc/pc/externalhmac.{h,cc} added for Chromium builds.
BUG=webrtc:4256
NOTRY=True
NOPRESUBMIT=True
TBR=perkj@webrtc.org, tommi@webrtc.org
Review-Url: https://codereview.webrtc.org/2037983002
Cr-Commit-Position: refs/heads/master@{#13030}
This means there's only one thread hop to the worker thread.
At the video engine level, SetOptions and SetSource
are combined into one method (all within the same critical section)
which ensures that no frame will be encoded while SetVideoSend
is only partially finished.
BUG=webrtc:5691
Review-Url: https://codereview.webrtc.org/1838413002
Cr-Commit-Position: refs/heads/master@{#13022}
By not providing the default implementation of the metrics API
it becomes possible for users of rtc_media to choose which
implementation to use. The dependency is moved into each test
target that uses it instead.
NOTRY=True
NOPRESUBMIT=True
Review-Url: https://codereview.webrtc.org/2026223002
Cr-Commit-Position: refs/heads/master@{#12991}
Reason for revert:
Too many errors to address showed up when trying to land this with Chromium changes in https://codereview.chromium.org/2022833002/.
Will address them separately before relanding.
Original issue's description:
> Reland of GN: Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc}
>
> Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc} in
> preparation for removing src/third_party/libjingle in Chromium.
>
> Changes from previous attempt:
> * Added libstunprober target
> * Adjusted warnings for Chromium's clang plugins
> * webrtc/pc/externalhmac.{h,cc} added for Chromium builds.
>
> As soon this has landed a roll including the changes in
> https://codereview.chromium.org/2022833002/ is needed to make
> Chromium build cleanly.
>
> BUG=webrtc:4256
> NOTRY=True
> NOPRESUBMIT=True
>
> Committed: https://crrev.com/164e978f981c7810c4260c4184f41e26bae90230
> Cr-Commit-Position: refs/heads/master@{#12983}
TBR=perkj@webrtc.org,tommi@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4256
Review-Url: https://codereview.webrtc.org/2023233002
Cr-Commit-Position: refs/heads/master@{#12988}
Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc} in
preparation for removing src/third_party/libjingle in Chromium.
Changes from previous attempt:
* Added libstunprober target
* Adjusted warnings for Chromium's clang plugins
* webrtc/pc/externalhmac.{h,cc} added for Chromium builds.
As soon this has landed a roll including the changes in
https://codereview.chromium.org/2022833002/ is needed to make
Chromium build cleanly.
BUG=webrtc:4256
NOTRY=True
NOPRESUBMIT=True
Review-Url: https://codereview.webrtc.org/1979933002
Cr-Commit-Position: refs/heads/master@{#12983}
This fixes a client breakage by adding back the RtpHeaderExtension temporarily
so that it can be fixed in the client before being removed in webrtc.
BUG=
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.chromium.win:win_chromium_rel_ng
Review-Url: https://codereview.webrtc.org/2024153002
Cr-Commit-Position: refs/heads/master@{#12977}
VoEBase is plumbed to optionally take an AudioDecoderFactory, or create
a builtin factory if none is provided.
Retained the CreateChannel interfaces in Channel and ChannelManager
and added variants for injecting an AudioDecoderFactory. The
"old-style" variants call CreateBuiltinAudioDecoderFactory to get a
factory to use.
(Just realized this means each channel uses a separate factory with the
old-style calls. Probably ok.)
BUG=webrtc:5805
Review-Url: https://codereview.webrtc.org/1993783002
Cr-Commit-Position: refs/heads/master@{#12961}
Currently there are two structs that are identical and track extension details:
webrtc::RtpExtension
cricket::RtpHeaderExtension
The use of the structs is mixed in the code to track the extensions being
supported. This results in duplicate definition of
the URI constants and there is code to convert between the two structs.
Clean up to use a single RtpHeader throughout the codebase. The actual location
of RtpHeader may change in future (perhaps to be located in api/). Additionally,
this CL renames some of the constants to clarify Uri and Id use.
BUG= webrtc:5895
Review-Url: https://codereview.webrtc.org/1984983002
Cr-Commit-Position: refs/heads/master@{#12924}
This affects the webrtc::VideoFrameBuffer and cricket::VideoFrame
classes.
To make this work, VideoFrameFactory is changed to use an
I420BufferPool rather than a plain VideoFrame to cache allocated
frames.
The I420BufferPool is reorganized to return an I420Buffer,
rather than a proxy object.
BUG=webrtc:5921, webrtc:5682
Review-Url: https://codereview.webrtc.org/2009193002
Cr-Commit-Position: refs/heads/master@{#12919}
Splits VideoCapturer::OnFrameCaptured into helper methods,
which enables use of the VideoAdaptation logic without
using a frame factory.
Refactors AndroidVideoCapturer to make adaptation decision
earlier, so we can crop and rotate using
NV12ToI420Rotate.
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/1973873003
Cr-Commit-Position: refs/heads/master@{#12895}
We're now supposed to accept incoming frames from any thread.
BUG=webrtc:5902
Review-Url: https://codereview.webrtc.org/1987663002
Cr-Commit-Position: refs/heads/master@{#12844}
GetWidth and GetHeight (renamed to width and height),
GetNativeHandle (replaced by video_frame_buffer()->native_handle).
TBR=tkchin@webrtc.org (trivial changes to objc RTCVideoFrame and VideoRendererAdapter)
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/1990063005
Cr-Commit-Position: refs/heads/master@{#12822}
Pass timestamps to VideoAdapter instead of setting expected input frame rate, and use that to calculate when frames should be dropped.
BUG=webrtc:4938
TEST=Enable quality slider and HUD in debug settings. Request low fps with the quality slider and observe dropped frames.
Review-Url: https://codereview.webrtc.org/1982983003
Cr-Commit-Position: refs/heads/master@{#12811}
Needed to avoid DrMemory warnings, if the frame is passed to libyuv
AVX assembly functions.
BUG=libyuv:377
Review-Url: https://codereview.webrtc.org/1985693002
Cr-Commit-Position: refs/heads/master@{#12765}
This is similar to how a "receive" method is used to apply
RtpParameters to an RtpReceiver in ORTC. Currently, SetParameters
doesn't allow changing the parameters, so the main use of the API is
to retrieve the set of configured codecs. But other uses will likely
be made possible in the future.
R=glaznev@webrtc.org, pthatcher@webrtc.org, tkchin@webrtc.org
Review URL: https://codereview.webrtc.org/1917193008 .
Cr-Commit-Position: refs/heads/master@{#12761}
Reason for revert:
Speculative revert to see if failures on the DrMemory bot are related to this cl. See e.g. here:
https://build.chromium.org/p/client.webrtc/builders/Win%20DrMemory%20Full/builds/4243
UNINITIALIZED READ: reading 0x04980040-0x04980060 32 byte(s) within 0x04980040-0x04980060
# 0 CopyRow_AVX
# 1 CopyPlane
# 2 I420Copy
# 3 webrtc::ExtractBuffer
# 4 cricket::WebRtcVideoCapturer::SignalFrameCapturedOnStartThread
# 5 cricket::WebRtcVideoCapturer::OnIncomingCapturedFrame
# 6 FakeWebRtcVideoCaptureModule::SendFrame
# 7 WebRtcVideoCapturerTest_TestCaptureVcm_Test::TestBody
# 8 testing::internal::HandleSehExceptionsInMethodIfSupported<>
Original issue's description:
> Reland of Delete webrtc::VideoFrame methods buffer and stride. (patchset #1 id:1 of https://codereview.webrtc.org/1935443002/ )
>
> Reason for revert:
> I plan to reland this change in a week or two, after downstream users are updated.
>
> Original issue's description:
> > Revert of Delete webrtc::VideoFrame methods buffer and stride. (patchset #14 id:250001 of https://codereview.webrtc.org/1900673002/ )
> >
> > Reason for revert:
> > Breaks chrome FYI bots.
> >
> > Original issue's description:
> > > Delete webrtc::VideoFrame methods buffer and stride.
> > >
> > > To make the HasOneRef/IsMutable hack work, also had to change the
> > > video_frame_buffer method to return a const ref to a scoped_ref_ptr,
> > > to not imply an AddRef.
> > >
> > > BUG=webrtc:5682
> >
> > TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org
> > # Skipping CQ checks because original CL landed less than 1 days ago.
> > NOPRESUBMIT=true
> > NOTREECHECKS=true
> > NOTRY=true
> > BUG=webrtc:5682
> >
> > Committed: https://crrev.com/5b3c443d301f2c2f18dac5b02652c08b91ea3828
> > Cr-Commit-Position: refs/heads/master@{#12558}
>
> TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=webrtc:5682
>
> Committed: https://crrev.com/d0dc66e0ea30c8614001e425a4ae0aa7dd56c2a7
> Cr-Commit-Position: refs/heads/master@{#12721}
TBR=perkj@webrtc.org,magjed@webrtc.org,pbos@webrtc.org,pthatcher@webrtc.org,stefan@webrtc.org,nisse@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:5682
Review-Url: https://codereview.webrtc.org/1983583002
Cr-Commit-Position: refs/heads/master@{#12745}
Wires up existing libvpx_build_vp9==0 GYP flag into WebRTC and makes VP9
optional. Change is GYP only for now since libvpx's GN files build VP9
unconditionally.
BUG=webrtc:5884
R=kjellander@webrtc.org
Review URL: https://codereview.webrtc.org/1970343002 .
Cr-Commit-Position: refs/heads/master@{#12741}
If OnOutputFormatRequest() is called, VideoAdapter will crop to the same
aspect ratio as the requested format. The output from
VideoAdapter.AdaptFrameResolution() now contains both how to crop the
input frame, and how to scale the cropped frame to the final adapted
resolution.
BUG=b/28622232
Review-Url: https://codereview.webrtc.org/1966273002
Cr-Commit-Position: refs/heads/master@{#12732}
Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc} in
preparation for removing src/third_party/libjingle in Chromium.
BUG=webrtc:4256
NOTRY=True
TBR=perkj@webrtc.org
Review-Url: https://codereview.webrtc.org/1973313002
Cr-Commit-Position: refs/heads/master@{#12731}
The caller can set a negative or zero file size to avoid using a limit.
BUG=
Review-Url: https://codereview.webrtc.org/1974453002
Cr-Commit-Position: refs/heads/master@{#12730}
Reason for revert:
Breaks GN in Chromium.
Original issue's description:
> GN: Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc}
>
> Add BUILD.gn files for webrtc/{api,media,libjingle,p2p,pc} in
> preparation for removing src/third_party/libjingle in Chromium.
>
> BUG=webrtc:4256
> NOTRY=True
>
> Committed: https://crrev.com/4d02a358b4205bd0f7b5f794b6fb8c157e075b9e
> Cr-Commit-Position: refs/heads/master@{#12724}
TBR=perkj@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:4256
Review-Url: https://codereview.webrtc.org/1977853002
Cr-Commit-Position: refs/heads/master@{#12726}