| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright (c) 2016 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/androidvideotracksource.h" | 11 #include "webrtc/api/androidvideotracksource.h" | 
| 12 | 12 | 
| 13 #include <utility> | 13 #include <utility> | 
| 14 | 14 | 
|  | 15 #include "third_party/libyuv/include/libyuv/convert.h" | 
|  | 16 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 
|  | 17 | 
| 15 namespace webrtc { | 18 namespace webrtc { | 
| 16 | 19 | 
| 17 AndroidVideoTrackSource::AndroidVideoTrackSource(rtc::Thread* signaling_thread, | 20 AndroidVideoTrackSource::AndroidVideoTrackSource(rtc::Thread* signaling_thread, | 
| 18                                                  JNIEnv* jni, | 21                                                  JNIEnv* jni, | 
| 19                                                  jobject j_egl_context, | 22                                                  jobject j_egl_context, | 
| 20                                                  bool is_screencast) | 23                                                  bool is_screencast) | 
| 21     : signaling_thread_(signaling_thread), | 24     : signaling_thread_(signaling_thread), | 
| 22       surface_texture_helper_(webrtc_jni::SurfaceTextureHelper::create( | 25       surface_texture_helper_(webrtc_jni::SurfaceTextureHelper::create( | 
| 23           jni, | 26           jni, | 
| 24           "Camera SurfaceTextureHelper", | 27           "Camera SurfaceTextureHelper", | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 99   int crop_x; | 102   int crop_x; | 
| 100   int crop_y; | 103   int crop_y; | 
| 101   int64_t translated_camera_time_us; | 104   int64_t translated_camera_time_us; | 
| 102 | 105 | 
| 103   if (!AdaptFrame(width, height, timestamp_ns / rtc::kNumNanosecsPerMicrosec, | 106   if (!AdaptFrame(width, height, timestamp_ns / rtc::kNumNanosecsPerMicrosec, | 
| 104                   &adapted_width, &adapted_height, &crop_width, &crop_height, | 107                   &adapted_width, &adapted_height, &crop_width, &crop_height, | 
| 105                   &crop_x, &crop_y, &translated_camera_time_us)) { | 108                   &crop_x, &crop_y, &translated_camera_time_us)) { | 
| 106     return; | 109     return; | 
| 107   } | 110   } | 
| 108 | 111 | 
| 109   int rotated_width = crop_width; |  | 
| 110   int rotated_height = crop_height; |  | 
| 111 |  | 
| 112   rtc::CritScope lock(&apply_rotation_crit_); |  | 
| 113   if (apply_rotation_ && (rotation == 90 || rotation == 270)) { |  | 
| 114     std::swap(adapted_width, adapted_height); |  | 
| 115     std::swap(rotated_width, rotated_height); |  | 
| 116   } |  | 
| 117 |  | 
| 118   rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer = |  | 
| 119       pre_scale_pool_.CreateBuffer(rotated_width, rotated_height); |  | 
| 120 |  | 
| 121   const uint8_t* y_plane = static_cast<const uint8_t*>(frame_data); | 112   const uint8_t* y_plane = static_cast<const uint8_t*>(frame_data); | 
| 122   const uint8_t* uv_plane = y_plane + width * height; | 113   const uint8_t* uv_plane = y_plane + width * height; | 
| 123   int uv_width = (width + 1) / 2; | 114   const int uv_width = (width + 1) / 2; | 
| 124 | 115 | 
| 125   RTC_CHECK_GE(length, width * height + 2 * uv_width * ((height + 1) / 2)); | 116   RTC_CHECK_GE(length, width * height + 2 * uv_width * ((height + 1) / 2)); | 
| 126 | 117 | 
| 127   // Can only crop at even pixels. | 118   // Can only crop at even pixels. | 
| 128   crop_x &= ~1; | 119   crop_x &= ~1; | 
| 129   crop_y &= ~1; | 120   crop_y &= ~1; | 
|  | 121   // Crop just by modifying pointers. | 
|  | 122   y_plane += width * crop_y + crop_x; | 
|  | 123   uv_plane += uv_width * crop_y + crop_x; | 
| 130 | 124 | 
| 131   libyuv::NV12ToI420Rotate( | 125   rtc::scoped_refptr<webrtc::I420Buffer> buffer = | 
| 132       y_plane + width * crop_y + crop_x, width, | 126       buffer_pool_.CreateBuffer(adapted_width, adapted_height); | 
| 133       uv_plane + uv_width * crop_y + crop_x, width, buffer->MutableDataY(), |  | 
| 134       buffer->StrideY(), |  | 
| 135       // Swap U and V, since we have NV21, not NV12. |  | 
| 136       buffer->MutableDataV(), buffer->StrideV(), buffer->MutableDataU(), |  | 
| 137       buffer->StrideU(), crop_width, crop_height, |  | 
| 138       static_cast<libyuv::RotationMode>(apply_rotation_ ? rotation : 0)); |  | 
| 139 | 127 | 
| 140   if (adapted_width != buffer->width() || adapted_height != buffer->height()) { | 128   if (adapted_width == crop_width && adapted_height == crop_height) { | 
| 141     rtc::scoped_refptr<webrtc::I420Buffer> scaled_buffer( | 129     // No scaling. | 
| 142         post_scale_pool_.CreateBuffer(adapted_width, adapted_height)); | 130     libyuv::NV12ToI420( | 
| 143     scaled_buffer->ScaleFrom(buffer); | 131         y_plane, width, | 
| 144     buffer = scaled_buffer; | 132         uv_plane, uv_width * 2, | 
|  | 133         buffer->MutableDataY(), buffer->StrideY(), | 
|  | 134         // Swap U and V, since we have NV21, not NV12. | 
|  | 135         buffer->MutableDataV(), buffer->StrideV(), | 
|  | 136         buffer->MutableDataU(), buffer->StrideU(), | 
|  | 137         buffer->width(), buffer->height()); | 
|  | 138 | 
|  | 139   } else { | 
|  | 140     // Scaling. | 
|  | 141     const int crop_uv_width = (crop_width + 1) / 2; | 
|  | 142     const int crop_uv_height = (crop_height + 1) / 2; | 
|  | 143     unscaled_uv_planes_.resize(crop_uv_width * crop_uv_height * 2); | 
|  | 144 | 
|  | 145     NV12ToI420Scale( | 
|  | 146         unscaled_uv_planes_.data(), | 
|  | 147         y_plane, width, | 
|  | 148         uv_plane, uv_width * 2, | 
|  | 149         crop_width, crop_height, | 
|  | 150         buffer->MutableDataY(), buffer->StrideY(), | 
|  | 151         // Swap U and V, since we have NV21, not NV12. | 
|  | 152         buffer->MutableDataV(), buffer->StrideV(), | 
|  | 153         buffer->MutableDataU(), buffer->StrideU(), | 
|  | 154         buffer->width(), buffer->height()); | 
|  | 155   } | 
|  | 156 | 
|  | 157   // Applying rotation is only supported for legacy reasons, and the performance | 
|  | 158   // for this path is not critical. | 
|  | 159   rtc::CritScope lock(&apply_rotation_crit_); | 
|  | 160   if (apply_rotation_ && rotation != 0) { | 
|  | 161     rtc::scoped_refptr<I420Buffer> rotated_buffer = I420Buffer::Create( | 
|  | 162         rotation == 180 ? buffer->width() : buffer->height(), | 
|  | 163         rotation == 180 ? buffer->height() : buffer->width()); | 
|  | 164 | 
|  | 165     libyuv::I420Rotate( | 
|  | 166         buffer->DataY(), buffer->StrideY(), | 
|  | 167         buffer->DataU(), buffer->StrideU(), | 
|  | 168         buffer->DataV(), buffer->StrideV(), | 
|  | 169         rotated_buffer->MutableDataY(), rotated_buffer->StrideY(), | 
|  | 170         rotated_buffer->MutableDataU(), rotated_buffer->StrideU(), | 
|  | 171         rotated_buffer->MutableDataV(), rotated_buffer->StrideV(), | 
|  | 172         buffer->width(), buffer->height(), | 
|  | 173         static_cast<libyuv::RotationMode>(rotation)); | 
|  | 174 | 
|  | 175     buffer = rotated_buffer; | 
| 145   } | 176   } | 
| 146 | 177 | 
| 147   OnFrame(cricket::WebRtcVideoFrame( | 178   OnFrame(cricket::WebRtcVideoFrame( | 
| 148               buffer, | 179               buffer, | 
| 149               apply_rotation_ ? webrtc::kVideoRotation_0 | 180               apply_rotation_ ? webrtc::kVideoRotation_0 | 
| 150                               : static_cast<webrtc::VideoRotation>(rotation), | 181                               : static_cast<webrtc::VideoRotation>(rotation), | 
| 151               translated_camera_time_us, 0), | 182               translated_camera_time_us, 0), | 
| 152           width, height); | 183           width, height); | 
| 153 } | 184 } | 
| 154 | 185 | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 253   } | 284   } | 
| 254   *crop_x = (width - *crop_width) / 2; | 285   *crop_x = (width - *crop_width) / 2; | 
| 255   *crop_y = (height - *crop_height) / 2; | 286   *crop_y = (height - *crop_height) / 2; | 
| 256 | 287 | 
| 257   *translated_camera_time_us = timestamp_aligner_.ClipTimestamp( | 288   *translated_camera_time_us = timestamp_aligner_.ClipTimestamp( | 
| 258       camera_time_us + offset_us, system_time_us); | 289       camera_time_us + offset_us, system_time_us); | 
| 259   return true; | 290   return true; | 
| 260 } | 291 } | 
| 261 | 292 | 
| 262 }  // namespace webrtc | 293 }  // namespace webrtc | 
| OLD | NEW | 
|---|