You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

455 lines
12KB

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