Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/capture/video/android/video_capture_device_android.h" | 5 #include "media/capture/video/android/video_capture_device_android.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/android/jni_android.h" | 10 #include "base/android/jni_android.h" |
| 11 #include "base/android/jni_array.h" | 11 #include "base/android/jni_array.h" |
| 12 #include "base/android/jni_string.h" | 12 #include "base/android/jni_string.h" |
| 13 #include "base/numerics/safe_conversions.h" | 13 #include "base/numerics/safe_conversions.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | |
| 15 #include "jni/VideoCapture_jni.h" | 16 #include "jni/VideoCapture_jni.h" |
| 16 #include "media/capture/video/android/photo_capabilities.h" | 17 #include "media/capture/video/android/photo_capabilities.h" |
| 17 #include "media/capture/video/android/video_capture_device_factory_android.h" | 18 #include "media/capture/video/android/video_capture_device_factory_android.h" |
| 18 #include "third_party/libyuv/include/libyuv.h" | 19 #include "third_party/libyuv/include/libyuv.h" |
| 19 | 20 |
| 20 using base::android::AttachCurrentThread; | 21 using base::android::AttachCurrentThread; |
| 21 using base::android::CheckException; | 22 using base::android::CheckException; |
| 22 using base::android::GetClass; | 23 using base::android::GetClass; |
| 23 using base::android::MethodID; | 24 using base::android::MethodID; |
| 24 using base::android::JavaRef; | 25 using base::android::JavaRef; |
| 25 using base::android::ScopedJavaLocalRef; | 26 using base::android::ScopedJavaLocalRef; |
| 26 | 27 |
| 27 namespace media { | 28 namespace media { |
| 28 | 29 |
| 29 // static | 30 // static |
| 30 bool VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(JNIEnv* env) { | 31 bool VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(JNIEnv* env) { |
| 31 return RegisterNativesImpl(env); | 32 return RegisterNativesImpl(env); |
| 32 } | 33 } |
| 33 | 34 |
| 34 VideoCaptureDeviceAndroid::VideoCaptureDeviceAndroid( | 35 VideoCaptureDeviceAndroid::VideoCaptureDeviceAndroid( |
| 35 const VideoCaptureDeviceDescriptor& device_descriptor) | 36 const VideoCaptureDeviceDescriptor& device_descriptor) |
| 36 : state_(kIdle), | 37 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 38 state_(kIdle), | |
| 37 got_first_frame_(false), | 39 got_first_frame_(false), |
| 38 device_descriptor_(device_descriptor) {} | 40 device_descriptor_(device_descriptor), |
| 41 weak_ptr_factory_(this) {} | |
| 39 | 42 |
| 40 VideoCaptureDeviceAndroid::~VideoCaptureDeviceAndroid() { | 43 VideoCaptureDeviceAndroid::~VideoCaptureDeviceAndroid() { |
| 41 DCHECK(thread_checker_.CalledOnValidThread()); | 44 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 42 StopAndDeAllocate(); | 45 StopAndDeAllocate(); |
| 43 } | 46 } |
| 44 | 47 |
| 45 bool VideoCaptureDeviceAndroid::Init() { | 48 bool VideoCaptureDeviceAndroid::Init() { |
| 46 int id; | 49 int id; |
| 47 if (!base::StringToInt(device_descriptor_.device_id, &id)) | 50 if (!base::StringToInt(device_descriptor_.device_id, &id)) |
| 48 return false; | 51 return false; |
| 49 | 52 |
| 50 j_capture_.Reset(VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid( | 53 j_capture_.Reset(VideoCaptureDeviceFactoryAndroid::createVideoCaptureAndroid( |
| 51 id, reinterpret_cast<intptr_t>(this))); | 54 id, reinterpret_cast<intptr_t>(this))); |
| 52 return true; | 55 return true; |
| 53 } | 56 } |
| 54 | 57 |
| 55 void VideoCaptureDeviceAndroid::AllocateAndStart( | 58 void VideoCaptureDeviceAndroid::AllocateAndStart( |
| 56 const VideoCaptureParams& params, | 59 const VideoCaptureParams& params, |
| 57 std::unique_ptr<Client> client) { | 60 std::unique_ptr<Client> client) { |
| 58 DCHECK(thread_checker_.CalledOnValidThread()); | 61 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 59 { | 62 { |
| 60 base::AutoLock lock(lock_); | 63 base::AutoLock lock(lock_); |
| 61 if (state_ != kIdle) | 64 if (state_ != kIdle) |
| 62 return; | 65 return; |
| 63 client_ = std::move(client); | 66 client_ = std::move(client); |
| 64 got_first_frame_ = false; | 67 got_first_frame_ = false; |
| 65 } | 68 } |
| 66 | 69 |
| 67 JNIEnv* env = AttachCurrentThread(); | 70 JNIEnv* env = AttachCurrentThread(); |
| 68 | 71 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 97 << capture_format_.frame_rate << "fps"; | 100 << capture_format_.frame_rate << "fps"; |
| 98 | 101 |
| 99 ret = Java_VideoCapture_startCapture(env, j_capture_.obj()); | 102 ret = Java_VideoCapture_startCapture(env, j_capture_.obj()); |
| 100 if (!ret) { | 103 if (!ret) { |
| 101 SetErrorState(FROM_HERE, "failed to start capture"); | 104 SetErrorState(FROM_HERE, "failed to start capture"); |
| 102 return; | 105 return; |
| 103 } | 106 } |
| 104 | 107 |
| 105 { | 108 { |
| 106 base::AutoLock lock(lock_); | 109 base::AutoLock lock(lock_); |
| 107 state_ = kCapturing; | 110 state_ = kConfigured; |
| 108 } | 111 } |
| 109 } | 112 } |
| 110 | 113 |
| 111 void VideoCaptureDeviceAndroid::StopAndDeAllocate() { | 114 void VideoCaptureDeviceAndroid::StopAndDeAllocate() { |
| 112 DCHECK(thread_checker_.CalledOnValidThread()); | 115 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 113 { | 116 { |
| 114 base::AutoLock lock(lock_); | 117 base::AutoLock lock(lock_); |
| 115 if (state_ != kCapturing && state_ != kError) | 118 if (state_ != kConfigured && state_ != kError) |
| 116 return; | 119 return; |
| 117 } | 120 } |
| 118 | 121 |
| 119 JNIEnv* env = AttachCurrentThread(); | 122 JNIEnv* env = AttachCurrentThread(); |
| 120 | 123 |
| 121 const jboolean ret = Java_VideoCapture_stopCapture(env, j_capture_.obj()); | 124 const jboolean ret = Java_VideoCapture_stopCapture(env, j_capture_.obj()); |
| 122 if (!ret) { | 125 if (!ret) { |
| 123 SetErrorState(FROM_HERE, "failed to stop capture"); | 126 SetErrorState(FROM_HERE, "failed to stop capture"); |
| 124 return; | 127 return; |
| 125 } | 128 } |
| 126 | 129 |
| 127 { | 130 { |
| 128 base::AutoLock lock(lock_); | 131 base::AutoLock lock(lock_); |
| 129 state_ = kIdle; | 132 state_ = kIdle; |
| 130 client_.reset(); | 133 client_.reset(); |
| 131 } | 134 } |
| 132 | 135 |
| 133 Java_VideoCapture_deallocate(env, j_capture_.obj()); | 136 Java_VideoCapture_deallocate(env, j_capture_.obj()); |
| 134 } | 137 } |
| 135 | 138 |
| 136 void VideoCaptureDeviceAndroid::TakePhoto(TakePhotoCallback callback) { | 139 void VideoCaptureDeviceAndroid::TakePhoto(TakePhotoCallback callback) { |
| 137 DCHECK(thread_checker_.CalledOnValidThread()); | 140 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 138 { | 141 { |
| 139 base::AutoLock lock(lock_); | 142 base::AutoLock lock(lock_); |
| 140 if (state_ != kCapturing) | 143 if (state_ != kConfigured) |
| 141 return; | 144 return; |
| 145 if (!got_first_frame_) { // We have to wait until we get the first frame. | |
| 146 photo_requests_queue_.push_back( | |
| 147 base::Bind(&VideoCaptureDeviceAndroid::DoTakePhoto, | |
| 148 weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback))); | |
| 149 return; | |
| 150 } | |
| 142 } | 151 } |
| 143 | 152 DoTakePhoto(std::move(callback)); |
| 144 JNIEnv* env = AttachCurrentThread(); | |
| 145 | |
| 146 // Make copy on the heap so we can pass the pointer through JNI. | |
| 147 std::unique_ptr<TakePhotoCallback> heap_callback( | |
| 148 new TakePhotoCallback(std::move(callback))); | |
| 149 const intptr_t callback_id = reinterpret_cast<intptr_t>(heap_callback.get()); | |
| 150 if (!Java_VideoCapture_takePhoto(env, j_capture_.obj(), callback_id, | |
| 151 next_photo_resolution_.width(), | |
| 152 next_photo_resolution_.height())) | |
| 153 return; | |
| 154 | |
| 155 { | |
| 156 base::AutoLock lock(photo_callbacks_lock_); | |
| 157 photo_callbacks_.push_back(std::move(heap_callback)); | |
| 158 } | |
| 159 } | 153 } |
| 160 | 154 |
| 161 void VideoCaptureDeviceAndroid::GetPhotoCapabilities( | 155 void VideoCaptureDeviceAndroid::GetPhotoCapabilities( |
| 162 GetPhotoCapabilitiesCallback callback) { | 156 GetPhotoCapabilitiesCallback callback) { |
| 163 DCHECK(thread_checker_.CalledOnValidThread()); | 157 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 164 JNIEnv* env = AttachCurrentThread(); | 158 { |
| 165 | 159 base::AutoLock lock(lock_); |
| 166 PhotoCapabilities caps( | 160 if (state_ != kConfigured) |
| 167 Java_VideoCapture_getPhotoCapabilities(env, j_capture_.obj())); | 161 return; |
| 168 | 162 if (!got_first_frame_) { // We have to wait until we get the first frame. |
| 169 // TODO(mcasas): Manual member copying sucks, consider adding typemapping from | 163 photo_requests_queue_.push_back( |
| 170 // PhotoCapabilities to mojom::PhotoCapabilitiesPtr, https://crbug.com/622002. | 164 base::Bind(&VideoCaptureDeviceAndroid::DoGetPhotoCapabilities, |
| 171 mojom::PhotoCapabilitiesPtr photo_capabilities = | 165 weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback))); |
| 172 mojom::PhotoCapabilities::New(); | 166 return; |
| 173 photo_capabilities->iso = mojom::Range::New(); | 167 } |
| 174 photo_capabilities->iso->current = caps.getCurrentIso(); | 168 } |
| 175 photo_capabilities->iso->max = caps.getMaxIso(); | 169 DoGetPhotoCapabilities(std::move(callback)); |
| 176 photo_capabilities->iso->min = caps.getMinIso(); | |
| 177 photo_capabilities->height = mojom::Range::New(); | |
| 178 photo_capabilities->height->current = caps.getCurrentHeight(); | |
| 179 photo_capabilities->height->max = caps.getMaxHeight(); | |
| 180 photo_capabilities->height->min = caps.getMinHeight(); | |
| 181 photo_capabilities->width = mojom::Range::New(); | |
| 182 photo_capabilities->width->current = caps.getCurrentWidth(); | |
| 183 photo_capabilities->width->max = caps.getMaxWidth(); | |
| 184 photo_capabilities->width->min = caps.getMinWidth(); | |
| 185 photo_capabilities->zoom = mojom::Range::New(); | |
| 186 photo_capabilities->zoom->current = caps.getCurrentZoom(); | |
| 187 photo_capabilities->zoom->max = caps.getMaxZoom(); | |
| 188 photo_capabilities->zoom->min = caps.getMinZoom(); | |
| 189 photo_capabilities->focus_mode = caps.getAutoFocusInUse() | |
| 190 ? mojom::FocusMode::AUTO | |
| 191 : mojom::FocusMode::MANUAL; | |
| 192 callback.Run(std::move(photo_capabilities)); | |
| 193 } | 170 } |
| 194 | 171 |
| 195 void VideoCaptureDeviceAndroid::SetPhotoOptions( | 172 void VideoCaptureDeviceAndroid::SetPhotoOptions( |
| 196 mojom::PhotoSettingsPtr settings, | 173 mojom::PhotoSettingsPtr settings, |
| 197 SetPhotoOptionsCallback callback) { | 174 SetPhotoOptionsCallback callback) { |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 175 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 199 JNIEnv* env = AttachCurrentThread(); | 176 { |
| 200 // |width| and/or |height| are kept for the next TakePhoto()s. | 177 base::AutoLock lock(lock_); |
| 201 if (settings->has_width || settings->has_height) | 178 if (state_ != kConfigured) |
| 202 next_photo_resolution_.SetSize(0, 0); | 179 return; |
| 203 if (settings->has_width) { | 180 if (!got_first_frame_) { // We have to wait until we get the first frame. |
| 204 next_photo_resolution_.set_width( | 181 photo_requests_queue_.push_back( |
| 205 base::saturated_cast<int>(settings->width)); | 182 base::Bind(&VideoCaptureDeviceAndroid::DoSetPhotoOptions, |
| 183 weak_ptr_factory_.GetWeakPtr(), base::Passed(&settings), | |
| 184 base::Passed(&callback))); | |
| 185 return; | |
| 186 } | |
| 206 } | 187 } |
| 207 if (settings->has_height) { | 188 DoSetPhotoOptions(std::move(settings), std::move(callback)); |
| 208 next_photo_resolution_.set_height( | |
| 209 base::saturated_cast<int>(settings->height)); | |
| 210 } | |
| 211 | |
| 212 if (settings->has_zoom) | |
| 213 Java_VideoCapture_setZoom(env, j_capture_.obj(), settings->zoom); | |
| 214 callback.Run(true); | |
| 215 } | 189 } |
| 216 | 190 |
| 217 void VideoCaptureDeviceAndroid::OnFrameAvailable( | 191 void VideoCaptureDeviceAndroid::OnFrameAvailable( |
| 218 JNIEnv* env, | 192 JNIEnv* env, |
| 219 const JavaParamRef<jobject>& obj, | 193 const JavaParamRef<jobject>& obj, |
| 220 const JavaParamRef<jbyteArray>& data, | 194 const JavaParamRef<jbyteArray>& data, |
| 221 jint length, | 195 jint length, |
| 222 jint rotation) { | 196 jint rotation) { |
| 223 { | 197 { |
| 224 base::AutoLock lock(lock_); | 198 base::AutoLock lock(lock_); |
| 225 if (state_ != kCapturing || !client_) | 199 if (state_ != kConfigured || !client_) |
| 226 return; | 200 return; |
| 227 } | 201 } |
| 228 | 202 |
| 229 jbyte* buffer = env->GetByteArrayElements(data, NULL); | 203 jbyte* buffer = env->GetByteArrayElements(data, NULL); |
| 230 if (!buffer) { | 204 if (!buffer) { |
| 231 LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: " | 205 LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: " |
| 232 "failed to GetByteArrayElements"; | 206 "failed to GetByteArrayElements"; |
| 233 return; | 207 return; |
| 234 } | 208 } |
| 235 | 209 |
| 236 const base::TimeTicks current_time = base::TimeTicks::Now(); | 210 const base::TimeTicks current_time = base::TimeTicks::Now(); |
| 237 if (!got_first_frame_) { | 211 { |
| 238 // Set aside one frame allowance for fluctuation. | 212 base::AutoLock lock(lock_); |
| 239 expected_next_frame_time_ = current_time - frame_interval_; | 213 if (!got_first_frame_) { |
| 240 first_ref_time_ = current_time; | 214 // Set aside one frame allowance for fluctuation. |
| 241 got_first_frame_ = true; | 215 expected_next_frame_time_ = current_time - frame_interval_; |
| 216 first_ref_time_ = current_time; | |
| 217 got_first_frame_ = true; | |
| 218 | |
| 219 for (const auto& request : photo_requests_queue_) | |
| 220 main_task_runner_->PostTask(FROM_HERE, request); | |
|
emircan
2016/08/03 21:55:54
photo_requests_queue_.clear();
mcasas
2016/08/03 22:19:36
Done.
| |
| 221 } | |
| 242 } | 222 } |
| 243 | 223 |
| 244 // Deliver the frame when it doesn't arrive too early. | 224 // Deliver the frame when it doesn't arrive too early. |
| 245 if (expected_next_frame_time_ <= current_time) { | 225 if (expected_next_frame_time_ <= current_time) { |
| 246 expected_next_frame_time_ += frame_interval_; | 226 expected_next_frame_time_ += frame_interval_; |
| 247 | 227 |
| 248 // TODO(qiangchen): Investigate how to get raw timestamp for Android, | 228 // TODO(qiangchen): Investigate how to get raw timestamp for Android, |
| 249 // rather than using reference time to calculate timestamp. | 229 // rather than using reference time to calculate timestamp. |
| 250 base::AutoLock lock(lock_); | 230 base::AutoLock lock(lock_); |
| 251 if (!client_) | 231 if (!client_) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 264 jint y_stride, | 244 jint y_stride, |
| 265 jobject u_buffer, | 245 jobject u_buffer, |
| 266 jobject v_buffer, | 246 jobject v_buffer, |
| 267 jint uv_row_stride, | 247 jint uv_row_stride, |
| 268 jint uv_pixel_stride, | 248 jint uv_pixel_stride, |
| 269 jint width, | 249 jint width, |
| 270 jint height, | 250 jint height, |
| 271 jint rotation) { | 251 jint rotation) { |
| 272 { | 252 { |
| 273 base::AutoLock lock(lock_); | 253 base::AutoLock lock(lock_); |
| 274 if (state_ != kCapturing || !client_) | 254 if (state_ != kConfigured || !client_) |
| 275 return; | 255 return; |
| 276 } | 256 } |
| 277 | 257 |
| 278 const base::TimeTicks current_time = base::TimeTicks::Now(); | 258 const base::TimeTicks current_time = base::TimeTicks::Now(); |
| 279 if (!got_first_frame_) { | 259 { |
| 280 // Set aside one frame allowance for fluctuation. | 260 base::AutoLock lock(lock_); |
| 281 expected_next_frame_time_ = current_time - frame_interval_; | 261 if (!got_first_frame_) { |
| 282 first_ref_time_ = current_time; | 262 // Set aside one frame allowance for fluctuation. |
| 283 got_first_frame_ = true; | 263 expected_next_frame_time_ = current_time - frame_interval_; |
| 264 first_ref_time_ = current_time; | |
| 265 got_first_frame_ = true; | |
| 266 | |
| 267 for (const auto& request : photo_requests_queue_) | |
| 268 main_task_runner_->PostTask(FROM_HERE, request); | |
| 269 photo_requests_queue_.clear(); | |
| 270 } | |
| 284 } | 271 } |
| 285 | 272 |
| 286 uint8_t* const y_src = | 273 uint8_t* const y_src = |
| 287 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer)); | 274 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer)); |
| 288 CHECK(y_src); | 275 CHECK(y_src); |
| 289 uint8_t* const u_src = | 276 uint8_t* const u_src = |
| 290 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer)); | 277 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer)); |
| 291 CHECK(u_src); | 278 CHECK(u_src); |
| 292 uint8_t* const v_src = | 279 uint8_t* const v_src = |
| 293 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer)); | 280 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 const std::string& reason) { | 365 const std::string& reason) { |
| 379 { | 366 { |
| 380 base::AutoLock lock(lock_); | 367 base::AutoLock lock(lock_); |
| 381 state_ = kError; | 368 state_ = kError; |
| 382 if (!client_) | 369 if (!client_) |
| 383 return; | 370 return; |
| 384 client_->OnError(from_here, reason); | 371 client_->OnError(from_here, reason); |
| 385 } | 372 } |
| 386 } | 373 } |
| 387 | 374 |
| 375 void VideoCaptureDeviceAndroid::DoTakePhoto(TakePhotoCallback callback) { | |
| 376 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 377 #if DCHECK_IS_ON() | |
| 378 { | |
| 379 base::AutoLock lock(lock_); | |
| 380 DCHECK_EQ(kConfigured, state_); | |
| 381 DCHECK(got_first_frame_); | |
| 382 } | |
| 383 #endif | |
| 384 JNIEnv* env = AttachCurrentThread(); | |
| 385 | |
| 386 // Make copy on the heap so we can pass the pointer through JNI. | |
| 387 std::unique_ptr<TakePhotoCallback> heap_callback( | |
| 388 new TakePhotoCallback(std::move(callback))); | |
| 389 const intptr_t callback_id = reinterpret_cast<intptr_t>(heap_callback.get()); | |
| 390 if (!Java_VideoCapture_takePhoto(env, j_capture_.obj(), callback_id, | |
| 391 next_photo_resolution_.width(), | |
| 392 next_photo_resolution_.height())) | |
| 393 return; | |
| 394 | |
| 395 { | |
| 396 base::AutoLock lock(photo_callbacks_lock_); | |
| 397 photo_callbacks_.push_back(std::move(heap_callback)); | |
| 398 } | |
| 399 } | |
| 400 | |
| 401 void VideoCaptureDeviceAndroid::DoGetPhotoCapabilities( | |
| 402 GetPhotoCapabilitiesCallback callback) { | |
| 403 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 404 #if DCHECK_IS_ON() | |
| 405 { | |
| 406 base::AutoLock lock(lock_); | |
| 407 DCHECK_EQ(kConfigured, state_); | |
| 408 DCHECK(got_first_frame_); | |
| 409 } | |
| 410 #endif | |
| 411 JNIEnv* env = AttachCurrentThread(); | |
| 412 | |
| 413 PhotoCapabilities caps( | |
| 414 Java_VideoCapture_getPhotoCapabilities(env, j_capture_.obj())); | |
| 415 | |
| 416 // TODO(mcasas): Manual member copying sucks, consider adding typemapping from | |
| 417 // PhotoCapabilities to mojom::PhotoCapabilitiesPtr, https://crbug.com/622002. | |
| 418 mojom::PhotoCapabilitiesPtr photo_capabilities = | |
| 419 mojom::PhotoCapabilities::New(); | |
| 420 photo_capabilities->iso = mojom::Range::New(); | |
| 421 photo_capabilities->iso->current = caps.getCurrentIso(); | |
| 422 photo_capabilities->iso->max = caps.getMaxIso(); | |
| 423 photo_capabilities->iso->min = caps.getMinIso(); | |
| 424 photo_capabilities->height = mojom::Range::New(); | |
| 425 photo_capabilities->height->current = caps.getCurrentHeight(); | |
| 426 photo_capabilities->height->max = caps.getMaxHeight(); | |
| 427 photo_capabilities->height->min = caps.getMinHeight(); | |
| 428 photo_capabilities->width = mojom::Range::New(); | |
| 429 photo_capabilities->width->current = caps.getCurrentWidth(); | |
| 430 photo_capabilities->width->max = caps.getMaxWidth(); | |
| 431 photo_capabilities->width->min = caps.getMinWidth(); | |
| 432 photo_capabilities->zoom = mojom::Range::New(); | |
| 433 photo_capabilities->zoom->current = caps.getCurrentZoom(); | |
| 434 photo_capabilities->zoom->max = caps.getMaxZoom(); | |
| 435 photo_capabilities->zoom->min = caps.getMinZoom(); | |
| 436 photo_capabilities->focus_mode = caps.getAutoFocusInUse() | |
| 437 ? mojom::FocusMode::AUTO | |
| 438 : mojom::FocusMode::MANUAL; | |
| 439 callback.Run(std::move(photo_capabilities)); | |
| 440 } | |
| 441 | |
| 442 void VideoCaptureDeviceAndroid::DoSetPhotoOptions( | |
| 443 mojom::PhotoSettingsPtr settings, | |
| 444 SetPhotoOptionsCallback callback) { | |
| 445 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 446 #if DCHECK_IS_ON() | |
| 447 { | |
| 448 base::AutoLock lock(lock_); | |
| 449 DCHECK_EQ(kConfigured, state_); | |
| 450 DCHECK(got_first_frame_); | |
| 451 } | |
| 452 #endif | |
| 453 JNIEnv* env = AttachCurrentThread(); | |
| 454 | |
| 455 // |width| and/or |height| are kept for the next TakePhoto()s. | |
| 456 if (settings->has_width || settings->has_height) | |
| 457 next_photo_resolution_.SetSize(0, 0); | |
| 458 if (settings->has_width) { | |
| 459 next_photo_resolution_.set_width( | |
| 460 base::saturated_cast<int>(settings->width)); | |
| 461 } | |
| 462 if (settings->has_height) { | |
| 463 next_photo_resolution_.set_height( | |
| 464 base::saturated_cast<int>(settings->height)); | |
| 465 } | |
| 466 | |
| 467 if (settings->has_zoom) | |
| 468 Java_VideoCapture_setZoom(env, j_capture_.obj(), settings->zoom); | |
| 469 | |
| 470 callback.Run(true); | |
| 471 } | |
| 472 | |
| 388 } // namespace media | 473 } // namespace media |
| OLD | NEW |