2017-07-19 10 views
0

J'ai un code qui filtre une vidéo image par image en utilisant JavaCV. Le code est comme ci-dessousTraitement de trame vidéo simultanée utilisant 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); 
     } 
    } 
} 

Depuis la ligne Frame editedFrame = filterFrame(frame); prend un temps assez long, il est possible d'utiliser multithreading peut donc être beaucoup plus rapide tout le processus? Je pensais utiliser quelque chose comme ExecutorService ou LinkedBlockingQueue pour traiter plusieurs images en une fois, puis enregistrer le cadre en fonction de l'horodatage.

+0

Votre méthode filterFrame (que vous n'avez pas montrée) peut-elle utiliser le multi-threading pour une exécution plus rapide? – auburg

+0

oui, vous pouvez. mais vous devriez penser à synchroniser les images. probablement vous pouvez diviser le travail dans filterFrame comme ici https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html. il serait plus sage –

+0

@VladislavKysliy est-il possible d'avoir comme service d'exécuteur pour comme 4 threads, puis le filtrage sera fait toutes les 4 images et les images seront enregistrées dans la même séquence, ils sont saisis? –

Répondre

0

Il est pattern producer:

classe Producer est pour l'exécution de tâche longue (-filtre):

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

classe des consommateurs est pour les cadres de magasin:

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

et la partie principale qui gèrent les tâches et fil d'arrêtPool

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

Remarque: Il ne s'agit pas d'une solution de copier-coller et d'une personnalisation de votre code. Si vous partagez plus d'informations, je le changerai