OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/rtc_video_capturer.h" | 5 #include "content/renderer/media/rtc_video_capturer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 | 9 |
10 namespace content { | 10 namespace content { |
11 | 11 |
12 RtcVideoCapturer::RtcVideoCapturer( | 12 RtcVideoCapturer::RtcVideoCapturer(const media::VideoCaptureSessionId id, |
13 const media::VideoCaptureSessionId id, | 13 VideoCaptureImplManager* vc_manager, |
14 VideoCaptureImplManager* vc_manager, | 14 bool is_screencast) |
15 bool is_screencast) | |
16 : is_screencast_(is_screencast), | 15 : is_screencast_(is_screencast), |
17 delegate_(new RtcVideoCaptureDelegate(id, vc_manager)), | 16 delegate_(new RtcVideoCaptureDelegate(id, vc_manager)), |
18 state_(VIDEO_CAPTURE_STATE_STOPPED) { | 17 state_(VIDEO_CAPTURE_STATE_STOPPED) {} |
19 } | |
20 | 18 |
21 RtcVideoCapturer::~RtcVideoCapturer() { | 19 RtcVideoCapturer::~RtcVideoCapturer() { |
22 DCHECK(VIDEO_CAPTURE_STATE_STOPPED); | 20 DCHECK(VIDEO_CAPTURE_STATE_STOPPED); |
23 DVLOG(3) << " RtcVideoCapturer::dtor"; | 21 DVLOG(3) << " RtcVideoCapturer::dtor"; |
24 } | 22 } |
25 | 23 |
26 cricket::CaptureState RtcVideoCapturer::Start( | 24 cricket::CaptureState RtcVideoCapturer::Start( |
27 const cricket::VideoFormat& capture_format) { | 25 const cricket::VideoFormat& capture_format) { |
28 DVLOG(3) << " RtcVideoCapturer::Start "; | 26 DVLOG(3) << " RtcVideoCapturer::Start "; |
29 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 27 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
30 DVLOG(1) << "Got a StartCapture when already started!!! "; | 28 DVLOG(1) << "Got a StartCapture when already started!!! "; |
31 return cricket::CS_FAILED; | 29 return cricket::CS_FAILED; |
32 } | 30 } |
33 | 31 |
34 media::VideoCaptureCapability cap; | 32 media::VideoCaptureCapability cap; |
35 cap.width = capture_format.width; | 33 cap.width = capture_format.width; |
36 cap.height = capture_format.height; | 34 cap.height = capture_format.height; |
37 cap.frame_rate = capture_format.framerate(); | 35 cap.frame_rate = capture_format.framerate(); |
38 cap.color = media::PIXEL_FORMAT_I420; | 36 cap.color = media::PIXEL_FORMAT_I420; |
39 | 37 |
40 SetCaptureFormat(&capture_format); | 38 SetCaptureFormat(&capture_format); |
41 | 39 |
42 state_ = VIDEO_CAPTURE_STATE_STARTED; | 40 state_ = VIDEO_CAPTURE_STATE_STARTED; |
43 start_time_ = base::Time::Now(); | 41 first_frame_timestamp_ = media::kNoTimestamp(); |
44 delegate_->StartCapture(cap, | 42 delegate_->StartCapture( |
| 43 cap, |
45 base::Bind(&RtcVideoCapturer::OnFrameCaptured, base::Unretained(this)), | 44 base::Bind(&RtcVideoCapturer::OnFrameCaptured, base::Unretained(this)), |
46 base::Bind(&RtcVideoCapturer::OnStateChange, base::Unretained(this))); | 45 base::Bind(&RtcVideoCapturer::OnStateChange, base::Unretained(this))); |
47 // Update the desired aspect ratio so that later the video frame can be | 46 // Update the desired aspect ratio so that later the video frame can be |
48 // cropped to meet the requirement if the camera returns a different | 47 // cropped to meet the requirement if the camera returns a different |
49 // resolution than the |cap|. | 48 // resolution than the |cap|. |
50 UpdateAspectRatio(cap.width, cap.height); | 49 UpdateAspectRatio(cap.width, cap.height); |
51 return cricket::CS_STARTING; | 50 return cricket::CS_STARTING; |
52 } | 51 } |
53 | 52 |
54 void RtcVideoCapturer::Stop() { | 53 void RtcVideoCapturer::Stop() { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 // Chrome does not support capability enumeration. | 87 // Chrome does not support capability enumeration. |
89 // Use the desired format as the best format. | 88 // Use the desired format as the best format. |
90 best_format->width = desired.width; | 89 best_format->width = desired.width; |
91 best_format->height = desired.height; | 90 best_format->height = desired.height; |
92 best_format->fourcc = cricket::FOURCC_I420; | 91 best_format->fourcc = cricket::FOURCC_I420; |
93 best_format->interval = desired.interval; | 92 best_format->interval = desired.interval; |
94 return true; | 93 return true; |
95 } | 94 } |
96 | 95 |
97 void RtcVideoCapturer::OnFrameCaptured( | 96 void RtcVideoCapturer::OnFrameCaptured( |
98 const media::VideoCapture::VideoFrameBuffer& buf) { | 97 const scoped_refptr<media::VideoFrame>& frame) { |
| 98 if (first_frame_timestamp_ == media::kNoTimestamp()) |
| 99 first_frame_timestamp_ = frame->GetTimestamp(); |
| 100 |
99 // Currently, |fourcc| is always I420. | 101 // Currently, |fourcc| is always I420. |
100 cricket::CapturedFrame frame; | 102 cricket::CapturedFrame captured_frame; |
101 frame.width = buf.width; | 103 captured_frame.width = frame->coded_size().width(); |
102 frame.height = buf.height; | 104 captured_frame.height = frame->coded_size().height(); |
103 frame.fourcc = cricket::FOURCC_I420; | 105 captured_frame.fourcc = cricket::FOURCC_I420; |
104 frame.data_size = buf.buffer_size; | |
105 // cricket::CapturedFrame time is in nanoseconds. | 106 // cricket::CapturedFrame time is in nanoseconds. |
106 frame.elapsed_time = (buf.timestamp - start_time_).InMicroseconds() * | 107 captured_frame.elapsed_time = |
| 108 (frame->GetTimestamp() - first_frame_timestamp_).InMicroseconds() * |
107 base::Time::kNanosecondsPerMicrosecond; | 109 base::Time::kNanosecondsPerMicrosecond; |
108 frame.time_stamp = | 110 captured_frame.time_stamp = frame->GetTimestamp().InMicroseconds() * |
109 (buf.timestamp - base::Time::UnixEpoch()).InMicroseconds() * | 111 base::Time::kNanosecondsPerMicrosecond; |
110 base::Time::kNanosecondsPerMicrosecond; | 112 // TODO(sheu): we assume contiguous layout of image planes. |
111 frame.data = buf.memory_pointer; | 113 captured_frame.data = frame->data(0); |
112 frame.pixel_height = 1; | 114 captured_frame.data_size = |
113 frame.pixel_width = 1; | 115 media::VideoFrame::AllocationSize(frame->format(), frame->coded_size()); |
| 116 captured_frame.pixel_height = 1; |
| 117 captured_frame.pixel_width = 1; |
114 | 118 |
115 TRACE_EVENT_INSTANT2("rtc_video_capturer", | 119 TRACE_EVENT_INSTANT2( |
116 "OnFrameCaptured", | 120 "rtc_video_capturer", |
117 TRACE_EVENT_SCOPE_THREAD, | 121 "OnFrameCaptured", |
118 "elapsed time", | 122 TRACE_EVENT_SCOPE_THREAD, |
119 frame.elapsed_time, | 123 "elapsed time", |
120 "timestamp_ms", | 124 captured_frame.elapsed_time, |
121 frame.time_stamp / talk_base::kNumNanosecsPerMillisec); | 125 "timestamp_ms", |
| 126 captured_frame.time_stamp / talk_base::kNumNanosecsPerMillisec); |
122 | 127 |
123 // This signals to libJingle that a new VideoFrame is available. | 128 // This signals to libJingle that a new VideoFrame is available. |
124 // libJingle have no assumptions on what thread this signal come from. | 129 // libJingle have no assumptions on what thread this signal come from. |
125 SignalFrameCaptured(this, &frame); | 130 SignalFrameCaptured(this, &captured_frame); |
126 } | 131 } |
127 | 132 |
128 void RtcVideoCapturer::OnStateChange( | 133 void RtcVideoCapturer::OnStateChange( |
129 RtcVideoCaptureDelegate::CaptureState state) { | 134 RtcVideoCaptureDelegate::CaptureState state) { |
130 cricket::CaptureState converted_state = cricket::CS_FAILED; | 135 cricket::CaptureState converted_state = cricket::CS_FAILED; |
131 DVLOG(3) << " RtcVideoCapturer::OnStateChange " << state; | 136 DVLOG(3) << " RtcVideoCapturer::OnStateChange " << state; |
132 switch (state) { | 137 switch (state) { |
133 case RtcVideoCaptureDelegate::CAPTURE_STOPPED: | 138 case RtcVideoCaptureDelegate::CAPTURE_STOPPED: |
134 converted_state = cricket::CS_STOPPED; | 139 converted_state = cricket::CS_STOPPED; |
135 break; | 140 break; |
136 case RtcVideoCaptureDelegate::CAPTURE_RUNNING: | 141 case RtcVideoCaptureDelegate::CAPTURE_RUNNING: |
137 converted_state = cricket::CS_RUNNING; | 142 converted_state = cricket::CS_RUNNING; |
138 break; | 143 break; |
139 case RtcVideoCaptureDelegate::CAPTURE_FAILED: | 144 case RtcVideoCaptureDelegate::CAPTURE_FAILED: |
140 // TODO(perkj): Update the comments in the the definition of | 145 // TODO(perkj): Update the comments in the the definition of |
141 // cricket::CS_FAILED. According to the comments, cricket::CS_FAILED | 146 // cricket::CS_FAILED. According to the comments, cricket::CS_FAILED |
142 // means that the capturer failed to start. But here and in libjingle it | 147 // means that the capturer failed to start. But here and in libjingle it |
143 // is also used if an error occur during capturing. | 148 // is also used if an error occur during capturing. |
144 converted_state = cricket::CS_FAILED; | 149 converted_state = cricket::CS_FAILED; |
145 break; | 150 break; |
146 default: | 151 default: |
147 NOTREACHED(); | 152 NOTREACHED(); |
148 break; | 153 break; |
149 } | 154 } |
150 SignalStateChange(this, converted_state); | 155 SignalStateChange(this, converted_state); |
151 } | 156 } |
152 | 157 |
153 } // namespace content | 158 } // namespace content |
OLD | NEW |