Signed-off-by: nablet developer <s...@nablet.com> --- libavcodec/qsv.c | 64 +++++++++++++++++++++-------------------------- libavcodec/qsv.h | 53 +++++++++++++++++++++++++++++++++++++++ libavcodec/qsv_api.c | 26 +++++++++++++++++++ libavcodec/qsv_internal.h | 15 +---------- libavcodec/qsvdec.c | 13 +++++----- libavcodec/qsvdec.h | 3 ++- libavcodec/qsvenc.c | 16 ++++++------ libavcodec/qsvenc.h | 2 +- 8 files changed, 125 insertions(+), 67 deletions(-)
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 4c8e6b0..81d1f0c 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -18,14 +18,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <mfx/mfxvideo.h> -#include <mfx/mfxplugin.h> - #include <stdio.h> #include <string.h> #include "libavutil/avstring.h" #include "libavutil/error.h" +#include "libavutil/log.h" + +#include "qsv.h" + +#if CONFIG_QSV + +#include <mfx/mfxvideo.h> +#include <mfx/mfxplugin.h> #include "avcodec.h" #include "qsv_internal.h" @@ -51,7 +56,7 @@ int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) return AVERROR(ENOSYS); } -int ff_qsv_error(int mfx_err) +int av_qsv_error(int mfx_err) { switch (mfx_err) { case MFX_ERR_NONE: @@ -85,7 +90,7 @@ int ff_qsv_error(int mfx_err) return AVERROR_UNKNOWN; } } -static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) +static int ff_qsv_set_display_handle(AVClass *avccl, struct AVQSVSession *qs) { // this code is only required for Linux. It searches for a valid // display handle. First in /dev/dri/renderD then in /dev/dri/card @@ -115,14 +120,14 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) fd = open(adapterpath, O_RDWR); if (fd < 0) { - av_log(avctx, AV_LOG_ERROR, + av_log(avccl, AV_LOG_ERROR, "mfx init: %s fd open failed\n", adapterpath); continue; } va_dpy = vaGetDisplayDRM(fd); if (!va_dpy) { - av_log(avctx, AV_LOG_ERROR, + av_log(avccl, AV_LOG_ERROR, "mfx init: %s vaGetDisplayDRM failed\n", adapterpath); close(fd); continue; @@ -130,22 +135,22 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) va_res = vaInitialize(va_dpy, &major_version, &minor_version); if (VA_STATUS_SUCCESS != va_res) { - av_log(avctx, AV_LOG_ERROR, + av_log(avccl, AV_LOG_ERROR, "mfx init: %s vaInitialize failed\n", adapterpath); close(fd); fd = -1; continue; } else { - av_log(avctx, AV_LOG_VERBOSE, + av_log(avccl, AV_LOG_VERBOSE, "mfx initialization: %s vaInitialize successful\n",adapterpath); qs->fd_display = fd; qs->va_display = va_dpy; ret = MFXVideoCORE_SetHandle(qs->session, (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy); if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, + av_log(avccl, AV_LOG_ERROR, "Error %d during set display handle\n", ret); - return ff_qsv_error(ret); + return av_qsv_error(ret); } break; } @@ -153,22 +158,7 @@ static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) #endif //AVCODEC_QSV_LINUX_SESSION_HANDLE return 0; } -/** - * @brief Initialize a MSDK session - * - * Media SDK is based on sessions, so this is the prerequisite - * initialization for HW acceleration. For Windows the session is - * complete and ready to use, for Linux a display handle is - * required. For releases of Media Server Studio >= 2015 R4 the - * render nodes interface is preferred (/dev/dri/renderD). - * Using Media Server Studio 2015 R4 or newer is recommended - * but the older /dev/dri/card interface is also searched - * for broader compatibility. - * - * @param avctx ffmpeg metadata for this codec context - * @param session the MSDK session used - */ -int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, +int av_qsv_init_session(AVClass *avccl, struct AVQSVSession *qs, const char *load_plugins) { mfxIMPL impl = MFX_IMPL_AUTO_ANY; @@ -179,11 +169,11 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, ret = MFXInit(impl, &ver, &qs->session); if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); - return ff_qsv_error(ret); + av_log(avccl, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); + return av_qsv_error(ret); } - ret = ff_qsv_set_display_handle(avctx, qs); + ret = ff_qsv_set_display_handle(avccl, qs); if (ret < 0) return ret; @@ -212,7 +202,7 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, if (!plugin) return AVERROR(ENOMEM); if (strlen(plugin) != 2 * sizeof(uid.Data)) { - av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID length\n"); + av_log(avccl, AV_LOG_ERROR, "Invalid plugin UID length\n"); err = AVERROR(EINVAL); goto load_plugin_fail; } @@ -220,7 +210,7 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, for (i = 0; i < sizeof(uid.Data); i++) { err = sscanf(plugin + 2 * i, "%2hhx", uid.Data + i); if (err != 1) { - av_log(avctx, AV_LOG_ERROR, "Invalid plugin UID\n"); + av_log(avccl, AV_LOG_ERROR, "Invalid plugin UID\n"); err = AVERROR(EINVAL); goto load_plugin_fail; } @@ -229,9 +219,9 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, ret = MFXVideoUSER_Load(qs->session, &uid, 1); if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Could not load the requested plugin: %s\n", + av_log(avccl, AV_LOG_ERROR, "Could not load the requested plugin: %s\n", plugin); - err = ff_qsv_error(ret); + err = av_qsv_error(ret); goto load_plugin_fail; } @@ -242,14 +232,14 @@ load_plugin_fail: } } - av_log(avctx, AV_LOG_VERBOSE, + av_log(avccl, AV_LOG_VERBOSE, "Initialized an internal MFX session using %s implementation\n", desc); return 0; } -int ff_qsv_close_internal_session(QSVSession *qs) +int av_qsv_close_session(AVQSVSession *qs) { if (qs->session) { MFXClose(qs->session); @@ -267,3 +257,5 @@ int ff_qsv_close_internal_session(QSVSession *qs) #endif return 0; } +#endif //CONFIG_QSV + diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h index b77158e..a44e20f 100644 --- a/libavcodec/qsv.h +++ b/libavcodec/qsv.h @@ -98,10 +98,63 @@ typedef struct AVQSVContext { } AVQSVContext; /** + * This struct is used for handling QSV session parameters + */ +typedef struct AVQSVSession { + /** + * QSV session handle + */ + mfxSession session; + + /** + * display descriptor + */ + int fd_display; + /** + * display handler + */ + void * va_display; +} AVQSVSession; + +/** * Allocate a new context. * * It must be freed by the caller with av_free(). */ AVQSVContext *av_qsv_alloc_context(void); +/** + * Initialize a MSDK session + * + * Media SDK is based on sessions, so this is the prerequisite + * initialization for HW acceleration. For Windows the session is + * complete and ready to use, for Linux a display handle is + * required. For releases of Media Server Studio >= 2015 R4 the + * render nodes interface is preferred (/dev/dri/renderD). + * Using Media Server Studio 2015 R4 or newer is recommended + * but the older /dev/dri/card interface is also searched + * for broader compatibility. + * + * @param avccl pointer to AVClass, uses for logging + * @param qs the MSDK session used + * @param load_plugins list of hexadecimal plug-in UIDs delimeted by colons. + */ +int av_qsv_init_session(AVClass *avccl, AVQSVSession *qs, + const char *load_plugins); + +/** + * Close a MSDK session + * + * @param qs the MSDK session used + */ +int av_qsv_close_session(AVQSVSession *qs); + +/** + * Translate native MSDK error code to AVERROR code + * + * @param mfx_err native MSDK error code + * @return one of AVERROR codes + */ +int av_qsv_error(int mfx_err); + #endif /* AVCODEC_QSV_H */ diff --git a/libavcodec/qsv_api.c b/libavcodec/qsv_api.c index 327ff7d..9b76073 100644 --- a/libavcodec/qsv_api.c +++ b/libavcodec/qsv_api.c @@ -32,11 +32,37 @@ AVQSVContext *av_qsv_alloc_context(void) return av_mallocz(sizeof(AVQSVContext)); } #else +struct AVQSVSession; +struct AVQSVContext; struct AVQSVContext *av_qsv_alloc_context(void); +int av_qsv_init_session(AVClass *avccl, struct AVQSVSession *qs, + const char *load_plugins); +int av_qsv_close_session(struct AVQSVSession *qs); +int av_qsv_error(int mfx_err); + struct AVQSVContext *av_qsv_alloc_context(void) { return NULL; } + +int av_qsv_init_session(AVClass *avccl, struct AVQSVSession *qs, + const char *load_plugins) +{ + av_log(avccl, AV_LOG_ERROR, + "The libmfx is not linked. Recompile FFmpeg with libmfx enabled\n"); + return AVERROR(ENOSYS); +} + +int av_qsv_close_session(struct AVQSVSession *qs) +{ + return AVERROR(ENOSYS); +} + +int av_qsv_error(int mfx_err) +{ + return AVERROR(ENOSYS); +} + #endif diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index f289a2b..c19a4ba 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -53,6 +53,7 @@ (MFX_VERSION_MAJOR > (MAJOR) || \ MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) + typedef struct QSVFrame { AVFrame *frame; mfxFrameSurface1 *surface; @@ -65,23 +66,9 @@ typedef struct QSVFrame { struct QSVFrame *next; } QSVFrame; -typedef struct QSVSession { - mfxSession session; -#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE - int fd_display; - VADisplay va_display; -#endif -} QSVSession; - /** * Convert a libmfx error code into a ffmpeg error code. */ -int ff_qsv_error(int mfx_err); - int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id); -int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, - const char *load_plugins); -int ff_qsv_close_internal_session(QSVSession *qs); - #endif /* AVCODEC_QSV_INTERNAL_H */ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 9125700..64406ff 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -34,7 +34,6 @@ #include "avcodec.h" #include "internal.h" -#include "qsv.h" #include "qsv_internal.h" #include "qsvdec.h" @@ -75,8 +74,8 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt } if (!q->session) { if (!q->internal_qs.session) { - ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, - q->load_plugins); + ret = av_qsv_init_session((AVClass*)&avctx->av_class, &q->internal_qs, + q->load_plugins); if (ret < 0) return ret; } @@ -108,7 +107,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt return avpkt->size; } else if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Decode header error %d\n", ret); - return ff_qsv_error(ret); + return av_qsv_error(ret); } param.IOPattern = q->iopattern; param.AsyncDepth = q->async_depth; @@ -126,7 +125,7 @@ static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, AVPacket *avpkt av_log(avctx, AV_LOG_ERROR, "Error initializing the MFX video decoder %d\n", ret); } - return ff_qsv_error(ret); + return av_qsv_error(ret); } avctx->profile = param.mfx.CodecProfile; @@ -405,7 +404,7 @@ static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q, if (MFX_ERR_MORE_DATA!=ret && ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret); - return ff_qsv_error(ret); + return av_qsv_error(ret); } n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync)); @@ -573,7 +572,7 @@ int ff_qsv_decode_close(QSVContext *q) q->session = NULL; - ff_qsv_close_internal_session(&q->internal_qs); + av_qsv_close_session(&q->internal_qs); av_fifo_free(q->async_fifo); q->async_fifo = NULL; diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index 97a3315..51beb87 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -33,6 +33,7 @@ #include "libavutil/pixfmt.h" #include "avcodec.h" +#include "qsv.h" #include "qsv_internal.h" typedef struct QSVContext { @@ -41,7 +42,7 @@ typedef struct QSVContext { // the session we allocated internally, in case the caller did not provide // one - QSVSession internal_qs; + AVQSVSession internal_qs; /** * a linked list of frames currently being used by QSV diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index be54bf9..f59e88f 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -603,7 +603,7 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q) ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param); if (ret < 0) - return ff_qsv_error(ret); + return av_qsv_error(ret); q->packet_size = q->param.mfx.BufferSizeInKB * 1000; @@ -696,8 +696,8 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) } if (!q->session) { - ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, - q->load_plugins); + ret = av_qsv_init_session((AVClass*)&avctx->av_class, &q->internal_qs, + q->load_plugins); if (ret < 0) return ret; @@ -713,13 +713,13 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n"); } else if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret); - return ff_qsv_error(ret); + return av_qsv_error(ret); } ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n"); - return ff_qsv_error(ret); + return av_qsv_error(ret); } if (opaque_alloc) { @@ -762,7 +762,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n"); } else if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n"); - return ff_qsv_error(ret); + return av_qsv_error(ret); } ret = qsv_retrieve_enc_params(avctx, q); @@ -976,7 +976,7 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, if (ret == MFX_ERR_MORE_DATA) return 0; av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret); - return ff_qsv_error(ret); + return av_qsv_error(ret); } if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) { @@ -1074,7 +1074,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) MFXVideoENCODE_Close(q->session); q->session = NULL; - ff_qsv_close_internal_session(&q->internal_qs); + av_qsv_close_session(&q->internal_qs); cur = q->work_frames; while (cur) { diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 2d7bd32..6ce2719 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -79,7 +79,7 @@ typedef struct QSVEncContext { QSVFrame *work_frames; mfxSession session; - QSVSession internal_qs; + AVQSVSession internal_qs; int packet_size; int width_align; -- 1.8.3.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel