[FFmpeg-devel] [PATCH] Add MediaFoundation wrapper
James Almer
jamrial at gmail.com
Sat Apr 1 18:13:45 EEST 2017
On 4/1/2017 8:28 AM, wm4 wrote:
> Can do audio decoding, audio encoding, video decoding, video encoding,
> video HW encoding. I also had video HW decoding, but removed it for now,
> as thw hwframes integration wasn't very sane.
>
> Some of the MS codecs aren't well tested, and might not work properly.
> ---
> configure | 34 +
> libavcodec/Makefile | 1 +
> libavcodec/allcodecs.c | 23 +
> libavcodec/mf.c | 1950 ++++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/mf_utils.c | 693 +++++++++++++++++
> libavcodec/mf_utils.h | 200 +++++
> 6 files changed, 2901 insertions(+)
> create mode 100644 libavcodec/mf.c
> create mode 100644 libavcodec/mf_utils.c
> create mode 100644 libavcodec/mf_utils.h
>
> diff --git a/configure b/configure
> index 6d76cf7e1e..9909e7ab77 100755
> --- a/configure
> +++ b/configure
> @@ -280,6 +280,7 @@ External library support:
> --disable-lzma disable lzma [autodetect]
> --enable-decklink enable Blackmagic DeckLink I/O support [no]
> --enable-mediacodec enable Android MediaCodec support [no]
> + --enable-mf enable decoding via MediaFoundation [no]
> --enable-netcdf enable NetCDF, needed for sofalizer filter [no]
> --enable-openal enable OpenAL 1.1 capture support [no]
> --enable-opencl enable OpenCL code
> @@ -1582,6 +1583,7 @@ EXTERNAL_LIBRARY_LIST="
> libzmq
> libzvbi
> mediacodec
> + mf
> netcdf
> openal
> opencl
> @@ -2124,6 +2126,7 @@ CONFIG_EXTRA="
> lpc
> lzf
> me_cmp
> + mf
> mpeg_er
> mpegaudio
> mpegaudiodsp
> @@ -2584,6 +2587,8 @@ zmbv_encoder_select="zlib"
> # platform codecs
> audiotoolbox_deps="AudioToolbox_AudioToolbox_h"
> audiotoolbox_extralibs="-framework CoreFoundation -framework AudioToolbox -framework CoreMedia"
> +mf_deps="mftransform_h"
> +mf_extralibs="-lmfplat -lole32 -lstrmiids -luuid -loleaut32 -lshlwapi"
>
> # hardware accelerators
> crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
> @@ -2892,6 +2897,34 @@ libx265_encoder_deps="libx265"
> libxavs_encoder_deps="libxavs"
> libxvid_encoder_deps="libxvid"
> libzvbi_teletext_decoder_deps="libzvbi"
> +aac_mf_decoder_deps="mf"
> +aac_mf_encoder_deps="mf"
> +ac3_mf_decoder_deps="mf"
> +ac3_mf_encoder_deps="mf"
> +eac3_mf_decoder_deps="mf"
> +h264_mf_decoder_deps="mf"
> +h264_mf_encoder_deps="mf"
> +hevc_mf_decoder_deps="mf"
> +hevc_mf_encoder_deps="mf"
> +mjpeg_mf_decoder_deps="mf"
> +mp1_mf_decoder_deps="mf"
> +mp2_mf_decoder_deps="mf"
> +mp3_mf_decoder_deps="mf"
> +mp3_mf_encoder_deps="mf"
> +mpeg2_mf_decoder_deps="mf"
> +mpeg4_mf_decoder_deps="mf"
> +msmpeg4v1_mf_decoder_deps="mf"
> +msmpeg4v2_mf_decoder_deps="mf"
> +msmpeg4v3_mf_decoder_deps="mf"
> +vc1_mf_decoder_deps="mf"
> +wmav1_mf_decoder_deps="mf"
> +wmav2_mf_decoder_deps="mf"
> +wmalossless_mf_decoder_deps="mf"
> +wmapro_mf_decoder_deps="mf"
> +wmavoice_mf_decoder_deps="mf"
> +wmv1_mf_decoder_deps="mf"
> +wmv2_mf_decoder_deps="mf"
> +wmv3_mf_decoder_deps="mf"
> videotoolbox_deps="VideoToolbox_VideoToolbox_h"
> videotoolbox_extralibs="-framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo"
> videotoolbox_encoder_deps="videotoolbox VTCompressionSessionPrepareToEncodeFrames"
> @@ -5632,6 +5665,7 @@ check_header io.h
> check_header libcrystalhd/libcrystalhd_if.h
> check_header mach/mach_time.h
> check_header malloc.h
> +check_header mftransform.h
> check_header net/udplite.h
> check_header poll.h
> check_header sys/mman.h
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 876a69e013..d26124f60c 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -915,6 +915,7 @@ OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
> OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
> OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
> OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o
> +OBJS-$(CONFIG_MF) += mf.o mf_utils.o mpeg4audio.o
>
> # parsers
> OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index b7d03ad601..c8704a267b 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -631,6 +631,29 @@ static void register_all(void)
> REGISTER_ENCODER(LIBXAVS, libxavs);
> REGISTER_ENCODER(LIBXVID, libxvid);
> REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext);
> + REGISTER_ENCDEC (AAC_MF, aac_mf);
> + REGISTER_ENCDEC (AC3_MF, ac3_mf);
> + REGISTER_DECODER(EAC3_MF, eac3_mf);
> + REGISTER_ENCDEC (H264_MF, h264_mf);
> + REGISTER_ENCDEC (HEVC_MF, hevc_mf);
> + REGISTER_DECODER(MJPEG_MF, mjpeg_mf);
> + REGISTER_DECODER(MP1_MF, mp1_mf);
> + REGISTER_DECODER(MP2_MF, mp2_mf);
> + REGISTER_ENCDEC (MP3_MF, mp3_mf);
> + REGISTER_DECODER(MPEG2_MF, mpeg2_mf);
> + REGISTER_DECODER(MPEG4_MF, mpeg4_mf);
> + REGISTER_DECODER(MSMPEG4V1_MF, msmpeg4v1_mf);
> + REGISTER_DECODER(MSMPEG4V2_MF, msmpeg4v2_mf);
> + REGISTER_DECODER(MSMPEG4V3_MF, msmpeg4v3_mf);
> + REGISTER_DECODER(VC1_MF, vc1_mf);
> + REGISTER_DECODER(WMALOSSLESS_MF, wmalossless_mf);
> + REGISTER_DECODER(WMAPRO_MF, wmapro_mf);
> + REGISTER_DECODER(WMAV1_MF, wmav1_mf);
> + REGISTER_DECODER(WMAV2_MF, wmav2_mf);
> + REGISTER_DECODER(WMAVOICE_MF, wmavoice_mf);
> + REGISTER_DECODER(WMV1_MF, wmv1_mf);
> + REGISTER_DECODER(WMV2_MF, wmv2_mf);
> + REGISTER_DECODER(WMV3_MF, wmv3_mf);
>
> /* text */
> REGISTER_DECODER(BINTEXT, bintext);
> diff --git a/libavcodec/mf.c b/libavcodec/mf.c
> new file mode 100644
> index 0000000000..baf5c19a2f
> --- /dev/null
> +++ b/libavcodec/mf.c
> @@ -0,0 +1,1950 @@
> +/*
> + * 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
> + */
> +#define COBJMACROS
> +#define _WIN32_WINNT 0x0601
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0601
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
> +
> +#include "mf_utils.h"
> +
> +// Include after mf_utils.h due to Windows include mess.
> +#include "libavutil/hwcontext.h"
> +#include "libavutil/hwcontext_mf.h"
CC libavcodec/mf.o
/ffmpeg/src/libavcodec/mf.c:24:36: fatal error: libavutil/hwcontext_mf.h: No such file or directory
#include "libavutil/hwcontext_mf.h"
^
compilation terminated.
make: *** [/ffmpeg/src/common.mak:60: libavcodec/mf.o] Error 1
[...]
> +#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA) \
> + static const AVClass ff_ ## NAME ## _mf_encoder_class = { \
> + .class_name = #NAME "_mf", \
> + .item_name = av_default_item_name, \
> + .option = OPTS, \
> + .version = LIBAVUTIL_VERSION_INT, \
> + }; \
> + AVCodec ff_ ## NAME ## _mf_encoder = { \
> + .priv_class = &ff_ ## NAME ## _mf_encoder_class, \
> + .name = #NAME "_mf", \
> + .long_name = NULL_IF_CONFIG_SMALL(#ID " via MediaFoundation"), \
> + .type = AVMEDIA_TYPE_ ## MEDIATYPE, \
> + .id = AV_CODEC_ID_ ## ID, \
> + .priv_data_size = sizeof(MFContext), \
> + .init = mf_init, \
> + .close = mf_close, \
> + .send_frame = mf_send_frame, \
> + .receive_packet = mf_receive_packet, \
> + EXTRA \
> + .capabilities = AV_CODEC_CAP_DELAY, \
AV_CODEC_CAP_AVOID_PROBING maybe?
> + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | \
> + FF_CODEC_CAP_INIT_CLEANUP, \
> + };
> +
> +#define AFMTS \
> + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, \
> + AV_SAMPLE_FMT_NONE },
> +
> +MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS);
> +MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS);
> +MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS);
> +
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +static const AVOption venc_opts[] = {
> + {"rate_control", "Select rate control mode", OFFSET(opt_enc_rc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, "rate_control"},
> + { "default", "Default mode", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, VE, "rate_control"},
> + { "cbr", "CBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_CBR}, 0, 0, VE, "rate_control"},
> + { "pc_vbr", "Peak constrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_PeakConstrainedVBR}, 0, 0, VE, "rate_control"},
> + { "u_vbr", "Unconstrained VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_UnconstrainedVBR}, 0, 0, VE, "rate_control"},
> + { "quality", "Quality mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_Quality}, 0, 0, VE, "rate_control" },
> + // The following rate_control modes require Windows 8.
> + { "ld_vbr", "Low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_LowDelayVBR}, 0, 0, VE, "rate_control"},
> + { "g_vbr", "Global VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalVBR}, 0, 0, VE, "rate_control" },
> + { "gld_vbr", "Global low delay VBR mode", 0, AV_OPT_TYPE_CONST, {.i64 = ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR}, 0, 0, VE, "rate_control"},
> + {"quality", "Quality", OFFSET(opt_enc_quality), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
> + {"hw_encoding", "Force hardware encoding", OFFSET(opt_enc_d3d), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, VE, "hw_encoding"},
> + {NULL}
> +};
> +
> +#define VFMTS \
> + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \
> + AV_PIX_FMT_YUV420P, \
> + AV_PIX_FMT_NONE },
> +
> +MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS);
> +MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS);
> diff --git a/libavcodec/mf_utils.c b/libavcodec/mf_utils.c
> new file mode 100644
> index 0000000000..1a69e49581
> --- /dev/null
> +++ b/libavcodec/mf_utils.c
> @@ -0,0 +1,693 @@
> +/*
> + * 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
> + */
> +#define COBJMACROS
> +#define _WIN32_WINNT 0x0601
Ditto
More information about the ffmpeg-devel
mailing list