5

I have a c++-cli code that is capturing videos from a folder in opencv using capture and then retrieving frames using cvquery frame. I then process frames and once all frames are processed i release the capture. It works fine but when I try to multithread it gives me a warning and cannot capture some of the videos in the folder with warning " insufficient thread locking around avcodec_open/close()".

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

    while(1)
    {
        img=cvqueryframe(capture) 

        if !img break;
        ///process img
    }

    cvreleasecapture(&capture);
}

Is there a way to fix the problem for multithreading? I was thinking of using

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

but there should a more efficient way, maybe using locking Monitor::Enter(obj) or lock(obj)?

fmvpsenior
  • 197
  • 7
  • 22
  • 1
    Take a look at [this](http://code.opencv.org/issues/1369) and [this](http://code.opencv.org/issues/1006) – Mohammad Aug 17 '12 at 19:41
  • I had a similar message when opening 2 videowriters in 2 different threads. Apparently the opening and closing of the writers is not threadsafe. Try adding a delay between starting and closing your threads. – diip_thomas Aug 31 '12 at 16:32

1 Answers1

10

The open and close functions in avcodec are not thread safe. To prevent issues in multi-threaded apps they have a simple mechanism that detects when two threads are inside these functions at the same time and when that happens they write the "insufficient thread locking" message.

The way to prevent this message is to lock the calls to cvCreateFileCapture and cvreleasecapture (which in turn call avcodec_open and avcodec_close) to ensure that these calls are always serialized. For example, if you had a mutex class called Mutex you could do something like this:

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();
}

There are many Mutex implementations. On Linux or OS X you can use pthread mutexes. On Windows you can use Win32 mutexes.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Thanks for your detailed answer. I'm not very familiar with mutex, but I believe it comes with the boost library? If I want to use the lock(obj) or Monitor::Enter(obj) found in http://stackoverflow.com/questions/1369459/cs-lock-in-managed-c what would be obj? – fmvpsenior Sep 04 '12 at 16:10
  • You can certainly use the mutex classes in boost. You want to look at boost::mutex for the lock itself and boost::lock_guard or boost::unique_lock for operating the lock. – Miguel Grinberg Sep 05 '12 at 00:16
  • The C++ Monitor class can also be used if you are using managed code. The "obj" argument to the Enter() and Exit() functions is the .NET object that you want to lock, so for example this could be the object in your the code you pasted above lives. Note this has to be a .NET object, not a C++ object. It really doesn't matter what object you lock, what matters is that you always use the same object in all the Enter/Exit calls, because these locks are specific to an object. Your code will be more readable if you go with a C++ mutex, in my opinion. – Miguel Grinberg Sep 05 '12 at 00:16
  • for locking purpose you should have a private object that its value won't changed and its better to use it for locking for example you can have `System::Object^ oLock = gcnew System::Object()` and this use `System::Threading::Monitor::Enter(oLock);` and `System::Threading::Monitor::Exit(oLock);` in place of `mutex` and this approach is much better in managed code, because using a mutex or any native object in managed code would have a performance penalty – BigBoss Sep 06 '12 at 00:18
  • 1
    You can use `av_lockmgr_register` to register your own lock mechanism, or compile the `libav`/`ffmpeg` with `--enable-pthreads`, although I'm not sure if this last one will work on windows. – Rhythmic Fistman Aug 19 '15 at 01:28