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 <mfx/mfxvideo.h>
31
44
52
54
55 #define PTS_TO_MFX_PTS(pts, pts_tb) ((pts) == AV_NOPTS_VALUE ? \
56 MFX_TIMESTAMP_UNKNOWN : pts_tb.num ? \
57 av_rescale_q(pts, pts_tb, mfx_tb) : pts)
58
59 #define MFX_PTS_TO_PTS(mfx_pts, pts_tb) ((mfx_pts) == MFX_TIMESTAMP_UNKNOWN ? \
60 AV_NOPTS_VALUE : pts_tb.num ? \
61 av_rescale_q(mfx_pts, mfx_tb, pts_tb) : mfx_pts)
62
67
69 // the session used for decoding
72
73 // the session we allocated internally, in case the caller did not provide
74 // one
76
78
79 /**
80 * a linked list of frames currently being used by QSV
81 */
83
87
94
95 // options set by the caller
99
101
105
113 },
115 },
117 };
118
121 {
123
125
128
132 break;
136 break;
139 break;
140 default:
143 }
144
148
155 }
156
160
161 return 0;
162 }
163
166 {
168
169 if (q->
gpu_copy == MFX_GPUCOPY_ON &&
170 !(q->
iopattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY)) {
172 "only works in system memory mode.\n");
174 }
175 if (session) {
177 } else if (hw_frames_ref) {
181 }
183
187
190 q->
iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY,
195 }
196
198 } else if (hw_device_ref) {
202 }
203
208
210 } else {
216 }
217
219 }
220
221 if (MFXQueryVersion(q->
session, &q->
ver) != MFX_ERR_NONE) {
224
228 }
229
231 }
232
233 /* make sure the decoder is uninitialized */
234 MFXVideoDECODE_Close(q->
session);
235
236 return 0;
237 }
238
240 {
241 mfxSession session =
NULL;
242 int iopattern = 0;
245 AV_PIX_FMT_QSV,
/* opaque format in case of video memory output */
246 pix_fmt,
/* system memory format obtained from bitstream parser */
248
253 }
254
259 }
260
267 }
268
272
274
278 }
279
281 frames_hwctx = hwframes_ctx->
hwctx;
287 frames_hwctx->
frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
288
290
295 }
296 }
297
301
303 if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
304 iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
305 else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
306 iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
307 }
308 }
309
310 if (!iopattern)
311 iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
313
315
320 }
321
326
327 return 0;
328 }
329
331 {
333
334 avctx->
width = param->mfx.FrameInfo.CropW;
335 avctx->
height = param->mfx.FrameInfo.CropH;
338 avctx->
level = param->mfx.CodecLevel;
339 avctx->
profile = param->mfx.CodecProfile;
342
346 "Error initializing the MFX video decoder");
347
349
353 return 0;
354 }
355
358 mfxVideoParam *param)
359 {
361 mfxExtVideoSignalInfo video_signal_info = { 0 };
362 mfxExtBuffer *header_ext_params[1] = { (mfxExtBuffer *)&video_signal_info };
363 mfxBitstream bs = { 0 };
364
366 bs.Data = avpkt->
data;
367 bs.DataLength = avpkt->
size;
368 bs.MaxLength = bs.DataLength;
371 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
372 } else
374
375
380 }
381
385
386 param->mfx.CodecId =
ret;
387 video_signal_info.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
388 video_signal_info.Header.BufferSz = sizeof(video_signal_info);
389 // The SDK doesn't support other ext buffers when calling MFXVideoDECODE_DecodeHeader,
390 // so do not append this buffer to the existent buffer array
391 param->ExtParam = header_ext_params;
392 param->NumExtParam = 1;
393 ret = MFXVideoDECODE_DecodeHeader(q->
session, &bs, param);
394 if (MFX_ERR_MORE_DATA ==
ret) {
396 }
399 "Error decoding stream header");
400
402
403 if (video_signal_info.ColourDescriptionPresent) {
405 avctx->
color_trc = video_signal_info.TransferCharacteristics;
406 avctx->
colorspace = video_signal_info.MatrixCoefficients;
407 }
408
411
412 #if QSV_VERSION_ATLEAST(1, 34)
415 #endif
416
417 return 0;
418 }
419
421 {
423
426 else
428
431
433 frame->surface = *(mfxFrameSurface1*)
frame->frame->data[3];
434 } else {
439 }
440 }
441
443
448
450 }
451
452 frame->surface.Data.ExtParam =
frame->ext_param;
453 frame->surface.Data.NumExtParam = 0;
454 frame->num_ext_params = 0;
455 frame->dec_info.Header.BufferId = MFX_EXTBUFF_DECODED_FRAME_INFO;
456 frame->dec_info.Header.BufferSz =
sizeof(
frame->dec_info);
458 #if QSV_VERSION_ATLEAST(1, 34)
460 frame->av1_film_grain_param.Header.BufferId = MFX_EXTBUFF_AV1_FILM_GRAIN_PARAM;
461 frame->av1_film_grain_param.Header.BufferSz =
sizeof(
frame->av1_film_grain_param);
462 frame->av1_film_grain_param.FilmGrainFlags = 0;
464 }
465 #endif
466
468
469 return 0;
470 }
471
473 {
475 while (cur) {
479 }
481 }
482 }
483
485 {
488
490
498 *surf = &
frame->surface;
499 return 0;
500 }
501
504 }
505
513 }
515
519
520 *surf = &
frame->surface;
521
522 return 0;
523 }
524
526 {
528 while (cur) {
530 return cur;
532 }
534 }
535
536 #if QSV_VERSION_ATLEAST(1, 34)
538 {
542
543 if (!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_APPLY))
544 return 0;
545
547
548 if (!fgp)
550
552 fgp->
seed = ext_param->GrainSeed;
554
560 aom->
overlap_flag = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_OVERLAP);
561 aom->
limit_output_range = !!(ext_param->FilmGrainFlags & MFX_FILM_GRAIN_CLIP_TO_RESTRICTED_RANGE);
562
564
566 aom->
y_points[
i][0] = ext_param->PointY[
i].Value;
567 aom->
y_points[
i][1] = ext_param->PointY[
i].Scaling;
568 }
569
571
573 aom->
uv_points[0][
i][0] = ext_param->PointCb[
i].Value;
574 aom->
uv_points[0][
i][1] = ext_param->PointCb[
i].Scaling;
575 }
576
578
580 aom->
uv_points[1][
i][0] = ext_param->PointCr[
i].Value;
581 aom->
uv_points[1][
i][1] = ext_param->PointCr[
i].Scaling;
582 }
583
584 for (
i = 0;
i < 24;
i++)
586
587 for (
i = 0;
i < 25;
i++) {
590 }
591
592 aom->
uv_mult[0] = ext_param->CbMult;
593 aom->
uv_mult[1] = ext_param->CrMult;
598
599 return 0;
600 }
601 #endif
602
606 {
607 mfxFrameSurface1 *insurf;
608 mfxFrameSurface1 *outsurf;
609 mfxSyncPoint *sync;
610 mfxBitstream bs = { { { 0 } } };
612
614 bs.Data = avpkt->
data;
615 bs.DataLength = avpkt->
size;
616 bs.MaxLength = bs.DataLength;
619 bs.DataFlag |= MFX_BITSTREAM_COMPLETE_FRAME;
620 }
621
623 if (!sync) {
626 }
627
628 do {
633 }
634
636 insurf, &outsurf, sync);
637 if (
ret == MFX_WRN_DEVICE_BUSY)
639
640 }
while (
ret == MFX_WRN_DEVICE_BUSY ||
ret == MFX_ERR_MORE_SURFACE);
641
642 if (
ret == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) {
646 return 0;
647 }
648
649 if (
ret != MFX_ERR_NONE &&
650 ret != MFX_ERR_MORE_DATA &&
651 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
652 ret != MFX_ERR_MORE_SURFACE) {
655 "Error during QSV decoding.");
656 }
657
658 /* make sure we do not enter an infinite loop if the SDK
659 * did not consume any data and did not return anything */
660 if (!*sync && !bs.DataOffset) {
661 bs.DataOffset = avpkt->
size;
665 } else {
667 }
668
669 if (*sync) {
672
673 if (!out_frame) {
675 "The returned surface does not correspond to any frame\n");
678 }
679
681
684 } else {
686 }
687
692
695
697 do {
699 }
while (
ret == MFX_WRN_IN_EXECUTION);
700 }
701
703
705
709
711
713 #if QSV_VERSION_ATLEAST(1, 34)
717 ret = qsv_export_film_grain(avctx, &aframe.
frame->av1_film_grain_param,
frame);
718
721 }
722 #endif
723
725 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :
726 outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :
727 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;
728 frame->top_field_first =
729 outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;
730 frame->interlaced_frame =
731 !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);
733 //Key frame is IDR frame is only suitable for H264. For HEVC, IRAPs are key frames.
736
737 /* update the surface properties */
739 ((mfxFrameSurface1*)
frame->data[3])->Info = outsurf->Info;
740
741 *got_frame = 1;
742 }
743
744 return bs.DataOffset;
745 }
746
748 {
750
752 MFXVideoDECODE_Close(q->
session);
753
759 }
760
761 while (cur) {
766 }
767
769
773 }
774
777 {
779 mfxVideoParam param = { 0 };
781
784
785 /* TODO: flush delayed frames on reinit */
786
787 // sw_pix_fmt, coded_width/height should be set for ff_get_format(),
788 // assume sw_pix_fmt is NV12 and coded_width/height to be 1280x720,
789 // the assumption may be not corret but will be updated after header decoded if not true.
796
797 /* decode zero-size pkt to flush the buffered pkt before reinit */
801 if (
ret < 0 || *got_frame)
803 }
804
806 mfxFrameAllocRequest request;
807 memset(&request, 0, sizeof(request));
808
814 else
816 goto reinit_fail;
817 }
819
821
824
825 ret = MFXVideoDECODE_QueryIOSurf(q->
session, ¶m, &request);
828
830
833 goto reinit_fail;
835 }
836
840 goto reinit_fail;
842 }
843
845
846 reinit_fail:
849 }
850
855 };
856
860
862
864
867
869 {
873
875 }
876
878 {
880
882
884
886
887 return 0;
888 }
889
891 {
895
897 uid =
"f622394d8d87452f878c51f2fc9b4131";
899 uid =
"a922394d8d87452f878c51f2fc9b4131";
900 }
902 static const char * const uid_hevcdec_sw = "15dd936825ad475ea34e35f3f54217a6";
903 static const char * const uid_hevcdec_hw = "33a61c0b4c27454ca8d85dde757c6f8e";
904
905 if (
s->qsv.load_plugins[0]) {
907 "load_plugins is not empty, but load_plugin is not set to 'none'."
908 "The load_plugin value will be ignored.\n");
909 } else {
911 uid = uid_hevcdec_sw;
912 else
913 uid = uid_hevcdec_hw;
914 }
915 }
919 if (!
s->qsv.load_plugins)
921 }
922
926 if (!
s->packet_fifo) {
929 }
930
933
934 return 0;
938 }
939
942 {
945
946 /* buffer the input packet */
949
954 }
955
956 /* process buffered data */
957 while (!*got_frame) {
958 /* prepare the input data */
959 if (
s->buffer_pkt.size <= 0) {
960 /* no more data */
963 /* in progress of reinit, no read from fifo and keep the buffer_pkt */
964 if (!
s->qsv.reinit_flag) {
967 }
968 }
969
972 /* Drop buffer_pkt when failed to decode the packet. Otherwise,
973 the decoder will keep decoding the failure packet. */
976 }
977 if (
s->qsv.reinit_flag)
978 continue;
979
980 s->buffer_pkt.size -=
ret;
981 s->buffer_pkt.data +=
ret;
982 }
983
985 }
986
988 {
990
992
994 s->qsv.initialized = 0;
995 }
996
997 #define OFFSET(x) offsetof(QSVDecContext, x)
998 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
999
1000 #define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \
1001 static const AVClass x##_qsv_class = { \
1002 .class_name = #x "_qsv", \
1003 .item_name = av_default_item_name, \
1004 .option = opt, \
1005 .version = LIBAVUTIL_VERSION_INT, \
1006 }; \
1007 const FFCodec ff_##x##_qsv_decoder = { \
1008 .p.name = #x "_qsv", \
1009 .p.long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync Video acceleration)"), \
1010 .priv_data_size = sizeof(QSVDecContext), \
1011 .p.type = AVMEDIA_TYPE_VIDEO, \
1012 .p.id = AV_CODEC_ID_##X, \
1013 .init = qsv_decode_init, \
1014 FF_CODEC_DECODE_CB(qsv_decode_frame), \
1015 .flush = qsv_decode_flush, \
1016 .close = qsv_decode_close, \
1017 .bsfs = bsf_name, \
1018 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \
1019 .p.priv_class = &x##_qsv_class, \
1020 .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \
1021 AV_PIX_FMT_P010, \
1022 AV_PIX_FMT_YUYV422, \
1023 AV_PIX_FMT_Y210, \
1024 AV_PIX_FMT_QSV, \
1025 AV_PIX_FMT_NONE }, \
1026 .hw_configs = qsv_hw_configs, \
1027 .p.wrapper_name = "qsv", \
1028 }; \
1029
1030 #define DEFINE_QSV_DECODER(x, X, bsf_name) DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, options)
1031
1032 #if CONFIG_HEVC_QSV_DECODER
1035
1040
1041 { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
1043
1044 {
"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"},
1049 };
1051 #endif
1052
1055
1056 {
"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"},
1061 };
1062
1063 #if CONFIG_H264_QSV_DECODER
1065 #endif
1066
1067 #if CONFIG_MPEG2_QSV_DECODER
1069 #endif
1070
1071 #if CONFIG_VC1_QSV_DECODER
1073 #endif
1074
1075 #if CONFIG_MJPEG_QSV_DECODER
1077 #endif
1078
1079 #if CONFIG_VP8_QSV_DECODER
1081 #endif
1082
1083 #if CONFIG_VP9_QSV_DECODER
1085 #endif
1086
1087 #if CONFIG_AV1_QSV_DECODER
1089 #endif