2017-10-22 17 views
1

44100Hzモノラル64kbit AAC-LCサウンドをpcm rawにデコードしています。そうすれば、AudioTrackでpcm rawを再生することができます。ここでAudioTrackに奇妙なサウンドをデコードしたAACサウンド

クラスです:

 
    2048 bytes decoded 

、私は時間に奇妙な音の時間を得た:

package com.sametaylak.cstudio.lib; 

import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioTrack; 
import android.media.MediaCodec; 
import android.media.MediaCodecInfo; 
import android.media.MediaFormat; 
import android.util.Log; 

import net.butterflytv.rtmp_client.RtmpClient; 

import java.io.IOException; 
import java.nio.ByteBuffer; 

public class AudioDecoder extends Thread { 
private MediaCodec decoder; 
private RtmpClient client; 
private AudioTrack track; 

public boolean startDecoder() { 
    try { 
     int bufferSizePlayer = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 
     track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizePlayer, AudioTrack.MODE_STREAM); 
     client = new RtmpClient(); 
     decoder = MediaCodec.createDecoderByType("audio/mp4a-latm"); 

     MediaFormat format = new MediaFormat(); 
     format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm"); 
     format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); 
     format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100); 
     format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024); 
     format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); 

     int profile = 2; 
     int freqIdx = 4; 
     int chanCfg = 1; 
     ByteBuffer csd = ByteBuffer.allocate(2); 
     csd.put(0, (byte) (profile << 3 | freqIdx >> 1)); 
     csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3)); 
     format.setByteBuffer("csd-0", csd); 

     decoder.configure(format, null, null, 0); 
     client.open("rtmp://192.168.1.41/live/samet live=1", false); 
     track.play(); 
     start(); 
     return true; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

@Override 
public void run() { 
    byte[] data; 

    ByteBuffer[] inputBuffers; 
    ByteBuffer[] outputBuffers; 

    ByteBuffer inputBuffer; 
    ByteBuffer outputBuffer; 

    MediaCodec.BufferInfo bufferInfo; 
    int inputBufferIndex; 
    int outputBufferIndex; 

    byte[] outData; 

    decoder.start(); 

    try { 
     for (;;) { 
      data = new byte[1024]; 
      client.read(data, 0, data.length); 

      inputBuffers = decoder.getInputBuffers(); 
      outputBuffers = decoder.getOutputBuffers(); 
      inputBufferIndex = decoder.dequeueInputBuffer(-1); 

      if (inputBufferIndex >= 0) { 
       inputBuffer = inputBuffers[inputBufferIndex]; 
       inputBuffer.clear(); 

       inputBuffer.put(data); 

       decoder.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0); 
      } 

      bufferInfo = new MediaCodec.BufferInfo(); 
      outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0); 

      while (outputBufferIndex >= 0) { 
       outputBuffer = outputBuffers[outputBufferIndex]; 

       outputBuffer.position(bufferInfo.offset); 
       outputBuffer.limit(bufferInfo.offset + bufferInfo.size); 

       outData = new byte[bufferInfo.size]; 
       outputBuffer.get(outData); 

       Log.d("AudioDecoder", outData.length + " bytes decoded"); 
       track.write(outData, 0, outData.length); 

       decoder.releaseOutputBuffer(outputBufferIndex, false); 
       outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0); 
      } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

Logcatは述べています。デコードは大丈夫だと思います。バッファサイズからの私の意見の問題。しかし、私は何をすべきかわからない!すべてが良いようです。

バッファサイズのaudiotrackと入力データを変更しようとしましたが、変更はありませんでした。

アイデア?

答えて

-1

デコードメソッドが呼び出される前に、デコーダの設定をしなかったと思います。

public boolean prepare() { 
      mBufferInfo = new MediaCodec.BufferInfo(); 
      //开始播放 
      mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, KEY_SAMPLE_RATE, CHANNEL_OUT, AUDIO_FORMAT, BUFFFER_SIZE, AudioTrack.MODE_STREAM); 
      mPlayer.play(); 
      try { 
       mDecoder = MediaCodec.createDecoderByType(MIME_TYPE); 
       MediaFormat format = new MediaFormat(); 
       //解码配置 
       format.setString(MediaFormat.KEY_MIME, MIME_TYPE); 
       format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, KEY_CHANNEL_COUNT); 
       format.setInteger(MediaFormat.KEY_SAMPLE_RATE, KEY_SAMPLE_RATE); 
       format.setInteger(MediaFormat.KEY_BIT_RATE, KEY_BIT_RATE); 
       format.setInteger(MediaFormat.KEY_IS_ADTS, 1); 
       format.setInteger(MediaFormat.KEY_AAC_PROFILE, KEY_AAC_PROFILE); 

       int profile = KEY_AAC_PROFILE; //AAC LC 
       int freqIdx = FREQ_IDX; //44.1KHz 
       int chanCfg = CHAN_CFG; //CPE 
       ByteBuffer csd = ByteBuffer.allocate(2); 
       csd.put(0, (byte) (profile << 3 | freqIdx >> 1)); 
       csd.put(1, (byte)((freqIdx & 0x01) << 7 | chanCfg << 3)); 
       format.setByteBuffer("csd-0", csd); 

       mDecoder.configure(format, null, null, 0); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return false; 
      } 
      if (mDecoder == null) { 
       Log.e(TAG, "create mediaDecode failed"); 
       return false; 
      } 
      mDecoder.start(); 
      return true; 
     } 

デコードとプレイトラックは、以下のように順番にスレッドで行われます。デコード()はデコード方法と同じです。

public void run() { 
      super.run(); 
      if (!prepare()) { 
       isRunning = false; 
       Log.d(TAG, "音频解码器初始化失败"); 
      } 
      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
       inputBuffers = mDecoder.getInputBuffers(); 
       outputBuffers = mDecoder.getOutputBuffers(); 
      } 
      while (isRunning) { 
       decode(); 
      } 
      release(); 
     } 
関連する問題