2016-07-22 131 views
0

于是,我就实现消费者 - 在Android的场景制作模式是这样的:ArrayBlockingQueue总是返回true

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时间..

我敢肯定它的同步问题..也许我在一个进程中运行相同的两个线程,因此调度程序希望来回通过任务?

任何想法/指针?

+1

听起来像消费者线程的处理速度足够快,队列永远不会填满... – wakjah

+0

我在想,但它不能,生产者应该运行30 fps可能接近20给定的时间来填充数据的ByteBuffer,并且执行JNI代码的时间肯定比实时慢 – Arjun

+0

在消费者方法中引入睡眠或挂起以确保队列已满,并查看会发生什么。 – Bex

回答

0

所以事实证明,上面的实现是正确的..但是我在onPreviewFrame函数调用中做了一些计算..这给消费者线程足够的时间来执行手头的工作..谢谢大家!