Reputation: 57
Can IMFTransform
interface be implemented to encode or decode H264 or AAC data or should I use FFmpeg or OpenH264.
Upvotes: 1
Views: 1927
Reputation: 69632
When you encode or decode media, IMFTransform
is the interface codecs expose in Media Foundation API. That is, you don't implement it - you take advantage of existing implementation of codecs which are available to you (you implement it when you want to extend the API and supply additional codec).
Stock Windows provides you with:
CLSID_CMSAACDecMFT
CLSID_AACMFTEncoder
CLSID_CMSH264DecoderMFT
, leverages DXVA hardware-assisted decoding wherever applicableCLSID_CMSH264EncoderMFT
, software (fallback) encoderAdditional hardware accelerated encoders might be provided with hardware drivers. All mentioned above are available in the form of IMFTransform
, can be consumed directly or using higher level Media Foundation APIs.
Upvotes: 4
Reputation: 647
You can implement the IMFTransform
interface to decode and encode H264 and AAC. Refer to CLSID_CMSH264DecoderMFT
and CLSID_CMSAACDecMFT
to decode H264 and ACC, also CLSID_CMSH264EncoderMFT
and CLSID_AACMFTEncoder
to encode H264 and ACC.
Encoder example : initialise the encoder.
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;
}
Decoder example : initialise the decoder.
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;
}
Upvotes: 2