func: static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)
  
  {
  
      const AVPixFmtDescriptor *desc;
  
      mfxSession session = NULL;
  
      int iopattern = 0;
  
      mfxVideoParam param = { { 0 } };
  
      int frame_width  = avctx->coded_width;
  
      int frame_height = avctx->coded_height;
  
      int ret;
  
  
  
      desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
  
      if (!desc)
  
          return AVERROR_BUG;
  
  
  
      if (!q->async_fifo) {
  
          q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
  
                                        (sizeof(mfxSyncPoint*) + sizeof(QSVFrame*)));
  
          if (!q->async_fifo)
  
              return AVERROR(ENOMEM);
  
      }
  
  
  
      if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) {
  
          AVQSVContext *user_ctx = avctx->hwaccel_context;
  
          session           = user_ctx->session;
  
          iopattern         = user_ctx->iopattern;
  
          q->ext_buffers    = user_ctx->ext_buffers;
  
          q->nb_ext_buffers = user_ctx->nb_ext_buffers;
  
      }
  
  
  
      if (avctx->hw_frames_ctx) {
  
          AVHWFramesContext    *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
  
          AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
  
  
  
          if (!iopattern) {
  
              if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
  
                  iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
  
              else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
  
                  iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
  
          }
  
  
  
          frame_width  = frames_hwctx->surfaces[0].Info.Width;
  
          frame_height = frames_hwctx->surfaces[0].Info.Height;
  
      }
  
  
  
      if (!iopattern)
  
          iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
  
      q->iopattern = iopattern;
  
  
  
      ret = qsv_init_session(avctx, q, session, avctx->hw_frames_ctx);
  
      if (ret < 0) {
  
          av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
  
          return ret;
  
      }
  
  
  
      ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
  
      if (ret < 0)
  
          return ret;
  
  
  
      param.mfx.CodecId      = ret;
  
      param.mfx.CodecProfile = avctx->profile;
  
      param.mfx.CodecLevel   = avctx->level;
  
  
  
      param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
  
      param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
  
      param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
  
      param.mfx.FrameInfo.FourCC         = q->fourcc;
  
      param.mfx.FrameInfo.Width          = frame_width;
  
      param.mfx.FrameInfo.Height         = frame_height;
  
      param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
  
  
  
      param.IOPattern   = q->iopattern;
  
      param.AsyncDepth  = q->async_depth;
  
      param.ExtParam    = q->ext_buffers;
  
      param.NumExtParam = q->nb_ext_buffers;
  
  
  
      ret = MFXVideoDECODE_Init(q->session, &param);
  
      if (ret < 0)
  
          return ff_qsv_print_error(avctx, ret,
  
                                    "Error initializing the MFX video decoder");
  
  
  
      q->frame_info = param.mfx.FrameInfo;
  
  
  
      return 0;
  
  }
  