6

LibAV/FFMpeg はスレッドセーフですか? 例えば。あるスレッドで AVFormatContext* を使用してファイルから読み取り、読み取りパケットを別のスレッドで単純にミューテックスを追加してデコードできますか、それともライブラリのスレッドの安全性は「わからない、気にしない」タイプの取引ですか? libav がエンコーダー スレッドの基本的なサポートを持っていることは知っていますが、複数のスレッド (ソース -> デコーダー -> フィルター -> エンコーダー -> シンク) に分割するブラックボックス タイプのアプローチを試し、複雑さを理解しようとしています。そのようなの。

ffmpeg とスレッドの経験があり、これに関連するその他の情報を教えていただけると幸いです。

4

2 に答える 2

8

独自のロック マネージャーを登録できます。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;

}

于 2012-12-15T22:08:06.787 に答える
3

既存の回答を拡張するには:

ffmpeg の av_lockmgr_register は、ロックを処理する方法です。

スレッドを使用した ffmpeg ビルド (および LIBAVCODEC_VERSION_MAJOR 55、LIBAVCODEC_VERSION_MINOR 38、および LIBAVCODEC_VERSION_MICRO 100 より後のバージョン - およそ 2013 年 10月頃、デフォルトの lockmgr を追加する ffmpeg commit を参照) には、使用できるデフォルトのロック マネージャーがあります。

libav との互換性が必要な場合 (2016 年 9 月の執筆時点)、これにはまだデフォルトのロックマネージャーがなく、独自のものを提供する必要があります。

以下は、純粋な 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;
}

次のように登録されます。

ret = av_lockmgr_register(ffmpeg_lockmgr_cb);
if (ret < 0)
{
    fprintf(stderr, "av_lockmgr_register failed (%d)\n", ret);
    abort();
}
于 2016-09-30T07:58:25.027 に答える