20 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602 22 #define _WIN32_WINNT 0x0602 58 #define MF_TIMEBASE (AVRational){1, 10000000} 60 #define MF_INVALID_TIME AV_NOPTS_VALUE 70 IMFMediaEvent *ev =
NULL;
71 MediaEventType ev_id = 0;
72 HRESULT hr = IMFMediaEventGenerator_GetEvent(c->
async_events, 0, &ev);
78 IMFMediaEvent_GetType(ev, &ev_id);
95 IMFMediaEvent_Release(ev);
121 IMFSample_SetSampleTime(sample, stime);
132 HRESULT hr = IMFSample_GetSampleTime(sample, &pts);
145 hr = IMFAttributes_GetBlobSize(type, &MF_MT_USER_DATA, &sz);
146 if (!FAILED(hr) && sz > 0) {
151 hr = IMFAttributes_GetBlob(type, &MF_MT_USER_DATA, avctx->
extradata, sz,
NULL);
167 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &sz);
170 "assuming %d bytes instead.\n", (
int)sz);
183 hr = IMFAttributes_GetBlobSize(type, &MF_MT_MPEG_SEQUENCE_HEADER, &sz);
184 if (!FAILED(hr) && sz > 0) {
188 hr = IMFAttributes_GetBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, extradata, sz,
NULL);
227 IMFMediaType_Release(type);
242 hr = IMFSample_GetTotalLength(sample, &len);
249 IMFSample_ConvertToContiguousBuffer(sample, &buffer);
253 hr = IMFMediaBuffer_Lock(buffer, &data,
NULL,
NULL);
255 IMFMediaBuffer_Release(buffer);
259 memcpy(avpkt->
data, data, len);
261 IMFMediaBuffer_Unlock(buffer);
262 IMFMediaBuffer_Release(buffer);
266 hr = IMFAttributes_GetUINT32(sample, &MFSampleExtension_CleanPoint, &t32);
267 if (c->
is_audio || (!FAILED(hr) && t32 != 0))
270 hr = IMFAttributes_GetUINT64(sample, &MFSampleExtension_DecodeTimestamp, &t);
320 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
322 IMFSample_Release(sample);
326 hr = IMFMediaBuffer_Lock(buffer, &data,
NULL,
NULL);
328 IMFMediaBuffer_Release(buffer);
329 IMFSample_Release(sample);
335 IMFMediaBuffer_SetCurrentLength(buffer, size);
336 IMFMediaBuffer_Unlock(buffer);
337 IMFMediaBuffer_Release(buffer);
339 IMFSample_Release(sample);
379 IMFSample_SetUINT32(sample, &MFSampleExtension_Discontinuity, TRUE);
382 if (hr == MF_E_NOTACCEPTING) {
384 }
else if (FAILED(hr)) {
390 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_COMMAND_DRAIN, 0);
408 MFT_OUTPUT_DATA_BUFFER out_buffers;
431 out_buffers = (MFT_OUTPUT_DATA_BUFFER) {
437 hr = IMFTransform_ProcessOutput(c->
mft, 0, 1, &out_buffers, &st);
439 if (out_buffers.pEvents)
440 IMFCollection_Release(out_buffers.pEvents);
443 *out_sample = out_buffers.pSample;
448 if (out_buffers.pSample)
449 IMFSample_Release(out_buffers.pSample);
451 if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
455 }
else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
477 if (ret >= 0 && !*out_sample)
509 IMFSample_Release(sample);
520 IMFSample_Release(sample);
536 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
540 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
541 if (!FAILED(hr) && t == avctx->
channels)
544 hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
551 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &t);
555 score |= (1LL << 31) - diff;
557 score |= (1LL << 30) + diff;
561 hr = IMFAttributes_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &t);
562 if (!FAILED(hr) && t != 0)
591 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
595 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
596 if (!FAILED(hr) && t == avctx->
channels)
613 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &t);
619 hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &t);
620 if (FAILED(hr) || t != avctx->
channels) {
635 hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &tg);
650 IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
672 IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
675 IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->
bit_rate);
718 if (pix_fmt != avctx->
pix_fmt) {
733 IMFMediaType *out_type =
NULL;
734 int64_t out_type_score = -1;
735 int out_type_index = -1;
743 hr = IMFTransform_GetOutputAvailableType(c->
mft, c->
out_stream_id, n, &type);
744 if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
746 if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
766 if (score > out_type_score) {
768 IMFMediaType_Release(out_type);
770 out_type_score = score;
772 IMFMediaType_AddRef(out_type);
775 IMFMediaType_Release(type);
781 hr = MFCreateMediaType(&out_type);
802 }
else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
813 IMFMediaType_Release(out_type);
822 IMFMediaType *in_type =
NULL;
823 int64_t in_type_score = -1;
824 int in_type_index = -1;
832 hr = IMFTransform_GetInputAvailableType(c->
mft, c->
in_stream_id, n, &type);
833 if (hr == MF_E_NO_MORE_TYPES || hr == E_NOTIMPL)
835 if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
855 if (score > in_type_score) {
857 IMFMediaType_Release(in_type);
859 in_type_score = score;
861 IMFMediaType_AddRef(in_type);
864 IMFMediaType_Release(type);
890 }
else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) {
901 IMFMediaType_Release(in_type);
913 for (n = 0; n < 2 && (need_input ||
need_output); n++) {
918 need_input = ret < 1;
948 (c->
out_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) ||
949 (c->
out_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES);
964 IMFAttributes *attrs;
973 hr = IMFTransform_GetAttributes(c->
mft, &attrs);
979 hr = IMFAttributes_GetUINT32(attrs, &MF_TRANSFORM_ASYNC, &v);
990 hr = IMFAttributes_SetUINT32(attrs, &MF_TRANSFORM_ASYNC_UNLOCK, TRUE);
996 hr = IMFTransform_QueryInterface(c->
mft, &IID_IMFMediaEventGenerator, (
void **)&c->
async_events);
1005 IMFAttributes_Release(attrs);
1013 MFT_REGISTER_TYPE_INFO reg = {0};
1022 reg.guidSubtype = *subtype;
1025 reg.guidMajorType = MFMediaType_Audio;
1026 category = MFT_CATEGORY_AUDIO_ENCODER;
1028 reg.guidMajorType = MFMediaType_Video;
1029 category = MFT_CATEGORY_VIDEO_ENCODER;
1068 hr = IMFTransform_QueryInterface(c->
mft, &IID_ICodecAPI, (
void **)&c->
codec_api);
1074 if (hr == E_NOTIMPL) {
1076 }
else if (FAILED(hr)) {
1087 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
1093 hr = IMFTransform_ProcessMessage(c->
mft, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
1101 int sleep = 10000, total = 0;
1103 while (total < 70*1000) {
1120 avctx->
extradata ?
"Got" :
"Didn't get", total / 1000);
1146 #define OFFSET(x) offsetof(MFContext, x) 1148 #define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, EXTRA) \ 1149 static const AVClass ff_ ## NAME ## _mf_encoder_class = { \ 1150 .class_name = #NAME "_mf", \ 1151 .item_name = av_default_item_name, \ 1153 .version = LIBAVUTIL_VERSION_INT, \ 1155 AVCodec ff_ ## NAME ## _mf_encoder = { \ 1156 .priv_class = &ff_ ## NAME ## _mf_encoder_class, \ 1157 .name = #NAME "_mf", \ 1158 .long_name = NULL_IF_CONFIG_SMALL(#ID " via MediaFoundation"), \ 1159 .type = AVMEDIA_TYPE_ ## MEDIATYPE, \ 1160 .id = AV_CODEC_ID_ ## ID, \ 1161 .priv_data_size = sizeof(MFContext), \ 1163 .close = mf_close, \ 1164 .receive_packet = mf_receive_packet, \ 1166 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, \ 1167 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | \ 1168 FF_CODEC_CAP_INIT_CLEANUP, \ 1172 .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, \ 1173 AV_SAMPLE_FMT_NONE }, 1179 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1182 {
"default",
"Default mode", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0,
VE,
"rate_control"},
1193 {
"default",
"Default scenario", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0,
VE,
"scenario"},
1207 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ 1208 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)
ptrdiff_t const GLvoid * data
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[]
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
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.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
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)
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
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
MFT_OUTPUT_STREAM_INFO out_info
static int mf_init(AVCodecContext *avctx)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
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)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
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
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)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
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)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#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)
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.