OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "media/video/capture/file_video_capture_device.h" | 5 #include "media/video/capture/file_video_capture_device.h" |
6 | 6 |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 base::Unretained(this))); | 203 base::Unretained(this))); |
204 } | 204 } |
205 | 205 |
206 void FileVideoCaptureDevice::OnStopAndDeAllocate() { | 206 void FileVideoCaptureDevice::OnStopAndDeAllocate() { |
207 DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); | 207 DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); |
208 file_.Close(); | 208 file_.Close(); |
209 client_.reset(); | 209 client_.reset(); |
210 current_byte_index_ = 0; | 210 current_byte_index_ = 0; |
211 first_frame_byte_index_ = 0; | 211 first_frame_byte_index_ = 0; |
212 frame_size_ = 0; | 212 frame_size_ = 0; |
| 213 next_frame_time_ = base::TimeTicks(); |
213 video_frame_.reset(); | 214 video_frame_.reset(); |
214 } | 215 } |
215 | 216 |
216 void FileVideoCaptureDevice::OnCaptureTask() { | 217 void FileVideoCaptureDevice::OnCaptureTask() { |
217 DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); | 218 DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); |
218 if (!client_) | 219 if (!client_) |
219 return; | 220 return; |
220 const base::TimeTicks timestamp_before_reading = base::TimeTicks::Now(); | |
221 int result = file_.Read(current_byte_index_, | 221 int result = file_.Read(current_byte_index_, |
222 reinterpret_cast<char*>(video_frame_.get()), | 222 reinterpret_cast<char*>(video_frame_.get()), |
223 frame_size_); | 223 frame_size_); |
224 | 224 |
225 // If we passed EOF to base::File, it will return 0 read characters. In that | 225 // If we passed EOF to base::File, it will return 0 read characters. In that |
226 // case, reset the pointer and read again. | 226 // case, reset the pointer and read again. |
227 if (result != frame_size_) { | 227 if (result != frame_size_) { |
228 CHECK_EQ(result, 0); | 228 CHECK_EQ(result, 0); |
229 current_byte_index_ = first_frame_byte_index_; | 229 current_byte_index_ = first_frame_byte_index_; |
230 CHECK_EQ(file_.Read(current_byte_index_, | 230 CHECK_EQ(file_.Read(current_byte_index_, |
231 reinterpret_cast<char*>(video_frame_.get()), | 231 reinterpret_cast<char*>(video_frame_.get()), |
232 frame_size_), | 232 frame_size_), |
233 frame_size_); | 233 frame_size_); |
234 } else { | 234 } else { |
235 current_byte_index_ += frame_size_ + kY4MSimpleFrameDelimiterSize; | 235 current_byte_index_ += frame_size_ + kY4MSimpleFrameDelimiterSize; |
236 } | 236 } |
237 | 237 |
238 // Give the captured frame to the client. | 238 // Give the captured frame to the client. |
| 239 const base::TimeTicks current_time = base::TimeTicks::Now(); |
239 client_->OnIncomingCapturedData(video_frame_.get(), | 240 client_->OnIncomingCapturedData(video_frame_.get(), |
240 frame_size_, | 241 frame_size_, |
241 capture_format_, | 242 capture_format_, |
242 0, | 243 0, |
243 base::TimeTicks::Now()); | 244 current_time); |
244 // Reschedule next CaptureTask. | 245 // Reschedule next CaptureTask. |
245 const base::TimeDelta frame_interval = | 246 const base::TimeDelta frame_interval = |
246 base::TimeDelta::FromMicroseconds(1E6 / capture_format_.frame_rate); | 247 base::TimeDelta::FromMicroseconds(1E6 / capture_format_.frame_rate); |
247 base::TimeDelta next_on_capture_timedelta = frame_interval - | 248 if (next_frame_time_.is_null()) { |
248 (base::TimeTicks::Now() - timestamp_before_reading); | 249 next_frame_time_ = current_time + frame_interval; |
249 if (next_on_capture_timedelta.InMilliseconds() < 0) { | 250 } else { |
250 DLOG(WARNING) << "Frame reading took longer than the frame interval."; | 251 next_frame_time_ += frame_interval; |
251 next_on_capture_timedelta = frame_interval; | |
252 } | 252 } |
253 base::MessageLoop::current()->PostDelayedTask( | 253 base::MessageLoop::current()->PostDelayedTask( |
254 FROM_HERE, | 254 FROM_HERE, |
255 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, | 255 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, |
256 base::Unretained(this)), | 256 base::Unretained(this)), |
257 next_on_capture_timedelta); | 257 next_frame_time_ - current_time); |
258 } | 258 } |
259 | 259 |
260 } // namespace media | 260 } // namespace media |
OLD | NEW |