0

私は現在、2つのビデオを同時に録画するソフトウェアに取り組んでいます。1つ目は25fpsのフレームレートで、2つ目は10 fps(または将来的には15 fps)のフレームレートです。後で、これらの2つのビデオは、ピクチャーインピクチャーを使用して1つのビデオにまとめられます。問題は、ピクチャーインピクチャーのDirectShowフィルターが異なるフレームレートのビデオをサポートしていないことです。ここで、2番目のビデオのフレームレートを25fpsにスケールアップするための「ダミーフレーム」を生成できるDirectShowフィルターを探しています。誰かがそのようなDirectShowフィルターを知っていますか?

よろしくお願いします、デビッド

4

3 に答える 3

1

フレームレートコンバーターをお試しください

http://msdn.microsoft.com/en-us/library/windows/desktop/ff819100(v=vs.85).aspx

于 2012-04-20T23:08:08.863 に答える
1

アップルトンの答えは正しいです。私はその答えを拡張し、手動で作成されたDirectShowグラフのフィルターをインスタンス化する方法を示すサンプルコード(C ++ / CLI)を提供しています(利用可能なまばらなドキュメントから断片をピックアップするのは時間がかかる場合があります)。関連するコードは、REDUCE_FRAME_RATE条件付きでコンパイルされたコード内にあります。COM_CALL()私のカスタムHRESULTチェックマクロです。

// Additional include files required for DMO support

#include <ParserUIDs.h>
#include <dmodshow.h>
#include <propsys.h>
    …

static void AddDecodedVideoSampleGrabber(
      AVStreamSourceBox^ sourceBox,
      IGraphBuilder* pGraph,
      CComPtr<IBaseFilter>& pDecodedVideoSampleGrabber,
      IPin* pSourcePin,
      CComPtr<IPin>& pDecodedVideoSampleGrabberOutPin
   ) {
      HRESULT hRes;

      COM_CALL(pDecodedVideoSampleGrabber.CoCreateInstance(CLSID_SampleGrabber));
      COM_CALL(pGraph->AddFilter(pDecodedVideoSampleGrabber, L"DecodedVideoSampleGrabber"));
      CComPtr<IPin> pDecodedVideoSampleGrabberInPin(FilterTools::GetPin(pDecodedVideoSampleGrabber, "Input"));
      COM_CALL(pGraph->ConnectDirect(pSourcePin, pDecodedVideoSampleGrabberInPin, NULL));
      pDecodedVideoSampleGrabberOutPin = FilterTools::GetPin(pDecodedVideoSampleGrabber, "Output");

      auto pFrameCallbackSink = (SampleGrabberCBSink*)sourceBox->SetupSampleGrabberCallback(
         FRAME_SAMPLE_GRABBER,
         IntPtr(pDecodedVideoSampleGrabber)
      ).ToPointer();
      sourceBox->SetDecodedVideoSampleGrabber(IntPtr(pFrameCallbackSink));

   #ifdef REDUCE_FRAME_RATE
      // insert frame-reduction filter before x264 encoding  
      CComPtr<IBaseFilter> pFrameReducer;
      COM_CALL(pFrameReducer.CoCreateInstance(CLSID_DMOWrapperFilter));
      COM_CALL(pGraph->AddFilter(pFrameReducer, L"FrameReducer"));

      CComPtr<IDMOWrapperFilter> pDmoWrapper;
      COM_CALL(pFrameReducer->QueryInterface(__uuidof(IDMOWrapperFilter), (void**)&pDmoWrapper));
      COM_CALL(pDmoWrapper->Init(__uuidof(CFrameRateConvertDmo), DMOCATEGORY_VIDEO_EFFECT));
      CComPtr<IPropertyStore> pPropStore;
      COM_CALL(pFrameReducer->QueryInterface(IID_PPV_ARGS(&pPropStore)));

      PROPVARIANT var;
      PropVariantInit(&var);
      var.vt = VT_UI8;
      var.uhVal.HighPart = OUTPUT_FPS;    // Desired frame rate
      var.uhVal.LowPart = 1;
      pPropStore->SetValue(MFPKEY_CONV_OUTPUTFRAMERATE, var);
      PropVariantClear(&var);
      CComPtr<IPin>&pDmoInPin(FilterTools::GetPin(pFrameReducer, "in0"));
      COM_CALL(pGraph->ConnectDirect(pDecodedVideoSampleGrabberOutPin, pDmoInPin, NULL));
      CComPtr<IPin>&pDmoOutPin(FilterTools::GetPin(pFrameReducer, "out0"));
      pDecodedVideoSampleGrabberOutPin = pDmoOutPin;
   #endif

   }
于 2019-05-26T01:11:56.987 に答える
0

独自のオーバーレイフィルターを実装し、デコーダーとレンダラーの間に配置する必要があります。このフィルターは、ストリーム->2つの入力ピンを受け入れることができる必要があります。最初のストリームの場合、フレームを取得し、2番目のストリームによって生成された画像オーバーレイをフレームに適用します。したがって、毎回、オーバーレイストリームに1つの画像が保存されます。もう1つの解決策は、サードパーティのオーバーレイフィルターを使用することです。

これを実現する2番目の方法は、VMR9フィルターでカスタムdirect3dアロケータープレゼンターを使用することです。このようにして、3D環境でのレンダリング中に画像を混合します。この場合の2番目のストリームは、実際には分離されたグラフとして実装され、出力はsamplegrabberフィルターまたはカスタムレンダラーを使用してbmp画像を生成する必要があります。この方法により、より柔軟なソリューションが作成されます。必要なときにいつでもオーバーレイビデオを交換できます。

于 2012-04-20T14:01:25.837 に答える