当前位置: 首页 > 知识库问答 >
问题:

使用MediaCodec API JNI解码H.264流

董飞航
2023-03-14

我正在开发一个使用MediaCodec API的H.264解码器。我试图在JNI层中调用MediaCodec java API,该函数如下所示:

void Decompress(const unsigned char *encodedInputdata, unsigned int inputLength, unsigned char **outputDecodedData, int &width, int &height) {
    // encodedInputdata is encoded H.264 remote stream
    // .....
    // outputDecodedData = call JNI function of MediaCodec Java API to decode
    // .....
}

稍后,我将把OutputDecodedData发送到我现有的视频呈现管道,并在Surface上呈现。

我希望我能够编写一个Java函数来解码输入流,但这些将是一个挑战-

  1. 此资源声明-

…你不能对解码的视频帧做任何事情,只能将它们呈现在表面

这里,一个表面已被传递decoder.configure(format,surface,null,0)在表面上呈现输出bytebuffer并且声明由于API限制,我们不能使用这个缓冲区,但要呈现它

那么,我是否能够将输出bytebuffer发送到本机层,以转换为无符号字符*并传递到我的呈现管道,而不是传递surfaceconfigure()

共有1个答案

贾飞章
2023-03-14

我看到了您提议的函数定义的两个基本问题。

首先,MediaCodec对访问单元(对于H.264是NAL单元)进行操作,而不是来自流的任意数据块,因此您需要一次传入一个NAL单元。一旦接收到块,编解码器可能希望在产生任何输出之前等待额外的帧到达。一般情况下,您不能通过一帧输入,然后等待接收一帧输出。

其次,正如您所注意到的,ByteBuffer输出是YUV编码的,采用多种颜色格式之一。格式因设备而异;高通设备特别使用自己的专有格式。(不过,它已经被反向工程过了,所以如果你四处搜索,你就能找到一些破解它的代码。)

 类似资料:
  • 我正在尝试使用MediaCodec API解码现场流屏幕捕获从PC由FFMPEG。 对于发件人(PC ffmpeg) 输出如下所示 用于接收器(Android MediaCodec) 我用surface创建了活动并实现了SurfaceHolder.Callback 对于PlayerThread 前四个字节是头和序列号 接下来的四个字节是时间戳 下四个字节是源标识符 因此,我删除了前12个字节,并将

  • 但是,深入分析我所基于的解析代码,它似乎期望第5个字节(直接在起始前缀代码之后)是: 0x65-I帧 0x41-a P帧 0x67-SPS帧 0x68-PPS帧 我在其他地方也看到过很多关于这些的报道。不过,我所经历的所有单元似乎都是从(按顺序)开始的: null

  • 我使用此命令从Raspberry摄像机流式传输实时视频: 我需要一种通过netcat传输H.264文件的方法,如上面的示例所示。它的接收方式必须与我的覆盆子相机相同。

  • H.264分析器可以用来分析学习H.264码流结构。可以比较详细的列出H.264码流中NAL的信息。

  • 我需要验证视频文件是(在Java): 视频是H.264编码的 我调查过JMF和Xuggle。 Xuggle使加载和解码文件变得更容易,并将其转换为另一种格式,但我还不知道如何确定我加载的文件的编码。 所以我想知道Xuggle是否有能力简单地返回视频类型 如果我需要自己确定,有人能给我指一些H.264格式的文档吗

  • 我已从安装ffmpeg 3.0https://github.com/FFmpeg/FFmpeg,我正在尝试将用mepeg4第2部分编码的视频转换为H264,但我得到未知编码器“libx264”错误 我试过h264, x264, libx264,都不管用) 我查看了支持的编解码器列表 这里是h264: 我使用的是ffmpeg 3.0,从列表中可以看出,似乎不支持h264编码,只支持h264解码,对吗