高速视频录制(使用 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 的用户投诉参考:
对于上下文:我正在开发一个评估视频到音频同步的应用程序,因此它对时间非常敏感。
在我的 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 的用户投诉参考: