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