Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Unified Diff: content/renderer/media/webrtc/media_stream_remote_video_source.cc

Issue 201583003: Implement a source for remote video tracks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/webrtc/media_stream_remote_video_source.cc
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f67afdbd3c3f8f7c35867f38603907898d8df43a
--- /dev/null
+++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -0,0 +1,156 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "content/renderer/media/native_handle_impl.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
+#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+
+namespace content {
+
+MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource(
+ webrtc::VideoTrackInterface* remote_track)
+ : MediaStreamVideoSource(NULL),
+ message_loop_proxy_(base::MessageLoopProxy::current()),
+ remote_track_(remote_track),
+ 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.
+ first_frame_received_(false) {
+ remote_track_->AddRenderer(this);
+ remote_track_->RegisterObserver(this);
+}
+
+MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() {
+ StopSourceImpl();
+}
+
+void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats(
+ int max_requested_width,
+ int max_requested_height) {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ 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
+ media::VideoCaptureFormats formats;
+ formats.push_back(format_);
+ OnSupportedFormats(formats);
+ }
+}
+
+void MediaStreamRemoteVideoSource::StartSourceImpl(
+ const media::VideoCaptureParams& params) {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ OnStartDone(true);
+}
+
+void MediaStreamRemoteVideoSource::StopSourceImpl() {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ remote_track_->RemoveRenderer(this);
+ remote_track_->UnregisterObserver(this);
+}
+
+webrtc::VideoSourceInterface* MediaStreamRemoteVideoSource::GetAdapter() {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ return remote_track_->GetSource();
+}
+
+void MediaStreamRemoteVideoSource::SetSize(int width, int height) {
+}
+
+void MediaStreamRemoteVideoSource::RenderFrame(
+ const cricket::VideoFrame* frame) {
+ 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
+ frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
+
+ scoped_refptr<media::VideoFrame> video_frame;
+ if (frame->GetNativeHandle() != NULL) {
+ NativeHandleImpl* handle =
+ static_cast<NativeHandleImpl*>(frame->GetNativeHandle());
+ video_frame = static_cast<media::VideoFrame*>(handle->GetHandle());
+ video_frame->SetTimestamp(timestamp);
+ } else {
+ gfx::Size size(frame->GetWidth(), frame->GetHeight());
+ video_frame = frame_pool_.CreateFrame(
+ media::VideoFrame::I420, size, gfx::Rect(size), size, timestamp);
+
+ // 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
+ DCHECK_EQ(frame->GetPixelWidth(), 1u);
+ 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
+
+ int y_rows = frame->GetHeight();
+ int uv_rows = frame->GetChromaHeight();
+ CopyYPlane(
+ frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame.get());
+ CopyUPlane(
+ frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame.get());
+ CopyVPlane(
+ frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get());
+ }
+
+ if (!first_frame_received_) {
+ first_frame_received_ = true;
+ media::VideoPixelFormat pixel_format = (
+ video_frame->format() == media::VideoFrame::I420) ?
+ media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_TEXTURE;
+ media::VideoCaptureFormat format(
+ gfx::Size(video_frame->natural_size().width(),
+ video_frame->natural_size().height()),
+ MediaStreamVideoSource::kDefaultFrameRate,
+ pixel_format);
+ message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&MediaStreamRemoteVideoSource::FrameFormatOnMainThread,
+ AsWeakPtr(), format));
+ }
+
+ // TODO(perkj): Consider delivering the frame on whatever thread the frame is
+ // delivered on once crbug/335327 is fixed.
+ 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.
+ FROM_HERE,
+ base::Bind(&MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread,
+ AsWeakPtr(), video_frame));
+}
+
+void MediaStreamRemoteVideoSource::OnChanged() {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ webrtc::MediaStreamTrackInterface::TrackState state = remote_track_->state();
+ if (state != track_state_) {
+ track_state_ = state;
+ switch (state) {
+ case webrtc::MediaStreamTrackInterface::kInitializing:
+ // Ignore the kInitializing state since there is no match in
+ // WebMediaStreamSource::ReadyState.
+ break;
+ case webrtc::MediaStreamTrackInterface::kLive:
+ SetReadyState(blink::WebMediaStreamSource::ReadyStateLive);
+ break;
+ case webrtc::MediaStreamTrackInterface::kEnded:
+ SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+}
+
+void MediaStreamRemoteVideoSource::FrameFormatOnMainThread(
+ const media::VideoCaptureFormat& format) {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ format_ = format;
+ if (GetState() == RETRIEVING_CAPABILITIES) {
+ media::VideoCaptureFormats formats;
+ formats.push_back(format);
+ OnSupportedFormats(formats);
+ }
+}
+
+void MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread(
+ scoped_refptr<media::VideoFrame> video_frame) {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ DeliverVideoFrame(video_frame);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698