ffmpeg_qsv.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
  28. {
  29. InputStream *ist = s->opaque;
  30. return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0);
  31. }
  32. static void qsv_uninit(AVCodecContext *s)
  33. {
  34. InputStream *ist = s->opaque;
  35. av_buffer_unref(&ist->hw_frames_ctx);
  36. }
  37. static int qsv_device_init(InputStream *ist)
  38. {
  39. int err;
  40. err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV,
  41. ist->hwaccel_device, NULL, 0);
  42. if (err < 0) {
  43. av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n");
  44. return err;
  45. }
  46. return 0;
  47. }
  48. int qsv_init(AVCodecContext *s)
  49. {
  50. InputStream *ist = s->opaque;
  51. AVHWFramesContext *frames_ctx;
  52. AVQSVFramesContext *frames_hwctx;
  53. int ret;
  54. if (!hw_device_ctx) {
  55. ret = qsv_device_init(ist);
  56. if (ret < 0)
  57. return ret;
  58. }
  59. av_buffer_unref(&ist->hw_frames_ctx);
  60. ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
  61. if (!ist->hw_frames_ctx)
  62. return AVERROR(ENOMEM);
  63. frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
  64. frames_hwctx = frames_ctx->hwctx;
  65. frames_ctx->width = FFALIGN(s->coded_width, 32);
  66. frames_ctx->height = FFALIGN(s->coded_height, 32);
  67. frames_ctx->format = AV_PIX_FMT_QSV;
  68. frames_ctx->sw_format = s->sw_pix_fmt;
  69. frames_ctx->initial_pool_size = 64;
  70. frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
  71. ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
  72. if (ret < 0) {
  73. av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
  74. return ret;
  75. }
  76. ist->hwaccel_get_buffer = qsv_get_buffer;
  77. ist->hwaccel_uninit = qsv_uninit;
  78. return 0;
  79. }
  80. int qsv_transcode_init(OutputStream *ost)
  81. {
  82. InputStream *ist;
  83. const enum AVPixelFormat *pix_fmt;
  84. int err, i;
  85. AVBufferRef *encode_frames_ref = NULL;
  86. AVHWFramesContext *encode_frames;
  87. AVQSVFramesContext *qsv_frames;
  88. /* check if the encoder supports QSV */
  89. if (!ost->enc->pix_fmts)
  90. return 0;
  91. for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
  92. if (*pix_fmt == AV_PIX_FMT_QSV)
  93. break;
  94. if (*pix_fmt == AV_PIX_FMT_NONE)
  95. return 0;
  96. if (strcmp(ost->avfilter, "null") || ost->source_index < 0)
  97. return 0;
  98. /* check if the decoder supports QSV and the output only goes to this stream */
  99. ist = input_streams[ost->source_index];
  100. if (ist->hwaccel_id != HWACCEL_QSV || !ist->dec || !ist->dec->pix_fmts)
  101. return 0;
  102. for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
  103. if (*pix_fmt == AV_PIX_FMT_QSV)
  104. break;
  105. if (*pix_fmt == AV_PIX_FMT_NONE)
  106. return 0;
  107. for (i = 0; i < nb_output_streams; i++)
  108. if (output_streams[i] != ost &&
  109. output_streams[i]->source_index == ost->source_index)
  110. return 0;
  111. av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n");
  112. if (!hw_device_ctx) {
  113. err = qsv_device_init(ist);
  114. if (err < 0)
  115. goto fail;
  116. }
  117. // This creates a dummy hw_frames_ctx for the encoder to be
  118. // suitably initialised. It only contains one real frame, so
  119. // hopefully doesn't waste too much memory.
  120. encode_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
  121. if (!encode_frames_ref) {
  122. err = AVERROR(ENOMEM);
  123. goto fail;
  124. }
  125. encode_frames = (AVHWFramesContext*)encode_frames_ref->data;
  126. qsv_frames = encode_frames->hwctx;
  127. encode_frames->width = FFALIGN(ist->resample_width, 32);
  128. encode_frames->height = FFALIGN(ist->resample_height, 32);
  129. encode_frames->format = AV_PIX_FMT_QSV;
  130. encode_frames->sw_format = AV_PIX_FMT_NV12;
  131. encode_frames->initial_pool_size = 1;
  132. qsv_frames->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
  133. err = av_hwframe_ctx_init(encode_frames_ref);
  134. if (err < 0)
  135. goto fail;
  136. ist->dec_ctx->pix_fmt = AV_PIX_FMT_QSV;
  137. ist->resample_pix_fmt = AV_PIX_FMT_QSV;
  138. ost->enc_ctx->pix_fmt = AV_PIX_FMT_QSV;
  139. ost->enc_ctx->hw_frames_ctx = encode_frames_ref;
  140. return 0;
  141. fail:
  142. av_buffer_unref(&encode_frames_ref);
  143. return err;
  144. }