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.

167 lines
4.6KB

  1. /*
  2. * Intel MediaSDK QSV encoder/decoder shared code
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * Libav is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <mfx/mfxvideo.h>
  21. #include <mfx/mfxplugin.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "libavutil/avstring.h"
  25. #include "libavutil/error.h"
  26. #include "avcodec.h"
  27. #include "qsv_internal.h"
  28. int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
  29. {
  30. switch (codec_id) {
  31. case AV_CODEC_ID_H264:
  32. return MFX_CODEC_AVC;
  33. #if QSV_VERSION_ATLEAST(1, 8)
  34. case AV_CODEC_ID_HEVC:
  35. return MFX_CODEC_HEVC;
  36. #endif
  37. case AV_CODEC_ID_MPEG1VIDEO:
  38. case AV_CODEC_ID_MPEG2VIDEO:
  39. return MFX_CODEC_MPEG2;
  40. case AV_CODEC_ID_VC1:
  41. return MFX_CODEC_VC1;
  42. default:
  43. break;
  44. }
  45. return AVERROR(ENOSYS);
  46. }
  47. int ff_qsv_error(int mfx_err)
  48. {
  49. switch (mfx_err) {
  50. case MFX_ERR_NONE:
  51. return 0;
  52. case MFX_ERR_MEMORY_ALLOC:
  53. case MFX_ERR_NOT_ENOUGH_BUFFER:
  54. return AVERROR(ENOMEM);
  55. case MFX_ERR_INVALID_HANDLE:
  56. return AVERROR(EINVAL);
  57. case MFX_ERR_DEVICE_FAILED:
  58. case MFX_ERR_DEVICE_LOST:
  59. case MFX_ERR_LOCK_MEMORY:
  60. return AVERROR(EIO);
  61. case MFX_ERR_NULL_PTR:
  62. case MFX_ERR_UNDEFINED_BEHAVIOR:
  63. case MFX_ERR_NOT_INITIALIZED:
  64. return AVERROR_BUG;
  65. case MFX_ERR_UNSUPPORTED:
  66. case MFX_ERR_NOT_FOUND:
  67. return AVERROR(ENOSYS);
  68. case MFX_ERR_MORE_DATA:
  69. case MFX_ERR_MORE_SURFACE:
  70. case MFX_ERR_MORE_BITSTREAM:
  71. return AVERROR(EAGAIN);
  72. case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
  73. case MFX_ERR_INVALID_VIDEO_PARAM:
  74. return AVERROR(EINVAL);
  75. case MFX_ERR_ABORTED:
  76. case MFX_ERR_UNKNOWN:
  77. default:
  78. return AVERROR_UNKNOWN;
  79. }
  80. }
  81. int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
  82. const char *load_plugins)
  83. {
  84. mfxIMPL impl = MFX_IMPL_AUTO_ANY;
  85. mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
  86. const char *desc;
  87. int ret;
  88. ret = MFXInit(impl, &ver, session);
  89. if (ret < 0) {
  90. av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n");
  91. return ff_qsv_error(ret);
  92. }
  93. if (load_plugins && *load_plugins) {
  94. while (*load_plugins) {
  95. mfxPluginUID uid;
  96. int i, err = 0;
  97. char *plugin = av_get_token(&load_plugins, ":");
  98. if (!plugin)
  99. return AVERROR(ENOMEM);
  100. if (strlen(plugin) != 2 * sizeof(uid.Data)) {
  101. av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID length\n");
  102. err = AVERROR(EINVAL);
  103. goto load_plugin_fail;
  104. }
  105. for (i = 0; i < sizeof(uid.Data); i++) {
  106. err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i);
  107. if (err != 1) {
  108. av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID\n");
  109. err = AVERROR(EINVAL);
  110. goto load_plugin_fail;
  111. }
  112. }
  113. ret = MFXVideoUSER_Load(*session, &uid, 1);
  114. if (ret < 0) {
  115. av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
  116. plugin);
  117. err = ff_qsv_error(ret);
  118. goto load_plugin_fail;
  119. }
  120. if (*load_plugins)
  121. load_plugins++;
  122. load_plugin_fail:
  123. av_freep(&plugin);
  124. if (err < 0)
  125. return err;
  126. }
  127. }
  128. MFXQueryIMPL(*session, &impl);
  129. switch (MFX_IMPL_BASETYPE(impl)) {
  130. case MFX_IMPL_SOFTWARE:
  131. desc = "software";
  132. break;
  133. case MFX_IMPL_HARDWARE:
  134. case MFX_IMPL_HARDWARE2:
  135. case MFX_IMPL_HARDWARE3:
  136. case MFX_IMPL_HARDWARE4:
  137. desc = "hardware accelerated";
  138. break;
  139. default:
  140. desc = "unknown";
  141. }
  142. av_log(avctx, AV_LOG_VERBOSE,
  143. "Initialized an internal MFX session using %s implementation\n",
  144. desc);
  145. return 0;
  146. }