2014-02-17 83 views
1

我正在尝试pipe一些ByteBuffer在一个线程(IO1)到另一个(IO2)。Java NIO管道和字节缓冲区

http://tutorials.jenkov.com/java-nio/pipe.html

private int bufferSize; 
private boolean isRecording; 

private Thread IO1; 
private Thread IO2; 

private ByteBuffer byteBuffer1; 
private ByteBuffer byteBuffer2; 

private Pipe pipe; 
private Pipe.SinkChannel skChannel; 
private Pipe.SourceChannel sourceChannel; 

      byteBuffer1 = ByteBuffer.allocateDirect(bufferSize); 
      byteBuffer2 = ByteBuffer.allocateDirect(bufferSize); 

      //An instance of Pipe is created 
      try 
      { 
       pipe = Pipe.open(); 
       skChannel = pipe.sink(); 
       sourceChannel = pipe.source(); 

       IO1.start(); 
       IO2.start(); 
      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 

-

IO1 = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     isRecording = true; 
     recorder.startRecording(); 
     try 
     { 
      int read; 
      while (isRecording) 
      { 
       // byteBuffer1.clear(); 
       read = recorder.read(byteBuffer1, bufferSize); 
       if (AudioRecord.ERROR_INVALID_OPERATION != read) 
       { 
         skChannel.write(byteBuffer1); 
         Log.v("========IO1 ", String.valueOf(read)); 
         //This triggered almost 20 times/second 
       } 
      } 
      recorder.stop(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
}); 

skChannel.write(byteBuffer1);Log.v("========IO1 ", String.valueOf(read)); 触发近20次/秒,这是预期的行为,到目前为止,一切顺利。

IO2 = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     try 
     { 
      int read; 
      while ( (read =sourceChannel.read(byteBuffer2)) >0) 
      { 
       Log.v("========IO2 ", String.valueOf(read)); 
       //this triggered only once 

       // To do Codec etc. 
       //............ 
      } 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     Log.v("========IO2 ", "END!!!!!"); //never triggered(this is fine) 
    } 
}); 

但是,Log.v("========IO2 ", String.valueOf(read));只触发一次,我不知道为什么。

有人能告诉我如何获得IO2中线程IO1的更新?

谢谢。

回答

0

您需要在写入之前翻转()缓冲区,然后再压缩()。

但是:总之,不要。线程之间的管道基本没有意义。使用队列,或让接收线程直接读取发送线程的输入。

如果你必须这样做,基本NIO复制循环是这样的:

while (in.read(buffer) > 0 || buffer.position() > 0) // or whatever your read API needs 
{ 
    buffer.flip(); 
    out.write(buffer); 
    buffer.compact(); 
} 
+0

感谢EJP,我准备另一个线程是我需要有MediaCodec循环的原因。正如你可以在这里看到http://developer.android.com/reference/android/media/MediaCodec.html它需要一个特定的(while)循环。事实上,我很困惑如何与AudioRecord循环线程一起实现此功能。在这种情况下,你还认为线程之间的管线是没有意义的吗?再次,我对此感到困惑,所以。 –

+0

@KenOKABE请参阅编辑。 – EJP

+0

谢谢。我放弃了按照你的建议使用双线程方法,并且越来越接近我所需要的。我为此放置了一个新问题:http://stackoverflow.com/questions/21804390/android-mediacodec-pcm-aac-encoder-pcmdecoder-in-real-time-with-correc如果您有兴趣,请加入。这是一个+400的声誉赏金问题。 –