[FFmpeg-devel] [PATCH] Add MediaFoundation wrapper

wm4 nfxjfg at googlemail.com
Sat Apr 1 18:20:31 EEST 2017


On Sat, 1 Apr 2017 12:13:45 -0300
James Almer <jamrial at gmail.com> wrote:

> 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.
> > ---

> > +#define COBJMACROS
> > +#define _WIN32_WINNT 0x0601  
> 
> #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0601
> #undef _WIN32_WINNT
> #define _WIN32_WINNT 0x0601
> #endif

OK I guess. Fixed locally.

> > +
> > +#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

This include statement can be removed. Then it'll most likely compile
(unless the file recursively pulled in another needed include file). I
removed hw decoding and the hwcontext stuff because it wasn't really
done.

> [...]
> 
> > +#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?

Added locally.

> 
> > +        .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

Done.


More information about the ffmpeg-devel mailing list