Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Unified Diff: media/capture/video/android/video_capture_device_android.cc

Issue 2212343003: Reland: ImageCapture: Queue up requests while device not ready (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable Android tests with bug and explanation Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/capture/video/android/video_capture_device_android.cc
diff --git a/media/capture/video/android/video_capture_device_android.cc b/media/capture/video/android/video_capture_device_android.cc
index a0596b5095c8699cd0b0e1ac3c5a01cee6341665..8df6ca9226053c4bc5c180c10ae00ddeee220222 100644
--- a/media/capture/video/android/video_capture_device_android.cc
+++ b/media/capture/video/android/video_capture_device_android.cc
@@ -12,6 +12,7 @@
#include "base/android/jni_string.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "jni/VideoCapture_jni.h"
#include "media/capture/video/android/photo_capabilities.h"
#include "media/capture/video/android/video_capture_device_factory_android.h"
@@ -34,12 +35,14 @@ bool VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(JNIEnv* env) {
VideoCaptureDeviceAndroid::VideoCaptureDeviceAndroid(
const VideoCaptureDeviceDescriptor& device_descriptor)
- : state_(kIdle),
+ : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ state_(kIdle),
got_first_frame_(false),
- device_descriptor_(device_descriptor) {}
+ device_descriptor_(device_descriptor),
+ weak_ptr_factory_(this) {}
VideoCaptureDeviceAndroid::~VideoCaptureDeviceAndroid() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
StopAndDeAllocate();
}
@@ -56,7 +59,7 @@ bool VideoCaptureDeviceAndroid::Init() {
void VideoCaptureDeviceAndroid::AllocateAndStart(
const VideoCaptureParams& params,
std::unique_ptr<Client> client) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
{
base::AutoLock lock(lock_);
if (state_ != kIdle)
@@ -105,15 +108,15 @@ void VideoCaptureDeviceAndroid::AllocateAndStart(
{
base::AutoLock lock(lock_);
- state_ = kCapturing;
+ state_ = kConfigured;
}
}
void VideoCaptureDeviceAndroid::StopAndDeAllocate() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
{
base::AutoLock lock(lock_);
- if (state_ != kCapturing && state_ != kError)
+ if (state_ != kConfigured && state_ != kError)
return;
}
@@ -135,84 +138,55 @@ void VideoCaptureDeviceAndroid::StopAndDeAllocate() {
}
void VideoCaptureDeviceAndroid::TakePhoto(TakePhotoCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
{
base::AutoLock lock(lock_);
- if (state_ != kCapturing)
+ if (state_ != kConfigured)
return;
+ if (!got_first_frame_) { // We have to wait until we get the first frame.
+ photo_requests_queue_.push_back(
+ base::Bind(&VideoCaptureDeviceAndroid::DoTakePhoto,
+ weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
+ return;
+ }
}
-
- JNIEnv* env = AttachCurrentThread();
-
- // Make copy on the heap so we can pass the pointer through JNI.
- std::unique_ptr<TakePhotoCallback> heap_callback(
- new TakePhotoCallback(std::move(callback)));
- const intptr_t callback_id = reinterpret_cast<intptr_t>(heap_callback.get());
- if (!Java_VideoCapture_takePhoto(env, j_capture_.obj(), callback_id,
- next_photo_resolution_.width(),
- next_photo_resolution_.height()))
- return;
-
- {
- base::AutoLock lock(photo_callbacks_lock_);
- photo_callbacks_.push_back(std::move(heap_callback));
- }
+ DoTakePhoto(std::move(callback));
}
void VideoCaptureDeviceAndroid::GetPhotoCapabilities(
GetPhotoCapabilitiesCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- JNIEnv* env = AttachCurrentThread();
-
- PhotoCapabilities caps(
- Java_VideoCapture_getPhotoCapabilities(env, j_capture_.obj()));
-
- // TODO(mcasas): Manual member copying sucks, consider adding typemapping from
- // PhotoCapabilities to mojom::PhotoCapabilitiesPtr, https://crbug.com/622002.
- mojom::PhotoCapabilitiesPtr photo_capabilities =
- mojom::PhotoCapabilities::New();
- photo_capabilities->iso = mojom::Range::New();
- photo_capabilities->iso->current = caps.getCurrentIso();
- photo_capabilities->iso->max = caps.getMaxIso();
- photo_capabilities->iso->min = caps.getMinIso();
- photo_capabilities->height = mojom::Range::New();
- photo_capabilities->height->current = caps.getCurrentHeight();
- photo_capabilities->height->max = caps.getMaxHeight();
- photo_capabilities->height->min = caps.getMinHeight();
- photo_capabilities->width = mojom::Range::New();
- photo_capabilities->width->current = caps.getCurrentWidth();
- photo_capabilities->width->max = caps.getMaxWidth();
- photo_capabilities->width->min = caps.getMinWidth();
- photo_capabilities->zoom = mojom::Range::New();
- photo_capabilities->zoom->current = caps.getCurrentZoom();
- photo_capabilities->zoom->max = caps.getMaxZoom();
- photo_capabilities->zoom->min = caps.getMinZoom();
- photo_capabilities->focus_mode = caps.getAutoFocusInUse()
- ? mojom::FocusMode::AUTO
- : mojom::FocusMode::MANUAL;
- callback.Run(std::move(photo_capabilities));
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kConfigured)
+ return;
+ if (!got_first_frame_) { // We have to wait until we get the first frame.
+ photo_requests_queue_.push_back(
+ base::Bind(&VideoCaptureDeviceAndroid::DoGetPhotoCapabilities,
+ weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
+ return;
+ }
+ }
+ DoGetPhotoCapabilities(std::move(callback));
}
void VideoCaptureDeviceAndroid::SetPhotoOptions(
mojom::PhotoSettingsPtr settings,
SetPhotoOptionsCallback callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
- JNIEnv* env = AttachCurrentThread();
- // |width| and/or |height| are kept for the next TakePhoto()s.
- if (settings->has_width || settings->has_height)
- next_photo_resolution_.SetSize(0, 0);
- if (settings->has_width) {
- next_photo_resolution_.set_width(
- base::saturated_cast<int>(settings->width));
- }
- if (settings->has_height) {
- next_photo_resolution_.set_height(
- base::saturated_cast<int>(settings->height));
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kConfigured)
+ return;
+ if (!got_first_frame_) { // We have to wait until we get the first frame.
+ photo_requests_queue_.push_back(
+ base::Bind(&VideoCaptureDeviceAndroid::DoSetPhotoOptions,
+ weak_ptr_factory_.GetWeakPtr(), base::Passed(&settings),
+ base::Passed(&callback)));
+ return;
+ }
}
-
- if (settings->has_zoom)
- Java_VideoCapture_setZoom(env, j_capture_.obj(), settings->zoom);
- callback.Run(true);
+ DoSetPhotoOptions(std::move(settings), std::move(callback));
}
void VideoCaptureDeviceAndroid::OnFrameAvailable(
@@ -223,7 +197,7 @@ void VideoCaptureDeviceAndroid::OnFrameAvailable(
jint rotation) {
{
base::AutoLock lock(lock_);
- if (state_ != kCapturing || !client_)
+ if (state_ != kConfigured || !client_)
return;
}
@@ -235,11 +209,18 @@ void VideoCaptureDeviceAndroid::OnFrameAvailable(
}
const base::TimeTicks current_time = base::TimeTicks::Now();
- if (!got_first_frame_) {
- // Set aside one frame allowance for fluctuation.
- expected_next_frame_time_ = current_time - frame_interval_;
- first_ref_time_ = current_time;
- got_first_frame_ = true;
+ {
+ base::AutoLock lock(lock_);
+ if (!got_first_frame_) {
+ // Set aside one frame allowance for fluctuation.
+ expected_next_frame_time_ = current_time - frame_interval_;
+ first_ref_time_ = current_time;
+ got_first_frame_ = true;
+
+ for (const auto& request : photo_requests_queue_)
+ main_task_runner_->PostTask(FROM_HERE, request);
+ photo_requests_queue_.clear();
+ }
}
// Deliver the frame when it doesn't arrive too early.
@@ -272,16 +253,23 @@ void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env,
jint rotation) {
{
base::AutoLock lock(lock_);
- if (state_ != kCapturing || !client_)
+ if (state_ != kConfigured || !client_)
return;
}
const base::TimeTicks current_time = base::TimeTicks::Now();
- if (!got_first_frame_) {
- // Set aside one frame allowance for fluctuation.
- expected_next_frame_time_ = current_time - frame_interval_;
- first_ref_time_ = current_time;
- got_first_frame_ = true;
+ {
+ base::AutoLock lock(lock_);
+ if (!got_first_frame_) {
+ // Set aside one frame allowance for fluctuation.
+ expected_next_frame_time_ = current_time - frame_interval_;
+ first_ref_time_ = current_time;
+ got_first_frame_ = true;
+
+ for (const auto& request : photo_requests_queue_)
+ main_task_runner_->PostTask(FROM_HERE, request);
+ photo_requests_queue_.clear();
+ }
}
uint8_t* const y_src =
@@ -386,4 +374,102 @@ void VideoCaptureDeviceAndroid::SetErrorState(
}
}
+void VideoCaptureDeviceAndroid::DoTakePhoto(TakePhotoCallback callback) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock lock(lock_);
+ DCHECK_EQ(kConfigured, state_);
+ DCHECK(got_first_frame_);
+ }
+#endif
+ JNIEnv* env = AttachCurrentThread();
+
+ // Make copy on the heap so we can pass the pointer through JNI.
+ std::unique_ptr<TakePhotoCallback> heap_callback(
+ new TakePhotoCallback(std::move(callback)));
+ const intptr_t callback_id = reinterpret_cast<intptr_t>(heap_callback.get());
+ if (!Java_VideoCapture_takePhoto(env, j_capture_.obj(), callback_id,
+ next_photo_resolution_.width(),
+ next_photo_resolution_.height()))
+ return;
+
+ {
+ base::AutoLock lock(photo_callbacks_lock_);
+ photo_callbacks_.push_back(std::move(heap_callback));
+ }
+}
+
+void VideoCaptureDeviceAndroid::DoGetPhotoCapabilities(
+ GetPhotoCapabilitiesCallback callback) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock lock(lock_);
+ DCHECK_EQ(kConfigured, state_);
+ DCHECK(got_first_frame_);
+ }
+#endif
+ JNIEnv* env = AttachCurrentThread();
+
+ PhotoCapabilities caps(
+ Java_VideoCapture_getPhotoCapabilities(env, j_capture_.obj()));
+
+ // TODO(mcasas): Manual member copying sucks, consider adding typemapping from
+ // PhotoCapabilities to mojom::PhotoCapabilitiesPtr, https://crbug.com/622002.
+ mojom::PhotoCapabilitiesPtr photo_capabilities =
+ mojom::PhotoCapabilities::New();
+ photo_capabilities->iso = mojom::Range::New();
+ photo_capabilities->iso->current = caps.getCurrentIso();
+ photo_capabilities->iso->max = caps.getMaxIso();
+ photo_capabilities->iso->min = caps.getMinIso();
+ photo_capabilities->height = mojom::Range::New();
+ photo_capabilities->height->current = caps.getCurrentHeight();
+ photo_capabilities->height->max = caps.getMaxHeight();
+ photo_capabilities->height->min = caps.getMinHeight();
+ photo_capabilities->width = mojom::Range::New();
+ photo_capabilities->width->current = caps.getCurrentWidth();
+ photo_capabilities->width->max = caps.getMaxWidth();
+ photo_capabilities->width->min = caps.getMinWidth();
+ photo_capabilities->zoom = mojom::Range::New();
+ photo_capabilities->zoom->current = caps.getCurrentZoom();
+ photo_capabilities->zoom->max = caps.getMaxZoom();
+ photo_capabilities->zoom->min = caps.getMinZoom();
+ photo_capabilities->focus_mode = caps.getAutoFocusInUse()
+ ? mojom::FocusMode::AUTO
+ : mojom::FocusMode::MANUAL;
+ callback.Run(std::move(photo_capabilities));
+}
+
+void VideoCaptureDeviceAndroid::DoSetPhotoOptions(
+ mojom::PhotoSettingsPtr settings,
+ SetPhotoOptionsCallback callback) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+#if DCHECK_IS_ON()
+ {
+ base::AutoLock lock(lock_);
+ DCHECK_EQ(kConfigured, state_);
+ DCHECK(got_first_frame_);
+ }
+#endif
+ JNIEnv* env = AttachCurrentThread();
+
+ // |width| and/or |height| are kept for the next TakePhoto()s.
+ if (settings->has_width || settings->has_height)
+ next_photo_resolution_.SetSize(0, 0);
+ if (settings->has_width) {
+ next_photo_resolution_.set_width(
+ base::saturated_cast<int>(settings->width));
+ }
+ if (settings->has_height) {
+ next_photo_resolution_.set_height(
+ base::saturated_cast<int>(settings->height));
+ }
+
+ if (settings->has_zoom)
+ Java_VideoCapture_setZoom(env, j_capture_.obj(), settings->zoom);
+
+ callback.Run(true);
+}
+
} // namespace media
« no previous file with comments | « media/capture/video/android/video_capture_device_android.h ('k') | media/capture/video/fake_video_capture_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698