gpt4 book ai didi

Android 应用程序在物理设备上崩溃但不是模拟器 : "Parcel: dup() failed in Parcel::read [...] error: Too many open files"

转载 作者:行者123 更新时间:2023-12-02 12:11:30 26 4
gpt4 key购买 nike

我正试图将旧手机变成联网安全摄像头,因为在所有这些骚乱期间,我所在地区的犯罪率急剧增加(而且我不想依赖其他人的应用程序来控制对我私有(private)时刻的访问)。
我正在分 block 和发送,所以相机记录视频几秒钟,停止,将捕获文件的二进制编码为 Base64,然后通过 POST 请求将其发送到家庭服务器,所有这些都在一个无限循环中。服务器解包 + 解码 + 将其作为原始二进制“MP4”保存到自己的磁盘上(TODO:用于运动检测的有趣后处理)。
在我的目标手机的操作系统版本和屏幕尺寸(及其周围)使用各种虚拟设备,这一切都可以长时间工作。我使用 60 秒的 block 超过 15 分钟,加上 6 秒的 block 超过一个小时。我一直收到模拟器在我的服务器上生成的愚蠢的虚拟房间视频。
但在运行 Android 6.0.1 并梦想成为安全摄像头的三星 Galaxy S5 上,通常需要发送 2 或 3 个视频才能让应用崩溃……除非你的分辨率设置得太高,否则你会遇到不同的情况症状。
症状 #0:在 block 的末尾崩溃

E/Parcel: dup() failed in Parcel::read, i is 1, fds[i] is -1, fd_count is 2, error: Too many open files

E/Surface: dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: -22

W/Adreno-EGLSUB: DequeueBuffer:721: dequeue native buffer fail: Invalid argument, buffer=0x0, handle=0x0

W/Adreno-EGL: <qeglDrvAPI_eglSwapBuffers:3800>: EGL_BAD_SURFACE


紧随其后的是第二个错误:

E/CameraDeviceGLThread-1: Received exception on GL render thread:

java.lang.IllegalStateException: swapBuffers: EGL error: 0x300d

最后,一旦 block 时间到了,相机再次进入录制,最终的错误发生,导致整个应用程序崩溃:

I/CameraDeviceState: Legacy camera service transitioning to state ERROR

E/AndroidRuntime: FATAL EXCEPTION: CameraThread

Process: com.example.roselawncam, PID: 14639

android.hardware.camera2.CameraAccessException: The camera device has encountered a serious error


症状 #1:因为你走得太远而在一个 block 中间崩溃了 🌈高分辨率🌈 为了你自己好
这些警告清楚地表明资源紧张会导致此症状。它们在应用程序崩溃时发生,更高的分辨率会导致更快的崩溃。我给这些坏男孩打了钟:
  • 1920x1080 (30 FPS):5 秒
  • 1280x720 (30 FPS):9 秒
  • 800x480 (30 FPS):15 秒

  • 前后摄像头的时间相似。在较低的分辨率下,您会开始遇到症状 #0,除非您将 block 时间延长。反正:

    W/Adreno-GSL: <gsl_ldd_control:475>: ioctl fd 28 code 0xc01c0915 (IOCTL_KGSL_MAP_USER_MEM) failed: errno 12 Out of memory

    W/Adreno-EGLSUB: SyncBackBuffer:3130: failed to map the memory for fd=281 offs=0

    E/Adreno-EGLSUB: SyncBackBuffer:3131: SyncBackBuffer: FATAL ERROR : (null)

    A/Adreno-GSL: Exiting the process com.example.roselawncam from function SyncBackBuffer and line 3131

    A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 19618 (CameraDeviceGLT)


    最后,相关的 Kotlin 部分:
    private fun createRecorder(surface: Surface) = MediaRecorder().apply {
    setAudioSource(MediaRecorder.AudioSource.MIC)
    setVideoSource(MediaRecorder.VideoSource.SURFACE)
    setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    setOutputFile(outputFile.absolutePath)
    setVideoEncodingBitRate(RECORDER_VIDEO_BITRATE)
    if (args_fps > 0) setVideoFrameRate(args_fps)
    setVideoSize(args_width, args_height)
    setVideoEncoder(MediaRecorder.VideoEncoder.H264)
    setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    setInputSurface(surface)
    }

    private fun recordIt(cameraManager: CameraManager, cameraThread: HandlerThread) {
    val cameraHandler = Handler(cameraThread.looper)
    val stateCallback: CameraDevice.StateCallback = object: CameraDevice.StateCallback() {
    override fun onOpened(camera: CameraDevice) {
    camera.createCaptureSession(
    listOf<Surface>(recorderSurface),
    object : CameraCaptureSession.StateCallback() {
    override fun onConfigured(session: CameraCaptureSession) {
    val recTimeSeconds = findViewById<TextView>(R.id.recTimeSeconds)
    val chunkTimeMilliseconds = recTimeSeconds.text.toString().toLong() * 1000

    // Boolean "stopREC" (e.g. "Stop Recording") is false at this point
    while (!stopREC) {
    // // // This loop should run forever, but crashes after a few times // // //
    val recorder: MediaRecorder by lazy { createRecorder(recorderSurface) }
    val recordRequest: CaptureRequest by lazy {
    session.device.createCaptureRequest(CameraDevice.TEMPLATE_RECORD).apply {
    addTarget(recorderSurface)
    set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, Range(args_fps, args_fps))
    }.build()
    }
    session.setRepeatingRequest(recordRequest, null, cameraHandler)
    recorder.apply { prepare(); start() }
    Thread.sleep(chunkTimeMilliseconds)
    recorder.apply { stop(); release() }

    // Send the video file across the network in JSON via POST request:
    val params = HashMap<String, String>()
    params["videodata"] = convertToBase64(outputFile)
    val jsonObject = JSONObject(params as Map<*, *>)
    val request = JsonObjectRequest(Request.Method.POST, url, jsonObject, null, null)
    queue.add(request)
    // // // End of loop that should've ran forever, but crashes occasionally instead // // //
    }
    camera.close()
    }
    override fun onConfigureFailed(session: CameraCaptureSession) {}
    },
    cameraHandler
    )
    }
    override fun onDisconnected(camera: CameraDevice) { recorder.stop(); recorder.release() }
    override fun onError(camera: CameraDevice, error:Int) { camera.close() }
    }
    cameraManager.openCamera(args_cameraId, stateCallback, cameraHandler)
    }

    最佳答案

    我有一些建议:

  • 在需要 file lock 的地方强制使用同步函数因此线程将按顺序执行该代码块,打开和关闭 file stream以有组织的方式,例如,访问文件。这样可以避免 out of memoryfile already in use错误。
  • 是否可以不将文件编码为 Base 64 ?字符串太大,检查是否避免任何错误。

  • 以及创建自己的应用程序的好举措。

    关于Android 应用程序在物理设备上崩溃但不是模拟器 : "Parcel: dup() failed in Parcel::read [...] error: Too many open files",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63626751/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com