Android Asynctask处理实时视频帧

时间:2013-02-19 17:31:07

标签: android image-processing android-asynctask

我正在使用OpenCV尝试进行一些实时视频处理。由于处理相当繁重,它会显着延迟输出帧,使实时流看起来不稳定。

我想将一些处理卸载到AsyncTask中。我试过了,它实际上让视频更加流畅。但是,它最终会立即启动大量任务,然后他们将慢慢开始返回一些结果。

有没有办法减慢这种速度,并通过使用Synchronize语句或其他方法等待结果?

在每个相机框架上,我开始执行其中一项任务。 DoImgProcessing执行长处理并返回字符串结果。

private class LongOperation extends AsyncTask<Mat, Void, String> {

    @Override
    protected String doInBackground(Mat... params) {
        Mat inputFrame = params[0];
        cropToCenter(inputFrame);
        return doImgProcessing(inputFrame);
    }      

    @Override
    protected void onPostExecute(String result) {
        Log.d(TAG, "on post execute: "+result);

    }

    @Override
    protected void onPreExecute() {
        Log.d(TAG, "on pre execute");
    }
}

public Mat onCameraFrame(Mat inputFrame) {
    inputFrame.copyTo(mRgba);//this will be used for the live stream
    LongOperation op = new LongOperation();
    op.execute(inputFrame);
    return mRgba;
}

2 个答案:

答案 0 :(得分:3)

我会做那样的事情:

// Example value for a timeout.
private static final long TIMEOUT = 1000L;

private BlockingQueue<Mat> frames = new LinkedBlockingQueue<Mat>();

Thread worker = new Thread() {
    @Override
    public void run() {
        while (running) {
            Mat inputFrame = frames.poll(TIMEOUT, TimeUnit.MILLISECONDS);
            if (inputFrame == null) {
                // timeout. Also, with a try {} catch block poll can be interrupted via Thread.interrupt() so not to wait for the timeout.
                continue;
            }
            cropToCenter(inputFrame);
            String result = doImgProcessing(inputFrame);
        }
    }
};
worker.start();

public Mat onCameraFrame(Mat inputFrame) {
    inputFrame.copyTo(mRgba);//this will be used for the live stream
    frames.put(inputFrame);
    return mRgba;
}

onCameraFrame将帧放在队列上,工作线程从队列中轮询。

这会对画面的接收和处理产生影响。您可以使用frames.size()监控队列的增长情况。

这是典型的生产者 - 消费者示例。

答案 1 :(得分:1)

如果您在每个帧上执行此操作,则听起来您需要一个线程。 AsyncTask适用于您希望在另一个线程上执行一次性活动的情况。在这里你想反复做。只需创建一个线程,当它完成一个帧时,它会向处理程序发送一条消息,以便在UI线程上运行post步骤。它可以在其循环顶部的信号量上等待下一帧准备就绪。