Android MediaCodec 似乎可以缓冲 H264 帧

2024-01-01

我正在手动读取 RTP/H264 流并将 H264 帧传递给 Android MediaCodec。我使用“markerBit”作为框架的边框。 MediaCodec 与 OpenGL 纹理 (SurfaceTexture) 绑定。 一般来说,一切正常。但解码器似乎缓冲帧。如果我将帧放入解码器中,它不会立即渲染到纹理。当我在解码器中添加 2-3 帧后,第一帧将渲染到纹理。

我正在针对 Android 4.4.4 实施。

private static final int INFINITE_TIMEOUT = -1;
private static final int TIMEOUT_OUTPUT_BUFFER_MEDIA_CODEC = 1000;
...
int bufferIndex = codec.dequeueInputBuffer(INFINITE_TIMEOUT);
if (bufferIndex < 0) {
  throw new RuntimeException("Error");
}

ByteBuffer inputBuffer = inputBuffers[bufferIndex];
inputBuffer.clear();

// Copy H264 data to inputBuffer
h264Frame.fill(inputBuffer);

codec.queueInputBuffer(bufferIndex, 0, inputBuffer.position(), 0, 0);
drainOutputBuffers();
...

and

private boolean drainOutputBuffers() {
MediaCodec.BufferInfo buffInfo = new MediaCodec.BufferInfo();

int outputBufferIndex = codec.dequeueOutputBuffer(buffInfo, TIMEOUT_OUTPUT_BUFFER_MEDIA_CODEC);

if (outputBufferIndex >= 0) {
  codec.releaseOutputBuffer(outputBufferIndex, true);
  return true;
}

switch (outputBufferIndex) {
  case MediaCodec.INFO_TRY_AGAIN_LATER:
    LOG.debug("Could not dequeue output buffer. Try again later");
    break;
  case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
    LOG.warn("The output format has changed.");
    break;
  case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
    LOG.warn("The output buffers has changed.");
    break;
  default:
    LOG.warn("The output buffer index was negative: {}", outputBufferIndex);
}
return false;
}

在渲染方面,我使用“onFrameAvailable”回调来检查是否必须更新 openGl 线程上的纹理。我用于检查的标志由锁(同步)保护。

我怀疑演示时间戳可能会影响渲染。但我将其设置为 0。因此我假设帧应该毫无延迟地渲染。

我希望将帧渲染到纹理,而不必放置额外的帧。


来自媒体编解码器文档 https://developer.android.com/reference/android/media/MediaCodec.html

Executing 状态有 3 个子状态:Flushed、Running 和 流结束。之后立马start()编解码器位于 Flushed 中 子状态,它保存所有缓冲区。一旦第一次输入 缓冲区出队,编解码器进入运行子状态,在该状态 度过了一生的大部分时间。当您使用以下命令对输入缓冲区进行排队时 流结束标记,编解码器转换到End-of-Stream子状态。在此状态下,编解码器不再接受进一步的输入 缓冲区,但仍然生成输出缓冲区,直到流结束 达到输出。您可以返回到 Flushed 子状态: 在执行状态下的任何时间使用flush()。

您需要“使用以下命令对输入缓冲区进行排队end-of-stream对您提供给解码器的第一帧执行此操作(确保它是关键帧)。

这一点是为了告诉解码器不要再期待更多帧,因此立即开始播放。否则,在看到任何东西之前喂 3 或 4 帧是正常的。这是所有 MPEG 解码器的期望,与 Android 无关。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android MediaCodec 似乎可以缓冲 H264 帧 的相关文章

随机推荐

  • 内容脚本匹配顶级域,如所有谷歌。*

    我希望我的内容脚本能够匹配所有谷歌域和特定页面 我知道这是不可能的 清单 json content scripts matches www google www youtube com readthedocs org 还有其他方法可以做到这
  • 页码 python-docx

    我正在尝试用 python 创建一个程序 它可以在 docx 文件中查找特定单词并返回它出现的页码 到目前为止 在浏览 python docx 文档时 我无法找到如何访问页码 甚至无法找到页码所在的页脚 有没有办法使用 python doc
  • 按照 swagger 规范,如何将嵌套对象的 json 定义为 yaml?

    我在 swagger yaml 中定义对象数组时遇到问题 每次我尝试定义 yaml 的 type array 部分时 Swagger 编辑器都会给出错误 我定义了它 但它不正确 因为它给出了错误 以下是我尝试在 swagger yaml 中
  • 2栏灵活布局

    我有 2 列结构 使用的CSS如下 div left position relative float left width 18 margin 1 div right position relative float right width
  • 将字节数组或文件存储转换为位图图像

    当我选择文件到存储文件后 如何将该文件转换为图像以便像个人资料图片一样显示 我将文件转换为字节数组 但不知道下一步该怎么做 或者还有其他方法吗 这是我的代码 var openPicker new Windows Storage Picker
  • 为 Android 构建 gdb 和 gdbserver

    我正在 64 位 Linux 上工作 需要构建数据库服务器对于我的 aarch64 Android 手机 有预建的数据库服务器在NDK中 但它使用NDK包中的python 而不是使用我的系统python 我无法安装其他python插件 如何
  • 数组上奇怪的迭代器语法背后的原因[重复]

    这个问题在这里已经有答案了 我最近了解到 要从数组中获取迭代器 您必须使用我以前从未见过的语法来访问它 let iterator myArray Symbol iterator 在我看来 实施Array prototype getItera
  • 我可以使用什么来代替 :inminated jQuery 选择器来避免 IE 8 中的异常?

    我有这样的代码 if chkCheckAll is indeterminate true 但它在 ie 8 中抛出异常 在 Jquery 中可以做什么来代替这个来与 ie8 一起使用 使用这个代替 var allChk chkCheckAl
  • 如何将变量从包含的模板传递到包含它的模板?

    在 Django 视图中 if request is ajax t get template bar templates html html t render Context edit True user some user return
  • ASP.NET MVC JsonResult 和 AuthorizeAttribute

    最直接的使用方法是什么AuthorizeAttribute and JsonResult在一起 以便当用户未经授权时应用程序返回 Json 错误而不是登录页面 我目前正在考虑的两件事正在扩展AuthorizeAttribute或者只是创建一
  • 保存 crontab 文件

    一个关于 Crontab 的简单问题 我保存 crontab 文件的位置重要吗 使用 crontab e 创建依赖于时间的作业 或者可以从任何目录读取它们 我问是因为我的 crontab 文件似乎被删除了 因为当我使用 crontab l
  • TYPO3 无法启用 htmlArea RTE

    我尝试在 TYPO3 6 2 LTS 版本 中安装模块 htmlArea RTE 在 扩展管理器 中 他是活动的 但是在 页面 中 当我编辑或创建新的文本记录时 所见即所得不会出现 我使用的是 Firefox 但我尝试了其他浏览器 但他也没
  • Maven 构建错误 - 无法解决以下工件

    我想通过maven构建一个spring mvc项目 出现以下错误 The following artifacts could not be resolved org aopalliance com springsource org aopa
  • 如何自定义 Amazon S3 中 Rails 5.2 ActiveStorage 附件的路径?

    添加附件时 例如 has one attached resume attachment 保存的文件最终位于 S3 存储桶的顶层 如何将它们添加到子目录中 例如 我的旧回形针配置可以按型号名称在目录中分类 你不能 到时候 只有一种选择 has
  • 使用字典值列表的堆栈图 (Python 3.x)

    我正在尝试从字典中制作堆栈图 其中值是 0 到 1 之间的浮点数列表 列表中值的索引是测量时间 t1 t2 tn 所有键都具有相同数量的值 例如 a 1 0 3 0 5 0 7 2 0 4 0 6 0 8 5 0 1 0 15 0 20 这
  • Entity Framework Core jsonb 列类型

    我将 Entity Framework Core 与 npgsql postgresql 一起用于 Entity Framework Core 我的问题是 使用迁移 如何标记类属性以生成 JSONB 列类型 例如 public class
  • Three.js 未捕获的安全错误:无法在“WebGLRenderingContext”上执行“texImage2D”:

    这个问题源于之前html5视频在android手机上无法播放的问题 Three js WebGLRenderered 视频无法在 Android 手机上播放 https stackoverflow com questions 2610948
  • 使用 C 连接器将选择和多重插入作为事务执行?

    我正在使用MySQL 我有一个 select 语句 后面跟着一些使用 C 连接器完成的 insert 语句 我想知道如何将它们全部放在一个事务下 然后最后提交 我已经阅读了 MySQL 5 0 参考手册并且C API 函数概述 http d
  • 如何获取graphql中的所有Enum值

    如何检索 graphql 中枚举类型的所有值 Example enum TRUCKPE NAME TATA 407 TATA 709 TATA 1106 ECHIER 1103 type Document truckType TRUCKPE
  • Android MediaCodec 似乎可以缓冲 H264 帧

    我正在手动读取 RTP H264 流并将 H264 帧传递给 Android MediaCodec 我使用 markerBit 作为框架的边框 MediaCodec 与 OpenGL 纹理 SurfaceTexture 绑定 一般来说 一切