首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Android上解码h264 ByteStream

在Android上解码h264 ByteStream
EN

Stack Overflow用户
提问于 2014-03-11 17:20:42
回答 1查看 9.6K关注 0票数 8

我想在Android中解码和显示一个原始的h264视频字节流,因此我目前正在使用MediaCodec/Format类。我从服务器上通过Udp获取帧数据。但不幸的是,目前什么都没有展示出来。

这是我到目前为止所拥有的。

初始化MediaCodec类:

代码语言:javascript
复制
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);

解码器的使用:

代码语言:javascript
复制
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(.);。你得做些类似的事

代码语言:javascript
复制
        BufferInfo buffInfo = new MediaCodec.BufferInfo();
        int outIndex = codec.dequeueOutputBuffer(buffInfo, 10000);

即使你没有被投入其中。;)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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文件,所以那里的编码/解码实现没有那么相关)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22332003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档