FFmpeg
Loading...
Searching...
No Matches
qsvdec.c
Go to the documentation of this file.
1/*
2 * Intel MediaSDK QSV codec-independent code
3 *
4 * copyright (c) 2013 Luca Barbato
5 * copyright (c) 2015 Anton Khirnov <anton@khirnov.net>
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include "config_components.h"
25
26#include <stdint.h>
27#include <string.h>
28#include <sys/types.h>
29
30#include <mfxvideo.h>
31
32#include "libavutil/common.h"
33#include "libavutil/fifo.h"
34#include "libavutil/frame.h"
35#include "libavutil/hwcontext.h"
37#include "libavutil/mem.h"
38#include "libavutil/log.h"
39#include "libavutil/opt.h"
40#include "libavutil/pixfmt.h"
41#include "libavutil/time.h"
42#include "libavutil/imgutils.h"
45#include "libavutil/avassert.h"
46
47#include "avcodec.h"
48#include "codec_internal.h"
49#include "internal.h"
50#include "decode.h"
51#include "hwconfig.h"
52#include "qsv.h"
53#include "qsv_internal.h"
54#include "libavutil/refstruct.h"
55
56#if QSV_ONEVPL
57#include <mfxdispatcher.h>
58#else
59#define MFXUnload(a) do { } while(0)
60#endif
61
62static const AVRational mfx_tb = { 1, 90000 };
63
64#define PTS_TO_MFX_PTS(pts, pts_tb) ((pts) == AV_NOPTS_VALUE ? \
65 MFX_TIMESTAMP_UNKNOWN : pts_tb.num ? \
66 av_rescale_q(pts, pts_tb, mfx_tb) : pts)
67
68#define MFX_PTS_TO_PTS(mfx_pts, pts_tb) ((mfx_pts) == MFX_TIMESTAMP_UNKNOWN ? \
69 AV_NOPTS_VALUE : pts_tb.num ? \
70 av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
71
72#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
73
74typedef struct QSVAsyncFrame {
75 mfxSyncPoint *sync;
78
79typedef struct QSVContext {
80 // the session used for decoding
81 mfxSession session;
82 mfxVersion ver;
83 mfxHandleType handle_type;
84
85 // the session we allocated internally, in case the caller did not provide
86 // one
88
90
91 /**
92 * a linked list of frames currently being used by QSV
93 */
95
99
101 uint32_t fourcc;
102 mfxFrameInfo frame_info;
106
107 // options set by the caller
111
113
114 mfxExtBuffer **ext_buffers;
116} QSVContext;
117
119 &(const AVCodecHWConfigInternal) {
120 .public = {
121 .pix_fmt = AV_PIX_FMT_QSV,
124 .device_type = AV_HWDEVICE_TYPE_QSV,
125 },
126 .hwaccel = NULL,
127 },
128 NULL
129};
130
132 AVBufferPool *pool)
133{
134 int ret = 0;
135
136 ret = ff_decode_frame_props(avctx, frame);
137 if (ret < 0)
138 return ret;
139
140 frame->width = avctx->coded_width;
141 frame->height = avctx->coded_height;
142
143 switch (avctx->pix_fmt) {
144 case AV_PIX_FMT_NV12:
145 frame->linesize[0] = FFALIGN(avctx->coded_width, 128);
146 break;
147 case AV_PIX_FMT_P010:
148 case AV_PIX_FMT_P012:
150 frame->linesize[0] = 2 * FFALIGN(avctx->coded_width, 128);
151 break;
152 case AV_PIX_FMT_Y210:
153 case AV_PIX_FMT_VUYX:
154 case AV_PIX_FMT_XV30:
155 case AV_PIX_FMT_Y212:
156 frame->linesize[0] = 4 * FFALIGN(avctx->coded_width, 128);
157 break;
158 case AV_PIX_FMT_XV36:
159 frame->linesize[0] = 8 * FFALIGN(avctx->coded_width, 128);
160 break;
161 default:
162 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n");
163 return AVERROR(EINVAL);
164 }
165
166 frame->buf[0] = av_buffer_pool_get(pool);
167 if (!frame->buf[0])
168 return AVERROR(ENOMEM);
169
170 frame->data[0] = frame->buf[0]->data;
171 if (avctx->pix_fmt == AV_PIX_FMT_NV12 ||
172 avctx->pix_fmt == AV_PIX_FMT_P010 ||
173 avctx->pix_fmt == AV_PIX_FMT_P012) {
174 frame->linesize[1] = frame->linesize[0];
175 frame->data[1] = frame->data[0] +
176 frame->linesize[0] * FFALIGN(avctx->coded_height, 64);
177 }
178
179 ret = ff_attach_decode_data(avctx, frame);
180 if (ret < 0)
181 return ret;
182
183 return 0;
184}
185
186static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session,
187 AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
188{
189 int ret;
190 mfxIMPL impl;
191
192 if (q->gpu_copy == MFX_GPUCOPY_ON &&
193 !(q->iopattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY)) {
194 av_log(avctx, AV_LOG_WARNING, "GPU-accelerated memory copy "
195 "only works in system memory mode.\n");
196 q->gpu_copy = MFX_GPUCOPY_OFF;
197 }
198 if (session) {
199 q->session = session;
200 } else if (hw_frames_ref) {
201 if (q->internal_qs.session) {
202 MFXClose(q->internal_qs.session);
204 }
207
208 q->frames_ctx.hw_frames_ctx = av_buffer_ref(hw_frames_ref);
210 return AVERROR(ENOMEM);
211
213 &q->frames_ctx, q->load_plugins,
215 q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY,
216#else
217 0,
218#endif
219 q->gpu_copy);
220 if (ret < 0) {
222 return ret;
223 }
224
226 } else if (hw_device_ref) {
227 if (q->internal_qs.session) {
228 MFXClose(q->internal_qs.session);
230 }
231
233 hw_device_ref, q->load_plugins, q->gpu_copy);
234 if (ret < 0)
235 return ret;
236
238 } else {
239 if (!q->internal_qs.session) {
241 q->load_plugins, q->gpu_copy);
242 if (ret < 0)
243 return ret;
244 }
245
247 }
248
249 if (MFXQueryIMPL(q->session, &impl) == MFX_ERR_NONE) {
250 switch (MFX_IMPL_VIA_MASK(impl)) {
251 case MFX_IMPL_VIA_VAAPI:
252 q->handle_type = MFX_HANDLE_VA_DISPLAY;
253 break;
254
255 case MFX_IMPL_VIA_D3D11:
256 q->handle_type = MFX_HANDLE_D3D11_DEVICE;
257 break;
258
259 case MFX_IMPL_VIA_D3D9:
260 q->handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
261 break;
262
263 default:
264 av_assert0(!"should not reach here");
265 }
266 } else {
267 av_log(avctx, AV_LOG_ERROR, "Error querying the implementation. \n");
268 goto fail;
269 }
270
271 if (MFXQueryVersion(q->session, &q->ver) != MFX_ERR_NONE) {
272 av_log(avctx, AV_LOG_ERROR, "Error querying the session version. \n");
273 goto fail;
274 }
275
276 /* make sure the decoder is uninitialized */
277 MFXVideoDECODE_Close(q->session);
278
279 return 0;
280
281fail:
282 q->session = NULL;
283
284 if (q->internal_qs.session) {
285 MFXClose(q->internal_qs.session);
287 }
288
289 if (q->internal_qs.loader) {
292 }
293
294 return AVERROR_EXTERNAL;
295}
296
297static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
298{
299 mfxSession session = NULL;
300 int iopattern = 0;
301 int ret;
302 enum AVPixelFormat pix_fmts[3] = {
303 AV_PIX_FMT_QSV, /* opaque format in case of video memory output */
304 pix_fmt, /* system memory format obtained from bitstream parser */
306
307 ret = ff_get_format(avctx, pix_fmts);
308 if (ret < 0) {
310 return ret;
311 }
312
313 if (!q->async_fifo) {
315 if (!q->async_fifo)
316 return AVERROR(ENOMEM);
317 }
318
319 if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) {
320 AVQSVContext *user_ctx = avctx->hwaccel_context;
321 session = user_ctx->session;
322 iopattern = user_ctx->iopattern;
323 q->ext_buffers = user_ctx->ext_buffers;
324 q->nb_ext_buffers = user_ctx->nb_ext_buffers;
325 }
326
327 if (avctx->hw_device_ctx && !avctx->hw_frames_ctx && ret == AV_PIX_FMT_QSV) {
328 AVHWFramesContext *hwframes_ctx;
329 AVQSVFramesContext *frames_hwctx;
330
332
333 if (!avctx->hw_frames_ctx) {
334 av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
335 return AVERROR(ENOMEM);
336 }
337
338 hwframes_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
339 frames_hwctx = hwframes_ctx->hwctx;
340 hwframes_ctx->width = FFALIGN(avctx->coded_width, 32);
341 hwframes_ctx->height = FFALIGN(avctx->coded_height, 32);
342 hwframes_ctx->format = AV_PIX_FMT_QSV;
343 hwframes_ctx->sw_format = avctx->sw_pix_fmt;
344 if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 9) && q->handle_type != MFX_HANDLE_D3D9_DEVICE_MANAGER)
345 hwframes_ctx->initial_pool_size = 0;
346 else
347 hwframes_ctx->initial_pool_size = q->suggest_pool_size + 16 + avctx->extra_hw_frames;
348 frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
349
351
352 if (ret < 0) {
353 av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
355 return ret;
356 }
357 }
358
359 if (avctx->hw_frames_ctx) {
361 AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
362
363 if (!iopattern) {
364#if QSV_HAVE_OPAQUE
365 if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
366 iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
367 else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
368 iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
369#else
370 if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
371 iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
372#endif
373 }
374 }
375
376 if (!iopattern)
377 iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
378 q->iopattern = iopattern;
379
380 ff_qsv_print_iopattern(avctx, q->iopattern, "Decoder");
381
382 ret = qsv_init_session(avctx, q, session, avctx->hw_frames_ctx, avctx->hw_device_ctx);
383 if (ret < 0) {
384 av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
385 return ret;
386 }
387
388 param->IOPattern = q->iopattern;
389 param->AsyncDepth = q->async_depth;
390 param->ExtParam = q->ext_buffers;
391 param->NumExtParam = q->nb_ext_buffers;
392
393 return 0;
394 }
395
396static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param)
397{
398 int ret;
399
400 avctx->width = param->mfx.FrameInfo.CropW;
401 avctx->height = param->mfx.FrameInfo.CropH;
402 avctx->coded_width = param->mfx.FrameInfo.Width;
403 avctx->coded_height = param->mfx.FrameInfo.Height;
404 avctx->level = param->mfx.CodecLevel;
405 avctx->profile = param->mfx.CodecProfile;
406 avctx->field_order = ff_qsv_map_picstruct(param->mfx.FrameInfo.PicStruct);
407 avctx->pix_fmt = ff_qsv_map_fourcc(param->mfx.FrameInfo.FourCC);
408
409 ret = MFXVideoDECODE_Init(q->session, param);
410 if (ret < 0)
411 return ff_qsv_print_error(avctx, ret,
412 "Error initializing the MFX video decoder");
413
414 q->frame_info = param->mfx.FrameInfo;
415
416 if (!avctx->hw_frames_ctx) {
417 ret = av_image_get_buffer_size(avctx->pix_fmt, FFALIGN(avctx->coded_width, 128), FFALIGN(avctx->coded_height, 64), 1);
418 if (ret < 0)
419 return ret;
421 }
422 return 0;
423}
424
426 const AVPacket *avpkt, enum AVPixelFormat pix_fmt,
427 mfxVideoParam *param)
428{
429 int ret;
430 mfxExtVideoSignalInfo video_signal_info = { 0 };
431 mfxExtBuffer *header_ext_params[1] = { (mfxExtBuffer *)&video_signal_info };
432 mfxBitstream bs = { 0 };
433
434 if (avpkt->size) {
435 bs.Data = avpkt->data;
436 bs.DataLength = avpkt->size;
437 bs.MaxLength = bs.DataLength;
438 bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase);
439 if (avctx->field_order == AV_FIELD_PROGRESSIVE)
440 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
441 } else
442 return AVERROR_INVALIDDATA;
443
444
445 if(!q->session) {
446 ret = qsv_decode_preinit(avctx, q, pix_fmt, param);
447 if (ret < 0)
448 return ret;
449 }
450
451 ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
452 if (ret < 0)
453 return ret;
454
455 param->mfx.CodecId = ret;
456 video_signal_info.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
457 video_signal_info.Header.BufferSz = sizeof(video_signal_info);
458 // The SDK doesn't support other ext buffers when calling MFXVideoDECODE_DecodeHeader,
459 // so do not append this buffer to the existent buffer array
460 param->ExtParam = header_ext_params;
461 param->NumExtParam = 1;
462 ret = MFXVideoDECODE_DecodeHeader(q->session, &bs, param);
463 if (MFX_ERR_MORE_DATA == ret) {
464 return AVERROR(EAGAIN);
465 }
466 if (ret < 0)
467 return ff_qsv_print_error(avctx, ret,
468 "Error decoding stream header");
469
470 avctx->color_range = video_signal_info.VideoFullRange ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
471
472 if (video_signal_info.ColourDescriptionPresent) {
473 avctx->color_primaries = video_signal_info.ColourPrimaries;
474 avctx->color_trc = video_signal_info.TransferCharacteristics;
475 avctx->colorspace = video_signal_info.MatrixCoefficients;
476 }
477
478 param->ExtParam = q->ext_buffers;
479 param->NumExtParam = q->nb_ext_buffers;
480
481 if (param->mfx.FrameInfo.FrameRateExtN == 0 || param->mfx.FrameInfo.FrameRateExtD == 0) {
482 param->mfx.FrameInfo.FrameRateExtN = 25;
483 param->mfx.FrameInfo.FrameRateExtD = 1;
484 }
485
486#if QSV_VERSION_ATLEAST(1, 34)
487 if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 34) && avctx->codec_id == AV_CODEC_ID_AV1)
488 param->mfx.FilmGrain = (avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) ? 0 : param->mfx.FilmGrain;
489#endif
490
491 return 0;
492}
493
495{
496 int ret;
497
498 if (q->pool)
499 ret = qsv_get_continuous_buffer(avctx, frame->frame, q->pool);
500 else
501 ret = ff_get_buffer(avctx, frame->frame, AV_GET_BUFFER_FLAG_REF);
502
503 if (ret < 0)
504 return ret;
505
506 if (frame->frame->format == AV_PIX_FMT_QSV) {
507 frame->surface = *(mfxFrameSurface1*)frame->frame->data[3];
508 } else {
509 ret = ff_qsv_map_frame_to_surface(frame->frame, &frame->surface);
510 if (ret < 0) {
511 av_log(avctx, AV_LOG_ERROR, "map frame to surface failed.\n");
512 return ret;
513 }
514 }
515
516 frame->surface.Info = q->frame_info;
517
518 if (q->frames_ctx.mids) {
520 if (ret < 0)
521 return ret;
522
523 frame->surface.Data.MemId = &q->frames_ctx.mids[ret];
524 }
525
526 frame->surface.Data.ExtParam = frame->ext_param;
527 frame->surface.Data.NumExtParam = 0;
528 frame->num_ext_params = 0;
529 frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO;
530 frame->dec_info.Header.BufferSz = sizeof(frame->dec_info);
531 ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->dec_info);
532#if QSV_VERSION_ATLEAST(1, 34)
533 if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 34) && avctx->codec_id == AV_CODEC_ID_AV1) {
534 frame->av1_film_grain_param.Header.BufferId = MFX_EXTBUFF_AV1_FILM_GRAIN_PARAM;
535 frame->av1_film_grain_param.Header.BufferSz = sizeof(frame->av1_film_grain_param);
536 frame->av1_film_grain_param.FilmGrainFlags = 0;
537 ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->av1_film_grain_param);
538 }
539#endif
540
541#if QSV_VERSION_ATLEAST(1, 35)
542 if ((QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == AV_CODEC_ID_HEVC) ||
543 (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 9) && avctx->codec_id == AV_CODEC_ID_AV1)) {
544 frame->mdcv.Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME;
545 frame->mdcv.Header.BufferSz = sizeof(frame->mdcv);
546 // The data in mdcv is valid when this flag is 1
547 frame->mdcv.InsertPayloadToggle = 0;
548 ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->mdcv);
549
550 frame->clli.Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO;
551 frame->clli.Header.BufferSz = sizeof(frame->clli);
552 // The data in clli is valid when this flag is 1
553 frame->clli.InsertPayloadToggle = 0;
554 ff_qsv_frame_add_ext_param(avctx, frame, (mfxExtBuffer *)&frame->clli);
555 }
556#endif
557
558 frame->used = 1;
559
560 return 0;
561}
562
564{
565 QSVFrame *cur = q->work_frames;
566 while (cur) {
567 if (cur->used && !cur->surface.Data.Locked && !cur->queued) {
568 cur->used = 0;
569 av_frame_unref(cur->frame);
570 }
571 cur = cur->next;
572 }
573}
574
575static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
576{
577 QSVFrame *frame, **last;
578 int ret;
579
581
582 frame = q->work_frames;
583 last = &q->work_frames;
584 while (frame) {
585 if (!frame->used) {
586 ret = alloc_frame(avctx, q, frame);
587 if (ret < 0)
588 return ret;
589 *surf = &frame->surface;
590 return 0;
591 }
592
593 last = &frame->next;
594 frame = frame->next;
595 }
596
597 frame = av_mallocz(sizeof(*frame));
598 if (!frame)
599 return AVERROR(ENOMEM);
600 frame->frame = av_frame_alloc();
601 if (!frame->frame) {
602 av_freep(&frame);
603 return AVERROR(ENOMEM);
604 }
605 *last = frame;
606
607 ret = alloc_frame(avctx, q, frame);
608 if (ret < 0)
609 return ret;
610
611 *surf = &frame->surface;
612
613 return 0;
614}
615
616static QSVFrame *find_frame(QSVContext *q, mfxFrameSurface1 *surf)
617{
618 QSVFrame *cur = q->work_frames;
619 while (cur) {
620 if (surf == &cur->surface)
621 return cur;
622 cur = cur->next;
623 }
624 return NULL;
625}
626
627#if QSV_VERSION_ATLEAST(1, 34)
628static int qsv_export_film_grain(AVCodecContext *avctx, mfxExtAV1FilmGrainParam *ext_param, AVFrame *frame)
629{
632 int i;
633
634 if (!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_APPLY))
635 return 0;
636
638
639 if (!fgp)
640 return AVERROR(ENOMEM);
641
643 fgp->seed = ext_param->GrainSeed;
644 aom = &fgp->codec.aom;
645
646 aom->chroma_scaling_from_luma = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_CHROMA_SCALING_FROM_LUMA);
647 aom->scaling_shift = ext_param->GrainScalingMinus8 + 8;
648 aom->ar_coeff_lag = ext_param->ArCoeffLag;
649 aom->ar_coeff_shift = ext_param->ArCoeffShiftMinus6 + 6;
650 aom->grain_scale_shift = ext_param->GrainScaleShift;
651 aom->overlap_flag = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_OVERLAP);
652 aom->limit_output_range = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_CLIP_TO_RESTRICTED_RANGE);
653
654 aom->num_y_points = ext_param->NumYPoints;
655
656 for (i = 0; i < aom->num_y_points; i++) {
657 aom->y_points[i][0] = ext_param->PointY[i].Value;
658 aom->y_points[i][1] = ext_param->PointY[i].Scaling;
659 }
660
661 aom->num_uv_points[0] = ext_param->NumCbPoints;
662
663 for (i = 0; i < aom->num_uv_points[0]; i++) {
664 aom->uv_points[0][i][0] = ext_param->PointCb[i].Value;
665 aom->uv_points[0][i][1] = ext_param->PointCb[i].Scaling;
666 }
667
668 aom->num_uv_points[1] = ext_param->NumCrPoints;
669
670 for (i = 0; i < aom->num_uv_points[1]; i++) {
671 aom->uv_points[1][i][0] = ext_param->PointCr[i].Value;
672 aom->uv_points[1][i][1] = ext_param->PointCr[i].Scaling;
673 }
674
675 for (i = 0; i < 24; i++)
676 aom->ar_coeffs_y[i] = ext_param->ArCoeffsYPlus128[i] - 128;
677
678 for (i = 0; i < 25; i++) {
679 aom->ar_coeffs_uv[0][i] = ext_param->ArCoeffsCbPlus128[i] - 128;
680 aom->ar_coeffs_uv[1][i] = ext_param->ArCoeffsCrPlus128[i] - 128;
681 }
682
683 aom->uv_mult[0] = ext_param->CbMult;
684 aom->uv_mult[1] = ext_param->CrMult;
685 aom->uv_mult_luma[0] = ext_param->CbLumaMult;
686 aom->uv_mult_luma[1] = ext_param->CrLumaMult;
687 aom->uv_offset[0] = ext_param->CbOffset;
688 aom->uv_offset[1] = ext_param->CrOffset;
689
690 return 0;
691}
692#endif
693
694#if QSV_VERSION_ATLEAST(1, 35)
695static int qsv_export_hdr_side_data(AVCodecContext *avctx, mfxExtMasteringDisplayColourVolume *mdcv,
696 mfxExtContentLightLevelInfo *clli, AVFrame *frame)
697{
698 int ret;
699
700 // The SDK reuses this flag for HDR SEI parsing
701 if (mdcv->InsertPayloadToggle) {
703 int mapping[3] = { 0, 1, 2 };
704 int chroma_den;
705 int max_luma_den;
706 int min_luma_den;
707
708 switch (avctx->codec_id) {
709 case AV_CODEC_ID_HEVC:
710 mapping[0] = 2;
711 mapping[1] = 0;
712 mapping[2] = 1;
713 chroma_den = 50000;
714 max_luma_den = 10000;
715 min_luma_den = 10000;
716 break;
717 case AV_CODEC_ID_AV1:
718 chroma_den = 1 << 16;
719 max_luma_den = 1 << 8;
720 min_luma_den = 1 << 14;
721 break;
722 default:
723 return AVERROR(ENOSYS);
724 }
725
726 ret = ff_decode_mastering_display_new(avctx, frame, &mastering);
727 if (ret < 0)
728 return ret;
729
730 if (mastering) {
731 for (int i = 0; i < 3; i++) {
732 const int j = mapping[i];
733 mastering->display_primaries[i][0] = av_make_q(mdcv->DisplayPrimariesX[j], chroma_den);
734 mastering->display_primaries[i][1] = av_make_q(mdcv->DisplayPrimariesY[j], chroma_den);
735 }
736
737 mastering->white_point[0] = av_make_q(mdcv->WhitePointX, chroma_den);
738 mastering->white_point[1] = av_make_q(mdcv->WhitePointY, chroma_den);
739
740 mastering->max_luminance = av_make_q(mdcv->MaxDisplayMasteringLuminance, max_luma_den);
741 mastering->min_luminance = av_make_q(mdcv->MinDisplayMasteringLuminance, min_luma_den);
742
743 mastering->has_luminance = 1;
744 mastering->has_primaries = 1;
745 }
746 }
747
748 // The SDK reuses this flag for HDR SEI parsing
749 if (clli->InsertPayloadToggle) {
751
752 ret = ff_decode_content_light_new(avctx, frame, &light);
753 if (ret < 0)
754 return ret;
755
756 if (light) {
757 light->MaxCLL = clli->MaxContentLightLevel;
758 light->MaxFALL = clli->MaxPicAverageLightLevel;
759 }
760 }
761
762 return 0;
763}
764#endif
765
767 AVFrame *frame, int *got_frame,
768 const AVPacket *avpkt)
769{
770 mfxFrameSurface1 *insurf;
771 mfxFrameSurface1 *outsurf;
772 mfxSyncPoint *sync;
773 mfxBitstream bs = { { { 0 } } };
774 int ret;
775
776 if (avpkt->size) {
777 bs.Data = avpkt->data;
778 bs.DataLength = avpkt->size;
779 bs.MaxLength = bs.DataLength;
780 bs.TimeStamp = PTS_TO_MFX_PTS(avpkt->pts, avctx->pkt_timebase);
781 if (avctx->field_order == AV_FIELD_PROGRESSIVE)
782 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
783 }
784
785 sync = av_mallocz(sizeof(*sync));
786 if (!sync) {
787 av_freep(&sync);
788 return AVERROR(ENOMEM);
789 }
790
791 do {
792 ret = get_surface(avctx, q, &insurf);
793 if (ret < 0) {
794 av_freep(&sync);
795 return ret;
796 }
797
798 ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL,
799 insurf, &outsurf, sync);
800 if (ret == MFX_WRN_DEVICE_BUSY)
801 av_usleep(500);
802
803 } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
804
805 if (ret == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) {
806 q->reinit_flag = 1;
807 av_log(avctx, AV_LOG_DEBUG, "Video parameter change\n");
808 av_freep(&sync);
809 return 0;
810 }
811
812 if (ret != MFX_ERR_NONE &&
813 ret != MFX_ERR_MORE_DATA &&
814 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
815 ret != MFX_ERR_MORE_SURFACE) {
816 av_freep(&sync);
817 return ff_qsv_print_error(avctx, ret,
818 "Error during QSV decoding.");
819 }
820
821 /* make sure we do not enter an infinite loop if the SDK
822 * did not consume any data and did not return anything */
823 if (!*sync && !bs.DataOffset) {
824 bs.DataOffset = avpkt->size;
825 ++q->zero_consume_run;
826 if (q->zero_consume_run > 1 &&
827 (avpkt->size ||
828 ret != MFX_ERR_MORE_DATA))
829 ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data");
830 } else {
831 q->zero_consume_run = 0;
832 }
833
834 if (*sync) {
835 QSVAsyncFrame aframe;
836 QSVFrame *out_frame = find_frame(q, outsurf);
837
838 if (!out_frame) {
839 av_log(avctx, AV_LOG_ERROR,
840 "The returned surface does not correspond to any frame\n");
841 av_freep(&sync);
842 return AVERROR_BUG;
843 }
844
845 out_frame->queued += 1;
846
847 aframe = (QSVAsyncFrame){ sync, out_frame };
848 av_fifo_write(q->async_fifo, &aframe, 1);
849 } else {
850 av_freep(&sync);
851 }
852
853 if ((av_fifo_can_read(q->async_fifo) >= q->async_depth) ||
854 (!avpkt->size && av_fifo_can_read(q->async_fifo))) {
855 QSVAsyncFrame aframe;
856 AVFrame *src_frame;
857
858 av_fifo_read(q->async_fifo, &aframe, 1);
859 aframe.frame->queued -= 1;
860
861 if (avctx->pix_fmt != AV_PIX_FMT_QSV) {
862 do {
863 ret = MFXVideoCORE_SyncOperation(q->session, *aframe.sync, 1000);
864 } while (ret == MFX_WRN_IN_EXECUTION);
865 }
866
867 av_freep(&aframe.sync);
868
869 src_frame = aframe.frame->frame;
870
871 ret = av_frame_ref(frame, src_frame);
872 if (ret < 0)
873 return ret;
874
875 outsurf = &aframe.frame->surface;
876
877 frame->pts = MFX_PTS_TO_PTS(outsurf->Data.TimeStamp, avctx->pkt_timebase);
878#if QSV_VERSION_ATLEAST(1, 34)
880 QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 34) &&
881 avctx->codec_id == AV_CODEC_ID_AV1) {
882 ret = qsv_export_film_grain(avctx, &aframe.frame->av1_film_grain_param, frame);
883
884 if (ret < 0)
885 return ret;
886 }
887#endif
888
889#if QSV_VERSION_ATLEAST(1, 35)
890 if ((QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 35) && avctx->codec_id == AV_CODEC_ID_HEVC) ||
891 (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 2, 9) && avctx->codec_id == AV_CODEC_ID_AV1)) {
892 ret = qsv_export_hdr_side_data(avctx, &aframe.frame->mdcv, &aframe.frame->clli, frame);
893 if (ret < 0)
894 return ret;
895 }
896#endif
897
898 frame->repeat_pict =
899 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
900 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
901 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
903 !!(outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF);
905 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
906 frame->pict_type = ff_qsv_map_pictype(aframe.frame->dec_info.FrameType);
907
908 if (avctx->codec_id == AV_CODEC_ID_H264 ||
909 avctx->codec_id == AV_CODEC_ID_HEVC ||
910 avctx->codec_id == AV_CODEC_ID_VVC) {
911 if (aframe.frame->dec_info.FrameType & MFX_FRAMETYPE_IDR)
912 frame->flags |= AV_FRAME_FLAG_KEY;
913 else
914 frame->flags &= ~AV_FRAME_FLAG_KEY;
915 } else {
916 if (aframe.frame->dec_info.FrameType & MFX_FRAMETYPE_I)
917 frame->flags |= AV_FRAME_FLAG_KEY;
918 else
919 frame->flags &= ~AV_FRAME_FLAG_KEY;
920 }
921 frame->crop_left = outsurf->Info.CropX;
922 frame->crop_top = outsurf->Info.CropY;
923 frame->crop_right = outsurf->Info.Width - (outsurf->Info.CropX + outsurf->Info.CropW);
924 frame->crop_bottom = outsurf->Info.Height - (outsurf->Info.CropY + outsurf->Info.CropH);
925
926 /* update the surface properties */
927 if (avctx->pix_fmt == AV_PIX_FMT_QSV)
928 ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info;
929
930 *got_frame = 1;
931 }
932
933 return bs.DataOffset;
934}
935
937{
938 QSVFrame *cur = q->work_frames;
939
940 if (q->session)
941 MFXVideoDECODE_Close(q->session);
942
943 if (q->async_fifo) {
944 QSVAsyncFrame aframe;
945 while (av_fifo_read(q->async_fifo, &aframe, 1) >= 0)
946 av_freep(&aframe.sync);
948 }
949
950 while (cur) {
951 q->work_frames = cur->next;
952 av_frame_free(&cur->frame);
953 av_freep(&cur);
954 cur = q->work_frames;
955 }
956
958
962}
963
965 AVFrame *frame, int *got_frame, const AVPacket *pkt)
966{
967 int ret;
968 mfxVideoParam param = { 0 };
970
971 if (!pkt->size)
972 return qsv_decode(avctx, q, frame, got_frame, pkt);
973
974 /* TODO: flush delayed frames on reinit */
975
976 // sw_pix_fmt, coded_width/height should be set for ff_get_format(),
977 // assume sw_pix_fmt is NV12 and coded_width/height to be 1280x720,
978 // the assumption may be not correct but will be updated after header decoded if not true.
981 if (!avctx->coded_width)
982 avctx->coded_width = 1280;
983 if (!avctx->coded_height)
984 avctx->coded_height = 720;
985
986 /* decode zero-size pkt to flush the buffered pkt before reinit */
987 if (q->reinit_flag) {
988 AVPacket zero_pkt = {0};
989 ret = qsv_decode(avctx, q, frame, got_frame, &zero_pkt);
990 if (ret < 0 || *got_frame)
991 return ret;
992 }
993
994 if (q->reinit_flag || !q->session || !q->initialized) {
995 mfxFrameAllocRequest request;
996 memset(&request, 0, sizeof(request));
997
998 q->reinit_flag = 0;
999 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, &param);
1000 if (ret < 0) {
1001 if (ret == AVERROR(EAGAIN))
1002 av_log(avctx, AV_LOG_VERBOSE, "More data is required to decode header\n");
1003 else
1004 av_log(avctx, AV_LOG_ERROR, "Error decoding header\n");
1005 goto reinit_fail;
1006 }
1007 param.IOPattern = q->iopattern;
1008
1009 q->orig_pix_fmt = avctx->pix_fmt = pix_fmt = ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC);
1010
1011 avctx->coded_width = param.mfx.FrameInfo.Width;
1012 avctx->coded_height = param.mfx.FrameInfo.Height;
1013
1014 ret = MFXVideoDECODE_QueryIOSurf(q->session, &param, &request);
1015 if (ret < 0)
1016 return ff_qsv_print_error(avctx, ret, "Error querying IO surface");
1017
1018 q->suggest_pool_size = request.NumFrameSuggested;
1019
1020 ret = qsv_decode_preinit(avctx, q, pix_fmt, &param);
1021 if (ret < 0)
1022 goto reinit_fail;
1023 q->initialized = 0;
1024 }
1025
1026 if (!q->initialized) {
1027 ret = qsv_decode_init_context(avctx, q, &param);
1028 if (ret < 0)
1029 goto reinit_fail;
1030 q->initialized = 1;
1031 }
1032
1033 return qsv_decode(avctx, q, frame, got_frame, pkt);
1034
1035reinit_fail:
1036 q->orig_pix_fmt = avctx->pix_fmt = AV_PIX_FMT_NONE;
1037 return ret;
1038}
1039
1045
1056
1058{
1059 AVPacket pkt;
1060 while (av_fifo_read(s->packet_fifo, &pkt, 1) >= 0)
1062
1063 av_packet_unref(&s->buffer_pkt);
1064}
1065
1067{
1068 QSVDecContext *s = avctx->priv_data;
1069
1071
1073
1074 av_fifo_freep2(&s->packet_fifo);
1075
1076 return 0;
1077}
1078
1080{
1081 QSVDecContext *s = avctx->priv_data;
1082 int ret;
1083 const char *uid = NULL;
1084
1085 if (avctx->codec_id == AV_CODEC_ID_VP8) {
1086 uid = "f622394d8d87452f878c51f2fc9b4131";
1087 } else if (avctx->codec_id == AV_CODEC_ID_VP9) {
1088 uid = "a922394d8d87452f878c51f2fc9b4131";
1089 }
1090 else if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != LOAD_PLUGIN_NONE) {
1091 static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
1092 static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
1093
1094 if (s->qsv.load_plugins[0]) {
1095 av_log(avctx, AV_LOG_WARNING,
1096 "load_plugins is not empty, but load_plugin is not set to 'none'."
1097 "The load_plugin value will be ignored.\n");
1098 } else {
1099 if (s->load_plugin == LOAD_PLUGIN_HEVC_SW)
1100 uid = uid_hevcdec_sw;
1101 else
1102 uid = uid_hevcdec_hw;
1103 }
1104 }
1105 if (uid) {
1106 av_freep(&s->qsv.load_plugins);
1107 s->qsv.load_plugins = av_strdup(uid);
1108 if (!s->qsv.load_plugins)
1109 return AVERROR(ENOMEM);
1110 }
1111
1112 s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12;
1113 s->packet_fifo = av_fifo_alloc2(1, sizeof(AVPacket),
1115 if (!s->packet_fifo) {
1116 ret = AVERROR(ENOMEM);
1117 goto fail;
1118 }
1119
1120 if (!avctx->pkt_timebase.num)
1121 av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n");
1122
1123 return 0;
1124fail:
1125 qsv_decode_close(avctx);
1126 return ret;
1127}
1128
1130 int *got_frame, AVPacket *avpkt)
1131{
1132 QSVDecContext *s = avctx->priv_data;
1133 int ret;
1134
1135 /* buffer the input packet */
1136 if (avpkt->size) {
1137 AVPacket input_ref;
1138
1139 ret = av_packet_ref(&input_ref, avpkt);
1140 if (ret < 0)
1141 return ret;
1142 av_fifo_write(s->packet_fifo, &input_ref, 1);
1143 }
1144
1145 /* process buffered data */
1146 while (!*got_frame) {
1147 /* prepare the input data */
1148 if (s->buffer_pkt.size <= 0) {
1149 /* no more data */
1150 if (!av_fifo_can_read(s->packet_fifo))
1151 return avpkt->size ? avpkt->size : qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt);
1152 /* in progress of reinit, no read from fifo and keep the buffer_pkt */
1153 if (!s->qsv.reinit_flag) {
1154 av_packet_unref(&s->buffer_pkt);
1155 av_fifo_read(s->packet_fifo, &s->buffer_pkt, 1);
1156 }
1157 }
1158
1159 ret = qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->buffer_pkt);
1160 if (ret < 0){
1161 if (ret == AVERROR(EAGAIN))
1162 ret = 0;
1163
1164 /* Drop buffer_pkt when failed to decode the packet. Otherwise,
1165 the decoder will keep decoding the failure packet. */
1166 av_packet_unref(&s->buffer_pkt);
1167 return ret;
1168 }
1169 if (s->qsv.reinit_flag)
1170 continue;
1171
1172 s->buffer_pkt.size -= ret;
1173 s->buffer_pkt.data += ret;
1174 }
1175
1176 return avpkt->size;
1177}
1178
1180{
1181 QSVDecContext *s = avctx->priv_data;
1182
1184
1185 s->qsv.orig_pix_fmt = AV_PIX_FMT_NONE;
1186 s->qsv.initialized = 0;
1187}
1188
1189#define OFFSET(x) offsetof(QSVDecContext, x)
1190#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1191
1192#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \
1193static const AVClass x##_qsv_class = { \
1194 .class_name = #x "_qsv", \
1195 .item_name = av_default_item_name, \
1196 .option = opt, \
1197 .version = LIBAVUTIL_VERSION_INT, \
1198}; \
1199const FFCodec ff_##x##_qsv_decoder = { \
1200 .p.name = #x "_qsv", \
1201 CODEC_LONG_NAME(#X " video (Intel Quick Sync Video acceleration)"), \
1202 .priv_data_size = sizeof(QSVDecContext), \
1203 .p.type = AVMEDIA_TYPE_VIDEO, \
1204 .p.id = AV_CODEC_ID_##X, \
1205 .init = qsv_decode_init, \
1206 FF_CODEC_DECODE_CB(qsv_decode_frame), \
1207 .flush = qsv_decode_flush, \
1208 .close = qsv_decode_close, \
1209 .bsfs = bsf_name, \
1210 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \
1211 .p.priv_class = &x##_qsv_class, \
1212 .hw_configs = qsv_hw_configs, \
1213 .p.wrapper_name = "qsv", \
1214 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING, \
1215}; \
1216
1217#define DEFINE_QSV_DECODER(x, X, bsf_name) DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, options)
1218
1219#if CONFIG_HEVC_QSV_DECODER
1220static const AVOption hevc_options[] = {
1221 { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
1222
1223 { "load_plugin", "A user plugin to load in an internal session", OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, .unit = "load_plugin" },
1224 { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE }, 0, 0, VD, .unit = "load_plugin" },
1225 { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_SW }, 0, 0, VD, .unit = "load_plugin" },
1226 { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_HEVC_HW }, 0, 0, VD, .unit = "load_plugin" },
1227
1228 { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
1229 OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
1230
1231 { "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, .unit = "gpu_copy"},
1232 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, .unit = "gpu_copy"},
1233 { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, .unit = "gpu_copy"},
1234 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, .unit = "gpu_copy"},
1235 { NULL },
1236};
1237DEFINE_QSV_DECODER_WITH_OPTION(hevc, HEVC, "hevc_mp4toannexb", hevc_options)
1238#endif
1239
1240static const AVOption options[] = {
1241 { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD },
1242
1243 { "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, .unit = "gpu_copy"},
1244 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_DEFAULT }, 0, 0, VD, .unit = "gpu_copy"},
1245 { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON }, 0, 0, VD, .unit = "gpu_copy"},
1246 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_OFF }, 0, 0, VD, .unit = "gpu_copy"},
1247 { NULL },
1248};
1249
1250#if CONFIG_H264_QSV_DECODER
1251DEFINE_QSV_DECODER(h264, H264, "h264_mp4toannexb")
1252#endif
1253
1254#if CONFIG_MPEG2_QSV_DECODER
1255DEFINE_QSV_DECODER(mpeg2, MPEG2VIDEO, NULL)
1256#endif
1257
1258#if CONFIG_VC1_QSV_DECODER
1259DEFINE_QSV_DECODER(vc1, VC1, NULL)
1260#endif
1261
1262#if CONFIG_MJPEG_QSV_DECODER
1263DEFINE_QSV_DECODER(mjpeg, MJPEG, NULL)
1264#endif
1265
1266#if CONFIG_VP8_QSV_DECODER
1267DEFINE_QSV_DECODER(vp8, VP8, NULL)
1268#endif
1269
1270#if CONFIG_VP9_QSV_DECODER
1271DEFINE_QSV_DECODER(vp9, VP9, NULL)
1272#endif
1273
1274#if CONFIG_AV1_QSV_DECODER
1275DEFINE_QSV_DECODER(av1, AV1, NULL)
1276#endif
1277
1278#if CONFIG_VVC_QSV_DECODER
1279DEFINE_QSV_DECODER(vvc, VVC, "vvc_mp4toannexb")
1280#endif
#define VD
Definition amfdec.c:787
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
common internal and external API header
#define NULL
Definition coverity.c:32
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1781
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition decode.c:1602
int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame)
Definition decode.c:1708
int ff_decode_content_light_new(const AVCodecContext *avctx, AVFrame *frame, AVContentLightMetadata **clm)
Wrapper around av_content_light_metadata_create_side_data(), which rejects side data overridden by th...
Definition decode.c:2312
int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame, AVMasteringDisplayMetadata **mdm)
Wrapper around av_mastering_display_metadata_create_side_data(), which rejects side data overridden b...
Definition decode.c:2267
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition decode.c:1233
@ AV_FIELD_PROGRESSIVE
Definition defs.h:222
static AVPacket * pkt
static enum AVPixelFormat pix_fmt
static AVFrame * frame
A generic FIFO API.
AVFilmGrainParams * av_film_grain_params_create_side_data(AVFrame *frame)
Allocate a complete AVFilmGrainParams and add it to the frame.
@ AV_FILM_GRAIN_PARAMS_AV1
The union is valid when interpreted as AVFilmGrainAOMParams (codec.aom)
reference-counted frame API
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition avcodec.h:415
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition avcodec.h:404
@ AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX
The codec supports this format via the hw_frames_ctx interface.
Definition codec.h:295
@ AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
The codec supports this format via the hw_device_ctx interface.
Definition codec.h:282
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_VVC
Definition codec_id.h:247
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition packet.c:442
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_allocz(size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
Definition buffer.c:93
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition buffer.c:328
AVBufferPool * av_buffer_pool_init(size_t size, AVBufferRef *(*alloc)(size_t size))
Allocate and initialize a buffer pool.
Definition buffer.c:283
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition buffer.c:390
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
Definition fifo.c:47
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
Definition fifo.c:286
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
Definition fifo.h:63
size_t av_fifo_can_read(const AVFifo *f)
Definition fifo.c:87
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
Definition fifo.c:188
int av_fifo_read(AVFifo *f, void *buf, size_t nb_elems)
Read data from a FIFO.
Definition fifo.c:240
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:695
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:700
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
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.
Definition imgutils.c:466
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
@ AV_HWDEVICE_TYPE_QSV
Definition hwcontext.h:33
An API-specific header for AV_HWDEVICE_TYPE_QSV.
misc image utilities
common internal api header.
#define av_cold
Definition attributes.h:117
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
UID uid
Definition mxfenc.c:2488
#define av_strdup(s)
Definition ops_static.c:55
AVOptions.
pixel format definitions
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_P012
Definition pixfmt.h:609
#define AV_PIX_FMT_Y210
Definition pixfmt.h:612
#define AV_PIX_FMT_P010
Definition pixfmt.h:608
#define AV_PIX_FMT_XV30
Definition pixfmt.h:615
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ 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...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_VUYX
packed VUYX 4:4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined
Definition pixfmt.h:406
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition pixfmt.h:74
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition pixfmt.h:247
#define AV_PIX_FMT_Y212
Definition pixfmt.h:613
#define AV_PIX_FMT_XV36
Definition pixfmt.h:616
int ff_qsv_map_frame_to_surface(const AVFrame *frame, mfxFrameSurface1 *surface)
Definition qsv.c:287
int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
Definition qsv.c:54
enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct)
Definition qsv.c:361
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins, int gpu_copy)
Definition qsv.c:681
int ff_qsv_print_error(void *log_ctx, mfxStatus err, const char *error_string)
Definition qsv.c:189
int ff_qsv_close_internal_session(QSVSession *qs)
Definition qsv.c:1159
int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession, QSVFramesContext *qsv_frames_ctx, const char *load_plugins, int opaque, int gpu_copy)
Definition qsv.c:1109
int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern, const char *extra_string)
Definition qsv.c:104
void ff_qsv_frame_add_ext_param(AVCodecContext *avctx, QSVFrame *frame, mfxExtBuffer *param)
Definition qsv.c:1177
int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, AVBufferRef *device_ref, const char *load_plugins, int gpu_copy)
Definition qsv.c:1032
enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type)
Definition qsv.c:379
enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
Definition qsv.c:207
int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame)
Definition qsv.c:348
int ff_qsv_print_warning(void *log_ctx, mfxStatus err, const char *warning_string)
Definition qsv.c:198
#define ASYNC_DEPTH_DEFAULT
#define QSV_HAVE_OPAQUE
#define QSV_RUNTIME_VERSION_ATLEAST(MFX_VERSION, MAJOR, MINOR)
static int qsv_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition qsvdec.c:1129
static int qsv_process_data(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *pkt)
Definition qsvdec.c:964
static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, const AVPacket *avpkt)
Definition qsvdec.c:766
static void qsv_clear_unused_frames(QSVContext *q)
Definition qsvdec.c:563
#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt)
Definition qsvdec.c:1192
static QSVFrame * find_frame(QSVContext *q, mfxFrameSurface1 *surf)
Definition qsvdec.c:616
static int qsv_decode_header(AVCodecContext *avctx, QSVContext *q, const AVPacket *avpkt, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
Definition qsvdec.c:425
static const AVRational mfx_tb
Definition qsvdec.c:62
#define PTS_TO_MFX_PTS(pts, pts_tb)
Definition qsvdec.c:64
static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixelFormat pix_fmt, mfxVideoParam *param)
Definition qsvdec.c:297
static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVideoParam *param)
Definition qsvdec.c:396
static int get_surface(AVCodecContext *avctx, QSVContext *q, mfxFrameSurface1 **surf)
Definition qsvdec.c:575
static void qsv_decode_flush(AVCodecContext *avctx)
Definition qsvdec.c:1179
#define MFXUnload(a)
Definition qsvdec.c:59
#define DEFINE_QSV_DECODER(x, X, bsf_name)
Definition qsvdec.c:1217
static void qsv_decode_close_qsvcontext(QSVContext *q)
Definition qsvdec.c:936
static const AVCodecHWConfigInternal *const qsv_hw_configs[]
Definition qsvdec.c:118
static void qsv_clear_buffers(QSVDecContext *s)
Definition qsvdec.c:1057
static av_cold int qsv_decode_init(AVCodecContext *avctx)
Definition qsvdec.c:1079
#define MFX_PTS_TO_PTS(mfx_pts, pts_tb)
Definition qsvdec.c:68
static av_cold int qsv_decode_close(AVCodecContext *avctx)
Definition qsvdec.c:1066
LoadPlugin
Definition qsvdec.c:1040
@ LOAD_PLUGIN_NONE
Definition qsvdec.c:1041
@ LOAD_PLUGIN_HEVC_HW
Definition qsvdec.c:1043
@ LOAD_PLUGIN_HEVC_SW
Definition qsvdec.c:1042
static int alloc_frame(AVCodecContext *avctx, QSVContext *q, QSVFrame *frame)
Definition qsvdec.c:494
#define MFX_IMPL_VIA_MASK(impl)
Definition qsvdec.c:72
#define OFFSET(x)
Definition qsvdec.c:1189
static int qsv_get_continuous_buffer(AVCodecContext *avctx, AVFrame *frame, AVBufferPool *pool)
Definition qsvdec.c:131
static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession session, AVBufferRef *hw_frames_ref, AVBufferRef *hw_device_ref)
Definition qsvdec.c:186
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:120
The buffer pool.
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition avcodec.h:554
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1472
enum AVFieldOrder field_order
Field order.
Definition avcodec.h:694
int level
Encoding level descriptor.
Definition avcodec.h:1651
int profile
profile
Definition avcodec.h:1641
int export_side_data
Bit set of AV_CODEC_EXPORT_DATA_* flags, which affects the kind of metadata exported in frame,...
Definition avcodec.h:1784
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
void * hwaccel_context
Legacy hardware accelerator context.
Definition avcodec.h:1448
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition avcodec.h:1494
int extra_hw_frames
Video decoding only.
Definition avcodec.h:1517
enum AVCodecID codec_id
Definition avcodec.h:453
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
void * priv_data
Definition avcodec.h:470
Content light level needed by to transmit HDR over HDMI (CTA-861.3).
unsigned MaxFALL
Max average light level per frame (cd/m^2).
unsigned MaxCLL
Max content light level (cd/m^2).
Definition fifo.c:35
This structure describes how to handle film grain synthesis for AOM codecs.
int chroma_scaling_from_luma
Signals whether to derive the chroma scaling function from the luma.
int limit_output_range
Signals to clip to limited color levels after film grain application.
int scaling_shift
Specifies the shift applied to the chroma components.
int grain_scale_shift
Signals the down shift applied to the generated gaussian numbers during synthesis.
int num_uv_points[2]
If chroma_scaling_from_luma is set to 0, signals the chroma scaling function parameters.
int overlap_flag
Signals whether to overlap film grain blocks.
int ar_coeff_lag
Specifies the auto-regression lag.
int uv_offset[2]
Offset used for component scaling function.
int ar_coeff_shift
Specifies the range of the auto-regressive coefficients.
uint8_t uv_points[2][10][2]
int8_t ar_coeffs_uv[2][25]
Chroma auto-regression coefficients.
int uv_mult[2]
Specifies the luma/chroma multipliers for the index to the component scaling function.
int8_t ar_coeffs_y[24]
Luma auto-regression coefficients.
int num_y_points
Number of points, and the scale and value for each point of the piecewise linear scaling function for...
This structure describes how to handle film grain synthesis in video for specific codecs.
AVFilmGrainAOMParams aom
union AVFilmGrainParams::@177057277273004265167152242113040056044005264354 codec
Additional fields may be added both here and in any structure included.
enum AVFilmGrainParamsType type
Specifies the codec for which this structure is valid.
uint64_t seed
Seed to use for the synthesis process, if the codec allows for it.
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int initial_pool_size
Initial size of the frame pool.
Definition hwcontext.h:190
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
Mastering display metadata capable of representing the color volume of the display used to master the...
int has_primaries
Flag indicating whether the display primaries (and white point) are set.
AVRational max_luminance
Max luminance of mastering display (cd/m^2).
AVRational min_luminance
Min luminance of mastering display (cd/m^2).
AVRational display_primaries[3][2]
CIE 1931 xy chromaticity coords of color primaries (r, g, b order).
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
int has_luminance
Flag indicating whether the luminance (min_ and max_) have been set.
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
uint8_t * data
Definition packet.h:603
This struct is used for communicating QSV parameters between libavcodec and the caller.
Definition qsv.h:36
int nb_ext_buffers
Definition qsv.h:52
mfxExtBuffer ** ext_buffers
Extra buffers to pass to encoder or decoder initialization.
Definition qsv.h:51
int iopattern
The IO pattern to use.
Definition qsv.h:46
mfxSession session
If non-NULL, the session to use for encoding or decoding.
Definition qsv.h:41
This struct is allocated as AVHWFramesContext.hwctx.
int frame_type
A combination of MFX_MEMTYPE_* describing the frame pool.
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
QSVFrame * frame
Definition qsvdec.c:76
mfxSyncPoint * sync
Definition qsvdec.c:75
mfxExtBuffer ** ext_buffers
Definition qsvdec.c:114
AVFifo * async_fifo
Definition qsvdec.c:96
int iopattern
Definition qsvdec.c:109
int zero_consume_run
Definition qsvdec.c:97
mfxSession session
Definition qsvdec.c:81
enum AVPixelFormat orig_pix_fmt
Definition qsvdec.c:100
int async_depth
Definition qsvdec.c:108
QSVFramesContext frames_ctx
Definition qsvdec.c:89
int suggest_pool_size
Definition qsvdec.c:104
int nb_ext_buffers
Definition qsvdec.c:115
int gpu_copy
Definition qsvdec.c:110
mfxHandleType handle_type
Definition qsvdec.c:83
char * load_plugins
Definition qsvdec.c:112
int reinit_flag
Definition qsvdec.c:98
uint32_t fourcc
Definition qsvdec.c:101
QSVSession internal_qs
Definition qsvdec.c:87
QSVFrame * work_frames
a linked list of frames currently being used by QSV
Definition qsvdec.c:94
AVBufferPool * pool
Definition qsvdec.c:103
mfxFrameInfo frame_info
Definition qsvdec.c:102
int initialized
Definition qsvdec.c:105
mfxVersion ver
Definition qsvdec.c:82
AVPacket buffer_pkt
Definition qsvdec.c:1054
AVFifo * packet_fifo
Definition qsvdec.c:1052
QSVContext qsv
Definition qsvdec.c:1048
int load_plugin
Definition qsvdec.c:1050
AVFrame * frame
struct QSVFrame * next
mfxFrameSurface1 surface
mfxExtDecodedFrameInfo dec_info
QSVMid * mids
The memory ids for the external frames.
AVBufferRef * hw_frames_ctx
mfxSession session
void * loader
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition time.c:93
static const AVOption hevc_options[]