]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
16d942f00aa3c55d6d55008cb3300cc8be86818e
[ffmpeg] / libavcodec / qsvenc.c
1 /*
2  * Intel MediaSDK QSV encoder utility functions
3  *
4  * copyright (c) 2013 Yukinori Yamazoe
5  * copyright (c) 2015 Anton Khirnov
6  *
7  * This file is part of Libav.
8  *
9  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 #include <string.h>
25 #include <sys/types.h>
26 #include <mfx/mfxvideo.h>
27
28 #include "libavutil/common.h"
29 #include "libavutil/hwcontext.h"
30 #include "libavutil/hwcontext_qsv.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/log.h"
33 #include "libavutil/time.h"
34 #include "libavutil/imgutils.h"
35
36 #include "avcodec.h"
37 #include "internal.h"
38 #include "qsv.h"
39 #include "qsv_internal.h"
40 #include "qsvenc.h"
41
42 static const struct {
43     mfxU16 profile;
44     const char *name;
45 } profile_names[] = {
46     { MFX_PROFILE_AVC_BASELINE,                 "baseline"              },
47     { MFX_PROFILE_AVC_MAIN,                     "main"                  },
48     { MFX_PROFILE_AVC_EXTENDED,                 "extended"              },
49     { MFX_PROFILE_AVC_HIGH,                     "high"                  },
50 #if QSV_VERSION_ATLEAST(1, 15)
51     { MFX_PROFILE_AVC_HIGH_422,                 "high 422"              },
52 #endif
53 #if QSV_VERSION_ATLEAST(1, 4)
54     { MFX_PROFILE_AVC_CONSTRAINED_BASELINE,     "constrained baseline"  },
55     { MFX_PROFILE_AVC_CONSTRAINED_HIGH,         "constrained high"      },
56     { MFX_PROFILE_AVC_PROGRESSIVE_HIGH,         "progressive high"      },
57 #endif
58     { MFX_PROFILE_MPEG2_SIMPLE,                 "simple"                },
59     { MFX_PROFILE_MPEG2_MAIN,                   "main"                  },
60     { MFX_PROFILE_MPEG2_HIGH,                   "high"                  },
61     { MFX_PROFILE_VC1_SIMPLE,                   "simple"                },
62     { MFX_PROFILE_VC1_MAIN,                     "main"                  },
63     { MFX_PROFILE_VC1_ADVANCED,                 "advanced"              },
64 #if QSV_VERSION_ATLEAST(1, 8)
65     { MFX_PROFILE_HEVC_MAIN,                    "main"                  },
66     { MFX_PROFILE_HEVC_MAIN10,                  "main10"                },
67     { MFX_PROFILE_HEVC_MAINSP,                  "mainsp"                },
68 #endif
69 };
70
71 static const char *print_profile(mfxU16 profile)
72 {
73     int i;
74     for (i = 0; i < FF_ARRAY_ELEMS(profile_names); i++)
75         if (profile == profile_names[i].profile)
76             return profile_names[i].name;
77     return "unknown";
78 }
79
80 static const struct {
81     mfxU16      rc_mode;
82     const char *name;
83 } rc_names[] = {
84     { MFX_RATECONTROL_CBR,     "CBR" },
85     { MFX_RATECONTROL_VBR,     "VBR" },
86     { MFX_RATECONTROL_CQP,     "CQP" },
87 #if QSV_HAVE_AVBR
88     { MFX_RATECONTROL_AVBR,    "AVBR" },
89 #endif
90 #if QSV_HAVE_LA
91     { MFX_RATECONTROL_LA,      "LA" },
92 #endif
93 #if QSV_HAVE_ICQ
94     { MFX_RATECONTROL_ICQ,     "ICQ" },
95     { MFX_RATECONTROL_LA_ICQ,  "LA_ICQ" },
96 #endif
97 #if QSV_HAVE_VCM
98     { MFX_RATECONTROL_VCM,     "VCM" },
99 #endif
100 #if QSV_VERSION_ATLEAST(1, 10)
101     { MFX_RATECONTROL_LA_EXT,  "LA_EXT" },
102 #endif
103 #if QSV_HAVE_LA_HRD
104     { MFX_RATECONTROL_LA_HRD,  "LA_HRD" },
105 #endif
106 #if QSV_HAVE_QVBR
107     { MFX_RATECONTROL_QVBR,    "QVBR" },
108 #endif
109 };
110
111 static const char *print_ratecontrol(mfxU16 rc_mode)
112 {
113     int i;
114     for (i = 0; i < FF_ARRAY_ELEMS(rc_names); i++)
115         if (rc_mode == rc_names[i].rc_mode)
116             return rc_names[i].name;
117     return "unknown";
118 }
119
120 static const char *print_threestate(mfxU16 val)
121 {
122     if (val == MFX_CODINGOPTION_ON)
123         return "ON";
124     else if (val == MFX_CODINGOPTION_OFF)
125         return "OFF";
126     return "unknown";
127 }
128
129 static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
130                              mfxExtBuffer **coding_opts)
131 {
132     mfxInfoMFX *info = &q->param.mfx;
133
134     mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[0];
135 #if QSV_HAVE_CO2
136     mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
137 #endif
138 #if QSV_HAVE_CO3
139     mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
140 #endif
141
142     av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
143            print_profile(info->CodecProfile), info->CodecLevel);
144
145     av_log(avctx, AV_LOG_VERBOSE, "GopPicSize: %"PRIu16"; GopRefDist: %"PRIu16"; GopOptFlag: ",
146            info->GopPicSize, info->GopRefDist);
147     if (info->GopOptFlag & MFX_GOP_CLOSED)
148         av_log(avctx, AV_LOG_VERBOSE, "closed ");
149     if (info->GopOptFlag & MFX_GOP_STRICT)
150         av_log(avctx, AV_LOG_VERBOSE, "strict ");
151     av_log(avctx, AV_LOG_VERBOSE, "; IdrInterval: %"PRIu16"\n", info->IdrInterval);
152
153     av_log(avctx, AV_LOG_VERBOSE, "TargetUsage: %"PRIu16"; RateControlMethod: %s\n",
154            info->TargetUsage, print_ratecontrol(info->RateControlMethod));
155
156     if (info->RateControlMethod == MFX_RATECONTROL_CBR ||
157         info->RateControlMethod == MFX_RATECONTROL_VBR
158 #if QSV_HAVE_VCM
159         || info->RateControlMethod == MFX_RATECONTROL_VCM
160 #endif
161         ) {
162         av_log(avctx, AV_LOG_VERBOSE,
163                "InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"\n",
164                info->InitialDelayInKB, info->TargetKbps, info->MaxKbps);
165     } else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
166         av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",
167                info->QPI, info->QPP, info->QPB);
168     }
169 #if QSV_HAVE_AVBR
170     else if (info->RateControlMethod == MFX_RATECONTROL_AVBR) {
171         av_log(avctx, AV_LOG_VERBOSE,
172                "TargetKbps: %"PRIu16"; Accuracy: %"PRIu16"; Convergence: %"PRIu16"\n",
173                info->TargetKbps, info->Accuracy, info->Convergence);
174     }
175 #endif
176 #if QSV_HAVE_LA
177     else if (info->RateControlMethod == MFX_RATECONTROL_LA
178 #if QSV_HAVE_LA_HRD
179              || info->RateControlMethod == MFX_RATECONTROL_LA_HRD
180 #endif
181              ) {
182         av_log(avctx, AV_LOG_VERBOSE,
183                "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
184                info->TargetKbps, co2->LookAheadDepth);
185     }
186 #endif
187 #if QSV_HAVE_ICQ
188     else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
189         av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);
190     } else if (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ) {
191         av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
192                info->ICQQuality, co2->LookAheadDepth);
193     }
194 #endif
195 #if QSV_HAVE_QVBR
196     else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
197         av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
198                co3->QVBRQuality);
199     }
200 #endif
201
202     av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",
203            info->NumSlice, info->NumRefFrame);
204     av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
205            print_threestate(co->RateDistortionOpt));
206
207 #if QSV_HAVE_CO2
208     av_log(avctx, AV_LOG_VERBOSE,
209            "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
210            print_threestate(co->RecoveryPointSEI), co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
211
212     av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %"PRIu16"; ", co2->MaxFrameSize);
213 #if QSV_HAVE_MAX_SLICE_SIZE
214     av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %"PRIu16"; ", co2->MaxSliceSize);
215 #endif
216     av_log(avctx, AV_LOG_VERBOSE, "\n");
217
218     av_log(avctx, AV_LOG_VERBOSE,
219            "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
220            print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
221            print_threestate(co2->ExtBRC));
222
223 #if QSV_HAVE_TRELLIS
224     av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
225     if (co2->Trellis & MFX_TRELLIS_OFF) {
226         av_log(avctx, AV_LOG_VERBOSE, "off");
227     } else if (!co2->Trellis) {
228         av_log(avctx, AV_LOG_VERBOSE, "auto");
229     } else {
230         if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE, "I");
231         if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE, "P");
232         if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE, "B");
233     }
234     av_log(avctx, AV_LOG_VERBOSE, "\n");
235 #endif
236
237 #if QSV_VERSION_ATLEAST(1, 8)
238     av_log(avctx, AV_LOG_VERBOSE,
239            "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
240            print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
241     switch (co2->LookAheadDS) {
242     case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");     break;
243     case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");      break;
244     case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");      break;
245     default:                   av_log(avctx, AV_LOG_VERBOSE, "unknown"); break;
246     }
247     av_log(avctx, AV_LOG_VERBOSE, "\n");
248
249     av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
250            print_threestate(co2->AdaptiveI), print_threestate(co2->AdaptiveB));
251     switch (co2->BRefType) {
252     case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");       break;
253     case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
254     default:                av_log(avctx, AV_LOG_VERBOSE, "auto");      break;
255     }
256     av_log(avctx, AV_LOG_VERBOSE, "\n");
257 #endif
258
259 #if QSV_VERSION_ATLEAST(1, 9)
260     av_log(avctx, AV_LOG_VERBOSE,
261            "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
262            co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
263 #endif
264 #endif
265
266     if (avctx->codec_id == AV_CODEC_ID_H264) {
267         av_log(avctx, AV_LOG_VERBOSE, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16"\n",
268                co->CAVLC == MFX_CODINGOPTION_ON ? "CAVLC" : "CABAC", co->MaxDecFrameBuffering);
269         av_log(avctx, AV_LOG_VERBOSE,
270                "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",
271                print_threestate(co->NalHrdConformance), print_threestate(co->SingleSeiNalUnit),
272                print_threestate(co->VuiVclHrdParameters), print_threestate(co->VuiNalHrdParameters));
273     }
274 }
275
276 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
277 {
278     const char *rc_desc;
279     mfxU16      rc_mode;
280
281     int want_la     = q->la_depth >= 10;
282     int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
283     int want_vcm    = q->vcm;
284
285     if (want_la && !QSV_HAVE_LA) {
286         av_log(avctx, AV_LOG_ERROR,
287                "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
288         return AVERROR(ENOSYS);
289     }
290     if (want_vcm && !QSV_HAVE_VCM) {
291         av_log(avctx, AV_LOG_ERROR,
292                "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
293         return AVERROR(ENOSYS);
294     }
295
296     if (want_la + want_qscale + want_vcm > 1) {
297         av_log(avctx, AV_LOG_ERROR,
298                "More than one of: { constant qscale, lookahead, VCM } requested, "
299                "only one of them can be used at a time.\n");
300         return AVERROR(EINVAL);
301     }
302
303     if (!want_qscale && avctx->global_quality > 0 && !QSV_HAVE_ICQ){
304         av_log(avctx, AV_LOG_ERROR,
305                "ICQ ratecontrol mode requested, but is not supported by this SDK version\n");
306         return AVERROR(ENOSYS);
307     }
308
309     if (want_qscale) {
310         rc_mode = MFX_RATECONTROL_CQP;
311         rc_desc = "constant quantization parameter (CQP)";
312     }
313 #if QSV_HAVE_VCM
314     else if (want_vcm) {
315         rc_mode = MFX_RATECONTROL_VCM;
316         rc_desc = "video conferencing mode (VCM)";
317     }
318 #endif
319 #if QSV_HAVE_LA
320     else if (want_la) {
321         rc_mode = MFX_RATECONTROL_LA;
322         rc_desc = "VBR with lookahead (LA)";
323
324 #if QSV_HAVE_ICQ
325         if (avctx->global_quality > 0) {
326             rc_mode = MFX_RATECONTROL_LA_ICQ;
327             rc_desc = "intelligent constant quality with lookahead (LA_ICQ)";
328         }
329 #endif
330     }
331 #endif
332 #if QSV_HAVE_ICQ
333     else if (avctx->global_quality > 0) {
334         rc_mode = MFX_RATECONTROL_ICQ;
335         rc_desc = "intelligent constant quality (ICQ)";
336     }
337 #endif
338     else if (avctx->rc_max_rate == avctx->bit_rate) {
339         rc_mode = MFX_RATECONTROL_CBR;
340         rc_desc = "constant bitrate (CBR)";
341     }
342 #if QSV_HAVE_AVBR
343     else if (!avctx->rc_max_rate) {
344         rc_mode = MFX_RATECONTROL_AVBR;
345         rc_desc = "average variable bitrate (AVBR)";
346     }
347 #endif
348     else {
349         rc_mode = MFX_RATECONTROL_VBR;
350         rc_desc = "variable bitrate (VBR)";
351     }
352
353     q->param.mfx.RateControlMethod = rc_mode;
354     av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", rc_desc);
355
356     return 0;
357 }
358
359 static int rc_supported(QSVEncContext *q)
360 {
361     mfxVideoParam param_out = { .mfx.CodecId = q->param.mfx.CodecId };
362     mfxStatus ret;
363
364     ret = MFXVideoENCODE_Query(q->session, &q->param, &param_out);
365     if (ret < 0 ||
366         param_out.mfx.RateControlMethod != q->param.mfx.RateControlMethod)
367         return 0;
368     return 1;
369 }
370
371 static int init_video_param_jpeg(AVCodecContext *avctx, QSVEncContext *q)
372 {
373     enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ?
374                                    avctx->sw_pix_fmt : avctx->pix_fmt;
375     const AVPixFmtDescriptor *desc;
376     int ret;
377
378     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
379     if (ret < 0)
380         return AVERROR_BUG;
381     q->param.mfx.CodecId = ret;
382
383     if (avctx->level > 0)
384         q->param.mfx.CodecLevel = avctx->level;
385     q->param.mfx.CodecProfile       = q->profile;
386
387     desc = av_pix_fmt_desc_get(sw_format);
388     if (!desc)
389         return AVERROR_BUG;
390
391     ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
392
393     q->param.mfx.FrameInfo.CropX          = 0;
394     q->param.mfx.FrameInfo.CropY          = 0;
395     q->param.mfx.FrameInfo.CropW          = avctx->width;
396     q->param.mfx.FrameInfo.CropH          = avctx->height;
397     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
398     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
399     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
400     q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
401     q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
402     q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
403
404     q->param.mfx.FrameInfo.Width  = FFALIGN(avctx->width, 16);
405     q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 16);
406
407     if (avctx->hw_frames_ctx) {
408         AVHWFramesContext *frames_ctx    = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
409         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
410         q->param.mfx.FrameInfo.Width  = frames_hwctx->surfaces[0].Info.Width;
411         q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height;
412     }
413
414     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
415         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
416         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
417     } else {
418         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
419         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
420     }
421
422     q->param.mfx.Interleaved          = 1;
423     q->param.mfx.Quality              = av_clip(avctx->global_quality, 1, 100);
424     q->param.mfx.RestartInterval      = 0;
425
426     return 0;
427 }
428
429 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
430 {
431     enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ?
432                                    avctx->sw_pix_fmt : avctx->pix_fmt;
433     const AVPixFmtDescriptor *desc;
434     float quant;
435     int ret;
436
437     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
438     if (ret < 0)
439         return AVERROR_BUG;
440     q->param.mfx.CodecId = ret;
441
442     if (avctx->level > 0)
443         q->param.mfx.CodecLevel = avctx->level;
444
445     q->param.mfx.CodecProfile       = q->profile;
446     q->param.mfx.TargetUsage        = q->preset;
447     q->param.mfx.GopPicSize         = FFMAX(0, avctx->gop_size);
448     q->param.mfx.GopRefDist         = FFMAX(-1, avctx->max_b_frames) + 1;
449     q->param.mfx.GopOptFlag         = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
450                                       MFX_GOP_CLOSED : 0;
451     q->param.mfx.IdrInterval        = q->idr_interval;
452     q->param.mfx.NumSlice           = avctx->slices;
453     q->param.mfx.NumRefFrame        = FFMAX(0, avctx->refs);
454     q->param.mfx.EncodedOrder       = 0;
455     q->param.mfx.BufferSizeInKB     = 0;
456
457     desc = av_pix_fmt_desc_get(sw_format);
458     if (!desc)
459         return AVERROR_BUG;
460
461     ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
462
463     q->param.mfx.FrameInfo.CropX          = 0;
464     q->param.mfx.FrameInfo.CropY          = 0;
465     q->param.mfx.FrameInfo.CropW          = avctx->width;
466     q->param.mfx.FrameInfo.CropH          = avctx->height;
467     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
468     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
469     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
470     q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
471     q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
472     q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
473
474     // TODO:  detect version of MFX--if the minor version is greater than
475     // or equal to 19, then can use the same alignment settings as H.264
476     // for HEVC
477     q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
478     q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
479
480     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
481         // it is important that PicStruct be setup correctly from the
482         // start--otherwise, encoding doesn't work and results in a bunch
483         // of incompatible video parameter errors
484         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
485         // height alignment always must be 32 for interlaced video
486         q->height_align = 32;
487     } else {
488         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
489         // for progressive video, the height should be aligned to 16 for
490         // H.264.  For HEVC, depending on the version of MFX, it should be
491         // either 32 or 16.  The lower number is better if possible.
492         q->height_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
493     }
494     q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
495
496     if (avctx->hw_frames_ctx) {
497         AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
498         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
499         q->param.mfx.FrameInfo.Width  = frames_hwctx->surfaces[0].Info.Width;
500         q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height;
501     }
502
503     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
504         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
505         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
506     } else {
507         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
508         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
509     }
510
511     ret = select_rc_mode(avctx, q);
512     if (ret < 0)
513         return ret;
514
515     switch (q->param.mfx.RateControlMethod) {
516     case MFX_RATECONTROL_CBR:
517     case MFX_RATECONTROL_VBR:
518 #if QSV_HAVE_VCM
519     case MFX_RATECONTROL_VCM:
520 #endif
521         q->param.mfx.BufferSizeInKB   = avctx->rc_buffer_size / 8000;
522         q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
523         q->param.mfx.TargetKbps       = avctx->bit_rate / 1000;
524         q->param.mfx.MaxKbps          = avctx->rc_max_rate / 1000;
525         break;
526     case MFX_RATECONTROL_CQP:
527         quant = avctx->global_quality / FF_QP2LAMBDA;
528
529         q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
530         q->param.mfx.QPP = av_clip(quant, 0, 51);
531         q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
532
533         break;
534 #if QSV_HAVE_AVBR
535     case MFX_RATECONTROL_AVBR:
536         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
537         q->param.mfx.Convergence = q->avbr_convergence;
538         q->param.mfx.Accuracy    = q->avbr_accuracy;
539         break;
540 #endif
541 #if QSV_HAVE_LA
542     case MFX_RATECONTROL_LA:
543         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
544         q->extco2.LookAheadDepth = q->la_depth;
545         break;
546 #if QSV_HAVE_ICQ
547     case MFX_RATECONTROL_LA_ICQ:
548         q->extco2.LookAheadDepth = q->la_depth;
549     case MFX_RATECONTROL_ICQ:
550         q->param.mfx.ICQQuality  = avctx->global_quality;
551         break;
552 #endif
553 #endif
554     }
555
556     // the HEVC encoder plugin currently fails if coding options
557     // are provided
558     if (avctx->codec_id != AV_CODEC_ID_HEVC) {
559         q->extco.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION;
560         q->extco.Header.BufferSz      = sizeof(q->extco);
561
562         if (q->rdo >= 0)
563             q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
564
565         if (avctx->codec_id == AV_CODEC_ID_H264) {
566 #if FF_API_CODER_TYPE
567 FF_DISABLE_DEPRECATION_WARNINGS
568             if (avctx->coder_type >= 0)
569                 q->cavlc = avctx->coder_type == FF_CODER_TYPE_VLC;
570 FF_ENABLE_DEPRECATION_WARNINGS
571 #endif
572             q->extco.CAVLC = q->cavlc ? MFX_CODINGOPTION_ON
573                                       : MFX_CODINGOPTION_UNKNOWN;
574
575             if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL)
576                 q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ?
577                                              MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
578
579             if (q->single_sei_nal_unit >= 0)
580                 q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
581             if (q->recovery_point_sei >= 0)
582                 q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
583             q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering;
584         }
585
586         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco;
587
588 #if QSV_HAVE_CO2
589         if (avctx->codec_id == AV_CODEC_ID_H264) {
590             q->extco2.Header.BufferId     = MFX_EXTBUFF_CODING_OPTION2;
591             q->extco2.Header.BufferSz     = sizeof(q->extco2);
592
593             if (q->int_ref_type >= 0)
594                 q->extco2.IntRefType = q->int_ref_type;
595             if (q->int_ref_cycle_size >= 0)
596                 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
597             if (q->int_ref_qp_delta != INT16_MIN)
598                 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
599
600             if (q->bitrate_limit >= 0)
601                 q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
602             if (q->mbbrc >= 0)
603                 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
604             if (q->extbrc >= 0)
605                 q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
606
607             if (q->max_frame_size >= 0)
608                 q->extco2.MaxFrameSize = q->max_frame_size;
609 #if QSV_HAVE_MAX_SLICE_SIZE
610             if (q->max_slice_size >= 0)
611                 q->extco2.MaxSliceSize = q->max_slice_size;
612 #endif
613
614 #if QSV_HAVE_TRELLIS
615             q->extco2.Trellis = q->trellis;
616 #endif
617
618 #if QSV_HAVE_LA_DS
619             q->extco2.LookAheadDS = q->la_ds;
620 #endif
621
622 #if QSV_HAVE_BREF_TYPE
623 #if FF_API_PRIVATE_OPT
624 FF_DISABLE_DEPRECATION_WARNINGS
625             if (avctx->b_frame_strategy >= 0)
626                 q->b_strategy = avctx->b_frame_strategy;
627 FF_ENABLE_DEPRECATION_WARNINGS
628 #endif
629             if (q->b_strategy >= 0)
630                 q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
631             if (q->adaptive_i >= 0)
632                 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
633             if (q->adaptive_b >= 0)
634                 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
635 #endif
636
637             q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
638         }
639 #endif
640     }
641
642     if (!rc_supported(q)) {
643         av_log(avctx, AV_LOG_ERROR,
644                "Selected ratecontrol mode is not supported by the QSV "
645                "runtime. Choose a different mode.\n");
646         return AVERROR(ENOSYS);
647     }
648
649     return 0;
650 }
651
652 static int qsv_retrieve_enc_jpeg_params(AVCodecContext *avctx, QSVEncContext *q)
653 {
654     int ret = 0;
655
656     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
657     if (ret < 0)
658         return ff_qsv_print_error(avctx, ret,
659                                   "Error calling GetVideoParam");
660
661     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
662
663     // for qsv mjpeg the return value maybe 0 so alloc the buffer
664     if (q->packet_size == 0)
665         q->packet_size = q->param.mfx.FrameInfo.Height * q->param.mfx.FrameInfo.Width * 4;
666
667     return 0;
668 }
669
670 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
671 {
672     AVCPBProperties *cpb_props;
673
674     uint8_t sps_buf[128];
675     uint8_t pps_buf[128];
676
677     mfxExtCodingOptionSPSPPS extradata = {
678         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
679         .Header.BufferSz = sizeof(extradata),
680         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
681         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
682     };
683
684     mfxExtCodingOption co = {
685         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
686         .Header.BufferSz = sizeof(co),
687     };
688 #if QSV_HAVE_CO2
689     mfxExtCodingOption2 co2 = {
690         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
691         .Header.BufferSz = sizeof(co2),
692     };
693 #endif
694 #if QSV_HAVE_CO3
695     mfxExtCodingOption3 co3 = {
696         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
697         .Header.BufferSz = sizeof(co3),
698     };
699 #endif
700
701     mfxExtBuffer *ext_buffers[] = {
702         (mfxExtBuffer*)&extradata,
703         (mfxExtBuffer*)&co,
704 #if QSV_HAVE_CO2
705         (mfxExtBuffer*)&co2,
706 #endif
707 #if QSV_HAVE_CO3
708         (mfxExtBuffer*)&co3,
709 #endif
710     };
711
712     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
713     int ret;
714
715     q->param.ExtParam    = ext_buffers;
716     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
717
718     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
719     if (ret < 0)
720         return ff_qsv_print_error(avctx, ret,
721                                   "Error calling GetVideoParam");
722
723     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
724
725     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
726         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
727         return AVERROR_UNKNOWN;
728     }
729
730     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
731                                  AV_INPUT_BUFFER_PADDING_SIZE);
732     if (!avctx->extradata)
733         return AVERROR(ENOMEM);
734
735     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
736     if (need_pps)
737         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
738     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
739     memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
740
741     cpb_props = ff_add_cpb_side_data(avctx);
742     if (!cpb_props)
743         return AVERROR(ENOMEM);
744     cpb_props->max_bitrate = avctx->rc_max_rate;
745     cpb_props->min_bitrate = avctx->rc_min_rate;
746     cpb_props->avg_bitrate = avctx->bit_rate;
747     cpb_props->buffer_size = avctx->rc_buffer_size;
748
749     dump_video_param(avctx, q, ext_buffers + 1);
750
751     return 0;
752 }
753
754 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
755 {
756     AVQSVContext *qsv = avctx->hwaccel_context;
757     mfxFrameSurface1 *surfaces;
758     int nb_surfaces, i;
759
760     nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
761
762     q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
763     if (!q->opaque_alloc_buf)
764         return AVERROR(ENOMEM);
765
766     q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
767     if (!q->opaque_surfaces)
768         return AVERROR(ENOMEM);
769
770     surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
771     for (i = 0; i < nb_surfaces; i++) {
772         surfaces[i].Info      = q->req.Info;
773         q->opaque_surfaces[i] = surfaces + i;
774     }
775
776     q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
777     q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
778     q->opaque_alloc.In.Surfaces     = q->opaque_surfaces;
779     q->opaque_alloc.In.NumSurface   = nb_surfaces;
780     q->opaque_alloc.In.Type         = q->req.Type;
781
782     q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
783
784     qsv->nb_opaque_surfaces = nb_surfaces;
785     qsv->opaque_surfaces    = q->opaque_alloc_buf;
786     qsv->opaque_alloc_type  = q->req.Type;
787
788     return 0;
789 }
790
791 static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
792 {
793     int ret;
794
795     if (avctx->hwaccel_context) {
796         AVQSVContext *qsv = avctx->hwaccel_context;
797         q->session = qsv->session;
798     } else if (avctx->hw_frames_ctx) {
799         q->frames_ctx.hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
800         if (!q->frames_ctx.hw_frames_ctx)
801             return AVERROR(ENOMEM);
802
803         ret = ff_qsv_init_session_frames(avctx, &q->internal_session,
804                                          &q->frames_ctx, q->load_plugins,
805                                          q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY);
806         if (ret < 0) {
807             av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
808             return ret;
809         }
810
811         q->session = q->internal_session;
812     } else if (avctx->hw_device_ctx) {
813         ret = ff_qsv_init_session_device(avctx, &q->internal_session,
814                                          avctx->hw_device_ctx, q->load_plugins);
815         if (ret < 0)
816             return ret;
817
818         q->session = q->internal_session;
819     } else {
820         ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
821                                            q->load_plugins);
822         if (ret < 0)
823             return ret;
824
825         q->session = q->internal_session;
826     }
827
828     return 0;
829 }
830
831 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
832 {
833     int iopattern = 0;
834     int opaque_alloc = 0;
835     int ret;
836
837     q->param.AsyncDepth = q->async_depth;
838
839     q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
840                                   (sizeof(AVPacket) + sizeof(mfxSyncPoint*) + sizeof(mfxBitstream*)));
841     if (!q->async_fifo)
842         return AVERROR(ENOMEM);
843
844     if (avctx->hwaccel_context) {
845         AVQSVContext *qsv = avctx->hwaccel_context;
846
847         iopattern    = qsv->iopattern;
848         opaque_alloc = qsv->opaque_alloc;
849     }
850
851     if (avctx->hw_frames_ctx) {
852         AVHWFramesContext    *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
853         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
854
855         if (!iopattern) {
856             if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
857                 iopattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;
858             else if (frames_hwctx->frame_type &
859                      (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))
860                 iopattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
861         }
862     }
863
864     if (!iopattern)
865         iopattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
866     q->param.IOPattern = iopattern;
867
868     ret = qsvenc_init_session(avctx, q);
869     if (ret < 0)
870         return ret;
871
872     // in the mfxInfoMFX struct, JPEG is different from other codecs
873     switch (avctx->codec_id) {
874     case AV_CODEC_ID_MJPEG:
875         ret = init_video_param_jpeg(avctx, q);
876         break;
877     default:
878         ret = init_video_param(avctx, q);
879         break;
880     }
881     if (ret < 0)
882         return ret;
883
884     ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
885     if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
886         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
887     } else if (ret < 0) {
888         return ff_qsv_print_error(avctx, ret,
889                                   "Error querying encoder params");
890     }
891
892     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
893     if (ret < 0)
894         return ff_qsv_print_error(avctx, ret,
895                                   "Error querying (IOSurf) the encoding parameters");
896
897     if (opaque_alloc) {
898         ret = qsv_init_opaque_alloc(avctx, q);
899         if (ret < 0)
900             return ret;
901     }
902
903     if (avctx->hwaccel_context) {
904         AVQSVContext *qsv = avctx->hwaccel_context;
905         int i, j;
906
907         q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
908                                        sizeof(*q->extparam));
909         if (!q->extparam)
910             return AVERROR(ENOMEM);
911
912         q->param.ExtParam = q->extparam;
913         for (i = 0; i < qsv->nb_ext_buffers; i++)
914             q->param.ExtParam[i] = qsv->ext_buffers[i];
915         q->param.NumExtParam = qsv->nb_ext_buffers;
916
917         for (i = 0; i < q->nb_extparam_internal; i++) {
918             for (j = 0; j < qsv->nb_ext_buffers; j++) {
919                 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
920                     break;
921             }
922             if (j < qsv->nb_ext_buffers)
923                 continue;
924
925             q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
926         }
927     } else {
928         q->param.ExtParam    = q->extparam_internal;
929         q->param.NumExtParam = q->nb_extparam_internal;
930     }
931
932     ret = MFXVideoENCODE_Init(q->session, &q->param);
933     if (ret < 0)
934         return ff_qsv_print_error(avctx, ret,
935                                   "Error initializing the encoder");
936     else if (ret > 0)
937         ff_qsv_print_warning(avctx, ret,
938                              "Warning in encoder initialization");
939
940     switch (avctx->codec_id) {
941     case AV_CODEC_ID_MJPEG:
942         ret = qsv_retrieve_enc_jpeg_params(avctx, q);
943         break;
944     default:
945         ret = qsv_retrieve_enc_params(avctx, q);
946         break;
947     }
948     if (ret < 0) {
949         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
950         return ret;
951     }
952
953     q->avctx = avctx;
954
955     return 0;
956 }
957
958 static void clear_unused_frames(QSVEncContext *q)
959 {
960     QSVFrame *cur = q->work_frames;
961     while (cur) {
962         if (cur->used && !cur->surface.Data.Locked) {
963             av_frame_unref(cur->frame);
964             cur->used = 0;
965         }
966         cur = cur->next;
967     }
968 }
969
970 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
971 {
972     QSVFrame *frame, **last;
973
974     clear_unused_frames(q);
975
976     frame = q->work_frames;
977     last  = &q->work_frames;
978     while (frame) {
979         if (!frame->used) {
980             *f = frame;
981             frame->used = 1;
982             return 0;
983         }
984
985         last  = &frame->next;
986         frame = frame->next;
987     }
988
989     frame = av_mallocz(sizeof(*frame));
990     if (!frame)
991         return AVERROR(ENOMEM);
992     frame->frame = av_frame_alloc();
993     if (!frame->frame) {
994         av_freep(&frame);
995         return AVERROR(ENOMEM);
996     }
997     *last = frame;
998
999     *f = frame;
1000     frame->used = 1;
1001
1002     return 0;
1003 }
1004
1005 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
1006                         mfxFrameSurface1 **surface)
1007 {
1008     QSVFrame *qf;
1009     int ret;
1010
1011     ret = get_free_frame(q, &qf);
1012     if (ret < 0)
1013         return ret;
1014
1015     if (frame->format == AV_PIX_FMT_QSV) {
1016         ret = av_frame_ref(qf->frame, frame);
1017         if (ret < 0)
1018             return ret;
1019
1020         qf->surface = *(mfxFrameSurface1*)qf->frame->data[3];
1021
1022         if (q->frames_ctx.mids) {
1023             ret = ff_qsv_find_surface_idx(&q->frames_ctx, qf);
1024             if (ret < 0)
1025                 return ret;
1026
1027             qf->surface.Data.MemId = &q->frames_ctx.mids[ret];
1028         }
1029     } else {
1030         /* make a copy if the input is not padded as libmfx requires */
1031         if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) {
1032             qf->frame->height = FFALIGN(frame->height, q->height_align);
1033             qf->frame->width  = FFALIGN(frame->width, q->width_align);
1034
1035             ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
1036             if (ret < 0)
1037                 return ret;
1038
1039             qf->frame->height = frame->height;
1040             qf->frame->width  = frame->width;
1041             ret = av_frame_copy(qf->frame, frame);
1042             if (ret < 0) {
1043                 av_frame_unref(qf->frame);
1044                 return ret;
1045             }
1046         } else {
1047             ret = av_frame_ref(qf->frame, frame);
1048             if (ret < 0)
1049                 return ret;
1050         }
1051
1052         qf->surface.Info = q->param.mfx.FrameInfo;
1053
1054         qf->surface.Info.PicStruct =
1055             !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
1056             frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
1057                                        MFX_PICSTRUCT_FIELD_BFF;
1058         if (frame->repeat_pict == 1)
1059             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
1060         else if (frame->repeat_pict == 2)
1061             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
1062         else if (frame->repeat_pict == 4)
1063             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
1064
1065         qf->surface.Data.PitchLow  = qf->frame->linesize[0];
1066         qf->surface.Data.Y         = qf->frame->data[0];
1067         qf->surface.Data.UV        = qf->frame->data[1];
1068     }
1069
1070     qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
1071
1072     *surface = &qf->surface;
1073
1074     return 0;
1075 }
1076
1077 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
1078 {
1079     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
1080         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
1081             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
1082             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
1083             av_log(avctx, AV_LOG_WARNING,
1084                    "Interlaced coding is supported"
1085                    " at Main/High Profile Level 2.1-4.1\n");
1086     }
1087 }
1088
1089 static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
1090                         const AVFrame *frame)
1091 {
1092     AVPacket new_pkt = { 0 };
1093     mfxBitstream *bs;
1094
1095     mfxFrameSurface1 *surf = NULL;
1096     mfxSyncPoint *sync     = NULL;
1097     int ret;
1098
1099     if (frame) {
1100         ret = submit_frame(q, frame, &surf);
1101         if (ret < 0) {
1102             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
1103             return ret;
1104         }
1105     }
1106
1107     ret = av_new_packet(&new_pkt, q->packet_size);
1108     if (ret < 0) {
1109         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
1110         return ret;
1111     }
1112
1113     bs = av_mallocz(sizeof(*bs));
1114     if (!bs) {
1115         av_packet_unref(&new_pkt);
1116         return AVERROR(ENOMEM);
1117     }
1118     bs->Data      = new_pkt.data;
1119     bs->MaxLength = new_pkt.size;
1120
1121     sync = av_mallocz(sizeof(*sync));
1122     if (!sync) {
1123         av_freep(&bs);
1124         av_packet_unref(&new_pkt);
1125         return AVERROR(ENOMEM);
1126     }
1127
1128     do {
1129         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, sync);
1130         if (ret == MFX_WRN_DEVICE_BUSY)
1131             av_usleep(1);
1132     } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION);
1133
1134     if (ret > 0)
1135         ff_qsv_print_warning(avctx, ret, "Warning during encoding");
1136
1137     if (ret < 0) {
1138         av_packet_unref(&new_pkt);
1139         av_freep(&bs);
1140         av_freep(&sync);
1141         return (ret == MFX_ERR_MORE_DATA) ?
1142                0 : ff_qsv_print_error(avctx, ret, "Error during encoding");
1143     }
1144
1145     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
1146         print_interlace_msg(avctx, q);
1147
1148     if (*sync) {
1149         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1150         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
1151         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
1152     } else {
1153         av_freep(&sync);
1154         av_packet_unref(&new_pkt);
1155         av_freep(&bs);
1156     }
1157
1158     return 0;
1159 }
1160
1161 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
1162                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
1163 {
1164     int ret;
1165
1166     ret = encode_frame(avctx, q, frame);
1167     if (ret < 0)
1168         return ret;
1169
1170     if (!av_fifo_space(q->async_fifo) ||
1171         (!frame && av_fifo_size(q->async_fifo))) {
1172         AVPacket new_pkt;
1173         mfxBitstream *bs;
1174         mfxSyncPoint *sync;
1175
1176         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1177         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
1178         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
1179
1180         do {
1181             ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
1182         } while (ret == MFX_WRN_IN_EXECUTION);
1183
1184         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
1185         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
1186         new_pkt.size = bs->DataLength;
1187
1188         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
1189             bs->FrameType & MFX_FRAMETYPE_xIDR)
1190             new_pkt.flags |= AV_PKT_FLAG_KEY;
1191
1192 #if FF_API_CODED_FRAME
1193 FF_DISABLE_DEPRECATION_WARNINGS
1194         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
1195             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1196         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
1197             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
1198         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
1199             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1200 FF_ENABLE_DEPRECATION_WARNINGS
1201 #endif
1202
1203         av_freep(&bs);
1204         av_freep(&sync);
1205
1206         if (pkt->data) {
1207             if (pkt->size < new_pkt.size) {
1208                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1209                        pkt->size, new_pkt.size);
1210                 av_packet_unref(&new_pkt);
1211                 return AVERROR(EINVAL);
1212             }
1213
1214             memcpy(pkt->data, new_pkt.data, new_pkt.size);
1215             pkt->size = new_pkt.size;
1216
1217             ret = av_packet_copy_props(pkt, &new_pkt);
1218             av_packet_unref(&new_pkt);
1219             if (ret < 0)
1220                 return ret;
1221         } else
1222             *pkt = new_pkt;
1223
1224         *got_packet = 1;
1225     }
1226
1227     return 0;
1228 }
1229
1230 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1231 {
1232     QSVFrame *cur;
1233
1234     if (q->session)
1235         MFXVideoENCODE_Close(q->session);
1236     if (q->internal_session)
1237         MFXClose(q->internal_session);
1238     q->session          = NULL;
1239     q->internal_session = NULL;
1240
1241     av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
1242     av_buffer_unref(&q->frames_ctx.mids_buf);
1243
1244     cur = q->work_frames;
1245     while (cur) {
1246         q->work_frames = cur->next;
1247         av_frame_free(&cur->frame);
1248         av_freep(&cur);
1249         cur = q->work_frames;
1250     }
1251
1252     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1253         AVPacket pkt;
1254         mfxSyncPoint *sync;
1255         mfxBitstream *bs;
1256
1257         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
1258         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1259         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
1260
1261         av_freep(&sync);
1262         av_freep(&bs);
1263         av_packet_unref(&pkt);
1264     }
1265     av_fifo_free(q->async_fifo);
1266     q->async_fifo = NULL;
1267
1268     av_freep(&q->opaque_surfaces);
1269     av_buffer_unref(&q->opaque_alloc_buf);
1270
1271     av_freep(&q->extparam);
1272
1273     return 0;
1274 }