Thread Safety of LibAv/FFMpeg?

北城余情 提交于 2021-01-21 04:49:26

问题


Is LibAV/FFMpeg thread safe? For example. Could i read from a file using AVFormatContext* in one thread and decode the read packet it in another with simple additions of mutexes or is the thread safetyness of the library a "don't know don't care" type deal? I know that libav has basic support for encoder threads but i'm trying more of a blackbox type approach where i break it up into multiple threads (Source -> Decoder -> Filter -> Encoder -> Sink) and trying to understand the complications of such.

Anyone with any experience with ffmpeg and threads and would like to chime in with any other info pertinent to this would also be greatly appreciated.


回答1:


You can register your own lock manager. The ffmpeg library will control thread safety.

Example:

 ::av_lockmgr_register(&my_lockmgr_cb);


 //// ..........

 int my_lockmgr_cb(void **mutex, enum AVLockOp op)
 {
  if (NULL == mutex)
   return -1;

   switch(op)
   {
   case AV_LOCK_CREATE:
   {
    *mutex = NULL;
    boost::mutex * m = new boost::mutex();
    *mutex = static_cast<void*>(m);
    break;
   }
   case AV_LOCK_OBTAIN:
   {
    boost::mutex * m =  static_cast<boost::mutex*>(*mutex);
    m->lock();
    break;
   }
   case AV_LOCK_RELEASE:
   {
    boost::mutex * m = static_cast<boost::mutex*>(*mutex);
    m->unlock();
    break;
   }
   case AV_LOCK_DESTROY:
   {
    boost::mutex * m = static_cast<boost::mutex*>(*mutex);
    delete m;
    break;
   }
   default:
   break;
}
return 0;

}




回答2:


To expand on the existing answer:

ffmpeg's av_lockmgr_register is the way to deal with locking.

An ffmpeg build with threads (and a later version than LIBAVCODEC_VERSION_MAJOR 55, LIBAVCODEC_VERSION_MINOR 38 and LIBAVCODEC_VERSION_MICRO 100 - roughly about October 2013, see ffmpeg commit adding default lockmgr) will have a default lock manager that you can just use.

If you need to be compatible with libav then (at the time of writing, September 2016) this does not yet have a default lock manager and you need to provide your own.

Here is a pure C pthread's implementation:

static int ffmpeg_lockmgr_cb(void **arg, enum AVLockOp op)
{
    pthread_mutex_t *mutex = *arg;
    int err;

    switch (op) {
    case AV_LOCK_CREATE:
        mutex = malloc(sizeof(*mutex));
        if (!mutex)
            return AVERROR(ENOMEM);
        if ((err = pthread_mutex_init(mutex, NULL))) {
            free(mutex);
            return AVERROR(err);
        }
        *arg = mutex;
        return 0;
    case AV_LOCK_OBTAIN:
        if ((err = pthread_mutex_lock(mutex)))
            return AVERROR(err);

        return 0;
    case AV_LOCK_RELEASE:
        if ((err = pthread_mutex_unlock(mutex)))
            return AVERROR(err);

        return 0;
    case AV_LOCK_DESTROY:
        if (mutex)
            pthread_mutex_destroy(mutex);
        free(mutex);
        *arg = NULL;
        return 0;
    }
    return 1;
}

which is registered like so:

ret = av_lockmgr_register(ffmpeg_lockmgr_cb);
if (ret < 0)
{
    fprintf(stderr, "av_lockmgr_register failed (%d)\n", ret);
    abort();
}


来源:https://stackoverflow.com/questions/13888915/thread-safety-of-libav-ffmpeg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!