0006-dlopen-libva.patch 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884
  1. From 95ebc0ad912447ba83cacb197f506b881f82179e Mon Sep 17 00:00:00 2001
  2. From: 21pages <sunboeasy@gmail.com>
  3. Date: Tue, 10 Dec 2024 15:29:21 +0800
  4. Subject: [PATCH 1/2] dlopen libva
  5. Signed-off-by: 21pages <sunboeasy@gmail.com>
  6. ---
  7. libavcodec/vaapi_decode.c | 96 ++++++-----
  8. libavcodec/vaapi_encode.c | 173 ++++++++++---------
  9. libavcodec/vaapi_encode_h264.c | 3 +-
  10. libavcodec/vaapi_encode_h265.c | 6 +-
  11. libavutil/hwcontext_vaapi.c | 292 ++++++++++++++++++++++++---------
  12. libavutil/hwcontext_vaapi.h | 96 +++++++++++
  13. 6 files changed, 477 insertions(+), 189 deletions(-)
  14. diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
  15. index a59194340f..e202b673f4 100644
  16. --- a/libavcodec/vaapi_decode.c
  17. +++ b/libavcodec/vaapi_decode.c
  18. @@ -38,17 +38,18 @@ int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
  19. size_t size)
  20. {
  21. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  22. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  23. VAStatus vas;
  24. VABufferID buffer;
  25. av_assert0(pic->nb_param_buffers + 1 <= MAX_PARAM_BUFFERS);
  26. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  27. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  28. type, size, 1, (void*)data, &buffer);
  29. if (vas != VA_STATUS_SUCCESS) {
  30. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
  31. "buffer (type %d): %d (%s).\n",
  32. - type, vas, vaErrorStr(vas));
  33. + type, vas, vaf->vaErrorStr(vas));
  34. return AVERROR(EIO);
  35. }
  36. @@ -69,6 +70,7 @@ int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
  37. size_t slice_size)
  38. {
  39. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  40. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  41. VAStatus vas;
  42. int index;
  43. @@ -88,13 +90,13 @@ int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
  44. index = 2 * pic->nb_slices;
  45. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  46. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  47. VASliceParameterBufferType,
  48. params_size, nb_params, (void*)params_data,
  49. &pic->slice_buffers[index]);
  50. if (vas != VA_STATUS_SUCCESS) {
  51. av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
  52. - "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
  53. + "parameter buffer: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  54. return AVERROR(EIO);
  55. }
  56. @@ -102,15 +104,15 @@ int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
  57. "is %#x.\n", pic->nb_slices, params_size,
  58. pic->slice_buffers[index]);
  59. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  60. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  61. VASliceDataBufferType,
  62. slice_size, 1, (void*)slice_data,
  63. &pic->slice_buffers[index + 1]);
  64. if (vas != VA_STATUS_SUCCESS) {
  65. av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
  66. "data buffer (size %zu): %d (%s).\n",
  67. - slice_size, vas, vaErrorStr(vas));
  68. - vaDestroyBuffer(ctx->hwctx->display,
  69. + slice_size, vas, vaf->vaErrorStr(vas));
  70. + vaf->vaDestroyBuffer(ctx->hwctx->display,
  71. pic->slice_buffers[index]);
  72. return AVERROR(EIO);
  73. }
  74. @@ -127,26 +129,27 @@ static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx,
  75. VAAPIDecodePicture *pic)
  76. {
  77. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  78. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  79. VAStatus vas;
  80. int i;
  81. for (i = 0; i < pic->nb_param_buffers; i++) {
  82. - vas = vaDestroyBuffer(ctx->hwctx->display,
  83. + vas = vaf->vaDestroyBuffer(ctx->hwctx->display,
  84. pic->param_buffers[i]);
  85. if (vas != VA_STATUS_SUCCESS) {
  86. av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
  87. "parameter buffer %#x: %d (%s).\n",
  88. - pic->param_buffers[i], vas, vaErrorStr(vas));
  89. + pic->param_buffers[i], vas, vaf->vaErrorStr(vas));
  90. }
  91. }
  92. for (i = 0; i < 2 * pic->nb_slices; i++) {
  93. - vas = vaDestroyBuffer(ctx->hwctx->display,
  94. + vas = vaf->vaDestroyBuffer(ctx->hwctx->display,
  95. pic->slice_buffers[i]);
  96. if (vas != VA_STATUS_SUCCESS) {
  97. av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice "
  98. "slice buffer %#x: %d (%s).\n",
  99. - pic->slice_buffers[i], vas, vaErrorStr(vas));
  100. + pic->slice_buffers[i], vas, vaf->vaErrorStr(vas));
  101. }
  102. }
  103. }
  104. @@ -155,6 +158,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
  105. VAAPIDecodePicture *pic)
  106. {
  107. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  108. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  109. VAStatus vas;
  110. int err;
  111. @@ -166,37 +170,37 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
  112. av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
  113. pic->output_surface);
  114. - vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  115. + vas = vaf->vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  116. pic->output_surface);
  117. if (vas != VA_STATUS_SUCCESS) {
  118. av_log(avctx, AV_LOG_ERROR, "Failed to begin picture decode "
  119. - "issue: %d (%s).\n", vas, vaErrorStr(vas));
  120. + "issue: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  121. err = AVERROR(EIO);
  122. goto fail_with_picture;
  123. }
  124. - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  125. + vas = vaf->vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  126. pic->param_buffers, pic->nb_param_buffers);
  127. if (vas != VA_STATUS_SUCCESS) {
  128. av_log(avctx, AV_LOG_ERROR, "Failed to upload decode "
  129. - "parameters: %d (%s).\n", vas, vaErrorStr(vas));
  130. + "parameters: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  131. err = AVERROR(EIO);
  132. goto fail_with_picture;
  133. }
  134. - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  135. + vas = vaf->vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  136. pic->slice_buffers, 2 * pic->nb_slices);
  137. if (vas != VA_STATUS_SUCCESS) {
  138. av_log(avctx, AV_LOG_ERROR, "Failed to upload slices: "
  139. - "%d (%s).\n", vas, vaErrorStr(vas));
  140. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  141. err = AVERROR(EIO);
  142. goto fail_with_picture;
  143. }
  144. - vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
  145. + vas = vaf->vaEndPicture(ctx->hwctx->display, ctx->va_context);
  146. if (vas != VA_STATUS_SUCCESS) {
  147. av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
  148. - "issue: %d (%s).\n", vas, vaErrorStr(vas));
  149. + "issue: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  150. err = AVERROR(EIO);
  151. if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
  152. AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS)
  153. @@ -213,10 +217,10 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
  154. goto exit;
  155. fail_with_picture:
  156. - vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
  157. + vas = vaf->vaEndPicture(ctx->hwctx->display, ctx->va_context);
  158. if (vas != VA_STATUS_SUCCESS) {
  159. av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
  160. - "after error: %d (%s).\n", vas, vaErrorStr(vas));
  161. + "after error: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  162. }
  163. fail:
  164. ff_vaapi_decode_destroy_buffers(avctx, pic);
  165. @@ -304,6 +308,7 @@ static int vaapi_decode_find_best_format(AVCodecContext *avctx,
  166. AVHWFramesContext *frames)
  167. {
  168. AVVAAPIDeviceContext *hwctx = device->hwctx;
  169. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  170. VAStatus vas;
  171. VASurfaceAttrib *attr;
  172. enum AVPixelFormat source_format, best_format, format;
  173. @@ -313,11 +318,11 @@ static int vaapi_decode_find_best_format(AVCodecContext *avctx,
  174. source_format = avctx->sw_pix_fmt;
  175. av_assert0(source_format != AV_PIX_FMT_NONE);
  176. - vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
  177. + vas = vaf->vaQuerySurfaceAttributes(hwctx->display, config_id,
  178. NULL, &nb_attr);
  179. if (vas != VA_STATUS_SUCCESS) {
  180. av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
  181. - "%d (%s).\n", vas, vaErrorStr(vas));
  182. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  183. return AVERROR(ENOSYS);
  184. }
  185. @@ -325,11 +330,11 @@ static int vaapi_decode_find_best_format(AVCodecContext *avctx,
  186. if (!attr)
  187. return AVERROR(ENOMEM);
  188. - vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
  189. + vas = vaf->vaQuerySurfaceAttributes(hwctx->display, config_id,
  190. attr, &nb_attr);
  191. if (vas != VA_STATUS_SUCCESS) {
  192. av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
  193. - "%d (%s).\n", vas, vaErrorStr(vas));
  194. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  195. av_freep(&attr);
  196. return AVERROR(ENOSYS);
  197. }
  198. @@ -471,6 +476,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
  199. AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
  200. AVVAAPIDeviceContext *hwctx = device->hwctx;
  201. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  202. codec_desc = avcodec_descriptor_get(avctx->codec_id);
  203. if (!codec_desc) {
  204. @@ -478,7 +484,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
  205. goto fail;
  206. }
  207. - profile_count = vaMaxNumProfiles(hwctx->display);
  208. + profile_count = vaf->vaMaxNumProfiles(hwctx->display);
  209. profile_list = av_malloc_array(profile_count,
  210. sizeof(VAProfile));
  211. if (!profile_list) {
  212. @@ -486,11 +492,11 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
  213. goto fail;
  214. }
  215. - vas = vaQueryConfigProfiles(hwctx->display,
  216. + vas = vaf->vaQueryConfigProfiles(hwctx->display,
  217. profile_list, &profile_count);
  218. if (vas != VA_STATUS_SUCCESS) {
  219. av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
  220. - "%d (%s).\n", vas, vaErrorStr(vas));
  221. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  222. err = AVERROR(ENOSYS);
  223. goto fail;
  224. }
  225. @@ -550,12 +556,12 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
  226. }
  227. }
  228. - vas = vaCreateConfig(hwctx->display, matched_va_profile,
  229. + vas = vaf->vaCreateConfig(hwctx->display, matched_va_profile,
  230. VAEntrypointVLD, NULL, 0,
  231. va_config);
  232. if (vas != VA_STATUS_SUCCESS) {
  233. av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
  234. - "configuration: %d (%s).\n", vas, vaErrorStr(vas));
  235. + "configuration: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  236. err = AVERROR(EIO);
  237. goto fail;
  238. }
  239. @@ -638,7 +644,7 @@ fail:
  240. av_hwframe_constraints_free(&constraints);
  241. av_freep(&hwconfig);
  242. if (*va_config != VA_INVALID_ID) {
  243. - vaDestroyConfig(hwctx->display, *va_config);
  244. + vaf->vaDestroyConfig(hwctx->display, *va_config);
  245. *va_config = VA_INVALID_ID;
  246. }
  247. av_freep(&profile_list);
  248. @@ -651,12 +657,14 @@ int ff_vaapi_common_frame_params(AVCodecContext *avctx,
  249. AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
  250. AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
  251. AVVAAPIDeviceContext *hwctx;
  252. + VAAPIDynLoadFunctions *vaf;
  253. VAConfigID va_config = VA_INVALID_ID;
  254. int err;
  255. if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
  256. return AVERROR(EINVAL);
  257. hwctx = device_ctx->hwctx;
  258. + vaf = hwctx->funcs;
  259. err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
  260. hw_frames_ctx);
  261. @@ -664,7 +672,7 @@ int ff_vaapi_common_frame_params(AVCodecContext *avctx,
  262. return err;
  263. if (va_config != VA_INVALID_ID)
  264. - vaDestroyConfig(hwctx->display, va_config);
  265. + vaf->vaDestroyConfig(hwctx->display, va_config);
  266. return 0;
  267. }
  268. @@ -672,6 +680,7 @@ int ff_vaapi_common_frame_params(AVCodecContext *avctx,
  269. int ff_vaapi_decode_init(AVCodecContext *avctx)
  270. {
  271. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  272. + VAAPIDynLoadFunctions *vaf;
  273. VAStatus vas;
  274. int err;
  275. @@ -686,13 +695,18 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
  276. ctx->hwfc = ctx->frames->hwctx;
  277. ctx->device = ctx->frames->device_ctx;
  278. ctx->hwctx = ctx->device->hwctx;
  279. + if (!ctx->hwctx || !ctx->hwctx->funcs) {
  280. + err = AVERROR(EINVAL);
  281. + goto fail;
  282. + }
  283. + vaf = ctx->hwctx->funcs;
  284. err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
  285. &ctx->va_config, NULL);
  286. if (err)
  287. goto fail;
  288. - vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
  289. + vas = vaf->vaCreateContext(ctx->hwctx->display, ctx->va_config,
  290. avctx->coded_width, avctx->coded_height,
  291. VA_PROGRESSIVE,
  292. ctx->hwfc->surface_ids,
  293. @@ -700,7 +714,7 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
  294. &ctx->va_context);
  295. if (vas != VA_STATUS_SUCCESS) {
  296. av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
  297. - "context: %d (%s).\n", vas, vaErrorStr(vas));
  298. + "context: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  299. err = AVERROR(EIO);
  300. goto fail;
  301. }
  302. @@ -718,22 +732,28 @@ fail:
  303. int ff_vaapi_decode_uninit(AVCodecContext *avctx)
  304. {
  305. VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
  306. + VAAPIDynLoadFunctions *vaf = NULL;
  307. VAStatus vas;
  308. + if (ctx->hwctx && ctx->hwctx->funcs)
  309. + vaf = ctx->hwctx->funcs;
  310. + if (!vaf)
  311. + return 0;
  312. +
  313. if (ctx->va_context != VA_INVALID_ID) {
  314. - vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  315. + vas = vaf->vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  316. if (vas != VA_STATUS_SUCCESS) {
  317. av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
  318. "context %#x: %d (%s).\n",
  319. - ctx->va_context, vas, vaErrorStr(vas));
  320. + ctx->va_context, vas, vaf->vaErrorStr(vas));
  321. }
  322. }
  323. if (ctx->va_config != VA_INVALID_ID) {
  324. - vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  325. + vas = vaf->vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  326. if (vas != VA_STATUS_SUCCESS) {
  327. av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
  328. "configuration %#x: %d (%s).\n",
  329. - ctx->va_config, vas, vaErrorStr(vas));
  330. + ctx->va_config, vas, vaf->vaErrorStr(vas));
  331. }
  332. }
  333. diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
  334. index 16a9a364f0..ccf6fa59d6 100644
  335. --- a/libavcodec/vaapi_encode.c
  336. +++ b/libavcodec/vaapi_encode.c
  337. @@ -43,6 +43,7 @@ static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
  338. int type, char *data, size_t bit_len)
  339. {
  340. VAAPIEncodeContext *ctx = avctx->priv_data;
  341. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  342. VAStatus vas;
  343. VABufferID param_buffer, data_buffer;
  344. VABufferID *tmp;
  345. @@ -57,24 +58,24 @@ static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
  346. return AVERROR(ENOMEM);
  347. pic->param_buffers = tmp;
  348. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  349. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  350. VAEncPackedHeaderParameterBufferType,
  351. sizeof(params), 1, &params, &param_buffer);
  352. if (vas != VA_STATUS_SUCCESS) {
  353. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  354. "for packed header (type %d): %d (%s).\n",
  355. - type, vas, vaErrorStr(vas));
  356. + type, vas, vaf->vaErrorStr(vas));
  357. return AVERROR(EIO);
  358. }
  359. pic->param_buffers[pic->nb_param_buffers++] = param_buffer;
  360. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  361. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  362. VAEncPackedHeaderDataBufferType,
  363. (bit_len + 7) / 8, 1, data, &data_buffer);
  364. if (vas != VA_STATUS_SUCCESS) {
  365. av_log(avctx, AV_LOG_ERROR, "Failed to create data buffer "
  366. "for packed header (type %d): %d (%s).\n",
  367. - type, vas, vaErrorStr(vas));
  368. + type, vas, vaf->vaErrorStr(vas));
  369. return AVERROR(EIO);
  370. }
  371. pic->param_buffers[pic->nb_param_buffers++] = data_buffer;
  372. @@ -89,6 +90,7 @@ static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
  373. int type, char *data, size_t len)
  374. {
  375. VAAPIEncodeContext *ctx = avctx->priv_data;
  376. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  377. VAStatus vas;
  378. VABufferID *tmp;
  379. VABufferID buffer;
  380. @@ -98,11 +100,11 @@ static int vaapi_encode_make_param_buffer(AVCodecContext *avctx,
  381. return AVERROR(ENOMEM);
  382. pic->param_buffers = tmp;
  383. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  384. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  385. type, len, 1, data, &buffer);
  386. if (vas != VA_STATUS_SUCCESS) {
  387. av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer "
  388. - "(type %d): %d (%s).\n", type, vas, vaErrorStr(vas));
  389. + "(type %d): %d (%s).\n", type, vas, vaf->vaErrorStr(vas));
  390. return AVERROR(EIO);
  391. }
  392. pic->param_buffers[pic->nb_param_buffers++] = buffer;
  393. @@ -141,6 +143,7 @@ static int vaapi_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_
  394. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  395. #endif
  396. VAAPIEncodeContext *ctx = avctx->priv_data;
  397. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  398. VAAPIEncodePicture *pic = base_pic->priv;
  399. VAStatus vas;
  400. @@ -156,22 +159,22 @@ static int vaapi_encode_wait(AVCodecContext *avctx, FFHWBaseEncodePicture *base_
  401. base_pic->encode_order, pic->input_surface);
  402. #if VA_CHECK_VERSION(1, 9, 0)
  403. - if (base_ctx->async_encode) {
  404. - vas = vaSyncBuffer(ctx->hwctx->display,
  405. + if (base_ctx->async_encode && vaf->vaSyncBuffer) {
  406. + vas = vaf->vaSyncBuffer(ctx->hwctx->display,
  407. pic->output_buffer,
  408. VA_TIMEOUT_INFINITE);
  409. if (vas != VA_STATUS_SUCCESS) {
  410. av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer completion: "
  411. - "%d (%s).\n", vas, vaErrorStr(vas));
  412. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  413. return AVERROR(EIO);
  414. }
  415. } else
  416. #endif
  417. { // If vaSyncBuffer is not implemented, try old version API.
  418. - vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
  419. + vas = vaf->vaSyncSurface(ctx->hwctx->display, pic->input_surface);
  420. if (vas != VA_STATUS_SUCCESS) {
  421. av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
  422. - "%d (%s).\n", vas, vaErrorStr(vas));
  423. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  424. return AVERROR(EIO);
  425. }
  426. }
  427. @@ -270,6 +273,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
  428. {
  429. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  430. VAAPIEncodeContext *ctx = avctx->priv_data;
  431. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  432. VAAPIEncodePicture *pic = base_pic->priv;
  433. VAAPIEncodeSlice *slice;
  434. VAStatus vas;
  435. @@ -587,28 +591,28 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
  436. }
  437. #endif
  438. - vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  439. + vas = vaf->vaBeginPicture(ctx->hwctx->display, ctx->va_context,
  440. pic->input_surface);
  441. if (vas != VA_STATUS_SUCCESS) {
  442. av_log(avctx, AV_LOG_ERROR, "Failed to begin picture encode issue: "
  443. - "%d (%s).\n", vas, vaErrorStr(vas));
  444. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  445. err = AVERROR(EIO);
  446. goto fail_with_picture;
  447. }
  448. - vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  449. + vas = vaf->vaRenderPicture(ctx->hwctx->display, ctx->va_context,
  450. pic->param_buffers, pic->nb_param_buffers);
  451. if (vas != VA_STATUS_SUCCESS) {
  452. av_log(avctx, AV_LOG_ERROR, "Failed to upload encode parameters: "
  453. - "%d (%s).\n", vas, vaErrorStr(vas));
  454. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  455. err = AVERROR(EIO);
  456. goto fail_with_picture;
  457. }
  458. - vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
  459. + vas = vaf->vaEndPicture(ctx->hwctx->display, ctx->va_context);
  460. if (vas != VA_STATUS_SUCCESS) {
  461. av_log(avctx, AV_LOG_ERROR, "Failed to end picture encode issue: "
  462. - "%d (%s).\n", vas, vaErrorStr(vas));
  463. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  464. err = AVERROR(EIO);
  465. // vaRenderPicture() has been called here, so we should not destroy
  466. // the parameter buffers unless separate destruction is required.
  467. @@ -622,12 +626,12 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
  468. if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
  469. AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {
  470. for (i = 0; i < pic->nb_param_buffers; i++) {
  471. - vas = vaDestroyBuffer(ctx->hwctx->display,
  472. + vas = vaf->vaDestroyBuffer(ctx->hwctx->display,
  473. pic->param_buffers[i]);
  474. if (vas != VA_STATUS_SUCCESS) {
  475. av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
  476. "param buffer %#x: %d (%s).\n",
  477. - pic->param_buffers[i], vas, vaErrorStr(vas));
  478. + pic->param_buffers[i], vas, vaf->vaErrorStr(vas));
  479. // And ignore.
  480. }
  481. }
  482. @@ -636,10 +640,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
  483. return 0;
  484. fail_with_picture:
  485. - vaEndPicture(ctx->hwctx->display, ctx->va_context);
  486. + vaf->vaEndPicture(ctx->hwctx->display, ctx->va_context);
  487. fail:
  488. for(i = 0; i < pic->nb_param_buffers; i++)
  489. - vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
  490. + vaf->vaDestroyBuffer(ctx->hwctx->display, pic->param_buffers[i]);
  491. if (pic->slices) {
  492. for (i = 0; i < pic->nb_slices; i++)
  493. av_freep(&pic->slices[i].codec_slice_params);
  494. @@ -657,16 +661,17 @@ fail_at_end:
  495. static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID buf_id)
  496. {
  497. VAAPIEncodeContext *ctx = avctx->priv_data;
  498. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  499. VACodedBufferSegment *buf_list, *buf;
  500. int size = 0;
  501. VAStatus vas;
  502. int err;
  503. - vas = vaMapBuffer(ctx->hwctx->display, buf_id,
  504. + vas = vaf->vaMapBuffer(ctx->hwctx->display, buf_id,
  505. (void**)&buf_list);
  506. if (vas != VA_STATUS_SUCCESS) {
  507. av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
  508. - "%d (%s).\n", vas, vaErrorStr(vas));
  509. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  510. err = AVERROR(EIO);
  511. return err;
  512. }
  513. @@ -674,10 +679,10 @@ static int vaapi_encode_get_coded_buffer_size(AVCodecContext *avctx, VABufferID
  514. for (buf = buf_list; buf; buf = buf->next)
  515. size += buf->size;
  516. - vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
  517. + vas = vaf->vaUnmapBuffer(ctx->hwctx->display, buf_id);
  518. if (vas != VA_STATUS_SUCCESS) {
  519. av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
  520. - "%d (%s).\n", vas, vaErrorStr(vas));
  521. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  522. err = AVERROR(EIO);
  523. return err;
  524. }
  525. @@ -689,15 +694,16 @@ static int vaapi_encode_get_coded_buffer_data(AVCodecContext *avctx,
  526. VABufferID buf_id, uint8_t **dst)
  527. {
  528. VAAPIEncodeContext *ctx = avctx->priv_data;
  529. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  530. VACodedBufferSegment *buf_list, *buf;
  531. VAStatus vas;
  532. int err;
  533. - vas = vaMapBuffer(ctx->hwctx->display, buf_id,
  534. + vas = vaf->vaMapBuffer(ctx->hwctx->display, buf_id,
  535. (void**)&buf_list);
  536. if (vas != VA_STATUS_SUCCESS) {
  537. av_log(avctx, AV_LOG_ERROR, "Failed to map output buffers: "
  538. - "%d (%s).\n", vas, vaErrorStr(vas));
  539. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  540. err = AVERROR(EIO);
  541. return err;
  542. }
  543. @@ -710,10 +716,10 @@ static int vaapi_encode_get_coded_buffer_data(AVCodecContext *avctx,
  544. *dst += buf->size;
  545. }
  546. - vas = vaUnmapBuffer(ctx->hwctx->display, buf_id);
  547. + vas = vaf->vaUnmapBuffer(ctx->hwctx->display, buf_id);
  548. if (vas != VA_STATUS_SUCCESS) {
  549. av_log(avctx, AV_LOG_ERROR, "Failed to unmap output buffers: "
  550. - "%d (%s).\n", vas, vaErrorStr(vas));
  551. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  552. err = AVERROR(EIO);
  553. return err;
  554. }
  555. @@ -936,6 +942,7 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  556. {
  557. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  558. VAAPIEncodeContext *ctx = avctx->priv_data;
  559. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  560. VAProfile *va_profiles = NULL;
  561. VAEntrypoint *va_entrypoints = NULL;
  562. VAStatus vas;
  563. @@ -977,16 +984,16 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  564. av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n",
  565. desc->name);
  566. - n = vaMaxNumProfiles(ctx->hwctx->display);
  567. + n = vaf->vaMaxNumProfiles(ctx->hwctx->display);
  568. va_profiles = av_malloc_array(n, sizeof(VAProfile));
  569. if (!va_profiles) {
  570. err = AVERROR(ENOMEM);
  571. goto fail;
  572. }
  573. - vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
  574. + vas = vaf->vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n);
  575. if (vas != VA_STATUS_SUCCESS) {
  576. av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n",
  577. - vas, vaErrorStr(vas));
  578. + vas, vaf->vaErrorStr(vas));
  579. err = AVERROR_EXTERNAL;
  580. goto fail;
  581. }
  582. @@ -1007,7 +1014,7 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  583. continue;
  584. #if VA_CHECK_VERSION(1, 0, 0)
  585. - profile_string = vaProfileStr(profile->va_profile);
  586. + profile_string = vaf->vaProfileStr(profile->va_profile);
  587. #else
  588. profile_string = "(no profile names)";
  589. #endif
  590. @@ -1037,18 +1044,18 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  591. av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
  592. profile_string, ctx->va_profile);
  593. - n = vaMaxNumEntrypoints(ctx->hwctx->display);
  594. + n = vaf->vaMaxNumEntrypoints(ctx->hwctx->display);
  595. va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint));
  596. if (!va_entrypoints) {
  597. err = AVERROR(ENOMEM);
  598. goto fail;
  599. }
  600. - vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
  601. + vas = vaf->vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile,
  602. va_entrypoints, &n);
  603. if (vas != VA_STATUS_SUCCESS) {
  604. av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for "
  605. "profile %s (%d): %d (%s).\n", profile_string,
  606. - ctx->va_profile, vas, vaErrorStr(vas));
  607. + ctx->va_profile, vas, vaf->vaErrorStr(vas));
  608. err = AVERROR_EXTERNAL;
  609. goto fail;
  610. }
  611. @@ -1070,7 +1077,7 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  612. ctx->va_entrypoint = va_entrypoints[i];
  613. #if VA_CHECK_VERSION(1, 0, 0)
  614. - entrypoint_string = vaEntrypointStr(ctx->va_entrypoint);
  615. + entrypoint_string = vaf->vaEntrypointStr(ctx->va_entrypoint);
  616. #else
  617. entrypoint_string = "(no entrypoint names)";
  618. #endif
  619. @@ -1095,12 +1102,12 @@ static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
  620. }
  621. rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
  622. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  623. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  624. ctx->va_profile, ctx->va_entrypoint,
  625. &rt_format_attr, 1);
  626. if (vas != VA_STATUS_SUCCESS) {
  627. av_log(avctx, AV_LOG_ERROR, "Failed to query RT format "
  628. - "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  629. + "config attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  630. err = AVERROR_EXTERNAL;
  631. goto fail;
  632. }
  633. @@ -1157,6 +1164,7 @@ static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
  634. static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
  635. {
  636. VAAPIEncodeContext *ctx = avctx->priv_data;
  637. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  638. uint32_t supported_va_rc_modes;
  639. const VAAPIEncodeRCMode *rc_mode;
  640. int64_t rc_bits_per_second;
  641. @@ -1170,12 +1178,12 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
  642. VAStatus vas;
  643. char supported_rc_modes_string[64];
  644. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  645. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  646. ctx->va_profile, ctx->va_entrypoint,
  647. &rc_attr, 1);
  648. if (vas != VA_STATUS_SUCCESS) {
  649. av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
  650. - "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  651. + "config attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  652. return AVERROR_EXTERNAL;
  653. }
  654. if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  655. @@ -1516,6 +1524,7 @@ static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
  656. {
  657. #if VA_CHECK_VERSION(1, 5, 0)
  658. VAAPIEncodeContext *ctx = avctx->priv_data;
  659. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  660. VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
  661. VAStatus vas;
  662. @@ -1526,14 +1535,14 @@ static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
  663. return AVERROR(EINVAL);
  664. }
  665. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  666. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  667. ctx->va_profile,
  668. ctx->va_entrypoint,
  669. &attr, 1);
  670. if (vas != VA_STATUS_SUCCESS) {
  671. ctx->max_frame_size = 0;
  672. av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
  673. - "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  674. + "config attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  675. return AVERROR_EXTERNAL;
  676. }
  677. @@ -1573,18 +1582,19 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
  678. {
  679. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  680. VAAPIEncodeContext *ctx = avctx->priv_data;
  681. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  682. VAStatus vas;
  683. VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
  684. uint32_t ref_l0, ref_l1;
  685. int prediction_pre_only, err;
  686. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  687. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  688. ctx->va_profile,
  689. ctx->va_entrypoint,
  690. &attr, 1);
  691. if (vas != VA_STATUS_SUCCESS) {
  692. av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames "
  693. - "attribute: %d (%s).\n", vas, vaErrorStr(vas));
  694. + "attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  695. return AVERROR_EXTERNAL;
  696. }
  697. @@ -1602,13 +1612,13 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
  698. if (!(ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY ||
  699. avctx->gop_size <= 1)) {
  700. attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
  701. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  702. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  703. ctx->va_profile,
  704. ctx->va_entrypoint,
  705. &attr, 1);
  706. if (vas != VA_STATUS_SUCCESS) {
  707. av_log(avctx, AV_LOG_WARNING, "Failed to query prediction direction "
  708. - "attribute: %d (%s).\n", vas, vaErrorStr(vas));
  709. + "attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  710. return AVERROR_EXTERNAL;
  711. } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
  712. av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any additional "
  713. @@ -1758,6 +1768,7 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
  714. {
  715. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  716. VAAPIEncodeContext *ctx = avctx->priv_data;
  717. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  718. VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
  719. { VAConfigAttribEncSliceStructure },
  720. #if VA_CHECK_VERSION(1, 1, 0)
  721. @@ -1789,13 +1800,13 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
  722. return 0;
  723. }
  724. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  725. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  726. ctx->va_profile,
  727. ctx->va_entrypoint,
  728. attr, FF_ARRAY_ELEMS(attr));
  729. if (vas != VA_STATUS_SUCCESS) {
  730. av_log(avctx, AV_LOG_ERROR, "Failed to query slice "
  731. - "attributes: %d (%s).\n", vas, vaErrorStr(vas));
  732. + "attributes: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  733. return AVERROR_EXTERNAL;
  734. }
  735. max_slices = attr[0].value;
  736. @@ -1849,16 +1860,17 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
  737. static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
  738. {
  739. VAAPIEncodeContext *ctx = avctx->priv_data;
  740. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  741. VAStatus vas;
  742. VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
  743. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  744. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  745. ctx->va_profile,
  746. ctx->va_entrypoint,
  747. &attr, 1);
  748. if (vas != VA_STATUS_SUCCESS) {
  749. av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
  750. - "attribute: %d (%s).\n", vas, vaErrorStr(vas));
  751. + "attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  752. return AVERROR_EXTERNAL;
  753. }
  754. @@ -1910,17 +1922,18 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
  755. {
  756. #if VA_CHECK_VERSION(0, 36, 0)
  757. VAAPIEncodeContext *ctx = avctx->priv_data;
  758. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  759. VAStatus vas;
  760. VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
  761. int quality = avctx->compression_level;
  762. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  763. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  764. ctx->va_profile,
  765. ctx->va_entrypoint,
  766. &attr, 1);
  767. if (vas != VA_STATUS_SUCCESS) {
  768. av_log(avctx, AV_LOG_ERROR, "Failed to query quality "
  769. - "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  770. + "config attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  771. return AVERROR_EXTERNAL;
  772. }
  773. @@ -1958,16 +1971,17 @@ static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
  774. #if VA_CHECK_VERSION(1, 0, 0)
  775. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  776. VAAPIEncodeContext *ctx = avctx->priv_data;
  777. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  778. VAStatus vas;
  779. VAConfigAttrib attr = { VAConfigAttribEncROI };
  780. - vas = vaGetConfigAttributes(ctx->hwctx->display,
  781. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display,
  782. ctx->va_profile,
  783. ctx->va_entrypoint,
  784. &attr, 1);
  785. if (vas != VA_STATUS_SUCCESS) {
  786. av_log(avctx, AV_LOG_ERROR, "Failed to query ROI "
  787. - "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
  788. + "config attribute: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  789. return AVERROR_EXTERNAL;
  790. }
  791. @@ -1992,10 +2006,11 @@ static void vaapi_encode_free_output_buffer(FFRefStructOpaque opaque,
  792. {
  793. AVCodecContext *avctx = opaque.nc;
  794. VAAPIEncodeContext *ctx = avctx->priv_data;
  795. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  796. VABufferID *buffer_id_ref = obj;
  797. VABufferID buffer_id = *buffer_id_ref;
  798. - vaDestroyBuffer(ctx->hwctx->display, buffer_id);
  799. + vaf->vaDestroyBuffer(ctx->hwctx->display, buffer_id);
  800. av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
  801. }
  802. @@ -2005,6 +2020,7 @@ static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
  803. AVCodecContext *avctx = opaque.nc;
  804. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  805. VAAPIEncodeContext *ctx = avctx->priv_data;
  806. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  807. VABufferID *buffer_id = obj;
  808. VAStatus vas;
  809. @@ -2012,13 +2028,13 @@ static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
  810. // to hold the largest possible compressed frame. We assume here
  811. // that the uncompressed frame plus some header data is an upper
  812. // bound on that.
  813. - vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  814. + vas = vaf->vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
  815. VAEncCodedBufferType,
  816. 3 * base_ctx->surface_width * base_ctx->surface_height +
  817. (1 << 16), 1, 0, buffer_id);
  818. if (vas != VA_STATUS_SUCCESS) {
  819. av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
  820. - "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
  821. + "output buffer: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  822. return AVERROR(ENOMEM);
  823. }
  824. @@ -2092,6 +2108,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  825. {
  826. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  827. VAAPIEncodeContext *ctx = avctx->priv_data;
  828. + VAAPIDynLoadFunctions *vaf = NULL;
  829. AVVAAPIFramesContext *recon_hwctx = NULL;
  830. VAStatus vas;
  831. int err;
  832. @@ -2107,6 +2124,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  833. ctx->hwctx = base_ctx->device->hwctx;
  834. + if (!ctx->hwctx || !ctx->hwctx->funcs) {
  835. + err = AVERROR(EINVAL);
  836. + goto fail;
  837. + }
  838. + vaf = ctx->hwctx->funcs;
  839. +
  840. err = vaapi_encode_profile_entrypoint(avctx);
  841. if (err < 0)
  842. goto fail;
  843. @@ -2157,13 +2180,13 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  844. goto fail;
  845. }
  846. - vas = vaCreateConfig(ctx->hwctx->display,
  847. + vas = vaf->vaCreateConfig(ctx->hwctx->display,
  848. ctx->va_profile, ctx->va_entrypoint,
  849. ctx->config_attributes, ctx->nb_config_attributes,
  850. &ctx->va_config);
  851. if (vas != VA_STATUS_SUCCESS) {
  852. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  853. - "configuration: %d (%s).\n", vas, vaErrorStr(vas));
  854. + "configuration: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  855. err = AVERROR(EIO);
  856. goto fail;
  857. }
  858. @@ -2173,7 +2196,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  859. goto fail;
  860. recon_hwctx = base_ctx->recon_frames->hwctx;
  861. - vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
  862. + vas = vaf->vaCreateContext(ctx->hwctx->display, ctx->va_config,
  863. base_ctx->surface_width, base_ctx->surface_height,
  864. VA_PROGRESSIVE,
  865. recon_hwctx->surface_ids,
  866. @@ -2181,7 +2204,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  867. &ctx->va_context);
  868. if (vas != VA_STATUS_SUCCESS) {
  869. av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
  870. - "context: %d (%s).\n", vas, vaErrorStr(vas));
  871. + "context: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  872. err = AVERROR(EIO);
  873. goto fail;
  874. }
  875. @@ -2255,14 +2278,16 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
  876. #if VA_CHECK_VERSION(1, 9, 0)
  877. // check vaSyncBuffer function
  878. - vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
  879. - if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
  880. - base_ctx->async_encode = 1;
  881. - base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
  882. - sizeof(VAAPIEncodePicture*),
  883. - 0);
  884. - if (!base_ctx->encode_fifo)
  885. - return AVERROR(ENOMEM);
  886. + if (vaf->vaSyncBuffer) {
  887. + vas = vaf->vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
  888. + if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
  889. + base_ctx->async_encode = 1;
  890. + base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
  891. + sizeof(VAAPIEncodePicture*),
  892. + 0);
  893. + if (!base_ctx->encode_fifo)
  894. + return AVERROR(ENOMEM);
  895. + }
  896. }
  897. #endif
  898. @@ -2291,14 +2316,14 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
  899. ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
  900. if (ctx->va_context != VA_INVALID_ID) {
  901. - if (ctx->hwctx)
  902. - vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  903. + if (ctx->hwctx && ctx->hwctx->funcs)
  904. + ctx->hwctx->funcs->vaDestroyContext(ctx->hwctx->display, ctx->va_context);
  905. ctx->va_context = VA_INVALID_ID;
  906. }
  907. if (ctx->va_config != VA_INVALID_ID) {
  908. - if (ctx->hwctx)
  909. - vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  910. + if (ctx->hwctx && ctx->hwctx->funcs)
  911. + ctx->hwctx->funcs->vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
  912. ctx->va_config = VA_INVALID_ID;
  913. }
  914. diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
  915. index fb87b68bec..6d4ce630ce 100644
  916. --- a/libavcodec/vaapi_encode_h264.c
  917. +++ b/libavcodec/vaapi_encode_h264.c
  918. @@ -868,6 +868,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
  919. static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
  920. {
  921. VAAPIEncodeContext *ctx = avctx->priv_data;
  922. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  923. VAAPIEncodeH264Context *priv = avctx->priv_data;
  924. int err;
  925. @@ -919,7 +920,7 @@ static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
  926. vaapi_encode_h264_sei_identifier_uuid,
  927. sizeof(priv->sei_identifier.uuid_iso_iec_11578));
  928. - driver = vaQueryVendorString(ctx->hwctx->display);
  929. + driver = vaf->vaQueryVendorString(ctx->hwctx->display);
  930. if (!driver)
  931. driver = "unknown driver";
  932. diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
  933. index 2283bcc0b4..7c624f99a9 100644
  934. --- a/libavcodec/vaapi_encode_h265.c
  935. +++ b/libavcodec/vaapi_encode_h265.c
  936. @@ -899,6 +899,8 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
  937. static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
  938. {
  939. FFHWBaseEncodeContext *base_ctx = avctx->priv_data;
  940. + VAAPIEncodeContext *ctx = avctx->priv_data;
  941. + VAAPIDynLoadFunctions *vaf = ctx->hwctx->funcs;
  942. VAAPIEncodeH265Context *priv = avctx->priv_data;
  943. #if VA_CHECK_VERSION(1, 13, 0)
  944. @@ -909,7 +911,7 @@ static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
  945. VAStatus vas;
  946. attr.type = VAConfigAttribEncHEVCFeatures;
  947. - vas = vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile,
  948. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile,
  949. ctx->va_entrypoint, &attr, 1);
  950. if (vas != VA_STATUS_SUCCESS) {
  951. av_log(avctx, AV_LOG_ERROR, "Failed to query encoder "
  952. @@ -923,7 +925,7 @@ static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
  953. }
  954. attr.type = VAConfigAttribEncHEVCBlockSizes;
  955. - vas = vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile,
  956. + vas = vaf->vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile,
  957. ctx->va_entrypoint, &attr, 1);
  958. if (vas != VA_STATUS_SUCCESS) {
  959. av_log(avctx, AV_LOG_ERROR, "Failed to query encoder "
  960. diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
  961. index 95aa38d9d2..13451e8ad7 100644
  962. --- a/libavutil/hwcontext_vaapi.c
  963. +++ b/libavutil/hwcontext_vaapi.c
  964. @@ -48,6 +48,7 @@ typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory)
  965. # include <unistd.h>
  966. #endif
  967. +#include <dlfcn.h>
  968. #include "avassert.h"
  969. #include "buffer.h"
  970. @@ -60,6 +61,128 @@ typedef HRESULT (WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory)
  971. #include "pixdesc.h"
  972. #include "pixfmt.h"
  973. +////////////////////////////////////////////////////////////
  974. +/// dynamic load functions
  975. +////////////////////////////////////////////////////////////
  976. +
  977. +#define LOAD_SYMBOL(name) do { \
  978. + funcs->name = dlsym(funcs->handle_va, #name); \
  979. + if (!funcs->name) { \
  980. + av_log(NULL, AV_LOG_ERROR, "Failed to load %s\n", #name); \
  981. + goto fail; \
  982. + } \
  983. +} while(0)
  984. +
  985. +static void vaapi_free_functions(VAAPIDynLoadFunctions *funcs)
  986. +{
  987. + if (!funcs)
  988. + return;
  989. +
  990. + if (funcs->handle_va_x11)
  991. + dlclose(funcs->handle_va_x11);
  992. + if (funcs->handle_va_drm)
  993. + dlclose(funcs->handle_va_drm);
  994. + if (funcs->handle_va)
  995. + dlclose(funcs->handle_va);
  996. + av_free(funcs);
  997. +}
  998. +
  999. +static VAAPIDynLoadFunctions *vaapi_load_functions(void)
  1000. +{
  1001. + VAAPIDynLoadFunctions *funcs = av_mallocz(sizeof(*funcs));
  1002. + if (!funcs)
  1003. + return NULL;
  1004. +
  1005. + // Load libva.so
  1006. + funcs->handle_va = dlopen("libva.so.2", RTLD_NOW | RTLD_LOCAL);
  1007. + if (!funcs->handle_va) {
  1008. + av_log(NULL, AV_LOG_ERROR, "Failed to load libva: %s\n", dlerror());
  1009. + goto fail;
  1010. + }
  1011. +
  1012. + // Load core functions
  1013. + LOAD_SYMBOL(vaInitialize);
  1014. + LOAD_SYMBOL(vaTerminate);
  1015. + LOAD_SYMBOL(vaCreateConfig);
  1016. + LOAD_SYMBOL(vaDestroyConfig);
  1017. + LOAD_SYMBOL(vaCreateContext);
  1018. + LOAD_SYMBOL(vaDestroyContext);
  1019. + LOAD_SYMBOL(vaCreateBuffer);
  1020. + LOAD_SYMBOL(vaDestroyBuffer);
  1021. + LOAD_SYMBOL(vaMapBuffer);
  1022. + LOAD_SYMBOL(vaUnmapBuffer);
  1023. + LOAD_SYMBOL(vaSyncSurface);
  1024. + LOAD_SYMBOL(vaGetConfigAttributes);
  1025. + LOAD_SYMBOL(vaCreateSurfaces);
  1026. + LOAD_SYMBOL(vaDestroySurfaces);
  1027. + LOAD_SYMBOL(vaBeginPicture);
  1028. + LOAD_SYMBOL(vaRenderPicture);
  1029. + LOAD_SYMBOL(vaEndPicture);
  1030. + LOAD_SYMBOL(vaQueryConfigEntrypoints);
  1031. + LOAD_SYMBOL(vaQueryConfigProfiles);
  1032. + LOAD_SYMBOL(vaGetDisplayAttributes);
  1033. + LOAD_SYMBOL(vaErrorStr);
  1034. + LOAD_SYMBOL(vaMaxNumEntrypoints);
  1035. + LOAD_SYMBOL(vaMaxNumProfiles);
  1036. + LOAD_SYMBOL(vaQueryVendorString);
  1037. + LOAD_SYMBOL(vaQuerySurfaceAttributes);
  1038. + LOAD_SYMBOL(vaDestroyImage);
  1039. + LOAD_SYMBOL(vaDeriveImage);
  1040. + LOAD_SYMBOL(vaPutImage);
  1041. + LOAD_SYMBOL(vaCreateImage);
  1042. + LOAD_SYMBOL(vaGetImage);
  1043. + LOAD_SYMBOL(vaExportSurfaceHandle);
  1044. + LOAD_SYMBOL(vaReleaseBufferHandle);
  1045. + LOAD_SYMBOL(vaAcquireBufferHandle);
  1046. + LOAD_SYMBOL(vaSetErrorCallback);
  1047. + LOAD_SYMBOL(vaSetInfoCallback);
  1048. + LOAD_SYMBOL(vaSetDriverName);
  1049. + LOAD_SYMBOL(vaEntrypointStr);
  1050. + LOAD_SYMBOL(vaQueryImageFormats);
  1051. + LOAD_SYMBOL(vaMaxNumImageFormats);
  1052. + LOAD_SYMBOL(vaProfileStr);
  1053. +
  1054. + // Load libva-x11.so
  1055. + funcs->handle_va_x11 = dlopen("libva-x11.so.2", RTLD_NOW | RTLD_LOCAL);
  1056. + if (!funcs->handle_va_x11) {
  1057. + av_log(NULL, AV_LOG_ERROR, "Failed to load libva-x11: %s\n", dlerror());
  1058. + goto fail;
  1059. + }
  1060. +
  1061. + funcs->vaGetDisplay = dlsym(funcs->handle_va_x11, "vaGetDisplay");
  1062. + if (!funcs->vaGetDisplay) {
  1063. + av_log(NULL, AV_LOG_ERROR, "Failed to load vaGetDisplay\n");
  1064. + goto fail;
  1065. + }
  1066. +
  1067. + // Load libva-drm.so
  1068. + funcs->handle_va_drm = dlopen("libva-drm.so.2", RTLD_NOW | RTLD_LOCAL);
  1069. + if (!funcs->handle_va_drm) {
  1070. + av_log(NULL, AV_LOG_ERROR, "Failed to load libva-drm: %s\n", dlerror());
  1071. + goto fail;
  1072. + }
  1073. +
  1074. + funcs->vaGetDisplayDRM = dlsym(funcs->handle_va_drm, "vaGetDisplayDRM");
  1075. + if (!funcs->vaGetDisplayDRM) {
  1076. + av_log(NULL, AV_LOG_ERROR, "Failed to load vaGetDisplayDRM\n");
  1077. + goto fail;
  1078. + }
  1079. +
  1080. + // Optional functions
  1081. + funcs->vaSyncBuffer = dlsym(funcs->handle_va, "vaSyncBuffer");
  1082. + av_log(NULL, AV_LOG_DEBUG, "vaSyncBuffer:%p.\n", funcs->vaSyncBuffer);
  1083. +
  1084. + return funcs;
  1085. +
  1086. +fail:
  1087. + vaapi_free_functions(funcs);
  1088. + return NULL;
  1089. +}
  1090. +
  1091. +////////////////////////////////////////////////////////////
  1092. +/// VAAPI API end
  1093. +////////////////////////////////////////////////////////////
  1094. +
  1095. typedef struct VAAPIDevicePriv {
  1096. #if HAVE_VAAPI_X11
  1097. @@ -236,6 +359,7 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
  1098. {
  1099. VAAPIDeviceContext *ctx = hwdev->hwctx;
  1100. AVVAAPIDeviceContext *hwctx = &ctx->p;
  1101. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1102. const AVVAAPIHWConfig *config = hwconfig;
  1103. VASurfaceAttrib *attr_list = NULL;
  1104. VAStatus vas;
  1105. @@ -246,11 +370,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
  1106. if (config &&
  1107. !(hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES)) {
  1108. attr_count = 0;
  1109. - vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
  1110. + vas = vaf->vaQuerySurfaceAttributes(hwctx->display, config->config_id,
  1111. 0, &attr_count);
  1112. if (vas != VA_STATUS_SUCCESS) {
  1113. av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
  1114. - "%d (%s).\n", vas, vaErrorStr(vas));
  1115. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  1116. err = AVERROR(ENOSYS);
  1117. goto fail;
  1118. }
  1119. @@ -261,11 +385,11 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
  1120. goto fail;
  1121. }
  1122. - vas = vaQuerySurfaceAttributes(hwctx->display, config->config_id,
  1123. + vas = vaf->vaQuerySurfaceAttributes(hwctx->display, config->config_id,
  1124. attr_list, &attr_count);
  1125. if (vas != VA_STATUS_SUCCESS) {
  1126. av_log(hwdev, AV_LOG_ERROR, "Failed to query surface attributes: "
  1127. - "%d (%s).\n", vas, vaErrorStr(vas));
  1128. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  1129. err = AVERROR(ENOSYS);
  1130. goto fail;
  1131. }
  1132. @@ -396,6 +520,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
  1133. {
  1134. VAAPIDeviceContext *ctx = hwdev->hwctx;
  1135. AVVAAPIDeviceContext *hwctx = &ctx->p;
  1136. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1137. VAImageFormat *image_list = NULL;
  1138. VAStatus vas;
  1139. const char *vendor_string;
  1140. @@ -403,7 +528,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
  1141. enum AVPixelFormat pix_fmt;
  1142. unsigned int fourcc;
  1143. - image_count = vaMaxNumImageFormats(hwctx->display);
  1144. + image_count = vaf->vaMaxNumImageFormats(hwctx->display);
  1145. if (image_count <= 0) {
  1146. err = AVERROR(EIO);
  1147. goto fail;
  1148. @@ -413,7 +538,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
  1149. err = AVERROR(ENOMEM);
  1150. goto fail;
  1151. }
  1152. - vas = vaQueryImageFormats(hwctx->display, image_list, &image_count);
  1153. + vas = vaf->vaQueryImageFormats(hwctx->display, image_list, &image_count);
  1154. if (vas != VA_STATUS_SUCCESS) {
  1155. err = AVERROR(EIO);
  1156. goto fail;
  1157. @@ -440,7 +565,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
  1158. }
  1159. }
  1160. - vendor_string = vaQueryVendorString(hwctx->display);
  1161. + vendor_string = vaf->vaQueryVendorString(hwctx->display);
  1162. if (vendor_string)
  1163. av_log(hwdev, AV_LOG_VERBOSE, "VAAPI driver: %s.\n", vendor_string);
  1164. @@ -493,15 +618,16 @@ static void vaapi_buffer_free(void *opaque, uint8_t *data)
  1165. {
  1166. AVHWFramesContext *hwfc = opaque;
  1167. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1168. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1169. VASurfaceID surface_id;
  1170. VAStatus vas;
  1171. surface_id = (VASurfaceID)(uintptr_t)data;
  1172. - vas = vaDestroySurfaces(hwctx->display, &surface_id, 1);
  1173. + vas = vaf->vaDestroySurfaces(hwctx->display, &surface_id, 1);
  1174. if (vas != VA_STATUS_SUCCESS) {
  1175. av_log(hwfc, AV_LOG_ERROR, "Failed to destroy surface %#x: "
  1176. - "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1177. + "%d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1178. }
  1179. }
  1180. @@ -511,6 +637,7 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
  1181. VAAPIFramesContext *ctx = hwfc->hwctx;
  1182. AVVAAPIFramesContext *avfc = &ctx->p;
  1183. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1184. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1185. VASurfaceID surface_id;
  1186. VAStatus vas;
  1187. AVBufferRef *ref;
  1188. @@ -519,13 +646,13 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
  1189. avfc->nb_surfaces >= hwfc->initial_pool_size)
  1190. return NULL;
  1191. - vas = vaCreateSurfaces(hwctx->display, ctx->rt_format,
  1192. + vas = vaf->vaCreateSurfaces(hwctx->display, ctx->rt_format,
  1193. hwfc->width, hwfc->height,
  1194. &surface_id, 1,
  1195. ctx->attributes, ctx->nb_attributes);
  1196. if (vas != VA_STATUS_SUCCESS) {
  1197. av_log(hwfc, AV_LOG_ERROR, "Failed to create surface: "
  1198. - "%d (%s).\n", vas, vaErrorStr(vas));
  1199. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  1200. return NULL;
  1201. }
  1202. av_log(hwfc, AV_LOG_DEBUG, "Created surface %#x.\n", surface_id);
  1203. @@ -534,7 +661,7 @@ static AVBufferRef *vaapi_pool_alloc(void *opaque, size_t size)
  1204. sizeof(surface_id), &vaapi_buffer_free,
  1205. hwfc, AV_BUFFER_FLAG_READONLY);
  1206. if (!ref) {
  1207. - vaDestroySurfaces(hwctx->display, &surface_id, 1);
  1208. + vaf->vaDestroySurfaces(hwctx->display, &surface_id, 1);
  1209. return NULL;
  1210. }
  1211. @@ -554,6 +681,7 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
  1212. VAAPIFramesContext *ctx = hwfc->hwctx;
  1213. AVVAAPIFramesContext *avfc = &ctx->p;
  1214. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1215. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1216. const VAAPIFormatDescriptor *desc;
  1217. VAImageFormat *expected_format;
  1218. AVBufferRef *test_surface = NULL;
  1219. @@ -669,7 +797,7 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
  1220. err = vaapi_get_image_format(hwfc->device_ctx,
  1221. hwfc->sw_format, &expected_format);
  1222. if (err == 0) {
  1223. - vas = vaDeriveImage(hwctx->display, test_surface_id, &test_image);
  1224. + vas = vaf->vaDeriveImage(hwctx->display, test_surface_id, &test_image);
  1225. if (vas == VA_STATUS_SUCCESS) {
  1226. if (expected_format->fourcc == test_image.format.fourcc) {
  1227. av_log(hwfc, AV_LOG_DEBUG, "Direct mapping possible.\n");
  1228. @@ -680,11 +808,11 @@ static int vaapi_frames_init(AVHWFramesContext *hwfc)
  1229. "expected format %08x.\n",
  1230. expected_format->fourcc, test_image.format.fourcc);
  1231. }
  1232. - vaDestroyImage(hwctx->display, test_image.image_id);
  1233. + vaf->vaDestroyImage(hwctx->display, test_image.image_id);
  1234. } else {
  1235. av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: "
  1236. "deriving image does not work: "
  1237. - "%d (%s).\n", vas, vaErrorStr(vas));
  1238. + "%d (%s).\n", vas, vaf->vaErrorStr(vas));
  1239. }
  1240. } else {
  1241. av_log(hwfc, AV_LOG_DEBUG, "Direct mapping disabled: "
  1242. @@ -765,33 +893,34 @@ static void vaapi_unmap_frame(AVHWFramesContext *hwfc,
  1243. {
  1244. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1245. VAAPIMapping *map = hwmap->priv;
  1246. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1247. VASurfaceID surface_id;
  1248. VAStatus vas;
  1249. surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3];
  1250. av_log(hwfc, AV_LOG_DEBUG, "Unmap surface %#x.\n", surface_id);
  1251. - vas = vaUnmapBuffer(hwctx->display, map->image.buf);
  1252. + vas = vaf->vaUnmapBuffer(hwctx->display, map->image.buf);
  1253. if (vas != VA_STATUS_SUCCESS) {
  1254. av_log(hwfc, AV_LOG_ERROR, "Failed to unmap image from surface "
  1255. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1256. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1257. }
  1258. if ((map->flags & AV_HWFRAME_MAP_WRITE) &&
  1259. !(map->flags & AV_HWFRAME_MAP_DIRECT)) {
  1260. - vas = vaPutImage(hwctx->display, surface_id, map->image.image_id,
  1261. + vas = vaf->vaPutImage(hwctx->display, surface_id, map->image.image_id,
  1262. 0, 0, hwfc->width, hwfc->height,
  1263. 0, 0, hwfc->width, hwfc->height);
  1264. if (vas != VA_STATUS_SUCCESS) {
  1265. av_log(hwfc, AV_LOG_ERROR, "Failed to write image to surface "
  1266. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1267. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1268. }
  1269. }
  1270. - vas = vaDestroyImage(hwctx->display, map->image.image_id);
  1271. + vas = vaf->vaDestroyImage(hwctx->display, map->image.image_id);
  1272. if (vas != VA_STATUS_SUCCESS) {
  1273. av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image from surface "
  1274. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1275. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1276. }
  1277. av_free(map);
  1278. @@ -801,6 +930,7 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
  1279. AVFrame *dst, const AVFrame *src, int flags)
  1280. {
  1281. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1282. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1283. VAAPIFramesContext *ctx = hwfc->hwctx;
  1284. VASurfaceID surface_id;
  1285. const VAAPIFormatDescriptor *desc;
  1286. @@ -839,10 +969,10 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
  1287. map->flags = flags;
  1288. map->image.image_id = VA_INVALID_ID;
  1289. - vas = vaSyncSurface(hwctx->display, surface_id);
  1290. + vas = vaf->vaSyncSurface(hwctx->display, surface_id);
  1291. if (vas != VA_STATUS_SUCCESS) {
  1292. av_log(hwfc, AV_LOG_ERROR, "Failed to sync surface "
  1293. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1294. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1295. err = AVERROR(EIO);
  1296. goto fail;
  1297. }
  1298. @@ -856,11 +986,11 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
  1299. // prefer not to be given direct-mapped memory if they request read access.
  1300. if (ctx->derive_works && dst->format == hwfc->sw_format &&
  1301. ((flags & AV_HWFRAME_MAP_DIRECT) || !(flags & AV_HWFRAME_MAP_READ))) {
  1302. - vas = vaDeriveImage(hwctx->display, surface_id, &map->image);
  1303. + vas = vaf->vaDeriveImage(hwctx->display, surface_id, &map->image);
  1304. if (vas != VA_STATUS_SUCCESS) {
  1305. av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from "
  1306. "surface %#x: %d (%s).\n",
  1307. - surface_id, vas, vaErrorStr(vas));
  1308. + surface_id, vas, vaf->vaErrorStr(vas));
  1309. err = AVERROR(EIO);
  1310. goto fail;
  1311. }
  1312. @@ -873,41 +1003,32 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
  1313. }
  1314. map->flags |= AV_HWFRAME_MAP_DIRECT;
  1315. } else {
  1316. - vas = vaCreateImage(hwctx->display, image_format,
  1317. + vas = vaf->vaCreateImage(hwctx->display, image_format,
  1318. hwfc->width, hwfc->height, &map->image);
  1319. if (vas != VA_STATUS_SUCCESS) {
  1320. av_log(hwfc, AV_LOG_ERROR, "Failed to create image for "
  1321. "surface %#x: %d (%s).\n",
  1322. - surface_id, vas, vaErrorStr(vas));
  1323. + surface_id, vas, vaf->vaErrorStr(vas));
  1324. err = AVERROR(EIO);
  1325. goto fail;
  1326. }
  1327. if (!(flags & AV_HWFRAME_MAP_OVERWRITE)) {
  1328. - vas = vaGetImage(hwctx->display, surface_id, 0, 0,
  1329. + vas = vaf->vaGetImage(hwctx->display, surface_id, 0, 0,
  1330. hwfc->width, hwfc->height, map->image.image_id);
  1331. if (vas != VA_STATUS_SUCCESS) {
  1332. av_log(hwfc, AV_LOG_ERROR, "Failed to read image from "
  1333. "surface %#x: %d (%s).\n",
  1334. - surface_id, vas, vaErrorStr(vas));
  1335. + surface_id, vas, vaf->vaErrorStr(vas));
  1336. err = AVERROR(EIO);
  1337. goto fail;
  1338. }
  1339. }
  1340. }
  1341. -#if VA_CHECK_VERSION(1, 21, 0)
  1342. - if (flags & AV_HWFRAME_MAP_READ)
  1343. - vaflags |= VA_MAPBUFFER_FLAG_READ;
  1344. - if (flags & AV_HWFRAME_MAP_WRITE)
  1345. - vaflags |= VA_MAPBUFFER_FLAG_WRITE;
  1346. - // On drivers not implementing vaMapBuffer2 libva calls vaMapBuffer instead.
  1347. - vas = vaMapBuffer2(hwctx->display, map->image.buf, &address, vaflags);
  1348. -#else
  1349. - vas = vaMapBuffer(hwctx->display, map->image.buf, &address);
  1350. -#endif
  1351. + vas = vaf->vaMapBuffer(hwctx->display, map->image.buf, &address);
  1352. if (vas != VA_STATUS_SUCCESS) {
  1353. av_log(hwfc, AV_LOG_ERROR, "Failed to map image from surface "
  1354. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1355. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1356. err = AVERROR(EIO);
  1357. goto fail;
  1358. }
  1359. @@ -936,9 +1057,9 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
  1360. fail:
  1361. if (map) {
  1362. if (address)
  1363. - vaUnmapBuffer(hwctx->display, map->image.buf);
  1364. + vaf->vaUnmapBuffer(hwctx->display, map->image.buf);
  1365. if (map->image.image_id != VA_INVALID_ID)
  1366. - vaDestroyImage(hwctx->display, map->image.image_id);
  1367. + vaf->vaDestroyImage(hwctx->display, map->image.image_id);
  1368. av_free(map);
  1369. }
  1370. return err;
  1371. @@ -1080,12 +1201,12 @@ static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc,
  1372. HWMapDescriptor *hwmap)
  1373. {
  1374. AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx;
  1375. -
  1376. + VAAPIDynLoadFunctions *vaf = dst_dev->funcs;
  1377. VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->priv;
  1378. av_log(dst_fc, AV_LOG_DEBUG, "Destroy surface %#x.\n", surface_id);
  1379. - vaDestroySurfaces(dst_dev->display, &surface_id, 1);
  1380. + vaf->vaDestroySurfaces(dst_dev->display, &surface_id, 1);
  1381. }
  1382. static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
  1383. @@ -1100,6 +1221,7 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
  1384. AVHWFramesContext *dst_fc =
  1385. (AVHWFramesContext*)dst->hw_frames_ctx->data;
  1386. AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx;
  1387. + VAAPIDynLoadFunctions *vaf = dst_dev->funcs;
  1388. const AVDRMFrameDescriptor *desc;
  1389. const VAAPIFormatDescriptor *format_desc;
  1390. VASurfaceID surface_id;
  1391. @@ -1216,7 +1338,7 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
  1392. * Gallium seem to do the correct error checks, so lets just try the
  1393. * PRIME_2 import first.
  1394. */
  1395. - vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1396. + vas = vaf->vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1397. src->width, src->height, &surface_id, 1,
  1398. prime_attrs, FF_ARRAY_ELEMS(prime_attrs));
  1399. if (vas != VA_STATUS_SUCCESS)
  1400. @@ -1267,7 +1389,7 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
  1401. FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
  1402. }
  1403. - vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1404. + vas = vaf->vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1405. src->width, src->height,
  1406. &surface_id, 1,
  1407. buffer_attrs, FF_ARRAY_ELEMS(buffer_attrs));
  1408. @@ -1298,14 +1420,14 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
  1409. FFSWAP(uint32_t, buffer_desc.offsets[1], buffer_desc.offsets[2]);
  1410. }
  1411. - vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1412. + vas = vaf->vaCreateSurfaces(dst_dev->display, format_desc->rt_format,
  1413. src->width, src->height,
  1414. &surface_id, 1,
  1415. attrs, FF_ARRAY_ELEMS(attrs));
  1416. #endif
  1417. if (vas != VA_STATUS_SUCCESS) {
  1418. av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM "
  1419. - "object: %d (%s).\n", vas, vaErrorStr(vas));
  1420. + "object: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  1421. return AVERROR(EIO);
  1422. }
  1423. av_log(dst_fc, AV_LOG_DEBUG, "Create surface %#x.\n", surface_id);
  1424. @@ -1343,6 +1465,7 @@ static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst,
  1425. const AVFrame *src, int flags)
  1426. {
  1427. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1428. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1429. VASurfaceID surface_id;
  1430. VAStatus vas;
  1431. VADRMPRIMESurfaceDescriptor va_desc;
  1432. @@ -1356,10 +1479,10 @@ static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst,
  1433. if (flags & AV_HWFRAME_MAP_READ) {
  1434. export_flags |= VA_EXPORT_SURFACE_READ_ONLY;
  1435. - vas = vaSyncSurface(hwctx->display, surface_id);
  1436. + vas = vaf->vaSyncSurface(hwctx->display, surface_id);
  1437. if (vas != VA_STATUS_SUCCESS) {
  1438. av_log(hwfc, AV_LOG_ERROR, "Failed to sync surface "
  1439. - "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1440. + "%#x: %d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1441. return AVERROR(EIO);
  1442. }
  1443. }
  1444. @@ -1367,14 +1490,14 @@ static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst,
  1445. if (flags & AV_HWFRAME_MAP_WRITE)
  1446. export_flags |= VA_EXPORT_SURFACE_WRITE_ONLY;
  1447. - vas = vaExportSurfaceHandle(hwctx->display, surface_id,
  1448. + vas = vaf->vaExportSurfaceHandle(hwctx->display, surface_id,
  1449. VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
  1450. export_flags, &va_desc);
  1451. if (vas != VA_STATUS_SUCCESS) {
  1452. if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
  1453. return AVERROR(ENOSYS);
  1454. av_log(hwfc, AV_LOG_ERROR, "Failed to export surface %#x: "
  1455. - "%d (%s).\n", surface_id, vas, vaErrorStr(vas));
  1456. + "%d (%s).\n", surface_id, vas, vaf->vaErrorStr(vas));
  1457. return AVERROR(EIO);
  1458. }
  1459. @@ -1437,6 +1560,7 @@ static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc,
  1460. HWMapDescriptor *hwmap)
  1461. {
  1462. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1463. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1464. VAAPIDRMImageBufferMapping *mapping = hwmap->priv;
  1465. VASurfaceID surface_id;
  1466. VAStatus vas;
  1467. @@ -1448,19 +1572,19 @@ static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc,
  1468. // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(),
  1469. // so we shouldn't close them separately.
  1470. - vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf);
  1471. + vas = vaf->vaReleaseBufferHandle(hwctx->display, mapping->image.buf);
  1472. if (vas != VA_STATUS_SUCCESS) {
  1473. av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer "
  1474. "handle of image %#x (derived from surface %#x): "
  1475. "%d (%s).\n", mapping->image.buf, surface_id,
  1476. - vas, vaErrorStr(vas));
  1477. + vas, vaf->vaErrorStr(vas));
  1478. }
  1479. - vas = vaDestroyImage(hwctx->display, mapping->image.image_id);
  1480. + vas = vaf->vaDestroyImage(hwctx->display, mapping->image.image_id);
  1481. if (vas != VA_STATUS_SUCCESS) {
  1482. av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image "
  1483. "derived from surface %#x: %d (%s).\n",
  1484. - surface_id, vas, vaErrorStr(vas));
  1485. + surface_id, vas, vaf->vaErrorStr(vas));
  1486. }
  1487. av_free(mapping);
  1488. @@ -1470,6 +1594,7 @@ static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst,
  1489. const AVFrame *src, int flags)
  1490. {
  1491. AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
  1492. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1493. VAAPIDRMImageBufferMapping *mapping = NULL;
  1494. VASurfaceID surface_id;
  1495. VAStatus vas;
  1496. @@ -1483,12 +1608,12 @@ static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst,
  1497. if (!mapping)
  1498. return AVERROR(ENOMEM);
  1499. - vas = vaDeriveImage(hwctx->display, surface_id,
  1500. + vas = vaf->vaDeriveImage(hwctx->display, surface_id,
  1501. &mapping->image);
  1502. if (vas != VA_STATUS_SUCCESS) {
  1503. av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from "
  1504. "surface %#x: %d (%s).\n",
  1505. - surface_id, vas, vaErrorStr(vas));
  1506. + surface_id, vas, vaf->vaErrorStr(vas));
  1507. err = AVERROR(EIO);
  1508. goto fail;
  1509. }
  1510. @@ -1543,13 +1668,13 @@ static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst,
  1511. }
  1512. }
  1513. - vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf,
  1514. + vas = vaf->vaAcquireBufferHandle(hwctx->display, mapping->image.buf,
  1515. &mapping->buffer_info);
  1516. if (vas != VA_STATUS_SUCCESS) {
  1517. av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer "
  1518. "handle from image %#x (derived from surface %#x): "
  1519. "%d (%s).\n", mapping->image.buf, surface_id,
  1520. - vas, vaErrorStr(vas));
  1521. + vas, vaf->vaErrorStr(vas));
  1522. err = AVERROR(EIO);
  1523. goto fail_derived;
  1524. }
  1525. @@ -1578,9 +1703,9 @@ static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst,
  1526. return 0;
  1527. fail_mapped:
  1528. - vaReleaseBufferHandle(hwctx->display, mapping->image.buf);
  1529. + vaf->vaReleaseBufferHandle(hwctx->display, mapping->image.buf);
  1530. fail_derived:
  1531. - vaDestroyImage(hwctx->display, mapping->image.image_id);
  1532. + vaf->vaDestroyImage(hwctx->display, mapping->image.image_id);
  1533. fail:
  1534. av_freep(&mapping);
  1535. return err;
  1536. @@ -1634,9 +1759,15 @@ static void vaapi_device_free(AVHWDeviceContext *ctx)
  1537. {
  1538. AVVAAPIDeviceContext *hwctx = ctx->hwctx;
  1539. VAAPIDevicePriv *priv = ctx->user_opaque;
  1540. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1541. - if (hwctx->display)
  1542. - vaTerminate(hwctx->display);
  1543. + if (hwctx && hwctx->display && vaf && vaf->vaTerminate)
  1544. + vaf->vaTerminate(hwctx->display);
  1545. +
  1546. + if (hwctx && hwctx->funcs) {
  1547. + vaapi_free_functions(hwctx->funcs);
  1548. + hwctx->funcs = NULL;
  1549. + }
  1550. #if HAVE_VAAPI_X11
  1551. if (priv->x11_display)
  1552. @@ -1669,20 +1800,21 @@ static int vaapi_device_connect(AVHWDeviceContext *ctx,
  1553. VADisplay display)
  1554. {
  1555. AVVAAPIDeviceContext *hwctx = ctx->hwctx;
  1556. + VAAPIDynLoadFunctions *vaf = hwctx->funcs;
  1557. int major, minor;
  1558. VAStatus vas;
  1559. #if CONFIG_VAAPI_1
  1560. - vaSetErrorCallback(display, &vaapi_device_log_error, ctx);
  1561. - vaSetInfoCallback (display, &vaapi_device_log_info, ctx);
  1562. + vaf->vaSetErrorCallback(display, &vaapi_device_log_error, ctx);
  1563. + vaf->vaSetInfoCallback (display, &vaapi_device_log_info, ctx);
  1564. #endif
  1565. hwctx->display = display;
  1566. - vas = vaInitialize(display, &major, &minor);
  1567. + vas = vaf->vaInitialize(display, &major, &minor);
  1568. if (vas != VA_STATUS_SUCCESS) {
  1569. av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI "
  1570. - "connection: %d (%s).\n", vas, vaErrorStr(vas));
  1571. + "connection: %d (%s).\n", vas, vaf->vaErrorStr(vas));
  1572. return AVERROR(EIO);
  1573. }
  1574. av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: "
  1575. @@ -1698,6 +1830,16 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
  1576. VADisplay display = NULL;
  1577. const AVDictionaryEntry *ent;
  1578. int try_drm, try_x11, try_win32, try_all;
  1579. + VAAPIDeviceContext *hwctx = ctx->hwctx;
  1580. + VAAPIDynLoadFunctions *vaf;
  1581. +
  1582. + hwctx->p.funcs = vaapi_load_functions();
  1583. + if (!hwctx->p.funcs) {
  1584. + av_log(NULL, AV_LOG_ERROR, "Failed to load libva: %s\n", dlerror());
  1585. + return AVERROR_EXTERNAL;
  1586. + }
  1587. +
  1588. + vaf = hwctx->p.funcs;
  1589. priv = av_mallocz(sizeof(*priv));
  1590. if (!priv)
  1591. @@ -1843,7 +1985,7 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
  1592. break;
  1593. }
  1594. - display = vaGetDisplayDRM(priv->drm_fd);
  1595. + display = vaf->vaGetDisplayDRM(priv->drm_fd);
  1596. if (!display) {
  1597. av_log(ctx, AV_LOG_VERBOSE, "Cannot open a VA display "
  1598. "from DRM device %s.\n", device);
  1599. @@ -1861,7 +2003,7 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
  1600. av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display "
  1601. "%s.\n", XDisplayName(device));
  1602. } else {
  1603. - display = vaGetDisplay(priv->x11_display);
  1604. + display = vaf->vaGetDisplay(priv->x11_display);
  1605. if (!display) {
  1606. av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
  1607. "from X11 display %s.\n", XDisplayName(device));
  1608. @@ -1950,11 +2092,11 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
  1609. if (ent) {
  1610. #if VA_CHECK_VERSION(0, 38, 0)
  1611. VAStatus vas;
  1612. - vas = vaSetDriverName(display, ent->value);
  1613. + vas = vaf->vaSetDriverName(display, ent->value);
  1614. if (vas != VA_STATUS_SUCCESS) {
  1615. av_log(ctx, AV_LOG_ERROR, "Failed to set driver name to "
  1616. - "%s: %d (%s).\n", ent->value, vas, vaErrorStr(vas));
  1617. - vaTerminate(display);
  1618. + "%s: %d (%s).\n", ent->value, vas, vaf->vaErrorStr(vas));
  1619. + vaf->vaTerminate(display);
  1620. return AVERROR_EXTERNAL;
  1621. }
  1622. #else
  1623. @@ -1970,6 +2112,8 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx,
  1624. AVHWDeviceContext *src_ctx,
  1625. AVDictionary *opts, int flags)
  1626. {
  1627. + VAAPIDeviceContext *hwctx = ctx->hwctx;
  1628. + VAAPIDynLoadFunctions *vaf = hwctx->p.funcs;
  1629. #if HAVE_VAAPI_DRM
  1630. if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) {
  1631. AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
  1632. @@ -2041,7 +2185,7 @@ static int vaapi_device_derive(AVHWDeviceContext *ctx,
  1633. ctx->user_opaque = priv;
  1634. ctx->free = &vaapi_device_free;
  1635. - display = vaGetDisplayDRM(fd);
  1636. + display = vaf->vaGetDisplayDRM(fd);
  1637. if (!display) {
  1638. av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from "
  1639. "DRM device.\n");
  1640. diff --git a/libavutil/hwcontext_vaapi.h b/libavutil/hwcontext_vaapi.h
  1641. index 0b2e071cb3..2c51223d45 100644
  1642. --- a/libavutil/hwcontext_vaapi.h
  1643. +++ b/libavutil/hwcontext_vaapi.h
  1644. @@ -20,6 +20,100 @@
  1645. #define AVUTIL_HWCONTEXT_VAAPI_H
  1646. #include <va/va.h>
  1647. +#include <va/va_x11.h>
  1648. +#include <va/va_drm.h>
  1649. +#include <va/va_str.h>
  1650. +
  1651. +
  1652. +////////////////////////////////////////////////////////////
  1653. +/// VAAPI dynamic load functions start
  1654. +////////////////////////////////////////////////////////////
  1655. +
  1656. +typedef struct VAAPIDynLoadFunctions {
  1657. + // Core VA functions
  1658. + VAStatus (*vaInitialize)(VADisplay dpy, int *major_version, int *minor_version);
  1659. + VAStatus (*vaTerminate)(VADisplay dpy);
  1660. + VAStatus (*vaCreateConfig)(VADisplay dpy, VAProfile profile, VAEntrypoint entrypoint,
  1661. + VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id);
  1662. + VAStatus (*vaDestroyConfig)(VADisplay dpy, VAConfigID config_id);
  1663. + VAStatus (*vaCreateContext)(VADisplay dpy, VAConfigID config_id, int picture_width,
  1664. + int picture_height, int flag, VASurfaceID *render_targets,
  1665. + int num_render_targets, VAContextID *context);
  1666. + VAStatus (*vaDestroyContext)(VADisplay dpy, VAContextID context);
  1667. + VAStatus (*vaCreateBuffer)(VADisplay dpy, VAContextID context, VABufferType type,
  1668. + unsigned int size, unsigned int num_elements, void *data,
  1669. + VABufferID *buf_id);
  1670. + VAStatus (*vaDestroyBuffer)(VADisplay dpy, VABufferID buf_id);
  1671. + VAStatus (*vaMapBuffer)(VADisplay dpy, VABufferID buf_id, void **pbuf);
  1672. + VAStatus (*vaUnmapBuffer)(VADisplay dpy, VABufferID buf_id);
  1673. + VAStatus (*vaSyncSurface)(VADisplay dpy, VASurfaceID render_target);
  1674. + VAStatus (*vaGetConfigAttributes)(VADisplay dpy, VAProfile profile,
  1675. + VAEntrypoint entrypoint, VAConfigAttrib *attrib_list,
  1676. + int num_attribs);
  1677. + VAStatus (*vaCreateSurfaces)(VADisplay dpy, unsigned int format,
  1678. + unsigned int width, unsigned int height,
  1679. + VASurfaceID *surfaces, unsigned int num_surfaces,
  1680. + VASurfaceAttrib *attrib_list, unsigned int num_attribs);
  1681. + VAStatus (*vaDestroySurfaces)(VADisplay dpy, VASurfaceID *surfaces, int num_surfaces);
  1682. + VAStatus (*vaBeginPicture)(VADisplay dpy, VAContextID context, VASurfaceID render_target);
  1683. + VAStatus (*vaRenderPicture)(VADisplay dpy, VAContextID context,
  1684. + VABufferID *buffers, int num_buffers);
  1685. + VAStatus (*vaEndPicture)(VADisplay dpy, VAContextID context);
  1686. + VAStatus (*vaQueryConfigEntrypoints)(VADisplay dpy, VAProfile profile,
  1687. + VAEntrypoint *entrypoint_list, int *num_entrypoints);
  1688. + VAStatus (*vaQueryConfigProfiles)(VADisplay dpy, VAProfile *profile_list, int *num_profiles);
  1689. + VAStatus (*vaGetDisplayAttributes)(VADisplay dpy, VADisplayAttribute *attr_list, int num_attributes);
  1690. + const char *(*vaErrorStr)(VAStatus error_status);
  1691. + int (*vaMaxNumEntrypoints)(VADisplay dpy);
  1692. + int (*vaMaxNumProfiles)(VADisplay dpy);
  1693. + const char *(*vaQueryVendorString)(VADisplay dpy);
  1694. + VAStatus (*vaQuerySurfaceAttributes)(VADisplay dpy, VAConfigID config_id,
  1695. + VASurfaceAttrib *attrib_list, int *num_attribs);
  1696. + VAStatus (*vaDestroyImage)(VADisplay dpy, VAImageID image);
  1697. + VAStatus (*vaDeriveImage)(VADisplay dpy, VASurfaceID surface, VAImage *image);
  1698. + VAStatus (*vaPutImage)(VADisplay dpy, VASurfaceID surface, VAImageID image,
  1699. + int src_x, int src_y, unsigned int src_width, unsigned int src_height,
  1700. + int dest_x, int dest_y, unsigned int dest_width, unsigned int dest_height);
  1701. + VAStatus (*vaCreateImage)(VADisplay dpy, VAImageFormat *format, int width, int height, VAImage *image);
  1702. + VAStatus (*vaGetImage)(VADisplay dpy, VASurfaceID surface,
  1703. + int x, int y, unsigned int width, unsigned int height,
  1704. + VAImageID image);
  1705. + VAStatus (*vaExportSurfaceHandle)(VADisplay dpy, VASurfaceID surface_id,
  1706. + uint32_t mem_type, uint32_t flags,
  1707. + void *descriptor);
  1708. + VAStatus (*vaReleaseBufferHandle)(VADisplay dpy, VABufferID buf_id);
  1709. + VAStatus (*vaAcquireBufferHandle)(VADisplay dpy, VABufferID buf_id,
  1710. + VABufferInfo *buf_info);
  1711. + VAStatus (*vaSetErrorCallback)(VADisplay dpy, VAMessageCallback callback, void *user_context);
  1712. + VAStatus (*vaSetInfoCallback)(VADisplay dpy, VAMessageCallback callback, void *user_context);
  1713. + VAStatus (*vaSetDriverName)(VADisplay dpy, const char *driver_name);
  1714. + const char *(*vaEntrypointStr)(VAEntrypoint entrypoint);
  1715. + VAStatus (*vaQueryImageFormats)(VADisplay dpy, VAImageFormat *format_list, int *num_formats);
  1716. + int (*vaMaxNumImageFormats)(VADisplay dpy);
  1717. + const char *(*vaProfileStr)(VAProfile profile);
  1718. +
  1719. +
  1720. + // Optional functions
  1721. + VAStatus (*vaSyncBuffer)(VADisplay dpy, VABufferID buf_id, uint64_t timeout_ns);
  1722. +
  1723. + // X11 specific functions
  1724. + VADisplay (*vaGetDisplay)(Display *dpy);
  1725. +
  1726. + // DRM specific functions
  1727. + VADisplay (*vaGetDisplayDRM)(int fd);
  1728. +
  1729. +
  1730. +
  1731. + // Library handles
  1732. + void *handle_va;
  1733. + void *handle_va_drm;
  1734. + void *handle_va_x11;
  1735. +} VAAPIDynLoadFunctions;
  1736. +
  1737. +
  1738. +////////////////////////////////////////////////////////////
  1739. +/// VAAPI API end
  1740. +////////////////////////////////////////////////////////////
  1741. /**
  1742. * @file
  1743. @@ -78,6 +172,8 @@ typedef struct AVVAAPIDeviceContext {
  1744. * operations using VAAPI with the same VADisplay.
  1745. */
  1746. unsigned int driver_quirks;
  1747. +
  1748. + VAAPIDynLoadFunctions *funcs;
  1749. } AVVAAPIDeviceContext;
  1750. /**
  1751. --
  1752. 2.34.1