qsvdec_other.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. * Intel MediaSDK QSV based MPEG-2, VC-1, VP8, MJPEG, VP9 and AV1 decoders
  3. *
  4. * copyright (c) 2015 Anton Khirnov
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <mfx/mfxvideo.h>
  25. #include "libavutil/common.h"
  26. #include "libavutil/fifo.h"
  27. #include "libavutil/opt.h"
  28. #include "avcodec.h"
  29. #include "internal.h"
  30. #include "qsv_internal.h"
  31. #include "qsvdec.h"
  32. #include "qsv.h"
  33. typedef struct QSVOtherContext {
  34. AVClass *class;
  35. QSVContext qsv;
  36. AVFifoBuffer *packet_fifo;
  37. AVPacket input_ref;
  38. } QSVOtherContext;
  39. static void qsv_clear_buffers(QSVOtherContext *s)
  40. {
  41. AVPacket pkt;
  42. while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
  43. av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
  44. av_packet_unref(&pkt);
  45. }
  46. av_packet_unref(&s->input_ref);
  47. }
  48. static av_cold int qsv_decode_close(AVCodecContext *avctx)
  49. {
  50. QSVOtherContext *s = avctx->priv_data;
  51. #if CONFIG_VP8_QSV_DECODER || CONFIG_VP9_QSV_DECODER
  52. if (avctx->codec_id == AV_CODEC_ID_VP8 || avctx->codec_id == AV_CODEC_ID_VP9)
  53. av_freep(&s->qsv.load_plugins);
  54. #endif
  55. ff_qsv_decode_close(&s->qsv);
  56. qsv_clear_buffers(s);
  57. av_fifo_free(s->packet_fifo);
  58. return 0;
  59. }
  60. static av_cold int qsv_decode_init(AVCodecContext *avctx)
  61. {
  62. QSVOtherContext *s = avctx->priv_data;
  63. int ret;
  64. #if CONFIG_VP8_QSV_DECODER
  65. if (avctx->codec_id == AV_CODEC_ID_VP8) {
  66. static const char *uid_vp8dec_hw = "f622394d8d87452f878c51f2fc9b4131";
  67. av_freep(&s->qsv.load_plugins);
  68. s->qsv.load_plugins = av_strdup(uid_vp8dec_hw);
  69. if (!s->qsv.load_plugins)
  70. return AVERROR(ENOMEM);
  71. }
  72. #endif
  73. #if CONFIG_VP9_QSV_DECODER
  74. if (avctx->codec_id == AV_CODEC_ID_VP9) {
  75. static const char *uid_vp9dec_hw = "a922394d8d87452f878c51f2fc9b4131";
  76. av_freep(&s->qsv.load_plugins);
  77. s->qsv.load_plugins = av_strdup(uid_vp9dec_hw);
  78. if (!s->qsv.load_plugins)
  79. return AVERROR(ENOMEM);
  80. }
  81. #endif
  82. s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12;
  83. s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
  84. if (!s->packet_fifo) {
  85. ret = AVERROR(ENOMEM);
  86. goto fail;
  87. }
  88. return 0;
  89. fail:
  90. qsv_decode_close(avctx);
  91. return ret;
  92. }
  93. static int qsv_decode_frame(AVCodecContext *avctx, void *data,
  94. int *got_frame, AVPacket *avpkt)
  95. {
  96. QSVOtherContext *s = avctx->priv_data;
  97. AVFrame *frame = data;
  98. int ret;
  99. /* buffer the input packet */
  100. if (avpkt->size) {
  101. AVPacket input_ref;
  102. if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
  103. ret = av_fifo_realloc2(s->packet_fifo,
  104. av_fifo_size(s->packet_fifo) + sizeof(input_ref));
  105. if (ret < 0)
  106. return ret;
  107. }
  108. ret = av_packet_ref(&input_ref, avpkt);
  109. if (ret < 0)
  110. return ret;
  111. av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
  112. }
  113. /* process buffered data */
  114. while (!*got_frame) {
  115. if (s->input_ref.size <= 0) {
  116. /* no more data */
  117. if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
  118. return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
  119. /* in progress of reinit, no read from fifo and keep the buffer_pkt */
  120. if (!s->qsv.reinit_flag) {
  121. av_packet_unref(&s->input_ref);
  122. av_fifo_generic_read(s->packet_fifo, &s->input_ref, sizeof(s->input_ref), NULL);
  123. }
  124. }
  125. ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->input_ref);
  126. if (ret < 0) {
  127. /* Drop input packet when failed to decode the packet. Otherwise,
  128. the decoder will keep decoding the failure packet. */
  129. av_packet_unref(&s->input_ref);
  130. return ret;
  131. }
  132. if (s->qsv.reinit_flag)
  133. continue;
  134. s->input_ref.size -= ret;
  135. s->input_ref.data += ret;
  136. }
  137. return avpkt->size;
  138. }
  139. static void qsv_decode_flush(AVCodecContext *avctx)
  140. {
  141. QSVOtherContext *s = avctx->priv_data;
  142. qsv_clear_buffers(s);
  143. ff_qsv_decode_flush(avctx, &s->qsv);
  144. }
  145. #define OFFSET(x) offsetof(QSVOtherContext, x)
  146. #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
  147. static const AVOption options[] = {
  148. { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
  149. { "gpu_copy", "A GPU-accelerated copy between video and system memory", OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"},
  150. { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, "gpu_copy"},
  151. { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, "gpu_copy"},
  152. { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, "gpu_copy"},
  153. { NULL },
  154. };
  155. #if CONFIG_MPEG2_QSV_DECODER
  156. static const AVClass mpeg2_qsv_class = {
  157. .class_name = "mpeg2_qsv",
  158. .item_name = av_default_item_name,
  159. .option = options,
  160. .version = LIBAVUTIL_VERSION_INT,
  161. };
  162. AVCodec ff_mpeg2_qsv_decoder = {
  163. .name = "mpeg2_qsv",
  164. .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video (Intel Quick Sync Video acceleration)"),
  165. .priv_data_size = sizeof(QSVOtherContext),
  166. .type = AVMEDIA_TYPE_VIDEO,
  167. .id = AV_CODEC_ID_MPEG2VIDEO,
  168. .init = qsv_decode_init,
  169. .decode = qsv_decode_frame,
  170. .flush = qsv_decode_flush,
  171. .close = qsv_decode_close,
  172. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  173. .priv_class = &mpeg2_qsv_class,
  174. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  175. AV_PIX_FMT_QSV,
  176. AV_PIX_FMT_NONE },
  177. .hw_configs = ff_qsv_hw_configs,
  178. .wrapper_name = "qsv",
  179. };
  180. #endif
  181. #if CONFIG_VC1_QSV_DECODER
  182. static const AVClass vc1_qsv_class = {
  183. .class_name = "vc1_qsv",
  184. .item_name = av_default_item_name,
  185. .option = options,
  186. .version = LIBAVUTIL_VERSION_INT,
  187. };
  188. AVCodec ff_vc1_qsv_decoder = {
  189. .name = "vc1_qsv",
  190. .long_name = NULL_IF_CONFIG_SMALL("VC-1 video (Intel Quick Sync Video acceleration)"),
  191. .priv_data_size = sizeof(QSVOtherContext),
  192. .type = AVMEDIA_TYPE_VIDEO,
  193. .id = AV_CODEC_ID_VC1,
  194. .init = qsv_decode_init,
  195. .decode = qsv_decode_frame,
  196. .flush = qsv_decode_flush,
  197. .close = qsv_decode_close,
  198. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  199. .priv_class = &vc1_qsv_class,
  200. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  201. AV_PIX_FMT_QSV,
  202. AV_PIX_FMT_NONE },
  203. .hw_configs = ff_qsv_hw_configs,
  204. .wrapper_name = "qsv",
  205. };
  206. #endif
  207. #if CONFIG_VP8_QSV_DECODER
  208. static const AVClass vp8_qsv_class = {
  209. .class_name = "vp8_qsv",
  210. .item_name = av_default_item_name,
  211. .option = options,
  212. .version = LIBAVUTIL_VERSION_INT,
  213. };
  214. AVCodec ff_vp8_qsv_decoder = {
  215. .name = "vp8_qsv",
  216. .long_name = NULL_IF_CONFIG_SMALL("VP8 video (Intel Quick Sync Video acceleration)"),
  217. .priv_data_size = sizeof(QSVOtherContext),
  218. .type = AVMEDIA_TYPE_VIDEO,
  219. .id = AV_CODEC_ID_VP8,
  220. .init = qsv_decode_init,
  221. .decode = qsv_decode_frame,
  222. .flush = qsv_decode_flush,
  223. .close = qsv_decode_close,
  224. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  225. .priv_class = &vp8_qsv_class,
  226. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  227. AV_PIX_FMT_QSV,
  228. AV_PIX_FMT_NONE },
  229. .hw_configs = ff_qsv_hw_configs,
  230. .wrapper_name = "qsv",
  231. };
  232. #endif
  233. #if CONFIG_MJPEG_QSV_DECODER
  234. static const AVClass mjpeg_qsv_class = {
  235. .class_name = "mjpeg_qsv",
  236. .item_name = av_default_item_name,
  237. .option = options,
  238. .version = LIBAVUTIL_VERSION_INT,
  239. };
  240. AVCodec ff_mjpeg_qsv_decoder = {
  241. .name = "mjpeg_qsv",
  242. .long_name = NULL_IF_CONFIG_SMALL("MJPEG video (Intel Quick Sync Video acceleration)"),
  243. .priv_data_size = sizeof(QSVOtherContext),
  244. .type = AVMEDIA_TYPE_VIDEO,
  245. .id = AV_CODEC_ID_MJPEG,
  246. .init = qsv_decode_init,
  247. .decode = qsv_decode_frame,
  248. .flush = qsv_decode_flush,
  249. .close = qsv_decode_close,
  250. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  251. .priv_class = &mjpeg_qsv_class,
  252. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  253. AV_PIX_FMT_QSV,
  254. AV_PIX_FMT_NONE },
  255. };
  256. #endif
  257. #if CONFIG_VP9_QSV_DECODER
  258. static const AVClass vp9_qsv_class = {
  259. .class_name = "vp9_qsv",
  260. .item_name = av_default_item_name,
  261. .option = options,
  262. .version = LIBAVUTIL_VERSION_INT,
  263. };
  264. AVCodec ff_vp9_qsv_decoder = {
  265. .name = "vp9_qsv",
  266. .long_name = NULL_IF_CONFIG_SMALL("VP9 video (Intel Quick Sync Video acceleration)"),
  267. .priv_data_size = sizeof(QSVOtherContext),
  268. .type = AVMEDIA_TYPE_VIDEO,
  269. .id = AV_CODEC_ID_VP9,
  270. .init = qsv_decode_init,
  271. .decode = qsv_decode_frame,
  272. .flush = qsv_decode_flush,
  273. .close = qsv_decode_close,
  274. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  275. .priv_class = &vp9_qsv_class,
  276. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  277. AV_PIX_FMT_P010,
  278. AV_PIX_FMT_QSV,
  279. AV_PIX_FMT_NONE },
  280. .hw_configs = ff_qsv_hw_configs,
  281. .wrapper_name = "qsv",
  282. };
  283. #endif
  284. #if CONFIG_AV1_QSV_DECODER
  285. static const AVClass av1_qsv_class = {
  286. .class_name = "av1_qsv",
  287. .item_name = av_default_item_name,
  288. .option = options,
  289. .version = LIBAVUTIL_VERSION_INT,
  290. };
  291. AVCodec ff_av1_qsv_decoder = {
  292. .name = "av1_qsv",
  293. .long_name = NULL_IF_CONFIG_SMALL("AV1 video (Intel Quick Sync Video acceleration)"),
  294. .priv_data_size = sizeof(QSVOtherContext),
  295. .type = AVMEDIA_TYPE_VIDEO,
  296. .id = AV_CODEC_ID_AV1,
  297. .init = qsv_decode_init,
  298. .decode = qsv_decode_frame,
  299. .flush = qsv_decode_flush,
  300. .close = qsv_decode_close,
  301. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID,
  302. .priv_class = &av1_qsv_class,
  303. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  304. AV_PIX_FMT_P010,
  305. AV_PIX_FMT_QSV,
  306. AV_PIX_FMT_NONE },
  307. .hw_configs = ff_qsv_hw_configs,
  308. .wrapper_name = "qsv",
  309. };
  310. #endif