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 ответов
Я бы сделал что-то вроде этого :
// 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 помещает кадр в очередь, рабочий поток опрашивает из очереди.
это decorelate прием и обработка рамки. Вы можете отслеживать рост очереди, используя frames.size()
.
это типичный пример производитель-потребитель.
Если вы делаете это на каждом кадре, похоже, вам нужен поток вместо этого. AsyncTask-это когда вы хотите выполнить одноразовое действие в другом потоке. Здесь вы хотите сделать это неоднократно. Просто создайте поток, и когда он закончит кадр, отправьте сообщение обработчику, чтобы запустить шаг post в потоке пользовательского интерфейса. Он может ждать на семафоре в верхней части своего цикла, чтобы следующий кадр был готов.