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

Unified Diff: media/screen_capture/android/screen_capture_machine_android.cc

Issue 1140113002: Implement screen capture for android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add ScreenCaptureMachineAndroid which inherited from content::VideoCaptureMachine Created 5 years, 7 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/screen_capture/android/screen_capture_machine_android.cc
diff --git a/media/screen_capture/android/screen_capture_machine_android.cc b/media/screen_capture/android/screen_capture_machine_android.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2044df340b4bad0dc9c3576ae300f6633ac21c29
--- /dev/null
+++ b/media/screen_capture/android/screen_capture_machine_android.cc
@@ -0,0 +1,159 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/screen_capture/android/screen_capture_machine_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+#include "content/browser/media/capture/video_capture_oracle.h"
+#include "jni/ScreenCapture_jni.h"
+#include "media/base/video_capture_types.h"
+#include "media/base/yuv_convert.h"
+#include "media/screen_capture/android/screen_capture_factory_android.h"
+#include "third_party/libyuv/include/libyuv.h"
+
+using base::android::AttachCurrentThread;
+
+namespace media {
+
+// static
+bool ScreenCaptureMachineAndroid::RegisterScreenCaptureMachine(JNIEnv* env) {
+ return media::RegisterNativesImpl(env);
+}
+
+
+ScreenCaptureMachineAndroid::ScreenCaptureMachineAndroid() {}
+
+ScreenCaptureMachineAndroid::~ScreenCaptureMachineAndroid() {}
+
+void ScreenCaptureMachineAndroid::OnFrameAvailable(JNIEnv* env,
+ jobject obj,
+ jbyteArray data,
+ jint cropWidth,
+ jint cropHeight,
+ jlong timestamp) {
+ const content::VideoCaptureOracle::Event event =
+ content::VideoCaptureOracle::kCompositorUpdate;
+ uint64_t absolute_micro =
+ static_cast<int64>(timestamp / base::Time::kNanosecondsPerMicrosecond);
+ const base::TimeTicks start_time =
+ base::TimeTicks::FromInternalValue(absolute_micro);
+ scoped_refptr<media::VideoFrame> frame;
+ content::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
+
+ bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
+ event, gfx::Rect(), start_time, &frame, &capture_frame_cb);
+
+ if (!oracle_decision) {
whywhat 2015/08/17 13:58:46 nit: no need for {} for a one line if statement.
+ return;
+ }
+
+ jbyte* buffer = env->GetByteArrayElements(data, NULL);
+ if (!buffer) {
+ return;
whywhat 2015/08/17 13:58:46 ditto
+ }
+
+ uint8* source_argb = reinterpret_cast<uint8_t*>(buffer);
+ int source_stride = cropWidth * 4;
+ // If needed, scale the captured frame to the required size.
+ if (gfx::Size(cropWidth, cropHeight) != frame->visible_rect().size()) {
+ scoped_ptr<uint8[]> scaled_frame_data;
+ scaled_frame_data.reset(new uint8[
+ frame->visible_rect().width() * frame->visible_rect().height() * 4]);
+ libyuv::ARGBScale(source_argb,
+ source_stride,
+ cropWidth,
+ cropHeight,
+ scaled_frame_data.get(),
+ frame->visible_rect().width() * 4,
+ frame->visible_rect().width(),
+ frame->visible_rect().height(),
+ libyuv::kFilterBilinear);
+ source_argb = scaled_frame_data.get();
+ source_stride = frame->visible_rect().width() * 4;
+ }
+
+ // Populate the VideoFrame.
+ DCHECK(frame->format() == media::VideoFrame::I420 ||
+ frame->format() == media::VideoFrame::YV12);
+
+ media::ConvertRGB32ToYUV(source_argb,
+ frame->visible_data(media::VideoFrame::kYPlane),
+ frame->visible_data(media::VideoFrame::kUPlane),
+ frame->visible_data(media::VideoFrame::kVPlane),
+ frame->visible_rect().width(),
+ frame->visible_rect().height(),
+ source_stride,
+ frame->stride(media::VideoFrame::kYPlane),
+ frame->stride(media::VideoFrame::kUPlane));
+
+ // Deliver the populated VideoFrame.
+ capture_frame_cb.Run(frame, start_time, true);
+
+ env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
+}
+
+void ScreenCaptureMachineAndroid::OnActivityResult(JNIEnv* env,
+ jobject obj,
+ jint result) {
+ if (result == 0) {
+ oracle_proxy_->ReportError("The user denied screen capture");
+ return;
+ }
+
+ media::Java_ScreenCapture_startCapture(env, obj);
+}
+
+void ScreenCaptureMachineAndroid::Start(
+ const scoped_refptr<content::ThreadSafeCaptureOracle>& oracle_proxy,
+ const media::VideoCaptureParams& params,
+ const base::Callback<void(bool)> callback) {
+ DCHECK(oracle_proxy.get());
+ oracle_proxy_ = oracle_proxy;
+
+ j_capture_.Reset(media::ScreenCaptureFactoryAndroid
+ ::createScreenCaptureMachineAndroid(reinterpret_cast<intptr_t>(this)));
+
+ if (j_capture_.obj() == NULL) {
+ LOG(ERROR) << "Failed to createScreenCaptureAndroid,"
+ " Maybe android version is too low";
+ callback.Run(false);
+ return;
+ }
+
+ power_save_blocker_.reset(
+ content::PowerSaveBlocker::Create(
+ content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
+ content::PowerSaveBlocker::kReasonOther,
+ "ScreenCaptureMachineAndroid is running").release());
+
+ capture_format_ = params.requested_format;
+ // This capturer always outputs ARGB, non-interlaced.
+ capture_format_.pixel_format = media::PIXEL_FORMAT_ARGB;
+
+ CHECK(capture_format_.frame_size.GetArea() > 0);
+ CHECK(!(capture_format_.frame_size.width() % 2));
+ CHECK(!(capture_format_.frame_size.height() % 2));
+
+ JNIEnv* env = AttachCurrentThread();
+ jboolean ret = media::Java_ScreenCapture_startPrompt(env, j_capture_.obj(),
+ capture_format_.frame_size.width(), capture_format_.frame_size.height());
+ if (!ret) {
+ callback.Run(false);
+ return;
+ }
+
+ callback.Run(true);
+}
+
+void ScreenCaptureMachineAndroid::Stop(const base::Closure& callback) {
+ power_save_blocker_.reset();
+
+ JNIEnv* env = AttachCurrentThread();
+ Java_ScreenCapture_stopCapture(env, j_capture_.obj());
+
+ callback.Run();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698