21 #include <mfx/mfxvideo.h>
22 #include <mfx/mfxplugin.h>
37 #if QSV_VERSION_ATLEAST(1, 12)
38 #include "mfx/mfxvp8.h"
46 #if QSV_VERSION_ATLEAST(1, 8)
48 return MFX_CODEC_HEVC;
52 return MFX_CODEC_MPEG2;
55 #if QSV_VERSION_ATLEAST(1, 12)
69 return MFX_PROFILE_UNKNOWN;
75 return 4 * profile + 1;
79 return MFX_PROFILE_UNKNOWN;
87 { MFX_ERR_NONE, 0,
"success" },
89 { MFX_ERR_NULL_PTR,
AVERROR(EINVAL),
"NULL pointer" },
90 { MFX_ERR_UNSUPPORTED,
AVERROR(ENOSYS),
"unsupported" },
91 { MFX_ERR_MEMORY_ALLOC,
AVERROR(ENOMEM),
"failed to allocate memory" },
92 { MFX_ERR_NOT_ENOUGH_BUFFER,
AVERROR(ENOMEM),
"insufficient input/output buffer" },
93 { MFX_ERR_INVALID_HANDLE,
AVERROR(EINVAL),
"invalid handle" },
94 { MFX_ERR_LOCK_MEMORY,
AVERROR(EIO),
"failed to lock the memory block" },
95 { MFX_ERR_NOT_INITIALIZED,
AVERROR_BUG,
"not initialized" },
96 { MFX_ERR_NOT_FOUND,
AVERROR(ENOSYS),
"specified object was not found" },
97 { MFX_ERR_MORE_DATA,
AVERROR(EAGAIN),
"expect more data at input" },
98 { MFX_ERR_MORE_SURFACE,
AVERROR(EAGAIN),
"expect more surface at output" },
100 { MFX_ERR_DEVICE_LOST,
AVERROR(EIO),
"device lost" },
101 { MFX_ERR_INCOMPATIBLE_VIDEO_PARAM,
AVERROR(EINVAL),
"incompatible video parameters" },
102 { MFX_ERR_INVALID_VIDEO_PARAM,
AVERROR(EINVAL),
"invalid video parameters" },
103 { MFX_ERR_UNDEFINED_BEHAVIOR,
AVERROR_BUG,
"undefined behavior" },
104 { MFX_ERR_DEVICE_FAILED,
AVERROR(EIO),
"device failed" },
105 { MFX_ERR_MORE_BITSTREAM,
AVERROR(EAGAIN),
"expect more bitstream at output" },
106 { MFX_ERR_INCOMPATIBLE_AUDIO_PARAM,
AVERROR(EINVAL),
"incompatible audio parameters" },
107 { MFX_ERR_INVALID_AUDIO_PARAM,
AVERROR(EINVAL),
"invalid audio parameters" },
109 { MFX_WRN_IN_EXECUTION, 0,
"operation in execution" },
110 { MFX_WRN_DEVICE_BUSY, 0,
"device busy" },
111 { MFX_WRN_VIDEO_PARAM_CHANGED, 0,
"video parameters changed" },
112 { MFX_WRN_PARTIAL_ACCELERATION, 0,
"partial acceleration" },
113 { MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, 0,
"incompatible video parameters" },
114 { MFX_WRN_VALUE_NOT_CHANGED, 0,
"value is saturated" },
115 { MFX_WRN_OUT_OF_RANGE, 0,
"value out of range" },
116 { MFX_WRN_FILTER_SKIPPED, 0,
"filter skipped" },
117 { MFX_WRN_INCOMPATIBLE_AUDIO_PARAM, 0,
"incompatible audio parameters" },
131 *desc =
"unknown error";
136 const char *error_string)
146 const char *warning_string)
171 *fourcc = MFX_FOURCC_NV12;
175 *fourcc = MFX_FOURCC_P010;
185 for (i = 0; i < ctx->
nb_mids; i++) {
196 if (!load_plugins || !*load_plugins)
199 while (*load_plugins) {
207 if (strlen(plugin) != 2 *
sizeof(uid.Data)) {
210 goto load_plugin_fail;
213 for (i = 0; i <
sizeof(uid.Data); i++) {
214 err = sscanf(plugin + 2 * i,
"%2hhx", uid.Data + i);
218 goto load_plugin_fail;
223 ret = MFXVideoUSER_Load(session, &uid, 1);
226 snprintf(errorbuf,
sizeof(errorbuf),
227 "Could not load the requested plugin '%s'", plugin);
229 goto load_plugin_fail;
245 const char *load_plugins)
247 mfxIMPL impl = MFX_IMPL_AUTO_ANY;
253 ret = MFXInit(impl, &ver, session);
256 "Error initializing an internal MFX session");
264 MFXQueryIMPL(*session, &impl);
266 switch (MFX_IMPL_BASETYPE(impl)) {
267 case MFX_IMPL_SOFTWARE:
270 case MFX_IMPL_HARDWARE:
271 case MFX_IMPL_HARDWARE2:
272 case MFX_IMPL_HARDWARE3:
273 case MFX_IMPL_HARDWARE4:
274 desc =
"hardware accelerated";
281 "Initialized an internal MFX session using %s implementation\n",
298 int nb_surfaces = frames_hwctx->nb_surfaces;
322 for (i = 0; i < nb_surfaces; i++) {
324 mid->
handle = frames_hwctx->surfaces[i].Data.MemId;
337 int nb_surfaces = frames_hwctx->nb_surfaces;
347 for (i = 0; i < nb_surfaces; i++)
348 resp->mids[i] = &mids[i];
349 resp->NumFrameActual = nb_surfaces;
351 resp->mids[resp->NumFrameActual] = (mfxMemId)
av_buffer_ref(hw_frames_ref);
352 if (!resp->mids[resp->NumFrameActual]) {
357 resp->mids[resp->NumFrameActual + 1] =
av_buffer_ref(mids_buf);
358 if (!resp->mids[resp->NumFrameActual + 1]) {
368 mfxFrameAllocResponse *resp)
375 if (!(req->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET |
376 MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)) ||
377 !(req->Type & (MFX_MEMTYPE_FROM_DECODE | MFX_MEMTYPE_FROM_ENCODE)))
378 return MFX_ERR_UNSUPPORTED;
380 if (req->Type & MFX_MEMTYPE_EXTERNAL_FRAME) {
384 mfxFrameInfo *i = &req->Info;
385 mfxFrameInfo *i1 = &frames_hwctx->surfaces[0].Info;
387 if (i->Width != i1->Width || i->Height != i1->Height ||
388 i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) {
390 "allocation request: %dx%d %d %d vs %dx%d %d %d\n",
391 i->Width, i->Height, i->FourCC, i->ChromaFormat,
392 i1->Width, i1->Height, i1->FourCC, i1->ChromaFormat);
393 return MFX_ERR_UNSUPPORTED;
399 "Error filling an external frame allocation request\n");
400 return MFX_ERR_MEMORY_ALLOC;
402 }
else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) {
405 mfxFrameInfo *i = &req->Info;
413 return MFX_ERR_MEMORY_ALLOC;
416 frames_hwctx = frames_ctx->hwctx;
420 frames_ctx->width = i->Width;
421 frames_ctx->height = i->Height;
422 frames_ctx->initial_pool_size = req->NumFrameSuggested;
424 frames_hwctx->frame_type = req->Type;
429 "Error initializing a frames context for an internal frame "
430 "allocation request\n");
432 return MFX_ERR_MEMORY_ALLOC;
438 return MFX_ERR_MEMORY_ALLOC;
446 "Error filling an internal frame allocation request\n");
447 return MFX_ERR_MEMORY_ALLOC;
450 return MFX_ERR_UNSUPPORTED;
472 return MFX_ERR_UNDEFINED_BEHAVIOR;
477 return MFX_ERR_MEMORY_ALLOC;
500 qsv_mid->
surf.Info = hw_frames_hwctx->surfaces[0].Info;
518 return MFX_ERR_MEMORY_ALLOC;
540 const char *load_plugins,
int opaque)
543 MFX_HANDLE_VA_DISPLAY,
544 MFX_HANDLE_D3D9_DEVICE_MANAGER,
545 MFX_HANDLE_D3D11_DEVICE,
547 mfxFrameAllocator frame_allocator = {
548 .pthis = qsv_frames_ctx,
559 mfxSession parent_session = device_hwctx->session;
564 mfxHDL handle =
NULL;
570 err = MFXQueryIMPL(parent_session, &impl);
571 if (err == MFX_ERR_NONE)
572 err = MFXQueryVersion(parent_session, &ver);
573 if (err != MFX_ERR_NONE)
575 "Error querying the session attributes");
578 err = MFXVideoCORE_GetHandle(parent_session, handle_types[i], &handle);
579 if (err == MFX_ERR_NONE) {
587 "from the session\n");
590 err = MFXInit(impl, &ver, &session);
591 if (err != MFX_ERR_NONE)
593 "Error initializing a child MFX session");
596 err = MFXVideoCORE_SetHandle(session,
handle_type, handle);
597 if (err != MFX_ERR_NONE)
599 "Error setting a HW handle");
609 qsv_frames_ctx->
logctx = avctx;
617 qsv_frames_ctx->
nb_mids = frames_hwctx->nb_surfaces;
619 err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator);
620 if (err != MFX_ERR_NONE)
622 "Error setting a frame allocator");
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req, mfxFrameAllocResponse *resp)
ptrdiff_t const GLvoid * data
static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
#define AV_LOG_WARNING
Something somehow does not look correct.
mfxHandleType handle_type
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
This struct is allocated as AVHWFramesContext.hwctx.
static int qsv_load_plugins(mfxSession session, const char *load_plugins, void *logctx)
int width
The allocated dimensions of the frames in this pool.
int ff_qsv_init_session_hwcontext(AVCodecContext *avctx, mfxSession *psession, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque)
AVBufferRef * hw_frames_ctx
int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string)
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
8 bits with AV_PIX_FMT_RGB32 palette
static void mids_buf_free(void *opaque, uint8_t *data)
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
#define AV_LOG_VERBOSE
Detailed information.
int ff_qsv_map_error(mfxStatus mfx_err, const char **desc)
Convert a libmfx error code into an ffmpeg error code.
This struct is allocated as AVHWDeviceContext.hwctx.
AVCodecID
Identify the syntax and semantics of the bitstream.
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
static void * av_mallocz_array(size_t nmemb, size_t size)
char * av_get_token(const char **buf, const char *term)
Unescape the given string until a non escaped terminating char, and return the token corresponding to...
int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string)
int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc)
int ff_qsv_profile_to_mfx(enum AVCodecID codec_id, int profile)
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
#define QSV_VERSION_MINOR
#define FF_PROFILE_UNKNOWN
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
preferred ID for MPEG-1/2 video decoding
#define FF_ARRAY_ELEMS(a)
static const mfxHandleType handle_types[]
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
static const struct @106 qsv_errors[]
Libavcodec external API header.
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
uint8_t * data
The data buffer.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AV_PIX_FMT_YUV420P10
static const char * format
AVBufferRef * hw_frames_ref
This struct describes a set or pool of "hardware" frames (i.e.
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
static int qsv_setup_mids(mfxFrameAllocResponse *resp, AVBufferRef *hw_frames_ref, AVBufferRef *mids_buf)
static AVBufferRef * qsv_create_mids(AVBufferRef *hw_frames_ref)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
A reference to a data buffer.
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
common internal and external API header
static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
static enum AVPixelFormat qsv_map_fourcc(uint32_t fourcc)
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags)
Map a hardware frame.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, const char *load_plugins)
#define QSV_VERSION_MAJOR
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
The mapping must be direct.
An API-specific header for AV_HWDEVICE_TYPE_QSV.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
AVPixelFormat
Pixel format.