diff --git a/configure b/configure index dbacfd61a8..952f5ecef4 100755 --- a/configure +++ b/configure @@ -1890,6 +1890,7 @@ CONFIG_EXTRA=" nettle pixblockdsp qpeldsp + qsv qsvdec rangecoder riffdec @@ -2073,6 +2074,7 @@ mpegaudio_select="mpegaudiodsp" mpegaudiodsp_select="dct" mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp videodsp" mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp" +qsvdec_select="qsv" # decoders / encoders aac_decoder_select="imdct15 mdct sinewin" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index bc2324f780..cef5b1623d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -92,6 +92,7 @@ OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ OBJS-$(CONFIG_NVENC) += nvenc.o OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o OBJS-$(CONFIG_QPELDSP) += qpeldsp.o +OBJS-$(CONFIG_QSV) += qsv.o OBJS-$(CONFIG_QSVDEC) += qsvdec.o OBJS-$(CONFIG_RANGECODER) += rangecoder.o RDFT-OBJS-$(CONFIG_HARDCODED_TABLES) += sin_tables.o @@ -865,7 +866,7 @@ SKIPHEADERS += %_tablegen.h \ SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h -SKIPHEADERS-$(CONFIG_QSVDEC) += qsv.h qsvdec.h +SKIPHEADERS-$(CONFIG_QSVDEC) += qsv.h qsvdec.h qsv_internal.h SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c new file mode 100644 index 0000000000..31be9d1fa3 --- /dev/null +++ b/libavcodec/qsv.c @@ -0,0 +1,115 @@ +/* + * Intel MediaSDK QSV encoder/decoder shared code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/error.h" + +#include "avcodec.h" +#include "qsv_internal.h" + +int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id) +{ + switch (codec_id) { + case AV_CODEC_ID_H264: + return MFX_CODEC_AVC; + case AV_CODEC_ID_MPEG1VIDEO: + case AV_CODEC_ID_MPEG2VIDEO: + return MFX_CODEC_MPEG2; + case AV_CODEC_ID_VC1: + return MFX_CODEC_VC1; + default: + break; + } + + return AVERROR(ENOSYS); +} + +int ff_qsv_error(int mfx_err) +{ + switch (mfx_err) { + case MFX_ERR_NONE: + return 0; + case MFX_ERR_MEMORY_ALLOC: + case MFX_ERR_NOT_ENOUGH_BUFFER: + return AVERROR(ENOMEM); + case MFX_ERR_INVALID_HANDLE: + return AVERROR(EINVAL); + case MFX_ERR_DEVICE_FAILED: + case MFX_ERR_DEVICE_LOST: + case MFX_ERR_LOCK_MEMORY: + return AVERROR(EIO); + case MFX_ERR_NULL_PTR: + case MFX_ERR_UNDEFINED_BEHAVIOR: + case MFX_ERR_NOT_INITIALIZED: + return AVERROR_BUG; + case MFX_ERR_UNSUPPORTED: + case MFX_ERR_NOT_FOUND: + return AVERROR(ENOSYS); + case MFX_ERR_MORE_DATA: + case MFX_ERR_MORE_SURFACE: + case MFX_ERR_MORE_BITSTREAM: + return AVERROR(EAGAIN); + case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: + case MFX_ERR_INVALID_VIDEO_PARAM: + return AVERROR(EINVAL); + case MFX_ERR_ABORTED: + case MFX_ERR_UNKNOWN: + default: + return AVERROR_UNKNOWN; + } +} + +int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session) +{ + mfxIMPL impl = MFX_IMPL_AUTO_ANY; + mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } }; + + const char *desc; + int ret; + + ret = MFXInit(impl, &ver, session); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); + return ff_qsv_error(ret); + } + + MFXQueryIMPL(*session, &impl); + + switch (MFX_IMPL_BASETYPE(impl)) { + case MFX_IMPL_SOFTWARE: + desc = "software"; + break; + case MFX_IMPL_HARDWARE: + case MFX_IMPL_HARDWARE2: + case MFX_IMPL_HARDWARE3: + case MFX_IMPL_HARDWARE4: + desc = "hardware accelerated"; + break; + default: + desc = "unknown"; + } + + av_log(avctx, AV_LOG_VERBOSE, + "Initialized an internal MFX session using %s implementation\n", + desc); + + return 0; +} diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h new file mode 100644 index 0000000000..b1079139b6 --- /dev/null +++ b/libavcodec/qsv_internal.h @@ -0,0 +1,38 @@ +/* + * Intel MediaSDK QSV encoder/decoder shared code + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_QSV_INTERNAL_H +#define AVCODEC_QSV_INTERNAL_H + +#define QSV_VERSION_MAJOR 1 +#define QSV_VERSION_MINOR 1 + +#define ASYNC_DEPTH_DEFAULT 4 // internal parallelism + +/** + * Convert a libmfx error code into a libav 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, mfxSession *session); + +#endif /* AVCODEC_QSV_INTERNAL_H */ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 762f158fff..0115b377d9 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -34,43 +34,9 @@ #include "avcodec.h" #include "internal.h" +#include "qsv_internal.h" #include "qsvdec.h" -int ff_qsv_error(int mfx_err) -{ - switch (mfx_err) { - case MFX_ERR_NONE: - return 0; - case MFX_ERR_MEMORY_ALLOC: - case MFX_ERR_NOT_ENOUGH_BUFFER: - return AVERROR(ENOMEM); - case MFX_ERR_INVALID_HANDLE: - return AVERROR(EINVAL); - case MFX_ERR_DEVICE_FAILED: - case MFX_ERR_DEVICE_LOST: - case MFX_ERR_LOCK_MEMORY: - return AVERROR(EIO); - case MFX_ERR_NULL_PTR: - case MFX_ERR_UNDEFINED_BEHAVIOR: - case MFX_ERR_NOT_INITIALIZED: - return AVERROR_BUG; - case MFX_ERR_UNSUPPORTED: - case MFX_ERR_NOT_FOUND: - return AVERROR(ENOSYS); - case MFX_ERR_MORE_DATA: - case MFX_ERR_MORE_SURFACE: - case MFX_ERR_MORE_BITSTREAM: - return AVERROR(EAGAIN); - case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: - case MFX_ERR_INVALID_VIDEO_PARAM: - return AVERROR(EINVAL); - case MFX_ERR_ABORTED: - case MFX_ERR_UNKNOWN: - default: - return AVERROR_UNKNOWN; - } -} - int ff_qsv_map_pixfmt(enum AVPixelFormat format) { switch (format) { @@ -82,58 +48,13 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format) } } -static int codec_id_to_mfx(enum AVCodecID codec_id) -{ - switch (codec_id) { - case AV_CODEC_ID_H264: - return MFX_CODEC_AVC; - case AV_CODEC_ID_MPEG1VIDEO: - case AV_CODEC_ID_MPEG2VIDEO: - return MFX_CODEC_MPEG2; - case AV_CODEC_ID_VC1: - return MFX_CODEC_VC1; - default: - break; - } - - return AVERROR(ENOSYS); -} - static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session) { if (!session) { if (!q->internal_session) { - mfxIMPL impl = MFX_IMPL_AUTO_ANY; - mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } }; - - const char *desc; - int ret; - - ret = MFXInit(impl, &ver, &q->internal_session); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error initializing an internal MFX session\n"); - return ff_qsv_error(ret); - } - - MFXQueryIMPL(q->internal_session, &impl); - - switch (MFX_IMPL_BASETYPE(impl)) { - case MFX_IMPL_SOFTWARE: - desc = "software"; - break; - case MFX_IMPL_HARDWARE: - case MFX_IMPL_HARDWARE2: - case MFX_IMPL_HARDWARE3: - case MFX_IMPL_HARDWARE4: - desc = "hardware accelerated"; - break; - default: - desc = "unknown"; - } - - av_log(avctx, AV_LOG_VERBOSE, - "Initialized an internal MFX session using %s implementation\n", - desc); + int ret = ff_qsv_init_internal_session(avctx, &q->internal_session); + if (ret < 0) + return ret; } q->session = q->internal_session; @@ -159,7 +80,7 @@ int ff_qsv_init(AVCodecContext *avctx, QSVContext *q, mfxSession session) } - ret = codec_id_to_mfx(avctx->codec_id); + ret = ff_qsv_codec_id_to_mfx(avctx->codec_id); if (ret < 0) return ret; diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index b57bcbfd74..a529003397 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -33,11 +33,6 @@ #include "avcodec.h" -#define QSV_VERSION_MAJOR 1 -#define QSV_VERSION_MINOR 1 - -#define ASYNC_DEPTH_DEFAULT 4 // internal parallelism - typedef struct QSVFrame { AVFrame *frame; mfxFrameSurface1 *surface; @@ -68,11 +63,6 @@ typedef struct QSVContext { int nb_ext_buffers; } QSVContext; -/** - * Convert a libmfx error code into a ffmpeg error code. - */ -int ff_qsv_error(int mfx_err); - int ff_qsv_map_pixfmt(enum AVPixelFormat format); int ff_qsv_init(AVCodecContext *s, QSVContext *q, mfxSession session); diff --git a/libavcodec/qsvdec_h264.c b/libavcodec/qsvdec_h264.c index 11e081c6f5..13eaa12efb 100644 --- a/libavcodec/qsvdec_h264.c +++ b/libavcodec/qsvdec_h264.c @@ -33,6 +33,7 @@ #include "avcodec.h" #include "internal.h" +#include "qsv_internal.h" #include "qsvdec.h" #include "qsv.h"