我想在Android中解码和显示一个原始的h264视频字节流,因此我目前正在使用MediaCodec/Format类。我从服务器上通过Udp获取帧数据。但不幸的是,目前什么都没有展示出来。
这是我到目前为止所拥有的。
初始化MediaCodec类:
codec = MediaCodec.createDecoderByType("video/avc");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "video/avc");
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 100000);
format.setInteger(MediaFormat.KEY_WIDTH, 800);
format.setInteger(MediaFormat.KEY_HEIGHT, 600);
format.setInteger("max-width", 800);
format.setInteger("max-height", 600);
format.setInteger("push-blank-buffers-on-shutdown", 1);
codec.configure(format, surface, null, 0);解码器的使用:
int inIndex = codec.dequeueInputBuffer(10000);
if(inIndex >= 0)
{
ByteBuffer inputBuffer = codecInputBuffers[inIndex];
inputBuffer.clear();
inputBuffer.put(frameData);
codec.queueInputBuffer(inIndex, 0, frameSize, 33, 0);
}
int outIndex = codec.dequeueOutputBuffer(null, 10000);
switch(outIndex)
{
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
codecOutputBuffers = codec.getOutputBuffers();
System.out.println("OB Changed");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
System.out.println("OF Changed");
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
System.out.println("l8r");
break;
default:
ByteBuffer buffer = codecOutputBuffers[outIndex];
codec.releaseOutputBuffer(outIndex, true);
}我正在测试这段代码的设备是Google 5,当我运行它时,outIndex一直等于MediaCodec.INFO_TRY_AGAIN_LATER。
我以前已经为笔记本编写了一个客户机,它工作得很好,所以我想来自服务器的h264流应该是可以的。
谢谢你的帮忙
编辑:如果有人遇到同样的问题,建议的修正(1)解决了这个问题。我更正了上面的代码。现在起作用了。我的示例中的另一个错误是,不能将null传递给.dequeueOutputBuffers(.);。你得做些类似的事
BufferInfo buffInfo = new MediaCodec.BufferInfo();
int outIndex = codec.dequeueOutputBuffer(buffInfo, 10000);即使你没有被投入其中。;)
发布于 2014-03-11 19:41:11
我看到了一些问题..。
(1)您正在尝试替换输入缓冲区数组中的缓冲区。MediaCodec不像这样工作--框架提供缓冲区,然后将数据复制到它们中。其思想是,通过允许框架执行分配,它可能避免以后复制数据。
您需要从decoder.getInputBuffers()获取输入缓冲区数组,并使用这些。确保clear()的ByteBuffer重置位置,并限制每次。
(2)您正在编写一包数据,并期望得到一个输出数据框架。实际上,在生成第一个帧之前,您可能需要提供多个数据缓冲区。有关示例,请参见这个职位。在某些配置文件中,编码器允许重新排序帧,所以即使在解码器开始运行之后,也不能只给帧喂食,等待解码后的数据从另一边弹出。
(3) AVC解码器需要SPS/PPS数据,它可以通过设置BUFFER_FLAG_CODEC_CONFIG标志的缓冲区提供,也可以通过使用MediaFormat#setByteBuffer()向MediaFormat添加“CSC-0”/“CSC-1”密钥的数据。这两种方法的示例都可以在EncodeDecodeTest中找到。
在大片状上有许多AVC解码示例,但是数据源是MediaCodec编码器,所以它们通常免费获得点#3。
本帖可能对你有用。
为了显示框架,您可以在格拉菲卡中看到不同的方法(通常使用.mp4文件,所以那里的编码/解码实现没有那么相关)。
https://stackoverflow.com/questions/22332003
复制相似问题