2017-09-26 17 views
0

onOutputBufferAvailable() 콜백 메소드 내에 outputBuffer에 문제가 있습니다. 이 콜백 메소드가 호출 될 때마다 outputBuffer.hasRemaining 메소드를 사용하여 outputBuffer을 확인합니다. 항상 false을 반환합니다.MediaCodec outputBuffer는 항상 비어 있습니다.

 codec.setCallback(new MediaCodec.Callback() { 

      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
      @Override 
      public void onInputBufferAvailable(MediaCodec mc, int inputBufferId) { 

       ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId); 
       int rounds = extractor.readSampleData(inputBuffer,0); 

       if(rounds > 0) { 
        long currentT = extractor.getSampleTime(); 
        Log.i("CurrentT", String.valueOf(currentT/(1000*1000))); 
        codec.queueInputBuffer(inputBufferId, 0, rounds, 0, 0); 
        extractor.advance(); 


       } else { 
        // EOS 
        codec.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
        Log.i("EOS","=-1"); 


       } 


      } 

      @Override 
      public void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) { 
       Log.i("error", "e"); 
      } 
      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
      @Override 
      public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) { 
       ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId); 

       Log.i("has", String.valueOf(outputBuffer.hasRemaining())); 
       if (outputBuffer.hasRemaining()) { 

        b = outputBuffer.get(); 
        Log.i("i", String.valueOf(b)); 
        BAOS.write(b); 
        outputBuffer.clear(); 

       } else { 

        array= BAOS.toByteArray(); 
        codec.stop(); 
        codec.release(); 

       } 
       codec.releaseOutputBuffer(outputBufferId, false); 

      } 


      @Override 
      public void onOutputFormatChanged(MediaCodec mc, MediaFormat format) { 
       // Subsequent data will conform to new format. 
       // Can ignore if using getOutputFormat(outputBufferId) 
       // mOutputFormat = format; // option B 
      } 
     }); 

답변

0

문제의 주된 이유는 잘못된 모드입니다. MediaCodec; MediaCodec.createByCodecName(...)codec = MediaCodec.createDecoderByType("audio/mpeg")이어야합니다. unsuccesfull이 get()을 사용하여 바이트를 얻으려고 시도한 후에 나는 결국 get(byte[] dst) 메소드로 끝났습니다. 아래 작업 코드.

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
      @Override 
      public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) { 
       ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId); 

        byte[] b = new byte[outputBuffer.remaining()]; 
        outputBuffer.get(b); 

        for(i=0;i< b.length;i++) { 
         BAOS.write(b[i]); 
        } 
        outputBuffer.clear(); 

       codec.releaseOutputBuffer(outputBufferId, false); 

       if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) { 
        array=BAOS.toByteArray(); 
        Log.i("array", String.valueOf(array.length)); 
        FileTools fl = new FileTools(); 
        fl.WriteFile(array); 
        codec.stop(); 
        codec.release(); 
       } 
      } 
1

위치 /를 ByteBuffer의에 한계 마커 MediaCodec으로 업데이트되지 않습니다, 당신은 당신이 실제 페이로드 데이터의 위치와 길이를 알고있어 MediaCodec.BufferInfo 개체를 확인해야합니다.

+0

실제 위치를 얻으려고 'presentationTimeUs()'를 사용합니까? – Kristopher

+0

아니요, MediaCodec.BufferInfo의 'offset' 및'size' 필드를 읽는 것을 의미합니다. 그러나,'getOutputBuffer()'의 문서는 이미 자동적으로 설정되었다는 것을 증명하는 것처럼 보입니다 : "반환 된 버퍼의 위치와 한계는 유효한 출력 데이터" – mstorsjo

+0

Do not know my info. offset '은 항상 0입니다.'info.size'는 4608입니다. – Kristopher