| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  *  Copyright 2015 The WebRTC project authors. All Rights Reserved. |    2  *  Copyright 2015 The WebRTC project authors. All Rights Reserved. | 
|    3  * |    3  * | 
|    4  *  Use of this source code is governed by a BSD-style license |    4  *  Use of this source code is governed by a BSD-style license | 
|    5  *  that can be found in the LICENSE file in the root of the source |    5  *  that can be found in the LICENSE file in the root of the source | 
|    6  *  tree. An additional intellectual property rights grant can be found |    6  *  tree. An additional intellectual property rights grant can be found | 
|    7  *  in the file PATENTS.  All contributing project authors may |    7  *  in the file PATENTS.  All contributing project authors may | 
|    8  *  be found in the AUTHORS file in the root of the source tree. |    8  *  be found in the AUTHORS file in the root of the source tree. | 
|    9  */ |    9  */ | 
|   10  |   10  | 
|   11 #include "webrtc/api/java/jni/androidvideocapturer_jni.h" |   11 #include "webrtc/api/java/jni/androidvideocapturer_jni.h" | 
|   12 #include "webrtc/api/java/jni/classreferenceholder.h" |   12 #include "webrtc/api/java/jni/classreferenceholder.h" | 
|   13 #include "webrtc/api/java/jni/native_handle_impl.h" |   13 #include "webrtc/api/java/jni/native_handle_impl.h" | 
|   14 #include "webrtc/api/java/jni/surfacetexturehelper_jni.h" |   14 #include "webrtc/api/java/jni/surfacetexturehelper_jni.h" | 
|   15 #include "third_party/libyuv/include/libyuv/convert.h" |   15 #include "third_party/libyuv/include/libyuv/convert.h" | 
 |   16 #include "third_party/libyuv/include/libyuv/scale.h" | 
|   16 #include "webrtc/base/bind.h" |   17 #include "webrtc/base/bind.h" | 
|   17  |   18  | 
|   18 namespace webrtc_jni { |   19 namespace webrtc_jni { | 
|   19  |   20  | 
|   20 jobject AndroidVideoCapturerJni::application_context_ = nullptr; |   21 jobject AndroidVideoCapturerJni::application_context_ = nullptr; | 
|   21  |   22  | 
|   22 // static |   23 // static | 
|   23 int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni, |   24 int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni, | 
|   24                                                jobject appliction_context) { |   25                                                jobject appliction_context) { | 
|   25   if (application_context_) { |   26   if (application_context_) { | 
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  162                       &webrtc::AndroidVideoCapturer::OnCapturerStarted, |  163                       &webrtc::AndroidVideoCapturer::OnCapturerStarted, | 
|  163                       success); |  164                       success); | 
|  164 } |  165 } | 
|  165  |  166  | 
|  166 void AndroidVideoCapturerJni::OnMemoryBufferFrame(void* video_frame, |  167 void AndroidVideoCapturerJni::OnMemoryBufferFrame(void* video_frame, | 
|  167                                                   int length, |  168                                                   int length, | 
|  168                                                   int width, |  169                                                   int width, | 
|  169                                                   int height, |  170                                                   int height, | 
|  170                                                   int rotation, |  171                                                   int rotation, | 
|  171                                                   int64_t timestamp_ns) { |  172                                                   int64_t timestamp_ns) { | 
|  172   const uint8_t* y_plane = static_cast<uint8_t*>(video_frame); |  173   RTC_DCHECK(rotation == 0 || rotation == 90 || rotation == 180 || | 
|  173   const uint8_t* vu_plane = y_plane + width * height; |  174              rotation == 270); | 
 |  175   rtc::CritScope cs(&capturer_lock_); | 
 |  176  | 
 |  177   int adapted_width; | 
 |  178   int adapted_height; | 
 |  179   int crop_width; | 
 |  180   int crop_height; | 
 |  181   int crop_x; | 
 |  182   int crop_y; | 
 |  183  | 
 |  184   if (!capturer_->AdaptFrame(width, height, timestamp_ns, | 
 |  185                              &adapted_width, &adapted_height, | 
 |  186                              &crop_width, &crop_height, &crop_x, &crop_y)) { | 
 |  187     return; | 
 |  188   } | 
 |  189  | 
 |  190   int rotated_width = crop_width; | 
 |  191   int rotated_height = crop_height; | 
 |  192  | 
 |  193   if (capturer_->apply_rotation() && (rotation == 90 || rotation == 270)) { | 
 |  194     std::swap(adapted_width, adapted_height); | 
 |  195     std::swap(rotated_width, rotated_height); | 
 |  196   } | 
|  174  |  197  | 
|  175   rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = |  198   rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = | 
|  176       buffer_pool_.CreateBuffer(width, height); |  199       pre_scale_pool_.CreateBuffer(rotated_width, rotated_height); | 
|  177   libyuv::NV21ToI420( |  200  | 
|  178       y_plane, width, |  201   const uint8_t* y_plane = static_cast<const uint8_t*>(video_frame); | 
|  179       vu_plane, width, |  202   const uint8_t* uv_plane = y_plane + width * height; | 
 |  203  | 
 |  204   // Can only crop at even pixels. | 
 |  205   crop_x &= ~1; | 
 |  206   crop_y &= ~1; | 
 |  207   int uv_width = (width + 1) / 2; | 
 |  208  | 
 |  209   libyuv::NV12ToI420Rotate( | 
 |  210       y_plane + width * crop_y + crop_x, width, | 
 |  211       uv_plane + uv_width * crop_y + crop_x, width, | 
|  180       buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane), |  212       buffer->MutableData(webrtc::kYPlane), buffer->stride(webrtc::kYPlane), | 
 |  213       // Swap U and V, since we have NV21, not NV12. | 
 |  214       buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane), | 
|  181       buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane), |  215       buffer->MutableData(webrtc::kUPlane), buffer->stride(webrtc::kUPlane), | 
|  182       buffer->MutableData(webrtc::kVPlane), buffer->stride(webrtc::kVPlane), |  216       crop_width, crop_height, static_cast<libyuv::RotationMode>( | 
|  183       width, height); |  217           capturer_->apply_rotation() ? rotation : 0)); | 
|  184  |  218  | 
|  185   rtc::CritScope cs(&capturer_lock_); |  219   if (adapted_width != rotated_width || adapted_height != rotated_height) { | 
|  186   if (!capturer_) { |  220     rtc::scoped_refptr<webrtc::VideoFrameBuffer> scaled = | 
|  187     LOG(LS_WARNING) << "OnMemoryBufferFrame() called for closed capturer."; |  221       post_scale_pool_.CreateBuffer(adapted_width, adapted_height); | 
|  188     return; |  222     // TODO(nisse): This should be done by some Scale method in | 
 |  223     // I420Buffer, but we can't do that right now, since | 
 |  224     // I420BufferPool uses a wrapper object. | 
 |  225     if (libyuv::I420Scale(buffer->DataY(), buffer->StrideY(), | 
 |  226                           buffer->DataU(), buffer->StrideU(), | 
 |  227                           buffer->DataV(), buffer->StrideV(), | 
 |  228                           rotated_width, rotated_height, | 
 |  229                           scaled->MutableDataY(), scaled->StrideY(), | 
 |  230                           scaled->MutableDataU(), scaled->StrideU(), | 
 |  231                           scaled->MutableDataV(), scaled->StrideV(), | 
 |  232                           adapted_width, adapted_height, | 
 |  233                           libyuv::kFilterBox) < 0) { | 
 |  234       LOG(LS_WARNING) << "I420Scale failed"; | 
 |  235       return; | 
 |  236     } | 
 |  237     buffer = scaled; | 
|  189   } |  238   } | 
|  190   capturer_->OnIncomingFrame(buffer, rotation, timestamp_ns); |  239   // TODO(nisse): Use microsecond time instead. | 
 |  240   capturer_->OnFrame(cricket::WebRtcVideoFrame( | 
 |  241                          buffer, timestamp_ns, | 
 |  242                          capturer_->apply_rotation() | 
 |  243                              ? webrtc::kVideoRotation_0 | 
 |  244                              : static_cast<webrtc::VideoRotation>(rotation)), | 
 |  245                      width, height); | 
|  191 } |  246 } | 
|  192  |  247  | 
|  193 void AndroidVideoCapturerJni::OnTextureFrame(int width, |  248 void AndroidVideoCapturerJni::OnTextureFrame(int width, | 
|  194                                              int height, |  249                                              int height, | 
|  195                                              int rotation, |  250                                              int rotation, | 
|  196                                              int64_t timestamp_ns, |  251                                              int64_t timestamp_ns, | 
|  197                                              const NativeHandleImpl& handle) { |  252                                              const NativeHandleImpl& handle) { | 
|  198   rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer( |  253   RTC_DCHECK(rotation == 0 || rotation == 90 || rotation == 180 || | 
|  199       surface_texture_helper_->CreateTextureFrame(width, height, handle)); |  254              rotation == 270); | 
 |  255   rtc::CritScope cs(&capturer_lock_); | 
|  200  |  256  | 
|  201   rtc::CritScope cs(&capturer_lock_); |  257   int adapted_width; | 
|  202   if (!capturer_) { |  258   int adapted_height; | 
|  203     LOG(LS_WARNING) << "OnTextureFrame() called for closed capturer."; |  259   int crop_width; | 
 |  260   int crop_height; | 
 |  261   int crop_x; | 
 |  262   int crop_y; | 
 |  263  | 
 |  264   if (!capturer_->AdaptFrame(width, height, timestamp_ns, | 
 |  265                              &adapted_width, &adapted_height, | 
 |  266                              &crop_width, &crop_height, &crop_x, &crop_y)) { | 
|  204     return; |  267     return; | 
|  205   } |  268   } | 
|  206   capturer_->OnIncomingFrame(buffer, rotation, timestamp_ns); |  269  | 
 |  270   Matrix matrix = handle.sampling_matrix; | 
 |  271  | 
 |  272   matrix.Crop(crop_width / static_cast<float>(width), | 
 |  273               crop_height / static_cast<float>(height), | 
 |  274               crop_x / static_cast<float>(width), | 
 |  275               crop_y / static_cast<float>(height)); | 
 |  276  | 
 |  277   if (capturer_->apply_rotation()) { | 
 |  278     if (rotation == webrtc::kVideoRotation_90 || | 
 |  279         rotation == webrtc::kVideoRotation_270) { | 
 |  280       std::swap(adapted_width, adapted_height); | 
 |  281     } | 
 |  282     matrix.Rotate(static_cast<webrtc::VideoRotation>(rotation)); | 
 |  283   } | 
 |  284  | 
 |  285   // TODO(nisse): Use microsecond time instead. | 
 |  286   capturer_->OnFrame( | 
 |  287       cricket::WebRtcVideoFrame( | 
 |  288           surface_texture_helper_->CreateTextureFrame( | 
 |  289               adapted_width, adapted_height, | 
 |  290               NativeHandleImpl(handle.oes_texture_id, matrix)), | 
 |  291           timestamp_ns, capturer_->apply_rotation() | 
 |  292                             ? webrtc::kVideoRotation_0 | 
 |  293                             : static_cast<webrtc::VideoRotation>(rotation)), | 
 |  294       width, height); | 
|  207 } |  295 } | 
|  208  |  296  | 
|  209 void AndroidVideoCapturerJni::OnOutputFormatRequest(int width, |  297 void AndroidVideoCapturerJni::OnOutputFormatRequest(int width, | 
|  210                                                     int height, |  298                                                     int height, | 
|  211                                                     int fps) { |  299                                                     int fps) { | 
|  212   AsyncCapturerInvoke("OnOutputFormatRequest", |  300   AsyncCapturerInvoke("OnOutputFormatRequest", | 
|  213                       &webrtc::AndroidVideoCapturer::OnOutputFormatRequest, |  301                       &webrtc::AndroidVideoCapturer::OnOutputFormatRequest, | 
|  214                       width, height, fps); |  302                       width, height, fps); | 
|  215 } |  303 } | 
|  216  |  304  | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|  246  |  334  | 
|  247 JOW(void, VideoCapturer_00024NativeObserver_nativeOnOutputFormatRequest) |  335 JOW(void, VideoCapturer_00024NativeObserver_nativeOnOutputFormatRequest) | 
|  248     (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height, |  336     (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height, | 
|  249         jint j_fps) { |  337         jint j_fps) { | 
|  250   LOG(LS_INFO) << "NativeObserver_nativeOnOutputFormatRequest"; |  338   LOG(LS_INFO) << "NativeObserver_nativeOnOutputFormatRequest"; | 
|  251   reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)->OnOutputFormatRequest( |  339   reinterpret_cast<AndroidVideoCapturerJni*>(j_capturer)->OnOutputFormatRequest( | 
|  252       j_width, j_height, j_fps); |  340       j_width, j_height, j_fps); | 
|  253 } |  341 } | 
|  254  |  342  | 
|  255 }  // namespace webrtc_jni |  343 }  // namespace webrtc_jni | 
| OLD | NEW |