有媒体codeC和MediaMuxer,但比特率和帧速率录制视频是不正确的不正确、比特率、媒体、帧速

2023-09-13 23:59:11 作者:た不再年少谁懂

我写了一个演示使用媒体codeC和MediaMuxer录制视频,我按照grafika实现了演示。

我记录我的演示视频,并使用ffprobe检查视频, 其结果是,如下所示:

 播放时间:00:00:06.86,启动:0.000000,码率:723 kb / s的
流#0:0(ENG):视频:H264(高)(AVC1 / 0x31637661),YUV420P,320×240,619 kb / s的,SAR 1:1 DAR 4:3,30.02 FPS,30 TBR,90K TBN,180K待定(默认)
元数据:
  CREATION_TIME:2015年6月5日13时19分24秒
  handler_name:VideoHandle
流#0:1(ENG):音频:AAC(LC)(MP4A / 0x6134706D),44100赫兹,单声道,fltp,96 KB /秒(默认)
元数据:
  CREATION_TIME:2015年6月5日13时19分24秒
  handler_name:SoundHandle
 

它包含视频和音频信息,我发现音频属性是一样的,因为我在源$ C ​​$ C设置,但在视频性能是不行的。 我的视频设置源$ C ​​$ c是如下:

  MediaFormat格式= MediaFormat.createVideoFormat(MIME_TYPE,mWidth,mHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            媒体codecInfo 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);
    如果(详细)Log.d(TAG,格式为:+格式);
    mVideoEn codeR =媒体codec.createEn coderByType(MIME_TYPE);
    mVideoEn coder.configure(格式,NULL,NULL,媒体codec.CONFIGURE_FLAG_EN code);
    mInputSurface = mVideoEn coder.createInputSurface();
    mVideoEn coder.start();
 

视频的宽度和高度都是正确的,但比特率和帧率比我在源$ C ​​$ C设置更高。它导致该视频文件的大小远大于 我期望。 然后,我修改了源$ C ​​$ C删除录音线程仅仅只录制视频。但它并没有任何差异,比特率和帧速率也更高。 谁可以告诉我的原因,并给我一些建议?

avc水平什么意思 码率是什么 比特率是干嘛的 帧速率是啥 分辨率又是什么 ...

和存在另一个问题。予录制破碎视频偶尔可以由系统播放器播放,但视频的开头仅有1或2秒后显示黑色和正常图像。我不知道如何上传文件中的计算器,我可以把碎的视频文件的人谁需要它。 有没有人来解决这个问题?

地址: 我发现了另一个奇怪的事情: 我的视频编码的配置:

 私人INT mWidth = 480;
私人诠释mHeight = 848;
私人诠释mVideoBitrate = 1200 * 1000;

    MediaFormat格式= MediaFormat.createVideoFormat(MIME_TYPE,480,848);

    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            媒体codecInfo codecCapabilities.COLOR_FormatSurface)。
    format.setInteger(MediaFormat.KEY_BIT_RATE,120);
    format.setInteger(MediaFormat.KEY_FRAME_RATE,30);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,1);
 

但实际的视频信息是:

 播放时间:00:00:06.01,启动:0.000000,比特率:6491 KB /秒
流#0:0(ENG):音频:AAC(LC)(MP4A / 0x6134706D),44100赫兹,单声道,fltp,15 kb / s的(默认)
元数据:
  CREATION_TIME:2015年9月30号15点44分十八秒
  handler_name:SoundHandle
流#0:1(ENG):视频:H264(基线)(AVC1 / 0x31637661),YUV420P,480x848,6484 KB /秒,SAR 1:1 DAR 30:53,16 FPS,30 TBR,90K TBN,180K待定(默认)
元数据:
  CREATION_TIME:2015年9月30号15点44分十八秒
  handler_name:VideoHandle
 

解决方案

它看起来像你预期的帧率(19fps)不实际的帧率(30fps)的匹配。带连接codeR试图满足比特率要求在19fps提交帧,但他们来更快,所以它射门和实际比特率就越高。我假设30fps的值从实际presentation时间标记的视频文件,他们会被传递到MediaMuxer了presentation时间戳设置确定。如果你想19fps的视频,你需要生成时间戳是(1000至1019年),单位为毫秒。

如果您的视频输入为30fps,则需要在编码过程中丢帧去19fps。媒体codeC不丢帧你 - 它连接$ C,你通过在$ CS一切

我不知道为什么你会在视频开始得到一个破碎的部分。

I wrote a demo to record a video using MediaCodec and MediaMuxer, I achieved the demo according to grafika.

I record a video with my demo and use ffprobe to check the video, the result is as follows:

  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. I don't know how to upload file in stackoverflow, I can send the broken video file to anyone who need it. Is there someone came with this problem?

ADD: I found another strange thing: My video encoding config:

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). 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. 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. If you want 19fps video, you need to generate time stamps that are (1000/19) milliseconds apart.

If your input video is 30fps, you will need to drop frames during the encoding process to get to 19fps. MediaCodec does not drop frames for you -- it encodes everything you pass in.

I don't know why you'd be getting a broken section at the start of the video.