20 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 22 #define _WIN32_WINNT 0x0602 56 #define MF_TIMEBASE (AVRational){1, 10000000} 58 #define MF_INVALID_TIME AV_NOPTS_VALUE 68 IMFMediaEvent *ev =
NULL;
69 MediaEventType ev_id = 0;
70 HRESULT hr = IMFMediaEventGenerator_GetEvent(c->
async_events, 0, &ev);
76 IMFMediaEvent_GetType(ev, &ev_id);
93 IMFMediaEvent_Release(ev);
119 IMFSample_SetSampleTime(sample, stime);
130 HRESULT hr = IMFSample_GetSampleTime(sample, &pts);
143 hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
144 if (!FAILED(hr) && sz > 0) {
149 hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->
extradata, sz,
NULL);
165 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
168 "assuming %d bytes instead.\n", (
int)sz);
181 hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
182 if (!FAILED(hr) && sz > 0) {
186 hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz,
NULL);
225 IMFMediaType_Release(type);
240 hr = IMFSample_GetTotalLength(sample, &len);
247 IMFSample_ConvertToContiguousBuffer(sample, &buffer);
251 hr = IMFMediaBuffer_Lock(buffer, &data,
NULL,
NULL);
253 IMFMediaBuffer_Release(buffer);
257 memcpy(avpkt->
data, data, len);
259 IMFMediaBuffer_Unlock(buffer);
260 IMFMediaBuffer_Release(buffer);
264 hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
265 if (c->
is_audio || (!FAILED(hr) && t32 != 0))
268 hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
318 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
320 IMFSample_Release(sample);
324 hr = IMFMediaBuffer_Lock(buffer, &data,
NULL,
NULL);
326 IMFMediaBuffer_Release(buffer);
327 IMFSample_Release(sample);
333 IMFMediaBuffer_SetCurrentLength(buffer, size);
334 IMFMediaBuffer_Unlock(buffer);
335 IMFMediaBuffer_Release(buffer);
337 IMFSample_Release(sample);
377 IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
380 if (hr == MF_E_NOTACCEPTING) {
382 }
else if (FAILED(hr)) {
388 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
417 IMFSample_Release(sample);
426 MFT_OUTPUT_DATA_BUFFER out_buffers;
449 out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
455 hr = IMFTransform_ProcessOutput(c->
mft, 0, 1, &out_buffers, &st);
457 if (out_buffers.pEvents)
458 IMFCollection_Release(out_buffers.pEvents);
461 *out_sample = out_buffers.pSample;
466 if (out_buffers.pSample)
467 IMFSample_Release(out_buffers.pSample);
469 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
473 }
else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
495 if (ret >= 0 && !*out_sample)
511 IMFSample_Release(sample);
527 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
531 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
532 if (!FAILED(hr) && t == avctx->
channels)
535 hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
542 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
546 score |= (1LL << 31) - diff;
548 score |= (1LL << 30) + diff;
552 hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
553 if (!FAILED(hr) && t != 0)
582 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
586 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
587 if (!FAILED(hr) && t == avctx->
channels)
604 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
610 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
611 if (FAILED(hr) || t != avctx->
channels) {
626 hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
641 IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
663 IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
666 IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->
bit_rate);
709 if (pix_fmt != avctx->
pix_fmt) {
724 IMFMediaType *out_type =
NULL;
725 int64_t out_type_score = -1;
726 int out_type_index = -1;
734 hr = IMFTransform_GetOutputAvailableType(c->
mft, c->
out_stream_id, n, &type);
735 if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
737 if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
757 if (score > out_type_score) {
759 IMFMediaType_Release(out_type);
761 out_type_score = score;
763 IMFMediaType_AddRef(out_type);
766 IMFMediaType_Release(type);
772 hr = MFCreateMediaType(&out_type);
793 }
else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
804 IMFMediaType_Release(out_type);
813 IMFMediaType *in_type =
NULL;
814 int64_t in_type_score = -1;
815 int in_type_index = -1;
823 hr = IMFTransform_GetInputAvailableType(c->
mft, c->
in_stream_id, n, &type);
824 if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
826 if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
846 if (score > in_type_score) {
848 IMFMediaType_Release(in_type);
850 in_type_score = score;
852 IMFMediaType_AddRef(in_type);
855 IMFMediaType_Release(type);
881 }
else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
892 IMFMediaType_Release(in_type);
904 for (n = 0; n < 2 && (need_input ||
need_output); n++) {
909 need_input = ret < 1;
939 (c->
out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
940 (c->
out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
955 IMFAttributes *attrs;
964 hr = IMFTransform_GetAttributes(c->
mft, &attrs);
970 hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
981 hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
987 hr = IMFTransform_QueryInterface(c->
mft, &IID_IMFMediaEventGenerator, (
void **)&c->
async_events);
996 IMFAttributes_Release(attrs);
1004 MFT_REGISTER_TYPE_INFO reg = {0};
1013 reg.guidSubtype = *subtype;
1016 reg.guidMajorType = MFMediaType_Audio;
1017 category = MFT_CATEGORY_AUDIO_ENCODER;
1019 reg.guidMajorType = MFMediaType_Video;
1020 category = MFT_CATEGORY_VIDEO_ENCODER;
1055 hr = IMFTransform_QueryInterface(c->
mft, &IID_ICodecAPI, (
void **)&c->
codec_api);
1061 if (hr == E_NOTIMPL) {
1063 }
else if (FAILED(hr)) {
1074 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
1080 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
1088 int sleep = 10000, total = 0;
1090 while (total < 70*1000) {
1107 avctx->
extradata ?
"Got" :
"Didn't get", total / 1000);
1131 #define OFFSET(x) offsetof(MFContext, x) 1133 #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA) \ 1134 static const AVClass ff_ ## NAME ## _mf_encoder_class = { \ 1135 .class_name = #NAME "_mf", \ 1136 .item_name = av_default_item_name, \ 1138 .version = LIBAVUTIL_VERSION_INT, \ 1140 AVCodec ff_ ## NAME ## _mf_encoder = { \ 1141 .priv_class = &ff_ ## NAME ## _mf_encoder_class, \ 1142 .name = #NAME "_mf", \ 1143 .long_name = NULL_IF_CONFIG_SMALL(#ID " via MediaFoundation"), \ 1144 .type = AVMEDIA_TYPE_ ## MEDIATYPE, \ 1145 .id = AV_CODEC_ID_ ## ID, \ 1146 .priv_data_size = sizeof(MFContext), \ 1148 .close = mf_close, \ 1149 .send_frame = mf_send_frame, \ 1150 .receive_packet = mf_receive_packet, \ 1152 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, \ 1153 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | \ 1154 FF_CODEC_CAP_INIT_CLEANUP, \ 1158 .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, \ 1159 AV_SAMPLE_FMT_NONE }, 1165 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1168 {
"default",
"Default mode", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0,
VE,
"rate_control"},
1179 {
"default",
"Default scenario", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0,
VE,
"scenario"},
1193 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ 1194 AV_PIX_FMT_YUV420P, \
#define FF_PROFILE_H264_MAIN
const struct AVCodec * codec
void ff_media_type_dump(void *log, IMFMediaType *type)
static int mf_enca_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
static enum AVPixelFormat pix_fmt
static LONGLONG mf_to_mf_time(AVCodecContext *avctx, int64_t av_pts)
This structure describes decoded (raw) audio or video data.
static void mf_sample_set_pts(AVCodecContext *avctx, IMFSample *sample, int64_t av_pts)
int av_image_copy_to_buffer(uint8_t *dst, int dst_size, const uint8_t *const src_data[4], const int src_linesize[4], enum AVPixelFormat pix_fmt, int width, int height, int align)
Copy image data from an image into a buffer.
#define AV_LOG_WARNING
Something somehow does not look correct.
int64_t bit_rate
the average bitrate
static const AVOption venc_opts[]
static int mf_choose_input_type(AVCodecContext *avctx)
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
static int mf_close(AVCodecContext *avctx)
enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
static int mf_choose_output_type(AVCodecContext *avctx)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int av_usleep(unsigned usec)
Sleep for a period of time.
static int mf_create(void *log, IMFTransform **mft, const AVCodec *codec, int use_hw)
static IMFSample * mf_v_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
static int mf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
static int64_t mf_enca_output_score(AVCodecContext *avctx, IMFMediaType *type)
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)
enum AVSampleFormat sample_fmt
audio sample format
MFT_OUTPUT_STREAM_INFO out_info
static int mf_init(AVCodecContext *avctx)
static IMFSample * mf_a_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
static int need_output(void)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define AVERROR_EOF
End of file.
#define AV_LOG_VERBOSE
Detailed information.
static int64_t mf_encv_output_score(AVCodecContext *avctx, IMFMediaType *type)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
static int64_t mf_enca_input_score(AVCodecContext *avctx, IMFMediaType *type)
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters...
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int has_b_frames
Size of the frame reordering buffer in the decoder.
static int mf_unlock_async(AVCodecContext *avctx)
static AVRational mf_get_tb(AVCodecContext *avctx)
static int64_t mf_sample_get_pts(AVCodecContext *avctx, IMFSample *sample)
preferred ID for decoding MPEG audio layer 1, 2 or 3
int flags
AV_CODEC_FLAG_*.
#define FF_PROFILE_H264_HIGH
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int flags
A combination of AV_PKT_FLAG values.
enum AVPictureType pict_type
Picture type of the frame.
static int mf_wait_events(AVCodecContext *avctx)
int width
picture width / height.
static int mf_encv_input_adjust(AVCodecContext *avctx, IMFMediaType *type)
#define ff_MFSetAttributeRatio
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
static int mf_setup_context(AVCodecContext *avctx)
static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample)
static int64_t mf_encv_input_score(AVCodecContext *avctx, IMFMediaType *type)
IMFSample * ff_create_memory_sample(void *fill_data, size_t size, size_t align)
static int mf_output_type_get(AVCodecContext *avctx)
enum AVMediaType codec_type
int64_t pkt_duration
duration of the corresponding packet, expressed in AVStream->time_base units, 0 if unknown...
static int mf_encv_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
AVSampleFormat
Audio sample formats.
int sample_rate
samples per second
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample)
static int mf_enca_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
main external API structure.
#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA)
enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
Describe the class of an AVClass context structure.
void ff_free_mf(IMFTransform **mft)
Rational number (pair of numerator and denominator).
static IMFSample * mf_avframe_to_sample(AVCodecContext *avctx, const AVFrame *frame)
static int mf_negotiate_types(AVCodecContext *avctx)
#define FF_VAL_VT_BOOL(v)
static int64_t mf_from_mf_time(AVCodecContext *avctx, LONGLONG stime)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
common internal api header.
MFT_INPUT_STREAM_INFO in_info
int out_stream_provides_samples
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid, UINT32 uw, UINT32 uh)
static av_always_inline int diff(const uint32_t a, const uint32_t b)
int channels
number of audio channels
const CLSID * ff_codec_to_mf_subtype(enum AVCodecID codec)
static int mf_encv_output_type_get(AVCodecContext *avctx, IMFMediaType *type)
static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPacket *avpkt)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
static int mf_enca_output_adjust(AVCodecContext *avctx, IMFMediaType *type)
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
This structure stores compressed data.
int nb_samples
number of audio samples (per channel) described by this frame
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
IMFMediaEventGenerator * async_events
static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)