c++ win32 COM
MP4エンコードについての質問です
上記のURLを参考に
MP4形式で入力し
MP4形式で出力するコードを書きましたが
「hr 0xc00da412
: ユーザー設定による出力の種類を許可する
エンコーダー MFT が見つかりません」
とのエラーコードが出てしまいます
エラーの箇所は
EncodeFile(PCWSTR pszInput, PCWSTR pszOutput)関数の
MFCreateTranscodeTopology()でエラーに
ここで質問なのですが
出力の種類を許可とは自身が何かを許可しなければいけない
といった旨のエラーコードなのでしょうか?
またMFCreateTranscodeTopology()の前に設定が必要ということですが
第一引数にIMFMediaSource(メディアソース)
第二引数にLPCWSTR(ファイルパス)
第三引数にIMFTranscodeProfile(トランスコードプロファイル)
第四引数にIMFTopology(トポロジ)それぞれポインタを渡しますが
上記のエラーではどの構造体で設定をすればよいのでしょうか?
CreateTranscodeProfile()関数の
CreateAACProfile関数や
CreateH264Profileでパラメーターや属性を決めたりしていますが
IMFAttributes構造体に
SetGUID関数でサブタイプ(MFVideoFormat_H264)を設定していたりと
一見すると設定が出来ている様に見えてしまいます
なにかの関数を追加し
エンコード出力の種類を許可するといったことでしょうか?
しかしチュートリアルにはそのような記述がないように思われます
(見落としているかと)
色々実験し
urlをカレントディレクトリにしたりしましたが
修正できませんでした
ライブラリが足りないのでしょうか?
何かパスが足りないのでしょうか?
どなたかご教授お願い致します。
エラーメッセージ
hr 0xc00da412
: ユーザー設定による出力の種類を許可する
エンコーダー MFT が見つかりません
visual studio 2022
pathは下記などの実験もしました
EncodeFile(argv[1], argv[2]);
↓
EncodeFile(PCWSTR(L"D:\デスクトップ\encode\ConsoleApplication1\ConsoleApplication1\x64\Debug\1.mp4"), PCWSTR(L"D:\デスクトップ\encode\ConsoleApplication1\ConsoleApplication1\x64\Debug\1.mp4"1.mp4"));
コードは文字制限のため、セッション部分は省いています
#include <new> #include <iostream> #include <windows.h> #include <mfapi.h> #include <Mfidl.h> #include <shlwapi.h> #include<codecapi.h> #pragma comment(lib, "mfplat") #pragma comment(lib, "mf") #pragma comment(lib, "mfuuid") #pragma comment(lib, "shlwapi") template <class T> void SafeRelease(T** ppT) { if (*ppT) { (*ppT)->Release(); *ppT = NULL; } } struct H264ProfileInfo { UINT32 profile; MFRatio fps; MFRatio frame_size; UINT32 bitrate; }; H264ProfileInfo h264_profiles[] = { { eAVEncH264VProfile_Base, { 15, 1 }, { 176, 144 }, 128000 }, { eAVEncH264VProfile_Base, { 15, 1 }, { 352, 288 }, 384000 }, { eAVEncH264VProfile_Base, { 30, 1 }, { 352, 288 }, 384000 }, { eAVEncH264VProfile_Base, { 29970, 1000 }, { 320, 240 }, 528560 }, { eAVEncH264VProfile_Base, { 15, 1 }, { 720, 576 }, 4000000 }, { eAVEncH264VProfile_Main, { 25, 1 }, { 720, 576 }, 10000000 }, { eAVEncH264VProfile_Main, { 30, 1 }, { 352, 288 }, 10000000 }, }; struct AACProfileInfo { UINT32 samplesPerSec; UINT32 numChannels; UINT32 bitsPerSample; UINT32 bytesPerSec; UINT32 aacProfile; }; AACProfileInfo aac_profiles[] = { { 96000, 2, 16, 24000, 0x29}, { 48000, 2, 16, 24000, 0x29}, { 44100, 2, 16, 16000, 0x29}, { 44100, 2, 16, 12000, 0x29}, }; int video_profile = 0; int audio_profile = 0; HRESULT CreateMediaSource(PCWSTR pszURL, IMFMediaSource** ppSource) { MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; IMFSourceResolver* pResolver = NULL; IUnknown* pSource = NULL; // Create the source resolver. HRESULT hr = MFCreateSourceResolver(&pResolver); wprintf(L"CreateObjectFromURL\n"); if (FAILED(hr)) { goto done; } // Use the source resolver to create the media source hr = pResolver->CreateObjectFromURL(pszURL, MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, &pSource); if (FAILED(hr)) { goto done; } wprintf(L"CreateObjectFromURL - FINISHED\n"); // Get the IMFMediaSource interface from the media source. hr = pSource->QueryInterface(IID_PPV_ARGS(ppSource)); done: SafeRelease(&pResolver); SafeRelease(&pSource); return hr; } HRESULT CreateAACProfile(DWORD index, IMFAttributes** ppAttributes) { if (index >= ARRAYSIZE(aac_profiles)) { return E_INVALIDARG; } const AACProfileInfo& profile = aac_profiles[index]; IMFAttributes* pAttributes = NULL; HRESULT hr = MFCreateAttributes(&pAttributes, 7);//コンテナー レベルの属性の属性ストアを作成します。 if (SUCCEEDED(hr)) { hr = pAttributes->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32( MF_MT_AUDIO_BITS_PER_SAMPLE, profile.bitsPerSample); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32( MF_MT_AUDIO_SAMPLES_PER_SECOND, profile.samplesPerSec); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32( MF_MT_AUDIO_NUM_CHANNELS, profile.numChannels); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32( MF_MT_AUDIO_AVG_BYTES_PER_SECOND, profile.bytesPerSec); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32( MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile.aacProfile); } if (SUCCEEDED(hr)) { *ppAttributes = pAttributes; (*ppAttributes)->AddRef(); } SafeRelease(&pAttributes); return hr; } HRESULT CreateH264Profile(DWORD index, IMFAttributes** ppAttributes) { if (index >= ARRAYSIZE(h264_profiles)) { return E_INVALIDARG; } IMFAttributes* pAttributes = NULL; const H264ProfileInfo& profile = h264_profiles[index]; HRESULT hr = MFCreateAttributes(&pAttributes, 5); //コンテナー レベルの属性の属性ストアを作成します。 if (SUCCEEDED(hr)) { hr = pAttributes->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32(MF_MT_MPEG2_PROFILE, profile.profile); } if (SUCCEEDED(hr)) { hr = MFSetAttributeSize( pAttributes, MF_MT_FRAME_SIZE, profile.frame_size.Numerator, profile.frame_size.Numerator); } if (SUCCEEDED(hr)) { hr = MFSetAttributeRatio( pAttributes, MF_MT_FRAME_RATE, profile.fps.Numerator, profile.fps.Denominator); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32(MF_MT_AVG_BITRATE, profile.bitrate); } if (SUCCEEDED(hr)) { *ppAttributes = pAttributes; (*ppAttributes)->AddRef(); } SafeRelease(&pAttributes); return hr; } HRESULT CreateTranscodeProfile(IMFTranscodeProfile** ppProfile) //エンコード パラメーターを記述します 空のトランスコード トポロジへ { IMFTranscodeProfile* pProfile = NULL; IMFAttributes* pAudio = NULL; IMFAttributes* pVideo = NULL; IMFAttributes* pContainer = NULL; HRESULT hr = MFCreateTranscodeProfile(&pProfile); //空のトランスコード プロファイル オブジェクトを作成します。 出力ファイルの構成設定が保存されます if (FAILED(hr)) { goto done; } wprintf(L"Maked empty profile\n"); // Audio attributes. hr = CreateAACProfile(audio_profile, &pAudio); if (FAILED(hr)) { goto done; } hr = pProfile->SetAudioAttributes(pAudio); if (FAILED(hr)) { goto done; } wprintf(L"Audio profile setting save\n"); // Video attributes. hr = CreateH264Profile(video_profile, &pVideo); if (FAILED(hr)) { goto done; } hr = pProfile->SetVideoAttributes(pVideo); if (FAILED(hr)) { goto done; } wprintf(L"Video profile setting save\n"); // Container attributes. hr = MFCreateAttributes(&pContainer, 1); //空の属性ストアを作成します。 item if (FAILED(hr)) { goto done; } hr = pContainer->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_MPEG4);//出力ファイルのコンテナーの種類を指定します。 シンク ライター属性 if (FAILED(hr)) { goto done; } hr = pProfile->SetContainerAttributes(pContainer);//コンテナー レベルの属性を設定 if (FAILED(hr)) { goto done; } *ppProfile = pProfile; (*ppProfile)->AddRef(); done: SafeRelease(&pProfile); SafeRelease(&pAudio); SafeRelease(&pVideo); SafeRelease(&pContainer); return hr; } HRESULT GetSourceDuration(IMFMediaSource* pSource, MFTIME* pDuration) { *pDuration = 0; IMFPresentationDescriptor* pPD = NULL; HRESULT hr = pSource->CreatePresentationDescriptor(&pPD); if (SUCCEEDED(hr)) { hr = pPD->GetUINT64(MF_PD_DURATION, (UINT64*)pDuration); pPD->Release(); } wprintf(L"Duration\n"); return hr; } HRESULT EncodeFile(PCWSTR pszInput, PCWSTR pszOutput) { IMFTranscodeProfile* pProfile = NULL; IMFMediaSource* pSource = NULL; IMFTopology* pTopology = NULL; CSession* pSession = NULL; MFTIME duration = 0; HRESULT hr = CreateMediaSource(pszInput, &pSource); if (FAILED(hr)) { goto done; } hr = GetSourceDuration(pSource, &duration); //メディア ソースに対してクエリを実行 if (FAILED(hr)) { goto done; } hr = CreateTranscodeProfile(&pProfile); if (FAILED(hr)) { goto done; } hr = MFCreateTranscodeTopology(pSource, pszOutput, pProfile, &pTopology); if (FAILED(hr)) { goto done; } hr = CSession::Create(&pSession); if (FAILED(hr)) { goto done; } hr = pSession->StartEncodingSession(pTopology); if (FAILED(hr)) { goto done; } hr = RunEncodingSession(pSession, duration); done: if (pSource) { pSource->Shutdown(); } SafeRelease(&pSession); SafeRelease(&pProfile); SafeRelease(&pSource); SafeRelease(&pTopology); return hr; } int main(int argc, wchar_t* argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (SUCCEEDED(hr)) { hr = MFStartup(MF_VERSION); // Media Foundation を初期化 if (SUCCEEDED(hr)) { hr = EncodeFile(argv[1], argv[2]); MFShutdown(); //Media Foundation をシャットダウン } CoUninitialize(); } return 0; }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。