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

Side by Side 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, 6 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/screen_capture/android/screen_capture_machine_android.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/scoped_java_ref.h"
9 #include "content/browser/media/capture/video_capture_oracle.h"
10 #include "jni/ScreenCapture_jni.h"
11 #include "media/base/video_capture_types.h"
12 #include "media/base/yuv_convert.h"
13 #include "media/screen_capture/android/screen_capture_factory_android.h"
14 #include "third_party/libyuv/include/libyuv.h"
15
16 using base::android::AttachCurrentThread;
17
18 namespace media {
19
20 // static
21 bool ScreenCaptureMachineAndroid::RegisterScreenCaptureMachine(JNIEnv* env) {
22 return media::RegisterNativesImpl(env);
23 }
24
25
26 ScreenCaptureMachineAndroid::ScreenCaptureMachineAndroid() {}
27
28 ScreenCaptureMachineAndroid::~ScreenCaptureMachineAndroid() {}
29
30 void ScreenCaptureMachineAndroid::OnFrameAvailable(JNIEnv* env,
31 jobject obj,
32 jbyteArray data,
33 jint cropWidth,
34 jint cropHeight,
35 jlong timestamp) {
36 const content::VideoCaptureOracle::Event event =
37 content::VideoCaptureOracle::kCompositorUpdate;
38 uint64_t absolute_micro =
39 static_cast<int64>(timestamp / base::Time::kNanosecondsPerMicrosecond);
40 const base::TimeTicks start_time =
41 base::TimeTicks::FromInternalValue(absolute_micro);
42 scoped_refptr<media::VideoFrame> frame;
43 content::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
44
45 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
46 event, gfx::Rect(), start_time, &frame, &capture_frame_cb);
47
48 if (!oracle_decision) {
whywhat 2015/08/17 13:58:46 nit: no need for {} for a one line if statement.
49 return;
50 }
51
52 jbyte* buffer = env->GetByteArrayElements(data, NULL);
53 if (!buffer) {
54 return;
whywhat 2015/08/17 13:58:46 ditto
55 }
56
57 uint8* source_argb = reinterpret_cast<uint8_t*>(buffer);
58 int source_stride = cropWidth * 4;
59 // If needed, scale the captured frame to the required size.
60 if (gfx::Size(cropWidth, cropHeight) != frame->visible_rect().size()) {
61 scoped_ptr<uint8[]> scaled_frame_data;
62 scaled_frame_data.reset(new uint8[
63 frame->visible_rect().width() * frame->visible_rect().height() * 4]);
64 libyuv::ARGBScale(source_argb,
65 source_stride,
66 cropWidth,
67 cropHeight,
68 scaled_frame_data.get(),
69 frame->visible_rect().width() * 4,
70 frame->visible_rect().width(),
71 frame->visible_rect().height(),
72 libyuv::kFilterBilinear);
73 source_argb = scaled_frame_data.get();
74 source_stride = frame->visible_rect().width() * 4;
75 }
76
77 // Populate the VideoFrame.
78 DCHECK(frame->format() == media::VideoFrame::I420 ||
79 frame->format() == media::VideoFrame::YV12);
80
81 media::ConvertRGB32ToYUV(source_argb,
82 frame->visible_data(media::VideoFrame::kYPlane),
83 frame->visible_data(media::VideoFrame::kUPlane),
84 frame->visible_data(media::VideoFrame::kVPlane),
85 frame->visible_rect().width(),
86 frame->visible_rect().height(),
87 source_stride,
88 frame->stride(media::VideoFrame::kYPlane),
89 frame->stride(media::VideoFrame::kUPlane));
90
91 // Deliver the populated VideoFrame.
92 capture_frame_cb.Run(frame, start_time, true);
93
94 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
95 }
96
97 void ScreenCaptureMachineAndroid::OnActivityResult(JNIEnv* env,
98 jobject obj,
99 jint result) {
100 if (result == 0) {
101 oracle_proxy_->ReportError("The user denied screen capture");
102 return;
103 }
104
105 media::Java_ScreenCapture_startCapture(env, obj);
106 }
107
108 void ScreenCaptureMachineAndroid::Start(
109 const scoped_refptr<content::ThreadSafeCaptureOracle>& oracle_proxy,
110 const media::VideoCaptureParams& params,
111 const base::Callback<void(bool)> callback) {
112 DCHECK(oracle_proxy.get());
113 oracle_proxy_ = oracle_proxy;
114
115 j_capture_.Reset(media::ScreenCaptureFactoryAndroid
116 ::createScreenCaptureMachineAndroid(reinterpret_cast<intptr_t>(this)));
117
118 if (j_capture_.obj() == NULL) {
119 LOG(ERROR) << "Failed to createScreenCaptureAndroid,"
120 " Maybe android version is too low";
121 callback.Run(false);
122 return;
123 }
124
125 power_save_blocker_.reset(
126 content::PowerSaveBlocker::Create(
127 content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep,
128 content::PowerSaveBlocker::kReasonOther,
129 "ScreenCaptureMachineAndroid is running").release());
130
131 capture_format_ = params.requested_format;
132 // This capturer always outputs ARGB, non-interlaced.
133 capture_format_.pixel_format = media::PIXEL_FORMAT_ARGB;
134
135 CHECK(capture_format_.frame_size.GetArea() > 0);
136 CHECK(!(capture_format_.frame_size.width() % 2));
137 CHECK(!(capture_format_.frame_size.height() % 2));
138
139 JNIEnv* env = AttachCurrentThread();
140 jboolean ret = media::Java_ScreenCapture_startPrompt(env, j_capture_.obj(),
141 capture_format_.frame_size.width(), capture_format_.frame_size.height());
142 if (!ret) {
143 callback.Run(false);
144 return;
145 }
146
147 callback.Run(true);
148 }
149
150 void ScreenCaptureMachineAndroid::Stop(const base::Closure& callback) {
151 power_save_blocker_.reset();
152
153 JNIEnv* env = AttachCurrentThread();
154 Java_ScreenCapture_stopCapture(env, j_capture_.obj());
155
156 callback.Run();
157 }
158
159 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698