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

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

Issue 1917023003: ScreenCapture for Android phase1, part I (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 4 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 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/base/video_capture_types.h"
12 #include "media/base/yuv_convert.h"
13 #include "media/capture/content/video_capture_oracle.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 RegisterNativesImpl(env);
23 }
24
25 ScreenCaptureMachineAndroid::ScreenCaptureMachineAndroid() {}
26
27 ScreenCaptureMachineAndroid::~ScreenCaptureMachineAndroid() {}
28
29 // static
30 ScopedJavaLocalRef<jobject>
31 ScreenCaptureMachineAndroid::createScreenCaptureMachineAndroid(
32 jlong nativeScreenCaptureMachineAndroid) {
33 return (Java_ScreenCapture_createScreenCaptureMachine(
34 AttachCurrentThread(), base::android::GetApplicationContext(),
35 nativeScreenCaptureMachineAndroid));
36 }
37
38 void ScreenCaptureMachineAndroid::OnFrameAvailable(JNIEnv* env,
39 jobject obj,
40 jbyteArray data,
41 jint cropWidth,
42 jint cropHeight,
43 jlong timestamp) {
44 const VideoCaptureOracle::Event event = VideoCaptureOracle::kCompositorUpdate;
45 uint64_t absolute_micro =
46 static_cast<int64>(timestamp / base::Time::kNanosecondsPerMicrosecond);
47 const base::TimeTicks start_time =
48 base::TimeTicks::FromInternalValue(absolute_micro);
49 scoped_refptr<VideoFrame> frame;
50 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
51
52 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture(
53 event, gfx::Rect(), start_time, &frame, &capture_frame_cb);
54
55 if (!oracle_decision)
56 return;
57
58 jbyte* buffer = env->GetByteArrayElements(data, NULL);
59 if (!buffer)
60 return;
61
62 uint8* source_argb = reinterpret_cast<uint8_t*>(buffer);
63 int source_stride = cropWidth * 4;
64
65 DCHECK(gfx::Size(cropWidth, cropHeight) == frame->visible_rect().size());
miu 2016/05/10 00:29:00 This CHECK will fail unless the client request fix
66 DCHECK(frame->format() == PIXEL_FORMAT_I420 ||
67 frame->format() == PIXEL_FORMAT_YV12);
68
69 // TODO(braveyao): Some reports show that they failed to get YUV_420_888
70 // format from
71 // MediaProjection on some devices. Check if it's a real problem and study if
72 // it's
73 // possible to move the colorspace conversion to GPU.
74 ConvertRGB32ToYUV(
75 source_argb, frame->visible_data(VideoFrame::kYPlane),
76 frame->visible_data(VideoFrame::kUPlane),
77 frame->visible_data(VideoFrame::kVPlane), frame->visible_rect().width(),
78 frame->visible_rect().height(), source_stride,
79 frame->stride(VideoFrame::kYPlane), frame->stride(VideoFrame::kUPlane));
80
81 // Deliver the populated VideoFrame.
82 capture_frame_cb.Run(frame, start_time, true);
83
84 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
85 }
86
87 void ScreenCaptureMachineAndroid::OnActivityResult(JNIEnv* env,
88 jobject obj,
89 jboolean result) {
90 if (!result) {
91 oracle_proxy_->ReportError(FROM_HERE, "The user denied screen capture");
92 return;
93 }
94
95 Java_ScreenCapture_startCapture(env, obj);
96 }
97
98 void ScreenCaptureMachineAndroid::Start(
99 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
100 const VideoCaptureParams& params,
101 const base::Callback<void(bool)> callback) {
102 DCHECK(oracle_proxy.get());
103 oracle_proxy_ = oracle_proxy;
104
105 j_capture_.Reset(
106 createScreenCaptureMachineAndroid(reinterpret_cast<intptr_t>(this)));
107
108 if (j_capture_.obj() == NULL) {
109 LOG(ERROR) << "Failed to createScreenCaptureAndroid,"
110 " Maybe android version is too low";
111 callback.Run(false);
112 return;
113 }
114
115 DCHECK(params.requested_format.frame_size.GetArea() > 0);
116 DCHECK(!(params.requested_format.frame_size.width() % 2));
117 DCHECK(!(params.requested_format.frame_size.height() % 2));
118
119 jboolean ret = Java_ScreenCapture_startPrompt(
120 AttachCurrentThread(), j_capture_.obj(),
121 params.requested_format.frame_size.width(),
122 params.requested_format.frame_size.height());
123 if (!ret) {
124 callback.Run(false);
125 return;
126 }
127
128 callback.Run(true);
129 }
130
131 void ScreenCaptureMachineAndroid::Stop(const base::Closure& callback) {
132 Java_ScreenCapture_stopCapture(AttachCurrentThread(), j_capture_.obj());
133
134 callback.Run();
135 }
136
137 // TODO(braveyao): On Android if the screen has no change, there will be no
138 // captured frame, which would "pause" capture. Check how to satisfy downstream
139 // consumers needing the extra "refreshing" frames.
140 void ScreenCaptureMachineAndroid::MaybeCaptureForRefresh() {}
141
142 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698