]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
qsvenc: Fix a misleading log message
[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 && QSV_HAVE_QVBR
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 check_enc_param(AVCodecContext *avctx, QSVEncContext *q)
360 {
361     mfxVideoParam param_out = { .mfx.CodecId = q->param.mfx.CodecId };
362     mfxStatus ret;
363
364 #define UNMATCH(x) (param_out.mfx.x != q->param.mfx.x)
365
366     ret = MFXVideoENCODE_Query(q->session, &q->param, &param_out);
367
368     if (ret < 0) {
369         if (UNMATCH(CodecId))
370             av_log(avctx, AV_LOG_ERROR, "Current codec type is unsupported\n");
371         if (UNMATCH(CodecProfile))
372             av_log(avctx, AV_LOG_ERROR, "Current profile is unsupported\n");
373         if (UNMATCH(RateControlMethod))
374             av_log(avctx, AV_LOG_ERROR, "Selected ratecontrol mode is unsupported\n");
375         if (UNMATCH(LowPower))
376               av_log(avctx, AV_LOG_ERROR, "Low power mode is unsupported\n");
377         if (UNMATCH(FrameInfo.FrameRateExtN) || UNMATCH(FrameInfo.FrameRateExtD))
378               av_log(avctx, AV_LOG_ERROR, "Current frame rate is unsupported\n");
379         if (UNMATCH(FrameInfo.PicStruct))
380               av_log(avctx, AV_LOG_ERROR, "Current picture structure is unsupported\n");
381         if (UNMATCH(FrameInfo.Width) || UNMATCH(FrameInfo.Height))
382               av_log(avctx, AV_LOG_ERROR, "Current resolution is unsupported\n");
383         if (UNMATCH(FrameInfo.FourCC))
384               av_log(avctx, AV_LOG_ERROR, "Current pixel format is unsupported\n");
385         return 0;
386     }
387     return 1;
388 }
389
390 static int init_video_param_jpeg(AVCodecContext *avctx, QSVEncContext *q)
391 {
392     enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ?
393                                    avctx->sw_pix_fmt : avctx->pix_fmt;
394     const AVPixFmtDescriptor *desc;
395     int ret;
396
397     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
398     if (ret < 0)
399         return AVERROR_BUG;
400     q->param.mfx.CodecId = ret;
401
402     if (avctx->level > 0)
403         q->param.mfx.CodecLevel = avctx->level;
404     q->param.mfx.CodecProfile       = q->profile;
405
406     desc = av_pix_fmt_desc_get(sw_format);
407     if (!desc)
408         return AVERROR_BUG;
409
410     ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
411
412     q->param.mfx.FrameInfo.CropX          = 0;
413     q->param.mfx.FrameInfo.CropY          = 0;
414     q->param.mfx.FrameInfo.CropW          = avctx->width;
415     q->param.mfx.FrameInfo.CropH          = avctx->height;
416     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
417     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
418     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
419     q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
420     q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
421     q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
422
423     q->param.mfx.FrameInfo.Width  = FFALIGN(avctx->width, 16);
424     q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 16);
425
426     if (avctx->hw_frames_ctx) {
427         AVHWFramesContext *frames_ctx    = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
428         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
429         q->param.mfx.FrameInfo.Width  = frames_hwctx->surfaces[0].Info.Width;
430         q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height;
431     }
432
433     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
434         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
435         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
436     } else {
437         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
438         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
439     }
440
441     q->param.mfx.Interleaved          = 1;
442     q->param.mfx.Quality              = av_clip(avctx->global_quality, 1, 100);
443     q->param.mfx.RestartInterval      = 0;
444
445     return 0;
446 }
447
448 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
449 {
450     enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ?
451                                    avctx->sw_pix_fmt : avctx->pix_fmt;
452     const AVPixFmtDescriptor *desc;
453     float quant;
454     int ret;
455
456     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
457     if (ret < 0)
458         return AVERROR_BUG;
459     q->param.mfx.CodecId = ret;
460
461     if (avctx->level > 0)
462         q->param.mfx.CodecLevel = avctx->level;
463
464     if (avctx->compression_level == FF_COMPRESSION_DEFAULT) {
465         avctx->compression_level = q->preset;
466     } else if (avctx->compression_level >= 0) {
467         if (avctx->compression_level > MFX_TARGETUSAGE_BEST_SPEED) {
468             av_log(avctx, AV_LOG_WARNING, "Invalid compression level: "
469                     "valid range is 0-%d, using %d instead\n",
470                     MFX_TARGETUSAGE_BEST_SPEED, MFX_TARGETUSAGE_BEST_SPEED);
471             avctx->compression_level = MFX_TARGETUSAGE_BEST_SPEED;
472         }
473     }
474
475     q->param.mfx.CodecProfile       = q->profile;
476     q->param.mfx.TargetUsage        = avctx->compression_level;
477     q->param.mfx.GopPicSize         = FFMAX(0, avctx->gop_size);
478     q->param.mfx.GopRefDist         = FFMAX(-1, avctx->max_b_frames) + 1;
479     q->param.mfx.GopOptFlag         = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
480                                       MFX_GOP_CLOSED : 0;
481     q->param.mfx.IdrInterval        = q->idr_interval;
482     q->param.mfx.NumSlice           = avctx->slices;
483     q->param.mfx.NumRefFrame        = FFMAX(0, avctx->refs);
484     q->param.mfx.EncodedOrder       = 0;
485     q->param.mfx.BufferSizeInKB     = 0;
486
487     desc = av_pix_fmt_desc_get(sw_format);
488     if (!desc)
489         return AVERROR_BUG;
490
491     ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
492
493     q->param.mfx.FrameInfo.CropX          = 0;
494     q->param.mfx.FrameInfo.CropY          = 0;
495     q->param.mfx.FrameInfo.CropW          = avctx->width;
496     q->param.mfx.FrameInfo.CropH          = avctx->height;
497     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
498     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
499     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
500     q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
501     q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
502     q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
503
504     // TODO:  detect version of MFX--if the minor version is greater than
505     // or equal to 19, then can use the same alignment settings as H.264
506     // for HEVC
507     q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
508     q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
509
510     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
511         // it is important that PicStruct be setup correctly from the
512         // start--otherwise, encoding doesn't work and results in a bunch
513         // of incompatible video parameter errors
514         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
515         // height alignment always must be 32 for interlaced video
516         q->height_align = 32;
517     } else {
518         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
519         // for progressive video, the height should be aligned to 16 for
520         // H.264.  For HEVC, depending on the version of MFX, it should be
521         // either 32 or 16.  The lower number is better if possible.
522         q->height_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
523     }
524     q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
525
526     if (avctx->hw_frames_ctx) {
527         AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
528         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
529         q->param.mfx.FrameInfo.Width  = frames_hwctx->surfaces[0].Info.Width;
530         q->param.mfx.FrameInfo.Height = frames_hwctx->surfaces[0].Info.Height;
531     }
532
533     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
534         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
535         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
536     } else {
537         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
538         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
539     }
540
541     ret = select_rc_mode(avctx, q);
542     if (ret < 0)
543         return ret;
544
545     switch (q->param.mfx.RateControlMethod) {
546     case MFX_RATECONTROL_CBR:
547     case MFX_RATECONTROL_VBR:
548 #if QSV_HAVE_VCM
549     case MFX_RATECONTROL_VCM:
550 #endif
551         q->param.mfx.BufferSizeInKB   = avctx->rc_buffer_size / 8000;
552         q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
553         q->param.mfx.TargetKbps       = avctx->bit_rate / 1000;
554         q->param.mfx.MaxKbps          = avctx->rc_max_rate / 1000;
555         break;
556     case MFX_RATECONTROL_CQP:
557         quant = avctx->global_quality / FF_QP2LAMBDA;
558
559         q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
560         q->param.mfx.QPP = av_clip(quant, 0, 51);
561         q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
562
563         break;
564 #if QSV_HAVE_AVBR
565     case MFX_RATECONTROL_AVBR:
566         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
567         q->param.mfx.Convergence = q->avbr_convergence;
568         q->param.mfx.Accuracy    = q->avbr_accuracy;
569         break;
570 #endif
571 #if QSV_HAVE_LA
572     case MFX_RATECONTROL_LA:
573         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
574         q->extco2.LookAheadDepth = q->la_depth;
575         break;
576 #if QSV_HAVE_ICQ
577     case MFX_RATECONTROL_LA_ICQ:
578         q->extco2.LookAheadDepth = q->la_depth;
579     case MFX_RATECONTROL_ICQ:
580         q->param.mfx.ICQQuality  = avctx->global_quality;
581         break;
582 #endif
583 #endif
584     }
585
586     // the HEVC encoder plugin currently fails if coding options
587     // are provided
588     if (avctx->codec_id != AV_CODEC_ID_HEVC) {
589         q->extco.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION;
590         q->extco.Header.BufferSz      = sizeof(q->extco);
591
592         if (q->rdo >= 0)
593             q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
594
595         if (avctx->codec_id == AV_CODEC_ID_H264) {
596 #if FF_API_CODER_TYPE
597 FF_DISABLE_DEPRECATION_WARNINGS
598             if (avctx->coder_type >= 0)
599                 q->cavlc = avctx->coder_type == FF_CODER_TYPE_VLC;
600 FF_ENABLE_DEPRECATION_WARNINGS
601 #endif
602             q->extco.CAVLC = q->cavlc ? MFX_CODINGOPTION_ON
603                                       : MFX_CODINGOPTION_UNKNOWN;
604
605             if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL)
606                 q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ?
607                                              MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
608
609             if (q->single_sei_nal_unit >= 0)
610                 q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
611             if (q->recovery_point_sei >= 0)
612                 q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
613             q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering;
614             q->extco.AUDelimiter          = q->aud ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
615         }
616
617         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco;
618
619 #if QSV_HAVE_CO2
620         if (avctx->codec_id == AV_CODEC_ID_H264) {
621             q->extco2.Header.BufferId     = MFX_EXTBUFF_CODING_OPTION2;
622             q->extco2.Header.BufferSz     = sizeof(q->extco2);
623
624             if (q->int_ref_type >= 0)
625                 q->extco2.IntRefType = q->int_ref_type;
626             if (q->int_ref_cycle_size >= 0)
627                 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
628             if (q->int_ref_qp_delta != INT16_MIN)
629                 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
630
631             if (q->bitrate_limit >= 0)
632                 q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
633             if (q->mbbrc >= 0)
634                 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
635             if (q->extbrc >= 0)
636                 q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
637
638             if (q->max_frame_size >= 0)
639                 q->extco2.MaxFrameSize = q->max_frame_size;
640 #if QSV_HAVE_MAX_SLICE_SIZE
641             if (q->max_slice_size >= 0)
642                 q->extco2.MaxSliceSize = q->max_slice_size;
643 #endif
644
645 #if QSV_HAVE_TRELLIS
646             q->extco2.Trellis = q->trellis;
647 #endif
648
649 #if QSV_HAVE_LA_DS
650             q->extco2.LookAheadDS = q->la_ds;
651 #endif
652
653 #if QSV_HAVE_BREF_TYPE
654 #if FF_API_PRIVATE_OPT
655 FF_DISABLE_DEPRECATION_WARNINGS
656             if (avctx->b_frame_strategy >= 0)
657                 q->b_strategy = avctx->b_frame_strategy;
658 FF_ENABLE_DEPRECATION_WARNINGS
659 #endif
660             if (q->b_strategy >= 0)
661                 q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
662             if (q->adaptive_i >= 0)
663                 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
664             if (q->adaptive_b >= 0)
665                 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
666 #endif
667
668             q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
669         }
670 #endif
671 #if QSV_HAVE_MF
672         if (avctx->codec_id == AV_CODEC_ID_H264) {
673             mfxVersion    ver;
674             ret = MFXQueryVersion(q->session,&ver);
675             if (ret >= MFX_ERR_NONE && QSV_RUNTIME_VERSION_ATLEAST(ver, 1, 25)) {
676                 q->extmfp.Header.BufferId     = MFX_EXTBUFF_MULTI_FRAME_PARAM;
677                 q->extmfp.Header.BufferSz     = sizeof(q->extmfp);
678
679                 q->extmfp.MFMode = q->mfmode;
680                 av_log(avctx,AV_LOG_VERBOSE,"MFMode:%d\n", q->extmfp.MFMode);
681                 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extmfp;
682             }
683         }
684 #endif
685     }
686
687     if (!check_enc_param(avctx,q)) {
688         av_log(avctx, AV_LOG_ERROR,
689                "some encoding parameters are not supported by the QSV "
690                "runtime. Please double check the input parameters.\n");
691         return AVERROR(ENOSYS);
692     }
693
694     return 0;
695 }
696
697 static int qsv_retrieve_enc_jpeg_params(AVCodecContext *avctx, QSVEncContext *q)
698 {
699     int ret = 0;
700
701     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
702     if (ret < 0)
703         return ff_qsv_print_error(avctx, ret,
704                                   "Error calling GetVideoParam");
705
706     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
707
708     // for qsv mjpeg the return value maybe 0 so alloc the buffer
709     if (q->packet_size == 0)
710         q->packet_size = q->param.mfx.FrameInfo.Height * q->param.mfx.FrameInfo.Width * 4;
711
712     return 0;
713 }
714
715 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
716 {
717     AVCPBProperties *cpb_props;
718
719     uint8_t sps_buf[128];
720     uint8_t pps_buf[128];
721
722     mfxExtCodingOptionSPSPPS extradata = {
723         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
724         .Header.BufferSz = sizeof(extradata),
725         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
726         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
727     };
728
729     mfxExtCodingOption co = {
730         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
731         .Header.BufferSz = sizeof(co),
732     };
733 #if QSV_HAVE_CO2
734     mfxExtCodingOption2 co2 = {
735         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
736         .Header.BufferSz = sizeof(co2),
737     };
738 #endif
739 #if QSV_HAVE_CO3
740     mfxExtCodingOption3 co3 = {
741         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
742         .Header.BufferSz = sizeof(co3),
743     };
744 #endif
745
746     mfxExtBuffer *ext_buffers[] = {
747         (mfxExtBuffer*)&extradata,
748         (mfxExtBuffer*)&co,
749 #if QSV_HAVE_CO2
750         (mfxExtBuffer*)&co2,
751 #endif
752 #if QSV_HAVE_CO3
753         (mfxExtBuffer*)&co3,
754 #endif
755     };
756
757     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
758     int ret;
759
760     q->param.ExtParam    = ext_buffers;
761     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
762
763     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
764     if (ret < 0)
765         return ff_qsv_print_error(avctx, ret,
766                                   "Error calling GetVideoParam");
767
768     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
769
770     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
771         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
772         return AVERROR_UNKNOWN;
773     }
774
775     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
776                                  AV_INPUT_BUFFER_PADDING_SIZE);
777     if (!avctx->extradata)
778         return AVERROR(ENOMEM);
779
780     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
781     if (need_pps)
782         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
783     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
784     memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
785
786     cpb_props = ff_add_cpb_side_data(avctx);
787     if (!cpb_props)
788         return AVERROR(ENOMEM);
789     cpb_props->max_bitrate = avctx->rc_max_rate;
790     cpb_props->min_bitrate = avctx->rc_min_rate;
791     cpb_props->avg_bitrate = avctx->bit_rate;
792     cpb_props->buffer_size = avctx->rc_buffer_size;
793
794     dump_video_param(avctx, q, ext_buffers + 1);
795
796     return 0;
797 }
798
799 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
800 {
801     AVQSVContext *qsv = avctx->hwaccel_context;
802     mfxFrameSurface1 *surfaces;
803     int nb_surfaces, i;
804
805     nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested;
806
807     q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
808     if (!q->opaque_alloc_buf)
809         return AVERROR(ENOMEM);
810
811     q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
812     if (!q->opaque_surfaces)
813         return AVERROR(ENOMEM);
814
815     surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
816     for (i = 0; i < nb_surfaces; i++) {
817         surfaces[i].Info      = q->req.Info;
818         q->opaque_surfaces[i] = surfaces + i;
819     }
820
821     q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
822     q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
823     q->opaque_alloc.In.Surfaces     = q->opaque_surfaces;
824     q->opaque_alloc.In.NumSurface   = nb_surfaces;
825     q->opaque_alloc.In.Type         = q->req.Type;
826
827     q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
828
829     qsv->nb_opaque_surfaces = nb_surfaces;
830     qsv->opaque_surfaces    = q->opaque_alloc_buf;
831     qsv->opaque_alloc_type  = q->req.Type;
832
833     return 0;
834 }
835
836 static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
837 {
838     int ret;
839
840     if (avctx->hwaccel_context) {
841         AVQSVContext *qsv = avctx->hwaccel_context;
842         q->session = qsv->session;
843     } else if (avctx->hw_frames_ctx) {
844         q->frames_ctx.hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx);
845         if (!q->frames_ctx.hw_frames_ctx)
846             return AVERROR(ENOMEM);
847
848         ret = ff_qsv_init_session_frames(avctx, &q->internal_session,
849                                          &q->frames_ctx, q->load_plugins,
850                                          q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY);
851         if (ret < 0) {
852             av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
853             return ret;
854         }
855
856         q->session = q->internal_session;
857     } else if (avctx->hw_device_ctx) {
858         ret = ff_qsv_init_session_device(avctx, &q->internal_session,
859                                          avctx->hw_device_ctx, q->load_plugins);
860         if (ret < 0)
861             return ret;
862
863         q->session = q->internal_session;
864     } else {
865         ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
866                                            q->load_plugins);
867         if (ret < 0)
868             return ret;
869
870         q->session = q->internal_session;
871     }
872
873     return 0;
874 }
875
876 static inline unsigned int qsv_fifo_item_size(void)
877 {
878     return sizeof(AVPacket) + sizeof(mfxSyncPoint*) + sizeof(mfxBitstream*);
879 }
880
881 static inline unsigned int qsv_fifo_size(const AVFifoBuffer* fifo)
882 {
883     return av_fifo_size(fifo)/qsv_fifo_item_size();
884 }
885
886 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
887 {
888     int iopattern = 0;
889     int opaque_alloc = 0;
890     int ret;
891
892     q->param.AsyncDepth = q->async_depth;
893
894     q->async_fifo = av_fifo_alloc(q->async_depth * qsv_fifo_item_size());
895     if (!q->async_fifo)
896         return AVERROR(ENOMEM);
897
898     if (avctx->hwaccel_context) {
899         AVQSVContext *qsv = avctx->hwaccel_context;
900
901         iopattern    = qsv->iopattern;
902         opaque_alloc = qsv->opaque_alloc;
903     }
904
905     if (avctx->hw_frames_ctx) {
906         AVHWFramesContext    *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
907         AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
908
909         if (!iopattern) {
910             if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
911                 iopattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;
912             else if (frames_hwctx->frame_type &
913                      (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))
914                 iopattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
915         }
916     }
917
918     if (!iopattern)
919         iopattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
920     q->param.IOPattern = iopattern;
921
922     ret = qsvenc_init_session(avctx, q);
923     if (ret < 0)
924         return ret;
925
926     // in the mfxInfoMFX struct, JPEG is different from other codecs
927     switch (avctx->codec_id) {
928     case AV_CODEC_ID_MJPEG:
929         ret = init_video_param_jpeg(avctx, q);
930         break;
931     default:
932         ret = init_video_param(avctx, q);
933         break;
934     }
935     if (ret < 0)
936         return ret;
937
938     ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
939     if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
940         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
941     } else if (ret < 0) {
942         return ff_qsv_print_error(avctx, ret,
943                                   "Error querying encoder params");
944     }
945
946     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
947     if (ret < 0)
948         return ff_qsv_print_error(avctx, ret,
949                                   "Error querying (IOSurf) the encoding parameters");
950
951     if (opaque_alloc) {
952         ret = qsv_init_opaque_alloc(avctx, q);
953         if (ret < 0)
954             return ret;
955     }
956
957     if (avctx->hwaccel_context) {
958         AVQSVContext *qsv = avctx->hwaccel_context;
959         int i, j;
960
961         q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
962                                        sizeof(*q->extparam));
963         if (!q->extparam)
964             return AVERROR(ENOMEM);
965
966         q->param.ExtParam = q->extparam;
967         for (i = 0; i < qsv->nb_ext_buffers; i++)
968             q->param.ExtParam[i] = qsv->ext_buffers[i];
969         q->param.NumExtParam = qsv->nb_ext_buffers;
970
971         for (i = 0; i < q->nb_extparam_internal; i++) {
972             for (j = 0; j < qsv->nb_ext_buffers; j++) {
973                 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
974                     break;
975             }
976             if (j < qsv->nb_ext_buffers)
977                 continue;
978
979             q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
980         }
981     } else {
982         q->param.ExtParam    = q->extparam_internal;
983         q->param.NumExtParam = q->nb_extparam_internal;
984     }
985
986     ret = MFXVideoENCODE_Init(q->session, &q->param);
987     if (ret < 0)
988         return ff_qsv_print_error(avctx, ret,
989                                   "Error initializing the encoder");
990     else if (ret > 0)
991         ff_qsv_print_warning(avctx, ret,
992                              "Warning in encoder initialization");
993
994     switch (avctx->codec_id) {
995     case AV_CODEC_ID_MJPEG:
996         ret = qsv_retrieve_enc_jpeg_params(avctx, q);
997         break;
998     default:
999         ret = qsv_retrieve_enc_params(avctx, q);
1000         break;
1001     }
1002     if (ret < 0) {
1003         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
1004         return ret;
1005     }
1006
1007     q->avctx = avctx;
1008
1009     return 0;
1010 }
1011
1012 static void clear_unused_frames(QSVEncContext *q)
1013 {
1014     QSVFrame *cur = q->work_frames;
1015     while (cur) {
1016         if (cur->used && !cur->surface.Data.Locked) {
1017             cur->used = 0;
1018         }
1019         cur = cur->next;
1020     }
1021 }
1022
1023 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
1024 {
1025     QSVFrame *frame, **last;
1026
1027     clear_unused_frames(q);
1028
1029     frame = q->work_frames;
1030     last  = &q->work_frames;
1031     while (frame) {
1032         if (!frame->used) {
1033             *f = frame;
1034             frame->used = 1;
1035             return 0;
1036         }
1037
1038         last  = &frame->next;
1039         frame = frame->next;
1040     }
1041
1042     frame = av_mallocz(sizeof(*frame));
1043     if (!frame)
1044         return AVERROR(ENOMEM);
1045     frame->frame = av_frame_alloc();
1046     if (!frame->frame) {
1047         av_freep(&frame);
1048         return AVERROR(ENOMEM);
1049     }
1050     *last = frame;
1051
1052     *f = frame;
1053     frame->used = 1;
1054
1055     return 0;
1056 }
1057
1058 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
1059                         mfxFrameSurface1 **surface)
1060 {
1061     QSVFrame *qf;
1062     int ret;
1063
1064     ret = get_free_frame(q, &qf);
1065     if (ret < 0)
1066         return ret;
1067
1068     if (frame->format == AV_PIX_FMT_QSV) {
1069         ret = av_frame_ref(qf->frame, frame);
1070         if (ret < 0)
1071             return ret;
1072
1073         qf->surface = *(mfxFrameSurface1*)qf->frame->data[3];
1074
1075         if (q->frames_ctx.mids) {
1076             ret = ff_qsv_find_surface_idx(&q->frames_ctx, qf);
1077             if (ret < 0)
1078                 return ret;
1079
1080             qf->surface.Data.MemId = &q->frames_ctx.mids[ret];
1081         }
1082     } else {
1083         /* make a copy if the input is not padded as libmfx requires */
1084         /* and to make allocation continious for data[0]/data[1] */
1085          if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) ||
1086             (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) {
1087             qf->frame->height = FFALIGN(frame->height, q->height_align);
1088             qf->frame->width  = FFALIGN(frame->width, q->width_align);
1089
1090             qf->frame->format = frame->format;
1091
1092             if (!qf->frame->data[0]) {
1093                 ret = av_frame_get_buffer(qf->frame, q->width_align);
1094                 if (ret < 0)
1095                     return ret;
1096             }
1097
1098             qf->frame->height = frame->height;
1099             qf->frame->width  = frame->width;
1100
1101             ret = av_frame_copy(qf->frame, frame);
1102             if (ret < 0) {
1103                 av_frame_unref(qf->frame);
1104                 return ret;
1105             }
1106         } else {
1107             ret = av_frame_ref(qf->frame, frame);
1108             if (ret < 0)
1109                 return ret;
1110         }
1111
1112         qf->surface.Info = q->param.mfx.FrameInfo;
1113
1114         qf->surface.Info.PicStruct =
1115             !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
1116             frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
1117                                        MFX_PICSTRUCT_FIELD_BFF;
1118         if (frame->repeat_pict == 1)
1119             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
1120         else if (frame->repeat_pict == 2)
1121             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
1122         else if (frame->repeat_pict == 4)
1123             qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
1124
1125         qf->surface.Data.PitchLow  = qf->frame->linesize[0];
1126         qf->surface.Data.Y         = qf->frame->data[0];
1127         qf->surface.Data.UV        = qf->frame->data[1];
1128     }
1129
1130     qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
1131
1132     *surface = &qf->surface;
1133
1134     return 0;
1135 }
1136
1137 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
1138 {
1139     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
1140         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
1141             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
1142             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
1143             av_log(avctx, AV_LOG_WARNING,
1144                    "Interlaced coding is supported"
1145                    " at Main/High Profile Level 2.2-4.0\n");
1146     }
1147 }
1148
1149 static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
1150                         const AVFrame *frame)
1151 {
1152     AVPacket new_pkt = { 0 };
1153     mfxBitstream *bs;
1154
1155     mfxFrameSurface1 *surf = NULL;
1156     mfxSyncPoint *sync     = NULL;
1157     int ret;
1158
1159     if (frame) {
1160         ret = submit_frame(q, frame, &surf);
1161         if (ret < 0) {
1162             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
1163             return ret;
1164         }
1165     }
1166
1167     ret = av_new_packet(&new_pkt, q->packet_size);
1168     if (ret < 0) {
1169         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
1170         return ret;
1171     }
1172
1173     bs = av_mallocz(sizeof(*bs));
1174     if (!bs) {
1175         av_packet_unref(&new_pkt);
1176         return AVERROR(ENOMEM);
1177     }
1178     bs->Data      = new_pkt.data;
1179     bs->MaxLength = new_pkt.size;
1180
1181     sync = av_mallocz(sizeof(*sync));
1182     if (!sync) {
1183         av_freep(&bs);
1184         av_packet_unref(&new_pkt);
1185         return AVERROR(ENOMEM);
1186     }
1187
1188     do {
1189         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, sync);
1190         if (ret == MFX_WRN_DEVICE_BUSY)
1191             av_usleep(1);
1192     } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION);
1193
1194     if (ret > 0)
1195         ff_qsv_print_warning(avctx, ret, "Warning during encoding");
1196
1197     if (ret < 0) {
1198         av_packet_unref(&new_pkt);
1199         av_freep(&bs);
1200         av_freep(&sync);
1201         return (ret == MFX_ERR_MORE_DATA) ?
1202                0 : ff_qsv_print_error(avctx, ret, "Error during encoding");
1203     }
1204
1205     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
1206         print_interlace_msg(avctx, q);
1207
1208     if (*sync) {
1209         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1210         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
1211         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
1212     } else {
1213         av_freep(&sync);
1214         av_packet_unref(&new_pkt);
1215         av_freep(&bs);
1216     }
1217
1218     return 0;
1219 }
1220
1221 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
1222                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
1223 {
1224     int ret;
1225
1226     ret = encode_frame(avctx, q, frame);
1227     if (ret < 0)
1228         return ret;
1229
1230     if ((qsv_fifo_size(q->async_fifo) >= q->async_depth) ||
1231         (!frame && av_fifo_size(q->async_fifo))) {
1232         AVPacket new_pkt;
1233         mfxBitstream *bs;
1234         mfxSyncPoint *sync;
1235
1236         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
1237         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
1238         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
1239
1240         do {
1241             ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
1242         } while (ret == MFX_WRN_IN_EXECUTION);
1243
1244         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
1245         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
1246         new_pkt.size = bs->DataLength;
1247
1248         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
1249             bs->FrameType & MFX_FRAMETYPE_xIDR)
1250             new_pkt.flags |= AV_PKT_FLAG_KEY;
1251
1252 #if FF_API_CODED_FRAME
1253 FF_DISABLE_DEPRECATION_WARNINGS
1254         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
1255             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1256         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
1257             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
1258         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
1259             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1260 FF_ENABLE_DEPRECATION_WARNINGS
1261 #endif
1262
1263         av_freep(&bs);
1264         av_freep(&sync);
1265
1266         if (pkt->data) {
1267             if (pkt->size < new_pkt.size) {
1268                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1269                        pkt->size, new_pkt.size);
1270                 av_packet_unref(&new_pkt);
1271                 return AVERROR(EINVAL);
1272             }
1273
1274             memcpy(pkt->data, new_pkt.data, new_pkt.size);
1275             pkt->size = new_pkt.size;
1276
1277             ret = av_packet_copy_props(pkt, &new_pkt);
1278             av_packet_unref(&new_pkt);
1279             if (ret < 0)
1280                 return ret;
1281         } else
1282             *pkt = new_pkt;
1283
1284         *got_packet = 1;
1285     }
1286
1287     return 0;
1288 }
1289
1290 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1291 {
1292     QSVFrame *cur;
1293
1294     if (q->session)
1295         MFXVideoENCODE_Close(q->session);
1296     if (q->internal_session)
1297         MFXClose(q->internal_session);
1298     q->session          = NULL;
1299     q->internal_session = NULL;
1300
1301     av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
1302     av_buffer_unref(&q->frames_ctx.mids_buf);
1303
1304     cur = q->work_frames;
1305     while (cur) {
1306         q->work_frames = cur->next;
1307         av_frame_free(&cur->frame);
1308         av_freep(&cur);
1309         cur = q->work_frames;
1310     }
1311
1312     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1313         AVPacket pkt;
1314         mfxSyncPoint *sync;
1315         mfxBitstream *bs;
1316
1317         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
1318         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1319         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
1320
1321         av_freep(&sync);
1322         av_freep(&bs);
1323         av_packet_unref(&pkt);
1324     }
1325     av_fifo_free(q->async_fifo);
1326     q->async_fifo = NULL;
1327
1328     av_freep(&q->opaque_surfaces);
1329     av_buffer_unref(&q->opaque_alloc_buf);
1330
1331     av_freep(&q->extparam);
1332
1333     return 0;
1334 }