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.

314 lines
9.5KB

  1. /*
  2. * Intel MediaSDK QSV based H.264 / HEVC decoder
  3. *
  4. * copyright (c) 2013 Luca Barbato
  5. * copyright (c) 2015 Anton Khirnov
  6. *
  7. * This file is part of Libav.
  8. *
  9. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. #include <stdint.h>
  24. #include <string.h>
  25. #include <mfx/mfxvideo.h>
  26. #include "libavutil/common.h"
  27. #include "libavutil/fifo.h"
  28. #include "libavutil/opt.h"
  29. #include "avcodec.h"
  30. #include "internal.h"
  31. #include "qsv_internal.h"
  32. #include "qsvdec.h"
  33. #include "qsv.h"
  34. enum LoadPlugin {
  35. LOAD_PLUGIN_NONE,
  36. LOAD_PLUGIN_HEVC_SW,
  37. LOAD_PLUGIN_HEVC_HW,
  38. };
  39. typedef struct QSVH2645Context {
  40. AVClass *class;
  41. QSVContext qsv;
  42. int load_plugin;
  43. // the filter for converting to Annex B
  44. AVBSFContext *bsf;
  45. AVFifoBuffer *packet_fifo;
  46. AVPacket pkt_filtered;
  47. } QSVH2645Context;
  48. static void qsv_clear_buffers(QSVH2645Context *s)
  49. {
  50. AVPacket pkt;
  51. while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) {
  52. av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL);
  53. av_packet_unref(&pkt);
  54. }
  55. av_bsf_free(&s->bsf);
  56. av_packet_unref(&s->pkt_filtered);
  57. }
  58. static av_cold int qsv_decode_close(AVCodecContext *avctx)
  59. {
  60. QSVH2645Context *s = avctx->priv_data;
  61. ff_qsv_decode_close(&s->qsv);
  62. qsv_clear_buffers(s);
  63. av_fifo_free(s->packet_fifo);
  64. return 0;
  65. }
  66. static av_cold int qsv_decode_init(AVCodecContext *avctx)
  67. {
  68. QSVH2645Context *s = avctx->priv_data;
  69. int ret;
  70. if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
  71. static const char *uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
  72. static const char *uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
  73. if (s->qsv.load_plugins[0]) {
  74. av_log(avctx, AV_LOG_WARNING,
  75. "load_plugins is not empty, but load_plugin is not set to 'none'."
  76. "The load_plugin value will be ignored.\n");
  77. } else {
  78. av_freep(&s->qsv.load_plugins);
  79. if (s->load_plugin == LOAD_PLUGIN_HEVC_SW)
  80. s->qsv.load_plugins = av_strdup(uid_hevcdec_sw);
  81. else
  82. s->qsv.load_plugins = av_strdup(uid_hevcdec_hw);
  83. if (!s->qsv.load_plugins)
  84. return AVERROR(ENOMEM);
  85. }
  86. }
  87. s->packet_fifo = av_fifo_alloc(sizeof(AVPacket));
  88. if (!s->packet_fifo) {
  89. ret = AVERROR(ENOMEM);
  90. goto fail;
  91. }
  92. return 0;
  93. fail:
  94. qsv_decode_close(avctx);
  95. return ret;
  96. }
  97. static int qsv_init_bsf(AVCodecContext *avctx, QSVH2645Context *s)
  98. {
  99. const char *filter_name = avctx->codec_id == AV_CODEC_ID_HEVC ?
  100. "hevc_mp4toannexb" : "h264_mp4toannexb";
  101. const AVBitStreamFilter *filter;
  102. int ret;
  103. if (s->bsf)
  104. return 0;
  105. filter = av_bsf_get_by_name(filter_name);
  106. if (!filter)
  107. return AVERROR_BUG;
  108. ret = av_bsf_alloc(filter, &s->bsf);
  109. if (ret < 0)
  110. return ret;
  111. ret = avcodec_parameters_from_context(s->bsf->par_in, avctx);
  112. if (ret < 0)
  113. return ret;
  114. s->bsf->time_base_in = avctx->time_base;
  115. ret = av_bsf_init(s->bsf);
  116. if (ret < 0)
  117. return ret;
  118. return ret;
  119. }
  120. static int qsv_decode_frame(AVCodecContext *avctx, void *data,
  121. int *got_frame, AVPacket *avpkt)
  122. {
  123. QSVH2645Context *s = avctx->priv_data;
  124. AVFrame *frame = data;
  125. int ret;
  126. /* make sure the bitstream filter is initialized */
  127. ret = qsv_init_bsf(avctx, s);
  128. if (ret < 0)
  129. return ret;
  130. /* buffer the input packet */
  131. if (avpkt->size) {
  132. AVPacket input_ref = { 0 };
  133. if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) {
  134. ret = av_fifo_realloc2(s->packet_fifo,
  135. av_fifo_size(s->packet_fifo) + sizeof(input_ref));
  136. if (ret < 0)
  137. return ret;
  138. }
  139. ret = av_packet_ref(&input_ref, avpkt);
  140. if (ret < 0)
  141. return ret;
  142. av_fifo_generic_write(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
  143. }
  144. /* process buffered data */
  145. while (!*got_frame) {
  146. /* prepare the input data -- convert to Annex B if needed */
  147. if (s->pkt_filtered.size <= 0) {
  148. AVPacket input_ref;
  149. /* no more data */
  150. if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
  151. return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
  152. av_packet_unref(&s->pkt_filtered);
  153. av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL);
  154. ret = av_bsf_send_packet(s->bsf, &input_ref);
  155. if (ret < 0) {
  156. av_packet_unref(&input_ref);
  157. return ret;
  158. }
  159. ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered);
  160. if (ret < 0)
  161. av_packet_move_ref(&s->pkt_filtered, &input_ref);
  162. else
  163. av_packet_unref(&input_ref);
  164. }
  165. ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->pkt_filtered);
  166. if (ret < 0)
  167. return ret;
  168. s->pkt_filtered.size -= ret;
  169. s->pkt_filtered.data += ret;
  170. }
  171. return avpkt->size;
  172. }
  173. static void qsv_decode_flush(AVCodecContext *avctx)
  174. {
  175. QSVH2645Context *s = avctx->priv_data;
  176. qsv_clear_buffers(s);
  177. ff_qsv_decode_flush(avctx, &s->qsv);
  178. }
  179. #define OFFSET(x) offsetof(QSVH2645Context, x)
  180. #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
  181. #if CONFIG_HEVC_QSV_DECODER
  182. AVHWAccel ff_hevc_qsv_hwaccel = {
  183. .name = "hevc_qsv",
  184. .type = AVMEDIA_TYPE_VIDEO,
  185. .id = AV_CODEC_ID_HEVC,
  186. .pix_fmt = AV_PIX_FMT_QSV,
  187. };
  188. static const AVOption hevc_options[] = {
  189. { "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 }, 0, INT_MAX, VD },
  190. { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_SW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" },
  191. { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, "load_plugin" },
  192. { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, "load_plugin" },
  193. { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, "load_plugin" },
  194. { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
  195. OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
  196. { NULL },
  197. };
  198. static const AVClass hevc_class = {
  199. .class_name = "hevc_qsv",
  200. .item_name = av_default_item_name,
  201. .option = hevc_options,
  202. .version = LIBAVUTIL_VERSION_INT,
  203. };
  204. AVCodec ff_hevc_qsv_decoder = {
  205. .name = "hevc_qsv",
  206. .long_name = NULL_IF_CONFIG_SMALL("HEVC (Intel Quick Sync Video acceleration)"),
  207. .priv_data_size = sizeof(QSVH2645Context),
  208. .type = AVMEDIA_TYPE_VIDEO,
  209. .id = AV_CODEC_ID_HEVC,
  210. .init = qsv_decode_init,
  211. .decode = qsv_decode_frame,
  212. .flush = qsv_decode_flush,
  213. .close = qsv_decode_close,
  214. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
  215. .priv_class = &hevc_class,
  216. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  217. AV_PIX_FMT_QSV,
  218. AV_PIX_FMT_NONE },
  219. };
  220. #endif
  221. #if CONFIG_H264_QSV_DECODER
  222. AVHWAccel ff_h264_qsv_hwaccel = {
  223. .name = "h264_qsv",
  224. .type = AVMEDIA_TYPE_VIDEO,
  225. .id = AV_CODEC_ID_H264,
  226. .pix_fmt = AV_PIX_FMT_QSV,
  227. };
  228. static const AVOption options[] = {
  229. { "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 }, 0, INT_MAX, VD },
  230. { NULL },
  231. };
  232. static const AVClass class = {
  233. .class_name = "h264_qsv",
  234. .item_name = av_default_item_name,
  235. .option = options,
  236. .version = LIBAVUTIL_VERSION_INT,
  237. };
  238. AVCodec ff_h264_qsv_decoder = {
  239. .name = "h264_qsv",
  240. .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration)"),
  241. .priv_data_size = sizeof(QSVH2645Context),
  242. .type = AVMEDIA_TYPE_VIDEO,
  243. .id = AV_CODEC_ID_H264,
  244. .init = qsv_decode_init,
  245. .decode = qsv_decode_frame,
  246. .flush = qsv_decode_flush,
  247. .close = qsv_decode_close,
  248. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
  249. .priv_class = &class,
  250. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
  251. AV_PIX_FMT_QSV,
  252. AV_PIX_FMT_NONE },
  253. };
  254. #endif