2014-02-17 116 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的聲譽賞金問題。 –