MediaCodec KEY_FRAME_RATE 似乎被忽略了 [英] MediaCodec KEY_FRAME_RATE seems to be ignored

查看:52
本文介绍了MediaCodec KEY_FRAME_RATE 似乎被忽略了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 android 4.4 中修改 screenrecord 的源并降低捕获的帧速率,但无论我输入什么值:

I am trying to modify the source for screenrecord in android 4.4 and lower the captured frame rate, but no matter what value I put in:

format->setFloat("frame-rate", 5);

结果总是一样的(非常高的帧率)

the result is always the same ( a very high frame rate )

编码器是否忽略了这个属性?如何控制帧率?

Is the encoder ignoring this property ? how can I control the frame rate ?

推荐答案

frame-rate 值不会被忽略,但它并没有做你想做的事情.

The frame-rate value is not ignored, but it doesn't do what you want.

frame-ratei-frame-interval 的组合决定了 I 帧(也称为同步帧")在编码输出中出现的频率.帧速率值也可能在满足某些设备上的 bitrate 目标方面发挥作用,但我不确定(参见例如 这篇文章).

The combination of frame-rate and i-frame-interval determines how often I-frames (also called "sync frames") appear in the encoded output. The frame rate value might also play a role in meeting the bitrate target on some devices, but I'm not sure about that (see e.g. this post).

MediaCodec 编码器不会丢帧.如果您想降低帧速率,则必须通过向其发送更少的帧来实现.

The MediaCodec encoder does not drop frames. If you want to reduce the frame rate, you have to do so by sending fewer frames to it.

screenrecord 命令不会以固定帧速率采样"屏幕.相反,它从表面合成器 (SurfaceFlinger) 接收到的每一帧都会发送到编码器,并带有适当的时间戳.如果 screenrecord 每秒接收 60 帧,您将获得 60fps 的输出.如果它快速连续接收 10 帧,然后在 5 秒内什么都没有,然后再接二连三,您将在输出文件中得到完全相同的内容.

The screenrecord command doesn't "sample" the screen at a fixed frame rate. Instead, every frame it receives from the surface compositor (SurfaceFlinger) is sent to the encoder, with an appropriate time stamp. If screenrecord receives 60 frames per seconds, you'll have 60fps output. If it receives 10 frames in quick succession, followed by nothing for 5 seconds, followed by a couple more, you'll have exactly that in the output file.

你可以修改screenrecord来丢帧,但是你要小心一点.如果您尝试通过丢弃每隔一帧将最大帧速率从 60fps 降低到 30fps,您将面临在frame0 - frame1 - long_pause - frame2"序列中丢弃 frame1 的风险,并且视频将保留在 frame0相反,显示一个不完整的动画.因此,您需要缓冲一帧,然后如果 N-1 帧与帧 N 之间的呈现时间差约为 17 毫秒,则编码或丢弃帧 N-1.

You can modify screenrecord to drop frames, but you have to be a bit careful. If you try to reduce the maximum frame rate from 60fps to 30fps by dropping every-other frame, you run the risk that in a "frame0 - frame1 - long_pause - frame2" sequence you'll drop frame1, and the video will hold on frame0 instead, showing a not-quite-complete animation. So you need to buffer up a frame, and then encode or drop frame N-1 if the difference in presentation times between that and frame N is ~17ms.

棘手的部分是 screenrecord 在其默认操作模式下,将帧定向到编码器而不接触它们,因此您看到的只是编码输出.您不能随意丢弃编码数据的单个帧,因此您确实希望首先防止编码器看到它们.如果您使用 screenrecord v1.1 源,您可以进入覆盖"模式,用于 --bugreport,让帧在到达编码器的途中通过 screenrecord.

The tricky part is that screenrecord, in its default operating mode, directs the frames to the encoder without touching them, so all you see is the encoded output. You can't arbitrarily drop individual frames of encoded data, so you really want to prevent the encoder from seeing them in the first place. If you use the screenrecord v1.1 sources you can tap into "overlay" mode, used for --bugreport, to have the frames pass through screenrecord on their way to the encoder.

在某些方面,编写降低帧速率的后处理器可能更简单.我不知道解码和重新编码视频会损失多少质量.

In some respects it might be simpler to write a post-processor that reduces the frame rate. I don't know how much quality would be lost by decoding and re-encoding the video.

更新:有关如何粗略地执行此操作的示例,请将其添加到 processFrame_l():

Update: for an example of how to do it crudely, add this to processFrame_l():

     int64_t droppedFrames = 0;
+    {
+        static int flipflop = 0;
+        flipflop = 1 - flipflop;
+        if (flipflop) {
+            printf("dropping frame %lld
", frameNumber);
+            return;
+        }
+    }

     if (mLastFrameNumber > 0) {

请注意,这是在 updateTexImage() 之后进行的,后者获取下一个缓冲区,并跳过对 swapBuffers() 的调用,后者将缓冲区提交给视频编码器.

Note this comes after updateTexImage(), which acquires the next buffer, and skips the call to swapBuffers(), which submits the buffer to the video encoder.

这篇关于MediaCodec KEY_FRAME_RATE 似乎被忽略了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆