Android摄像头本机访问:startPreview()vs startRecording()

Android摄像头本机访问:startPreview()vs startRecording(),android,android-ndk,camera,Android,Android Ndk,Camera,尝试使用Android ICS中的本机代码使摄像头正常工作: 大多数手册都参考了startPreview()方法。但在浏览AOSP代码时,我也在中找到了“startRecording()”方法。说它是从接口ICameraRecordingProxy “允许录像机在录制过程中接收视频帧” 所以问题是——就性能而言,“startRecording”方法比“startPreview”更有效吗 进入本机代码的唯一目标是性能,Java“Camera”太慢,OpenCV也没有提供所需的FPS级别 编辑:目标

尝试使用Android ICS中的本机代码使摄像头正常工作: 大多数手册都参考了startPreview()方法。但在浏览AOSP代码时,我也在
中找到了“startRecording()”方法。说它是从接口ICameraRecordingProxy “允许录像机在录制过程中接收视频帧”

所以问题是——就性能而言,“startRecording”方法比“startPreview”更有效吗

进入本机代码的唯一目标是性能,Java“Camera”太慢,OpenCV也没有提供所需的FPS级别

编辑:目标平台是:API级别=17,设备Allwinner A31开发板,1280x720x30FPS。 任务是从相机捕获帧,修改帧,编码(H264)并存储到SD卡。 纯java MediaRecorder使用1280x720x30写入mp4文件。不需要在屏幕上显示实时预览

本机模式下的OpenCV-demo1提供1920x1080x2(在java模式下相同)。带有空PreviewCallback的简单java方法最大FPS为15


提前感谢您。

就性能而言,使用本机摄像头没有任何好处。在Java()中使用时,每秒的帧数与任何本机备选方案相同。但在某些SOC上,例如三星,摄像头输出可能直接(0-copy)与HW h264编码器连接,这自然会提供出色的吞吐量。这就是纯java MediaRecorder在幕后所做的。如果需要对缓冲区进行任何操作,则无法实现相同的效果。

要关闭主题: 我能够达到1280x720与FPS=30使用本机访问摄像头和硬件H264编码器。还可以动态修改(水印)数据,保持FPS高。 没有任何其他方法-任何JAVA或OpenCV都不能提供超过15 FPS的速度(可能是我没有努力…)

startRecording()工作正常

谢谢你的评论

dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) 
以内部形式提供数据。不能保证纯yuv帧数据。例如,
data.get()->size()
可以大于yuv帧大小,也可以是大约20字节大小的数据结构,用于将真实(?)帧缓冲区保留在相机缓冲区列表中的某个位置


所以,这个主题还不完整。:)

Grafika可以通过相机预览进行录制——在2012 Nexus7上,以30帧/秒的速度运行,只需Java代码。(不过,
MediaCodec
确实需要API 16+)请参阅中的“显示+捕获摄像头”。如果你主要对直接录制感兴趣,也许你想要的是
MediaRecorder
()?谢谢你的链接,但是Grafika“一个为API 18(Android 4.3)开发的SDK应用程序”,我的目标SDK是17:(尝试构建和启动-不走运。MediaRecorder很不错,工作也很好,但我需要修改Fly上的帧。Grafika所做的一些工作将在API 16中工作。在API 18之前,您得不到的是
Surface
输入到
MediaCodec
,不幸的是,这对您所做的工作的性能非常重要。取决于t您计划进行的帧修改,API 18提供的东西可以在其他方面帮助您…这里可以找到使用一些简单的基于GPU着色器的图像过滤器的Grafika演示:非常感谢,“Grafika”非常有趣,但问题是目标设备无法升级到API 18:(通常出于市场份额的原因,针对较旧的API是很常见的。您应该在问题中提及目标API,并说明您计划对帧进行何种修改(即简单的帧插入/删除、奇特的图像过滤、您是否希望在YUV或RGB空间工作等)。您需要在录制的同时在屏幕上显示预览吗?您说您没有达到目标FPS速率;您需要的速率是多少,分辨率是多少?您的目标设备是什么?为什么?根据在进入java world之前至少复制了几次的帧数据。因此,任何对帧的java访问都应该比本机慢。我正在考虑从AOSP获取MediaRecorder源,并对其进行修改,以使FPS略低于MediaRecorder提供的FPS来完成工作。是否可行?这一解释并不令人信服。它们算作2个memcpy的通常只是传递指针、切换虚拟地址等。我应该重复一下将相机直接连接到en同一系统进程中的编码器确实为MediaRecorder提供了一些优势。使用31 CPU,如果使用2片线程进行超快x264编码,您应该能够以15 FPS或更高的速度实现720p。修改AOSP MediaRecorder将无济于事,因为实际的繁重工作发生在系统媒体服务中,您将立即失去一个当你尝试修改数据时,我会有优势。你认为原则上(java/本机)是否可能达到1280x720x30 FPS捕获、水印、编码并将视频存储到SD卡?我所知道的在现代四核设备(三星Note 10)上使用x264的最佳效果大约是吞吐量的一半:我们可以达到800x480x30。使用HW编码器(通过舞台灯光),1280x720x30是可能的,但我没有A31的第一手经验。您是否使用本机allwinner编码器c代码?类似于AWcodecTest.cpp?不,我使用了AOSP的一部分:#包括,您可以提供一些示例代码吗?非常感谢。如果您可以共享它的示例项目,这将非常有用。显示代码将有助于ots!毕竟是这样。是的,我的3台测试设备中的一台提供了正确的yuv帧,没有跨步(如预览模式),在这种情况下一切正常。一些摄像头可以在流模式下提供yuv帧。尝试设置摄像头->storeMetaDataInBuffers(false)。成功后,摄像头工作正常,但可能会发生一次复制操作(例如,从GPU内存到主机)。在Android API21之前,没有任何通用案例可以让yuv以流模式运行。一些元数据表示仅用于硬件到硬件的数据传输,
msgType==CAMERA_MSG_VIDEO_FRAME