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.

165 lines
4.5KB

  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. MFXQueryIMPL(*session, &impl);
  94. switch (MFX_IMPL_BASETYPE(impl)) {
  95. case MFX_IMPL_SOFTWARE:
  96. desc = "software";
  97. break;
  98. case MFX_IMPL_HARDWARE:
  99. case MFX_IMPL_HARDWARE2:
  100. case MFX_IMPL_HARDWARE3:
  101. case MFX_IMPL_HARDWARE4:
  102. desc = "hardware accelerated";
  103. break;
  104. default:
  105. desc = "unknown";
  106. }
  107. if (load_plugins && *load_plugins) {
  108. while (*load_plugins) {
  109. mfxPluginUID uid;
  110. int i, err = 0;
  111. char *plugin = av_get_token(&load_plugins, ":");
  112. if (!plugin)
  113. return AVERROR(ENOMEM);
  114. if (strlen(plugin) != 2 * sizeof(uid.Data)) {
  115. av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID length\n");
  116. err = AVERROR(EINVAL);
  117. goto load_plugin_fail;
  118. }
  119. for (i = 0; i < sizeof(uid.Data); i++) {
  120. err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i);
  121. if (err != 1) {
  122. av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID\n");
  123. err = AVERROR(EINVAL);
  124. goto load_plugin_fail;
  125. }
  126. }
  127. ret = MFXVideoUSER_Load(*session, &uid, 1);
  128. if (ret < 0) {
  129. av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n",
  130. plugin);
  131. err = ff_qsv_error(ret);
  132. goto load_plugin_fail;
  133. }
  134. load_plugin_fail:
  135. av_freep(&plugin);
  136. if (err < 0)
  137. return err;
  138. }
  139. }
  140. av_log(avctx, AV_LOG_VERBOSE,
  141. "Initialized an internal MFX session using %s implementation\n",
  142. desc);
  143. return 0;
  144. }