I'm now trying to use MP3 encoder mft on Win10 pro Insider preview, but failed to set output media type.
Below is my code:
// Fill in MPEGLAYER3WAVEFORMAT data
MPEGLAYER3WAVEFORMAT mp3wfx;
ZeroMemory(&mp3wfx, sizeof(mp3wfx));
mp3wfx.wID = MPEGLAYER3_ID_MPEG;
mp3wfx.fdwFlags = 2; // no padding
mp3wfx.nBlockSize = int16_t(144 * (128000 / 44100)); // bitrate = 128000kbps
mp3wfx.nFramesPerBlock = 1;
mp3wfx.nCodecDelay = 0;
mp3wfx.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; // MP3
mp3wfx.wfx.nChannels = 2;
mp3wfx.wfx.nSamplesPerSec = 44100;
mp3wfx.wfx.wBitsPerSample = 16;
mp3wfx.wfx.nBlockAlign = (mp3wfx.wfx.nChannels * mp3wfx.wfx.wBitsPerSample) / 8;
mp3wfx.wfx.nAvgBytesPerSec = mp3wfx.wfx.nSamplesPerSec * mp3wfx.wfx.nBlockAlign;
mp3wfx.wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX); // 12
LComObject<IMFMediaType> ciOutputType; // Output media type of the encoder
hr = fpMFCreateMediaType((IMFMediaType**)(ciOutputType.GetAssignablePtrRef()));
WAVEFORMATEX* pWave = (WAVEFORMATEX*)&mp3wfx;
MFInitMediaTypeFromWaveFormatEx(ciOutputType.get(), pWave, sizeof(MPEGLAYER3WAVEFORMAT));
hr = ciEncoder->SetOutputType(0, ciOutputType.get(), 0);
please ignore the wrappers I have on those COM objects/interfaces. Mftrace output these
5552,500 05:05:15.03439 CMFPlatExportDetours::MFTEnumEx @ Activate 00 @034CE628, MFT_FRIENDLY_NAME_Attribute=MP3 Encoder ACM Wrapper MFT;MFT_INPUT_TYPES_Attributes=61 75 64 73 00 00 10 00 80 00 00 aa 00 38 9b 71 01 00 00 00 00 00 10 00 80 00 00 aa 00 38 9b 71 ;MFT_TRANSFORM_CLSID_Attribute={11103421-354C-4CCA-A7A3-1AFF9A5B6701};MFT_OUTPUT_TYPES_Attributes=61 75 64 73 00 00 10 00 80 00 00 aa 00 38 9b 71 55 00 00 00 00 00 10 00 80 00 00 aa 00 38 9b 71 ;MF_TRANSFORM_FLAGS_Attribute=1;MF_TRANSFORM_CATEGORY_Attribute=MFT_CATEGORY_AUDIO_ENCODER
5552,500 05:05:15.03616 COle32ExportDetours::CoCreateInstance @ New MFT @03510D20, <NULL>
5552,500 05:05:15.03618 COle32ExportDetours::CoCreateInstance @ Created {11103421-354C-4CCA-A7A3-1AFF9A5B6701} MP3 ACM Wrapper MFT (C:\Windows\System32\mfcore.dll) @03510D20 - traced interfaces: IMFTransform @03510D20,
5552,500 05:05:15.03681 CMFTransformDetours::SetOutputType @03510D20 Failed MT: MF_MT_AUDIO_AVG_BYTES_PER_SECOND=176400;MF_MT_AUDIO_BLOCK_ALIGNMENT=4;MF_MT_AUDIO_NUM_CHANNELS=2;MF_MT_MAJOR_TYPE=MEDIATYPE_Audio;MF_MT_AUDIO_SAMPLES_PER_SECOND=44100;MF_MT_AUDIO_PREFER_WAVEFORMATEX=1;MF_MT_USER_DATA=01 00 02 00 00 00 20 01 01 00 00 00 ;MF_MT_AUDIO_BITS_PER_SAMPLE=16;MF_MT_SUBTYPE=MFAudioFormat_MP3
Thanks for help
So it says:
SetOutputType @03510D20 Failed MT:
MF_MT_MAJOR_TYPE=MEDIATYPE_Audio;
MF_MT_SUBTYPE=MFAudioFormat_MP3;
MF_MT_AUDIO_PREFER_WAVEFORMATEX=1;
MF_MT_AUDIO_SAMPLES_PER_SECOND=44100;
MF_MT_AUDIO_NUM_CHANNELS=2;
MF_MT_AUDIO_BITS_PER_SAMPLE=16;
MF_MT_AUDIO_AVG_BYTES_PER_SECOND=176400;
MF_MT_AUDIO_BLOCK_ALIGNMENT=4;
MF_MT_USER_DATA=01 00 02 00 00 00 20 01 01 00 00 00 ;
There are two important things here:
MF_MT_AUDIO_AVG_BYTES_PER_SECOND
needs a correct value because there is a list of acceptable bitratesMF_MT_USER_DATA
is additional format data for the media type; presumably MPEGLAYER3WAVEFORMAT
values that follow WAVEFORMATEX
fields - the MFT might expect certain values, which are different from those you provide. You took the correct approach of asking MFT to enumerate output media types. Now you need to pick the closest and compare to what you have, you should see the difference that makes codec to reject your format.