Потокобезопасность LibAv / FFMpeg?

Является ли LibAV / FFMpeg поток безопасным? Например. Могу ли я прочитать файл, используя AVFormatContext * в одном потоке, и декодировать прочитанный пакет в другом с простыми добавлениями мьютексов, или безопасность потоков библиотеки является соглашением типа «не знаю, не важно»? Я знаю, что libav имеет базовую поддержку потоков кодировщика, но я пробую больше подхода типа черного ящика, где я делю его на несколько потоков (Source -> Decoder -> Filter -> Encoder -> Sink) и пытаюсь понять сложности из таких.

Любой, кто имеет опыт работы с ffmpeg и потоками и хотел бы присоединиться к любой другой информации, относящейся к этому, также был бы очень признателен.

4

Решение

Вы можете зарегистрировать свой собственный менеджер блокировки. Библиотека ffmpeg будет контролировать безопасность потоков.

Пример:

 ::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;

}

7

Другие решения

Чтобы расширить существующий ответ:

av_lockmgr_register — это способ борьбы с блокировками.

Сборка ffmpeg с потоками (и более поздней версией, чем LIBAVCODEC_VERSION_MAJOR 55, LIBAVCODEC_VERSION_MINOR 38 и LIBAVCODEC_VERSION_MICRO 100 — примерно в октябре 2013 года, см. ffmpeg фиксирует добавление по умолчанию lockmgr) будет иметь менеджер блокировок по умолчанию, который вы можете просто использовать.

Если вам требуется совместимость с libav, то (на момент написания, сентябрь 2016 г.) у него еще не было диспетчера блокировки по умолчанию, и вам нужно предоставить свой собственный.

Вот чистая реализация Cpthread:

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

который зарегистрирован так:

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

По вопросам рекламы [email protected]