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

Side by Side Diff: media/capture/video/android/video_capture_device_android.cc

Issue 2156003006: Android video capture: use new libyuv::Android420ToI420 API for format converting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rename variable and format Created 4 years, 5 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/capture/video/android/video_capture_device_android.h" 5 #include "media/capture/video/android/video_capture_device_android.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/android/jni_android.h" 10 #include "base/android/jni_android.h"
11 #include "base/android/jni_array.h" 11 #include "base/android/jni_array.h"
12 #include "base/android/jni_string.h" 12 #include "base/android/jni_string.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "jni/VideoCapture_jni.h" 14 #include "jni/VideoCapture_jni.h"
15 #include "media/capture/video/android/photo_capabilities.h" 15 #include "media/capture/video/android/photo_capabilities.h"
16 #include "media/capture/video/android/video_capture_device_factory_android.h" 16 #include "media/capture/video/android/video_capture_device_factory_android.h"
17 #include "mojo/public/cpp/bindings/string.h" 17 #include "mojo/public/cpp/bindings/string.h"
18 #include "third_party/libyuv/include/libyuv.h"
18 19
19 using base::android::AttachCurrentThread; 20 using base::android::AttachCurrentThread;
20 using base::android::CheckException; 21 using base::android::CheckException;
21 using base::android::GetClass; 22 using base::android::GetClass;
22 using base::android::MethodID; 23 using base::android::MethodID;
23 using base::android::JavaRef; 24 using base::android::JavaRef;
24 using base::android::ScopedJavaLocalRef; 25 using base::android::ScopedJavaLocalRef;
25 26
26 namespace media { 27 namespace media {
27 28
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 if (state_ != kCapturing || !client_.get()) 203 if (state_ != kCapturing || !client_.get())
203 return; 204 return;
204 205
205 jbyte* buffer = env->GetByteArrayElements(data, NULL); 206 jbyte* buffer = env->GetByteArrayElements(data, NULL);
206 if (!buffer) { 207 if (!buffer) {
207 LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: " 208 LOG(ERROR) << "VideoCaptureDeviceAndroid::OnFrameAvailable: "
208 "failed to GetByteArrayElements"; 209 "failed to GetByteArrayElements";
209 return; 210 return;
210 } 211 }
211 212
212 base::TimeTicks current_time = base::TimeTicks::Now(); 213 const base::TimeTicks current_time = base::TimeTicks::Now();
213 if (!got_first_frame_) { 214 if (!got_first_frame_) {
214 // Set aside one frame allowance for fluctuation. 215 // Set aside one frame allowance for fluctuation.
215 expected_next_frame_time_ = current_time - frame_interval_; 216 expected_next_frame_time_ = current_time - frame_interval_;
216 first_ref_time_ = current_time; 217 first_ref_time_ = current_time;
217 got_first_frame_ = true; 218 got_first_frame_ = true;
218 } 219 }
219 220
220 // Deliver the frame when it doesn't arrive too early. 221 // Deliver the frame when it doesn't arrive too early.
221 if (expected_next_frame_time_ <= current_time) { 222 if (expected_next_frame_time_ <= current_time) {
222 expected_next_frame_time_ += frame_interval_; 223 expected_next_frame_time_ += frame_interval_;
223 224
224 // TODO(qiangchen): Investigate how to get raw timestamp for Android, 225 // TODO(qiangchen): Investigate how to get raw timestamp for Android,
225 // rather than using reference time to calculate timestamp. 226 // rather than using reference time to calculate timestamp.
226 client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length, 227 client_->OnIncomingCapturedData(reinterpret_cast<uint8_t*>(buffer), length,
227 capture_format_, rotation, current_time, 228 capture_format_, rotation, current_time,
228 current_time - first_ref_time_); 229 current_time - first_ref_time_);
229 } 230 }
230 231
231 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT); 232 env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
232 } 233 }
233 234
235 void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env,
236 jobject obj,
237 jobject y_buffer,
238 jint y_stride,
239 jobject u_buffer,
240 jobject v_buffer,
241 jint uv_row_stride,
242 jint uv_pixel_stride,
243 jint width,
244 jint height,
245 jint rotation) {
246 const base::TimeTicks current_time = base::TimeTicks::Now();
247 if (!got_first_frame_) {
248 // Set aside one frame allowance for fluctuation.
249 expected_next_frame_time_ = current_time - frame_interval_;
250 first_ref_time_ = current_time;
251 got_first_frame_ = true;
252 }
253
254 uint8_t* const y_src =
255 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer));
256 CHECK(y_src);
257 uint8_t* const u_src =
258 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer));
259 CHECK(u_src);
260 uint8_t* const v_src =
261 reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer));
262 CHECK(v_src);
263
264 const int y_plane_length = width * height;
265 const int uv_plane_length = y_plane_length / 4;
266 const int buffer_length = y_plane_length + uv_plane_length * 2;
267 std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_length]);
268
269 libyuv::Android420ToI420(y_src, y_stride, u_src, uv_row_stride, v_src,
miu 2016/07/20 19:34:22 Sanity-check question: Is client code allowed to m
braveyao 2016/07/20 22:02:04 Not quite understand the concern here. Planes have
miu 2016/07/22 20:44:24 Oh, never mind. I read this wrong. No problem here
270 uv_row_stride, uv_pixel_stride, buffer.get(), width,
271 buffer.get() + y_plane_length, width / 2,
272 buffer.get() + y_plane_length + uv_plane_length,
273 width / 2, width, height);
274
275 // Deliver the frame when it doesn't arrive too early.
276 if (expected_next_frame_time_ <= current_time) {
277 expected_next_frame_time_ += frame_interval_;
278
279 // TODO(qiangchen): Investigate how to get raw timestamp for Android,
miu 2016/07/20 19:34:22 We solved this problem in the screen capture (part
braveyao 2016/07/20 22:02:04 Screen capture doesn't care about A/V sync (no aud
280 // rather than using reference time to calculate timestamp.
281 client_->OnIncomingCapturedData(buffer.get(), buffer_length,
282 capture_format_, rotation, current_time,
283 current_time - first_ref_time_);
284 }
285 }
286
234 void VideoCaptureDeviceAndroid::OnError(JNIEnv* env, 287 void VideoCaptureDeviceAndroid::OnError(JNIEnv* env,
235 const JavaParamRef<jobject>& obj, 288 const JavaParamRef<jobject>& obj,
236 const JavaParamRef<jstring>& message) { 289 const JavaParamRef<jstring>& message) {
237 SetErrorState(FROM_HERE, 290 SetErrorState(FROM_HERE,
238 base::android::ConvertJavaStringToUTF8(env, message)); 291 base::android::ConvertJavaStringToUTF8(env, message));
239 } 292 }
240 293
241 void VideoCaptureDeviceAndroid::OnPhotoTaken( 294 void VideoCaptureDeviceAndroid::OnPhotoTaken(
242 JNIEnv* env, 295 JNIEnv* env,
243 const base::android::JavaParamRef<jobject>& obj, 296 const base::android::JavaParamRef<jobject>& obj,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 const tracked_objects::Location& from_here, 343 const tracked_objects::Location& from_here,
291 const std::string& reason) { 344 const std::string& reason) {
292 { 345 {
293 base::AutoLock lock(lock_); 346 base::AutoLock lock(lock_);
294 state_ = kError; 347 state_ = kError;
295 } 348 }
296 client_->OnError(from_here, reason); 349 client_->OnError(from_here, reason);
297 } 350 }
298 351
299 } // namespace media 352 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698