func: int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
  
  {
  
      PerThreadContext *p = avctx->thread_opaque;
  
      int *progress, err;
  
  
  
      f->owner = avctx;
  
  
  
      ff_init_buffer_info(avctx, f);
  
  
  
      if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
  
          f->thread_opaque = NULL;
  
          return avctx->get_buffer(avctx, f);
  
      }
  
  
  
      if (p->state != STATE_SETTING_UP &&
  
          (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks &&
  
                  avctx->get_buffer != avcodec_default_get_buffer))) {
  
          av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
  
          return -1;
  
      }
  
  
  
      pthread_mutex_lock(&p->parent->buffer_mutex);
  
      f->thread_opaque = progress = allocate_progress(p);
  
  
  
      if (!progress) {
  
          pthread_mutex_unlock(&p->parent->buffer_mutex);
  
          return -1;
  
      }
  
  
  
      progress[0] =
  
      progress[1] = -1;
  
  
  
      if (avctx->thread_safe_callbacks ||
  
          avctx->get_buffer == avcodec_default_get_buffer) {
  
          err = avctx->get_buffer(avctx, f);
  
      } else {
  
          p->requested_frame = f;
  
          p->state = STATE_GET_BUFFER;
  
          pthread_mutex_lock(&p->progress_mutex);
  
          pthread_cond_signal(&p->progress_cond);
  
  
  
          while (p->state != STATE_SETTING_UP)
  
              pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
  
  
  
          err = p->result;
  
  
  
          pthread_mutex_unlock(&p->progress_mutex);
  
  
  
          if (!avctx->codec->update_thread_context)
  
              ff_thread_finish_setup(avctx);
  
      }
  
  
  
      pthread_mutex_unlock(&p->parent->buffer_mutex);
  
  
  
      return err;
  
  }
  