5

キャプチャを使用してopencvのフォルダーからビデオをキャプチャし、cvqueryフレームを使用してフレームを取得するc++-cliコードがあります。次にフレームを処理し、すべてのフレームが処理されたらキャプチャを解放します。正常に動作しますが、マルチスレッドを実行しようとすると警告が表示され、「avcodec_open / close()周辺のスレッドロックが不十分です」という警告とともにフォルダー内の一部のビデオをキャプチャできません。

//for each video in folder do
{
    capture=cvCreateFileCapture(filename);

    while(1)
    {
        img=cvqueryframe(capture) 

        if !img break;
        ///process img
    }

    cvreleasecapture(&capture);
}

マルチスレッドの問題を修正する方法はありますか?使うことを考えていました

while(!capture) 
    capture=cvCreateFileCapture(filename);

しかし、もっと効率的な方法があるはずです。おそらく、Monitor :: Enter(obj)またはlock(obj)をロックすることを使用しますか?

4

1 に答える 1

10

avcodecのopenand関数はスレッドセーフではありません。closeマルチスレッドアプリでの問題を防ぐために、2つのスレッドがこれらの関数内に同時にあることを検出し、それが発生したときに「不十分なスレッドロック」メッセージを書き込む単純なメカニズムがあります。

このメッセージを防ぐ方法は、とへの呼び出しをロックしてcvCreateFileCapturecvreleasecapture次に、とを呼び出しavcodec_openavcodec_close)、これらの呼び出しが常にシリアル化されるようにすることです。たとえば、Mutexというミューテックスクラスがある場合は、次のようにすることができます。

extern Mutex m; // application-wide mutex

//for each video in folder do
{
    m.lock();
    capture=cvCreateFileCapture(filename);
    m.unlock();

    while(1)
    {
        img=cvqueryframe(capture) 

        if !img break;
        ///process img
    }

    m.lock();
    cvreleasecapture(&capture);
    m.unlock();
}

多くのMutexの実装があります。LinuxまたはOSXでは、 pthreadミューテックスを使用できます。Windowsでは、 Win32ミューテックスを使用できます。

于 2012-09-03T07:19:54.907 に答える