Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / webrtc / webrtc_video_sink_adapter.cc
1 // Copyright 2013 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/webrtc_video_sink_adapter.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "content/renderer/media/native_handle_impl.h"
12 #include "media/base/video_frame.h"
13 #include "media/base/video_util.h"
14 #include "third_party/libjingle/source/talk/media/base/videoframe.h"
15 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
16 #include "ui/gfx/size.h"
17
18 using media::CopyYPlane;
19 using media::CopyUPlane;
20 using media::CopyVPlane;
21
22 namespace content {
23
24 WebRtcVideoSinkAdapter::WebRtcVideoSinkAdapter(
25     webrtc::VideoTrackInterface* video_track,
26     MediaStreamVideoSink* sink)
27     : message_loop_proxy_(base::MessageLoopProxy::current()),
28       sink_(sink),
29       video_track_(video_track),
30       state_(video_track->state()),
31       track_enabled_(video_track->enabled()) {
32   DCHECK(sink);
33   video_track_->AddRenderer(this);
34   video_track_->RegisterObserver(this);
35   DVLOG(1) << "WebRtcVideoSinkAdapter";
36 }
37
38 WebRtcVideoSinkAdapter::~WebRtcVideoSinkAdapter() {
39   video_track_->RemoveRenderer(this);
40   video_track_->UnregisterObserver(this);
41   DVLOG(1) << "~WebRtcVideoSinkAdapter";
42 }
43
44 void WebRtcVideoSinkAdapter::SetSize(int width, int height) {
45 }
46
47 void WebRtcVideoSinkAdapter::RenderFrame(const cricket::VideoFrame* frame) {
48   base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
49       frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
50
51   scoped_refptr<media::VideoFrame> video_frame;
52   if (frame->GetNativeHandle() != NULL) {
53     NativeHandleImpl* handle =
54         static_cast<NativeHandleImpl*>(frame->GetNativeHandle());
55     video_frame = static_cast<media::VideoFrame*>(handle->GetHandle());
56     video_frame->SetTimestamp(timestamp);
57   } else {
58     gfx::Size size(frame->GetWidth(), frame->GetHeight());
59     video_frame = media::VideoFrame::CreateFrame(
60         media::VideoFrame::YV12, size, gfx::Rect(size), size, timestamp);
61
62     // Aspect ratio unsupported; DCHECK when there are non-square pixels.
63     DCHECK_EQ(frame->GetPixelWidth(), 1u);
64     DCHECK_EQ(frame->GetPixelHeight(), 1u);
65
66     int y_rows = frame->GetHeight();
67     int uv_rows = frame->GetHeight() / 2;  // YV12 format.
68     CopyYPlane(
69         frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame.get());
70     CopyUPlane(
71         frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame.get());
72     CopyVPlane(
73         frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get());
74   }
75
76   message_loop_proxy_->PostTask(
77       FROM_HERE, base::Bind(&WebRtcVideoSinkAdapter::DoRenderFrameOnMainThread,
78                             AsWeakPtr(), video_frame));
79 }
80
81 void WebRtcVideoSinkAdapter::OnChanged() {
82   DCHECK(message_loop_proxy_->BelongsToCurrentThread());
83
84   // TODO(perkj): OnChanged belongs to the base class of WebRtcVideoSinkAdapter
85   // common for both webrtc audio and video.
86   webrtc::MediaStreamTrackInterface::TrackState state = video_track_->state();
87   if (state != state_) {
88     state_ = state;
89     switch (state) {
90       case webrtc::MediaStreamTrackInterface::kInitializing:
91         // Ignore the kInitializing state since there is no match in
92         // WebMediaStreamSource::ReadyState.
93         break;
94       case webrtc::MediaStreamTrackInterface::kLive:
95         sink_->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateLive);
96         break;
97       case webrtc::MediaStreamTrackInterface::kEnded:
98         sink_->OnReadyStateChanged(
99             blink::WebMediaStreamSource::ReadyStateEnded);
100         break;
101       default:
102         NOTREACHED();
103         break;
104     }
105   }
106   if (track_enabled_ != video_track_->enabled()) {
107     track_enabled_ = video_track_->enabled();
108     sink_->OnEnabledChanged(track_enabled_);
109   }
110 }
111
112 void WebRtcVideoSinkAdapter::DoRenderFrameOnMainThread(
113     scoped_refptr<media::VideoFrame> video_frame) {
114   DCHECK(message_loop_proxy_->BelongsToCurrentThread());
115   sink_->OnVideoFrame(video_frame);
116 }
117
118 }  // namespace content