40 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) 
   41 #define QSV_HAVE_USER_PLUGIN    !QSV_ONEVPL 
   42 #define QSV_HAVE_AUDIO          !QSV_ONEVPL 
   44 #if QSV_HAVE_USER_PLUGIN 
   45 #include <mfxplugin.h> 
   49 #include <mfxdispatcher.h> 
   51 #define MFXUnload(a) do { } while(0) 
   60         return MFX_CODEC_HEVC;
 
   63         return MFX_CODEC_MPEG2;
 
   69         return MFX_CODEC_JPEG;
 
   72 #if QSV_VERSION_ATLEAST(1, 34) 
   76 #if QSV_VERSION_ATLEAST(2, 11) 
   92     {MFX_IOPATTERN_IN_VIDEO_MEMORY,     
"input is video memory surface"         },
 
   93     {MFX_IOPATTERN_IN_SYSTEM_MEMORY,    
"input is system memory surface"        },
 
   95     {MFX_IOPATTERN_IN_OPAQUE_MEMORY,    
"input is opaque memory surface"        },
 
   97     {MFX_IOPATTERN_OUT_VIDEO_MEMORY,    
"output is video memory surface"        },
 
   98     {MFX_IOPATTERN_OUT_SYSTEM_MEMORY,   
"output is system memory surface"       },
 
  100     {MFX_IOPATTERN_OUT_OPAQUE_MEMORY,   
"output is opaque memory surface"       },
 
  105                            const char *extra_string)
 
  115         desc = 
"unknown iopattern";
 
  121 static const struct {
 
  126     { MFX_ERR_NONE,                     0,               
"success"                              },
 
  128     { MFX_ERR_NULL_PTR,                 
AVERROR(EINVAL), 
"NULL pointer"                         },
 
  129     { MFX_ERR_UNSUPPORTED,              
AVERROR(ENOSYS), 
"unsupported"                          },
 
  130     { MFX_ERR_MEMORY_ALLOC,             
AVERROR(ENOMEM), 
"failed to allocate memory"            },
 
  131     { MFX_ERR_NOT_ENOUGH_BUFFER,        
AVERROR(ENOMEM), 
"insufficient input/output buffer"     },
 
  132     { MFX_ERR_INVALID_HANDLE,           
AVERROR(EINVAL), 
"invalid handle"                       },
 
  133     { MFX_ERR_LOCK_MEMORY,              
AVERROR(EIO),    
"failed to lock the memory block"      },
 
  134     { MFX_ERR_NOT_INITIALIZED,          
AVERROR_BUG,     
"not initialized"                      },
 
  135     { MFX_ERR_NOT_FOUND,                
AVERROR(ENOSYS), 
"specified object was not found"       },
 
  139     { MFX_ERR_MORE_SURFACE,             
AVERROR_UNKNOWN, 
"expect more surface at output"        },
 
  140     { MFX_ERR_MORE_BITSTREAM,           
AVERROR_UNKNOWN, 
"expect more bitstream at output"      },
 
  142     { MFX_ERR_DEVICE_LOST,              
AVERROR(EIO),    
"device lost"                          },
 
  143     { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM, 
AVERROR(EINVAL), 
"incompatible video parameters"        },
 
  144     { MFX_ERR_INVALID_VIDEO_PARAM,      
AVERROR(EINVAL), 
"invalid video parameters"             },
 
  145     { MFX_ERR_UNDEFINED_BEHAVIOR,       
AVERROR_BUG,     
"undefined behavior"                   },
 
  146     { MFX_ERR_DEVICE_FAILED,            
AVERROR(EIO),    
"device failed"                        },
 
  148     { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM, 
AVERROR(EINVAL), 
"incompatible audio parameters"        },
 
  149     { MFX_ERR_INVALID_AUDIO_PARAM,      
AVERROR(EINVAL), 
"invalid audio parameters"             },
 
  151     { MFX_ERR_GPU_HANG,                 
AVERROR(EIO),    
"GPU Hang"                             },
 
  152     { MFX_ERR_REALLOC_SURFACE,          
AVERROR_UNKNOWN, 
"need bigger surface for output"       },
 
  154     { MFX_WRN_IN_EXECUTION,             0,               
"operation in execution"               },
 
  155     { MFX_WRN_DEVICE_BUSY,              0,               
"device busy"                          },
 
  156     { MFX_WRN_VIDEO_PARAM_CHANGED,      0,               
"video parameters changed"             },
 
  157     { MFX_WRN_PARTIAL_ACCELERATION,     0,               
"partial acceleration"                 },
 
  158     { MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, 0,               
"incompatible video parameters"        },
 
  159     { MFX_WRN_VALUE_NOT_CHANGED,        0,               
"value is saturated"                   },
 
  160     { MFX_WRN_OUT_OF_RANGE,             0,               
"value out of range"                   },
 
  161     { MFX_WRN_FILTER_SKIPPED,           0,               
"filter skipped"                       },
 
  163     { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0,               
"incompatible audio parameters"        },
 
  166 #if QSV_VERSION_ATLEAST(1, 31) 
  167     { MFX_ERR_NONE_PARTIAL_OUTPUT,      0,               
"partial output"                       },
 
  185         *
desc = 
"unknown error";
 
  190                        const char *error_string)
 
  199                          const char *warning_string)
 
  219 #if QSV_VERSION_ATLEAST(1, 31) 
  234         *
fourcc = MFX_FOURCC_NV12;
 
  239         *
fourcc = MFX_FOURCC_P010;
 
  243         *
fourcc = MFX_FOURCC_A2RGB10;
 
  247         *
fourcc = MFX_FOURCC_RGB4;
 
  252         *
fourcc = MFX_FOURCC_YUY2;
 
  257         *
fourcc = MFX_FOURCC_Y210;
 
  261         *
fourcc = MFX_FOURCC_AYUV;
 
  265         *
fourcc = MFX_FOURCC_Y410;
 
  268 #if QSV_VERSION_ATLEAST(1, 31) 
  270         *
fourcc = MFX_FOURCC_P016;
 
  274         *
fourcc = MFX_FOURCC_Y216;
 
  278         *
fourcc = MFX_FOURCC_Y416;
 
  289     switch (
frame->format) {
 
  293         surface->Data.Y  = 
frame->data[0];
 
  294         surface->Data.UV = 
frame->data[1];
 
  296         surface->Data.V  = surface->Data.UV + 1;
 
  300         surface->Data.B = 
frame->data[0];
 
  301         surface->Data.G = 
frame->data[0] + 1;
 
  302         surface->Data.R = 
frame->data[0] + 2;
 
  303         surface->Data.A = 
frame->data[0] + 3;
 
  306         surface->Data.Y = 
frame->data[0];
 
  307         surface->Data.U = 
frame->data[0] + 1;
 
  308         surface->Data.V = 
frame->data[0] + 3;
 
  313         surface->Data.Y16 = (mfxU16 *)
frame->data[0];
 
  314         surface->Data.U16 = (mfxU16 *)
frame->data[0] + 1;
 
  315         surface->Data.V16 = (mfxU16 *)
frame->data[0] + 3;
 
  319         surface->Data.V = 
frame->data[0];
 
  320         surface->Data.U = 
frame->data[0] + 1;
 
  321         surface->Data.Y = 
frame->data[0] + 2;
 
  324         surface->Data.A = 
frame->data[0] + 3;
 
  328         surface->Data.U = 
frame->data[0];
 
  332         surface->Data.U = 
frame->data[0];
 
  333         surface->Data.Y = 
frame->data[0] + 2;
 
  334         surface->Data.V = 
frame->data[0] + 4;
 
  337         surface->Data.A = 
frame->data[0] + 6;
 
  343     surface->Data.PitchLow  = 
frame->linesize[0];
 
  351     for (
i = 0; 
i < 
ctx->nb_mids; 
i++) {
 
  353         mfxHDLPair *pair = (mfxHDLPair*)
frame->surface.Data.MemId;
 
  364     switch (mfx_pic_struct & 0xF) {
 
  365     case MFX_PICSTRUCT_PROGRESSIVE:
 
  368     case MFX_PICSTRUCT_FIELD_TFF:
 
  371     case MFX_PICSTRUCT_FIELD_BFF:
 
  382     switch (mfx_pic_type & 0x7) {
 
  383     case MFX_FRAMETYPE_I:
 
  384         if (mfx_pic_type & MFX_FRAMETYPE_S)
 
  389     case MFX_FRAMETYPE_B:
 
  392     case MFX_FRAMETYPE_P:
 
  393         if (mfx_pic_type & MFX_FRAMETYPE_S)
 
  398     case MFX_FRAMETYPE_UNKNOWN:
 
  411 #if QSV_HAVE_USER_PLUGIN 
  412     if (!load_plugins || !*load_plugins)
 
  415     while (*load_plugins) {
 
  423         if (strlen(plugin) != 2 * 
sizeof(
uid.Data)) {
 
  426             goto load_plugin_fail;
 
  429         for (
i = 0; 
i < 
sizeof(
uid.Data); 
i++) {
 
  430             err = sscanf(plugin + 2 * 
i, 
"%2hhx", 
uid.Data + 
i);
 
  434                 goto load_plugin_fail;
 
  439         ret = MFXVideoUSER_Load(session, &
uid, 1);
 
  442             snprintf(errorbuf, 
sizeof(errorbuf),
 
  443                      "Could not load the requested plugin '%s'", plugin);
 
  445             goto load_plugin_fail;
 
  464 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE 
  471     av_dict_set(&child_device_opts, 
"vendor_id", 
"0x8086", 0);
 
  472     av_dict_set(&child_device_opts, 
"driver",    
"iHD",    0);
 
  481         hwctx = qs->va_device_ctx->hwctx;
 
  484                 (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)hwctx->
display);
 
  492 #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE 
  496                               mfxIMPL implementation,
 
  501     mfxLoader loader = 
NULL;
 
  503     mfxVariant impl_value = {0};
 
  512     cfg = MFXCreateConfig(loader);
 
  518     impl_value.Type = MFX_VARIANT_TYPE_U32;
 
  519     impl_value.Data.U32 = (implementation == MFX_IMPL_SOFTWARE) ?
 
  520         MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE;
 
  521     sts = MFXSetConfigFilterProperty(cfg,
 
  522                                      (
const mfxU8 *)
"mfxImplDescription.Impl", impl_value);
 
  523     if (sts != MFX_ERR_NONE) {
 
  525                "property: %d\n", sts);
 
  529     impl_value.Type = MFX_VARIANT_TYPE_U32;
 
  530     impl_value.Data.U32 = pver->Version;
 
  531     sts = MFXSetConfigFilterProperty(cfg,
 
  532                                      (
const mfxU8 *)
"mfxImplDescription.ApiVersion.Version",
 
  534     if (sts != MFX_ERR_NONE) {
 
  536                "property: %d\n", sts);
 
  552 static int qsv_create_mfx_session_from_loader(
void *
ctx, mfxLoader loader, mfxSession *psession)
 
  555     mfxSession session = 
NULL;
 
  556     uint32_t impl_idx = 0;
 
  560         mfxImplDescription *impl_desc;
 
  562         sts = MFXEnumImplementations(loader, impl_idx,
 
  563                                      MFX_IMPLCAPS_IMPLDESCSTRUCTURE,
 
  564                                      (mfxHDL *)&impl_desc);
 
  566         if (sts == MFX_ERR_NOT_FOUND)
 
  568         else if (sts != MFX_ERR_NONE) {
 
  573         sts = MFXCreateSession(loader, impl_idx, &session);
 
  574         MFXDispReleaseImplDescription(loader, impl_desc);
 
  575         if (sts == MFX_ERR_NONE)
 
  581     if (sts != MFX_ERR_NONE) {
 
  599                                   mfxIMPL implementation,
 
  602                                   mfxSession *psession,
 
  605     mfxLoader loader = 
NULL;
 
  608     if (*ploader == 
NULL) {
 
  610                "Use Intel(R) oneVPL to create MFX session, the required " 
  611                "implementation version is %d.%d\n",
 
  612                pver->Major, pver->Minor);
 
  614         if (qsv_new_mfx_loader(avctx, implementation, pver, (
void **)&loader))
 
  620                "Use Intel(R) oneVPL to create MFX session with the specified MFX loader\n");
 
  625     if (qsv_create_mfx_session_from_loader(avctx, loader, psession))
 
  634     if (!*ploader && loader)
 
  643                                   mfxIMPL implementation,
 
  646                                   mfxSession *psession,
 
  649     mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
 
  650     mfxSession session = 
NULL;
 
  654            "Use Intel(R) Media SDK to create MFX session, the required " 
  655            "implementation version is %d.%d\n",
 
  656            pver->Major, pver->Minor);
 
  661     init_par.GPUCopy = gpu_copy;
 
  662     init_par.Implementation = implementation;
 
  663     init_par.Version = *pver;
 
  664     sts = MFXInitEx(init_par, &session);
 
  667                                   "Error initializing a MFX session");
 
  670                              "Warning in MFX initialization");
 
  682                                  const char *load_plugins, 
int gpu_copy)
 
  686         MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11,
 
  707                    "supported, try next mfx implementation.\n");
 
  710 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE 
  711     ret = ff_qsv_set_display_handle(avctx, qs);
 
  723     if (
ret != MFX_ERR_NONE)
 
  725                                   "Error querying the session attributes");
 
  727     switch (MFX_IMPL_BASETYPE(impl)) {
 
  728     case MFX_IMPL_SOFTWARE:
 
  731     case MFX_IMPL_HARDWARE:
 
  732     case MFX_IMPL_HARDWARE2:
 
  733     case MFX_IMPL_HARDWARE3:
 
  734     case MFX_IMPL_HARDWARE4:
 
  735         desc = 
"hardware accelerated";
 
  742            "Initialized an internal MFX session using %s implementation\n",
 
  758     int                  nb_surfaces = frames_hwctx->nb_surfaces;
 
  775     for (
i = 0; 
i < nb_surfaces; 
i++) {
 
  777         mid->
handle_pair   = (mfxHDLPair*)frames_hwctx->surfaces[
i].Data.MemId;
 
  789     int                  nb_surfaces = frames_hwctx->nb_surfaces;
 
  795     resp->mids = 
av_calloc(nb_surfaces + 2, 
sizeof(*resp->mids));
 
  799     for (
i = 0; 
i < nb_surfaces; 
i++)
 
  800         resp->mids[
i] = &mids[
i];
 
  801     resp->NumFrameActual = nb_surfaces;
 
  803     resp->mids[resp->NumFrameActual] = (mfxMemId)
av_buffer_ref(hw_frames_ref);
 
  804     if (!resp->mids[resp->NumFrameActual]) {
 
  815                                  mfxFrameAllocResponse *resp)
 
  822     if (!(req->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET |
 
  823                        MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))         ||
 
  824         !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)))
 
  825         return MFX_ERR_UNSUPPORTED;
 
  827     if (req->Type & MFX_MEMTYPE_EXTERNAL_FRAME) {
 
  831         mfxFrameInfo      *
i  = &req->Info;
 
  834         if (!frames_hwctx->nb_surfaces) {
 
  836                    "Dynamic frame pools, no frame is pre-allocated\n");
 
  841         i1 = &frames_hwctx->surfaces[0].Info;
 
  842         if (
i->Width  > i1->Width  || 
i->Height > i1->Height ||
 
  843             i->FourCC != i1->FourCC || 
i->ChromaFormat != i1->ChromaFormat) {
 
  845                    "allocation request: %dx%d %d %d vs %dx%d %d %d\n",
 
  846                    i->Width,  
i->Height,  
i->FourCC,  
i->ChromaFormat,
 
  847                    i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat);
 
  848             return MFX_ERR_UNSUPPORTED;
 
  854                    "Error filling an external frame allocation request\n");
 
  855             return MFX_ERR_MEMORY_ALLOC;
 
  857     } 
else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) {
 
  861         mfxFrameInfo      *
i  = &req->Info;
 
  868         if (!ext_frames_hwctx->nb_surfaces)
 
  869             return MFX_ERR_UNSUPPORTED;
 
  873             return MFX_ERR_MEMORY_ALLOC;
 
  876         frames_hwctx = frames_ctx->hwctx;
 
  880         frames_ctx->width             = 
i->Width;
 
  881         frames_ctx->height            = 
i->Height;
 
  882         frames_ctx->initial_pool_size = req->NumFrameSuggested;
 
  884         frames_hwctx->frame_type      = req->Type;
 
  889                    "Error initializing a frames context for an internal frame " 
  890                    "allocation request\n");
 
  892             return MFX_ERR_MEMORY_ALLOC;
 
  898             return MFX_ERR_MEMORY_ALLOC;
 
  906                    "Error filling an internal frame allocation request\n");
 
  907             return MFX_ERR_MEMORY_ALLOC;
 
  910         return MFX_ERR_UNSUPPORTED;
 
  937     if (!frames_hwctx->nb_surfaces)
 
  938         return MFX_ERR_UNSUPPORTED;
 
  942     hw_frames_hwctx = hw_frames_ctx->hwctx;
 
  943     if (qsv_mid->locked_frame)
 
  944         return MFX_ERR_UNDEFINED_BEHAVIOR;
 
  948     if (!qsv_mid->locked_frame)
 
  949         return MFX_ERR_MEMORY_ALLOC;
 
  950     qsv_mid->locked_frame->format  = hw_frames_ctx->sw_format;
 
  954     if (!qsv_mid->hw_frame)
 
  957     qsv_mid->hw_frame->data[3] = (uint8_t*)&qsv_mid->surf;
 
  962     if (!qsv_mid->hw_frame->buf[0])
 
  965     qsv_mid->hw_frame->width   = hw_frames_ctx->width;
 
  966     qsv_mid->hw_frame->height  = hw_frames_ctx->height;
 
  968     qsv_mid->hw_frame->hw_frames_ctx = 
av_buffer_ref(qsv_mid->hw_frames_ref);
 
  969     if (!qsv_mid->hw_frame->hw_frames_ctx)
 
  972     qsv_mid->surf.Info = hw_frames_hwctx->surfaces[0].Info;
 
  973     qsv_mid->surf.Data.MemId = qsv_mid->handle_pair;
 
  981     ptr->Pitch = qsv_mid->locked_frame->linesize[0];
 
  982     ptr->Y     = qsv_mid->locked_frame->data[0];
 
  983     ptr->U     = qsv_mid->locked_frame->data[1];
 
  984     ptr->V     = qsv_mid->locked_frame->data[1] + 1;
 
  990     return MFX_ERR_MEMORY_ALLOC;
 
 1000     if (!frames_hwctx->nb_surfaces)
 
 1001         return MFX_ERR_UNSUPPORTED;
 
 1007     return MFX_ERR_NONE;
 
 1015     mfxHDLPair *pair_dst = (mfxHDLPair*)hdl;
 
 1016     mfxHDLPair *pair_src;
 
 1018     if (frames_hwctx->nb_surfaces) {
 
 1022         pair_src = (mfxHDLPair*)mid;
 
 1025     pair_dst->first = pair_src->first;
 
 1027     if (pair_src->second != (mfxMemId)MFX_INFINITE)
 
 1028         pair_dst->second = pair_src->second;
 
 1029     return MFX_ERR_NONE;
 
 1033                                AVBufferRef *device_ref, 
const char *load_plugins,
 
 1038     mfxSession        parent_session = device_hwctx->session;
 
 1039     void                     *loader = device_hwctx->loader;
 
 1040     mfxHDL                    handle = 
NULL;
 
 1041     int          hw_handle_supported = 0;
 
 1046     mfxHandleType handle_type;
 
 1050     err = MFXQueryIMPL(parent_session, &impl);
 
 1051     if (err == MFX_ERR_NONE)
 
 1052         err = MFXQueryVersion(parent_session, &ver);
 
 1053     if (err != MFX_ERR_NONE)
 
 1055                                   "Error querying the session attributes");
 
 1058         handle_type = MFX_HANDLE_VA_DISPLAY;
 
 1059         hw_handle_supported = 1;
 
 1061         handle_type = MFX_HANDLE_D3D11_DEVICE;
 
 1062         hw_handle_supported = 1;
 
 1064         handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
 
 1065         hw_handle_supported = 1;
 
 1068     if (hw_handle_supported) {
 
 1069         err = MFXVideoCORE_GetHandle(parent_session, handle_type, &handle);
 
 1070         if (err != MFX_ERR_NONE) {
 
 1072                                   "Error getting handle session");
 
 1077                "from the session\n");
 
 1086         err = MFXVideoCORE_SetHandle(session, handle_type, handle);
 
 1087         if (err != MFX_ERR_NONE)
 
 1089                                       "Error setting a HW handle");
 
 1093         err = MFXJoinSession(parent_session, session);
 
 1094         if (err != MFX_ERR_NONE)
 
 1096                                       "Error joining session");
 
 1105     *psession = session;
 
 1111                                const char *load_plugins, 
int opaque, 
int gpu_copy)
 
 1113     mfxFrameAllocator frame_allocator = {
 
 1114         .pthis  = qsv_frames_ctx,
 
 1131                                      frames_ctx->
device_ref, load_plugins, gpu_copy);
 
 1136         qsv_frames_ctx->
logctx = avctx;
 
 1141         if (frames_hwctx->nb_surfaces) {
 
 1144             if (!qsv_frames_ctx->
mids)
 
 1146             qsv_frames_ctx->
nb_mids = frames_hwctx->nb_surfaces;
 
 1149         err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator);
 
 1150         if (err != MFX_ERR_NONE)
 
 1152                                       "Error setting a frame allocator");
 
 1155     *psession = session;
 
 1171 #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE 
 1178                                  mfxExtBuffer * param)
 
 1182     for (
i = 0; 
i < 
frame->num_ext_params; 
i++) {
 
 1183         mfxExtBuffer *ext_buffer = 
frame->ext_param[
i];
 
 1185         if (ext_buffer->BufferId == param->BufferId) {
 
 1193         frame->ext_param[
frame->num_ext_params] = param;
 
 1194         frame->num_ext_params++;
 
 1195         frame->surface.Data.NumExtParam = 
frame->num_ext_params;
 
 1198                "have enough space\n");