对于我的Quadcopter项目,我试图在我的Android手机上显示原始的H.264流。输入流来自TCP连接 我做了一些关于解码器如何工作的研究,并创建了以下解码器线程 SPS和PPS变量是从另一个函数中的数据中检索出来的,这应该是有效的,因为我从工作代码中复制了它。
private class PlayerThread extends Thread {
private MediaCodec decoder;
private Surface surface;
public PlayerThread(Surface surface) {
this.surface = surface;
}
@Override
public void run()
{
while(SPS == null || PPS == null || SPS.length == 0 || PPS.length == 0)
{
try
{
Log.e("EncodeDecode", "DECODER_THREAD:: sps,pps not ready yet");
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d("EncodeDecode", "DECODER_THREAD:: sps,pps READY");
decoder = MediaCodec.createDecoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(SPS));
mediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(PPS));
decoder.configure(mediaFormat, surface /* surface */, null /* crypto */, 0 /* flags */);
if (decoder == null)
{
Log.e("DecodeActivity", "DECODER_THREAD:: Can't find video info!");
return;
}
decoder.start();
Log.d("EncodeDecode", "DECODER_THREAD:: decoder.start() called");
ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
int i = 0;
while(!Thread.interrupted())
{
Frame currentFrame = null;
try
{
Log.d("EncodeDecode", "DECODER_THREAD:: calling queue.take(), if there is no frame in the queue it will wait");
currentFrame = queue.take();
}
catch (InterruptedException e)
{
Log.e("EncodeDecode","DECODER_THREAD:: interrupted while PlayerThread was waiting for the next frame");
e.printStackTrace();
}
if(currentFrame == null)
Log.e("EncodeDecode","DECODER_THREAD:: null frame dequeued");
else
Log.d("EncodeDecode","DECODER_THREAD:: " + currentFrame.id + " no frame dequeued");
if(currentFrame != null && currentFrame.frameData != null && currentFrame.frameData.length != 0)
{
Log.d("EncodeDecode", "DECODER_THREAD:: decoding frame no: " + i + " , dataLength = " + currentFrame.frameData.length);
int inIndex = 0;
while ((inIndex = decoder.dequeueInputBuffer(1)) < 0)
;
if (inIndex >= 0)
{
Log.d("EncodeDecode", "DECODER_THREAD:: sample size: " + currentFrame.frameData.length);
ByteBuffer buffer = inputBuffers[inIndex];
buffer.clear();
buffer.put(currentFrame.frameData);
decoder.queueInputBuffer(inIndex, 0, currentFrame.frameData.length, 33, 0);
BufferInfo info = new BufferInfo();
int outIndex = decoder.dequeueOutputBuffer(info, 100000);
switch (outIndex)
{
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.e("EncodeDecode", "DECODER_THREAD:: INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.e("EncodeDecode", "DECODER_THREAD:: New format " + decoder.getOutputFormat());
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.e("EncodeDecode", "DECODER_THREAD:: dequeueOutputBuffer timed out!");
break;
default:
Log.d("EncodeDecode", "DECODER_THREAD:: decoded SUCCESSFULLY!!!");
ByteBuffer outbuffer = outputBuffers[outIndex];
decoder.releaseOutputBuffer(outIndex, true);
break;
}
i++;
}
}
}
decoder.stop();
decoder.release();
}
}
这会产生下一个错误:(我无法发布图片:(,所以这里是链接)
Error_Log
我在带有VLC的笔记本电脑上测试了数据流并显示了视频,所以我想这部分是有用的 此外,该应用程序正在创建一个表面,它显示接收到一些数据。但是当它试图将输出缓冲区放到表面时,应用程序会退出错误。
我是解码的新手,这是我的第一个Android应用程序,所以我真的不知道要看。所以我希望有人能指出我正确的方向。
如果您有兴趣,我的整个代码都在此链接中:
H264_video.java