ffmpeg_qsv.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg 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. * FFmpeg 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 FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <mfx/mfxvideo.h>
  19. #include <stdlib.h>
  20. #include "libavutil/dict.h"
  21. #include "libavutil/hwcontext.h"
  22. #include "libavutil/hwcontext_qsv.h"
  23. #include "libavutil/mem.h"
  24. #include "libavutil/opt.h"
  25. #include "libavcodec/qsv.h"
  26. #include "ffmpeg.h"
  27. char *qsv_device = NULL;
  28. static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
  29. {
  30. InputStream *ist = s->opaque;
  31. return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0);
  32. }
  33. static void qsv_uninit(AVCodecContext *s)
  34. {
  35. InputStream *ist = s->opaque;
  36. av_buffer_unref(&ist->hw_frames_ctx);
  37. }
  38. static int qsv_device_init(InputStream *ist)
  39. {
  40. int err;
  41. AVDictionary *dict = NULL;
  42. if (qsv_device) {
  43. err = av_dict_set(&dict, "child_device", qsv_device, 0);
  44. if (err < 0)
  45. return err;
  46. }
  47. err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV,
  48. ist->hwaccel_device, dict, 0);
  49. if (err < 0) {
  50. av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n");
  51. goto err_out;
  52. }
  53. err_out:
  54. if (dict)
  55. av_dict_free(&dict);
  56. return err;
  57. }
  58. int qsv_init(AVCodecContext *s)
  59. {
  60. InputStream *ist = s->opaque;
  61. AVHWFramesContext *frames_ctx;
  62. AVQSVFramesContext *frames_hwctx;
  63. int ret;
  64. if (!hw_device_ctx) {
  65. ret = qsv_device_init(ist);
  66. if (ret < 0)
  67. return ret;
  68. }
  69. av_buffer_unref(&ist->hw_frames_ctx);
  70. ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
  71. if (!ist->hw_frames_ctx)
  72. return AVERROR(ENOMEM);
  73. frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
  74. frames_hwctx = frames_ctx->hwctx;
  75. frames_ctx->width = FFALIGN(s->coded_width, 32);
  76. frames_ctx->height = FFALIGN(s->coded_height, 32);
  77. frames_ctx->format = AV_PIX_FMT_QSV;
  78. frames_ctx->sw_format = s->sw_pix_fmt;
  79. frames_ctx->initial_pool_size = 64;
  80. frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
  81. ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
  82. if (ret < 0) {
  83. av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
  84. return ret;
  85. }
  86. ist->hwaccel_get_buffer = qsv_get_buffer;
  87. ist->hwaccel_uninit = qsv_uninit;
  88. return 0;
  89. }