2017-09-26 160 views
0

我的outputBuffer在我的onOutputBufferAvailable()回調方法中有問題。每次調用此回調方法時,我使用outputBuffer.hasRemaining方法檢查outputBuffer並始終返回falseMediaCodec 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

位置/上的ByteBuffers限制標誌不被MediaCodec更新,你需要檢查你必須知道實際的有效載荷數據的位置和長度MediaCodec.BufferInfo對象。

+0

您的意思是'presentationTimeUs()'獲取實際位置? – Kristopher

+0

不,我的意思是讀取MediaCodec.BufferInfo中的'offset'和'size'字段。然而,'getOutputBuffer()'的文檔似乎並沒有記錄它已經自動設置:「返回的緩衝區的位置和限制被設置爲有效的輸出數據」 – mstorsjo

+0

不知道爲什麼,但我的信息。偏移量「始終是0.」info.size「是4608. – Kristopher