2011-01-20 14 views
3

DirectShowグラフを既存のアプリケーションに統合する際に奇妙な問題が発生しています。最初にカバーするDirectShow - 新しいスレッドを作成できません

カップルの事:

  1. グラフの目的は、公開のDirectShowインターフェースを持っているフレームグラバーからの生の映像をもたらすことです。グラフはVMR9を介して表示するためにビデオを右に持ち、生フレームをISampleGrabber(DirectShowの例)を通していくつかのアルゴリズムに公開します。
  2. グラフは個々のプロジェクトで構築され、正常に実行されています。ビデオはうまく表示され、すべてが幸せです。

これを既存のコードに統合する際に問題が発生します。アプリケーションの初期化から、私はまずグラフを作成し、ウィンドウレスモードでVMR9を実行します。後で初期化すると、_beginthreadex経由で2つのワーカースレッドが作成されます。 _beginthreadexへの呼び出しは、グラフが作成されて実行されているときにのみ(そして、メモリ不足の)戻りコード12で失敗します。

ここで明らかなのは、メモリが不足しているか、他のリソースがあることです。しかし、スレッドが開始しようとしている時点で、私は〜420MBの2GBシステムメモリを使用しています。スレッドスタックサイズは明示的に1MBに設定されています。だから私は私が言うことができる限り、記憶から外れていない。さらに、実行中のアプリケーションには合計15のスレッドがありますので、私はばかげた量を作りません。

誰もがDirectShowで同様の問題を経験しましたか?私はすべての入力を探していますが、私たちはかなりの時間この問題をデバッグしようとしており、成功していません。

ほとんどのDirectShowグラフでは、コードが長いので、必要なコードを投稿します。要求されたよう

編集

。 DirectShowコードのどの部分がスレッドの起動に失敗するのかはわかりません。しかし、私が構築するだけで、グラフを実行しないと、スレッドは正常に機能します。だから私は失敗が実行呼び出し後に発生すると思います。次のようにグラフを実行するための私のコードは次のとおりです。SetVMRSize機能は、単にその親ウィンドウにVMRのサイズを変更

if (CurrentState != Stopped) 
     return WrongState; 

    HRESULT hr; 
    printf("Attempting to run graph... "); 
    Timer->Start(); 
    hr = pMediaControl->Run(); 
    if (FAILED(hr)) 
    { 
     OAFilterState State; 
     hr = pMediaControl->GetState(1000, &State);  
     if ((SUCCEEDED(hr) && State != State_Running) || FAILED(hr)) 
     { 
      return FailedToStartGraph; 
     } 
    } 
    CurrentState = Streaming; 
    SetVMRSize(); 
    Timer->Stop(); 
    RunTime->Start(); 
    FrameRate->Reset(); 

    return NoError; 

:注目すべき

void KontronGraph::SetVMRSize() 
{ 
    if (CurrentState == Disconnected || VideoMode != ParentWindow) 
     return; 
    long lWidth, lHeight; 
    HRESULT hr = pWindowController->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL); 
    if (SUCCEEDED(hr)) 
    { 
     RECT rcSrc, rcDest; 
     // Set the source rectangle. 
     rcSrc.left = 0; 
     rcSrc.right = lWidth; 
     rcSrc.top = 0; 
     rcSrc.bottom = lHeight; 

     // Get the window client area. 
     GetClientRect(MyHwnd, &rcDest); 
     // Set the destination rectangle. 
     rcDest.right = rcDest.right - rcDest.left; 
     rcDest.bottom = rcDest.bottom - rcDest.top; 
     rcDest.left = 0; 
     rcDest.top = 0; 

     // Set the video position. 
     hr = pWindowController->SetVideoPosition(&rcSrc, &rcDest); 
    } 
} 

を、pWindowControllerはIVMRWindowlessControl9あるとpMediaControlはIMediaControl

です編集2

CreateThを使用してコードをテストしました。 __beginthreadexの代わりに読み取ります。スレッドを起動するために失敗した後、GetLastError関数は、()を返します。

8:ない十分なストレージが プロセス、このコマンドに使用可能です。

HANDLE worker_thread = CreateThread(0, 
Thread_Stack_Size, worker_thread_op, thread_param, 0, 0); 

のCreateThreadのためのパラメータの一部:

スレッドを作成するためのコードがどのように見えるで起動するには

Thread_Stack_Size = 1024 * 1024; 
typedef DWORD (WINAPI *worker_thread_op_type)(LPVOID params); 
+0

ビデオRAMで実行している可能性はありますか? – StefanE

答えて

2

、私はあなたがしてCreateThread_beginthreadexを交換していることを示唆していますGetLastErrorを使用してエラーの原因を特定します。これは、多くの場合、_beginthreadexで設定されたCRTエラーコードよりも具体的です。あなたがこれを行うことであなたが観察していることを私に教えてください。私は私の答えを更新します。

また、スレッド作成を失敗させる(DirectShow)コードの部分、およびスレッドを作成するコード行をポストできますか?

アップデート:具体的なエラーに関しては、メモリリークの可能性があります。 420MBだけがであり、となる可能性がありますが、それ以上のページはと予約されている可能性があります。これらのページはアプリケーションの2GBの仮想空間の上限にカウントされます。 DirectShowグラフを実行すると、この領域の残りの部分が使い果たされた可能性があります。

したがって、DirectShow自体がエラーの原因ではなく、代わりにアプリケーションの既存のエラーを明らかにする可能性があります。

ここではあなたに関連するかもしれないMSDNからいくつかの追加情報は、あなたが以前にあなたのプログラム(Thread Stack Size)の他のスレッドを作成した場合は特に、です:

それぞれの新しいスレッドは両方とも予約からなる独自のスタック領域を受け取り、最初にコミットされたメモリ。予約されたメモリサイズは、仮想メモリ内のスタックの合計割り当てを表します。したがって、予約サイズは仮想アドレス範囲に制限されます。最初にコミットされたページは、参照されるまで物理メモリを利用しません。 ...スレッドが終了すると、スタックは解放されます。スレッドが別のスレッドによって終了されても解放されません。

+0

DirectShowコードを追加しました。テストしたらすぐにCreateThreadに関するコメントを追加します。 – DeusAduro

+0

私はCreateThreadテストの結果を追加しました。また、DirectShowグラフはメインアプリケーションの別個のDLLにあります。私はこの問題にどのように追加できるのか分かりませんが、言及する価値はあると思いました。 – DeusAduro

0

sysinternals-web-pagesには、メモリがどのように使用され、どのように使用されるかを扱う多数のビデオがあります。あなたの問題にあなたを助けることができるかもしれません。

http://technet.microsoft.com/en-us/sysinternals/bb963887

http://player.microsoftpdc.com/Session/1689962d-dea2-48bd-80d8-96e954fa5329

http://player.microsoftpdc.com/Session/1c97b279-d7e3-4a3e-9a76-0dac23dfddb5

これはあなたを助けることを願っています。

0

これは問題であるかどうかはわかりませんが、ほとんどのDirectX関連ツール(DirectShowが含まれていると仮定します)では、関連する呼び出しがすべて同じスレッドで発生することを確認する必要があります;言い換えれば、あるスレッドでDirectShowを設定した場合、その同じスレッドを使用してすべての呼び出しを行います。 DirectShowを使用して以来、これは長い時間がかかりました。これが当てはまると100%肯定的ではありませんが、密接に関連する技術であるD3Dの多くの問題を確実に解決します。

FWIW。

+0

こんにちは、これはDirectShowに当てはまると思いますが、私はすでにこれを行っています(すべてのDS呼び出しは、作成された同じスレッド内で呼び出されます)。しかし、入力をありがとう。 – DeusAduro

関連する問題