[英]Concurrent video frame processing using JavaCV
我有一個使用JavaCV逐幀過濾視頻的代碼。 代碼如下
try (FFmpegFrameGrabber grabber = createGrabber()) {
grabber.start();
try (FFmpegFrameRecorder recorder = createRecorder(grabber)) {
recorder.start();
Frame frame;
while ((frame = grabber.grab()) != null) {
Frame editedFrame = filterFrame(frame); //This takes a long time.
recorder.setTimestamp(grabber.getTimestamp());
recorder.record(editedFrame);
}
}
}
由於行Frame editedFrame = filterFrame(frame);
需要很長時間,是否有可能利用多線程處理,從而使整個過程更快? 我正在考慮使用ExecutorService
或LinkedBlockingQueue
類的東西一次處理多個幀,然后根據時間戳記錄回幀。
它是模式生產者 :
生產者類用於執行長任務(filterFrame):
import java.util.concurrent.Callable;
public class Producer implements Callable<Frame> {
private final Frame frame;
public Producer(Frame frame) {
this.frame = frame;
}
@Override
public Frame call() throws Exception {
return filterFrame(frame);
}
}
消費者類別適用於商店框架:
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class Consumer implements Runnable {
private final BlockingQueue<Map.Entry<Long, Future<Frame>>> queue;
public Boolean continueProducing = Boolean.TRUE;
private final FFmpegFrameRecorder recorder;
public Consumer(FFmpegFrameRecorder recorder,
BlockingQueue<Map.Entry<Long, Future<Frame>>> queue) {
this.recorder = recorder;
this.queue = queue;
}
@Override
public void run() {
try {
Map.Entry<Long, Future<Frame>> entry = this.queue.poll(2, TimeUnit.SECONDS);
Frame editedFrame = entry.getValue().get();
recorder.setTimestamp(entry.getKey());
recorder.record(editedFrame);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
以及管理任務和關閉線程的主要部分
try (FFmpegFrameGrabber grabber = createGrabber()) {
grabber.start();
try (FFmpegFrameRecorder recorder = createRecorder(grabber)) {
recorder.start();
Frame frame;
ExecutorService threadPool = Executors.newWorkStealingPool();
BlockingQueue<Map.Entry<Long, Future<Frame>>> queue = new LinkedBlockingQueue<>();
threadPool.execute(new Consumer(recorder, queue));
while ((frame = grabber.grab()) != null) {
queue.put(new Map.Entry<Long, Future<Frame>>() {
@Override
public Long getKey() {
return grabber.getTimestamp();
}
@Override
public Future<Frame> getValue() {
return threadPool.submit(new Producer(frame)); // Frame editedFrame = filterFrame(frame); //This takes a long time.
}
@Override
public Future<Frame> setValue(Future<Frame> value) {
return null;
}
});
}
threadPool.shutdownNow();
}
}
注意:這不是復制粘貼解決方案,需要對您的代碼進行一些自定義。 如果您分享更多信息,我將對其進行更改
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.