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.

477 lines
15KB

  1. /*
  2. * Video Decode and Presentation API for UNIX (VDPAU) is used for
  3. * HW decode acceleration for MPEG-1/2, MPEG-4 ASP, H.264 and VC-1.
  4. *
  5. * Copyright (c) 2008 NVIDIA
  6. *
  7. * This file is part of FFmpeg.
  8. *
  9. * FFmpeg is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2.1 of the License, or (at your option) any later version.
  13. *
  14. * FFmpeg is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with FFmpeg; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include <limits.h>
  24. #include "avcodec.h"
  25. #include "decode.h"
  26. #include "internal.h"
  27. #include "h264dec.h"
  28. #include "vc1.h"
  29. #include "vdpau.h"
  30. #include "vdpau_internal.h"
  31. // XXX: at the time of adding this ifdefery, av_assert* wasn't use outside.
  32. // When dropping it, make sure other av_assert* were not added since then.
  33. /**
  34. * @addtogroup VDPAU_Decoding
  35. *
  36. * @{
  37. */
  38. static int vdpau_error(VdpStatus status)
  39. {
  40. switch (status) {
  41. case VDP_STATUS_OK:
  42. return 0;
  43. case VDP_STATUS_NO_IMPLEMENTATION:
  44. return AVERROR(ENOSYS);
  45. case VDP_STATUS_DISPLAY_PREEMPTED:
  46. return AVERROR(EIO);
  47. case VDP_STATUS_INVALID_HANDLE:
  48. return AVERROR(EBADF);
  49. case VDP_STATUS_INVALID_POINTER:
  50. return AVERROR(EFAULT);
  51. case VDP_STATUS_RESOURCES:
  52. return AVERROR(ENOBUFS);
  53. case VDP_STATUS_HANDLE_DEVICE_MISMATCH:
  54. return AVERROR(EXDEV);
  55. case VDP_STATUS_ERROR:
  56. return AVERROR(EIO);
  57. default:
  58. return AVERROR(EINVAL);
  59. }
  60. }
  61. AVVDPAUContext *av_alloc_vdpaucontext(void)
  62. {
  63. return av_vdpau_alloc_context();
  64. }
  65. MAKE_ACCESSORS(AVVDPAUContext, vdpau_hwaccel, AVVDPAU_Render2, render2)
  66. int av_vdpau_get_surface_parameters(AVCodecContext *avctx,
  67. VdpChromaType *type,
  68. uint32_t *width, uint32_t *height)
  69. {
  70. VdpChromaType t;
  71. uint32_t w = avctx->coded_width;
  72. uint32_t h = avctx->coded_height;
  73. /* See <vdpau/vdpau.h> for per-type alignment constraints. */
  74. switch (avctx->sw_pix_fmt) {
  75. case AV_PIX_FMT_YUV420P:
  76. case AV_PIX_FMT_YUVJ420P:
  77. case AV_PIX_FMT_YUV420P10:
  78. case AV_PIX_FMT_YUV420P12:
  79. t = VDP_CHROMA_TYPE_420;
  80. w = (w + 1) & ~1;
  81. h = (h + 3) & ~3;
  82. break;
  83. case AV_PIX_FMT_YUV422P:
  84. case AV_PIX_FMT_YUVJ422P:
  85. t = VDP_CHROMA_TYPE_422;
  86. w = (w + 1) & ~1;
  87. h = (h + 1) & ~1;
  88. break;
  89. case AV_PIX_FMT_YUV444P:
  90. case AV_PIX_FMT_YUVJ444P:
  91. case AV_PIX_FMT_YUV444P10:
  92. case AV_PIX_FMT_YUV444P12:
  93. t = VDP_CHROMA_TYPE_444;
  94. h = (h + 1) & ~1;
  95. break;
  96. default:
  97. return AVERROR(ENOSYS);
  98. }
  99. if (type)
  100. *type = t;
  101. if (width)
  102. *width = w;
  103. if (height)
  104. *height = h;
  105. return 0;
  106. }
  107. int ff_vdpau_common_frame_params(AVCodecContext *avctx,
  108. AVBufferRef *hw_frames_ctx)
  109. {
  110. AVHWFramesContext *hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;
  111. VdpChromaType type;
  112. uint32_t width;
  113. uint32_t height;
  114. if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height))
  115. return AVERROR(EINVAL);
  116. hw_frames->format = AV_PIX_FMT_VDPAU;
  117. hw_frames->sw_format = avctx->sw_pix_fmt;
  118. hw_frames->width = width;
  119. hw_frames->height = height;
  120. return 0;
  121. }
  122. int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
  123. int level)
  124. {
  125. VDPAUHWContext *hwctx = avctx->hwaccel_context;
  126. VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
  127. VdpVideoSurfaceQueryCapabilities *surface_query_caps;
  128. VdpDecoderQueryCapabilities *decoder_query_caps;
  129. VdpDecoderCreate *create;
  130. VdpGetInformationString *info;
  131. const char *info_string;
  132. void *func;
  133. VdpStatus status;
  134. VdpBool supported;
  135. uint32_t max_level, max_mb, max_width, max_height;
  136. VdpChromaType type;
  137. uint32_t width;
  138. uint32_t height;
  139. int ret;
  140. vdctx->width = UINT32_MAX;
  141. vdctx->height = UINT32_MAX;
  142. if (av_vdpau_get_surface_parameters(avctx, &type, &width, &height))
  143. return AVERROR(ENOSYS);
  144. if (hwctx) {
  145. hwctx->reset = 0;
  146. if (hwctx->context.decoder != VDP_INVALID_HANDLE) {
  147. vdctx->decoder = hwctx->context.decoder;
  148. vdctx->render = hwctx->context.render;
  149. vdctx->device = VDP_INVALID_HANDLE;
  150. return 0; /* Decoder created by user */
  151. }
  152. vdctx->device = hwctx->device;
  153. vdctx->get_proc_address = hwctx->get_proc_address;
  154. if (hwctx->flags & AV_HWACCEL_FLAG_IGNORE_LEVEL)
  155. level = 0;
  156. if (!(hwctx->flags & AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH) &&
  157. type != VDP_CHROMA_TYPE_420)
  158. return AVERROR(ENOSYS);
  159. } else {
  160. AVHWFramesContext *frames_ctx;
  161. AVVDPAUDeviceContext *dev_ctx;
  162. ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
  163. if (ret < 0)
  164. return ret;
  165. frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
  166. dev_ctx = frames_ctx->device_ctx->hwctx;
  167. vdctx->device = dev_ctx->device;
  168. vdctx->get_proc_address = dev_ctx->get_proc_address;
  169. if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_IGNORE_LEVEL)
  170. level = 0;
  171. }
  172. if (level < 0)
  173. return AVERROR(ENOTSUP);
  174. status = vdctx->get_proc_address(vdctx->device,
  175. VDP_FUNC_ID_GET_INFORMATION_STRING,
  176. &func);
  177. if (status != VDP_STATUS_OK)
  178. return vdpau_error(status);
  179. else
  180. info = func;
  181. status = info(&info_string);
  182. if (status != VDP_STATUS_OK)
  183. return vdpau_error(status);
  184. if (avctx->codec_id == AV_CODEC_ID_HEVC && strncmp(info_string, "NVIDIA ", 7) == 0 &&
  185. !(avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) {
  186. int driver_version = 0;
  187. sscanf(info_string, "NVIDIA VDPAU Driver Shared Library %d", &driver_version);
  188. if (driver_version < 410) {
  189. av_log(avctx, AV_LOG_VERBOSE, "HEVC with NVIDIA VDPAU drivers is buggy, skipping.\n");
  190. return AVERROR(ENOTSUP);
  191. }
  192. }
  193. status = vdctx->get_proc_address(vdctx->device,
  194. VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES,
  195. &func);
  196. if (status != VDP_STATUS_OK)
  197. return vdpau_error(status);
  198. else
  199. surface_query_caps = func;
  200. status = surface_query_caps(vdctx->device, type, &supported,
  201. &max_width, &max_height);
  202. if (status != VDP_STATUS_OK)
  203. return vdpau_error(status);
  204. if (supported != VDP_TRUE ||
  205. max_width < width || max_height < height)
  206. return AVERROR(ENOTSUP);
  207. status = vdctx->get_proc_address(vdctx->device,
  208. VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES,
  209. &func);
  210. if (status != VDP_STATUS_OK)
  211. return vdpau_error(status);
  212. else
  213. decoder_query_caps = func;
  214. status = decoder_query_caps(vdctx->device, profile, &supported, &max_level,
  215. &max_mb, &max_width, &max_height);
  216. #ifdef VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE
  217. if ((status != VDP_STATUS_OK || supported != VDP_TRUE) && profile == VDP_DECODER_PROFILE_H264_CONSTRAINED_BASELINE) {
  218. profile = VDP_DECODER_PROFILE_H264_MAIN;
  219. status = decoder_query_caps(vdctx->device, profile, &supported,
  220. &max_level, &max_mb,
  221. &max_width, &max_height);
  222. }
  223. #endif
  224. if (status != VDP_STATUS_OK)
  225. return vdpau_error(status);
  226. if (supported != VDP_TRUE || max_level < level ||
  227. max_width < width || max_height < height)
  228. return AVERROR(ENOTSUP);
  229. status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_CREATE,
  230. &func);
  231. if (status != VDP_STATUS_OK)
  232. return vdpau_error(status);
  233. else
  234. create = func;
  235. status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_RENDER,
  236. &func);
  237. if (status != VDP_STATUS_OK)
  238. return vdpau_error(status);
  239. else
  240. vdctx->render = func;
  241. status = create(vdctx->device, profile, width, height, avctx->refs,
  242. &vdctx->decoder);
  243. if (status == VDP_STATUS_OK) {
  244. vdctx->width = avctx->coded_width;
  245. vdctx->height = avctx->coded_height;
  246. }
  247. return vdpau_error(status);
  248. }
  249. int ff_vdpau_common_uninit(AVCodecContext *avctx)
  250. {
  251. VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
  252. VdpDecoderDestroy *destroy;
  253. void *func;
  254. VdpStatus status;
  255. if (vdctx->device == VDP_INVALID_HANDLE)
  256. return 0; /* Decoder created and destroyed by user */
  257. if (vdctx->width == UINT32_MAX && vdctx->height == UINT32_MAX)
  258. return 0;
  259. status = vdctx->get_proc_address(vdctx->device,
  260. VDP_FUNC_ID_DECODER_DESTROY, &func);
  261. if (status != VDP_STATUS_OK)
  262. return vdpau_error(status);
  263. else
  264. destroy = func;
  265. status = destroy(vdctx->decoder);
  266. return vdpau_error(status);
  267. }
  268. static int ff_vdpau_common_reinit(AVCodecContext *avctx)
  269. {
  270. VDPAUHWContext *hwctx = avctx->hwaccel_context;
  271. VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
  272. if (vdctx->device == VDP_INVALID_HANDLE)
  273. return 0; /* Decoder created by user */
  274. if (avctx->coded_width == vdctx->width &&
  275. avctx->coded_height == vdctx->height && (!hwctx || !hwctx->reset))
  276. return 0;
  277. avctx->hwaccel->uninit(avctx);
  278. return avctx->hwaccel->init(avctx);
  279. }
  280. int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx,
  281. av_unused const uint8_t *buffer,
  282. av_unused uint32_t size)
  283. {
  284. pic_ctx->bitstream_buffers_allocated = 0;
  285. pic_ctx->bitstream_buffers_used = 0;
  286. pic_ctx->bitstream_buffers = NULL;
  287. return 0;
  288. }
  289. int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
  290. struct vdpau_picture_context *pic_ctx)
  291. {
  292. VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
  293. AVVDPAUContext *hwctx = avctx->hwaccel_context;
  294. VdpVideoSurface surf = ff_vdpau_get_surface_id(frame);
  295. VdpStatus status;
  296. int val;
  297. val = ff_vdpau_common_reinit(avctx);
  298. if (val < 0)
  299. return val;
  300. if (hwctx && !hwctx->render && hwctx->render2) {
  301. status = hwctx->render2(avctx, frame, (void *)&pic_ctx->info,
  302. pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
  303. } else
  304. status = vdctx->render(vdctx->decoder, surf, &pic_ctx->info,
  305. pic_ctx->bitstream_buffers_used,
  306. pic_ctx->bitstream_buffers);
  307. av_freep(&pic_ctx->bitstream_buffers);
  308. return vdpau_error(status);
  309. }
  310. #if CONFIG_MPEG1_VDPAU_HWACCEL || \
  311. CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
  312. CONFIG_VC1_VDPAU_HWACCEL || CONFIG_WMV3_VDPAU_HWACCEL
  313. int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
  314. {
  315. MpegEncContext *s = avctx->priv_data;
  316. Picture *pic = s->current_picture_ptr;
  317. struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
  318. int val;
  319. val = ff_vdpau_common_end_frame(avctx, pic->f, pic_ctx);
  320. if (val < 0)
  321. return val;
  322. ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
  323. return 0;
  324. }
  325. #endif
  326. int ff_vdpau_add_buffer(struct vdpau_picture_context *pic_ctx,
  327. const uint8_t *buf, uint32_t size)
  328. {
  329. VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers;
  330. buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated,
  331. (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers));
  332. if (!buffers)
  333. return AVERROR(ENOMEM);
  334. pic_ctx->bitstream_buffers = buffers;
  335. buffers += pic_ctx->bitstream_buffers_used++;
  336. buffers->struct_version = VDP_BITSTREAM_BUFFER_VERSION;
  337. buffers->bitstream = buf;
  338. buffers->bitstream_bytes = size;
  339. return 0;
  340. }
  341. #if FF_API_VDPAU_PROFILE
  342. int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
  343. {
  344. #define PROFILE(prof) \
  345. do { \
  346. *profile = VDP_DECODER_PROFILE_##prof; \
  347. return 0; \
  348. } while (0)
  349. switch (avctx->codec_id) {
  350. case AV_CODEC_ID_MPEG1VIDEO: PROFILE(MPEG1);
  351. case AV_CODEC_ID_MPEG2VIDEO:
  352. switch (avctx->profile) {
  353. case FF_PROFILE_MPEG2_MAIN: PROFILE(MPEG2_MAIN);
  354. case FF_PROFILE_MPEG2_SIMPLE: PROFILE(MPEG2_SIMPLE);
  355. default: return AVERROR(EINVAL);
  356. }
  357. case AV_CODEC_ID_H263: PROFILE(MPEG4_PART2_ASP);
  358. case AV_CODEC_ID_MPEG4:
  359. switch (avctx->profile) {
  360. case FF_PROFILE_MPEG4_SIMPLE: PROFILE(MPEG4_PART2_SP);
  361. case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: PROFILE(MPEG4_PART2_ASP);
  362. default: return AVERROR(EINVAL);
  363. }
  364. case AV_CODEC_ID_H264:
  365. switch (avctx->profile & ~FF_PROFILE_H264_INTRA) {
  366. case FF_PROFILE_H264_BASELINE: PROFILE(H264_BASELINE);
  367. case FF_PROFILE_H264_CONSTRAINED_BASELINE:
  368. case FF_PROFILE_H264_MAIN: PROFILE(H264_MAIN);
  369. case FF_PROFILE_H264_HIGH: PROFILE(H264_HIGH);
  370. #ifdef VDP_DECODER_PROFILE_H264_EXTENDED
  371. case FF_PROFILE_H264_EXTENDED: PROFILE(H264_EXTENDED);
  372. #endif
  373. default: return AVERROR(EINVAL);
  374. }
  375. case AV_CODEC_ID_WMV3:
  376. case AV_CODEC_ID_VC1:
  377. switch (avctx->profile) {
  378. case FF_PROFILE_VC1_SIMPLE: PROFILE(VC1_SIMPLE);
  379. case FF_PROFILE_VC1_MAIN: PROFILE(VC1_MAIN);
  380. case FF_PROFILE_VC1_ADVANCED: PROFILE(VC1_ADVANCED);
  381. default: return AVERROR(EINVAL);
  382. }
  383. }
  384. return AVERROR(EINVAL);
  385. #undef PROFILE
  386. }
  387. #endif /* FF_API_VDPAU_PROFILE */
  388. AVVDPAUContext *av_vdpau_alloc_context(void)
  389. {
  390. return av_mallocz(sizeof(VDPAUHWContext));
  391. }
  392. int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device,
  393. VdpGetProcAddress *get_proc, unsigned flags)
  394. {
  395. VDPAUHWContext *hwctx;
  396. if (flags & ~(AV_HWACCEL_FLAG_IGNORE_LEVEL|AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH))
  397. return AVERROR(EINVAL);
  398. if (av_reallocp(&avctx->hwaccel_context, sizeof(*hwctx)))
  399. return AVERROR(ENOMEM);
  400. hwctx = avctx->hwaccel_context;
  401. memset(hwctx, 0, sizeof(*hwctx));
  402. hwctx->context.decoder = VDP_INVALID_HANDLE;
  403. hwctx->device = device;
  404. hwctx->get_proc_address = get_proc;
  405. hwctx->flags = flags;
  406. hwctx->reset = 1;
  407. return 0;
  408. }
  409. /* @}*/