何时以及如何使用 H.264/AVC Remux MFT 和 MP4 接收器

本主题介绍何时以及如何使用 H.264/AVC Remux MFT 和 MP4 接收器。

何时使用 H.264/AVC Remux MFT

MPEG-4 文件格式要求每个压缩样本包含一张主图片,其 NAL 单位顺序正确。 (请参阅 H.264 AVC 规范的第 7.4.1.2.3 节“ NAL 单位顺序和编码图片与访问单位的关联”中的主图片和强制 NAL 单位顺序的定义。) 它还要求每个压缩样本与演示时间戳、解码时间戳和样本持续时间相关联。

在许多情况下,当应用程序需要在 MPEG-4 文件容器中录制 H.264/AVC 视频时,压缩示例可能无法满足上述要求。 例如,一个压缩的示例可能不包含完整的主图片,或者可能没有与之关联的正确演示时间戳。 一些应用程序示例包括:

  • 将 H.264/AVC 流式处理基本视频写入 MPEG-4 文件容器。
  • 在 MPEG-4 文件容器中录制相机捕获的 H.264/AVC 基本视频。
  • 在 MPEG-4 文件容器中录制 H.264/AVC 视频会议。
  • 在 MPEG-2 TS 或 MP4 中连接两个 H.264/AVC 视频,并使用正确的时间戳写入 MPEG-4 文件容器。
  • 将 H.264/AVC 视频从 AVCHD、MPEG-2 TS/PS 文件格式转换为 MPEG-4 文件格式。
  • 在不转码的情况下剪裁 H.264/AVC 视频文件。

在这种情况下,应用程序需要使用 H.264/AVC remux MFT 来转换不包含完整主图片的压缩样本,然后再将其写入 MPEG-4 文件容器。

如何使用 H.264/AVC Remux MFT 和 MP4 接收器

将源输出媒体类型设置为 MFVideoFormat_H264_ES,这表示每个示例可能不包含完整的主图片。 将 MP4 接收器的输入媒体类型设置为 MFVideoFormat_H264。 因此,H.264/AVC remux MFT 的输入媒体类型 MFVideoFormat_H264_ES 并且 H.264/AVC remux MFT 的输出媒体类型 MFVideoFormat_H264,这将自动插入拓扑解析程序。

H.264/AVC remux 会忽略样本持续时间,因为不包含完整主图片的样本的样本持续时间没有明确的含义。 相反,采样持续时间是从帧速率计算的。 帧速率是从序列参数计算得出的。 如果序列参数中不存在信息,则从输入媒体类型中的参数计算帧速率。 如果帧速率信息不可用,则使用默认帧速率 29.97 fps。

H.264/AVC remux MFT 根据帧速率对每个压缩图片 (DTS) 线性内插解码时间戳。 H.264/AVC remux MFT 遵循输入样本中 PTS) (输入表示时间戳,并将它们传递到输出(如果存在)。 它根据帧速率、以前的 PTS 和图片输出顺序,通过解码的图片缓冲 (DBP 执行 PTS 内插,) H.264 AVC 规范的附件 C.4.5.3 凸起过程 。 H.264/AVC remux MFT 的每个输出样本应具有 PTS、DTS 和采样持续时间。 H.264/AVC remux MFT 还标识位流中的IDR图片,并使用 MFSampleExtension_CleanPoint的 MF 属性将它们设置为清洁点。

目前,H.264/AVC remux MFT 最多可处理 64 个重新排序的帧。 如果重新排序的帧数超过 64,并且存在长期参考帧,则 H.264/AVC remux MFT 将为该帧内插错误的 PTS,并在错误的时间输出该帧。

若要实例化 H.264/AVC remux MFT,请在 H.264/AVC remux MFT 上设置正确的输入和输出媒体类型,设置 MP4 接收器的输入媒体类型,并解析拓扑。

以下示例代码演示如何初始化 H.264/AVC remux MFT 和 MP4 接收器。

对于 H.264/AVC remux MFT,

hr = CoCreateInstance(
            CLSID_CMSH264RemuxMFT,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IMFTransform,
            (void**) &pIMFTransform
            );

无需进行任何其他配置。

对于 MP4 接收器,

IMFByteStream*  pMFBSOutputFile = NULL;
hr = MFCreateFile(
    MF_ACCESSMODE_READWRITE,
    MF_OPENMODE_DELETE_IF_EXIST,
    MF_FILEFLAGS_NONE,
    m_pszOutputFile,
    &pMFBSOutputFile);
if(FAILED(hr))
{
    Log(L"ERROR>> Failed to create output file for MP4 Sink (hr=0x%x)", hr);
    break;
}

hr = MFCreateMPEG4MediaSink(
    pMFBSOutputFile,
    (guidMajorType == MFMediaType_Video) ? pMediaType : NULL,  // pMediaType comes from the output type of the remux MFT
    (guidMajorType == MFMediaType_Audio) ? pMediaType : NULL,
    &m_pMediaSink);
if(FAILED(hr))
{
    Log(L"ERROR>> Failed to create MP4 Sink (hr=0x%x)", hr);
    break;
}
hr = m_pMediaSink->GetStreamSinkByIndex(0, &pStream);

Media Foundation 中支持的媒体格式