ffmpeg_vaapi.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "config.h"
  19. #include <fcntl.h>
  20. #include <unistd.h>
  21. #include <va/va.h>
  22. #if HAVE_VAAPI_X11
  23. # include <va/va_x11.h>
  24. #endif
  25. #if HAVE_VAAPI_DRM
  26. # include <va/va_drm.h>
  27. #endif
  28. #include "libavutil/avassert.h"
  29. #include "libavutil/avconfig.h"
  30. #include "libavutil/buffer.h"
  31. #include "libavutil/frame.h"
  32. #include "libavutil/hwcontext.h"
  33. #include "libavutil/hwcontext_vaapi.h"
  34. #include "libavutil/imgutils.h"
  35. #include "libavutil/opt.h"
  36. #include "libavutil/pixfmt.h"
  37. #include "libavcodec/vaapi.h"
  38. #include "ffmpeg.h"
  39. static AVClass vaapi_class = {
  40. .class_name = "vaapi",
  41. .item_name = av_default_item_name,
  42. .version = LIBAVUTIL_VERSION_INT,
  43. };
  44. #define DEFAULT_SURFACES 20
  45. typedef struct VAAPIDecoderContext {
  46. const AVClass *class;
  47. AVBufferRef *device_ref;
  48. AVHWDeviceContext *device;
  49. AVBufferRef *frames_ref;
  50. AVHWFramesContext *frames;
  51. VAProfile va_profile;
  52. VAEntrypoint va_entrypoint;
  53. VAConfigID va_config;
  54. VAContextID va_context;
  55. enum AVPixelFormat decode_format;
  56. int decode_width;
  57. int decode_height;
  58. int decode_surfaces;
  59. // The output need not have the same format, width and height as the
  60. // decoded frames - the copy for non-direct-mapped access is actually
  61. // a whole vpp instance which can do arbitrary scaling and format
  62. // conversion.
  63. enum AVPixelFormat output_format;
  64. struct vaapi_context decoder_vaapi_context;
  65. } VAAPIDecoderContext;
  66. static int vaapi_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
  67. {
  68. InputStream *ist = avctx->opaque;
  69. VAAPIDecoderContext *ctx = ist->hwaccel_ctx;
  70. int err;
  71. err = av_hwframe_get_buffer(ctx->frames_ref, frame, 0);
  72. if (err < 0) {
  73. av_log(ctx, AV_LOG_ERROR, "Failed to allocate decoder surface.\n");
  74. } else {
  75. av_log(ctx, AV_LOG_DEBUG, "Decoder given surface %#x.\n",
  76. (unsigned int)(uintptr_t)frame->data[3]);
  77. }
  78. return err;
  79. }
  80. static int vaapi_retrieve_data(AVCodecContext *avctx, AVFrame *input)
  81. {
  82. InputStream *ist = avctx->opaque;
  83. VAAPIDecoderContext *ctx = ist->hwaccel_ctx;
  84. AVFrame *output = 0;
  85. int err;
  86. av_assert0(input->format == AV_PIX_FMT_VAAPI);
  87. if (ctx->output_format == AV_PIX_FMT_VAAPI) {
  88. // Nothing to do.
  89. return 0;
  90. }
  91. av_log(ctx, AV_LOG_DEBUG, "Retrieve data from surface %#x.\n",
  92. (unsigned int)(uintptr_t)input->data[3]);
  93. output = av_frame_alloc();
  94. if (!output)
  95. return AVERROR(ENOMEM);
  96. output->format = ctx->output_format;
  97. err = av_hwframe_transfer_data(output, input, 0);
  98. if (err < 0) {
  99. av_log(ctx, AV_LOG_ERROR, "Failed to transfer data to "
  100. "output frame: %d.\n", err);
  101. goto fail;
  102. }
  103. err = av_frame_copy_props(output, input);
  104. if (err < 0) {
  105. av_frame_unref(output);
  106. goto fail;
  107. }
  108. av_frame_unref(input);
  109. av_frame_move_ref(input, output);
  110. av_frame_free(&output);
  111. return 0;
  112. fail:
  113. if (output)
  114. av_frame_free(&output);
  115. return err;
  116. }
  117. static const struct {
  118. enum AVCodecID codec_id;
  119. int codec_profile;
  120. VAProfile va_profile;
  121. } vaapi_profile_map[] = {
  122. #define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v }
  123. MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
  124. MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
  125. MAP(H263, UNKNOWN, H263Baseline),
  126. MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
  127. MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
  128. MPEG4AdvancedSimple),
  129. MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
  130. MAP(H264, H264_CONSTRAINED_BASELINE,
  131. H264ConstrainedBaseline),
  132. MAP(H264, H264_BASELINE, H264Baseline),
  133. MAP(H264, H264_MAIN, H264Main ),
  134. MAP(H264, H264_HIGH, H264High ),
  135. #if VA_CHECK_VERSION(0, 37, 0)
  136. MAP(HEVC, HEVC_MAIN, HEVCMain ),
  137. #endif
  138. MAP(WMV3, VC1_SIMPLE, VC1Simple ),
  139. MAP(WMV3, VC1_MAIN, VC1Main ),
  140. MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
  141. MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
  142. MAP(VC1, VC1_SIMPLE, VC1Simple ),
  143. MAP(VC1, VC1_MAIN, VC1Main ),
  144. MAP(VC1, VC1_COMPLEX, VC1Advanced ),
  145. MAP(VC1, VC1_ADVANCED, VC1Advanced ),
  146. #if VA_CHECK_VERSION(0, 35, 0)
  147. MAP(VP8, UNKNOWN, VP8Version0_3 ),
  148. #endif
  149. #if VA_CHECK_VERSION(0, 37, 1)
  150. MAP(VP9, VP9_0, VP9Profile0 ),
  151. #endif
  152. #undef MAP
  153. };
  154. static int vaapi_build_decoder_config(VAAPIDecoderContext *ctx,
  155. AVCodecContext *avctx,
  156. int fallback_allowed)
  157. {
  158. AVVAAPIDeviceContext *hwctx = ctx->device->hwctx;
  159. AVVAAPIHWConfig *hwconfig = NULL;
  160. AVHWFramesConstraints *constraints = NULL;
  161. VAStatus vas;
  162. int err, i, j;
  163. int loglevel = fallback_allowed ? AV_LOG_VERBOSE : AV_LOG_ERROR;
  164. const AVCodecDescriptor *codec_desc;
  165. const AVPixFmtDescriptor *pix_desc;
  166. enum AVPixelFormat pix_fmt;
  167. VAProfile profile, *profile_list = NULL;
  168. int profile_count, exact_match, alt_profile;
  169. codec_desc = avcodec_descriptor_get(avctx->codec_id);
  170. if (!codec_desc) {
  171. err = AVERROR(EINVAL);
  172. goto fail;
  173. }
  174. profile_count = vaMaxNumProfiles(hwctx->display);
  175. profile_list = av_malloc(profile_count * sizeof(VAProfile));
  176. if (!profile_list) {
  177. err = AVERROR(ENOMEM);
  178. goto fail;
  179. }
  180. vas = vaQueryConfigProfiles(hwctx->display,
  181. profile_list, &profile_count);
  182. if (vas != VA_STATUS_SUCCESS) {
  183. av_log(ctx, loglevel, "Failed to query profiles: %d (%s).\n",
  184. vas, vaErrorStr(vas));
  185. err = AVERROR(EIO);
  186. goto fail;
  187. }
  188. profile = VAProfileNone;
  189. exact_match = 0;
  190. for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
  191. int profile_match = 0;
  192. if (avctx->codec_id != vaapi_profile_map[i].codec_id)
  193. continue;
  194. if (avctx->profile == vaapi_profile_map[i].codec_profile)
  195. profile_match = 1;
  196. profile = vaapi_profile_map[i].va_profile;
  197. for (j = 0; j < profile_count; j++) {
  198. if (profile == profile_list[j]) {
  199. exact_match = profile_match;
  200. break;
  201. }
  202. }
  203. if (j < profile_count) {
  204. if (exact_match)
  205. break;
  206. alt_profile = vaapi_profile_map[i].codec_profile;
  207. }
  208. }
  209. av_freep(&profile_list);
  210. if (profile == VAProfileNone) {
  211. av_log(ctx, loglevel, "No VAAPI support for codec %s.\n",
  212. codec_desc->name);
  213. err = AVERROR(ENOSYS);
  214. goto fail;
  215. }
  216. if (!exact_match) {
  217. if (fallback_allowed || !hwaccel_lax_profile_check) {
  218. av_log(ctx, loglevel, "No VAAPI support for codec %s "
  219. "profile %d.\n", codec_desc->name, avctx->profile);
  220. if (!fallback_allowed) {
  221. av_log(ctx, AV_LOG_WARNING, "If you want attempt decoding "
  222. "anyway with a possibly-incompatible profile, add "
  223. "the option -hwaccel_lax_profile_check.\n");
  224. }
  225. err = AVERROR(EINVAL);
  226. goto fail;
  227. } else {
  228. av_log(ctx, AV_LOG_WARNING, "No VAAPI support for codec %s "
  229. "profile %d: trying instead with profile %d.\n",
  230. codec_desc->name, avctx->profile, alt_profile);
  231. av_log(ctx, AV_LOG_WARNING, "This may fail or give "
  232. "incorrect results, depending on your hardware.\n");
  233. }
  234. }
  235. ctx->va_profile = profile;
  236. ctx->va_entrypoint = VAEntrypointVLD;
  237. vas = vaCreateConfig(hwctx->display, ctx->va_profile,
  238. ctx->va_entrypoint, 0, 0, &ctx->va_config);
  239. if (vas != VA_STATUS_SUCCESS) {
  240. av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline "
  241. "configuration: %d (%s).\n", vas, vaErrorStr(vas));
  242. err = AVERROR(EIO);
  243. goto fail;
  244. }
  245. hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
  246. if (!hwconfig) {
  247. err = AVERROR(ENOMEM);
  248. goto fail;
  249. }
  250. hwconfig->config_id = ctx->va_config;
  251. constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
  252. hwconfig);
  253. if (!constraints)
  254. goto fail;
  255. // Decide on the decoder target format.
  256. // If the user specified something with -hwaccel_output_format then
  257. // try to use that to minimise conversions later.
  258. ctx->decode_format = AV_PIX_FMT_NONE;
  259. if (ctx->output_format != AV_PIX_FMT_NONE &&
  260. ctx->output_format != AV_PIX_FMT_VAAPI) {
  261. for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
  262. if (constraints->valid_sw_formats[i] == ctx->decode_format) {
  263. ctx->decode_format = ctx->output_format;
  264. av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (output "
  265. "format).\n", av_get_pix_fmt_name(ctx->decode_format));
  266. break;
  267. }
  268. }
  269. }
  270. // Otherwise, we would like to try to choose something which matches the
  271. // decoder output, but there isn't enough information available here to
  272. // do so. Assume for now that we are always dealing with YUV 4:2:0, so
  273. // pick a format which does that.
  274. if (ctx->decode_format == AV_PIX_FMT_NONE) {
  275. for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
  276. pix_fmt = constraints->valid_sw_formats[i];
  277. pix_desc = av_pix_fmt_desc_get(pix_fmt);
  278. if (pix_desc->nb_components == 3 &&
  279. pix_desc->log2_chroma_w == 1 &&
  280. pix_desc->log2_chroma_h == 1) {
  281. ctx->decode_format = pix_fmt;
  282. av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (format "
  283. "matched).\n", av_get_pix_fmt_name(ctx->decode_format));
  284. break;
  285. }
  286. }
  287. }
  288. // Otherwise pick the first in the list and hope for the best.
  289. if (ctx->decode_format == AV_PIX_FMT_NONE) {
  290. ctx->decode_format = constraints->valid_sw_formats[0];
  291. av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (first in list).\n",
  292. av_get_pix_fmt_name(ctx->decode_format));
  293. if (i > 1) {
  294. // There was a choice, and we picked randomly. Warn the user
  295. // that they might want to choose intelligently instead.
  296. av_log(ctx, AV_LOG_WARNING, "Using randomly chosen decode "
  297. "format %s.\n", av_get_pix_fmt_name(ctx->decode_format));
  298. }
  299. }
  300. // Ensure the picture size is supported by the hardware.
  301. ctx->decode_width = avctx->coded_width;
  302. ctx->decode_height = avctx->coded_height;
  303. if (ctx->decode_width < constraints->min_width ||
  304. ctx->decode_height < constraints->min_height ||
  305. ctx->decode_width > constraints->max_width ||
  306. ctx->decode_height >constraints->max_height) {
  307. av_log(ctx, AV_LOG_ERROR, "VAAPI hardware does not support image "
  308. "size %dx%d (constraints: width %d-%d height %d-%d).\n",
  309. ctx->decode_width, ctx->decode_height,
  310. constraints->min_width, constraints->max_width,
  311. constraints->min_height, constraints->max_height);
  312. err = AVERROR(EINVAL);
  313. goto fail;
  314. }
  315. av_hwframe_constraints_free(&constraints);
  316. av_freep(&hwconfig);
  317. // Decide how many reference frames we need. This might be doable more
  318. // nicely based on the codec and input stream?
  319. ctx->decode_surfaces = DEFAULT_SURFACES;
  320. // For frame-threaded decoding, one additional surfaces is needed for
  321. // each thread.
  322. if (avctx->active_thread_type & FF_THREAD_FRAME)
  323. ctx->decode_surfaces += avctx->thread_count;
  324. return 0;
  325. fail:
  326. av_hwframe_constraints_free(&constraints);
  327. av_freep(&hwconfig);
  328. vaDestroyConfig(hwctx->display, ctx->va_config);
  329. av_freep(&profile_list);
  330. return err;
  331. }
  332. static void vaapi_decode_uninit(AVCodecContext *avctx)
  333. {
  334. InputStream *ist = avctx->opaque;
  335. VAAPIDecoderContext *ctx = ist->hwaccel_ctx;
  336. if (ctx) {
  337. AVVAAPIDeviceContext *hwctx = ctx->device->hwctx;
  338. if (ctx->va_context != VA_INVALID_ID) {
  339. vaDestroyContext(hwctx->display, ctx->va_context);
  340. ctx->va_context = VA_INVALID_ID;
  341. }
  342. if (ctx->va_config != VA_INVALID_ID) {
  343. vaDestroyConfig(hwctx->display, ctx->va_config);
  344. ctx->va_config = VA_INVALID_ID;
  345. }
  346. av_buffer_unref(&ctx->frames_ref);
  347. av_buffer_unref(&ctx->device_ref);
  348. av_free(ctx);
  349. }
  350. av_buffer_unref(&ist->hw_frames_ctx);
  351. ist->hwaccel_ctx = 0;
  352. ist->hwaccel_uninit = 0;
  353. ist->hwaccel_get_buffer = 0;
  354. ist->hwaccel_retrieve_data = 0;
  355. }
  356. int vaapi_decode_init(AVCodecContext *avctx)
  357. {
  358. InputStream *ist = avctx->opaque;
  359. AVVAAPIDeviceContext *hwctx;
  360. AVVAAPIFramesContext *avfc;
  361. VAAPIDecoderContext *ctx;
  362. VAStatus vas;
  363. int err;
  364. int loglevel = (ist->hwaccel_id != HWACCEL_VAAPI ? AV_LOG_VERBOSE
  365. : AV_LOG_ERROR);
  366. if (ist->hwaccel_ctx)
  367. vaapi_decode_uninit(avctx);
  368. // We have -hwaccel without -vaapi_device, so just initialise here with
  369. // the device passed as -hwaccel_device (if -vaapi_device was passed, it
  370. // will always have been called before now).
  371. if (!hw_device_ctx) {
  372. err = vaapi_device_init(ist->hwaccel_device);
  373. if (err < 0)
  374. return err;
  375. }
  376. ctx = av_mallocz(sizeof(*ctx));
  377. if (!ctx)
  378. return AVERROR(ENOMEM);
  379. ctx->class = &vaapi_class;
  380. ctx->device_ref = av_buffer_ref(hw_device_ctx);
  381. ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
  382. ctx->va_config = VA_INVALID_ID;
  383. ctx->va_context = VA_INVALID_ID;
  384. hwctx = ctx->device->hwctx;
  385. ctx->output_format = ist->hwaccel_output_format;
  386. err = vaapi_build_decoder_config(ctx, avctx,
  387. ist->hwaccel_id != HWACCEL_VAAPI);
  388. if (err < 0) {
  389. av_log(ctx, loglevel, "No supported configuration for this codec.");
  390. goto fail;
  391. }
  392. avctx->pix_fmt = ctx->output_format;
  393. ctx->frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
  394. if (!ctx->frames_ref) {
  395. av_log(ctx, loglevel, "Failed to create VAAPI frame context.\n");
  396. err = AVERROR(ENOMEM);
  397. goto fail;
  398. }
  399. ctx->frames = (AVHWFramesContext*)ctx->frames_ref->data;
  400. ctx->frames->format = AV_PIX_FMT_VAAPI;
  401. ctx->frames->sw_format = ctx->decode_format;
  402. ctx->frames->width = ctx->decode_width;
  403. ctx->frames->height = ctx->decode_height;
  404. ctx->frames->initial_pool_size = ctx->decode_surfaces;
  405. err = av_hwframe_ctx_init(ctx->frames_ref);
  406. if (err < 0) {
  407. av_log(ctx, loglevel, "Failed to initialise VAAPI frame "
  408. "context: %d\n", err);
  409. goto fail;
  410. }
  411. avfc = ctx->frames->hwctx;
  412. vas = vaCreateContext(hwctx->display, ctx->va_config,
  413. ctx->decode_width, ctx->decode_height,
  414. VA_PROGRESSIVE,
  415. avfc->surface_ids, avfc->nb_surfaces,
  416. &ctx->va_context);
  417. if (vas != VA_STATUS_SUCCESS) {
  418. av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline "
  419. "context: %d (%s).\n", vas, vaErrorStr(vas));
  420. err = AVERROR(EINVAL);
  421. goto fail;
  422. }
  423. av_log(ctx, AV_LOG_DEBUG, "VAAPI decoder (re)init complete.\n");
  424. // We would like to set this on the AVCodecContext for use by whoever gets
  425. // the frames from the decoder, but unfortunately the AVCodecContext we
  426. // have here need not be the "real" one (H.264 makes many copies for
  427. // threading purposes). To avoid the problem, we instead store it in the
  428. // InputStream and propagate it from there.
  429. ist->hw_frames_ctx = av_buffer_ref(ctx->frames_ref);
  430. if (!ist->hw_frames_ctx) {
  431. err = AVERROR(ENOMEM);
  432. goto fail;
  433. }
  434. ist->hwaccel_ctx = ctx;
  435. ist->hwaccel_uninit = vaapi_decode_uninit;
  436. ist->hwaccel_get_buffer = vaapi_get_buffer;
  437. ist->hwaccel_retrieve_data = vaapi_retrieve_data;
  438. ctx->decoder_vaapi_context.display = hwctx->display;
  439. ctx->decoder_vaapi_context.config_id = ctx->va_config;
  440. ctx->decoder_vaapi_context.context_id = ctx->va_context;
  441. avctx->hwaccel_context = &ctx->decoder_vaapi_context;
  442. return 0;
  443. fail:
  444. vaapi_decode_uninit(avctx);
  445. return err;
  446. }
  447. static AVClass *vaapi_log = &vaapi_class;
  448. av_cold int vaapi_device_init(const char *device)
  449. {
  450. int err;
  451. err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
  452. device, NULL, 0);
  453. if (err < 0) {
  454. av_log(&vaapi_log, AV_LOG_ERROR, "Failed to create a VAAPI device\n");
  455. return err;
  456. }
  457. return 0;
  458. }