.ogg 파일을 재생할 때 MediaExtractor.seekTo() 호출 후 .dequeueOutputBuffer()가 항상 MediaCodec.INFO_TRY_AGAIN_LATER로 시간 초과됩니다. 거의 끊임없이 추구하기 때문에 문제가 발생합니다. 최대 블로킹 시간은 무의미하며 설정된 시간과 관계없이 항상 타임 아웃됩니다.Ogg 오디오 파일을 검색 할 때 MediaCodec.dequeueOutputBuffer 시간 초과가 발생했습니다.
모든 .ogg 파일 및 다른 오디오 파일 형식에서 발생합니다.
다음은이 문제를 해결하려면 어쨌든, 거기 관련 코드이며, 제한 시간은 오그 파일 seekTo()를 호출 할 때마다 후
final int res = codec.dequeueOutputBuffer(info, TIMEOUT_US);
그런 일에 어떻게됩니까? 여기
public MediaCodecMp3Decoder(String fullPath) throws IOException
{
extractor = new MediaExtractor();
extractor.setDataSource(fullPath);
format = extractor.getTrackFormat(0);
String mime = format.getString(MediaFormat.KEY_MIME);
durationUs = format.getLong(MediaFormat.KEY_DURATION);
codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null, null, 0);
codec.start();
codecInputBuffers = codec.getInputBuffers();
codecOutputBuffers = codec.getOutputBuffers();
extractor.selectTrack(0);
info = new MediaCodec.BufferInfo();
}
public byte[] decodeChunk()
{
advanceInput();
final int res = codec.dequeueOutputBuffer(info, TIMEOUT_US);
if (res >= 0)
{
int outputBufIndex = res;
ByteBuffer buf = codecOutputBuffers[outputBufIndex];
if(chunk == null || chunk.length != info.size)
{
chunk = new byte[info.size];
}
buf.get(chunk);
buf.clear();
codec.releaseOutputBuffer(outputBufIndex, false);
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
{
sawOutputEOS = true;
}
else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
codecOutputBuffers = codec.getOutputBuffers();
}
else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
format = codec.getOutputFormat();
Log.d("MP3", "Output format has changed to " + format);
}
return chunk;
}
private void advanceInput()
{
boolean sawInputEOS = false;
int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_US);
if (inputBufIndex >= 0)
{
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
int sampleSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = 0;
if (sampleSize < 0)
{
sawInputEOS = true;
sampleSize = 0;
}
else
{
presentationTimeUs = extractor.getSampleTime();
currentTimeUs += presentationTimeUs - lastPresentationTime;
lastPresentationTime = presentationTimeUs;
}
codec.queueInputBuffer(inputBufIndex,
0,
sampleSize,
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS)
{
extractor.advance();
}
}
}
public void seek(long timeInUs)
{
extractor.seekTo(timeInUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
lastPresentationTime = currentTimeUs = timeInUs;
codec.flush();
}
유일한 로그 캣 종래이며 seekTo() 후 AudioTrack에 버퍼 언더런 I은 또한
03-01 13:48:25.042: I/AudioFlinger(125): BUFFER TIMEOUT: remove(4099) from active list on thread 0x40b42008
03-01 13:48:25.312: W/AudioTrack(29349): releaseBuffer() track 0x6a110c10 name=s:125;n:3;f:-1 disabled due to previous underrun, restarting
dequeueOutputBuffer()에 설정 한 1 초 시간 제한에 기인 I seekTo() 및 decodeChunk()에 대한 호출이 다른 스레드에서 발생하지만 동일한 객체에서 동기화된다는 점에 유의해야합니다.
synchronized (decodeLock)
{
decoder.seek(timeInUs);
}
synchronized (decodeLock)
{
input = decoder.decodeChunk();
...
}
logcat을 공유 할 수 있습니까? 검색을 한 후 readSampleData가 반환하는 크기는 무엇입니까? – Marlon
LogCat을 게시했습니다. 시크 (seek) 후에 sampleSize는 147이며, 정상 작동 중에 크기와 일치하는 정상 크기입니다. presentationTimeUs와 동일합니다. –
안드로이드 버전을보고 계십니까? KLP에서 수정 된 문제와 관련된 몇 가지 문제점이 있습니다. – marcone