1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

avcodec: Add MediaFoundation encoder wrapper

This contains encoder wrappers for H264, HEVC, AAC, AC3 and MP3.

This is based on top of an original patch by wm4
<nfxjfg@googlemail.com>. The original patch supported both encoding
and decoding, but this patch only includes encoding.

The patch contains further changes by Paweł Wegner
<pawel.wegner95@gmail.com> (primarily for splitting out the encoding
parts of the original patch) and further cleanup, build compatibility
fixes and tweaks for use with Qualcomm encoders by Martin Storsjö.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
wm4 2017-04-04 07:45:41 +02:00 committed by Martin Storsjö
parent b559a5882f
commit 050b72ab5e
9 changed files with 2063 additions and 1 deletions

View File

@ -69,6 +69,7 @@ version <next>:
- scdet filter
- NotchLC decoder
- gradients source video filter
- MediaFoundation encoder wrapper
version 4.2:

11
configure vendored
View File

@ -304,6 +304,7 @@ External library support:
--enable-mbedtls enable mbedTLS, needed for https support
if openssl, gnutls or libtls is not used [no]
--enable-mediacodec enable Android MediaCodec support [no]
--enable-mediafoundation enable encoding via MediaFoundation [auto]
--enable-libmysofa enable libmysofa, needed for sofalizer filter [no]
--enable-openal enable OpenAL 1.1 capture support [no]
--enable-opencl enable OpenCL processing [no]
@ -1704,6 +1705,7 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST="
libxcb_shape
libxcb_xfixes
lzma
mediafoundation
schannel
sdl2
securetransport
@ -3011,6 +3013,8 @@ wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
# hardware-accelerated codecs
mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer"
mediafoundation_extralibs="-lmfplat -lmfuuid -lole32 -lstrmiids"
omx_deps="libdl pthreads"
omx_rpi_select="omx"
qsv_deps="libmfx"
@ -3035,6 +3039,8 @@ nvenc_deps="ffnvcodec"
nvenc_deps_any="libdl LoadLibrary"
nvenc_encoder_deps="nvenc"
aac_mf_encoder_deps="mediafoundation"
ac3_mf_encoder_deps="mediafoundation"
h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
h264_amf_encoder_deps="amf"
@ -3043,6 +3049,7 @@ h264_cuvid_decoder_deps="cuvid"
h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
h264_mediacodec_decoder_deps="mediacodec"
h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser"
h264_mf_encoder_deps="mediafoundation"
h264_mmal_decoder_deps="mmal"
h264_nvenc_encoder_deps="nvenc"
h264_omx_encoder_deps="omx"
@ -3059,6 +3066,7 @@ hevc_cuvid_decoder_deps="cuvid"
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
hevc_mediacodec_decoder_deps="mediacodec"
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
hevc_mf_encoder_deps="mediafoundation"
hevc_nvenc_encoder_deps="nvenc"
hevc_qsv_decoder_select="hevc_mp4toannexb_bsf qsvdec"
hevc_qsv_encoder_select="hevcparse qsvenc"
@ -3075,6 +3083,7 @@ mjpeg_qsv_encoder_deps="libmfx"
mjpeg_qsv_encoder_select="qsvenc"
mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
mp3_mf_encoder_deps="mediafoundation"
mpeg1_cuvid_decoder_deps="cuvid"
mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
mpeg2_crystalhd_decoder_select="crystalhd"
@ -6101,6 +6110,7 @@ check_headers io.h
check_headers linux/perf_event.h
check_headers libcrystalhd/libcrystalhd_if.h
check_headers malloc.h
check_headers mftransform.h
check_headers net/udplite.h
check_headers poll.h
check_headers sys/param.h
@ -6163,6 +6173,7 @@ check_type "windows.h dxva.h" "DXVA_PicParams_VP9" -DWINAPI_FAMILY=WINAPI_FAMILY
check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
check_type "windows.h d3d11.h" "ID3D11VideoContext"
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
check_type "vdpau/vdpau.h" "VdpPictureInfoVP9"

View File

@ -2725,6 +2725,14 @@ fastest.
@end table
@section MediaFoundation
This provides wrappers to encoders (both audio and video) in the
MediaFoundation framework. It can access both SW and HW encoders.
Video encoders can take input in either of nv12 or yuv420p form
(some encoders support both, some support only either - in practice,
nv12 is the safer choice, especially among HW encoders).
@section mpeg2
MPEG-2 video encoder.

View File

@ -170,12 +170,14 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \
aacenc_ltp.o \
aacenc_pred.o \
psymodel.o mpeg4audio.o kbdwin.o cbrt_data.o
OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o
OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o ac3tab.o
OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \
ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_ACELP_KELVIN_DECODER) += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
OBJS-$(CONFIG_AGM_DECODER) += agm.o
OBJS-$(CONFIG_AIC_DECODER) += aic.o
@ -356,6 +358,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o
OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o
OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o
@ -378,6 +381,7 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o
OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o
@ -455,6 +459,7 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
mpegaudiodata.o mpegaudiodsp_data.o
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
OBJS-$(CONFIG_MP3FLOAT_DECODER) += mpegaudiodec_float.o
@ -1156,6 +1161,7 @@ SKIPHEADERS-$(CONFIG_JNI) += ffjni.h
SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h
SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h
SKIPHEADERS-$(CONFIG_MEDIACODEC) += mediacodecdec_common.h mediacodec_surface.h mediacodec_wrapper.h mediacodec_sw_buffer.h
SKIPHEADERS-$(CONFIG_MEDIAFOUNDATION) += mf_utils.h
SKIPHEADERS-$(CONFIG_NVDEC) += nvdec.h
SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h
SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h

View File

@ -677,7 +677,9 @@ extern AVCodec ff_xsub_decoder;
/* external libraries */
extern AVCodec ff_aac_at_encoder;
extern AVCodec ff_aac_at_decoder;
extern AVCodec ff_aac_mf_encoder;
extern AVCodec ff_ac3_at_decoder;
extern AVCodec ff_ac3_mf_encoder;
extern AVCodec ff_adpcm_ima_qt_at_decoder;
extern AVCodec ff_alac_at_encoder;
extern AVCodec ff_alac_at_decoder;
@ -689,6 +691,7 @@ extern AVCodec ff_ilbc_at_decoder;
extern AVCodec ff_mp1_at_decoder;
extern AVCodec ff_mp2_at_decoder;
extern AVCodec ff_mp3_at_decoder;
extern AVCodec ff_mp3_mf_encoder;
extern AVCodec ff_pcm_alaw_at_encoder;
extern AVCodec ff_pcm_alaw_at_decoder;
extern AVCodec ff_pcm_mulaw_at_encoder;
@ -758,6 +761,7 @@ extern AVCodec ff_libopenh264_encoder;
extern AVCodec ff_libopenh264_decoder;
extern AVCodec ff_h264_amf_encoder;
extern AVCodec ff_h264_cuvid_decoder;
extern AVCodec ff_h264_mf_encoder;
extern AVCodec ff_h264_nvenc_encoder;
extern AVCodec ff_h264_omx_encoder;
extern AVCodec ff_h264_qsv_encoder;
@ -772,6 +776,7 @@ extern AVCodec ff_nvenc_hevc_encoder;
extern AVCodec ff_hevc_amf_encoder;
extern AVCodec ff_hevc_cuvid_decoder;
extern AVCodec ff_hevc_mediacodec_decoder;
extern AVCodec ff_hevc_mf_encoder;
extern AVCodec ff_hevc_nvenc_encoder;
extern AVCodec ff_hevc_qsv_encoder;
extern AVCodec ff_hevc_v4l2m2m_encoder;

680
libavcodec/mf_utils.c Normal file
View File

@ -0,0 +1,680 @@
/*
* 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
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0602
#endif
#include "mf_utils.h"
#include "libavutil/pixdesc.h"
HRESULT ff_MFGetAttributeSize(IMFAttributes *pattr, REFGUID guid,
UINT32 *pw, UINT32 *ph)
{
UINT64 t;
HRESULT hr = IMFAttributes_GetUINT64(pattr, guid, &t);
if (!FAILED(hr)) {
*pw = t >> 32;
*ph = (UINT32)t;
}
return hr;
}
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid,
UINT32 uw, UINT32 uh)
{
UINT64 t = (((UINT64)uw) << 32) | uh;
return IMFAttributes_SetUINT64(pattr, guid, t);
}
#define ff_MFSetAttributeRatio ff_MFSetAttributeSize
#define ff_MFGetAttributeRatio ff_MFGetAttributeSize
// MFTEnumEx was missing from mingw-w64's mfplat import library until
// mingw-w64 v6.0.0, thus wrap it and load it using GetProcAddress.
// It's also missing in Windows Vista's mfplat.dll.
HRESULT ff_MFTEnumEx(GUID guidCategory, UINT32 Flags,
const MFT_REGISTER_TYPE_INFO *pInputType,
const MFT_REGISTER_TYPE_INFO *pOutputType,
IMFActivate ***pppMFTActivate, UINT32 *pnumMFTActivate)
{
HRESULT (WINAPI *MFTEnumEx_ptr)(GUID guidCategory, UINT32 Flags,
const MFT_REGISTER_TYPE_INFO *pInputType,
const MFT_REGISTER_TYPE_INFO *pOutputType,
IMFActivate ***pppMFTActivate,
UINT32 *pnumMFTActivate) = NULL;
#if !HAVE_UWP
HANDLE lib = GetModuleHandleW(L"mfplat.dll");
if (lib)
MFTEnumEx_ptr = (void *)GetProcAddress(lib, "MFTEnumEx");
#else
// In UWP (which lacks GetModuleHandle), just link directly against
// the functions - this requires building with new/complete enough
// import libraries.
MFTEnumEx_ptr = MFTEnumEx;
#endif
if (!MFTEnumEx_ptr)
return E_FAIL;
return MFTEnumEx_ptr(guidCategory,
Flags,
pInputType,
pOutputType,
pppMFTActivate,
pnumMFTActivate);
}
char *ff_hr_str_buf(char *buf, size_t size, HRESULT hr)
{
#define HR(x) case x: return (char *) # x;
switch (hr) {
HR(S_OK)
HR(E_UNEXPECTED)
HR(MF_E_INVALIDMEDIATYPE)
HR(MF_E_INVALIDSTREAMNUMBER)
HR(MF_E_INVALIDTYPE)
HR(MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING)
HR(MF_E_TRANSFORM_TYPE_NOT_SET)
HR(MF_E_UNSUPPORTED_D3D_TYPE)
HR(MF_E_TRANSFORM_NEED_MORE_INPUT)
HR(MF_E_TRANSFORM_STREAM_CHANGE)
HR(MF_E_NOTACCEPTING)
HR(MF_E_NO_SAMPLE_TIMESTAMP)
HR(MF_E_NO_SAMPLE_DURATION)
#undef HR
}
snprintf(buf, size, "%x", (unsigned)hr);
return buf;
}
// If fill_data!=NULL, initialize the buffer and set the length. (This is a
// subtle but important difference: some decoders want CurrentLength==0 on
// provided output buffers.)
IMFSample *ff_create_memory_sample(void *fill_data, size_t size, size_t align)
{
HRESULT hr;
IMFSample *sample;
IMFMediaBuffer *buffer;
hr = MFCreateSample(&sample);
if (FAILED(hr))
return NULL;
align = FFMAX(align, 16); // 16 is "recommended", even if not required
hr = MFCreateAlignedMemoryBuffer(size, align - 1, &buffer);
if (FAILED(hr))
return NULL;
if (fill_data) {
BYTE *tmp;
hr = IMFMediaBuffer_Lock(buffer, &tmp, NULL, NULL);
if (FAILED(hr)) {
IMFMediaBuffer_Release(buffer);
IMFSample_Release(sample);
return NULL;
}
memcpy(tmp, fill_data, size);
IMFMediaBuffer_SetCurrentLength(buffer, size);
IMFMediaBuffer_Unlock(buffer);
}
IMFSample_AddBuffer(sample, buffer);
IMFMediaBuffer_Release(buffer);
return sample;
}
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
{
HRESULT hr;
UINT32 bits;
GUID subtype;
hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits);
if (FAILED(hr))
return AV_SAMPLE_FMT_NONE;
hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &subtype);
if (FAILED(hr))
return AV_SAMPLE_FMT_NONE;
if (IsEqualGUID(&subtype, &MFAudioFormat_PCM)) {
switch (bits) {
case 8: return AV_SAMPLE_FMT_U8;
case 16: return AV_SAMPLE_FMT_S16;
case 32: return AV_SAMPLE_FMT_S32;
}
} else if (IsEqualGUID(&subtype, &MFAudioFormat_Float)) {
switch (bits) {
case 32: return AV_SAMPLE_FMT_FLT;
case 64: return AV_SAMPLE_FMT_DBL;
}
}
return AV_SAMPLE_FMT_NONE;
}
struct mf_pix_fmt_entry {
const GUID *guid;
enum AVPixelFormat pix_fmt;
};
static const struct mf_pix_fmt_entry mf_pix_fmts[] = {
{&MFVideoFormat_IYUV, AV_PIX_FMT_YUV420P},
{&MFVideoFormat_I420, AV_PIX_FMT_YUV420P},
{&MFVideoFormat_NV12, AV_PIX_FMT_NV12},
{&MFVideoFormat_P010, AV_PIX_FMT_P010},
{&MFVideoFormat_P016, AV_PIX_FMT_P010}, // not equal, but compatible
{&MFVideoFormat_YUY2, AV_PIX_FMT_YUYV422},
};
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
{
HRESULT hr;
GUID subtype;
int i;
hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &subtype);
if (FAILED(hr))
return AV_PIX_FMT_NONE;
for (i = 0; i < FF_ARRAY_ELEMS(mf_pix_fmts); i++) {
if (IsEqualGUID(&subtype, mf_pix_fmts[i].guid))
return mf_pix_fmts[i].pix_fmt;
}
return AV_PIX_FMT_NONE;
}
const GUID *ff_pix_fmt_to_guid(enum AVPixelFormat pix_fmt)
{
int i;
for (i = 0; i < FF_ARRAY_ELEMS(mf_pix_fmts); i++) {
if (mf_pix_fmts[i].pix_fmt == pix_fmt)
return mf_pix_fmts[i].guid;
}
return NULL;
}
// If this GUID is of the form XXXXXXXX-0000-0010-8000-00AA00389B71, then
// extract the XXXXXXXX prefix as FourCC (oh the pain).
int ff_fourcc_from_guid(const GUID *guid, uint32_t *out_fourcc)
{
if (guid->Data2 == 0 && guid->Data3 == 0x0010 &&
guid->Data4[0] == 0x80 &&
guid->Data4[1] == 0x00 &&
guid->Data4[2] == 0x00 &&
guid->Data4[3] == 0xAA &&
guid->Data4[4] == 0x00 &&
guid->Data4[5] == 0x38 &&
guid->Data4[6] == 0x9B &&
guid->Data4[7] == 0x71) {
*out_fourcc = guid->Data1;
return 0;
}
*out_fourcc = 0;
return AVERROR_UNKNOWN;
}
struct GUID_Entry {
const GUID *guid;
const char *name;
};
#define GUID_ENTRY(var) {&(var), # var}
static struct GUID_Entry guid_names[] = {
GUID_ENTRY(MFT_FRIENDLY_NAME_Attribute),
GUID_ENTRY(MFT_TRANSFORM_CLSID_Attribute),
GUID_ENTRY(MFT_ENUM_HARDWARE_URL_Attribute),
GUID_ENTRY(MFT_CONNECTED_STREAM_ATTRIBUTE),
GUID_ENTRY(MFT_CONNECTED_TO_HW_STREAM),
GUID_ENTRY(MF_SA_D3D_AWARE),
GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT),
GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE),
GUID_ENTRY(ff_MF_SA_D3D11_BINDFLAGS),
GUID_ENTRY(ff_MF_SA_D3D11_USAGE),
GUID_ENTRY(ff_MF_SA_D3D11_AWARE),
GUID_ENTRY(ff_MF_SA_D3D11_SHARED),
GUID_ENTRY(ff_MF_SA_D3D11_SHARED_WITHOUT_MUTEX),
GUID_ENTRY(MF_MT_SUBTYPE),
GUID_ENTRY(MF_MT_MAJOR_TYPE),
GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
GUID_ENTRY(MF_MT_FRAME_SIZE),
GUID_ENTRY(MF_MT_INTERLACE_MODE),
GUID_ENTRY(MF_MT_USER_DATA),
GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
GUID_ENTRY(MFMediaType_Audio),
GUID_ENTRY(MFMediaType_Video),
GUID_ENTRY(MFAudioFormat_PCM),
GUID_ENTRY(MFAudioFormat_Float),
GUID_ENTRY(MFVideoFormat_H264),
GUID_ENTRY(MFVideoFormat_H264_ES),
GUID_ENTRY(ff_MFVideoFormat_HEVC),
GUID_ENTRY(ff_MFVideoFormat_HEVC_ES),
GUID_ENTRY(MFVideoFormat_MPEG2),
GUID_ENTRY(MFVideoFormat_MP43),
GUID_ENTRY(MFVideoFormat_MP4V),
GUID_ENTRY(MFVideoFormat_WMV1),
GUID_ENTRY(MFVideoFormat_WMV2),
GUID_ENTRY(MFVideoFormat_WMV3),
GUID_ENTRY(MFVideoFormat_WVC1),
GUID_ENTRY(MFAudioFormat_Dolby_AC3),
GUID_ENTRY(MFAudioFormat_Dolby_DDPlus),
GUID_ENTRY(MFAudioFormat_AAC),
GUID_ENTRY(MFAudioFormat_MP3),
GUID_ENTRY(MFAudioFormat_MSP1),
GUID_ENTRY(MFAudioFormat_WMAudioV8),
GUID_ENTRY(MFAudioFormat_WMAudioV9),
GUID_ENTRY(MFAudioFormat_WMAudio_Lossless),
GUID_ENTRY(MF_MT_ALL_SAMPLES_INDEPENDENT),
GUID_ENTRY(MF_MT_COMPRESSED),
GUID_ENTRY(MF_MT_FIXED_SIZE_SAMPLES),
GUID_ENTRY(MF_MT_SAMPLE_SIZE),
GUID_ENTRY(MF_MT_WRAPPED_TYPE),
GUID_ENTRY(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION),
GUID_ENTRY(MF_MT_AAC_PAYLOAD_TYPE),
GUID_ENTRY(MF_MT_AUDIO_AVG_BYTES_PER_SECOND),
GUID_ENTRY(MF_MT_AUDIO_BITS_PER_SAMPLE),
GUID_ENTRY(MF_MT_AUDIO_BLOCK_ALIGNMENT),
GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
GUID_ENTRY(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND),
GUID_ENTRY(MF_MT_AUDIO_FOLDDOWN_MATRIX),
GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
GUID_ENTRY(MF_MT_AUDIO_PREFER_WAVEFORMATEX),
GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_BLOCK),
GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
GUID_ENTRY(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE),
GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGREF),
GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGTARGET),
GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKREF),
GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKTARGET),
GUID_ENTRY(MF_MT_AVG_BIT_ERROR_RATE),
GUID_ENTRY(MF_MT_AVG_BITRATE),
GUID_ENTRY(MF_MT_DEFAULT_STRIDE),
GUID_ENTRY(MF_MT_DRM_FLAGS),
GUID_ENTRY(MF_MT_FRAME_RATE),
GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MAX),
GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MIN),
GUID_ENTRY(MF_MT_FRAME_SIZE),
GUID_ENTRY(MF_MT_GEOMETRIC_APERTURE),
GUID_ENTRY(MF_MT_INTERLACE_MODE),
GUID_ENTRY(MF_MT_MAX_KEYFRAME_SPACING),
GUID_ENTRY(MF_MT_MINIMUM_DISPLAY_APERTURE),
GUID_ENTRY(MF_MT_MPEG_SEQUENCE_HEADER),
GUID_ENTRY(MF_MT_MPEG_START_TIME_CODE),
GUID_ENTRY(MF_MT_MPEG2_FLAGS),
GUID_ENTRY(MF_MT_MPEG2_LEVEL),
GUID_ENTRY(MF_MT_MPEG2_PROFILE),
GUID_ENTRY(MF_MT_PAD_CONTROL_FLAGS),
GUID_ENTRY(MF_MT_PALETTE),
GUID_ENTRY(MF_MT_PAN_SCAN_APERTURE),
GUID_ENTRY(MF_MT_PAN_SCAN_ENABLED),
GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
GUID_ENTRY(MF_MT_SOURCE_CONTENT_HINT),
GUID_ENTRY(MF_MT_TRANSFER_FUNCTION),
GUID_ENTRY(MF_MT_VIDEO_CHROMA_SITING),
GUID_ENTRY(MF_MT_VIDEO_LIGHTING),
GUID_ENTRY(MF_MT_VIDEO_NOMINAL_RANGE),
GUID_ENTRY(MF_MT_VIDEO_PRIMARIES),
GUID_ENTRY(MF_MT_VIDEO_ROTATION),
GUID_ENTRY(MF_MT_YUV_MATRIX),
GUID_ENTRY(ff_CODECAPI_AVDecVideoThumbnailGenerationMode),
GUID_ENTRY(ff_CODECAPI_AVDecVideoDropPicWithMissingRef),
GUID_ENTRY(ff_CODECAPI_AVDecVideoSoftwareDeinterlaceMode),
GUID_ENTRY(ff_CODECAPI_AVDecVideoFastDecodeMode),
GUID_ENTRY(ff_CODECAPI_AVLowLatencyMode),
GUID_ENTRY(ff_CODECAPI_AVDecVideoH264ErrorConcealment),
GUID_ENTRY(ff_CODECAPI_AVDecVideoMPEG2ErrorConcealment),
GUID_ENTRY(ff_CODECAPI_AVDecVideoCodecType),
GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVAMode),
GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVABusEncryption),
GUID_ENTRY(ff_CODECAPI_AVDecVideoSWPowerLevel),
GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedWidth),
GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedHeight),
GUID_ENTRY(ff_CODECAPI_AVDecNumWorkerThreads),
GUID_ENTRY(ff_CODECAPI_AVDecSoftwareDynamicFormatChange),
GUID_ENTRY(ff_CODECAPI_AVDecDisableVideoPostProcessing),
};
char *ff_guid_str_buf(char *buf, size_t buf_size, const GUID *guid)
{
uint32_t fourcc;
int n;
for (n = 0; n < FF_ARRAY_ELEMS(guid_names); n++) {
if (IsEqualGUID(guid, guid_names[n].guid)) {
snprintf(buf, buf_size, "%s", guid_names[n].name);
return buf;
}
}
if (ff_fourcc_from_guid(guid, &fourcc) >= 0) {
snprintf(buf, buf_size, "<FourCC %s>", av_fourcc2str(fourcc));
return buf;
}
snprintf(buf, buf_size,
"{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
(unsigned) guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1],
guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5],
guid->Data4[6], guid->Data4[7]);
return buf;
}
void ff_attributes_dump(void *log, IMFAttributes *attrs)
{
HRESULT hr;
UINT32 count;
int n;
hr = IMFAttributes_GetCount(attrs, &count);
if (FAILED(hr))
return;
for (n = 0; n < count; n++) {
GUID key;
MF_ATTRIBUTE_TYPE type;
char extra[80] = {0};
const char *name = NULL;
hr = IMFAttributes_GetItemByIndex(attrs, n, &key, NULL);
if (FAILED(hr))
goto err;
name = ff_guid_str(&key);
if (IsEqualGUID(&key, &MF_MT_AUDIO_CHANNEL_MASK)) {
UINT32 v;
hr = IMFAttributes_GetUINT32(attrs, &key, &v);
if (FAILED(hr))
goto err;
snprintf(extra, sizeof(extra), " (0x%x)", (unsigned)v);
} else if (IsEqualGUID(&key, &MF_MT_FRAME_SIZE)) {
UINT32 w, h;
hr = ff_MFGetAttributeSize(attrs, &MF_MT_FRAME_SIZE, &w, &h);
if (FAILED(hr))
goto err;
snprintf(extra, sizeof(extra), " (%dx%d)", (int)w, (int)h);
} else if (IsEqualGUID(&key, &MF_MT_PIXEL_ASPECT_RATIO) ||
IsEqualGUID(&key, &MF_MT_FRAME_RATE)) {
UINT32 num, den;
hr = ff_MFGetAttributeRatio(attrs, &key, &num, &den);
if (FAILED(hr))
goto err;
snprintf(extra, sizeof(extra), " (%d:%d)", (int)num, (int)den);
}
hr = IMFAttributes_GetItemType(attrs, &key, &type);
if (FAILED(hr))
goto err;
switch (type) {
case MF_ATTRIBUTE_UINT32: {
UINT32 v;
hr = IMFAttributes_GetUINT32(attrs, &key, &v);
if (FAILED(hr))
goto err;
av_log(log, AV_LOG_VERBOSE, " %s=%d%s\n", name, (int)v, extra);
break;
case MF_ATTRIBUTE_UINT64: {
UINT64 v;
hr = IMFAttributes_GetUINT64(attrs, &key, &v);
if (FAILED(hr))
goto err;
av_log(log, AV_LOG_VERBOSE, " %s=%lld%s\n", name, (long long)v, extra);
break;
}
case MF_ATTRIBUTE_DOUBLE: {
DOUBLE v;
hr = IMFAttributes_GetDouble(attrs, &key, &v);
if (FAILED(hr))
goto err;
av_log(log, AV_LOG_VERBOSE, " %s=%f%s\n", name, (double)v, extra);
break;
}
case MF_ATTRIBUTE_STRING: {
wchar_t s[512]; // being lazy here
hr = IMFAttributes_GetString(attrs, &key, s, sizeof(s), NULL);
if (FAILED(hr))
goto err;
av_log(log, AV_LOG_VERBOSE, " %s='%ls'%s\n", name, s, extra);
break;
}
case MF_ATTRIBUTE_GUID: {
GUID v;
hr = IMFAttributes_GetGUID(attrs, &key, &v);
if (FAILED(hr))
goto err;
av_log(log, AV_LOG_VERBOSE, " %s=%s%s\n", name, ff_guid_str(&v), extra);
break;
}
case MF_ATTRIBUTE_BLOB: {
UINT32 sz;
UINT8 buffer[100];
hr = IMFAttributes_GetBlobSize(attrs, &key, &sz);
if (FAILED(hr))
goto err;
if (sz <= sizeof(buffer)) {
// hex-dump it
char str[512] = {0};
size_t pos = 0;
hr = IMFAttributes_GetBlob(attrs, &key, buffer, sizeof(buffer), &sz);
if (FAILED(hr))
goto err;
for (pos = 0; pos < sz; pos++) {
const char *hex = "0123456789ABCDEF";
if (pos * 3 + 3 > sizeof(str))
break;
str[pos * 3 + 0] = hex[buffer[pos] >> 4];
str[pos * 3 + 1] = hex[buffer[pos] & 15];
str[pos * 3 + 2] = ' ';
}
str[pos * 3 + 0] = 0;
av_log(log, AV_LOG_VERBOSE, " %s=<blob size %d: %s>%s\n", name, (int)sz, str, extra);
} else {
av_log(log, AV_LOG_VERBOSE, " %s=<blob size %d>%s\n", name, (int)sz, extra);
}
break;
}
case MF_ATTRIBUTE_IUNKNOWN: {
av_log(log, AV_LOG_VERBOSE, " %s=<IUnknown>%s\n", name, extra);
break;
}
default:
av_log(log, AV_LOG_VERBOSE, " %s=<unknown type>%s\n", name, extra);
break;
}
}
if (IsEqualGUID(&key, &MF_MT_SUBTYPE)) {
const char *fmt;
fmt = av_get_sample_fmt_name(ff_media_type_to_sample_fmt(attrs));
if (fmt)
av_log(log, AV_LOG_VERBOSE, " FF-sample-format=%s\n", fmt);
fmt = av_get_pix_fmt_name(ff_media_type_to_pix_fmt(attrs));
if (fmt)
av_log(log, AV_LOG_VERBOSE, " FF-pixel-format=%s\n", fmt);
}
continue;
err:
av_log(log, AV_LOG_VERBOSE, " %s=<failed to get value>\n", name ? name : "?");
}
}
void ff_media_type_dump(void *log, IMFMediaType *type)
{
ff_attributes_dump(log, (IMFAttributes *)type);
}
const CLSID *ff_codec_to_mf_subtype(enum AVCodecID codec)
{
switch (codec) {
case AV_CODEC_ID_H264: return &MFVideoFormat_H264;
case AV_CODEC_ID_HEVC: return &ff_MFVideoFormat_HEVC;
case AV_CODEC_ID_AC3: return &MFAudioFormat_Dolby_AC3;
case AV_CODEC_ID_AAC: return &MFAudioFormat_AAC;
case AV_CODEC_ID_MP3: return &MFAudioFormat_MP3;
default: return NULL;
}
}
static int init_com_mf(void *log)
{
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (hr == RPC_E_CHANGED_MODE) {
av_log(log, AV_LOG_ERROR, "COM must not be in STA mode\n");
return AVERROR(EINVAL);
} else if (FAILED(hr)) {
av_log(log, AV_LOG_ERROR, "could not initialize COM\n");
return AVERROR(ENOSYS);
}
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
if (FAILED(hr)) {
av_log(log, AV_LOG_ERROR, "could not initialize MediaFoundation\n");
CoUninitialize();
return AVERROR(ENOSYS);
}
return 0;
}
static void uninit_com_mf(void)
{
MFShutdown();
CoUninitialize();
}
// Find and create a IMFTransform with the given input/output types. When done,
// you should use ff_free_mf() to destroy it, which will also uninit COM.
int ff_instantiate_mf(void *log,
GUID category,
MFT_REGISTER_TYPE_INFO *in_type,
MFT_REGISTER_TYPE_INFO *out_type,
int use_hw,
IMFTransform **res)
{
HRESULT hr;
int n;
int ret;
IMFActivate **activate;
UINT32 num_activate;
IMFActivate *winner = 0;
UINT32 flags;
ret = init_com_mf(log);
if (ret < 0)
return ret;
flags = MFT_ENUM_FLAG_SORTANDFILTER;
if (use_hw) {
flags |= MFT_ENUM_FLAG_HARDWARE;
} else {
flags |= MFT_ENUM_FLAG_SYNCMFT;
}
hr = ff_MFTEnumEx(category, flags, in_type, out_type, &activate,
&num_activate);
if (FAILED(hr))
goto error_uninit_mf;
if (log) {
if (!num_activate)
av_log(log, AV_LOG_ERROR, "could not find any MFT for the given media type\n");
for (n = 0; n < num_activate; n++) {
av_log(log, AV_LOG_VERBOSE, "MF %d attributes:\n", n);
ff_attributes_dump(log, (IMFAttributes *)activate[n]);
}
}
*res = NULL;
for (n = 0; n < num_activate; n++) {
if (log)
av_log(log, AV_LOG_VERBOSE, "activate MFT %d\n", n);
hr = IMFActivate_ActivateObject(activate[n], &IID_IMFTransform,
(void **)res);
if (*res) {
winner = activate[n];
IMFActivate_AddRef(winner);
break;
}
}
for (n = 0; n < num_activate; n++)
IMFActivate_Release(activate[n]);
CoTaskMemFree(activate);
if (!*res) {
if (log)
av_log(log, AV_LOG_ERROR, "could not create MFT\n");
goto error_uninit_mf;
}
if (log) {
wchar_t s[512]; // being lazy here
IMFAttributes *attrs;
hr = IMFTransform_GetAttributes(*res, &attrs);
if (!FAILED(hr) && attrs) {
av_log(log, AV_LOG_VERBOSE, "MFT attributes\n");
ff_attributes_dump(log, attrs);
IMFAttributes_Release(attrs);
}
hr = IMFActivate_GetString(winner, &MFT_FRIENDLY_NAME_Attribute, s,
sizeof(s), NULL);
if (!FAILED(hr))
av_log(log, AV_LOG_INFO, "MFT name: '%ls'\n", s);
}
IMFActivate_Release(winner);
return 0;
error_uninit_mf:
uninit_com_mf();
return AVERROR(ENOSYS);
}
void ff_free_mf(IMFTransform **mft)
{
if (*mft)
IMFTransform_Release(*mft);
*mft = NULL;
uninit_com_mf();
}

159
libavcodec/mf_utils.h Normal file
View File

@ -0,0 +1,159 @@
/*
* 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_MF_UTILS_H
#define AVCODEC_MF_UTILS_H
#include <windows.h>
#include <initguid.h>
#ifdef _MSC_VER
// The official way of including codecapi (via dshow.h) makes the ICodecAPI
// interface unavailable in UWP mode, but including icodecapi.h + codecapi.h
// seems to be equivalent. (These headers conflict with the official way
// of including it though, through strmif.h via dshow.h. And on mingw, the
// mf*.h headers below indirectly include strmif.h.)
#include <icodecapi.h>
#else
#include <dshow.h>
#endif
// Older versions of mingw-w64 need codecapi.h explicitly included, while newer
// ones include it implicitly from dshow.h (via uuids.h).
#include <codecapi.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfobjects.h>
#include <mftransform.h>
#include "avcodec.h"
// These functions do exist in mfapi.h, but are only available within
// __cplusplus ifdefs.
HRESULT ff_MFGetAttributeSize(IMFAttributes *pattr, REFGUID guid,
UINT32 *pw, UINT32 *ph);
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid,
UINT32 uw, UINT32 uh);
#define ff_MFSetAttributeRatio ff_MFSetAttributeSize
#define ff_MFGetAttributeRatio ff_MFGetAttributeSize
// MFTEnumEx was missing from mingw-w64's mfplat import library until
// mingw-w64 v6.0.0, thus wrap it and load it using GetProcAddress.
// It's also missing in Windows Vista's mfplat.dll.
HRESULT ff_MFTEnumEx(GUID guidCategory, UINT32 Flags,
const MFT_REGISTER_TYPE_INFO *pInputType,
const MFT_REGISTER_TYPE_INFO *pOutputType,
IMFActivate ***pppMFTActivate, UINT32 *pnumMFTActivate);
// These do exist in mingw-w64's codecapi.h, but they aren't properly defined
// by the header until after mingw-w64 v7.0.0.
DEFINE_GUID(ff_CODECAPI_AVDecVideoThumbnailGenerationMode, 0x2efd8eee,0x1150,0x4328,0x9c,0xf5,0x66,0xdc,0xe9,0x33,0xfc,0xf4);
DEFINE_GUID(ff_CODECAPI_AVDecVideoDropPicWithMissingRef, 0xf8226383,0x14c2,0x4567,0x97,0x34,0x50,0x04,0xe9,0x6f,0xf8,0x87);
DEFINE_GUID(ff_CODECAPI_AVDecVideoSoftwareDeinterlaceMode, 0x0c08d1ce,0x9ced,0x4540,0xba,0xe3,0xce,0xb3,0x80,0x14,0x11,0x09);
DEFINE_GUID(ff_CODECAPI_AVDecVideoFastDecodeMode, 0x6b529f7d,0xd3b1,0x49c6,0xa9,0x99,0x9e,0xc6,0x91,0x1b,0xed,0xbf);
DEFINE_GUID(ff_CODECAPI_AVLowLatencyMode, 0x9c27891a,0xed7a,0x40e1,0x88,0xe8,0xb2,0x27,0x27,0xa0,0x24,0xee);
DEFINE_GUID(ff_CODECAPI_AVDecVideoH264ErrorConcealment, 0xececace8,0x3436,0x462c,0x92,0x94,0xcd,0x7b,0xac,0xd7,0x58,0xa9);
DEFINE_GUID(ff_CODECAPI_AVDecVideoMPEG2ErrorConcealment, 0x9d2bfe18,0x728d,0x48d2,0xb3,0x58,0xbc,0x7e,0x43,0x6c,0x66,0x74);
DEFINE_GUID(ff_CODECAPI_AVDecVideoCodecType, 0x434528e5,0x21f0,0x46b6,0xb6,0x2c,0x9b,0x1b,0x6b,0x65,0x8c,0xd1);
DEFINE_GUID(ff_CODECAPI_AVDecVideoDXVAMode, 0xf758f09e,0x7337,0x4ae7,0x83,0x87,0x73,0xdc,0x2d,0x54,0xe6,0x7d);
DEFINE_GUID(ff_CODECAPI_AVDecVideoDXVABusEncryption, 0x42153c8b,0xfd0b,0x4765,0xa4,0x62,0xdd,0xd9,0xe8,0xbc,0xc3,0x88);
DEFINE_GUID(ff_CODECAPI_AVDecVideoSWPowerLevel, 0xfb5d2347,0x4dd8,0x4509,0xae,0xd0,0xdb,0x5f,0xa9,0xaa,0x93,0xf4);
DEFINE_GUID(ff_CODECAPI_AVDecVideoMaxCodedWidth, 0x5ae557b8,0x77af,0x41f5,0x9f,0xa6,0x4d,0xb2,0xfe,0x1d,0x4b,0xca);
DEFINE_GUID(ff_CODECAPI_AVDecVideoMaxCodedHeight, 0x7262a16a,0xd2dc,0x4e75,0x9b,0xa8,0x65,0xc0,0xc6,0xd3,0x2b,0x13);
DEFINE_GUID(ff_CODECAPI_AVDecNumWorkerThreads, 0x9561c3e8,0xea9e,0x4435,0x9b,0x1e,0xa9,0x3e,0x69,0x18,0x94,0xd8);
DEFINE_GUID(ff_CODECAPI_AVDecSoftwareDynamicFormatChange, 0x862e2f0a,0x507b,0x47ff,0xaf,0x47,0x01,0xe2,0x62,0x42,0x98,0xb7);
DEFINE_GUID(ff_CODECAPI_AVDecDisableVideoPostProcessing, 0xf8749193,0x667a,0x4f2c,0xa9,0xe8,0x5d,0x4a,0xf9,0x24,0xf0,0x8f);
// These are missing from mingw-w64's headers until after mingw-w64 v7.0.0.
DEFINE_GUID(ff_CODECAPI_AVEncCommonRateControlMode, 0x1c0608e9, 0x370c, 0x4710, 0x8a, 0x58, 0xcb, 0x61, 0x81, 0xc4, 0x24, 0x23);
DEFINE_GUID(ff_CODECAPI_AVEncCommonQuality, 0xfcbf57a3, 0x7ea5, 0x4b0c, 0x96, 0x44, 0x69, 0xb4, 0x0c, 0x39, 0xc3, 0x91);
DEFINE_GUID(ff_CODECAPI_AVEncCommonMeanBitRate, 0xf7222374, 0x2144, 0x4815, 0xb5, 0x50, 0xa3, 0x7f, 0x8e, 0x12, 0xee, 0x52);
DEFINE_GUID(ff_CODECAPI_AVEncH264CABACEnable, 0xee6cad62, 0xd305, 0x4248, 0xa5, 0xe, 0xe1, 0xb2, 0x55, 0xf7, 0xca, 0xf8);
DEFINE_GUID(ff_CODECAPI_AVEncVideoForceKeyFrame, 0x398c1b98, 0x8353, 0x475a, 0x9e, 0xf2, 0x8f, 0x26, 0x5d, 0x26, 0x3, 0x45);
DEFINE_GUID(ff_CODECAPI_AVEncMPVDefaultBPictureCount, 0x8d390aac, 0xdc5c, 0x4200, 0xb5, 0x7f, 0x81, 0x4d, 0x04, 0xba, 0xba, 0xb2);
DEFINE_GUID(ff_CODECAPI_AVScenarioInfo, 0xb28a6e64,0x3ff9,0x446a,0x8a,0x4b,0x0d,0x7a,0x53,0x41,0x32,0x36);
DEFINE_GUID(ff_MF_SA_D3D11_BINDFLAGS, 0xeacf97ad, 0x065c, 0x4408, 0xbe, 0xe3, 0xfd, 0xcb, 0xfd, 0x12, 0x8b, 0xe2);
DEFINE_GUID(ff_MF_SA_D3D11_USAGE, 0xe85fe442, 0x2ca3, 0x486e, 0xa9, 0xc7, 0x10, 0x9d, 0xda, 0x60, 0x98, 0x80);
DEFINE_GUID(ff_MF_SA_D3D11_AWARE, 0x206b4fc8, 0xfcf9, 0x4c51, 0xaf, 0xe3, 0x97, 0x64, 0x36, 0x9e, 0x33, 0xa0);
DEFINE_GUID(ff_MF_SA_D3D11_SHARED, 0x7b8f32c3, 0x6d96, 0x4b89, 0x92, 0x3, 0xdd, 0x38, 0xb6, 0x14, 0x14, 0xf3);
DEFINE_GUID(ff_MF_SA_D3D11_SHARED_WITHOUT_MUTEX, 0x39dbd44d, 0x2e44, 0x4931, 0xa4, 0xc8, 0x35, 0x2d, 0x3d, 0xc4, 0x21, 0x15);
DEFINE_GUID(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT, 0x851745d5, 0xc3d6, 0x476d, 0x95, 0x27, 0x49, 0x8e, 0xf2, 0xd1, 0xd, 0x18);
DEFINE_GUID(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE, 0xf5523a5, 0x1cb2, 0x47c5, 0xa5, 0x50, 0x2e, 0xeb, 0x84, 0xb4, 0xd1, 0x4a);
DEFINE_MEDIATYPE_GUID(ff_MFVideoFormat_HEVC, 0x43564548); // FCC('HEVC')
DEFINE_MEDIATYPE_GUID(ff_MFVideoFormat_HEVC_ES, 0x53564548); // FCC('HEVS')
// This enum is missing from mingw-w64's codecapi.h by v7.0.0.
enum ff_eAVEncCommonRateControlMode {
ff_eAVEncCommonRateControlMode_CBR = 0,
ff_eAVEncCommonRateControlMode_PeakConstrainedVBR = 1,
ff_eAVEncCommonRateControlMode_UnconstrainedVBR = 2,
ff_eAVEncCommonRateControlMode_Quality = 3,
ff_eAVEncCommonRateControlMode_LowDelayVBR = 4,
ff_eAVEncCommonRateControlMode_GlobalVBR = 5,
ff_eAVEncCommonRateControlMode_GlobalLowDelayVBR = 6
};
enum ff_eAVScenarioInfo {
ff_eAVScenarioInfo_Unknown = 0,
ff_eAVScenarioInfo_DisplayRemoting = 1,
ff_eAVScenarioInfo_VideoConference = 2,
ff_eAVScenarioInfo_Archive = 3,
ff_eAVScenarioInfo_LiveStreaming = 4,
ff_eAVScenarioInfo_CameraRecord = 5,
ff_eAVScenarioInfo_DisplayRemotingWithFeatureMap = 6
};
// These do exist in mingw-w64's mfobjects.idl, but are missing from
// mfobjects.h that is generated from the former, due to incorrect use of
// ifdefs in the IDL file.
enum {
ff_METransformUnknown = 600,
ff_METransformNeedInput,
ff_METransformHaveOutput,
ff_METransformDrainComplete,
ff_METransformMarker,
};
char *ff_hr_str_buf(char *buf, size_t size, HRESULT hr);
#define ff_hr_str(hr) ff_hr_str_buf((char[80]){0}, 80, hr)
// Possibly compiler-dependent; the MS/MinGW definition for this is just crazy.
#define FF_VARIANT_VALUE(type, contents) &(VARIANT){ .vt = (type), contents }
#define FF_VAL_VT_UI4(v) FF_VARIANT_VALUE(VT_UI4, .ulVal = (v))
#define FF_VAL_VT_BOOL(v) FF_VARIANT_VALUE(VT_BOOL, .boolVal = (v))
IMFSample *ff_create_memory_sample(void *fill_data, size_t size, size_t align);
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type);
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type);
const GUID *ff_pix_fmt_to_guid(enum AVPixelFormat pix_fmt);
int ff_fourcc_from_guid(const GUID *guid, uint32_t *out_fourcc);
char *ff_guid_str_buf(char *buf, size_t buf_size, const GUID *guid);
#define ff_guid_str(guid) ff_guid_str_buf((char[80]){0}, 80, guid)
void ff_attributes_dump(void *log, IMFAttributes *attrs);
void ff_media_type_dump(void *log, IMFMediaType *type);
const CLSID *ff_codec_to_mf_subtype(enum AVCodecID codec);
int ff_instantiate_mf(void *log, GUID category,
MFT_REGISTER_TYPE_INFO *in_type,
MFT_REGISTER_TYPE_INFO *out_type,
int use_hw, IMFTransform **res);
void ff_free_mf(IMFTransform **mft);
#endif

1192
libavcodec/mfenc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
#define LIBAVCODEC_VERSION_MINOR 85
#define LIBAVCODEC_VERSION_MINOR 86
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \