繁体   English   中英

使用FFMPEG调整视频帧的大小

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM