4

我的工作流程如下:

  1. 获取原始 YUV 帧。
  2. 将其传递给 Windows Media Foundation 以编码为 H.264 帧。
  3. 将输出转换为 FFmpeg AVPacket。
  4. 将带有 av_interleaved_write_frame 的数据包注入到与其他内容混合的输出文件中。

在 Windows 7 上,这很好用。在 Windows 8 上,av_interleaved_write_frame 坏了。原因是 Windows 8 在输出中引入了 B 帧,而 av_interleaved_write_frame 就是不喜欢,无论我如何设置 pts/dts。

我修改了编码器以使用 0 B 帧,然后给了我想要的输出。但...

在大约 10-15 秒的编码帧之后,视频会从近乎完美的状态降级到非常块状和非常低的帧速率。我尝试更改 Windows 8 可用的大多数设置来修改编码器,但似乎没有任何帮助。

唯一产生影响的是改变编码器的比特率。我增加编码器比特率的次数越多,视频在开始降级之前播放的时间就越长。

关于可能导致这种情况发生的 Windows 7 和 Windows 8 之间发生了什么变化的任何想法?

编码器设置减去成功检查(它们都成功)

IMFMediaType * mInputType = NULL;

MFCreateMediaType(&mOutputType);

mOutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
mOutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
mOutputType->SetUINT32(MF_MT_AVG_BITRATE, 10000000);

MFSetAttributeSize(mOutputType, MF_MT_FRAME_SIZE, frameWidth, frameHeight);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE, 30, 1);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE_RANGE_MAX, 30, 1);
MFSetAttributeSize(mOutputType, MF_MT_FRAME_RATE_RANGE_MIN, 15, 1);

mOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
mOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
mOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, 1);
mOutputType->SetUINT32(MF_MT_SAMPLE_SIZE, frameWidth * frameHeight * 2);
mOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Main);
mOutputType->SetUINT32(CODECAPI_AVEncCommonRateControlMode, eAVEncCommonRateControlMode_Quality);
mOutputType->SetUINT32(CODECAPI_AVEncCommonQuality, 80);

帧的编码基本上是:

  1. MFCreateMemoryBuffer 来存储传入的 YUV 数据。
  2. MFCreateSample。
  3. 将缓冲液连接到样品上。
  4. 设置采样时间和持续时间。
  5. 过程输入
  6. ProcessOutput 具有适当的输出大小
  7. 成功后,使用示例信息构建一个 AVPacket
4

0 回答 0