我需要使用ffmpeg调整相机预览框的大小。我编写了ffmpeg代码和相关的java代码,我正在做的是将byte []发送到本机代码并在其他byte []中获取输出但是我总是在我的本机代码中获得输出缓冲区零。
这是我的原生代码:
jint Java_com_sample_FfmpegNdk_resizeRawImage( JNIEnv *env, jobject thiz, jbyteArray input_array, jarray output_array, jint width, jint height) {
jbyte *data;
jsize array_size = (*env)->GetArrayLength(env, input_array);
data = (*env)->GetByteArrayElements(env, input_array, NULL);
LOGD_CUSTOM(env, "Data Length: (%d)", strlen(data));
LOGD_CUSTOM(env, "Array Length: (%d)", array_size);
AVFrame *frame1 = av_frame_alloc();
avpicture_fill((AVPicture*)frame1, data, AV_PIX_FMT_NV12, 720, 480);
struct SwsContext *resize;
resize = sws_getContext(720, 480, AV_PIX_FMT_NV12, width, height, AV_PIX_FMT_NV12, SWS_BICUBIC, NULL, NULL, NULL);
AVFrame* frame2 = av_frame_alloc();
int num_bytes = avpicture_get_size(AV_PIX_FMT_NV12, width, height);
uint8_t* frame2_buffer = (uint8_t *)av_malloc(num_bytes);
avpicture_fill((AVPicture*)frame2, frame2_buffer, AV_PIX_FMT_NV12, width, height);
LOGD_CUSTOM(env, "Frame1 Data: (%d)", strlen(frame1->data));
sws_scale(resize, frame1->data, frame1->linesize, 0, height, frame2->data, frame2->linesize);
LOGD_CUSTOM(env, "Frame2 Data: (%d)", strlen(frame2->data));
(*env)->ReleaseByteArrayElements(env, output_array, (jbyte*)frame2->data, JNI_ABORT);
jsize array_size_s = (*env)->GetArrayLength(env, output_array);
LOGD_CUSTOM(env, "Array Length After: (%d)", array_size_s);
sws_freeContext(resize);
free(data);
return 0;
}
这是我的代码,我正在进行相机预览
myCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(final byte[] data, Camera camera) {
if (data != null) {
byte[] new_data = new byte[1024];
Log.e("lenght", "IIp lenght : " + data.length);
FfmpegNdk.resizeRawImage(data, new_data, 480, 270);
Log.e("lenght", "oIp lenght : " + new_data.length);
}
}
});
答案 0 :(得分:0)
我认为JNI_ABORT
就是这个原因,该标志阻止JVM将数据复制回客户端。
尝试更改此行
(*env)->ReleaseByteArrayElements(env, output_array, (jbyte*)frame2->data, JNI_ABORT);
到
(*env)->ReleaseByteArrayElements(env, output_array, (jbyte*)frame2->data, JNI_COMMIT);
JNI_COMMIT
将复制数据,您需要使用
av_frame_free(&frame2)
了解更多信息,请检查 http://developer.android.com/training/articles/perf-jni.html#arrays