实施 'IMFTransform' 编码或解码 H264 或 AAC

Implement 'IMFTransform' to encode or decode H264 or AAC

能否实现 IMFTransform 接口来编码或解码 H264 或 AAC 数据,或者我应该使用 FFmpeg or OpenH264

您可以实现 IMFTransform 接口来对 H264 和 AAC 进行解码和编码。参考CLSID_CMSH264DecoderMFTCLSID_CMSAACDecMFT解码H264和ACC,也参考CLSID_CMSH264EncoderMFTCLSID_AACMFTEncoder编码H264和ACC。

编码器示例:初始化编码器。

        IUnknown    *_transformUnk;
        IMFTransform *_encoder;

        HRESULT MediaEncoder::InitialiseEncoder(EncoderType encoder)
        {
            HRESULT hr = S_OK;

            // Has the encoder been init.
            if (!_isOpen)
            {
                _encoderType = encoder;

                // Init the COM.
                CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

                // Create a new close event handler.
                _hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                // If event was not created.
                if (_hCloseEvent == NULL)
                {
                    // Get the result value.
                    hr = __HRESULT_FROM_WIN32(GetLastError());
                }

                // If successful creation of the close event.
                if (SUCCEEDED(hr))
                {
                    // Start up Media Foundation platform.
                    hr = MFStartup(MF_VERSION);
                    _isOpen = true;
                }

                if (SUCCEEDED(hr))
                {
                    // Select the encoder.
                    switch (encoder)
                    {
                    case Nequeo::Media::Foundation::EncoderType::H264:
                        // Create the H264 encoder.
                        hr = CreateEncoder(CLSID_CMSH264EncoderMFT);
                        break;

                    case Nequeo::Media::Foundation::EncoderType::AAC:
                        // Create the AAC encoder.
                        hr = CreateEncoder(CLSID_AACMFTEncoder);
                        break;

                    case Nequeo::Media::Foundation::EncoderType::MP3:
                        // Create the MP3 encoder.
                        hr = CreateEncoder(CLSID_MP3ACMCodecWrapper);
                        break;

                    default:
                        hr = ((HRESULT)-1L);
                        break;
                    }
                }

                if (SUCCEEDED(hr))
                {
                    // Query for the IMFTransform interface 
                    hr = _transformUnk->QueryInterface(IID_PPV_ARGS(&_encoder));

                    // Encoder has been created.
                    _created = true;
                }
            }

            // Return the result.
            return hr;
        }

        HRESULT MediaEncoder::CreateEncoder(const CLSID encoder)
        {
            HRESULT hr = S_OK;

            // Create the decoder.
            hr = CoCreateInstance(encoder, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&_transformUnk);

            // Return the result.
            return hr;
        }

解码器示例:初始化解码器。

    IUnknown    *_transformUnk;
    IMFTransform    *_decoder;

    HRESULT MediaDecoder::InitialiseDecoder(DecoderType decoder)
        {
            HRESULT hr = S_OK;

            // Has the decoder been init.
            if (!_isOpen)
            {
                _decoderType = decoder;

                // Init the COM.
                CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

                // Create a new close event handler.
                _hCloseEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                // If event was not created.
                if (_hCloseEvent == NULL)
                {
                    // Get the result value.
                    hr = __HRESULT_FROM_WIN32(GetLastError());
                }

                // If successful creation of the close event.
                if (SUCCEEDED(hr))
                {
                    // Start up Media Foundation platform.
                    hr = MFStartup(MF_VERSION);
                    _isOpen = true;
                }

                if (SUCCEEDED(hr))
                {
                    // Select the decoder.
                    switch (decoder)
                    {
                    case Nequeo::Media::Foundation::DecoderType::H264:
                        // Create the H264 decoder.
                        hr = CreateDecoder(CLSID_CMSH264DecoderMFT);
                        break;

                    case Nequeo::Media::Foundation::DecoderType::AAC:
                        // Create the AAC decoder.
                        hr = CreateDecoder(CLSID_CMSAACDecMFT);
                        break;

                    case Nequeo::Media::Foundation::DecoderType::MP3:
                        // Create the MP3 decoder.
                        hr = CreateDecoder(CLSID_CMP3DecMediaObject);
                        break;

                    case Nequeo::Media::Foundation::DecoderType::MPEG4:
                        // Create the MPEG4 decoder.
                        hr = CreateDecoder(CLSID_CMpeg4sDecMFT);
                        break;

                    default:
                        hr = ((HRESULT)-1L);
                        break;
                    }
                }

                if (SUCCEEDED(hr))
                {
                    // Query for the IMFTransform interface 
                    hr = _transformUnk->QueryInterface(IID_PPV_ARGS(&_decoder));

                    // Decoder has been created.
                    _created = true;
                }
            }

            // Return the result.
            return hr;
        }

        HRESULT MediaDecoder::CreateDecoder(const CLSID decoder)
        {
            HRESULT hr = S_OK;

            // Create the decoder.
            hr = CoCreateInstance(decoder, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&_transformUnk);

            // Return the result.
            return hr;
        }

当您对媒体进行编码或解码时,IMFTransform 是媒体基础 API 中公开的接口编解码器。也就是说,您不实现它 - 您利用现有的可用编解码器实现(当您想要扩展 API 并提供额外的编解码器时实现它)。

股票Windows为您提供:

硬件驱动程序可能会提供额外的硬件加速编码器。上述所有内容都以 IMFTransform 的形式提供,可以直接使用或使用更高级别的媒体基础 APIs.