hwcontext.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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 "buffer.h"
  20. #include "common.h"
  21. #include "hwcontext.h"
  22. #include "hwcontext_internal.h"
  23. #include "imgutils.h"
  24. #include "log.h"
  25. #include "mem.h"
  26. #include "pixdesc.h"
  27. #include "pixfmt.h"
  28. static const HWContextType *hw_table[] = {
  29. #if CONFIG_CUDA
  30. &ff_hwcontext_type_cuda,
  31. #endif
  32. #if CONFIG_DXVA2
  33. &ff_hwcontext_type_dxva2,
  34. #endif
  35. #if CONFIG_QSV
  36. &ff_hwcontext_type_qsv,
  37. #endif
  38. #if CONFIG_VAAPI
  39. &ff_hwcontext_type_vaapi,
  40. #endif
  41. #if CONFIG_VDPAU
  42. &ff_hwcontext_type_vdpau,
  43. #endif
  44. NULL,
  45. };
  46. static const AVClass hwdevice_ctx_class = {
  47. .class_name = "AVHWDeviceContext",
  48. .item_name = av_default_item_name,
  49. .version = LIBAVUTIL_VERSION_INT,
  50. };
  51. static void hwdevice_ctx_free(void *opaque, uint8_t *data)
  52. {
  53. AVHWDeviceContext *ctx = (AVHWDeviceContext*)data;
  54. /* uninit might still want access the hw context and the user
  55. * free() callback might destroy it, so uninit has to be called first */
  56. if (ctx->internal->hw_type->device_uninit)
  57. ctx->internal->hw_type->device_uninit(ctx);
  58. if (ctx->free)
  59. ctx->free(ctx);
  60. av_freep(&ctx->hwctx);
  61. av_freep(&ctx->internal->priv);
  62. av_freep(&ctx->internal);
  63. av_freep(&ctx);
  64. }
  65. AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
  66. {
  67. AVHWDeviceContext *ctx;
  68. AVBufferRef *buf;
  69. const HWContextType *hw_type = NULL;
  70. int i;
  71. for (i = 0; hw_table[i]; i++) {
  72. if (hw_table[i]->type == type) {
  73. hw_type = hw_table[i];
  74. break;
  75. }
  76. }
  77. if (!hw_type)
  78. return NULL;
  79. ctx = av_mallocz(sizeof(*ctx));
  80. if (!ctx)
  81. return NULL;
  82. ctx->internal = av_mallocz(sizeof(*ctx->internal));
  83. if (!ctx->internal)
  84. goto fail;
  85. if (hw_type->device_priv_size) {
  86. ctx->internal->priv = av_mallocz(hw_type->device_priv_size);
  87. if (!ctx->internal->priv)
  88. goto fail;
  89. }
  90. if (hw_type->device_hwctx_size) {
  91. ctx->hwctx = av_mallocz(hw_type->device_hwctx_size);
  92. if (!ctx->hwctx)
  93. goto fail;
  94. }
  95. buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
  96. hwdevice_ctx_free, NULL,
  97. AV_BUFFER_FLAG_READONLY);
  98. if (!buf)
  99. goto fail;
  100. ctx->type = type;
  101. ctx->av_class = &hwdevice_ctx_class;
  102. ctx->internal->hw_type = hw_type;
  103. return buf;
  104. fail:
  105. if (ctx->internal)
  106. av_freep(&ctx->internal->priv);
  107. av_freep(&ctx->internal);
  108. av_freep(&ctx->hwctx);
  109. av_freep(&ctx);
  110. return NULL;
  111. }
  112. int av_hwdevice_ctx_init(AVBufferRef *ref)
  113. {
  114. AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
  115. int ret;
  116. if (ctx->internal->hw_type->device_init) {
  117. ret = ctx->internal->hw_type->device_init(ctx);
  118. if (ret < 0)
  119. goto fail;
  120. }
  121. return 0;
  122. fail:
  123. if (ctx->internal->hw_type->device_uninit)
  124. ctx->internal->hw_type->device_uninit(ctx);
  125. return ret;
  126. }
  127. static const AVClass hwframe_ctx_class = {
  128. .class_name = "AVHWFramesContext",
  129. .item_name = av_default_item_name,
  130. .version = LIBAVUTIL_VERSION_INT,
  131. };
  132. static void hwframe_ctx_free(void *opaque, uint8_t *data)
  133. {
  134. AVHWFramesContext *ctx = (AVHWFramesContext*)data;
  135. if (ctx->internal->pool_internal)
  136. av_buffer_pool_uninit(&ctx->internal->pool_internal);
  137. if (ctx->internal->hw_type->frames_uninit)
  138. ctx->internal->hw_type->frames_uninit(ctx);
  139. if (ctx->free)
  140. ctx->free(ctx);
  141. av_buffer_unref(&ctx->device_ref);
  142. av_freep(&ctx->hwctx);
  143. av_freep(&ctx->internal->priv);
  144. av_freep(&ctx->internal);
  145. av_freep(&ctx);
  146. }
  147. AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
  148. {
  149. AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)device_ref_in->data;
  150. const HWContextType *hw_type = device_ctx->internal->hw_type;
  151. AVHWFramesContext *ctx;
  152. AVBufferRef *buf, *device_ref = NULL;
  153. ctx = av_mallocz(sizeof(*ctx));
  154. if (!ctx)
  155. return NULL;
  156. ctx->internal = av_mallocz(sizeof(*ctx->internal));
  157. if (!ctx->internal)
  158. goto fail;
  159. if (hw_type->frames_priv_size) {
  160. ctx->internal->priv = av_mallocz(hw_type->frames_priv_size);
  161. if (!ctx->internal->priv)
  162. goto fail;
  163. }
  164. if (hw_type->frames_hwctx_size) {
  165. ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
  166. if (!ctx->hwctx)
  167. goto fail;
  168. }
  169. device_ref = av_buffer_ref(device_ref_in);
  170. if (!device_ref)
  171. goto fail;
  172. buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx),
  173. hwframe_ctx_free, NULL,
  174. AV_BUFFER_FLAG_READONLY);
  175. if (!buf)
  176. goto fail;
  177. ctx->av_class = &hwframe_ctx_class;
  178. ctx->device_ref = device_ref;
  179. ctx->device_ctx = device_ctx;
  180. ctx->format = AV_PIX_FMT_NONE;
  181. ctx->sw_format = AV_PIX_FMT_NONE;
  182. ctx->internal->hw_type = hw_type;
  183. return buf;
  184. fail:
  185. if (device_ref)
  186. av_buffer_unref(&device_ref);
  187. if (ctx->internal)
  188. av_freep(&ctx->internal->priv);
  189. av_freep(&ctx->internal);
  190. av_freep(&ctx->hwctx);
  191. av_freep(&ctx);
  192. return NULL;
  193. }
  194. static int hwframe_pool_prealloc(AVBufferRef *ref)
  195. {
  196. AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
  197. AVFrame **frames;
  198. int i, ret = 0;
  199. frames = av_mallocz_array(ctx->initial_pool_size, sizeof(*frames));
  200. if (!frames)
  201. return AVERROR(ENOMEM);
  202. for (i = 0; i < ctx->initial_pool_size; i++) {
  203. frames[i] = av_frame_alloc();
  204. if (!frames[i])
  205. goto fail;
  206. ret = av_hwframe_get_buffer(ref, frames[i], 0);
  207. if (ret < 0)
  208. goto fail;
  209. }
  210. fail:
  211. for (i = 0; i < ctx->initial_pool_size; i++)
  212. av_frame_free(&frames[i]);
  213. av_freep(&frames);
  214. return ret;
  215. }
  216. int av_hwframe_ctx_init(AVBufferRef *ref)
  217. {
  218. AVHWFramesContext *ctx = (AVHWFramesContext*)ref->data;
  219. const enum AVPixelFormat *pix_fmt;
  220. int ret;
  221. /* validate the pixel format */
  222. for (pix_fmt = ctx->internal->hw_type->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++) {
  223. if (*pix_fmt == ctx->format)
  224. break;
  225. }
  226. if (*pix_fmt == AV_PIX_FMT_NONE) {
  227. av_log(ctx, AV_LOG_ERROR,
  228. "The hardware pixel format '%s' is not supported by the device type '%s'\n",
  229. av_get_pix_fmt_name(ctx->format), ctx->internal->hw_type->name);
  230. return AVERROR(ENOSYS);
  231. }
  232. /* validate the dimensions */
  233. ret = av_image_check_size(ctx->width, ctx->height, 0, ctx);
  234. if (ret < 0)
  235. return ret;
  236. /* format-specific init */
  237. if (ctx->internal->hw_type->frames_init) {
  238. ret = ctx->internal->hw_type->frames_init(ctx);
  239. if (ret < 0)
  240. goto fail;
  241. }
  242. if (ctx->internal->pool_internal && !ctx->pool)
  243. ctx->pool = ctx->internal->pool_internal;
  244. /* preallocate the frames in the pool, if requested */
  245. if (ctx->initial_pool_size > 0) {
  246. ret = hwframe_pool_prealloc(ref);
  247. if (ret < 0)
  248. goto fail;
  249. }
  250. return 0;
  251. fail:
  252. if (ctx->internal->hw_type->frames_uninit)
  253. ctx->internal->hw_type->frames_uninit(ctx);
  254. return ret;
  255. }
  256. int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
  257. enum AVHWFrameTransferDirection dir,
  258. enum AVPixelFormat **formats, int flags)
  259. {
  260. AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
  261. if (!ctx->internal->hw_type->transfer_get_formats)
  262. return AVERROR(ENOSYS);
  263. return ctx->internal->hw_type->transfer_get_formats(ctx, dir, formats);
  264. }
  265. static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
  266. {
  267. AVFrame *frame_tmp;
  268. int ret = 0;
  269. frame_tmp = av_frame_alloc();
  270. if (!frame_tmp)
  271. return AVERROR(ENOMEM);
  272. /* if the format is set, use that
  273. * otherwise pick the first supported one */
  274. if (dst->format >= 0) {
  275. frame_tmp->format = dst->format;
  276. } else {
  277. enum AVPixelFormat *formats;
  278. ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx,
  279. AV_HWFRAME_TRANSFER_DIRECTION_FROM,
  280. &formats, 0);
  281. if (ret < 0)
  282. goto fail;
  283. frame_tmp->format = formats[0];
  284. av_freep(&formats);
  285. }
  286. frame_tmp->width = src->width;
  287. frame_tmp->height = src->height;
  288. ret = av_frame_get_buffer(frame_tmp, 32);
  289. if (ret < 0)
  290. goto fail;
  291. ret = av_hwframe_transfer_data(frame_tmp, src, flags);
  292. if (ret < 0)
  293. goto fail;
  294. av_frame_move_ref(dst, frame_tmp);
  295. fail:
  296. av_frame_free(&frame_tmp);
  297. return ret;
  298. }
  299. int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
  300. {
  301. AVHWFramesContext *ctx;
  302. int ret;
  303. if (!dst->buf[0])
  304. return transfer_data_alloc(dst, src, flags);
  305. if (src->hw_frames_ctx) {
  306. ctx = (AVHWFramesContext*)src->hw_frames_ctx->data;
  307. ret = ctx->internal->hw_type->transfer_data_from(ctx, dst, src);
  308. if (ret < 0)
  309. return ret;
  310. } else if (dst->hw_frames_ctx) {
  311. ctx = (AVHWFramesContext*)dst->hw_frames_ctx->data;
  312. ret = ctx->internal->hw_type->transfer_data_to(ctx, dst, src);
  313. if (ret < 0)
  314. return ret;
  315. } else
  316. return AVERROR(ENOSYS);
  317. return 0;
  318. }
  319. int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
  320. {
  321. AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data;
  322. int ret;
  323. if (!ctx->internal->hw_type->frames_get_buffer)
  324. return AVERROR(ENOSYS);
  325. if (!ctx->pool)
  326. return AVERROR(EINVAL);
  327. frame->hw_frames_ctx = av_buffer_ref(hwframe_ref);
  328. if (!frame->hw_frames_ctx)
  329. return AVERROR(ENOMEM);
  330. ret = ctx->internal->hw_type->frames_get_buffer(ctx, frame);
  331. if (ret < 0) {
  332. av_buffer_unref(&frame->hw_frames_ctx);
  333. return ret;
  334. }
  335. return 0;
  336. }
  337. void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
  338. {
  339. AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
  340. const HWContextType *hw_type = ctx->internal->hw_type;
  341. if (hw_type->device_hwconfig_size == 0)
  342. return NULL;
  343. return av_mallocz(hw_type->device_hwconfig_size);
  344. }
  345. AVHWFramesConstraints *av_hwdevice_get_hwframe_constraints(AVBufferRef *ref,
  346. const void *hwconfig)
  347. {
  348. AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
  349. const HWContextType *hw_type = ctx->internal->hw_type;
  350. AVHWFramesConstraints *constraints;
  351. if (!hw_type->frames_get_constraints)
  352. return NULL;
  353. constraints = av_mallocz(sizeof(*constraints));
  354. if (!constraints)
  355. return NULL;
  356. constraints->min_width = constraints->min_height = 0;
  357. constraints->max_width = constraints->max_height = INT_MAX;
  358. if (hw_type->frames_get_constraints(ctx, hwconfig, constraints) >= 0) {
  359. return constraints;
  360. } else {
  361. av_hwframe_constraints_free(&constraints);
  362. return NULL;
  363. }
  364. }
  365. void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
  366. {
  367. if (*constraints) {
  368. av_freep(&(*constraints)->valid_hw_formats);
  369. av_freep(&(*constraints)->valid_sw_formats);
  370. }
  371. av_freep(constraints);
  372. }
  373. int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type,
  374. const char *device, AVDictionary *opts, int flags)
  375. {
  376. AVBufferRef *device_ref = NULL;
  377. AVHWDeviceContext *device_ctx;
  378. int ret = 0;
  379. device_ref = av_hwdevice_ctx_alloc(type);
  380. if (!device_ref) {
  381. ret = AVERROR(ENOMEM);
  382. goto fail;
  383. }
  384. device_ctx = (AVHWDeviceContext*)device_ref->data;
  385. if (!device_ctx->internal->hw_type->device_create) {
  386. ret = AVERROR(ENOSYS);
  387. goto fail;
  388. }
  389. ret = device_ctx->internal->hw_type->device_create(device_ctx, device,
  390. opts, flags);
  391. if (ret < 0)
  392. goto fail;
  393. ret = av_hwdevice_ctx_init(device_ref);
  394. if (ret < 0)
  395. goto fail;
  396. *pdevice_ref = device_ref;
  397. return 0;
  398. fail:
  399. av_buffer_unref(&device_ref);
  400. *pdevice_ref = NULL;
  401. return ret;
  402. }