0

基本的には、オーディオ/ビデオをキャプチャしたいと思います。mp4マルチプレクサを介して実行し、ディスク上のファイルに保存します。ICaptureGraphBuilder2を使用する前は、カスタム形式で保存する場合は使用できないようです。

これまでの私のコード、

ビデオ/オーディオデバイスを列挙します。このサンプルでは、​​オーディオのみをキャプチャしようとしています。正しいデバイスを取得し、GetPinを使用してフィルターピンを列挙し、出力ピンを取得します。

hr = pMoniker2->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc2);
hr = pGraph->AddFilter(pSrc2, L"AudioCap");

hr = GetPin(pSrc2, PINDIR_OUTPUT, &outPin);

これはカスタムフィルター、MP4マルチプレクサーです。正しくロードされ、入力ピンを取得して出力ピンに接続できます。ここまでは順調ですね。

HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4mux.dll"), clsid, &pUnk);
if (SUCCEEDED(hr))
{
    IBaseFilterPtr pFilter = pUnk;
    HRESULT hr = pGraph->AddFilter(pFilter, L"Private Filter");
    hr = GetPin(pFilter, PINDIR_INPUT, &inPin);
}

hr = pGraph->Connect(outPin, inPin);

これは私が迷子になる場所です。レンダリングして出力をディスク上のファイルに保存するための次の手順を実行する方法がわかりません。ですから、次のステップで助けていただければ幸いです。よろしくお願いします。

編集:Filesinkコード

AM_MEDIA_TYPE mType;

mType.majortype = MEDIATYPE_Video;
mType.subtype = MEDIASUBTYPE_H264;
mType.bFixedSizeSamples = FALSE;
mType.bTemporalCompression = TRUE;
mType.lSampleSize = 0;
mType.formattype = FORMAT_None;
mType.pUnk = NULL;
mType.cbFormat = 0;
mType.pbFormat = NULL;
//Not 100% sure about the setup of the media format.

IBaseFilter * iFiltera = NULL; 
IFileSinkFilter* iFilter = NULL; 
IGraphBuilder *pGraph;

hr = pMoniker2->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc2); //audio capture
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,  IID_IGraphBuilder, (void**)&pGraph);
hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&iFiltera);

hr = pBuild->SetFiltergraph(pGraph);

hr = pGraph->AddFilter(pSrc2, L"AudioCap");
hr = GetPin(pSrc2, PINDIR_OUTPUT, &outPin); //ADDED

hr = pGraph->AddFilter(iFiltera, L"FileWriter");
hr = iFiltera->QueryInterface(IID_IFileSinkFilter, (void**)&iFilter);

iFilter->SetFileName((LPCOLESTR)"c:\\wav\\tester.mp4", NULL); //UPDATED mType set to NULL

HRESULT hr = CreateObjectFromPath(TEXT("c:\\filters\\mp4mux.dll"), clsid, &pUnk);

IBaseFilterPtr pFilter = pUnk;
if (SUCCEEDED(hr))
{

    HRESULT hr = pGraph->AddFilter(pFilter, L"Private Filter");
    hr = GetPin(pFilter, PINDIR_INPUT, &inPin); //mux in

    hr = GetPin(pFilter, PINDIR_OUTPUT, &mOutPin); //mux out
    hr = GetPin(iFiltera, PINDIR_INPUT, &filePin); // filewriter in
}

hr = pGraph->Connect(outPin, inPin); //connect audio out and mux in
hr = pGraph->Connect(mOutPin, filePin); //connect mux out and file in; Error 0x80040217(VFW_E_CANNOT_CONNECT?) //works now

//ADDED code
IMediaControl *pMC = NULL;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);

hr = pMC->Run();
Sleep(4000);
hr = pMC->Stop();  
4

1 に答える 1

1

特定のタスクに必要なフィルターグラフトポロジを把握する必要があります。ここでキャプチャを実行しています-問題ありません。つまり、コードスニペットを提供したオーディオキャプチャフィルターがあります。次に、オーディオを圧縮するか(AACMP4ファイルを作成する場合はMPEG-4 Part 3を選択する必要があります)、オーディオを非圧縮PCMのままにします。次に、MPEG-4マルチプレクサを接続します。マルチプレクサは出力ストリームを生成し、ファイルライターフィルタを使用してパイプラインを完了することが期待されます。

GraphEdit SDKアプリケーションでチェーンを手動で構築できます(または、より豊富な代替ツールがあります)。フィルタグラフは次のようになります。

フィルタグラフ

アプリケーションでフィルターグラフを公開し、リモートで接続してトポロジを検査できることに注意してください。これにより、デバッグがはるかに簡単になります。フィルタグラフ(IMediaControl::Run::Stopコードから)を開始/停止すると、ファイルが作成されます。

私の理解では、マルチプレクサを追加した直後に迷子になります。次に、出力ピンを見つけ、追加File Writerし、クエリを実行しIFileSinkFilter、それを使用して宛先ファイル名を設定し、入力ピンを見つけ、接続されていない2つのピン(マルチプレクサ出力、ライター入力)を接続する必要があります。パイプラインを実行する準備が整いました。

于 2012-06-26T16:51:35.610 に答える