0

ビデオ ファイルのサムネイルを生成する目的で、directshownet DirectShow ラッパーを利用することに成功しました。多くのテスト インスタンスでは、コードは問題なく動作します

ただし、RenderStream 関数呼び出しで「不明な例外」をスローするものもあります。

例外の原因を追跡できませんでした。エラー コードは「-2147467259」、InnerException:null です。COM インターフェイスの障害を調査した経験はあまりありませんが、エラー コードは論理値を形成していないようです。

私の最初の考えは、適切なコーデックなどの欠如でしたが、問題は、人気のあるコーデック パックのほとんどがインストールされているいくつかのテスト マシン (ffdshow、k-lite コーデック パックなど) で解決しません。動画もアプリの外で問題なく再生されます。

マシンは x64 バージョンの Windows (Windows 7 および win server 2008 r2) を実行しており、x64 バージョンの ffdshow コーデック パックをインストールしてから、32 ビット バージョンの ffdshow をインストールするなどの他の設定で再生し、x64 でテスト アプリをコンパイルすることもできます。 x86 ビルド モードと同様です。サンプル クリップで常に失敗します。また、特に h264 を見て、FFDSHOW 設定パネルで特定のコーデックを有効/無効にしようとしました。何もない。問題のあるサンプル ビデオは、次の仕様を使用してエンコードされています: v-codec:H264 - MPEG-4 AVC (パート 10) avc1 解像度:1280x768 FPS:23..

グラフを構築するためのコードは、多くのテスト ケースで機能するので問題ないと思いますが、次のとおりです。

 private void SetupGraph( string FileName)
 {
     int hr;

     // Get the graphbuilder object
     m_FilterGraph = new FilterGraph() as IFilterGraph2;

     // Get a ICaptureGraphBuilder2 to help build the graph
     ICaptureGraphBuilder2 icgb2 = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;

     try
     {
         // Link the ICaptureGraphBuilder2 to the IFilterGraph2
         hr = icgb2.SetFiltergraph(m_FilterGraph);
         DsError.ThrowExceptionForHR(hr);

         // Add the filters necessary to render the file.  This function will
         // work with a number of different file types.
         IBaseFilter sourceFilter = null;

         hr = m_FilterGraph.AddSourceFilter(FileName, null, out sourceFilter);
         DsError.ThrowExceptionForHR(hr);

         // Get the SampleGrabber interface
         m_sampGrabber = (ISampleGrabber)new SampleGrabber();
         IBaseFilter baseGrabFlt = (IBaseFilter)m_sampGrabber;

         // Configure the Sample Grabber
         ConfigureSampleGrabber(m_sampGrabber);

         // Add it to the filter
         hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
         DsError.ThrowExceptionForHR(hr);


         // Connect the pieces together, use the default renderer
         hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, null);
         DsError.ThrowExceptionForHR(hr); // **HERE** is where the 'unknown exception' is thrown.

         // Now that the graph is built, read the dimensions of the bitmaps we'll be getting
         SaveSizeInfo(m_sampGrabber);

         // Configure the Video Window
         IVideoWindow videoWindow = m_FilterGraph as IVideoWindow;
         videoWindow.put_AutoShow(OABool.False);
         // ConfigureVideoWindow(videoWindow, hWin);
         //
         // Grab some other interfaces
         m_mediaEvent = m_FilterGraph as IMediaEvent;
         m_mediaCtrl = m_FilterGraph as IMediaControl;
         m_mediaSeeking = m_FilterGraph as IMediaSeeking;
         m_mediaSample = m_FilterGraph as IMediaSample;
         m_mediaPosition = m_FilterGraph as IMediaPosition;

     }
     catch
     { }
     finally
     {
         if (icgb2 != null)
         {
             Marshal.ReleaseComObject(icgb2);
             icgb2 = null;
         }
     }

 }

まだ問題を絞り込もうとしています。私は単にアイデアを使い果たしたので、コメントをいただければ幸いです。 更新: 問題をより具体的にすることができるようです: DirecShow utlize h264 コーデックをシステムで利用できるようにするために、上記のグラフを変更する方法は? 見た目からして、それ自体は起こりません。もう 1 つの更新に値するものがあると思います: grapsh の構築などのテーマについて深く掘り下げました。さまざまなフィルター設定で遊ぶために、GrapStudio ソフトウェアもダウンロードしました。ただし、Render Media File サブメニューを選択して問題のあるビデオを指定するとすぐに、「ファイルをレンダリングできません」と表示されます。ビデオ ファイルは、Windows メディア プレーヤーまたは VLC で問題なく再生されます。FFDSHOW が提供する h264video コーデックでエンコードされています。

別の更新: K-Lite コーデック パック x64 を使用して、GraphStudio のレンダリング ムービー ([ファイル] -> [MEdia ファイルのレンダリング]) を作成することができました。グラフが作成されます (LAV Video Decoder を使用します)。私のアプリはまだグラフの自動生成に失敗していますが、x64 プラットフォームもターゲットにしており、GraphStudio が同じ API 関数を呼び出すだけで読んだことからもわかります。それはとても奇妙です。そこで、半自動グラフを作成することにしました。

    Guid gui = new Guid("EE30215D-164F-4A92-A4EB-9D4C13390F9F");
Object o;
ty = Type.GetTypeFromCLSID(gui);
o = Activator.CreateInstance(ty, false);
IBaseFilter ibfVideoDec = (IBaseFilter)o;
hr=m_FilterGraph.AddFilter(ibfVideoDec, "LAV Video decoder");
DsError.ThrowExceptionForHR(hr);

必要な他のフィルターを追加しながら、RenderFile を呼び出します。なし。すべてのフィルターは、対応する CLSID によって初期化されました。エラーはありません。レンダリングされません。最新のコーデックなどの使用に関しては、DirectShowNetまたはおそらくDirectShow全体がひどく文書化されていると私に尋ねたら.

4

1 に答える 1

0

エラーは0x80004005 E_FAIL「不明なエラー」です。グラフビルダーは、詳細を提供せずに、一部の内部コンポーネントからエラーを転送します。より細かいステップで代わりにグラフを作成せずに理由を見つける方法はありません。これは、システム内のサード パーティ コンポーネントの障害を含むあらゆる可能性があります (これは、コーデック パックを重ねてインストールした場合に発生する可能性が非常に高い)。個体とRenderStream個体に分けて原因を解説します。ConnectAddFitler

于 2012-11-09T01:53:31.420 に答える