问题标签 [android-mediacodec]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3719 浏览

android - 从 MediaCodec 解码输出缓冲区

我正在使用 Android MediaCodec 库来解码存储在文件系统上的视频。我得到一个看起来合法的输出缓冲区(带有正确的bufferinfo.offsetand size)。它的格式似乎是 256(即 JPEG)。我尝试用 解码它BitmapFactory.decodeByteArray,但结果是null.

有谁知道确定输出缓冲区格式的正确方法?开始解码输出字节数组的正确方法是什么?

0 投票
0 回答
146 浏览

android - 什么是 lib_k3_generic_audio_extractor.so、lib_k3_mov_extractor.so 等等?

我正在试验 Android MediaCodec,我从这里得到的代码:https ://code.google.com/p/android-source-browsing.platform--cts

当我尝试运行代码“android-source-browsing.platform--cts/tests/tests/media/src/android/media/cts/DecoderTest.java”时,出现以下错误:

显然 lib_k3_avi_extractor.so、lib_k3_mov_extractor.so 等库不在我的设备中。这是我的问题:这些库是什么?它们是干什么用的?为什么它们不在设备中?我用谷歌搜索了这些库,但奇怪的是,搜索结果一无所获。

下面列出了生成错误的 Java 代码,以及我添加日志信息的小改动:

0 投票
1 回答
1335 浏览

android - MediaCodec:如何衡量性能?

我正在阅读有关 MediaCodec 和其他在线教程/示例的 Android 文档。据我了解,使用 MediaCodec 的方式是这样的(伪代码中的解码器示例):

这是使用 MediaCodec 的正确方法吗?如果没有,请用正确的方法启发我。如果这是正确的方法,我该如何衡量 MediaCodec 的性能?是 codec.dequeueOutputBuffer() 返回和 codec.queueInputBuffer() 返回之间的时间差吗?我想要微秒的准确度/精度。感谢您的想法和想法。

0 投票
1 回答
4319 浏览

android - 如何直接从 Android Surface 访问 EGL Image 以在 MediaCodec 视频解码器中使用?

我目前正在编写一个 android 应用程序,我需要在其中缓存视频帧,以便我可以轻松地来回切换,几乎没有延迟。

MediaCodec现在,我通过向对象的 Configure 调用提供 SurfacereleaseOutputBuffer并将渲染标志设置为true.

我发现访问解码的表面数据的唯一方法(除了解码返回的字节缓冲区,其格式似乎与设备相关)是调用链接到表面updateTeximage的链接,将其附加到目标并将其渲染到我创建的目标纹理我自己为了缓存它。SurfaceTextureGL_TEXTURE_EXTERNAL_OESGL_TEXTURE2D

我想优化这个缓存过程并能够在不同的线程上解码帧。使用我当前的方法,这意味着我必须为视频解码器创建另一个 EGL 上下文,共享上下文等...

我的问题是:是否可以在不调用的情况下访问与 Surface 关联的 EGL 图像或本机缓冲区数据 updateTexImage

这样我就可以缓存 egl 图像(根据 ,它不需要 EGL 上下文EGL_ANDROID_image_native_buffer)。这也将以 YUV 格式缓存,这将比我现在缓存的原始 RGB 纹理更节省存储。

0 投票
1 回答
604 浏览

android - 尽管在屏幕上渲染了帧,但 outputBuffers 返回空指针,使用 Android 中的 MediaCodec

我正在使用MediaCodec该类使用此链接中给出的代码解码 .mp4 视频。

我能够在屏幕上获得渲染的输出,但是当我尝试访问时outputBuffers[outIndex],我得到一个空指针错误。我无法弄清楚如何访问帧缓冲区以对其进行一些处理。

0 投票
4 回答
8897 浏览

android - 如何初始化 MediaFormat 以配置 MediaCodec 来解码原始 AAC 数据?

我的 StreamPlayer 有一个奇怪的问题,我需要任何可以得到的帮助。

我需要实现的主要目标是 StreamPlayer,它能够以尽可能小的延迟播放 MPEG-2 传输流。为此,我遵循这种方法:

流由基于 Java 的 TS Parser 解析。我已经实现了一个 TSExtractor,它与 MediaExtractor 类似并且工作正常。我可以像使用 MediaExtractor 一样接收所选曲目的所有媒体样本

要解码 AAC 数据,我想创建和配置 MediaCodec 的实例。使用 MediaExtractor 类,这通常由

因为我必须在我使用的 TSExtractor.getTrackFormat(int track) 方法中初始化 MediaFormat

因为我所有的 AAC 样本都包含我做的 ADTS

阅读这篇文章后,我终于使用“csd-0”键添加了一个 ESDS 框架

其中值 0x11 和 0x90 是从 ADTS 中提取的。

当我现在想解码 AAC 样本时,解码器帖子

到日志。

为了验证我的 TSExtractor 是否正确提取了样本,我使用 VLC 记录了相同的流,将其重新混合为 mp4 文件,而不进行转码,因此原始流没有改变。现在我可以用录制的 mp4 文件初始化 MediaExtractor,并比较我的 TSExtractor 和 MediaExtractor 创建的样本。使用跟踪和错误我发现了一个非常奇怪的行为:

当我使用 MediaExtractor 创建的 mediaFormat 配置 MediaCodec 时,MediaCodec 可以毫无问题地解码我的 TSExtractor 返回的 AAC 样本。比较由我的 TSExtractor 创建的基本上包含 HashMap 的 MediaFormat 和由 MediaExtractor 创建的 MediaFormat 给出了以下差异:

由 MediaExtractor 创建:

mediaFormat: {max-input-size=1212, durationUs=77428875, is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=0,limit =2,容量=2],采样率=48000}

由 TSExtractor 创建:

mediaFormat: {is-adts=1, channel-count=2, mime=audio/mp4a-latm, csd-0=java.nio.ByteArrayBuffer[position=2,limit=2,capacity=2], 采样率= 48000}

即使我采用 TSExtractor 创建的 MediaFormat 与 MediaExtractor 创建的 MediaFormat 相似,解码器使用自己创建的解码器也会出现相同的错误,而使用另一个解码器则没有任何问题。

任何帮助都会非常有帮助。

0 投票
1 回答
13585 浏览

android - 使用 MediaCodec 将一系列图像保存为视频

我正在尝试将MediaCodec一系列图像保存为文件中的字节数组,并保存到视频文件中。我已经在 a 上测试了这些图像SurfaceView(连续播放它们),我可以很好地看到它们。我查看了许多使用 的示例MediaCodec,以下是我的理解(如果我错了,请纠正我):

从 MediaCodec 对象获取 InputBuffers -> 用帧的图像数据填充它 -> 将输入缓冲区排队 -> 获取编码的输出缓冲区 -> 将其写入文件 -> 增加演示时间并重复

但是,我对此进行了很多测试,最终得到以下两种情况之一:

  • 我尝试模仿的所有示例项目都导致媒体服务器queueInputBuffer在第二次调用时死机。
  • 我尝试在最后调用codec.flush()(在将输出缓冲区保存到文件之后,虽然我看到的例子都没有这样做)并且媒体服务器没有死,但是,我无法用任何媒体播放器打开输出视频文件,所以出了点问题。

这是我的代码:

我的问题是,如何使用 MediaCodec 从图像流中获取工作视频。我究竟做错了什么?

另一个问题(如果我不太贪心的话),我想在这个视频中添加一个音轨,也可以用 MediaCodec 来完成,还是必须使用 FFmpeg?

注意:我知道MediaMux在 Android 4.3 中,但是,这不是我的选择,因为我的应用程序必须在 Android 4.1+ 上运行。

更新 感谢fadden的回答,我能够在没有媒体服务器死亡的情况下访问EOS(上面的代码是修改后的)。但是,我得到的文件正在产生乱码。这是我得到的视频快照(仅作为 .h264 文件使用)。

视频输出

我的输入图像格式是 YUV 图像(来自相机预览的 NV21)。我无法让它成为任何可播放的格式。我尝试了所有 COLOR_FormatYUV420 格式和相同的乱码输出。而且我仍然找不到(使用 MediaCodec)添加音频。

0 投票
1 回答
325 浏览

android - MediaCodec 会截断传入的数据包以进行解码吗?

MediaCodec用来解码用 ffmpeg 编码的 h264 数据包。当我使用 ffmpeg 解码时,帧显示正常。但是,当我使用MediaCodec硬件解码器进行解码时,有时会在帧中间出现黑条。仅当编码比特率设置得足够高(例如超过 4000000)以使任何给定AVPacket大小都高于 95000 左右时,才会发生这种情况。似乎MediaCodec(或底层解码器)正在截断帧。不幸的是,我需要质量,所以比特率不能被拒绝。我已经验证帧没有在其他地方被截断,并且我尝试设置MediaFormat.KEY_MAX_INPUT_SIZE为更高的值。

有没有人遇到过这个问题或知道我可以解决它的方法?

我附上了我在 OpenGL 中渲染然后在我的 Galaxy S4 上解码的随机像素图像。

一只忙碌的猫

0 投票
3 回答
1922 浏览

android-4.3-jelly-bean - 输入为 Surface 的媒体编解码器 API 无法与 H264 编码器一起使用(bigflake 示例代码)

我正在尝试在 4.3 上运行带有 H264 编码器的媒体编解码器 API 的示例代码,在 bigflake 的以下链接中进行了解释

http://bigflake.com/mediacodec/CameraToMpegTest.java.txt

我遇到了以下问题。-> 在 H264 编码器代码中,颜色格式、高度和宽度没有得到更新,因为 getpatameter 实现存在问题。所以我应用了这个补丁(https://code.google.com/p/android/issues/detail?id=58834)。-> 应用补丁后,编码器也不编码 -> 我看到像 D/CameraToMpegTest(3421) 这样的观察结果:编码器输出格式已更改:{csd-1=java.nio.ByteArrayBuffer[position=0,limit=8 ,容量=8],高度=144,mime=video/avc,csd-0=java.nio.ByteArrayBuffer[位置=0,限制=12,容量=12],什么=1869968451,宽度=176}

那么为什么这个值会被改变,不知道......之后我们总是看到编码器将 queueOutputBuffer 的状态提供为 INFO_TRY_AGAIN_LATER。所以它创建了文件,但它不编码任何东西,它停止为

I/MPEG4Writer(3421):接收到总/0 长度 (0/0) 缓冲区并编码 0 帧。- 视频

D/MPEG4Writer(3421):停止视频轨道

D/MPEG4Writer(3421):停止视频轨道源

D/MPEG4Writer(3421):视频轨道停止

D/MPEG4Writer(3421):停止编写器线程

D/MPEG4Writer(3421): 最后一批写入了 0 个块

D/MPEG4Writer(3421):编写器线程已停止

因此,据我所知,它应该可以工作,但看起来编码器仍然没有正确配置......

请指导这...谢谢

内哈尔

0 投票
3 回答
15680 浏览

android - 使用 Android 的 MediaCodec 和 MediaMuxer 混合 AAC 音频

我正在修改一个Android 框架示例,以将 MediaCodec 生成的基本 AAC 流打包到一个独立的 .mp4 文件中。我正在使用一个MediaMuxer包含由一个实例生成的 AAC 轨道的单个MediaCodec实例。

但是,我最终总是在调用以下内容时收到错误消息mMediaMuxer.writeSampleData(trackIndex, encodedData, bufferInfo)

E/MPEG4Writer﹕timestampUs 0 < lastTimestampUs XXXXX for Audio track

当我将原始输入数据排队时,mCodec.queueInputBuffer(...)我提供 0 作为每个框架示例的时间戳值(我也尝试使用单调递增的时间戳值,结果相同。我已经成功地将原始相机帧编码为 h264/mp​​4 文件同样的方法)。

查看完整来源

最相关的片段:

更新:我发现了一个我认为存在的根本症状MediaCodec。:

我发送presentationTimeUs=1000queueInputBuffer(...)info.presentationTimeUs= 33219在调用后接收MediaCodec.dequeueOutputBuffer(info, timeoutUs)。fadden 留下了与此行为相关的有用评论。