MediaCodec h264编码器输出大量原始流

时间:2015-12-21 15:04:59

标签: java android h.264 mediacodec encoder

我在Android应用程序中使用MediaCodec来编码来自Usb相机的帧,然后将该原始流提供给mp4parser以创建mp4(API级别为16)。

在许多设备上一切都运行良好,但我遇到了Galaxy S3(I9300)的问题。

问题在于,当我向编码器发送帧1分钟时,有时我会从编码器获得非常大的输出。

尺寸范围介于2.5MB-20MB之间。 对于较长的剪辑,此问题会变得更糟,例如7分钟范围是9MB-120MB。

这是正常的吗?

我试图捕获相同的场景,但仍然得到不同的结果。

编码器设置:

Codec: OMX.SEC.AVC.Encoder
Color Format: 21
KEY_FRAME_RATE: 8.77
KEY_BIT_RATE: ~880Kbit

还有一件事,当我将帧发送到编码器时我正在使用:

mediaVideoCodec.queueInputBuffer(inputBufferIndex, 0, FrameData.length, computePresentationTime(frameCounter), 0);

和功能

private long computePresentationTime(int frameIndex) {
    return (long)(132 + (frameIndex * (1000000f / 8.77f)));
}

编码是在后台线程中完成的,所以我不确定我可以在这里使用系统时间,除非生产者保存帧和时间。 这是正确的,132代表什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

" 132"意味着代码是从the CTS test复制的,它生成了它编码的视频。测试代码创建了一系列具有恒定帧速率的帧。作为确定时间戳通过未修改而不是由编解码器内部生成的努力的一部分,添加了一个小偏移量。

在880Kbps时,您预计(880/8)*(7 * 60)/ 1024 = 45MB。大多数编码器都能很好地匹配所需的速率。当帧上的时间戳与帧速率不匹配时(例如this post),我发现这种情况很糟糕,但是由于您生成了时间戳我不会确定为什么会这样。

理想情况下,时间戳来自相机,而不是生成的值或系统时间。否则你无法知道在源附近是否丢弃了一帧。

MediaCodec在Android 4.1(API 16)中有many problems,已在Android 4.3(API 18)中解析。你在测试什么设备和Android版本?