安卓的AsyncTask处理实时视频帧实时、视频、AsyncTask

2023-09-05 07:32:48 作者:我依旧只是一只蘑菇

我使用OpenCV的尝试做一些实时视频处理。由于该处理是相当沉重的,它拖延输出帧显著,使得实时流看震荡。

我想卸载一些处理成一个AsyncTask的。我已经尝试过了,它实际上使视频更加流畅。但是,它最终开始了大量的任务一次,然后他们会慢慢开始与一些成果回来。

有没有什么办法的结果是,通过使用同步语句,或一些其他方法来减缓下来,并等待?

在每个摄像机架,我开始这些任务之一。 DoImgProcessing不长处理,并返回一个字符串结果。

 私有类LongOperation扩展的AsyncTask<垫,太虚,字符串> {

    @覆盖
    保护字符串doInBackground(马太福音... PARAMS){
        垫inputFrame = PARAMS [0];
        cropToCenter(inputFrame);
        返回doImgProcessing(inputFrame);
    }

    @覆盖
    保护无效onPostExecute(字符串结果){
        Log.d(TAG,在后执行:+结果);

    }

    @覆盖
    在preExecute保护无效(){
        Log.d(TAG,在pre执行);
    }
}

公共垫onCameraFrame(马太福音inputFrame){
    inputFrame.copyTo(mRgba); //这将被用于实时流
    LongOperation OP =新LongOperation();
    op.execute(inputFrame);
    返回mRgba;
}
 

解决方案

我会做这样的事情:

对于超时

  //示例值。
私有静态最后长超时= 1000L;

私人的BlockingQueue<垫>帧=新的LinkedBlockingQueue<垫>();

螺纹工人=新的Thread(){
    @覆盖
    公共无效的run(){
        而(运行){
            垫inputFrame = frames.poll(TIMEOUT,TimeUnit.MILLISECONDS);
            如果(inputFrame == NULL){
                // 时间到。此外,有一个尝试{} catch块可以投票通过了Thread.interrupt(),所以不会被打断等待超时。
                继续;
            }
            cropToCenter(inputFrame);
            字符串结果= doImgProcessing(inputFrame);
        }
    }
};
worker.start();

公共垫onCameraFrame(马太福音inputFrame){
    inputFrame.copyTo(mRgba); //这将被用于实时流
    frames.put(inputFrame);
    返回mRgba;
}
 
Android性能优化典范 五

在onCameraFrame搁架上的队列中,工作线程投票从队列中。

这decorelate接待和框架的治疗。您可以使用监视队列的增长 frames.size()

这是一个典型的生产者 - 消费者例子。

I am using OpenCV to attempt to do some live video processing. Since the processing is fairly heavy, it delays the output frames significantly, making the live stream look choppy.

I'd like to offload some of the processing into an AsyncTask. I've tried it and it actually makes the video much smoother. However, it ends up starting a large amount of Tasks at once, and then they will slowly start returning with some results.

Is there any way to slow this down, and wait for a result, either by using Synchronize statements, or some other method?

On each camera frame, I start one of these tasks. DoImgProcessing does the long processing and returns a string result.

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;
}

解决方案

I would do something like that :

// 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;
}

The onCameraFrame puts the frame on the Queue, the worker Thread polls from the Queue.

This decorelate the reception and the treatment of the frame. You can monitor the growth of the Queue using frames.size().

This is a typical producer-consumer example.