android - 当 >= 65[FPS] 时,camera2 API 帧跳过并崩溃

标签 android crash frame-rate android-camera2 mediarecorder

我目前正在开发一个以 this project 为例进行慢动作录制的 Android 应用程序。我已经在 ZTE BLADE L5 PLUS (Android 5.0) 上尝试过这个应用程序,它运行得很好,但是由于我需要超过 30[FPS] 才能获得高质量的慢动作视频,所以我换成了 Sony Xperia XZs (Android 8.0)并尝试了这个应用程序。

我现在有两个问题:

1.-跳过的帧:
当我从 30(没有尝试过)到 65 FPS 录制时,应用程序偶尔会丢失比我用 mMediaRecorder.setVideoFrameRate(int) 修复的帧更多的帧,这实际上使视频输出“卡住”超过 1 秒。为什么会发生这种情况以及如何预防?

2.-如果我设置的值 >= 65 FPS,应用程序就会崩溃:
我实际上不知道我在这里做错了什么。如果有人在代码中看到可能导致失败的内容,我将不胜感激所有帮助。

代码:

    private void setupMediaRecorder() throws IOException
{
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setOutputFile(mVideoFileName);
    mMediaRecorder.setVideoEncodingBitRate(1000000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mMediaRecorder.setOrientationHint(mTotalRotation);
    try
    {
        mMediaRecorder.prepare();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

< 65FPS 的日志:
    11-07 11:33:28.788 9285-9309/com.company.www.project I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
11-07 11:33:28.793 9285-9309/com.company.www.project I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
11-07 11:33:28.809 9285-9309/com.company.www.project I/OpenGLRenderer: Initialized EGL, version 1.4
11-07 11:33:28.846 9285-9285/com.company.www.project I/CameraManagerGlobal: Connecting to camera service
11-07 11:33:28.874 9285-9285/com.company.www.project E/libc: Access denied finding property "persist.camera.cfa.packagelist"
11-07 11:33:28.862 9285-9285/com.company.www.project W/.project: type=1400 audit(0.0:1356): avc: denied { read } for name="u:object_r:camera_prop:s0" dev="tmpfs" ino=3332 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:camera_prop:s0 tclass=file permissive=0 ppid=1034 pcomm="main" pgid=1034 pgcomm="main"
11-07 11:33:28.874 9285-9285/com.company.www.project E/libc: Access denied finding property "persist.camera.cfa.packagelist"
11-07 11:33:28.879 9285-9290/com.company.www.project I/zygote64: Do partial code cache collection, code=27KB, data=23KB
    After code cache collection, code=27KB, data=23KB
    Increasing code cache capacity to 128KB
11-07 11:33:28.936 9285-9309/com.company.www.project I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
11-07 11:33:31.638 9285-9290/com.company.www.project I/zygote64: Do partial code cache collection, code=50KB, data=44KB
    After code cache collection, code=50KB, data=44KB
    Increasing code cache capacity to 256KB
11-07 11:33:31.639 9285-9290/com.company.www.project I/zygote64: Compiler allocated 6MB to compile void android.view.ViewRootImpl.performTraversals()
11-07 11:33:39.400 9285-9290/com.company.www.project I/zygote64: Do full code cache collection, code=124KB, data=90KB
11-07 11:33:39.401 9285-9290/com.company.www.project I/zygote64: After code cache collection, code=89KB, data=59KB
11-07 11:34:00.273 9285-9285/com.company.www.project I/Choreographer: Skipped 55 frames!  The application may be doing too much work on its main thread.
11-07 11:34:00.729 9285-9290/com.company.www.project I/zygote64: Do partial code cache collection, code=124KB, data=82KB
    After code cache collection, code=124KB, data=82KB
    Increasing code cache capacity to 512KB
11-07 11:34:21.830 9285-9285/com.company.www.project I/Choreographer: Skipped 36 frames!  The application may be doing too much work on its main thread.

日志 >= 65FPS:
11-07 12:14:59.806 10366-10366/com.company.www.project E/MediaRecorder: prepare failed: -2147483648
11-07 12:14:59.806 10366-10366/com.company.www.project W/System.err: java.io.IOException: prepare failed.
11-07 12:14:59.807 10366-10366/com.company.www.project W/System.err:     at android.media.MediaRecorder._prepare(Native Method)
        at android.media.MediaRecorder.prepare(MediaRecorder.java:954)
        at com.company.www.project.MainActivity.setupMediaRecorder(MainActivity.java:444)
        at com.company.www.project.MainActivity.startRecord(MainActivity.java:456)
        at com.company.www.project.MainActivity.checkWriteStoragePermission(MainActivity.java:412)
        at com.company.www.project.MainActivity.access$800(MainActivity.java:42)
        at com.company.www.project.MainActivity$3.onClick(MainActivity.java:191)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24710)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:251)
        at android.app.ActivityThread.main(ActivityThread.java:6572)
11-07 12:14:59.808 10366-10366/com.company.www.project W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
11-07 12:14:59.808 10366-10366/com.company.www.project E/MediaRecorder: SurfaceMediaSource could not be initialized!
11-07 12:14:59.810 10366-10366/com.company.www.project E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.company.www.project, PID: 10366
    java.lang.IllegalStateException: failed to get surface
        at android.media.MediaRecorder.getSurface(Native Method)
        at com.company.www.project.MainActivity.startRecord(MainActivity.java:467)
        at com.company.www.project.MainActivity.checkWriteStoragePermission(MainActivity.java:412)
        at com.company.www.project.MainActivity.access$800(MainActivity.java:42)
        at com.company.www.project.MainActivity$3.onClick(MainActivity.java:191)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24710)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:251)
        at android.app.ActivityThread.main(ActivityThread.java:6572)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

谢谢你的时间=)

最佳答案

好的,我找到了一个部分答案,我将与我遇到的下一个问题分享:)
所以我现在所做的就是将 QUALITY_HIGH 配置文件作为我的 mMediaRecorder 的基础,并且只是更改了比特率和帧率,试图以 120 FPS 的速度记录,就像这样:

private void setupMediaRecorder() throws IOException
{
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    mMediaRecorder.setOutputFormat(profile.fileFormat);
    mMediaRecorder.setVideoEncoder(profile.videoCodec);
    mMediaRecorder.setVideoEncodingBitRate(8000000);
    mMediaRecorder.setVideoFrameRate(120);
    mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);

    mMediaRecorder.setOutputFile(mVideoFileName);

    mMediaRecorder.setOrientationHint(mTotalRotation);
    try
    {
        mMediaRecorder.prepare();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

现在我正在录制 30 FPS 的视频,但我实际上并不理解 --> 如果我在 MediaRecorder 上设置 120 FPS 会怎样?

关于如何让 MediaRecorder 以 120FPS 实际录制的任何想法?

谢谢!

关于android - 当 >= 65[FPS] 时,camera2 API 帧跳过并崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53187910/

相关文章:

vba - 由于缺少引用xlam,Excel崩溃

java - 提高 LWJGL 游戏性能的最佳方法是什么?

android - 为每个对话框更改对话框主题

Android:在 Android 1.5 上安装应用程序时 INSTALL_FAILED_DEXOPT

ios - 无法在标签栏上找到随机崩溃的根本原因

iphone - iPad 应用程序的奇怪崩溃报告

java - 独立于帧率的 LibGdx 物理

c++ - 如何更改libav解码帧率?

java - 将代码从 onCreate 方法中移出并移到它自己的类文件中

java - 如何在用户编辑后获取 EditText 的值?