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

Side by Side Diff: media/capture/content/android/screen_capture_machine_android.cc

Issue 2214533002: move //media/capture to //device/capture (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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/capture/content/android/screen_capture_machine_android.h"
6
7 #include "base/android/context_utils.h"
8 #include "base/android/jni_android.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "jni/ScreenCapture_jni.h"
11 #include "media/capture/content/video_capture_oracle.h"
12 #include "third_party/libyuv/include/libyuv.h"
13
14 using base::android::AttachCurrentThread;
15
16 namespace media {
17
18 // static
19 bool ScreenCaptureMachineAndroid::RegisterScreenCaptureMachine(JNIEnv* env) {
20 return RegisterNativesImpl(env);
21 }
22
23 ScreenCaptureMachineAndroid::ScreenCaptureMachineAndroid() {}
24
25 ScreenCaptureMachineAndroid::~ScreenCaptureMachineAndroid() {}
26
27 // static
28 ScopedJavaLocalRef<jobject>
29 ScreenCaptureMachineAndroid::createScreenCaptureMachineAndroid(
30 jlong nativeScreenCaptureMachineAndroid) {
31 return (Java_ScreenCapture_createScreenCaptureMachine(
32 AttachCurrentThread(), base::android::GetApplicationContext(),
33 nativeScreenCaptureMachineAndroid));
34 }
35
36 void ScreenCaptureMachineAndroid::OnRGBAFrameAvailable(JNIEnv* env,
37 jobject obj,
38 jobject buf,
39 jint row_stride,
40 jint left,
41 jint top,
42 jint width,
43 jint height,
44 jlong timestamp) {
45 const VideoCaptureOracle::Event event = VideoCaptureOracle::kCompositorUpdate;
46 const uint64_t absolute_micro =
47 timestamp / base::Time::kNanosecondsPerMicrosecond;
48 const base::TimeTicks start_time =
49 base::TimeTicks() + base::TimeDelta::FromMicroseconds(absolute_micro);
50 scoped_refptr<VideoFrame> frame;
51 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
52
53 if (!oracle_proxy_->ObserveEventAndDecideCapture(
54 event, gfx::Rect(), start_time, &frame, &capture_frame_cb)) {
55 return;
56 }
57
58 DCHECK(frame->format() == PIXEL_FORMAT_I420 ||
59 frame->format() == PIXEL_FORMAT_YV12);
60
61 scoped_refptr<VideoFrame> temp_frame = frame;
62 if (frame->visible_rect().width() != width ||
63 frame->visible_rect().height() != height) {
64 temp_frame = VideoFrame::CreateFrame(
65 PIXEL_FORMAT_I420, gfx::Size(width, height), gfx::Rect(width, height),
66 gfx::Size(width, height), base::TimeDelta());
67 }
68
69 uint8_t* const src =
70 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(buf));
71 CHECK(src);
72
73 const int offset = top * row_stride + left * 4;
74 // ABGR little endian (rgba in memory) to I420.
75 libyuv::ABGRToI420(
76 src + offset, row_stride, temp_frame->visible_data(VideoFrame::kYPlane),
77 temp_frame->stride(VideoFrame::kYPlane),
78 temp_frame->visible_data(VideoFrame::kUPlane),
79 temp_frame->stride(VideoFrame::kUPlane),
80 temp_frame->visible_data(VideoFrame::kVPlane),
81 temp_frame->stride(VideoFrame::kVPlane),
82 temp_frame->visible_rect().width(), temp_frame->visible_rect().height());
83
84 if (temp_frame != frame) {
85 libyuv::I420Scale(
86 temp_frame->visible_data(VideoFrame::kYPlane),
87 temp_frame->stride(VideoFrame::kYPlane),
88 temp_frame->visible_data(VideoFrame::kUPlane),
89 temp_frame->stride(VideoFrame::kUPlane),
90 temp_frame->visible_data(VideoFrame::kVPlane),
91 temp_frame->stride(VideoFrame::kVPlane),
92 temp_frame->visible_rect().width(), temp_frame->visible_rect().height(),
93 frame->visible_data(VideoFrame::kYPlane),
94 frame->stride(VideoFrame::kYPlane),
95 frame->visible_data(VideoFrame::kUPlane),
96 frame->stride(VideoFrame::kUPlane),
97 frame->visible_data(VideoFrame::kVPlane),
98 frame->stride(VideoFrame::kVPlane), frame->visible_rect().width(),
99 frame->visible_rect().height(), libyuv::kFilterBilinear);
100 }
101
102 capture_frame_cb.Run(frame, start_time, true);
103
104 lastFrame_ = frame;
105 }
106
107 void ScreenCaptureMachineAndroid::OnI420FrameAvailable(JNIEnv* env,
108 jobject obj,
109 jobject y_buffer,
110 jint y_stride,
111 jobject u_buffer,
112 jobject v_buffer,
113 jint uv_row_stride,
114 jint uv_pixel_stride,
115 jint left,
116 jint top,
117 jint width,
118 jint height,
119 jlong timestamp) {
120 const VideoCaptureOracle::Event event = VideoCaptureOracle::kCompositorUpdate;
121 const uint64_t absolute_micro =
122 timestamp / base::Time::kNanosecondsPerMicrosecond;
123 const base::TimeTicks start_time =
124 base::TimeTicks() + base::TimeDelta::FromMicroseconds(absolute_micro);
125 scoped_refptr<VideoFrame> frame;
126 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
127
128 if (!oracle_proxy_->ObserveEventAndDecideCapture(
129 event, gfx::Rect(), start_time, &frame, &capture_frame_cb)) {
130 return;
131 }
132
133 DCHECK(frame->format() == PIXEL_FORMAT_I420 ||
134 frame->format() == PIXEL_FORMAT_YV12);
135
136 scoped_refptr<VideoFrame> temp_frame = frame;
137 if (frame->visible_rect().width() != width ||
138 frame->visible_rect().height() != height) {
139 temp_frame = VideoFrame::CreateFrame(
140 PIXEL_FORMAT_I420, gfx::Size(width, height), gfx::Rect(width, height),
141 gfx::Size(width, height), base::TimeDelta());
142 }
143
144 uint8_t* const y_src =
145 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer));
146 CHECK(y_src);
147 uint8_t* u_src =
148 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer));
149 CHECK(u_src);
150 uint8_t* v_src =
151 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer));
152 CHECK(v_src);
153
154 const int y_offset = top * y_stride + left;
155 const int uv_offset = (top / 2) * uv_row_stride + left / 2;
156 libyuv::Android420ToI420(
157 y_src + y_offset, y_stride, u_src + uv_offset, uv_row_stride,
158 v_src + uv_offset, uv_row_stride, uv_pixel_stride,
159 temp_frame->visible_data(VideoFrame::kYPlane),
160 temp_frame->stride(VideoFrame::kYPlane),
161 temp_frame->visible_data(VideoFrame::kUPlane),
162 temp_frame->stride(VideoFrame::kUPlane),
163 temp_frame->visible_data(VideoFrame::kVPlane),
164 temp_frame->stride(VideoFrame::kVPlane),
165 temp_frame->visible_rect().width(), temp_frame->visible_rect().height());
166
167 if (temp_frame != frame) {
168 libyuv::I420Scale(
169 temp_frame->visible_data(VideoFrame::kYPlane),
170 temp_frame->stride(VideoFrame::kYPlane),
171 temp_frame->visible_data(VideoFrame::kUPlane),
172 temp_frame->stride(VideoFrame::kUPlane),
173 temp_frame->visible_data(VideoFrame::kVPlane),
174 temp_frame->stride(VideoFrame::kVPlane),
175 temp_frame->visible_rect().width(), temp_frame->visible_rect().height(),
176 frame->visible_data(VideoFrame::kYPlane),
177 frame->stride(VideoFrame::kYPlane),
178 frame->visible_data(VideoFrame::kUPlane),
179 frame->stride(VideoFrame::kUPlane),
180 frame->visible_data(VideoFrame::kVPlane),
181 frame->stride(VideoFrame::kVPlane), frame->visible_rect().width(),
182 frame->visible_rect().height(), libyuv::kFilterBilinear);
183 }
184
185 capture_frame_cb.Run(frame, start_time, true);
186
187 lastFrame_ = frame;
188 }
189
190 void ScreenCaptureMachineAndroid::OnActivityResult(JNIEnv* env,
191 jobject obj,
192 jboolean result) {
193 if (!result) {
194 oracle_proxy_->ReportError(FROM_HERE, "The user denied screen capture");
195 return;
196 }
197
198 Java_ScreenCapture_startCapture(env, obj);
199 }
200
201 void ScreenCaptureMachineAndroid::Start(
202 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
203 const VideoCaptureParams& params,
204 const base::Callback<void(bool)> callback) {
205 DCHECK(oracle_proxy.get());
206 oracle_proxy_ = oracle_proxy;
207
208 j_capture_.Reset(
209 createScreenCaptureMachineAndroid(reinterpret_cast<intptr_t>(this)));
210
211 if (j_capture_.obj() == nullptr) {
212 DLOG(ERROR) << "Failed to createScreenCaptureAndroid";
213 callback.Run(false);
214 return;
215 }
216
217 DCHECK(params.requested_format.frame_size.GetArea());
218 DCHECK(!(params.requested_format.frame_size.width() % 2));
219 DCHECK(!(params.requested_format.frame_size.height() % 2));
220
221 const jboolean ret = Java_ScreenCapture_startPrompt(
222 AttachCurrentThread(), j_capture_.obj(),
223 params.requested_format.frame_size.width(),
224 params.requested_format.frame_size.height());
225
226 callback.Run(ret);
227 }
228
229 void ScreenCaptureMachineAndroid::Stop(const base::Closure& callback) {
230 Java_ScreenCapture_stopCapture(AttachCurrentThread(), j_capture_.obj());
231
232 callback.Run();
233 }
234
235 // ScreenCapture on Android works in a passive way and there are no captured
236 // frames when there is no update to the screen. When the oracle asks for a
237 // capture refresh, the cached captured frame is redelivered.
238 void ScreenCaptureMachineAndroid::MaybeCaptureForRefresh() {
239 if (lastFrame_.get() == nullptr)
240 return;
241
242 const VideoCaptureOracle::Event event =
243 VideoCaptureOracle::kActiveRefreshRequest;
244 const base::TimeTicks start_time = base::TimeTicks::Now();
245 scoped_refptr<VideoFrame> frame;
246 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
247
248 if (!oracle_proxy_->ObserveEventAndDecideCapture(
249 event, gfx::Rect(), start_time, &frame, &capture_frame_cb)) {
250 return;
251 }
252
253 DCHECK(frame->format() == PIXEL_FORMAT_I420 ||
254 frame->format() == PIXEL_FORMAT_YV12);
255
256 libyuv::I420Scale(
257 lastFrame_->visible_data(VideoFrame::kYPlane),
258 lastFrame_->stride(VideoFrame::kYPlane),
259 lastFrame_->visible_data(VideoFrame::kUPlane),
260 lastFrame_->stride(VideoFrame::kUPlane),
261 lastFrame_->visible_data(VideoFrame::kVPlane),
262 lastFrame_->stride(VideoFrame::kVPlane),
263 lastFrame_->visible_rect().width(), lastFrame_->visible_rect().height(),
264 frame->visible_data(VideoFrame::kYPlane),
265 frame->stride(VideoFrame::kYPlane),
266 frame->visible_data(VideoFrame::kUPlane),
267 frame->stride(VideoFrame::kUPlane),
268 frame->visible_data(VideoFrame::kVPlane),
269 frame->stride(VideoFrame::kVPlane), frame->visible_rect().width(),
270 frame->visible_rect().height(), libyuv::kFilterBilinear);
271
272 capture_frame_cb.Run(frame, start_time, true);
273 }
274
275 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/content/android/screen_capture_machine_android.h ('k') | media/capture/content/animated_content_sampler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698