简体   繁体   English

使用MediaCodec和MediaMuxer录制视频,但比特率和帧率不正确

[英]Record video with MediaCodec and MediaMuxer, but the bitrate and framerate are incorrect

I wrote a demo to record a video using MediaCodec and MediaMuxer. 我写了一个使用MediaCodec和MediaMuxer录制视频的演示。

I record a video with my demo and use ffprobe to check the video, the result is as follows: 我用我的演示录制视频并使用ffprobe检查视频,结果如下:

  Duration: 00:00:06.86, start: 0.000000, bitrate: 723 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 320x240, 619 kb/s, SAR 1:1 DAR 4:3, 30.02 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : VideoHandle
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 96 kb/s (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : SoundHandle

It contains video and audio information, I found the audio properties are the same as I set in the source code, but the video properties are not all right. 它包含视频和音频信息,我发现音频属性与我在源代码中设置的相同,但视频属性不是很好。 My video settings source code is as follows: 我的视频设置源代码如下:

        MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 384000);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, 19);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    if (VERBOSE) Log.d(TAG, "format: " + format);
    mVideoEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
    mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = mVideoEncoder.createInputSurface();
    mVideoEncoder.start();

The width and height of the video are right but bitrate and framerate are higher than I set in source code. 视频的宽度和高度是正确的,但比特率和帧率高于我在源代码中设置的值。 It results in that the video file size is much larger than I expected. 这导致视频文件大小比我预期的要大得多。 Then, I modified my source code to remove audio recording thread and just record the video only. 然后,我修改了我的源代码以删除录音线程,只记录视频。 But it didn't make any differences, the bitrate and framerate are also higher. 但它没有任何差异,比特率和帧率也更高。 Who can tell me the reason and give me some advices? 谁能告诉我原因并给我一些建议?

And there is another problem. 还有另一个问题。 I record a broken video occasionally which can be played by system player, but the begining of the video is just black and normal image displayed after 1 or 2 seconds. 我偶尔会录制一个可以由系统播放器播放的损坏视频,但视频的开头只是黑色,1或2秒后显示正常图像。 I don't know how to upload file in stackoverflow, I can send the broken video file to anyone who need it. 我不知道如何在stackoverflow中上传文件,我可以将损坏的视频文件发送给任何需要它的人。 Is there someone came with this problem? 有人有这个问题吗?

ADD: I found another strange thing: My video encoding config: ADD:我发现了另一个奇怪的事情:我的视频编码配置:

private int mWidth = 480;
private int mHeight = 848;
private int mVideoBitrate = 1200 * 1000;

    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, 480, 848);

    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 1200000);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

but the actual video info is: 但实际的视频信息是:

  Duration: 00:00:06.01, start: 0.000000, bitrate: 6491 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 15 kb/s (default)
Metadata:
  creation_time   : 2015-09-30 15:44:18
  handler_name    : SoundHandle
Stream #0:1(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 480x848, 6484 kb/s, SAR 1:1 DAR 30:53, 16 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
  creation_time   : 2015-09-30 15:44:18
  handler_name    : VideoHandle

It looks like your expected frame rate (19fps) doesn't match the actual frame rate (30fps). 看起来您的预期帧速率(19fps)与实际帧速率(30fps)不匹配。 The encoder is attempting to meet the bit rate requirements for frames submitted at 19fps, but they're coming in faster, so it misses and the actual bit rate is higher. 编码器试图满足以19fps提交的帧的比特率要求,但它们的速度更快,因此它错过了,实际比特率更高。 I'm assuming the 30fps value is determined from the actual presentation time stamps in the video file, which are set by the presentation time stamps passed into MediaMuxer. 我假设30fps值是根据视频文件中的实际演示时间戳确定的,这些时间戳是由传递给MediaMuxer的演示时间戳设置的。 If you want 19fps video, you need to generate time stamps that are (1000/19) milliseconds apart. 如果您需要19fps视频,则需要生成相隔(1000/19)毫秒的时间戳。

If your input video is 30fps, you will need to drop frames during the encoding process to get to 19fps. 如果您的输入视频是30fps,则需要在编码过程中删除帧以达到19fps。 MediaCodec does not drop frames for you -- it encodes everything you pass in. MediaCodec不会为您丢帧 - 它会对您传入的所有内容进行编码。

I don't know why you'd be getting a broken section at the start of the video. 我不知道为什么你会在视频开头看到一个破碎的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM