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.

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