Ich benutze Android MediaCodec API, um h264 Frames zu decodieren. Ich konnte die Frames in der Ansicht decodieren und rendern. Mein Problem ist, dass der Decoder viele Frames verpasst, besonders die ersten Frames. DecodeMediaCodec.dequeueOutputBuffer() Rückgabe -1. aÜber 150 h264 Bilder, gerade entschlüsselt 43 Bilder. Ich kann nicht finden, wo das Problem ist. Hier sind meine Codes.Android MediaCodec entschlüsseln h264 rohe frame
/**
* init decoder
*/
private void initDecodeMediaCodec()
{
mDecodeMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE,
VIDEO_WIDTH_640,
VIDEO_HEIGHT_480);
mDecodeMediaCodec.configure(format,
new Surface(mRemoteVideoView.getSurfaceTexture()),
null,
0);
mDecodeMediaCodec.start();
mDecodeInputBuffers = mDecodeMediaCodec.getInputBuffers();
System.out.println("decode-----"
+ mDecodeMediaCodec.getCodecInfo().getName());
}
Nach Decoder initial, ich werde Decoder-Thread starten.
/**
*
* @param frameData
*/
private void decode()
{
new Thread(new Runnable()
{
@Override
public void run()
{
while (true)
{
ByteBuffer decodeDataBuffer = null;
try
{
//take h264 frame from cache queue
decodeDataBuffer = decodeDataQuene.take();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
BufferInfo info = new BufferInfo();
int inputBufferIndex = mDecodeMediaCodec.dequeueInputBuffer(-1);
System.out.println("inputBufferIndex: " + inputBufferIndex);
if (inputBufferIndex >= 0)
{
ByteBuffer buffer = mDecodeInputBuffers[inputBufferIndex];
buffer.clear();
buffer.put(decodeDataBuffer.array());
mDecodeMediaCodec.queueInputBuffer(inputBufferIndex,
0,
decodeDataBuffer.array().length,
0,
0);
decodeDataBuffer.clear();
decodeDataBuffer = null;
}
int outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info,
1000);
System.out.println("outputBufferIndex: "
+ outputBufferIndex);
do
{
if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER)
{
//no output available yet
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
//encodeOutputBuffers = mDecodeMediaCodec.getOutputBuffers();
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
MediaFormat formats = mDecodeMediaCodec.getOutputFormat();
//mediaformat changed
}
else if (outputBufferIndex < 0)
{
//unexpected result from encoder.dequeueOutputBuffer
}
else
{
mDecodeMediaCodec.releaseOutputBuffer(outputBufferIndex,
true);
outputBufferIndex = mDecodeMediaCodec.dequeueOutputBuffer(info,
0);
System.out.println("inner outputBufferIndex: "
+ outputBufferIndex);
}
} while (outputBufferIndex > 0);
}
}
}).start();
}
Jeder weiß, warum? Ich habe Ihre help.My Android-Gerät Nexus hoffen ist 7.
Ich habe Ihre gegebenen Ressourcen nachgeschlagen, und ich habe einige Fragen dazu. ** 1) Gibt es irgendwelche Möglichkeiten, den Decoder dazu zu bringen, den Rahmen schnell zu decodieren? ** ** 2) Sollte ich das cds-0, welches der erste codierte Rahmen ist, dem Decoderformat hinzufügen? ** ** 3) Ist PresentationTime ist erforderlich? ** –
(1) Sie können möglicherweise etwas Zeit sparen, indem Sie den Decoder im Voraus konfigurieren und starten. Ich habe nicht damit experimentiert. Wie viel Verzögerung siehst du? (2) Sie können die CSD entweder zum 'MediaFormat' hinzufügen oder als erstes Bild mit dem gesetzten 'CODEC_CONFIG'-Flag übergeben. Tu beides nicht. (3) Ich denke nicht, dass der Codec beim Dekodieren dem PTS Aufmerksamkeit schenkt. (Es ist * jedoch wichtig, wenn es kodiert wird.) Wenn Sie die Zeitstempel von der Quelle bekommen, ist es eine gute Idee, sie zu behalten - z. falls Ihre Videoquelle keine Frames mit einer konstanten Rate liefert. – fadden
Die Verzögerung auf meinem Nexus 7 beträgt etwa 19 Bilder und 6 Bilder auf meinem Samsung S3. Der Dalai ist relativ stabil. Es scheint eine Beziehung mit der Hardware zu haben, aber ich bin mir nicht sicher. –