OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 "media/capture/screen_capture_device_core.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/memory/weak_ptr.h" |
| 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/threading/thread_checker.h" |
| 14 |
| 15 namespace media { |
| 16 |
| 17 namespace { |
| 18 |
| 19 void DeleteCaptureMachine( |
| 20 scoped_ptr<VideoCaptureMachine> capture_machine) { |
| 21 capture_machine.reset(); |
| 22 } |
| 23 |
| 24 } // namespace |
| 25 |
| 26 void ScreenCaptureDeviceCore::AllocateAndStart( |
| 27 const VideoCaptureParams& params, |
| 28 scoped_ptr<VideoCaptureDevice::Client> client) { |
| 29 DCHECK(thread_checker_.CalledOnValidThread()); |
| 30 |
| 31 if (state_ != kIdle) { |
| 32 DVLOG(1) << "Allocate() invoked when not in state Idle."; |
| 33 return; |
| 34 } |
| 35 |
| 36 if (params.requested_format.frame_rate <= 0) { |
| 37 std::string error_msg("Invalid frame_rate: "); |
| 38 error_msg += base::DoubleToString(params.requested_format.frame_rate); |
| 39 DVLOG(1) << error_msg; |
| 40 client->OnError(error_msg); |
| 41 return; |
| 42 } |
| 43 |
| 44 if (params.requested_format.pixel_format != PIXEL_FORMAT_I420 && |
| 45 params.requested_format.pixel_format != PIXEL_FORMAT_TEXTURE) { |
| 46 std::string error_msg = base::StringPrintf( |
| 47 "unsupported format: %d", params.requested_format.pixel_format); |
| 48 DVLOG(1) << error_msg; |
| 49 client->OnError(error_msg); |
| 50 return; |
| 51 } |
| 52 |
| 53 if (params.requested_format.frame_size.IsEmpty()) { |
| 54 std::string error_msg = |
| 55 "invalid frame size: " + params.requested_format.frame_size.ToString(); |
| 56 DVLOG(1) << error_msg; |
| 57 client->OnError(error_msg); |
| 58 return; |
| 59 } |
| 60 |
| 61 oracle_proxy_ = new ThreadSafeCaptureOracle(client.Pass(), params); |
| 62 |
| 63 capture_machine_->Start( |
| 64 oracle_proxy_, |
| 65 params, |
| 66 base::Bind(&ScreenCaptureDeviceCore::CaptureStarted, AsWeakPtr())); |
| 67 |
| 68 TransitionStateTo(kCapturing); |
| 69 } |
| 70 |
| 71 void ScreenCaptureDeviceCore::StopAndDeAllocate() { |
| 72 DCHECK(thread_checker_.CalledOnValidThread()); |
| 73 |
| 74 if (state_ != kCapturing) |
| 75 return; |
| 76 |
| 77 oracle_proxy_->Stop(); |
| 78 oracle_proxy_ = NULL; |
| 79 |
| 80 TransitionStateTo(kIdle); |
| 81 |
| 82 capture_machine_->Stop(base::Bind(&base::DoNothing)); |
| 83 } |
| 84 |
| 85 void ScreenCaptureDeviceCore::CaptureStarted(bool success) { |
| 86 DCHECK(thread_checker_.CalledOnValidThread()); |
| 87 if (!success) { |
| 88 std::string reason("Failed to start capture machine."); |
| 89 DVLOG(1) << reason; |
| 90 Error(reason); |
| 91 } |
| 92 } |
| 93 |
| 94 ScreenCaptureDeviceCore::ScreenCaptureDeviceCore( |
| 95 scoped_ptr<VideoCaptureMachine> capture_machine) |
| 96 : state_(kIdle), |
| 97 capture_machine_(capture_machine.Pass()) { |
| 98 DCHECK(capture_machine_.get()); |
| 99 } |
| 100 |
| 101 ScreenCaptureDeviceCore::~ScreenCaptureDeviceCore() { |
| 102 DCHECK(thread_checker_.CalledOnValidThread()); |
| 103 DCHECK_NE(state_, kCapturing); |
| 104 if (capture_machine_) { |
| 105 capture_machine_->Stop(base::Bind(&DeleteCaptureMachine, |
| 106 base::Passed(&capture_machine_))); |
| 107 } |
| 108 DVLOG(1) << "ScreenCaptureDeviceCore@" << this << " destroying."; |
| 109 } |
| 110 |
| 111 void ScreenCaptureDeviceCore::TransitionStateTo(State next_state) { |
| 112 DCHECK(thread_checker_.CalledOnValidThread()); |
| 113 |
| 114 #ifndef NDEBUG |
| 115 static const char* kStateNames[] = { |
| 116 "Idle", "Allocated", "Capturing", "Error" |
| 117 }; |
| 118 DVLOG(1) << "State change: " << kStateNames[state_] |
| 119 << " --> " << kStateNames[next_state]; |
| 120 #endif |
| 121 |
| 122 state_ = next_state; |
| 123 } |
| 124 |
| 125 void ScreenCaptureDeviceCore::Error(const std::string& reason) { |
| 126 DCHECK(thread_checker_.CalledOnValidThread()); |
| 127 |
| 128 if (state_ == kIdle) |
| 129 return; |
| 130 |
| 131 if (oracle_proxy_.get()) |
| 132 oracle_proxy_->ReportError(reason); |
| 133 |
| 134 StopAndDeAllocate(); |
| 135 TransitionStateTo(kError); |
| 136 } |
| 137 |
| 138 } // namespace media |
OLD | NEW |