Go to the documentation of this file.
26 #include <sys/types.h>
28 #include <mfx/mfxvideo.h>
143 if (q->
gpu_copy == MFX_GPUCOPY_ON &&
144 !(q->
iopattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY)) {
146 "only works in system memory mode.\n");
151 }
else if (hw_frames_ref) {
164 q->
iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY,
172 }
else if (hw_device_ref) {
196 MFXVideoDECODE_Close(q->
session);
203 return sizeof(mfxSyncPoint*) +
sizeof(
QSVFrame*);
213 mfxSession session =
NULL;
246 if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
247 iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
248 else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
249 iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
254 iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
277 avctx->
width = param->mfx.FrameInfo.CropW;
278 avctx->
height = param->mfx.FrameInfo.CropH;
281 avctx->
level = param->mfx.CodecLevel;
282 avctx->
profile = param->mfx.CodecProfile;
289 "Error initializing the MFX video decoder");
301 mfxVideoParam *param)
305 mfxBitstream bs = { 0 };
308 bs.Data = avpkt->
data;
309 bs.DataLength = avpkt->
size;
310 bs.MaxLength = bs.DataLength;
311 bs.TimeStamp = avpkt->
pts;
313 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
328 param->mfx.CodecId =
ret;
329 ret = MFXVideoDECODE_DecodeHeader(q->
session, &bs, param);
330 if (MFX_ERR_MORE_DATA ==
ret) {
335 "Error decoding stream header");
353 frame->surface = *(mfxFrameSurface1*)
frame->frame->data[3];
357 frame->surface.Data.PitchLow =
frame->frame->linesize[0];
358 frame->surface.Data.Y =
frame->frame->data[0];
359 frame->surface.Data.UV =
frame->frame->data[1];
369 frame->surface.Data.ExtParam = &
frame->ext_param;
370 frame->surface.Data.NumExtParam = 1;
371 frame->ext_param = (mfxExtBuffer*)&
frame->dec_info;
372 frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO;
373 frame->dec_info.Header.BufferSz =
sizeof(
frame->dec_info);
406 *surf = &
frame->surface;
428 *surf = &
frame->surface;
449 mfxFrameSurface1 *insurf;
450 mfxFrameSurface1 *outsurf;
452 mfxBitstream bs = { { { 0 } } };
456 bs.Data = avpkt->
data;
457 bs.DataLength = avpkt->
size;
458 bs.MaxLength = bs.DataLength;
459 bs.TimeStamp = avpkt->
pts;
461 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
478 insurf, &outsurf, sync);
479 if (
ret == MFX_WRN_DEVICE_BUSY)
482 }
while (
ret == MFX_WRN_DEVICE_BUSY ||
ret == MFX_ERR_MORE_SURFACE);
484 if (
ret != MFX_ERR_NONE &&
485 ret != MFX_ERR_MORE_DATA &&
486 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
487 ret != MFX_ERR_MORE_SURFACE) {
490 "Error during QSV decoding.");
495 if (!*sync && !bs.DataOffset) {
496 bs.DataOffset = avpkt->
size;
500 }
else if (!*sync && bs.DataOffset) {
511 "The returned surface does not correspond to any frame\n");
533 ret = MFXVideoCORE_SyncOperation(q->
session, *sync, 1000);
534 }
while (
ret == MFX_WRN_IN_EXECUTION);
539 src_frame = out_frame->
frame;
549 frame->pkt_pts = outsurf->Data.TimeStamp;
552 frame->pts = outsurf->Data.TimeStamp;
555 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
556 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
557 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
558 frame->top_field_first =
559 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
560 frame->interlaced_frame =
561 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
565 frame->key_frame = !!(out_frame->
dec_info.FrameType & MFX_FRAMETYPE_IDR);
569 ((mfxFrameSurface1*)
frame->data[3])->Info = outsurf->Info;
574 return bs.DataOffset;
582 MFXVideoDECODE_Close(q->
session);
615 mfxVideoParam param = { 0 };
723 uid =
"f622394d8d87452f878c51f2fc9b4131";
725 uid =
"a922394d8d87452f878c51f2fc9b4131";
728 static const char *
const uid_hevcdec_sw =
"15dd936825ad475ea34e35f3f54217a6";
729 static const char *
const uid_hevcdec_hw =
"33a61c0b4c27454ca8d85dde757c6f8e";
731 if (
s->qsv.load_plugins[0]) {
733 "load_plugins is not empty, but load_plugin is not set to 'none'."
734 "The load_plugin value will be ignored.\n");
737 uid = uid_hevcdec_sw;
739 uid = uid_hevcdec_hw;
745 if (!
s->qsv.load_plugins)
751 if (!
s->packet_fifo) {
787 while (!*got_frame) {
789 if (
s->buffer_pkt.size <= 0) {
794 if (!
s->qsv.reinit_flag) {
807 if (
s->qsv.reinit_flag)
810 s->buffer_pkt.size -=
ret;
811 s->buffer_pkt.data +=
ret;
824 s->qsv.initialized = 0;
827 #define OFFSET(x) offsetof(QSVDecContext, x)
828 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
830 #define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \
831 static const AVClass x##_qsv_class = { \
832 .class_name = #x "_qsv", \
833 .item_name = av_default_item_name, \
835 .version = LIBAVUTIL_VERSION_INT, \
837 AVCodec ff_##x##_qsv_decoder = { \
839 .long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync Video acceleration)"), \
840 .priv_data_size = sizeof(QSVDecContext), \
841 .type = AVMEDIA_TYPE_VIDEO, \
842 .id = AV_CODEC_ID_##X, \
843 .init = qsv_decode_init, \
844 .decode = qsv_decode_frame, \
845 .flush = qsv_decode_flush, \
846 .close = qsv_decode_close, \
848 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \
849 .priv_class = &x##_qsv_class, \
850 .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \
854 .hw_configs = qsv_hw_configs, \
855 .wrapper_name = "qsv", \
858 #define DEFINE_QSV_DECODER(x, X, bsf_name) DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, options)
860 #if CONFIG_HEVC_QSV_DECODER
869 {
"load_plugins",
"A :-separate list of hexadecimal plugin UIDs to load in an internal session",
872 {
"gpu_copy",
"A GPU-accelerated copy between video and system memory",
OFFSET(qsv.gpu_copy),
AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF,
VD,
"gpu_copy"},
884 {
"gpu_copy",
"A GPU-accelerated copy between video and system memory",
OFFSET(qsv.gpu_copy),
AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF,
VD,
"gpu_copy"},
891 #if CONFIG_H264_QSV_DECODER
895 #if CONFIG_MPEG2_QSV_DECODER
899 #if CONFIG_VC1_QSV_DECODER
903 #if CONFIG_MJPEG_QSV_DECODER
907 #if CONFIG_VP8_QSV_DECODER
911 #if CONFIG_VP9_QSV_DECODER
915 #if CONFIG_AV1_QSV_DECODER
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
#define FF_ENABLE_DEPRECATION_WARNINGS
void * hwaccel_context
Hardware accelerator context.
#define AV_LOG_WARNING
Something somehow does not look correct.
AVPixelFormat
Pixel format.
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
static int qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *pkt)
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
AVBufferRef * hw_frames_ctx
uint8_t * data
The data buffer.
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
static unsigned int qsv_fifo_size(const AVFifoBuffer *fifo)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int ff_qsv_close_internal_session(QSVSession *qs)
This structure describes decoded (raw) audio or video data.
enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
enum AVFieldOrder field_order
Field order.
int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
AVBufferRef * av_buffer_allocz(buffer_size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
QSVFrame * work_frames
a linked list of frames currently being used by QSV
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
int iopattern
The IO pattern to use.
int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, AVBufferRef *device_ref, const char *load_plugins, int gpu_copy)
AVBufferPool * av_buffer_pool_init(buffer_size_t size, AVBufferRef *(*alloc)(buffer_size_t size))
Allocate and initialize a buffer pool.
AVFifoBuffer * packet_fifo
#define DEFINE_QSV_DECODER(x, X, bsf_name)
static const AVOption options[]
#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static QSVFrame * find_frame(QSVContext *q, mfxFrameSurface1 *surf)
static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, const AVPacket *avpkt, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string)
int av_fifo_space(const AVFifoBuffer *f)
Return the amount of space in bytes in the AVFifoBuffer, that is the amount of data you can write int...
#define ASYNC_DEPTH_DEFAULT
@ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
The codec supports this format via the hw_frames_ctx interface.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
static av_cold int qsv_decode_init(AVCodecContext *avctx)
static unsigned int qsv_fifo_item_size(void)
QSVFramesContext frames_ctx
static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
static enum AVPixelFormat pix_fmts[]
enum AVPixelFormat pix_fmt
For decoders, a hardware pixel format which that decoder may be able to decode to if suitable hardwar...
static enum AVPixelFormat pix_fmt
int av_usleep(unsigned usec)
Sleep for a period of time.
int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
Resize an AVFifoBuffer.
int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque, int gpu_copy)
Describe the class of an AVClass context structure.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, const char *extra_string)
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
AVFifoBuffer * async_fifo
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
static void qsv_clear_buffers(QSVDecContext *s)
mfxExtBuffer ** ext_buffers
static void qsv_decode_close_qsvcontext(QSVContext *q)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
mfxSession session
If non-NULL, the session to use for encoding or decoding.
static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *avpkt)
static av_cold int qsv_decode_close(AVCodecContext *avctx)
mfxExtBuffer ** ext_buffers
Extra buffers to pass to encoder or decoder initialization.
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.
static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
@ AV_CODEC_HW_CONFIG_METHOD_AD_HOC
The codec supports this format by some ad-hoc method.
static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session, AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
This struct describes a set or pool of "hardware" frames (i.e.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
main external API structure.
enum AVPixelFormat orig_pix_fmt
static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param)
This struct is used for communicating QSV parameters between libavcodec and the caller.
enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define FF_DISABLE_DEPRECATION_WARNINGS
static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferPool *pool)
This struct is allocated as AVHWFramesContext.hwctx.
int coded_width
Bitstream width / height, may be different from width/height e.g.
char * av_strdup(const char *s)
Duplicate a string.
A reference to a data buffer.
mfxExtDecodedFrameInfo dec_info
int ff_attach_decode_data(AVFrame *frame)
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
This structure stores compressed data.
static void qsv_clear_unused_frames(QSVContext *q)
int width
picture width / height.
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
AVCodecHWConfig public
This is the structure which will be returned to the user by avcodec_get_hw_config().
int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string)
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins, int gpu_copy)
static void qsv_decode_flush(AVCodecContext *avctx)
static const AVCodecHWConfigInternal *const qsv_hw_configs[]