[英]Resize video frame using FFMPEG
我需要使用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);
}
}
});
我认为是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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.