2014-02-17 2 views
1

나는 일부 ByteBuffer을 다른 스레드 (IO1)에서 다른 것 (IO2)으로 만들려고합니다. Java NIO Pipe와 ByteBuffer

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));는 한 번만 실행됩니다, 그리고 그 이유를 모른다.

누가 IO1 스레드 IO2에 대한 업데이트를 어떻게 얻을 수 있는지 말해 줄 수 있습니까?

감사합니다.

답변

0

쓰기 전에 버퍼를 뒤집고 (나중에) compact()해야합니다.

하지만 : 한마디로 말하면 안됩니다. 스레드 간의 파이프는 기본적으로 무의미합니다. 큐를 사용하거나 수신 스레드가 송신 스레드의 입력을 직접 읽도록하십시오. 이 작업을 수행해야하는 경우

는 기본 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 평판의 현상금 문제입니다. –