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

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

Issue 1460703002: Implement AndroidTextureBuffer::NativeToI420. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Get a shared ref to the java SurfaceTectureHelper. 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,
11 * this list of conditions and the following disclaimer in the documentation 11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution. 12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products 13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
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 #include <android/log.h>
28 #include "talk/app/webrtc/java/jni/native_handle_impl.h" 29 #include "talk/app/webrtc/java/jni/native_handle_impl.h"
29 30
31 #include "talk/app/webrtc/java/jni/jni_helpers.h"
32 #include "third_party/libyuv/include/libyuv/convert.h"
33 #include "webrtc/base/bind.h"
30 #include "webrtc/base/checks.h" 34 #include "webrtc/base/checks.h"
31 #include "webrtc/base/keep_ref_until_done.h" 35 #include "webrtc/base/keep_ref_until_done.h"
36 #include "webrtc/base/logging.h"
32 #include "webrtc/base/scoped_ref_ptr.h" 37 #include "webrtc/base/scoped_ref_ptr.h"
33 38
34 using webrtc::NativeHandleBuffer; 39 using webrtc::NativeHandleBuffer;
35 40
36 namespace webrtc_jni { 41 namespace webrtc_jni {
37 42
43 // Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
44 static const int kBufferAlignment = 64;
45
38 NativeHandleImpl::NativeHandleImpl(JNIEnv* jni, 46 NativeHandleImpl::NativeHandleImpl(JNIEnv* jni,
39 jint j_oes_texture_id, 47 jint j_oes_texture_id,
40 jfloatArray j_transform_matrix) 48 jfloatArray j_transform_matrix,
41 : oes_texture_id(j_oes_texture_id) { 49 jobject helper)
50 : oes_texture_id(j_oes_texture_id),
51 surface_texture_helper(helper) {
42 RTC_CHECK_EQ(16, jni->GetArrayLength(j_transform_matrix)); 52 RTC_CHECK_EQ(16, jni->GetArrayLength(j_transform_matrix));
43 jfloat* transform_matrix_ptr = 53 jfloat* transform_matrix_ptr =
44 jni->GetFloatArrayElements(j_transform_matrix, nullptr); 54 jni->GetFloatArrayElements(j_transform_matrix, nullptr);
55 // TODO(nisse): Hold on to java float array instead, since it is
magjed_webrtc 2015/12/03 12:33:58 Yes, but then you need a ScopedGlobalRef or simila
nisse-webrtc 2015/12/03 13:35:20 If we add a reference to the java array, can we de
magjed_webrtc 2015/12/03 14:30:46 Yes, then we wouldn't need the C++ sampling_matrix
56 // used only for callbacks into java.
45 for (int i = 0; i < 16; ++i) { 57 for (int i = 0; i < 16; ++i) {
46 sampling_matrix[i] = transform_matrix_ptr[i]; 58 sampling_matrix[i] = transform_matrix_ptr[i];
47 } 59 }
48 jni->ReleaseFloatArrayElements(j_transform_matrix, transform_matrix_ptr, 0); 60 jni->ReleaseFloatArrayElements(j_transform_matrix, transform_matrix_ptr, 0);
49 } 61 }
50 62
51 AndroidTextureBuffer::AndroidTextureBuffer( 63 AndroidTextureBuffer::AndroidTextureBuffer(
52 int width, 64 int width,
53 int height, 65 int height,
54 const NativeHandleImpl& native_handle, 66 const NativeHandleImpl& native_handle,
55 const rtc::Callback0<void>& no_longer_used) 67 const rtc::Callback0<void>& no_longer_used)
56 : webrtc::NativeHandleBuffer(&native_handle_, width, height), 68 : webrtc::NativeHandleBuffer(&native_handle_, width, height),
57 native_handle_(native_handle), 69 native_handle_(native_handle),
58 no_longer_used_cb_(no_longer_used) {} 70 no_longer_used_cb_(no_longer_used) {}
59 71
60 AndroidTextureBuffer::~AndroidTextureBuffer() { 72 AndroidTextureBuffer::~AndroidTextureBuffer() {
61 no_longer_used_cb_(); 73 no_longer_used_cb_();
62 } 74 }
63 75
76 #define TAG "AndroidTextureBuffer"
77 // Alternatively: #define AT_LOG LOG(LS_ERROR)
78 #define ALOGE LOG_TAG(rtc::LS_ERROR, TAG)
79
80 #define USE_CONVERT_YUV 1
81 #if USE_CONVERT_YUV
64 rtc::scoped_refptr<webrtc::VideoFrameBuffer> 82 rtc::scoped_refptr<webrtc::VideoFrameBuffer>
65 AndroidTextureBuffer::NativeToI420Buffer() { 83 AndroidTextureBuffer::NativeToI420Buffer() {
66 RTC_NOTREACHED() 84 ALOGE << "NativeToI420Buffer called";
67 << "AndroidTextureBuffer::NativeToI420Buffer not implemented."; 85 int y_width = (width()+3) / 4;
68 return nullptr; 86 int uv_width = (width()+7) / 8;
87 int stride = 8 * uv_width;
88 int uv_height = (height()+1)/2;
89 size_t size = stride * (height() + uv_height);
90 // TODO(nisse): Use scoped_ptr? The data is owned by the frame, and
91 // deleted by its destructor callback.
magjed_webrtc 2015/12/03 12:33:58 Yes, use scoped_ptr here...
nisse-webrtc 2015/12/04 09:40:34 Done. Not sure if it's an improvement, though. W
92 uint8_t *y_data = static_cast<uint8_t*>(
93 webrtc::AlignedMalloc(size, kBufferAlignment));
94 uint8_t *u_data = y_data + height() * stride;
95 uint8_t *v_data = u_data + stride/2;
96
97 rtc::scoped_refptr<webrtc::VideoFrameBuffer> copy =
98 new rtc::RefCountedObject<webrtc::WrappedI420Buffer>(
99 width(), height(),
100 y_data, stride,
101 u_data, stride,
102 v_data, stride,
103 rtc::Bind(&webrtc::AlignedFree, y_data));
magjed_webrtc 2015/12/03 12:33:58 ...and y_data.release() here. Btw, you need to cha
nisse-webrtc 2015/12/03 13:35:20 Rename, why and to what?
magjed_webrtc 2015/12/03 14:30:46 Why? - Because it is not just y data anymore. To w
104
105 ALOGE << "width: " << width() << " height: " << height() <<
106 " stride: " << stride;
107
108 JNIEnv* jni = AttachCurrentThreadIfNeeded();
109 ScopedLocalRefFrame local_ref_frame(jni);
110
111 ALOGE << "Looking up textureToYUV mid";
112 jmethodID transform_mid = GetMethodID(
113 jni,
114 GetObjectClass(jni, native_handle_.surface_texture_helper),
115 "textureToYUV",
116 "(Ljava/nio/ByteBuffer;IIII[F)V");
117
118 ALOGE << "Creating byte buffer";
119 jobject byte_buffer = jni->NewDirectByteBuffer(y_data, size);
120
121 /* Set u = v = 0. */
122 memset(u_data, 0x80, stride * uv_height);
123
124 // TODO(nisse): Keep java transform matrix around.
125 jfloatArray sampling_matrix = jni->NewFloatArray(16);
126 jni->SetFloatArrayRegion(sampling_matrix, 0, 16,
127 native_handle_.sampling_matrix);
128
129 ALOGE << "Calling java textureToYUV";
130 jni->CallVoidMethod(native_handle_.surface_texture_helper,
131 transform_mid,
132 byte_buffer, width(), height(), stride,
133 native_handle_.oes_texture_id, sampling_matrix);
134 CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception";
135
136 return copy;
69 } 137 }
70 138
139 #else /* ! USE_CONVERT_YUV */
140 rtc::scoped_refptr<webrtc::VideoFrameBuffer>
141 AndroidTextureBuffer::NativeToI420Buffer() {
142 ALOGE << "NativeToI420Buffer called";
143 rtc::scoped_refptr<webrtc::VideoFrameBuffer> copy =
144 new rtc::RefCountedObject<webrtc::I420Buffer>(
145 width(), height());
146
147 JNIEnv* jni = AttachCurrentThreadIfNeeded();
148 ScopedLocalRefFrame local_ref_frame(jni);
149
150 ALOGE << "Looking up textureToRGBA mid";
151 jmethodID transform_mid = GetMethodID(
152 jni,
153 GetObjectClass(jni, native_handle_.surface_texture_helper),
154 "textureToRGBA",
155 "(Ljava/nio/ByteBuffer;III[F)V");
156 size_t size = 4*width() * height();
157 uint8_t *rgba = new uint8_t[size];
158 ALOGE << "Creating byte buffer";
159 jobject byte_buffer = jni->NewDirectByteBuffer(rgba, size);
160 // TODO(nisse): Keep java transform matrix around.
161 jfloatArray sampling_matrix = jni->NewFloatArray(16);
162 jni->SetFloatArrayRegion(sampling_matrix, 0, 16,
163 native_handle_.sampling_matrix);
164
165 ALOGE << "Calling java textureToRGBA";
166 jni->CallVoidMethod(native_handle_.surface_texture_helper,
167 transform_mid,
168 byte_buffer, width(), height(),
169 native_handle_.oes_texture_id, sampling_matrix);
170 CHECK_EXCEPTION(jni) << "textureToRGBA throwed an exception";
171
172 ALOGE << "Converting to YUV";
173 libyuv::ABGRToI420(
174 rgba, 4*width(),
175 copy->MutableData(webrtc::kYPlane), copy->stride(webrtc::kYPlane),
176 copy->MutableData(webrtc::kUPlane), copy->stride(webrtc::kUPlane),
177 copy->MutableData(webrtc::kVPlane), copy->stride(webrtc::kVPlane),
178 width(), height());
179
180 // TODO(nisse): Use some destructor or scoped_*, to make it
181 // exception safe.
182 delete[] rgba;
183
184 return copy;
185 }
186 #endif /* ! USE_CONVERT_YUV */
187
71 rtc::scoped_refptr<AndroidTextureBuffer> AndroidTextureBuffer::CropAndScale( 188 rtc::scoped_refptr<AndroidTextureBuffer> AndroidTextureBuffer::CropAndScale(
72 int cropped_input_width, 189 int cropped_input_width,
73 int cropped_input_height, 190 int cropped_input_height,
74 int dst_widht, 191 int dst_widht,
75 int dst_height) { 192 int dst_height) {
76 // TODO(perkj) Implement cropping. 193 // TODO(perkj) Implement cropping.
77 RTC_CHECK_EQ(cropped_input_width, width_); 194 RTC_CHECK_EQ(cropped_input_width, width_);
78 RTC_CHECK_EQ(cropped_input_height, height_); 195 RTC_CHECK_EQ(cropped_input_height, height_);
79 196
80 // Here we use Bind magic to add a reference count to |this| until the newly 197 // Here we use Bind magic to add a reference count to |this| until the newly
81 // created AndroidTextureBuffer is destructed. ScaledFrameNotInUse will be 198 // created AndroidTextureBuffer is destructed. ScaledFrameNotInUse will be
82 // called that happens and when it finishes, the reference count to |this| 199 // called that happens and when it finishes, the reference count to |this|
83 // will be decreased by one. 200 // will be decreased by one.
84 return new rtc::RefCountedObject<AndroidTextureBuffer>( 201 return new rtc::RefCountedObject<AndroidTextureBuffer>(
85 dst_widht, dst_height, native_handle_, 202 dst_widht, dst_height, native_handle_,
86 rtc::KeepRefUntilDone(this)); 203 rtc::KeepRefUntilDone(this));
87 } 204 }
88 205
89 } // namespace webrtc_jni 206 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698