【问题标题】:Media Foundation SetInputType returns "The stream number provided was invalid"Media Foundation SetInputType 返回“提供的流号无效”
【发布时间】:2017-08-17 03:55:21
【问题描述】:

为了简单起见,我正在使用我机器上可用的软件 H264 编码器 MFT 开发 H.264 编码器(与我最终将使用的英特尔 QSV 硬件编码器相反)。根据一些教程,我整理了以下代码:

IMFTransform* encoder;
DWORD numInputs, numOutputs;
DWORD *inputIDs, *outputIDs;
MFRatio fps = { 24, 1 }, par = { 1, 1 };
HRESULT hr;

hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
    return hr;
}

// Create the MFT
hr = FindVideoEncoder(false, true, true, &encoder);
if (FAILED(hr))
{
    return hr;
}

// Obtain number of streams attached to MFT
encoder->GetStreamCount(&numInputs, &numOutputs);

// Allocate appropriate size arrays
inputIDs = new DWORD[numInputs];
outputIDs = new DWORD[numOutputs];

// Obtain stream IDs
encoder->GetStreamIDs(numInputs, inputIDs, numOutputs, outputIDs);

// Set input and output types
IMFMediaType *inputType, *outputType;

CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
    &outputType, MFMediaType_Video, MFVideoFormat_H264);
hr = encoder->SetOutputType(outputIDs[0], outputType, 0);
if (FAILED(hr))
{
    return hr;
}

CreateVideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
    &inputType, MFMediaType_Video, MFVideoFormat_Base);
hr = encoder->SetInputType(inputIDs[0], inputType, 0);
if (FAILED(hr))
{
    return hr;
}

代码在下一行失败,给出“提供的流号无效”的 HRESULT 值。

hr = encoder->SetOutputType(outputIDs[0], outputType, 0);

我尝试在 SetOutputType 之前调用 SetInputType,但它会产生相同的错误。我究竟做错了什么?提前感谢您的回答。

编辑:添加了 CreateVideoType 函数来显示 outputType 和 inputType 是如何创建的

HRESULT CreateVideoType(
    UINT32               width,
    UINT32               height,
    MFVideoInterlaceMode interlaceMode,
    const MFRatio&       frameRate,
    const MFRatio&       par,
    IMFMediaType         **ppType,
    GUID                 majorType,
    GUID                 subtype
    )
{
    if (ppType == NULL)
    {
        return E_POINTER;
    }

    LONG    lStride = 0;
    UINT    cbImage = 0;

    IMFMediaType *pType = NULL;

    // Set the subtype GUID from the FOURCC or D3DFORMAT value.
    //subtype.Data1 = D3DFMT_A8R8G8B8;

    if (FAILED(MFCreateMediaType(&pType)))
    {
        goto done;
    }

    if (FAILED(pType->SetGUID(MF_MT_MAJOR_TYPE, majorType)))
    {
        goto done;
    }

    if (FAILED(pType->SetGUID(MF_MT_SUBTYPE, subtype)))
    {
        goto done;
    }

    if (FAILED(pType->SetUINT32(MF_MT_INTERLACE_MODE, interlaceMode)))
    {
        goto done;
    }


    if (FAILED(MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, width, height)))
    {
        goto done;
    }

    // Calculate the default stride value.
    if (FAILED(pType->SetUINT32(MF_MT_DEFAULT_STRIDE, UINT32(lStride))))
    {
        goto done;
    }

    // Calculate the image size in bytes.
    if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
    {
        goto done;
    }

    if (FAILED(pType->SetUINT32(MF_MT_SAMPLE_SIZE, cbImage)))
    {
        goto done;
    }

    if (FAILED(pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE)))
    {
        goto done;
    }

    if (FAILED(pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)))
    {
        goto done;
    }

    // Frame rate
    if (FAILED(MFSetAttributeRatio(pType, MF_MT_FRAME_RATE, frameRate.Numerator, frameRate.Denominator)))
    {
        goto done;
    }

    // Pixel aspect ratio   
    if (FAILED(MFSetAttributeRatio(pType, MF_MT_PIXEL_ASPECT_RATIO, par.Numerator, par.Denominator)))
    {
        goto done;
    }

    // Return the pointer to the caller.
    *ppType = pType;
    (*ppType)->AddRef();

done:
    SafeRelease(&pType);
    return S_OK;
}

【问题讨论】:

  • 嗨,什么结果返回代码encoder->GetStreamIDs(numInputs, inputIDs, numOutputs, outputIDs);? Microsoft H264 编码器 MFT 仅适用于一个流。如果方法 GetStreamIDs 返回 E_NOTIMP 那么它不会填充 outputIDs - 检查它。
  • 函数返回一个ID相同的输入和一个输出; 3452816845。HRESULT 确实是 E_NOTIMPL。
  • 这是错误的 - 相同的 ID; 3452816845。两者的 ID 都必须为 0。这意味着 Microsoft H264 编码器 MFT 不实现 GetStreamIDs
  • 当调用 hr = encoder->SetOutputType(0, outputType, 0); 时,我得到一个 AccessViolation 读取位置 0xFFFFFFFFFF。看来ID也是流的内存指针。
  • 如何创建 MediaType outputType?你确定它指向正确的内存吗?

标签: windows encoding h.264 ms-media-foundation


【解决方案1】:

Microsoft H264 编码器 MFT 不实现 GetStreamIDs- 它返回 E_NOTIMPL。您必须将输入和输出流 ID 设置为 0。

【讨论】:

    【解决方案2】:

    正如 Evgeny 在讨论中指出的那样,在代码运行之前有几个问题需要解决。将 inputIDoutputID 更改为 0 可以解决 SetInputTypeSetOutputType 调用的问题,但是视频类型的创建存在一些问题。

    首先创建输出类型:

    CreateH264VideoType(FRAME_WIDTH, FRAME_HEIGHT, MFVideoInterlace_Unknown, fps, par,
            &outputType, MFMediaType_Video, MFVideoFormat_H264);
    

    在函数 CreateH264VideoType 我删除了

     // Calculate the image size in bytes.
    
    if (FAILED(MFCalculateImageSize(subtype, width, height, &cbImage)))
    {
        goto done;
    }
    

    我必须添加

    // Profile
    if (FAILED(pType->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Base)))
    {
        goto done;
    }
    
    // Bitrate
    if (FAILED(pType->SetUINT32(MF_MT_AVG_BITRATE, 166723584)))
    {
        goto done;
    }
    

    对于 CreateUncompressedVideoType,我删除了 MFCalculateImageSize 并添加了比特率属性集调用。这解决了编码器初始化的错误。

    【讨论】:

      猜你喜欢
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      相关资源
      最近更新 更多