1717#include " JNI_VideoBufferConverter.h"
1818#include " JavaRuntimeException.h"
1919
20- #include " libyuv/convert_from.h"
20+ #include " api/video/i420_buffer.h"
21+
22+ #include " libyuv/convert.h"
2123#include " libyuv/video_common.h"
2224
2325size_t CalcBufferSize (int width, int height, int fourCC) {
@@ -78,10 +80,17 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_VideoBufferConverter_I
7880 jbyte * arrayPtr = env->GetByteArrayElements (dst, nullptr );
7981 uint8_t * dstPtr = reinterpret_cast <uint8_t *>(arrayPtr);
8082
81- libyuv::ConvertFromI420 (srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV,
82- dstPtr, 0 , width, height, static_cast <uint32_t >(fourCC));
83+ const int conversionResult = libyuv::ConvertFromI420 (srcY, srcStrideY, srcU, srcStrideU,
84+ srcV, srcStrideV, dstPtr, 0 , width, height, static_cast <uint32_t >(fourCC));
85+
86+ if (conversionResult < 0 ) {
87+ env->Throw (jni::JavaRuntimeException (env, " Failed to convert buffer to I420: %d" ,
88+ conversionResult));
89+ }
90+ else {
91+ env->SetByteArrayRegion (dst, 0 , arrayLength, arrayPtr);
92+ }
8393
84- env->SetByteArrayRegion (dst, 0 , arrayLength, arrayPtr);
8594 env->ReleaseByteArrayElements (dst, arrayPtr, JNI_ABORT);
8695}
8796
@@ -105,8 +114,87 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_VideoBufferConverter_I
105114 return ;
106115 }
107116
108- libyuv::ConvertFromI420 (srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV,
109- address, 0 , width, height, static_cast <uint32_t >(fourCC));
117+ const int conversionResult = libyuv::ConvertFromI420 (srcY, srcStrideY, srcU, srcStrideU,
118+ srcV, srcStrideV, address, 0 , width, height, static_cast <uint32_t >(fourCC));
119+
120+ if (conversionResult < 0 ) {
121+ env->Throw (jni::JavaRuntimeException (env, " Failed to convert buffer to I420: %d" ,
122+ conversionResult));
123+ }
124+ }
125+ else {
126+ env->Throw (jni::JavaRuntimeException (env, " Non-direct buffer provided" ));
127+ }
128+ }
129+
130+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_VideoBufferConverter_byteArrayToI420
131+ (JNIEnv * env, jclass cls, jbyteArray src, jint width, jint height, jobject jDstY, jint dstStrideY,
132+ jobject jDstU, jint dstStrideU, jobject jDstV, jint dstStrideV, jint fourCC)
133+ {
134+ jsize arrayLength = env->GetArrayLength (src);
135+ size_t requiredSize = CalcBufferSize (width, height, fourCC);
136+
137+ if (arrayLength < requiredSize) {
138+ env->Throw (jni::JavaRuntimeException (env, " Insufficient buffer size [has %d, need %zd]" ,
139+ arrayLength, requiredSize));
140+ return ;
141+ }
142+
143+ uint8_t * dstY = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstY));
144+ uint8_t * dstU = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstU));
145+ uint8_t * dstV = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstV));
146+
147+ jbyte * arrayPtr = env->GetByteArrayElements (src, nullptr );
148+ const uint8_t * srcPtr = reinterpret_cast <uint8_t *>(arrayPtr);
149+
150+ const int conversionResult = libyuv::ConvertToI420 (
151+ srcPtr, arrayLength,
152+ dstY, dstStrideY,
153+ dstU, dstStrideU,
154+ dstV, dstStrideV,
155+ 0 , 0 , width, height, width, height,
156+ libyuv::kRotate0 , static_cast <uint32_t >(fourCC));
157+
158+ if (conversionResult < 0 ) {
159+ env->Throw (jni::JavaRuntimeException (env, " Failed to convert buffer to I420: %d" ,
160+ conversionResult));
161+ }
162+
163+ env->ReleaseByteArrayElements (src, arrayPtr, JNI_ABORT);
164+ }
165+
166+ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_media_video_VideoBufferConverter_directBufferToI420
167+ (JNIEnv * env, jclass, jobject src, jint width, jint height, jobject jDstY, jint dstStrideY,
168+ jobject jDstU, jint dstStrideU, jobject jDstV, jint dstStrideV, jint fourCC)
169+ {
170+ uint8_t * dstY = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstY));
171+ uint8_t * dstU = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstU));
172+ uint8_t * dstV = static_cast <uint8_t *>(env->GetDirectBufferAddress (jDstV));
173+
174+ const uint8_t * address = static_cast <uint8_t *>(env->GetDirectBufferAddress (src));
175+
176+ if (address != NULL ) {
177+ size_t bufferLength = env->GetDirectBufferCapacity (src);
178+ size_t requiredSize = CalcBufferSize (width, height, fourCC);
179+
180+ if (bufferLength < requiredSize) {
181+ env->Throw (jni::JavaRuntimeException (env, " Insufficient buffer size [has %zd, need %zd]" ,
182+ bufferLength, requiredSize));
183+ return ;
184+ }
185+
186+ const int conversionResult = libyuv::ConvertToI420 (
187+ address, bufferLength,
188+ dstY, dstStrideY,
189+ dstU, dstStrideU,
190+ dstV, dstStrideV,
191+ 0 , 0 , width, height, width, height,
192+ libyuv::kRotate0 , static_cast <uint32_t >(fourCC));
193+
194+ if (conversionResult < 0 ) {
195+ env->Throw (jni::JavaRuntimeException (env, " Failed to convert buffer to I420: %d" ,
196+ conversionResult));
197+ }
110198 }
111199 else {
112200 env->Throw (jni::JavaRuntimeException (env, " Non-direct buffer provided" ));
0 commit comments