本文介绍了如何从相机对象获取原始preVIEW数据至少每秒15帧的Andr​​oid?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从Camera对象获得的原始preVIEW数据至少每秒15 框架,但我只能得到110毫秒的框架,这意味着我可以得到只有每秒9帧。我下面介绍一下我的code。

 相机mCamera = Camera.open();
Camera.Parameters参数= mCamera.getParameters();
parameters.set previewFrameRate(30);
parameters.set previewFpsRange(15000,30000);
mCamera.setParameters(参数);
mCamera.addCallbackBuffer(新字节[dataBufferSize]);
// dataBufferSize表示字节大小的相框
mCamera.addCallbackBuffer(新字节[dataBufferSize]);
mCamera.addCallbackBuffer(新字节[dataBufferSize]);
mCamera.set previewDisplay(videoCaptureViewHolder);
// videoCaptureViewHolder是SurfaceHolder对象
mCamera.set previewCallbackWithBuffer(新相机。previewCallback(){
  私人长时间戳= 0;
  在previewFrame(byte []的数据,摄像头摄像头){市民同步无效
    Log.v(CameraTest,时间差=+(System.currentTimeMillis的() - 时间戳));
    时间戳= System.currentTimeMillis的();
    //做的图像数据处理
    camera.addCallbackBuffer(数据);
    返回;
  }
}
mCamera.start preVIEW();
 

在听取了code以上,dataBufferSize和videoCaptureViewHolder定义和计算或在其他语句中指定。

我跑我的code,我可以在屏幕上看到preVIEW,我得到下面的日志:

  ...
V / CameraTest(5396):时间间隔= 105
V / CameraTest(5396):时间间隔= 112
V / CameraTest(5396):时间间隔= 113
V / CameraTest(5396):时间间隔= 115
V / CameraTest(5396):时间间隔= 116
V / CameraTest(5396):时间间隔= 113
V / CameraTest(5396):时间间隔= 115
...
 

这意味着在previewFrame(byte []的数据,摄像头摄像头)被称为每隔110毫秒,所以我可以不超过每秒9帧。我按问题设置无论什么preVIEW帧速率设置previewFrameRate()什么preVIEW FPS范围我按问题将设置previewFpsRange() ,日志是一样的。

难道有人给我这个问题的一些帮助?我需要从Camera对象获得的原始preVIEW数据至少每秒15帧。谢谢你在前进。

我把我下面的整个code。

CameraTest.java

 包test.cameratest;

进口java.io.IOException异常;
进口java.util.Iterator的;
进口的java.util.List;
进口android.app.Activity;
进口android.graphics.ImageFormat;
进口android.hardware.Camera;
进口android.hardware.Camera.ErrorCallback;
进口android.hardware.Camera.Parameters;
进口android.hardware.Camera.Size;
进口android.os.Bundle;
进口android.util.Log;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;
进口android.view.SurfaceHolder.Callback;

公共类CameraTestActivity延伸活动{
    SurfaceView mVideoCaptureView;
    相机mCamera;
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        mVideoCaptureView =(SurfaceView)findViewById(R.id.video_capture_surface);
        SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
        videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        videoCaptureViewHolder.addCallback(新的回调(){
            公共无效surfaceDestroyed(SurfaceHolder持有者){
            }

            公共无效surfaceCreated(SurfaceHolder持有者){
                startVideo();
            }

            公共无效surfaceChanged(SurfaceHolder持有人,INT格式,
                    INT宽度,高度INT){
            }
        });
    }
    私人无效startVideo(){
        SurfaceHolder videoCaptureViewHolder = NULL;
        尝试 {
            mCamera = Camera.open();
        }赶上(RuntimeException的E){
            Log.e(CameraTest,摄像头打开申请);
            返回;
        }
        mCamera.setErrorCallback(新ErrorCallback(){
            公共无效onerror的(INT错误,相机摄像头){
            }
        });
        Camera.Parameters参数= mCamera.getParameters();
        parameters.set previewFrameRate(30);
        parameters.set previewFpsRange(15000,30000);
        名单< INT [] GT;支持previewFps = parameters.getSupported previewFpsRange();
        迭代器< INT [] GT;支持previewFpsIterator =支持previewFps.iterator();
        而(支持previewFpsIterator.hasNext()){
            INT [] tmpRate =支持previewFpsIterator.next();
            StringBuffer的SB =新的StringBuffer();
            sb.append(支持previewRate:);
            的for(int i = tmpRate.length,J = 0; J<我; J ++){
                sb.append(tmpRate [J] +);
            }
            Log.v(CameraTest,sb.toString());
        }

        名单<大小>支持previewSizes = parameters.getSupported previewSizes();
        迭代器<大小>支持previewSizesIterator =支持previewSizes.iterator();
        而(支持previewSizesIterator.hasNext()){
            大小tmpSize =支持previewSizesIterator.next();
            Log.v(CameraTest,支持previewSize.width =+ tmpSize.width +支持previewSize.height =+ tmpSize.height);
        }

        mCamera.setParameters(参数);
        如果(NULL!= mVideoCaptureView)
            videoCaptureViewHolder = mVideoCaptureView.getHolder();
        尝试 {
            mCamera.set previewDisplay(videoCaptureViewHolder);
        }赶上(的Throwable T){
        }
        Log.v(CameraTest,摄像头previewFrameRate =+ mCamera.getParameters()获得previewFrameRate());
        尺码previewSize = mCamera.getParameters()得到previewSize();
        INT dataBufferSize =(INT)(previewSize.height * previewSize.width *
                               (ImageFormat.getBitsPerPixel(mCamera.getParameters()获得previewFormat())/ 8.0));
        mCamera.addCallbackBuffer(新字节[dataBufferSize]);
        mCamera.addCallbackBuffer(新字节[dataBufferSize]);
        mCamera.addCallbackBuffer(新字节[dataBufferSize]);
        mCamera.set previewCallbackWithBuffer(新相机。previewCallback(){
            私人长时间戳= 0;
            在previewFrame(byte []的数据,摄像头摄像头){市民同步无效
                Log.v(CameraTest,时间差=+(System.currentTimeMillis的() - 时间戳));
                时间戳= System.currentTimeMillis的();
                尝试{
                    camera.addCallbackBuffer(数据);
                }赶上(例外五){
                    Log.e(CameraTest,addCallbackBuffer误差);
                    返回;
                }
                返回;
            }
        });
        尝试 {
            mCamera.start preVIEW();
        }赶上(的Throwable E){
            mCamera.release();
            mCamera = NULL;
            返回;
        }
    }
    私人无效stopVideo(){
        如果(空== mCamera)
            返回;
        尝试 {
            mCamera.stop preVIEW();
            mCamera.set previewDisplay(空);
            mCamera.set previewCallbackWithBuffer(空);
            mCamera.release();
        }赶上(IOException异常E){
            e.printStackTrace();
            返回;
        }
        mCamera = NULL;
    }
    公共无效结束(){
        stopVideo();
        super.finish();
    };
}
 

AndroidManifest.xml中

 < XML版本=1.0编码=UTF-8&GT?;
<舱单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
      包=test.cameratest
      安卓版code =1
      机器人:VERSIONNAME =1.0>
    <使用-SDK安卓的minSdkVersion =9的Andr​​oid版本:targetSdkVersion =10机器人:maxSdkVersion =10/>
    <使用-权限的Andr​​oid:名称=android.permission.CAMERA/>
    <使用-权限的Andr​​oid:名称=android.permission.INTERNET对/>
    <使用-权限的Andr​​oid:名称=android.permission.VIBRATE/>
    <使用-权限的Andr​​oid:名称=android.permission.ACCESS_WIFI_STATE/>
    <使用-权限的Andr​​oid:名称=android.permission.WAKE_LOCK/>
    <使用-权限的Andr​​oid:名称=android.permission.RECORD_AUDIO/>
    <使用-权限的Andr​​oid:名称=android.permission.MOUNT_UNMOUNT_FILESYSTEMS/>
    <使用-权限的Andr​​oid:名称=android.permission.READ_CONTACTS/>
    <使用-权限的Andr​​oid:名称=android.permission.MODIFY_AUDIO_SETTINGS/>
    <使用-权限的Andr​​oid:名称=android.permission.ACCESS_NETWORK_STATE/>
    <使用-权限的Andr​​oid:名称=android.permission.PROCESS_OUTGOING_CALLS/>
    <使用-权限的Andr​​oid:名称=android.permission.CALL_PHONE/>
    <使用-权限的Andr​​oid:名称=android.permission.BOOT_COMPLETED/>
    <使用-权限的Andr​​oid:名称=android.permission.WRITE_EXTERNAL_STORAG​​E/>
    <使用-权限的Andr​​oid:名称=android.permission.WRITE_SETTINGS/>
    <应用机器人:图标=@可绘制/图标机器人:标签=@字符串/ APP_NAME>
        <活动机器人:CameraTestActivityNAME =
                  机器人:标签=@字符串/ APP_NAME>
            <意向滤光器>
                <作用机器人:名称=android.intent.action.MAIN/>
                <类机器人:名称=android.intent.category.LAUNCHER/>
            &所述; /意图滤光器>
        < /活性GT;
    < /用途>
< /舱单>
 

解决方案

我affraid,你不能。 preVIEW帧率设置提示相机的参加办法(运行在单独的进程) - 它是免费的接受或直接忽略它。它也没有用preVIEW框检索相关

当你请求preVIEW框,你刚才说的外部应用程序,你想拥有它。缓冲区被分配在相机应用程序,然后通过mmaped内存段传递到你的活动 - 这需要时间。

您可能会希望在某些设备上的性能,但不一定在一个你在玩。

如果您需要定义的帧速率,则必须捕获视频,然后解析/ DECOM preSS产生的二进制流。

I need to obtain raw preview data from Camera object at least 15 frame per second, but I can only get a frame in 110 milliseconds which means I can get only 9 frames per second. I brief my code below.

Camera mCamera = Camera.open();
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFrameRate(30);
parameters.setPreviewFpsRange(15000,30000);
mCamera.setParameters(parameters);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
//dataBufferSize stands for the byte size for a picture frame
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewDisplay(videoCaptureViewHolder);
//videoCaptureViewHolder is a SurfaceHolder object
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
  private long timestamp=0;
  public synchronized void onPreviewFrame(byte[] data, Camera camera) {
    Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
    timestamp=System.currentTimeMillis();
    //do picture data process
    camera.addCallbackBuffer(data);
    return;
  }
}
mCamera.startPreview();

In the briefed code above, dataBufferSize and videoCaptureViewHolder is defined and calculated or assigned in other statements.

I run my code, I can see preview on the screen and I get the log below:

...
V/CameraTest( 5396): Time Gap = 105
V/CameraTest( 5396): Time Gap = 112
V/CameraTest( 5396): Time Gap = 113
V/CameraTest( 5396): Time Gap = 115
V/CameraTest( 5396): Time Gap = 116
V/CameraTest( 5396): Time Gap = 113
V/CameraTest( 5396): Time Gap = 115
...

This means onPreviewFrame(byte[] data, Camera camera) is called every 110 milliseconds so I can get no more than 9 frames per second. And no matter what preview frame rate I set by issue setPreviewFrameRate() and what preview Fps range I set by issue setPreviewFpsRange(), the log is the same.

Would some one give me some help on this problem? I need to obtain raw preview data from Camera object at least 15 frames per second. Thank you in advance.

I put my entire code below.

CameraTest.java

package test.cameratest;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class CameraTestActivity extends Activity {
    SurfaceView mVideoCaptureView;
    Camera mCamera;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
        SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
        videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        videoCaptureViewHolder.addCallback(new Callback() {
            public void surfaceDestroyed(SurfaceHolder holder) {
            }

            public void surfaceCreated(SurfaceHolder holder) {
                startVideo();
            }

            public void surfaceChanged(SurfaceHolder holder, int format,
                    int width, int height) {
            }
        });
    }
    private void startVideo() {
        SurfaceHolder videoCaptureViewHolder = null;
        try {
            mCamera = Camera.open();
        } catch (RuntimeException e) {
            Log.e("CameraTest", "Camera Open filed");
            return;
        }
        mCamera.setErrorCallback(new ErrorCallback() {
            public void onError(int error, Camera camera) {
            }
        }); 
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewFrameRate(30);
        parameters.setPreviewFpsRange(15000,30000);
        List<int[]> supportedPreviewFps=parameters.getSupportedPreviewFpsRange();
        Iterator<int[]> supportedPreviewFpsIterator=supportedPreviewFps.iterator();
        while(supportedPreviewFpsIterator.hasNext()){
            int[] tmpRate=supportedPreviewFpsIterator.next();
            StringBuffer sb=new StringBuffer();
            sb.append("supportedPreviewRate: ");
            for(int i=tmpRate.length,j=0;j<i;j++){
                sb.append(tmpRate[j]+", ");
            }
            Log.v("CameraTest",sb.toString());
        }

        List<Size> supportedPreviewSizes=parameters.getSupportedPreviewSizes();
        Iterator<Size> supportedPreviewSizesIterator=supportedPreviewSizes.iterator();
        while(supportedPreviewSizesIterator.hasNext()){
            Size tmpSize=supportedPreviewSizesIterator.next();
            Log.v("CameraTest","supportedPreviewSize.width = "+tmpSize.width+"supportedPreviewSize.height = "+tmpSize.height);
        }

        mCamera.setParameters(parameters);
        if (null != mVideoCaptureView)
            videoCaptureViewHolder = mVideoCaptureView.getHolder();
        try {
            mCamera.setPreviewDisplay(videoCaptureViewHolder);
        } catch (Throwable t) {
        }
        Log.v("CameraTest","Camera PreviewFrameRate = "+mCamera.getParameters().getPreviewFrameRate());
        Size previewSize=mCamera.getParameters().getPreviewSize();
        int dataBufferSize=(int)(previewSize.height*previewSize.width*
                               (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
        mCamera.addCallbackBuffer(new byte[dataBufferSize]);
        mCamera.addCallbackBuffer(new byte[dataBufferSize]);
        mCamera.addCallbackBuffer(new byte[dataBufferSize]);
        mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
            private long timestamp=0;
            public synchronized void onPreviewFrame(byte[] data, Camera camera) {
                Log.v("CameraTest","Time Gap = "+(System.currentTimeMillis()-timestamp));
                timestamp=System.currentTimeMillis();
                try{
                    camera.addCallbackBuffer(data);
                }catch (Exception e) {
                    Log.e("CameraTest", "addCallbackBuffer error");
                    return;
                }
                return;
            }
        });
        try {
            mCamera.startPreview();
        } catch (Throwable e) {
            mCamera.release();
            mCamera = null;
            return;
        }
    }
    private void stopVideo() {
        if(null==mCamera)
            return;
        try {
            mCamera.stopPreview();
            mCamera.setPreviewDisplay(null);
            mCamera.setPreviewCallbackWithBuffer(null);
            mCamera.release();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        mCamera = null;
    }
    public void finish(){
        stopVideo();
        super.finish();
    };
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="test.cameratest"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="10" android:maxSdkVersion="10"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />    
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".CameraTestActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
解决方案

I'm affraid, you can not. Preview framerate setting is hint for camera appplication ( which runs in separate process) - and it is free to accept or silently ignore it. It is also not related with preview frame retrieval

When you request preview frame, you just say external application that you would like to have it. Buffer for it is allocated in camera application and then passed to your activity via mmaped memory segment - this takes time.

You may get desired performance on some devices, but not necessarily on one you are playing with.

If you need defined frame rate, you will have to capture video and then parse / decompress resulting binary stream.

这篇关于如何从相机对象获取原始preVIEW数据至少每秒15帧的Andr​​oid?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 05:31