android mediacodec仅在收到下一个I帧后播放I帧(I帧之间的时差为2-3秒)
我正在尝试使用Android MediaCodec对NAL单元进行解码。问题是视频的播放延迟为2-3秒,因为只有在接收到下一个I帧后才播放第一个I帧,I帧之间的时间差为2-3秒。因此,如果我将同一个I帧连续放置2次,那么它将毫不延迟地播放。但在这种情况下,我不能播放其余的帧 我不明白问题出在哪里。我试着自己解决它,但我做不到android mediacodec仅在收到下一个I帧后播放I帧(I帧之间的时差为2-3秒),android,android-mediacodec,Android,Android Mediacodec,我正在尝试使用Android MediaCodec对NAL单元进行解码。问题是视频的播放延迟为2-3秒,因为只有在接收到下一个I帧后才播放第一个I帧,I帧之间的时间差为2-3秒。因此,如果我将同一个I帧连续放置2次,那么它将毫不延迟地播放。但在这种情况下,我不能播放其余的帧 我不明白问题出在哪里。我试着自己解决它,但我做不到 public void play(MediaCodec decoder, PESPacket currentPES){ byte[] data = currentP
public void play(MediaCodec decoder, PESPacket currentPES){
byte[] data = currentPES.data.toByteArray();
pts = currentPES.getPts();
try {
if (data[4] == 0x67) {
Log.d(TAG, "found sps/pps!");
int ibs = decoder.dequeueInputBuffer(0);
if (ibs >= 0) {
ByteBuffer buffer = decoder.getInputBuffers()[ibs];
buffer.clear();
buffer.put(data);
decoder.queueInputBuffer(ibs, 0, data.length, pts, MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
}
} else {
if (data[4] == 0x41) { // not I-frame
int ibs = decoder.dequeueInputBuffer(0);
if (ibs >= 0) {
System.out.println("queueInputBuffer little");
ByteBuffer buffer = decoder.getInputBuffers()[ibs];
buffer.clear();
buffer.put(data);
decoder.queueInputBuffer(ibs, 0, data.length, pts, 0);
}
}
if (data[4] == 0x65) { // I-frame
int ibs = decoder.dequeueInputBuffer(0);
if (ibs >= 0) {
System.out.println("queueInputBuffer");
ByteBuffer buffer = decoder.getInputBuffers()[ibs];
buffer.clear();
buffer.put(data);
decoder.queueInputBuffer(ibs, 0, data.length, pts, 0);
}
}
}
int outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 10000);
if (outputBufferIndex >= 0) {
System.out.println("releaseOutputBuffer " + outputBufferIndex);
decoder.releaseOutputBuffer(outputBufferIndex, true);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
System.out.println("INFO_OUTPUT_BUFFERS_CHANGED ");
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat format = decoder.getOutputFormat();
System.out.println("INFO_OUTPUT_FORMAT_CHANGED " + format);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
可能已经太晚了,但我想分享一些信息 如果仅向视频解码器发送IDR帧,则可以在配置解码器时尝试将MediaFormat中的android.\u num-input-buffers和android.\u num-output-buffers设置为1。这将尝试在视频解码器中分配单个缓冲区,从而立即输出缓冲区。然而,该行为不能保证,将取决于解码器的实现 我猜,谷歌的软件H264解码器omx.Google.H264.decoder应该支持这种行为,但我还没有测试过 有关如何设置参数,请参考以下Android source code FrameDecoder.cpp。FrameDecoder.cpp是Android API MetaDataExtractor.getFrameAt的框架层实现
你的共和党有多大?这是正常的,预计解码器中会有一些延迟-你不能输入一个缓冲区,然后等待它从另一端弹出-但它通常在4帧左右。GOP大小是15。我只有在收到第十五帧后才有输出缓冲区。。。这是MediaCodec的正常行为吗?我不认为有正常行为。MediaCodec是供应商提供的使用OMX接口的编解码器驱动程序的包装器。缓冲量取决于编解码器实现和流的性质。在基于qcom的设备上解码AVC时,我看到了初始启动时的大约4帧。谢谢。那么,你能告诉我问题出在哪里吗?我正在测试Nexus5。你解决过这个问题吗?
451 // For the thumbnail extraction case, try to allocate single buffer in both
452 // input and output ports, if seeking to a sync frame. NOTE: This request may
453 // fail if component requires more than that for decoding.
454 bool isSeekingClosest = (mSeekMode == MediaSource::ReadOptions::SEEK_CLOSEST)
455 || (mSeekMode == MediaSource::ReadOptions::SEEK_FRAME_INDEX);
456 if (!isSeekingClosest) {
457 videoFormat->setInt32("android._num-input-buffers", 1);
458 videoFormat->setInt32("android._num-output-buffers", 1);
459 }