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.

403 lines
10KB

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