2016-07-22 6 views
0

Так что я пытался реализовать потребитель - шаблон производителя в андроида сценарий как таковой:ArrayBlockingQueue всегда возвращает истину

public class CameraPreview extends SurfaceView ... { 

    ....... 

    public ArrayBlockingQueue<ByteBuffer> mProcessingQueue; 

    public CameraPreview(){ 
      mProcessingQueue = new ArrayBlockingQueue<ByteBuffer>(10); 
      HandlerThread handlerThread = new HandlerThread("Image Processing Thread"); 
      handlerThread.start(); 
      Handler handler = new Handler(handlerThread.getLooper()); 
      handler.post(new Runnable() { 
       @Override 
       public void run() { 
        new ImageProcessingThread().start(); 
       } 
      }); 
     } 


    public void onPreviewFrame(final byte[] data, Camera camera){ 

      ....... 

      if(!mProcessingQueue.offer(byteBuffer)) { 
       byteBuffer.clear(); 
       Log.v("IMAGE_AVOIDED", count + ""); 
      } else { 
       Log.v("IMAGE_PUSHED", count + ""); 
      } 

    } 

    public void processImage(ByteBuffer image){ 

      .. call to opencv jni function .. 

    } 

    public class ImageProcessingThread extends Thread{ 
      int count = 0; 

      @Override 
     public void run() { 
      super.run(); 

      while(mImageProcessingRunning){ 
       try { 
        ByteBuffer image = mProcessingQueue.take(); 
        Log.v("IMAGE_TAKEN", count++ + ""); 
        processImage(image); 
        image.clear(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 

Однако, когда я запускаю этот код .. он никогда не производит оператор журнала IMAGE_AVOIDED .. это чередуется между IMAGE_TAKEN и IMAGE_PUSHED .. один кадр перетаскивается .. и один фрейм обрабатывается.

Я надеялся, что смогу постоянно размещать кадры в mProcessingQueue и когда потребительский поток был готов, чтобы взять из очереди .. таким образом я мог бы отбросить кадры, если очередь была заполнена, и только поместить последние кадры в очередь, чтобы приблизиться к re al time ..

Я уверен, что это проблема синхронизации. Может быть, я запускаю те же два потока в одном процессе, и поэтому планировщик надеется на повторение задач?

Любые идеи/указатели ??

+1

Похоже, что обработка потребительского потока достаточно быстро, что очередь никогда не заполняется ... – wakjah

+0

Я думал об этом, но это не может быть, продюсер должен запустить 30 кадров в секунду, вероятно, ближе к 20 заданному времени, чтобы заполнить ByteBuffer данными, и время выполнения кода JNI определенно медленнее, чем в реальном времени. – Arjun

+0

Представьте, что вы спали или зависаете в своем потребительском методе, чтобы убедиться, что очередь заполнена, и посмотрите, что произойдет. – Bex

ответ

0

Так получилось, что приведенная выше реализация верна. Однако я делал некоторые вычисления в вызове функции onPreviewFrame .., который дал потребительскому потоку достаточное количество времени для выполнения работы под рукой. Спасибо всем!

Смежные вопросы