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

Side by Side Diff: talk/app/webrtc/java/jni/androidvideocapturer_jni.cc

Issue 1530843002: Android VideoCapture : Use NV21 instead of YUV12 and clean up. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years 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
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 11 matching lines...) Expand all
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * 26 *
27 */ 27 */
28 28
29 #include "talk/app/webrtc/java/jni/androidvideocapturer_jni.h" 29 #include "talk/app/webrtc/java/jni/androidvideocapturer_jni.h"
30 #include "talk/app/webrtc/java/jni/classreferenceholder.h" 30 #include "talk/app/webrtc/java/jni/classreferenceholder.h"
31 #include "talk/app/webrtc/java/jni/native_handle_impl.h" 31 #include "talk/app/webrtc/java/jni/native_handle_impl.h"
32 #include "talk/app/webrtc/java/jni/surfacetexturehelper_jni.h"
33 #include "third_party/libyuv/include/libyuv/convert.h"
32 #include "webrtc/base/bind.h" 34 #include "webrtc/base/bind.h"
33 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
34 35
35 namespace webrtc_jni { 36 namespace webrtc_jni {
36 37
37 jobject AndroidVideoCapturerJni::application_context_ = nullptr; 38 jobject AndroidVideoCapturerJni::application_context_ = nullptr;
38 39
39 // static 40 // static
40 int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni, 41 int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni,
41 jobject appliction_context) { 42 jobject appliction_context) {
42 if (application_context_) { 43 if (application_context_) {
43 jni->DeleteGlobalRef(application_context_); 44 jni->DeleteGlobalRef(application_context_);
44 } 45 }
45 application_context_ = NewGlobalRef(jni, appliction_context); 46 application_context_ = NewGlobalRef(jni, appliction_context);
46 47
47 return 0; 48 return 0;
48 } 49 }
49 50
50 AndroidVideoCapturerJni::AndroidVideoCapturerJni( 51 AndroidVideoCapturerJni::AndroidVideoCapturerJni(
51 JNIEnv* jni, 52 JNIEnv* jni,
52 jobject j_video_capturer, 53 jobject j_video_capturer,
53 jobject j_surface_texture_helper) 54 jobject j_surface_texture_helper)
54 : j_video_capturer_(jni, j_video_capturer), 55 : j_video_capturer_(jni, j_video_capturer),
55 j_surface_texture_helper_(jni, j_surface_texture_helper),
56 j_video_capturer_class_( 56 j_video_capturer_class_(
57 jni, FindClass(jni, "org/webrtc/VideoCapturerAndroid")), 57 jni, FindClass(jni, "org/webrtc/VideoCapturerAndroid")),
58 j_observer_class_( 58 j_observer_class_(
59 jni, 59 jni,
60 FindClass(jni, 60 FindClass(jni,
61 "org/webrtc/VideoCapturerAndroid$NativeObserver")), 61 "org/webrtc/VideoCapturerAndroid$NativeObserver")),
62 surface_texture_helper_(new rtc::RefCountedObject<SurfaceTextureHelper>(
63 jni, j_surface_texture_helper)),
62 capturer_(nullptr) { 64 capturer_(nullptr) {
63 LOG(LS_INFO) << "AndroidVideoCapturerJni ctor"; 65 LOG(LS_INFO) << "AndroidVideoCapturerJni ctor";
64 thread_checker_.DetachFromThread(); 66 thread_checker_.DetachFromThread();
65 } 67 }
66 68
67 AndroidVideoCapturerJni::~AndroidVideoCapturerJni() { 69 AndroidVideoCapturerJni::~AndroidVideoCapturerJni() {
68 LOG(LS_INFO) << "AndroidVideoCapturerJni dtor"; 70 LOG(LS_INFO) << "AndroidVideoCapturerJni dtor";
69 jni()->CallVoidMethod( 71 jni()->CallVoidMethod(
70 *j_video_capturer_, 72 *j_video_capturer_,
71 GetMethodID(jni(), *j_video_capturer_class_, "release", "()V")); 73 GetMethodID(jni(), *j_video_capturer_class_, "release", "()V"));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 void (webrtc::AndroidVideoCapturer::*method)(Args...), 125 void (webrtc::AndroidVideoCapturer::*method)(Args...),
124 typename Identity<Args>::type... args) { 126 typename Identity<Args>::type... args) {
125 rtc::CritScope cs(&capturer_lock_); 127 rtc::CritScope cs(&capturer_lock_);
126 if (!invoker_) { 128 if (!invoker_) {
127 LOG(LS_WARNING) << method_name << "() called for closed capturer."; 129 LOG(LS_WARNING) << method_name << "() called for closed capturer.";
128 return; 130 return;
129 } 131 }
130 invoker_->AsyncInvoke<void>(rtc::Bind(method, capturer_, args...)); 132 invoker_->AsyncInvoke<void>(rtc::Bind(method, capturer_, args...));
131 } 133 }
132 134
133 void AndroidVideoCapturerJni::ReturnBuffer(int64_t time_stamp) {
134 jmethodID m = GetMethodID(jni(), *j_video_capturer_class_,
135 "returnBuffer", "(J)V");
136 jni()->CallVoidMethod(*j_video_capturer_, m, time_stamp);
137 CHECK_EXCEPTION(jni()) << "error during VideoCapturerAndroid.returnBuffer";
138 }
139
140 std::string AndroidVideoCapturerJni::GetSupportedFormats() { 135 std::string AndroidVideoCapturerJni::GetSupportedFormats() {
141 jmethodID m = 136 jmethodID m =
142 GetMethodID(jni(), *j_video_capturer_class_, 137 GetMethodID(jni(), *j_video_capturer_class_,
143 "getSupportedFormatsAsJson", "()Ljava/lang/String;"); 138 "getSupportedFormatsAsJson", "()Ljava/lang/String;");
144 jstring j_json_caps = 139 jstring j_json_caps =
145 (jstring) jni()->CallObjectMethod(*j_video_capturer_, m); 140 (jstring) jni()->CallObjectMethod(*j_video_capturer_, m);
146 CHECK_EXCEPTION(jni()) << "error during supportedFormatsAsJson"; 141 CHECK_EXCEPTION(jni()) << "error during supportedFormatsAsJson";
147 return JavaToStdString(jni(), j_json_caps); 142 return JavaToStdString(jni(), j_json_caps);
148 } 143 }
149 144
150 void AndroidVideoCapturerJni::OnCapturerStarted(bool success) { 145 void AndroidVideoCapturerJni::OnCapturerStarted(bool success) {
151 LOG(LS_INFO) << "AndroidVideoCapturerJni capture started: " << success; 146 LOG(LS_INFO) << "AndroidVideoCapturerJni capture started: " << success;
152 AsyncCapturerInvoke("OnCapturerStarted", 147 AsyncCapturerInvoke("OnCapturerStarted",
153 &webrtc::AndroidVideoCapturer::OnCapturerStarted, 148 &webrtc::AndroidVideoCapturer::OnCapturerStarted,
154 success); 149 success);
155 } 150 }
156 151
157 void AndroidVideoCapturerJni::OnMemoryBufferFrame(void* video_frame, 152 void AndroidVideoCapturerJni::OnMemoryBufferFrame(void* video_frame,
158 int length, 153 int length,
159 int width, 154 int width,
160 int height, 155 int height,
161 int rotation, 156 int rotation,
162 int64_t timestamp_ns) { 157 int64_t timestamp_ns) {
163 const uint8_t* y_plane = static_cast<uint8_t*>(video_frame); 158 const uint8_t* y_plane = static_cast<uint8_t*>(video_frame);
164 // Android guarantees that the stride is a multiple of 16. 159 const uint8_t* vu_plane = y_plane + width * height;
165 // http://developer.android.com/reference/android/hardware/Camera.Parameters.h tml#setPreviewFormat%28int%29
166 int y_stride;
167 int uv_stride;
168 webrtc::Calc16ByteAlignedStride(width, &y_stride, &uv_stride);
169 const uint8_t* v_plane = y_plane + y_stride * height;
170 const uint8_t* u_plane =
171 v_plane + uv_stride * webrtc::AlignInt(height, 2) / 2;
172 160
173 // Wrap the Java buffer, and call ReturnBuffer() in the wrapped 161 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer =
174 // VideoFrameBuffer destructor. 162 buffer_pool_.CreateBuffer(width, height);
175 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer( 163 libyuv::NV21ToI420(
176 new rtc::RefCountedObject<webrtc::WrappedI420Buffer>( 164 y_plane, width,
177 width, height, y_plane, y_stride, u_plane, uv_stride, v_plane, 165 vu_plane, width,
178 uv_stride, 166 buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane),
179 rtc::Bind(&AndroidVideoCapturerJni::ReturnBuffer, this, 167 buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane),
180 timestamp_ns))); 168 buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane),
169 width, height);
181 AsyncCapturerInvoke("OnIncomingFrame", 170 AsyncCapturerInvoke("OnIncomingFrame",
182 &webrtc::AndroidVideoCapturer::OnIncomingFrame, 171 &webrtc::AndroidVideoCapturer::OnIncomingFrame,
183 buffer, rotation, timestamp_ns); 172 buffer, rotation, timestamp_ns);
184 } 173 }
185 174
186 void AndroidVideoCapturerJni::OnTextureFrame(int width, 175 void AndroidVideoCapturerJni::OnTextureFrame(int width,
187 int height, 176 int height,
188 int rotation, 177 int rotation,
189 int64_t timestamp_ns, 178 int64_t timestamp_ns,
190 const NativeHandleImpl& handle) { 179 const NativeHandleImpl& handle) {
191 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer( 180 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer(
192 new rtc::RefCountedObject<AndroidTextureBuffer>( 181 surface_texture_helper_->CreateTextureFrame(width, height, handle));
193 width, height, handle, *j_surface_texture_helper_, 182
194 rtc::Bind(&AndroidVideoCapturerJni::ReturnBuffer, this,
195 timestamp_ns)));
196 AsyncCapturerInvoke("OnIncomingFrame", 183 AsyncCapturerInvoke("OnIncomingFrame",
197 &webrtc::AndroidVideoCapturer::OnIncomingFrame, 184 &webrtc::AndroidVideoCapturer::OnIncomingFrame,
198 buffer, rotation, timestamp_ns); 185 buffer, rotation, timestamp_ns);
199 } 186 }
200 187
201 void AndroidVideoCapturerJni::OnOutputFormatRequest(int width, 188 void AndroidVideoCapturerJni::OnOutputFormatRequest(int width,
202 int height, 189 int height,
203 int fps) { 190 int fps) {
204 AsyncCapturerInvoke("OnOutputFormatRequest", 191 AsyncCapturerInvoke("OnOutputFormatRequest",
205 &webrtc::AndroidVideoCapturer::OnOutputFormatRequest, 192 &webrtc::AndroidVideoCapturer::OnOutputFormatRequest,
206 width, height, fps); 193 width, height, fps);
207 } 194 }
208 195
209 JNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); } 196 JNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); }
210 197
211 JOW(void, 198 JOW(void,
212 VideoCapturerAndroid_00024NativeObserver_nativeOnByteBufferFrameCaptured) 199 VideoCapturerAndroid_00024NativeObserver_nativeOnByteBufferFrameCaptured)
213 (JNIEnv* jni, jclass, jlong j_capturer, jbyteArray j_frame, jint length, 200 (JNIEnv* jni, jclass, jlong j_capturer, jbyteArray j_frame, jint length,
214 jint width, jint height, jint rotation, jlong timestamp) { 201 jint width, jint height, jint rotation, jlong timestamp) {
215 jboolean is_copy = true; 202 jboolean is_copy = true;
216 jbyte* bytes = jni->GetByteArrayElements(j_frame, &is_copy); 203 jbyte* bytes = jni->GetByteArrayElements(j_frame, &is_copy);
217 // If this is a copy of the original frame, it means that the memory
218 // is not direct memory and thus VideoCapturerAndroid does not guarantee
219 // that the memory is valid when we have released |j_frame|.
220 // TODO(magjed): Move ReleaseByteArrayElements() into ReturnBuffer() and
221 // remove this check.
222 RTC_CHECK(!is_copy)
223 << "NativeObserver_nativeOnFrameCaptured: frame is a copy";
224 reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer) 204 reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)
225 ->OnMemoryBufferFrame(bytes, length, width, height, rotation, timestamp); 205 ->OnMemoryBufferFrame(bytes, length, width, height, rotation, timestamp);
226 jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT); 206 jni->ReleaseByteArrayElements(j_frame, bytes, JNI_ABORT);
227 } 207 }
228 208
229 JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnTextureFrameCaptured) 209 JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnTextureFrameCaptured)
230 (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height, 210 (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height,
231 jint j_oes_texture_id, jfloatArray j_transform_matrix, 211 jint j_oes_texture_id, jfloatArray j_transform_matrix,
232 jint j_rotation, jlong j_timestamp) { 212 jint j_rotation, jlong j_timestamp) {
233 reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer) 213 reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)
(...skipping 23 matching lines...) Expand all
257 rtc::scoped_refptr<webrtc::AndroidVideoCapturerDelegate> delegate = 237 rtc::scoped_refptr<webrtc::AndroidVideoCapturerDelegate> delegate =
258 new rtc::RefCountedObject<AndroidVideoCapturerJni>( 238 new rtc::RefCountedObject<AndroidVideoCapturerJni>(
259 jni, j_video_capturer, j_surface_texture_helper); 239 jni, j_video_capturer, j_surface_texture_helper);
260 rtc::scoped_ptr<cricket::VideoCapturer> capturer( 240 rtc::scoped_ptr<cricket::VideoCapturer> capturer(
261 new webrtc::AndroidVideoCapturer(delegate)); 241 new webrtc::AndroidVideoCapturer(delegate));
262 // Caller takes ownership of the cricket::VideoCapturer* pointer. 242 // Caller takes ownership of the cricket::VideoCapturer* pointer.
263 return jlongFromPointer(capturer.release()); 243 return jlongFromPointer(capturer.release());
264 } 244 }
265 245
266 } // namespace webrtc_jni 246 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/jni/androidvideocapturer_jni.h ('k') | talk/app/webrtc/java/jni/surfacetexturehelper_jni.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698