Chromium Code Reviews| Index: media/capture/video/android/video_capture_device_android.cc |
| diff --git a/media/capture/video/android/video_capture_device_android.cc b/media/capture/video/android/video_capture_device_android.cc |
| index 320976116830970cf156ff0ea1769fcd97447789..8fb8623903b8406f6212e10f4798609b7f96e86d 100644 |
| --- a/media/capture/video/android/video_capture_device_android.cc |
| +++ b/media/capture/video/android/video_capture_device_android.cc |
| @@ -15,6 +15,7 @@ |
| #include "media/capture/video/android/photo_capabilities.h" |
| #include "media/capture/video/android/video_capture_device_factory_android.h" |
| #include "mojo/public/cpp/bindings/string.h" |
| +#include "third_party/libyuv/include/libyuv.h" |
| using base::android::AttachCurrentThread; |
| using base::android::CheckException; |
| @@ -209,7 +210,7 @@ void VideoCaptureDeviceAndroid::OnFrameAvailable( |
| return; |
| } |
| - base::TimeTicks current_time = base::TimeTicks::Now(); |
| + const base::TimeTicks current_time = base::TimeTicks::Now(); |
| if (!got_first_frame_) { |
| // Set aside one frame allowance for fluctuation. |
| expected_next_frame_time_ = current_time - frame_interval_; |
| @@ -231,6 +232,58 @@ void VideoCaptureDeviceAndroid::OnFrameAvailable( |
| env->ReleaseByteArrayElements(data, buffer, JNI_ABORT); |
| } |
| +void VideoCaptureDeviceAndroid::OnI420FrameAvailable(JNIEnv* env, |
| + jobject obj, |
| + jobject y_buffer, |
| + jint y_stride, |
| + jobject u_buffer, |
| + jobject v_buffer, |
| + jint uv_row_stride, |
| + jint uv_pixel_stride, |
| + jint width, |
| + jint height, |
| + jint rotation) { |
| + const base::TimeTicks current_time = base::TimeTicks::Now(); |
| + if (!got_first_frame_) { |
| + // Set aside one frame allowance for fluctuation. |
| + expected_next_frame_time_ = current_time - frame_interval_; |
| + first_ref_time_ = current_time; |
| + got_first_frame_ = true; |
| + } |
| + |
| + uint8_t* const y_src = |
| + reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(y_buffer)); |
| + CHECK(y_src); |
| + uint8_t* const u_src = |
| + reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(u_buffer)); |
| + CHECK(u_src); |
| + uint8_t* const v_src = |
| + reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(v_buffer)); |
| + CHECK(v_src); |
| + |
| + const int y_plane_length = width * height; |
| + const int uv_plane_length = y_plane_length / 4; |
| + const int buffer_length = y_plane_length + uv_plane_length * 2; |
| + std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_length]); |
| + |
| + 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
|
| + uv_row_stride, uv_pixel_stride, buffer.get(), width, |
| + buffer.get() + y_plane_length, width / 2, |
| + buffer.get() + y_plane_length + uv_plane_length, |
| + width / 2, width, height); |
| + |
| + // Deliver the frame when it doesn't arrive too early. |
| + if (expected_next_frame_time_ <= current_time) { |
| + expected_next_frame_time_ += frame_interval_; |
| + |
| + // 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
|
| + // rather than using reference time to calculate timestamp. |
| + client_->OnIncomingCapturedData(buffer.get(), buffer_length, |
| + capture_format_, rotation, current_time, |
| + current_time - first_ref_time_); |
| + } |
| +} |
| + |
| void VideoCaptureDeviceAndroid::OnError(JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| const JavaParamRef<jstring>& message) { |