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