简体   繁体   English

LibAv / FFMpeg的线程安全性?

[英]Thread Safety of LibAv/FFMpeg?

Is LibAV/FFMpeg thread safe? LibAV / FFMpeg线程安全吗? 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? 我可以在一个线程中使用AVFormatContext *从一个文件中读取并通过简单添加的互斥量将读取数据包解码到另一个文件中,或者是“不知道不关心”类型交易的库的线程安全性吗? 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. 我知道libav对编码器线程有基本的支持,但我正在尝试更多的黑盒类型方法,我把它分解成多个线程(源 - >解码器 - >过滤器 - >编码器 - >接收器)并试图了解并发症这样的。

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. 任何对ffmpeg和线程有任何经验的人都希望与任何其他与此相关的信息相互关联,也将非常感激。

You can register your own lock manager. 您可以注册自己的锁管理器。 The ffmpeg library will control thread safety. ffmpeg库将控制线程安全性。

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;

} }

To expand on the existing answer: 扩展现有答案:

ffmpeg's av_lockmgr_register is the way to deal with locking. ffmpeg的av_lockmgr_register是处理锁定的方法。

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. 带有线程的ffmpeg构建(以及比LIBAVCODEC_VERSION_MAJOR 55更高版本,LIBAVCODEC_VERSION_MINOR 38和LIBAVCODEC_VERSION_MICRO 100 - 大约在2013年10月左右,请参阅ffmpeg commit添加默认lockmgr )将具有您可以使用的默认锁定管理器。

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. 如果您需要与libav兼容(在撰写本文时,2016年9月),这还没有默认的锁定管理器,您需要提供自己的。

Here is a pure C pthread's implementation: 这是一个纯C pthread的实现:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM