2013-07-11 11 views
1

마이크에서 오디오 스트림을 3gpp (AMR-NB)로 인코딩하려고합니다. 문제는 출력 버퍼에 이상한 데이터가 포함되어 있다는 것입니다. 코드와 출력은 다음과 같습니다Android MediaCodec 3gpp 인코더 출력 버퍼에 잘못된 바이트가 포함되어 있습니다.

만들기 미디어 인코더 : MIC에서

MediaFormat format = MediaFormat.createAudioFormat("audio/3gpp", 8*1024, 1); 
format.setInteger(MediaFormat.KEY_BIT_RATE, 8*1024); 
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, minBufSize); 
MediaCodec encoder = MediaCodec.createEncoderByType("audio/3gpp"); 
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 
encoder.start(); 

PCM 데이터가 올바른 것 같다 스레드에서 실행, 인코딩 된 바이트 (버퍼를 읽기

(파일로 저장, 대담 경청))

ByteBuffer[] outputBuffers = encoder.getOutputBuffers(); 
int outputBufferIndex = 0; 
while(outputBufferIndex >= 0) 
{ 
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); 
    outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, -1); 
    if (outputBufferIndex >= 0) 
    { 
     ByteBuffer outputBuffer = outputBuffers[outputBufferIndex]; 
     byte[] outData = new byte[bufferInfo.size]; 
     outputBuffer.get(outData); 
     outputBuffer.clear(); 
     encoder.releaseOutputBuffer(outputBufferIndex, false); 
     Log.d(LOG_TAG_ENCODING, util.bytesToString(outData)); 
    } 
    else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) 
    { 
     outputBuffers = encoder.getOutputBuffers(); 
    } 
} 

출력은 :

07-11 13:13:58.622: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.632: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.667: 34 ff d9 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.672: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
07-11 13:13:58.677: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
012,351,

저는 인터넷 검색을하고 도움을받지 못했습니다. 안드로이드는 MediaCodec 사용법에 관한 문서도 훌륭하지 않습니다. OutputBuffer 컨텍스트에서 ByteBuffer.clear()를 사용하면 많은 시행 착오를 겪을 수 있습니다.

최고, Ahti.

+0

버퍼가 전달 될 때'outputBuffer'의 위치와 한계가 올바르게 설정되지 않을 수 있습니다. 'outputBuffer.position (bufferInfo.offset)'및'outputBuffer.limit (bufferInfo.offset + bufferInfo.size)'를 시도하십시오. – fadden

답변

1

거기에있는 동료 환자 모두에게 내 질문에 대답합니다.

실제 문제는 실제 PCM 데이터를 인코더 입력에 공급하는 것이 었습니다. 안드로이드 워드 프로세서 (확인, 그것은 정직의 ByteBuffer의 행동을 할 사실은 더있다) 정확히 입력 버퍼에 데이터를 공급하는 방법에 대한 막연한 :

int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs); 
if (inputBufferIndex >= 0) { 
    // fill inputBuffers[inputBufferIndex] with valid data 
    ... 
    codec.queueInputBuffer(inputBufferIndex, ...); 
} 

내 해석은 다음과 같은 데이터를 추가했다 :

inputBuffers[inputBufferIndex].clear(); 
inputBuffers[inputBufferIndex].put(audioPCMbuffer); 
codec.queueInputBuffer(inputBufferIndex, ...); 

위의 코드에는 1 비트 누락이 있습니다. ByteBuffer의 위치를 ​​바꿉니다! 이 구현을 볼 수있는 간단한 코드를 찾기가 매우 힘들었다로

inputBuffers[inputBufferIndex].flip(); 

하면 나중에 참조 할 수 있도록 여기를 유지.

+0

'flip()'은'limit = position'을 설정하고'position = 0'을 설정합니다. 'clear()'는'limit = capacity'를 설정하고'position = 0'을 설정합니다. 버퍼가 제출 된 후에'flip() '을 호출하면 어떤 이점이 있는지 확실하지 않습니다. – fadden