Discussion:
[Libav-user] FFmpeg thread safety
Ole Andre Birkedal
2014-08-11 10:39:02 UTC
Permalink
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.

Does there exist an exhausting list of all the function that are not
thread safe?

- Ole Andre Birkedal
wm4
2014-08-18 21:10:30 UTC
Permalink
On Mon, 11 Aug 2014 12:39:02 +0200
Post by Ole Andre Birkedal
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.
Does there exist an exhausting list of all the function that are not
thread safe?
All of them.
Patrick Dehne
2014-08-18 21:22:02 UTC
Permalink
Post by wm4
On Mon, 11 Aug 2014 12:39:02 +0200
Post by Ole Andre Birkedal
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.
Does there exist an exhausting list of all the function that are not
thread safe?
All of them.
You may want to take a look at the documentation of av_lockmgr_register.
wm4
2014-08-18 21:30:07 UTC
Permalink
On Mon, 18 Aug 2014 23:22:02 +0200
Post by Patrick Dehne
Post by wm4
On Mon, 11 Aug 2014 12:39:02 +0200
Post by Ole Andre Birkedal
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.
Does there exist an exhausting list of all the function that are not
thread safe?
All of them.
You may want to take a look at the documentation of av_lockmgr_register.
All functions that are specific to a certain context (like
AVCodecContext) are by default not thread-safe. Of course using
different contexts at the same time from different threads should be
perfectly fine.

However, many codecs use some global data that is usually constant, but
needs to be initialized once. That's why av_lockmgr_register() exists.
It's a very messy way to allocate mutexes that are supposed to
coordinate this initialization.

However, at least FFmpeg (not Libav) doesn't require this anymore, if
you have compiled ffmpeg with threading. It may even be safer not to
use the lock manager stuff, because then you avoid library-safety
issues.
J Decker
2014-08-19 08:09:44 UTC
Permalink
Post by wm4
All functions that are specific to a certain context (like
AVCodecContext) are by default not thread-safe. Of course using
different contexts at the same time from different threads should be
perfectly fine.
However, many codecs use some global data that is usually constant, but
needs to be initialized once. That's why av_lockmgr_register() exists.
It's a very messy way to allocate mutexes that are supposed to
coordinate this initialization.
So if I have lots of videos, and want to play multiple videos at the same
time, using separate contexts for each is OK? Or is it not OK because the
codecs use globals?
Or I have to put critical sections around every call to the library suite?
A semi-off-topic question? Why does avcodec-56 allocate so many threads?
Why does it need any more threads than the thread I call a decode with?

In the example code, decoding audio and video in separate threads didn't
require locks? What if I have a thread per video and play 32 on the screen
at once?
Post by wm4
However, at least FFmpeg (not Libav) doesn't require this anymore, if
you have compiled ffmpeg with threading. It may even be safer not to
use the lock manager stuff, because then you avoid library-safety
issues.
_______________________________________________
Libav-user mailing list
http://ffmpeg.org/mailman/listinfo/libav-user
wm4
2014-08-19 17:36:34 UTC
Permalink
On Tue, 19 Aug 2014 01:09:44 -0700
Post by J Decker
Post by wm4
All functions that are specific to a certain context (like
AVCodecContext) are by default not thread-safe. Of course using
different contexts at the same time from different threads should be
perfectly fine.
However, many codecs use some global data that is usually constant, but
needs to be initialized once. That's why av_lockmgr_register() exists.
It's a very messy way to allocate mutexes that are supposed to
coordinate this initialization.
So if I have lots of videos, and want to play multiple videos at the same
time, using separate contexts for each is OK? Or is it not OK because the
codecs use globals?
The globals are things like huge tables, which are constant, but it's
easier/smaller to initialize them at startup, instead of hardcoding
them into the binary. So, on opening the codec context, these tables
are initialized (if they aren't already).

So it should be ok, as long as initialization doesn't go wrong.

Supporting threads is a huge mess, partly because ffmpeg supports many
legacy architectures. The "lock manager" stuff was probably meant to
allow the user to plugin exotic threading APIs (pure non-sense if you
ask me). Now there's a default "lock manager". It's usually enabled by
default, but AFAIK depends on threading support within ffmpeg. So make
sure you didn't accidentally disable threading.

If you're using Libav (the ffmpeg fork shipped with Ubuntu, Debian),
or if you're using an ancient version of ffmpeg, be aware that it won't
have that default lock manager.

Functions like avcodec_register_all() still need to be synchronized.
Post by J Decker
Or I have to put critical sections around every call to the library suite?
No, you just have to synchronize access to each context. Generally,
ffmpeg code do any locking for the user. (It only does locking to
coordinate internal threads, not more.)
Post by J Decker
A semi-off-topic question? Why does avcodec-56 allocate so many threads?
Why does it need any more threads than the thread I call a decode with?
libavcodec supports multithreaded decoding. I forgot, maybe it's
default now?
Post by J Decker
In the example code, decoding audio and video in separate threads didn't
require locks? What if I have a thread per video and play 32 on the screen
at once?
That should work fine.
John Orr
2014-08-20 15:32:12 UTC
Permalink
Post by Patrick Dehne
Post by wm4
On Mon, 11 Aug 2014 12:39:02 +0200
Post by Ole Andre Birkedal
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.
Does there exist an exhausting list of all the function that are not
thread safe?
All of them.
You may want to take a look at the documentation of av_lockmgr_register.
Certain ffmpeg open and close functions need to be serialized across all
threads.

These include avformat_open_input/avformat_close_input and
avcodec_open/avcodec_close.

By default ffmpeg assumes your app is single threaded and doesn't need
locking, so the underlying "locks" are no-ops. There is a function,
av_lockmgr_register, that allows the app to provide your locking mechanism.

The docs for avcodec_open/close and avformat_open/close_input do not
mention av_lockmgr_register. It wasn't until I looked through ffmpeg
source code and found the no-op locking mechanism that I found out about
av_lockmgr_register. That gave me something to google for, so I found
some discussions about it, like this one:


http://stackoverflow.com/questions/13888915/thread-safety-of-libav-ffmpeg


--Johno
wm4
2014-08-20 16:42:14 UTC
Permalink
On Wed, 20 Aug 2014 11:32:12 -0400
Post by John Orr
Post by Patrick Dehne
Post by wm4
On Mon, 11 Aug 2014 12:39:02 +0200
Post by Ole Andre Birkedal
Hi.
I'm currently developing a multithreaded C++ program using std::thread.
Recently I have been having some crashing issues and it all seems to
related non-thread safety of some function in the FFmpeg API.
Does there exist an exhausting list of all the function that are not
thread safe?
All of them.
You may want to take a look at the documentation of av_lockmgr_register.
Certain ffmpeg open and close functions need to be serialized across all
threads.
These include avformat_open_input/avformat_close_input and
avcodec_open/avcodec_close.
By default ffmpeg assumes your app is single threaded and doesn't need
locking, so the underlying "locks" are no-ops. There is a function,
av_lockmgr_register, that allows the app to provide your locking mechanism.
The docs for avcodec_open/close and avformat_open/close_input do not
mention av_lockmgr_register. It wasn't until I looked through ffmpeg
source code and found the no-op locking mechanism that I found out about
av_lockmgr_register. That gave me something to google for, so I found
Like I mentioned in the other email, as long as ffmpeg is compiled with
threading, and is recent enough, a default "lock manager" is set.
Post by John Orr
http://stackoverflow.com/questions/13888915/thread-safety-of-libav-ffmpeg
--Johno
_______________________________________________
Libav-user mailing list
http://ffmpeg.org/mailman/listinfo/libav-user
Loading...