Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/location.h" | |
| 9 #include "content/renderer/media/native_handle_impl.h" | |
| 10 #include "media/base/video_frame.h" | |
| 11 #include "media/base/video_util.h" | |
| 12 #include "third_party/libjingle/source/talk/media/base/videoframe.h" | |
| 13 | |
| 14 namespace content { | |
| 15 | |
| 16 MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource( | |
| 17 webrtc::VideoTrackInterface* remote_track) | |
| 18 : MediaStreamVideoSource(NULL), | |
| 19 message_loop_proxy_(base::MessageLoopProxy::current()), | |
| 20 remote_track_(remote_track), | |
| 21 track_state_(remote_track_->state()), | |
|
Jói
2014/03/17 22:00:40
As a minor suggestion, perhaps this should be call
Ronghua Wu (Left Chromium)
2014/03/17 22:45:35
+1
perkj_chrome
2014/03/19 16:34:48
Done.
perkj_chrome
2014/03/19 16:34:48
Done.
| |
| 22 first_frame_received_(false) { | |
| 23 remote_track_->AddRenderer(this); | |
| 24 remote_track_->RegisterObserver(this); | |
| 25 } | |
| 26 | |
| 27 MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() { | |
| 28 StopSourceImpl(); | |
| 29 } | |
| 30 | |
| 31 void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats( | |
| 32 int max_requested_width, | |
| 33 int max_requested_height) { | |
| 34 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 35 if (format_.IsValid()) { | |
|
Jói
2014/03/17 22:00:40
If format_ is not valid, is it acceptable to never
Ronghua Wu (Left Chromium)
2014/03/17 22:45:35
Should call OnSupportedFormats regardless, otherwi
perkj_chrome
2014/03/19 16:34:48
So the idea here is that format_ gets valid when t
| |
| 36 media::VideoCaptureFormats formats; | |
| 37 formats.push_back(format_); | |
| 38 OnSupportedFormats(formats); | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 void MediaStreamRemoteVideoSource::StartSourceImpl( | |
| 43 const media::VideoCaptureParams& params) { | |
| 44 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 45 OnStartDone(true); | |
| 46 } | |
| 47 | |
| 48 void MediaStreamRemoteVideoSource::StopSourceImpl() { | |
| 49 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 50 remote_track_->RemoveRenderer(this); | |
| 51 remote_track_->UnregisterObserver(this); | |
| 52 } | |
| 53 | |
| 54 webrtc::VideoSourceInterface* MediaStreamRemoteVideoSource::GetAdapter() { | |
| 55 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 56 return remote_track_->GetSource(); | |
| 57 } | |
| 58 | |
| 59 void MediaStreamRemoteVideoSource::SetSize(int width, int height) { | |
| 60 } | |
| 61 | |
| 62 void MediaStreamRemoteVideoSource::RenderFrame( | |
| 63 const cricket::VideoFrame* frame) { | |
| 64 base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds( | |
|
Jói
2014/03/17 22:00:40
Note that there is also a FromMicroseconds factory
perkj_chrome
2014/03/19 16:34:48
Except that I introduce the video frame pool I kep
| |
| 65 frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec); | |
| 66 | |
| 67 scoped_refptr<media::VideoFrame> video_frame; | |
| 68 if (frame->GetNativeHandle() != NULL) { | |
| 69 NativeHandleImpl* handle = | |
| 70 static_cast<NativeHandleImpl*>(frame->GetNativeHandle()); | |
| 71 video_frame = static_cast<media::VideoFrame*>(handle->GetHandle()); | |
| 72 video_frame->SetTimestamp(timestamp); | |
| 73 } else { | |
| 74 gfx::Size size(frame->GetWidth(), frame->GetHeight()); | |
| 75 video_frame = frame_pool_.CreateFrame( | |
| 76 media::VideoFrame::I420, size, gfx::Rect(size), size, timestamp); | |
| 77 | |
| 78 // Aspect ratio unsupported; DCHECK when there are non-square pixels. | |
|
Ronghua Wu (Left Chromium)
2014/03/17 22:45:35
how do you mean by "Aspect ratio unsupported"?
perkj_chrome
2014/03/19 16:34:48
This function is actually copied from the one I th
| |
| 79 DCHECK_EQ(frame->GetPixelWidth(), 1u); | |
| 80 DCHECK_EQ(frame->GetPixelHeight(), 1u); | |
|
Ronghua Wu (Left Chromium)
2014/03/17 22:45:35
why is this check needed?
perkj_chrome
2014/03/19 16:34:48
On 2014/03/17 22:45:35, Ronghua Wu wrote:
> why is
| |
| 81 | |
| 82 int y_rows = frame->GetHeight(); | |
| 83 int uv_rows = frame->GetChromaHeight(); | |
| 84 CopyYPlane( | |
| 85 frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame.get()); | |
| 86 CopyUPlane( | |
| 87 frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame.get()); | |
| 88 CopyVPlane( | |
| 89 frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get()); | |
| 90 } | |
| 91 | |
| 92 if (!first_frame_received_) { | |
| 93 first_frame_received_ = true; | |
| 94 media::VideoPixelFormat pixel_format = ( | |
| 95 video_frame->format() == media::VideoFrame::I420) ? | |
| 96 media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_TEXTURE; | |
| 97 media::VideoCaptureFormat format( | |
| 98 gfx::Size(video_frame->natural_size().width(), | |
| 99 video_frame->natural_size().height()), | |
| 100 MediaStreamVideoSource::kDefaultFrameRate, | |
| 101 pixel_format); | |
| 102 message_loop_proxy_->PostTask( | |
| 103 FROM_HERE, | |
| 104 base::Bind(&MediaStreamRemoteVideoSource::FrameFormatOnMainThread, | |
| 105 AsWeakPtr(), format)); | |
| 106 } | |
| 107 | |
| 108 // TODO(perkj): Consider delivering the frame on whatever thread the frame is | |
| 109 // delivered on once crbug/335327 is fixed. | |
| 110 message_loop_proxy_->PostTask( | |
|
Ronghua Wu (Left Chromium)
2014/03/17 22:45:35
Don't deliver the frame before the source is start
perkj_chrome
2014/03/19 16:34:48
ok- But we need to do that on the correct thread.
| |
| 111 FROM_HERE, | |
| 112 base::Bind(&MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread, | |
| 113 AsWeakPtr(), video_frame)); | |
| 114 } | |
| 115 | |
| 116 void MediaStreamRemoteVideoSource::OnChanged() { | |
| 117 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 118 webrtc::MediaStreamTrackInterface::TrackState state = remote_track_->state(); | |
| 119 if (state != track_state_) { | |
| 120 track_state_ = state; | |
| 121 switch (state) { | |
| 122 case webrtc::MediaStreamTrackInterface::kInitializing: | |
| 123 // Ignore the kInitializing state since there is no match in | |
| 124 // WebMediaStreamSource::ReadyState. | |
| 125 break; | |
| 126 case webrtc::MediaStreamTrackInterface::kLive: | |
| 127 SetReadyState(blink::WebMediaStreamSource::ReadyStateLive); | |
| 128 break; | |
| 129 case webrtc::MediaStreamTrackInterface::kEnded: | |
| 130 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | |
| 131 break; | |
| 132 default: | |
| 133 NOTREACHED(); | |
| 134 break; | |
| 135 } | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 void MediaStreamRemoteVideoSource::FrameFormatOnMainThread( | |
| 140 const media::VideoCaptureFormat& format) { | |
| 141 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 142 format_ = format; | |
| 143 if (GetState() == RETRIEVING_CAPABILITIES) { | |
| 144 media::VideoCaptureFormats formats; | |
| 145 formats.push_back(format); | |
| 146 OnSupportedFormats(formats); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 void MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread( | |
| 151 scoped_refptr<media::VideoFrame> video_frame) { | |
| 152 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); | |
| 153 DeliverVideoFrame(video_frame); | |
| 154 } | |
| 155 | |
| 156 } // namespace content | |
| OLD | NEW |