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

Side by Side Diff: media/screen_capture/android/screen_capturer2_android.cc

Issue 1140113002: Implement screen capture for android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: make ScreenCapturerAndroid inherit VideoCaptureDevice 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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_capturer2_android.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/scoped_java_ref.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "jni/ScreenCapture_jni.h"
11 #include "media/base/video_capture_types.h"
12 #include "media/screen_capture/android/screen_capture_factory_android.h"
13
14 using base::android::AttachCurrentThread;
15
16 namespace media {
17
18 // static
19 bool ScreenCapturer2Android::RegisterScreenCapturer2(JNIEnv* env) {
20 return media::RegisterNativesImpl(env);
21 }
22
23 ScreenCapturer2Android::ScreenCapturer2Android()
24 : state_(kIdle), got_first_frame_(false) {}
25
26 ScreenCapturer2Android::~ScreenCapturer2Android() {
27 StopAndDeAllocate();
28 }
29
30 void ScreenCapturer2Android::OnFrameAvailable(JNIEnv* env,
31 jobject obj,
32 jbyteArray data,
33 jint length) {
34 base::AutoLock lock(lock_);
35 if (state_ != kCapturing || !client_.get())
36 return;
37
38 jbyte* buffer = env->GetByteArrayElements(data, NULL);
39 if (!buffer) {
40 LOG(ERROR) << "ScreenCapturer2Android::OnFrameAvailable: "
41 "failed to GetByteArrayElements";
42 return;
43 }
44
45 base::TimeTicks current_time = base::TimeTicks::Now();
46 if (!got_first_frame_) {
47 // Set aside one frame allowance for fluctuation.
48 expected_next_frame_time_ = current_time - frame_interval_;
49 got_first_frame_ = true;
50 }
51
52 // Deliver the frame when it doesn't arrive too early.
53 if (expected_next_frame_time_ <= current_time) {
54 expected_next_frame_time_ += frame_interval_;
55
56 client_->OnIncomingCapturedData(reinterpret_cast<uint8*>(buffer),
57 length,
58 capture_format_,
59 0,
60 base::TimeTicks::Now());
61 }
62
63 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
64 }
65
66 void ScreenCapturer2Android::OnActivityResult(JNIEnv* env,
67 jobject obj,
68 jint result) {
69 if (result == 0) {
70 state_ = kIdle;
71 return;
72 }
73
74 media::Java_ScreenCapture_startCapture(env, obj);
75
76 {
77 base::AutoLock lock(lock_);
78 state_ = kCapturing;
79 }
80 }
81
82 bool ScreenCapturer2Android::Init() {
83 j_capture_.Reset(media::ScreenCaptureFactoryAndroid
84 ::createScreenCapture2Android(reinterpret_cast<intptr_t>(this)));
85
86 if (j_capture_.obj() == NULL) {
87 LOG(ERROR) << "ScreenCapturer2Android::Init"
88 " failed to createScreenCaptureAndroid,"
89 " Maybe android version is too low";
90 return false;
91 }
92 return true;
93 }
94
95 void ScreenCapturer2Android::AllocateAndStart(
96 const VideoCaptureParams& params,
97 scoped_ptr<Client> client) {
98 DVLOG(1) << "ScreenCapturer2Android::AllocateAndStart";
99 {
100 base::AutoLock lock(lock_);
101 if (state_ != kIdle)
102 return;
103 client_ = client.Pass();
104 got_first_frame_ = false;
105 }
106 /*
107 // Store current width and height.
108 capture_format_.frame_size.SetSize(
109 params.requested_format.frame_size.width(),
110 params.requested_format.frame_size.height());
111 capture_format_.frame_rate = params.requested_format.frame_rate;
112 */
113 capture_format_ = params.requested_format;
114 // This capturer always outputs ARGB, non-interlaced.
115 capture_format_.pixel_format = media::PIXEL_FORMAT_ARGB;
116
117 CHECK(capture_format_.frame_size.GetArea() > 0);
118 CHECK(!(capture_format_.frame_size.width() % 2));
119 CHECK(!(capture_format_.frame_size.height() % 2));
120
121 if (capture_format_.frame_rate > 0) {
122 frame_interval_ = base::TimeDelta::FromMicroseconds(
123 (base::Time::kMicrosecondsPerSecond + capture_format_.frame_rate - 1) /
124 capture_format_.frame_rate);
125 }
126
127 DVLOG(1) << "ScreenCapturer2Android::AllocateAndStart: queried frame_size="
128 << capture_format_.frame_size.ToString()
129 << ", frame_rate=" << capture_format_.frame_rate;
130
131 JNIEnv* env = AttachCurrentThread();
132 jboolean ret = media::Java_ScreenCapture_start(env, j_capture_.obj(),
133 capture_format_.frame_size.width(), capture_format_.frame_size.height());
134 if (!ret) {
135 {
136 base::AutoLock lock(lock_);
137 state_ = kError;
138 }
139 client_->OnError("Failed to start");
140 return;
141 }
142 }
143
144 void ScreenCapturer2Android::StopAndDeAllocate() {
145 DVLOG(1) << "ScreenCapturer2Android::StopAndDeAllocate";
146 {
147 base::AutoLock lock(lock_);
148 if (state_ != kCapturing && state_ != kError)
149 return;
150 }
151
152 JNIEnv* env = AttachCurrentThread();
153 Java_ScreenCapture_stopCapture(env, j_capture_.obj());
154
155 {
156 base::AutoLock lock(lock_);
157 state_ = kIdle;
158 client_.reset();
159 }
160 }
161
162 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698