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

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

Issue 2219813002: Revert of ImageCapture: Queue up requests while device not ready (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 e388e9085140e6d35bc3e5db9808acc9627f2f32..3d0774c2307a907b8e3858b12e3c1e012d02232f 100644
--- a/media/capture/video/android/video_capture_device_android.cc
+++ b/media/capture/video/android/video_capture_device_android.cc
@@ -12,7 +12,6 @@
#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,14 +33,12 @@
VideoCaptureDeviceAndroid::VideoCaptureDeviceAndroid(
const VideoCaptureDeviceDescriptor& device_descriptor)
- : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- state_(kIdle),
+ : state_(kIdle),
got_first_frame_(false),
- device_descriptor_(device_descriptor),
- weak_ptr_factory_(this) {}
+ device_descriptor_(device_descriptor) {}
VideoCaptureDeviceAndroid::~VideoCaptureDeviceAndroid() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
StopAndDeAllocate();
}
@@ -58,7 +55,7 @@
void VideoCaptureDeviceAndroid::AllocateAndStart(
const VideoCaptureParams& params,
std::unique_ptr<Client> client) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
{
base::AutoLock lock(lock_);
if (state_ != kIdle)
@@ -107,15 +104,15 @@
{
base::AutoLock lock(lock_);
- state_ = kConfigured;
+ state_ = kCapturing;
}
}
void VideoCaptureDeviceAndroid::StopAndDeAllocate() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
- {
- base::AutoLock lock(lock_);
- if (state_ != kConfigured && state_ != kError)
+ DCHECK(thread_checker_.CalledOnValidThread());
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kCapturing && state_ != kError)
return;
}
@@ -137,251 +134,13 @@
}
void VideoCaptureDeviceAndroid::TakePhoto(TakePhotoCallback callback) {
- 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::DoTakePhoto,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
- return;
- }
- }
- DoTakePhoto(std::move(callback));
-}
-
-void VideoCaptureDeviceAndroid::GetPhotoCapabilities(
- GetPhotoCapabilitiesCallback callback) {
- 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(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;
- }
- }
- DoSetPhotoOptions(std::move(settings), std::move(callback));
-}
-
-void VideoCaptureDeviceAndroid::OnFrameAvailable(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jbyteArray>& data,
- jint length,
- jint rotation) {
- {
- base::AutoLock lock(lock_);
- if (state_ != kConfigured || !client_)
- return;
- }
-
- jbyte* buffer = env->GetByteArrayElements(data, NULL);
- if (!buffer) {
- LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: "
- "failed to GetByteArrayElements";
- return;
- }
-
- const base::TimeTicks current_time = base::TimeTicks::Now();
- {
- 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.
- if (expected_next_frame_time_ <= current_time) {
- expected_next_frame_time_ += frame_interval_;
-
- // TODO(qiangchen): Investigate how to get raw timestamp for Android,
- // rather than using reference time to calculate timestamp.
- base::AutoLock lock(lock_);
- if (!client_)
- return;
- client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length,
- capture_format_, rotation, current_time,
- current_time - first_ref_time_);
- }
-
- env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
-}
-
-void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env,
- jobject obj,
- jobject y_buffer,
- jint y_stride,
- jobject u_buffer,
- jobject v_buffer,
- jint uv_row_stride,
- jint uv_pixel_stride,
- jint width,
- jint height,
- jint rotation) {
- {
- base::AutoLock lock(lock_);
- if (state_ != kConfigured || !client_)
- return;
- }
-
- const base::TimeTicks current_time = base::TimeTicks::Now();
- {
- 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 =
- reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer));
- CHECK(y_src);
- uint8_t* const u_src =
- reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer));
- CHECK(u_src);
- uint8_t* const v_src =
- reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer));
- CHECK(v_src);
-
- const int y_plane_length = width * height;
- const int uv_plane_length = y_plane_length / 4;
- const int buffer_length = y_plane_length + uv_plane_length * 2;
- std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_length]);
-
- libyuv::Android420ToI420(y_src, y_stride, u_src, uv_row_stride, v_src,
- uv_row_stride, uv_pixel_stride, buffer.get(), width,
- buffer.get() + y_plane_length, width / 2,
- buffer.get() + y_plane_length + uv_plane_length,
- width / 2, width, height);
-
- // Deliver the frame when it doesn't arrive too early.
- if (expected_next_frame_time_ <= current_time) {
- expected_next_frame_time_ += frame_interval_;
-
- // TODO(qiangchen): Investigate how to get raw timestamp for Android,
- // rather than using reference time to calculate timestamp.
- base::AutoLock lock(lock_);
- if (!client_)
- return;
- client_->OnIncomingCapturedData(buffer.get(), buffer_length,
- capture_format_, rotation, current_time,
- current_time - first_ref_time_);
- }
-}
-
-void VideoCaptureDeviceAndroid::OnError(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& message) {
- SetErrorState(FROM_HERE,
- base::android::ConvertJavaStringToUTF8(env, message));
-}
-
-void VideoCaptureDeviceAndroid::OnPhotoTaken(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jlong callback_id,
- const base::android::JavaParamRef<jbyteArray>& data) {
- DCHECK(callback_id);
-
- base::AutoLock lock(photo_callbacks_lock_);
-
- TakePhotoCallback* const cb =
- reinterpret_cast<TakePhotoCallback*>(callback_id);
- // Search for the pointer |cb| in the list of |photo_callbacks_|.
- const auto reference_it =
- std::find_if(photo_callbacks_.begin(), photo_callbacks_.end(),
- [cb](const std::unique_ptr<TakePhotoCallback>& callback) {
- return callback.get() == cb;
- });
- if (reference_it == photo_callbacks_.end()) {
- NOTREACHED() << "|callback_id| not found.";
- return;
- }
-
- mojom::BlobPtr blob = mojom::Blob::New();
- base::android::JavaByteArrayToByteVector(env, data.obj(), &blob->data);
- blob->mime_type = blob->data.empty() ? "" : "image/jpeg";
- cb->Run(std::move(blob));
-
- photo_callbacks_.erase(reference_it);
-}
-
-VideoPixelFormat VideoCaptureDeviceAndroid::GetColorspace() {
- JNIEnv* env = AttachCurrentThread();
- const int current_capture_colorspace =
- Java_VideoCapture_getColorspace(env, j_capture_.obj());
- switch (current_capture_colorspace) {
- case ANDROID_IMAGE_FORMAT_YV12:
- return media::PIXEL_FORMAT_YV12;
- case ANDROID_IMAGE_FORMAT_YUV_420_888:
- return media::PIXEL_FORMAT_I420;
- case ANDROID_IMAGE_FORMAT_NV21:
- return media::PIXEL_FORMAT_NV21;
- case ANDROID_IMAGE_FORMAT_UNKNOWN:
- default:
- return media::PIXEL_FORMAT_UNKNOWN;
- }
-}
-
-void VideoCaptureDeviceAndroid::SetErrorState(
- const tracked_objects::Location& from_here,
- const std::string& reason) {
- {
- base::AutoLock lock(lock_);
- state_ = kError;
- if (!client_)
- return;
- client_->OnError(from_here, reason);
- }
-}
-
-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
+ DCHECK(thread_checker_.CalledOnValidThread());
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kCapturing)
+ return;
+ }
+
JNIEnv* env = AttachCurrentThread();
// Make copy on the heap so we can pass the pointer through JNI.
@@ -399,16 +158,9 @@
}
}
-void VideoCaptureDeviceAndroid::DoGetPhotoCapabilities(
+void VideoCaptureDeviceAndroid::GetPhotoCapabilities(
GetPhotoCapabilitiesCallback callback) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
-#if DCHECK_IS_ON()
- {
- base::AutoLock lock(lock_);
- DCHECK_EQ(kConfigured, state_);
- DCHECK(got_first_frame_);
- }
-#endif
+ DCHECK(thread_checker_.CalledOnValidThread());
JNIEnv* env = AttachCurrentThread();
PhotoCapabilities caps(
@@ -440,19 +192,11 @@
callback.Run(std::move(photo_capabilities));
}
-void VideoCaptureDeviceAndroid::DoSetPhotoOptions(
+void VideoCaptureDeviceAndroid::SetPhotoOptions(
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();
-
+ 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);
@@ -467,8 +211,178 @@
if (settings->has_zoom)
Java_VideoCapture_setZoom(env, j_capture_.obj(), settings->zoom);
-
callback.Run(true);
}
+void VideoCaptureDeviceAndroid::OnFrameAvailable(
+ JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jbyteArray>& data,
+ jint length,
+ jint rotation) {
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kCapturing || !client_)
+ return;
+ }
+
+ jbyte* buffer = env->GetByteArrayElements(data, NULL);
+ if (!buffer) {
+ LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: "
+ "failed to GetByteArrayElements";
+ 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;
+ }
+
+ // Deliver the frame when it doesn't arrive too early.
+ if (expected_next_frame_time_ <= current_time) {
+ expected_next_frame_time_ += frame_interval_;
+
+ // TODO(qiangchen): Investigate how to get raw timestamp for Android,
+ // rather than using reference time to calculate timestamp.
+ base::AutoLock lock(lock_);
+ if (!client_)
+ return;
+ client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length,
+ capture_format_, rotation, current_time,
+ current_time - first_ref_time_);
+ }
+
+ env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
+}
+
+void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env,
+ jobject obj,
+ jobject y_buffer,
+ jint y_stride,
+ jobject u_buffer,
+ jobject v_buffer,
+ jint uv_row_stride,
+ jint uv_pixel_stride,
+ jint width,
+ jint height,
+ jint rotation) {
+ {
+ base::AutoLock lock(lock_);
+ if (state_ != kCapturing || !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;
+ }
+
+ uint8_t* const y_src =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer));
+ CHECK(y_src);
+ uint8_t* const u_src =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer));
+ CHECK(u_src);
+ uint8_t* const v_src =
+ reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer));
+ CHECK(v_src);
+
+ const int y_plane_length = width * height;
+ const int uv_plane_length = y_plane_length / 4;
+ const int buffer_length = y_plane_length + uv_plane_length * 2;
+ std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_length]);
+
+ libyuv::Android420ToI420(y_src, y_stride, u_src, uv_row_stride, v_src,
+ uv_row_stride, uv_pixel_stride, buffer.get(), width,
+ buffer.get() + y_plane_length, width / 2,
+ buffer.get() + y_plane_length + uv_plane_length,
+ width / 2, width, height);
+
+ // Deliver the frame when it doesn't arrive too early.
+ if (expected_next_frame_time_ <= current_time) {
+ expected_next_frame_time_ += frame_interval_;
+
+ // TODO(qiangchen): Investigate how to get raw timestamp for Android,
+ // rather than using reference time to calculate timestamp.
+ base::AutoLock lock(lock_);
+ if (!client_)
+ return;
+ client_->OnIncomingCapturedData(buffer.get(), buffer_length,
+ capture_format_, rotation, current_time,
+ current_time - first_ref_time_);
+ }
+}
+
+void VideoCaptureDeviceAndroid::OnError(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jstring>& message) {
+ SetErrorState(FROM_HERE,
+ base::android::ConvertJavaStringToUTF8(env, message));
+}
+
+void VideoCaptureDeviceAndroid::OnPhotoTaken(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jlong callback_id,
+ const base::android::JavaParamRef<jbyteArray>& data) {
+ DCHECK(callback_id);
+
+ base::AutoLock lock(photo_callbacks_lock_);
+
+ TakePhotoCallback* const cb =
+ reinterpret_cast<TakePhotoCallback*>(callback_id);
+ // Search for the pointer |cb| in the list of |photo_callbacks_|.
+ const auto reference_it =
+ std::find_if(photo_callbacks_.begin(), photo_callbacks_.end(),
+ [cb](const std::unique_ptr<TakePhotoCallback>& callback) {
+ return callback.get() == cb;
+ });
+ if (reference_it == photo_callbacks_.end()) {
+ NOTREACHED() << "|callback_id| not found.";
+ return;
+ }
+
+ mojom::BlobPtr blob = mojom::Blob::New();
+ base::android::JavaByteArrayToByteVector(env, data.obj(), &blob->data);
+ blob->mime_type = blob->data.empty() ? "" : "image/jpeg";
+ cb->Run(std::move(blob));
+
+ photo_callbacks_.erase(reference_it);
+}
+
+VideoPixelFormat VideoCaptureDeviceAndroid::GetColorspace() {
+ JNIEnv* env = AttachCurrentThread();
+ const int current_capture_colorspace =
+ Java_VideoCapture_getColorspace(env, j_capture_.obj());
+ switch (current_capture_colorspace) {
+ case ANDROID_IMAGE_FORMAT_YV12:
+ return media::PIXEL_FORMAT_YV12;
+ case ANDROID_IMAGE_FORMAT_YUV_420_888:
+ return media::PIXEL_FORMAT_I420;
+ case ANDROID_IMAGE_FORMAT_NV21:
+ return media::PIXEL_FORMAT_NV21;
+ case ANDROID_IMAGE_FORMAT_UNKNOWN:
+ default:
+ return media::PIXEL_FORMAT_UNKNOWN;
+ }
+}
+
+void VideoCaptureDeviceAndroid::SetErrorState(
+ const tracked_objects::Location& from_here,
+ const std::string& reason) {
+ {
+ base::AutoLock lock(lock_);
+ state_ = kError;
+ if (!client_)
+ return;
+ client_->OnError(from_here, reason);
+ }
+}
+
} // 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