高速视频录制(使用 CameraConstrainedHighSpeedCaptureSession)崩溃并显示奇怪的行为

High speed video recording (using CameraConstrainedHighSpeedCaptureSession) crashing and displaying odd behaviour

对于上下文:我正在开发一个评估视频到音频同步的应用程序,因此它对时间非常敏感。

在我的 Pixel 2XL 上录制、解码和评估工作正常且准确,但在其他手机上的问题包括:

在 firebase 测试中,它会导致两部独立手机(OnePlus 3t 和 Razer 2 - not OnePlus 5t 或更高版本 - API 28)上的本机崩溃。

在 Samsung SM-G975 (API 28) 上它会导致显示屏冻结,但会录制视频。

在惠威 3P 上它 returns 极度不准确的结果(8 或 9 帧)。

我同样打开 CameraCapture 会话:

private void setupHighSpeedSession() {
 try {
 openCloseLock.acquire();
 mCaptureSession.abortCaptures();
 mImageReader.close();
 mCaptureRequestBuilder = null;
 mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
 List<Surface> surfaceList = new ArrayList<>();

 Surface recorderSurface = mRecordAnalyze.getRecorder().getSurface();
 surfaceList.add(recorderSurface);
 mCaptureRequestBuilder.addTarget(recorderSurface);

 SurfaceTexture previewTexture = preview.getSurfaceTexture();

 previewTexture.setDefaultBufferSize(highSpeedSize.getWidth(), highSpeedSize.getHeight());

 Surface previewSurface = new Surface(previewTexture);

 surfaceList.add(previewSurface);
 mCaptureRequestBuilder.addTarget(previewSurface);

 mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
 highSpeedFrameRate);

 mCaptureRequestBuilder.setTag(CAMERA_HIGHSPEED_TAG);

 if (!openCloseLock.tryAcquire(5000, TimeUnit.MILLISECONDS)) {
 throw new RuntimeException("Timeout waiting for mCamera lock");
 }
 mCameraDevice.createConstrainedHighSpeedCaptureSession(surfaceList, mCaptureSessionListener, mBackgroundHandler);
 } catch (CameraAccessException e) {
 e.printStackTrace();
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 openCloseLock.release();
 }

并设置 MediaRecorder:

void setupRecorder() throws IOException {
 mRecorder = new MediaRecorder();
 mRecorder.setAudioSource(mAudioProcessor.getAudioInput());
 mRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
 mRecorder.setVideoFrameRate(mCamera.getHighSpeedFrameRate());
 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
 mRecorder.setAudioChannels(1);
 Size highSpeedSize = mCamera.getHighSpeedSize();
 Log.i(TAG, "RecAnalyze Size: " + highSpeedSize);
 mRecorder.setVideoSize(highSpeedSize.getWidth(), highSpeedSize.getHeight());
 recordFile = getRecorderPath();
 Log.i(TAG, "RecAnalyze Path: " + recordFile.getAbsolutePath());
 mRecorder.setOutputFile(recordFile.getAbsolutePath());

用于高速功能的轮询摄像头:

if (cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)[i] ==
 CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO) {
 if (Arrays.asList(map.getHighSpeedVideoFpsRanges()).contains(new Range<>(120, 120))) {
 highSpeedFrameRate = new Range<>(120, 120);
 } else {
 highSpeedFrameRate = Collections.min(Arrays.asList(map.getHighSpeedVideoFpsRanges()), new CompareRange());
 }
 highSpeedSize = Collections.min(Arrays.asList(map.getHighSpeedVideoSizesFor(highSpeedFrameRate)), new CompareByArea());

另一件奇怪的事情:许多电话,其规格宣传高速功能,报告自己无法记录高速。

OnePlus 3t 崩溃:

     *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'OnePlus/OnePlus3/OnePlus3T:8.0.0/OPR1.170623.032/05171658:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 896, tid: 22783, name: C3Dev-0-ReqQueu  >>> /system/bin/cameraserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
Cause: null pointer dereference
    r0 00000001  r1 00000000  r2 00000002  r3 0000ec9e
    r4 00000001  r5 ecdf9600  r6 0000f042  r7 00000002
    r8 00000000  r9 ee7f96ac  sl ecdb2f00  fp ecdb2f0c
    ip 00000000  sp ede00718  lr f07a5aef  pc f07a6838  cpsr 600f0030
backtrace:
    #00 pc 000a7838  /system/lib/libcameraservice.so (_ZNSt3__113unordered_mapIKPK13native_handleyN7android13Camera3Device12HalInterface12BufferHasherENS7_16BufferComparatorENS_9allocatorINS_4pairIS4_yEEEEEixERS4_+159)
    #01 pc 000a6aeb  /system/lib/libcameraservice.so (_ZN7android13Camera3Device12HalInterface11getBufferIdERKPK13native_handlei+86)
    #02 pc 000a69a9  /system/lib/libcameraservice.so (_ZN7android13Camera3Device12HalInterface17wrapAsHidlRequestEP23camera3_capture_requestPNS_8hardware6camera6device4V3_214CaptureRequestEPNSt3__16vectorIP13native_handleNSA_9allocatorISD_EEEE+352)
    #03 pc 000a6d29  /system/lib/libcameraservice.so (_ZN7android13Camera3Device12HalInterface27processBatchCaptureRequestsERNSt3__16vectorIP23camera3_capture_requestNS2_9allocatorIS5_EEEEPj+144)
    #04 pc 000a8357  /system/lib/libcameraservice.so (_ZN7android13Camera3Device13RequestThread17sendRequestsBatchEv+110)
    #05 pc 000a8c0b  /system/lib/libcameraservice.so (_ZN7android13Camera3Device13RequestThread10threadLoopEv+290)
    #06 pc 0000d57b  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+270)
    #07 pc 0004840f  /system/lib/libc.so (_ZL15__pthread_startPv+22)
    #08 pc 0001b54d  /system/lib/libc.so (__start_thread+32)

这是因为启用了高速录制功能,但第 3 方应用程序(库存相机除外)的配置 被供应商 方锁定。

唯一的选择是对设备进行 root 并刷新自定义或库存 ROM。

OnePlus 的用户投诉参考:

  1. Samsung locked Camera Configuration
  2. OnePlus locked Camera Configuration