| 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" |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 "failed to GetByteArrayElements"; | 245 "failed to GetByteArrayElements"; |
| 246 return; | 246 return; |
| 247 } | 247 } |
| 248 | 248 |
| 249 const base::TimeTicks current_time = base::TimeTicks::Now(); | 249 const base::TimeTicks current_time = base::TimeTicks::Now(); |
| 250 { | 250 { |
| 251 base::AutoLock lock(lock_); | 251 base::AutoLock lock(lock_); |
| 252 if (!got_first_frame_) { | 252 if (!got_first_frame_) { |
| 253 // Set aside one frame allowance for fluctuation. | 253 // Set aside one frame allowance for fluctuation. |
| 254 expected_next_frame_time_ = current_time - frame_interval_; | 254 expected_next_frame_time_ = current_time - frame_interval_; |
| 255 first_ref_time_ = current_time; | |
| 256 got_first_frame_ = true; | 255 got_first_frame_ = true; |
| 257 | 256 |
| 258 for (const auto& request : photo_requests_queue_) | 257 for (const auto& request : photo_requests_queue_) |
| 259 main_task_runner_->PostTask(FROM_HERE, request); | 258 main_task_runner_->PostTask(FROM_HERE, request); |
| 260 photo_requests_queue_.clear(); | 259 photo_requests_queue_.clear(); |
| 261 } | 260 } |
| 262 } | 261 } |
| 263 | 262 |
| 264 // Deliver the frame when it doesn't arrive too early. | 263 // Deliver the frame when it doesn't arrive too early. |
| 265 if (expected_next_frame_time_ <= current_time) { | 264 if (expected_next_frame_time_ <= current_time) { |
| 265 // Using |expected_next_frame_time_| to estimate a proper capture timestamp |
| 266 // since android.hardware.Camera API doesn't expose a better timestamp. |
| 267 const base::TimeDelta capture_time = |
| 268 expected_next_frame_time_ - base::TimeTicks(); |
| 269 |
| 266 expected_next_frame_time_ += frame_interval_; | 270 expected_next_frame_time_ += frame_interval_; |
| 267 | 271 |
| 268 // TODO(qiangchen): Investigate how to get raw timestamp for Android, | 272 // TODO(qiangchen): Investigate how to get raw timestamp for Android, |
| 269 // rather than using reference time to calculate timestamp. | 273 // rather than using reference time to calculate timestamp. |
| 270 base::AutoLock lock(lock_); | 274 base::AutoLock lock(lock_); |
| 271 if (!client_) | 275 if (!client_) |
| 272 return; | 276 return; |
| 273 client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length, | 277 client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length, |
| 274 capture_format_, rotation, current_time, | 278 capture_format_, rotation, current_time, |
| 275 current_time - first_ref_time_); | 279 capture_time); |
| 276 } | 280 } |
| 277 | 281 |
| 278 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT); | 282 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT); |
| 279 } | 283 } |
| 280 | 284 |
| 281 void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env, | 285 void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env, |
| 282 jobject obj, | 286 jobject obj, |
| 283 jobject y_buffer, | 287 jobject y_buffer, |
| 284 jint y_stride, | 288 jint y_stride, |
| 285 jobject u_buffer, | 289 jobject u_buffer, |
| 286 jobject v_buffer, | 290 jobject v_buffer, |
| 287 jint uv_row_stride, | 291 jint uv_row_stride, |
| 288 jint uv_pixel_stride, | 292 jint uv_pixel_stride, |
| 289 jint width, | 293 jint width, |
| 290 jint height, | 294 jint height, |
| 291 jint rotation) { | 295 jint rotation, |
| 296 jlong timestamp) { |
| 292 { | 297 { |
| 293 base::AutoLock lock(lock_); | 298 base::AutoLock lock(lock_); |
| 294 if (state_ != kConfigured || !client_) | 299 if (state_ != kConfigured || !client_) |
| 295 return; | 300 return; |
| 296 } | 301 } |
| 302 const int64_t absolute_micro = |
| 303 timestamp / base::Time::kNanosecondsPerMicrosecond; |
| 304 const base::TimeDelta capture_time = |
| 305 base::TimeDelta::FromMicroseconds(absolute_micro); |
| 297 | 306 |
| 298 const base::TimeTicks current_time = base::TimeTicks::Now(); | 307 const base::TimeTicks current_time = base::TimeTicks::Now(); |
| 299 { | 308 { |
| 300 base::AutoLock lock(lock_); | 309 base::AutoLock lock(lock_); |
| 301 if (!got_first_frame_) { | 310 if (!got_first_frame_) { |
| 302 // Set aside one frame allowance for fluctuation. | 311 // Set aside one frame allowance for fluctuation. |
| 303 expected_next_frame_time_ = current_time - frame_interval_; | 312 expected_next_frame_time_ = current_time - frame_interval_; |
| 304 first_ref_time_ = current_time; | |
| 305 got_first_frame_ = true; | 313 got_first_frame_ = true; |
| 306 | 314 |
| 307 for (const auto& request : photo_requests_queue_) | 315 for (const auto& request : photo_requests_queue_) |
| 308 main_task_runner_->PostTask(FROM_HERE, request); | 316 main_task_runner_->PostTask(FROM_HERE, request); |
| 309 photo_requests_queue_.clear(); | 317 photo_requests_queue_.clear(); |
| 310 } | 318 } |
| 311 } | 319 } |
| 312 | 320 |
| 313 uint8_t* const y_src = | 321 uint8_t* const y_src = |
| 314 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer)); | 322 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 335 if (expected_next_frame_time_ <= current_time) { | 343 if (expected_next_frame_time_ <= current_time) { |
| 336 expected_next_frame_time_ += frame_interval_; | 344 expected_next_frame_time_ += frame_interval_; |
| 337 | 345 |
| 338 // TODO(qiangchen): Investigate how to get raw timestamp for Android, | 346 // TODO(qiangchen): Investigate how to get raw timestamp for Android, |
| 339 // rather than using reference time to calculate timestamp. | 347 // rather than using reference time to calculate timestamp. |
| 340 base::AutoLock lock(lock_); | 348 base::AutoLock lock(lock_); |
| 341 if (!client_) | 349 if (!client_) |
| 342 return; | 350 return; |
| 343 client_->OnIncomingCapturedData(buffer.get(), buffer_length, | 351 client_->OnIncomingCapturedData(buffer.get(), buffer_length, |
| 344 capture_format_, rotation, current_time, | 352 capture_format_, rotation, current_time, |
| 345 current_time - first_ref_time_); | 353 capture_time); |
| 346 } | 354 } |
| 347 } | 355 } |
| 348 | 356 |
| 349 void VideoCaptureDeviceAndroid::OnError(JNIEnv* env, | 357 void VideoCaptureDeviceAndroid::OnError(JNIEnv* env, |
| 350 const JavaParamRef<jobject>& obj, | 358 const JavaParamRef<jobject>& obj, |
| 351 const JavaParamRef<jstring>& message) { | 359 const JavaParamRef<jstring>& message) { |
| 352 SetErrorState(FROM_HERE, | 360 SetErrorState(FROM_HERE, |
| 353 base::android::ConvertJavaStringToUTF8(env, message)); | 361 base::android::ConvertJavaStringToUTF8(env, message)); |
| 354 } | 362 } |
| 355 | 363 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 | 533 |
| 526 Java_VideoCapture_setPhotoOptions( | 534 Java_VideoCapture_setPhotoOptions( |
| 527 env, j_capture_, zoom, static_cast<int>(focus_mode), | 535 env, j_capture_, zoom, static_cast<int>(focus_mode), |
| 528 static_cast<int>(exposure_mode), width, height, points_of_interest, | 536 static_cast<int>(exposure_mode), width, height, points_of_interest, |
| 529 settings->has_exposure_compensation, exposure_compensation); | 537 settings->has_exposure_compensation, exposure_compensation); |
| 530 | 538 |
| 531 callback.Run(true); | 539 callback.Run(true); |
| 532 } | 540 } |
| 533 | 541 |
| 534 } // namespace media | 542 } // namespace media |
| OLD | NEW |