]> git.sesse.net Git - ffmpeg/blob - libavcodec/qsvenc.c
Merge commit '11c9bd633f635f07a762be1ecd672de55daf4edc'
[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     uint8_t sps_buf[128];
547     uint8_t pps_buf[128];
548
549     mfxExtCodingOptionSPSPPS extradata = {
550         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
551         .Header.BufferSz = sizeof(extradata),
552         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
553         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
554     };
555
556     mfxExtCodingOption co = {
557         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
558         .Header.BufferSz = sizeof(co),
559     };
560 #if QSV_HAVE_CO2
561     mfxExtCodingOption2 co2 = {
562         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
563         .Header.BufferSz = sizeof(co2),
564     };
565 #endif
566 #if QSV_HAVE_CO3
567     mfxExtCodingOption3 co3 = {
568         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
569         .Header.BufferSz = sizeof(co3),
570     };
571 #endif
572
573     mfxExtBuffer *ext_buffers[] = {
574         (mfxExtBuffer*)&extradata,
575         (mfxExtBuffer*)&co,
576 #if QSV_HAVE_CO2
577         (mfxExtBuffer*)&co2,
578 #endif
579 #if QSV_HAVE_CO3
580         (mfxExtBuffer*)&co3,
581 #endif
582     };
583
584     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
585     int ret;
586
587     q->param.ExtParam    = ext_buffers;
588     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
589
590     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
591     if (ret < 0)
592         return ff_qsv_error(ret);
593
594     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
595
596     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
597         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
598         return AVERROR_UNKNOWN;
599     }
600
601     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
602                                  AV_INPUT_BUFFER_PADDING_SIZE);
603     if (!avctx->extradata)
604         return AVERROR(ENOMEM);
605
606     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
607     if (need_pps)
608         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
609     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
610     memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
611
612     dump_video_param(avctx, q, ext_buffers + 1);
613
614     return 0;
615 }
616
617 static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
618 {
619     AVQSVContext *qsv = avctx->hwaccel_context;
620     mfxFrameSurface1 *surfaces;
621     int nb_surfaces, i;
622
623     nb_surfaces = qsv->nb_opaque_surfaces + q->req.NumFrameSuggested + q->async_depth;
624
625     q->opaque_alloc_buf = av_buffer_allocz(sizeof(*surfaces) * nb_surfaces);
626     if (!q->opaque_alloc_buf)
627         return AVERROR(ENOMEM);
628
629     q->opaque_surfaces = av_malloc_array(nb_surfaces, sizeof(*q->opaque_surfaces));
630     if (!q->opaque_surfaces)
631         return AVERROR(ENOMEM);
632
633     surfaces = (mfxFrameSurface1*)q->opaque_alloc_buf->data;
634     for (i = 0; i < nb_surfaces; i++) {
635         surfaces[i].Info      = q->req.Info;
636         q->opaque_surfaces[i] = surfaces + i;
637     }
638
639     q->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
640     q->opaque_alloc.Header.BufferSz = sizeof(q->opaque_alloc);
641     q->opaque_alloc.In.Surfaces     = q->opaque_surfaces;
642     q->opaque_alloc.In.NumSurface   = nb_surfaces;
643     q->opaque_alloc.In.Type         = q->req.Type;
644
645     q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->opaque_alloc;
646
647     qsv->nb_opaque_surfaces = nb_surfaces;
648     qsv->opaque_surfaces    = q->opaque_alloc_buf;
649     qsv->opaque_alloc_type  = q->req.Type;
650
651     return 0;
652 }
653
654 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
655 {
656     int opaque_alloc = 0;
657     int ret;
658
659     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
660     q->param.AsyncDepth = q->async_depth;
661
662     q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
663                                   (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
664     if (!q->async_fifo)
665         return AVERROR(ENOMEM);
666
667     if (avctx->hwaccel_context) {
668         AVQSVContext *qsv = avctx->hwaccel_context;
669
670         q->session         = qsv->session;
671         q->param.IOPattern = qsv->iopattern;
672
673         opaque_alloc = qsv->opaque_alloc;
674     }
675
676     if (!q->session) {
677         ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
678                                            q->load_plugins);
679         if (ret < 0)
680             return ret;
681
682         q->session = q->internal_qs.session;
683     }
684
685     ret = init_video_param(avctx, q);
686     if (ret < 0)
687         return ret;
688
689     ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
690     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
691         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
692     } else if (ret < 0) {
693         av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
694         return ff_qsv_error(ret);
695     }
696
697     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
698     if (ret < 0) {
699         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
700         return ff_qsv_error(ret);
701     }
702
703     if (opaque_alloc) {
704         ret = qsv_init_opaque_alloc(avctx, q);
705         if (ret < 0)
706             return ret;
707     }
708
709     if (avctx->hwaccel_context) {
710         AVQSVContext *qsv = avctx->hwaccel_context;
711         int i, j;
712
713         q->extparam = av_mallocz_array(qsv->nb_ext_buffers + q->nb_extparam_internal,
714                                        sizeof(*q->extparam));
715         if (!q->extparam)
716             return AVERROR(ENOMEM);
717
718         q->param.ExtParam = q->extparam;
719         for (i = 0; i < qsv->nb_ext_buffers; i++)
720             q->param.ExtParam[i] = qsv->ext_buffers[i];
721         q->param.NumExtParam = qsv->nb_ext_buffers;
722
723         for (i = 0; i < q->nb_extparam_internal; i++) {
724             for (j = 0; j < qsv->nb_ext_buffers; j++) {
725                 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
726                     break;
727             }
728             if (j < qsv->nb_ext_buffers)
729                 continue;
730
731             q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
732         }
733     } else {
734         q->param.ExtParam    = q->extparam_internal;
735         q->param.NumExtParam = q->nb_extparam_internal;
736     }
737
738     ret = MFXVideoENCODE_Init(q->session, &q->param);
739     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
740         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
741     } else if (ret < 0) {
742         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
743         return ff_qsv_error(ret);
744     }
745
746     ret = qsv_retrieve_enc_params(avctx, q);
747     if (ret < 0) {
748         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
749         return ret;
750     }
751
752     q->avctx = avctx;
753
754     return 0;
755 }
756
757 static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
758 {
759     if (enc_ctrl) {
760         int i;
761         for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
762             mfxPayload* pay = enc_ctrl->Payload[i];
763             av_free(enc_ctrl->Payload[i]->Data);
764             av_free(pay);
765         }
766         enc_ctrl->NumPayload = 0;
767     }
768 }
769
770 static void clear_unused_frames(QSVEncContext *q)
771 {
772     QSVFrame *cur = q->work_frames;
773     while (cur) {
774         if (cur->surface && !cur->surface->Data.Locked) {
775             cur->surface = NULL;
776             free_encoder_ctrl_payloads(&cur->enc_ctrl);
777             av_frame_unref(cur->frame);
778         }
779         cur = cur->next;
780     }
781 }
782
783 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
784 {
785     QSVFrame *frame, **last;
786
787     clear_unused_frames(q);
788
789     frame = q->work_frames;
790     last  = &q->work_frames;
791     while (frame) {
792         if (!frame->surface) {
793             *f = frame;
794             return 0;
795         }
796
797         last  = &frame->next;
798         frame = frame->next;
799     }
800
801     frame = av_mallocz(sizeof(*frame));
802     if (!frame)
803         return AVERROR(ENOMEM);
804     frame->frame = av_frame_alloc();
805     if (!frame->frame) {
806         av_freep(&frame);
807         return AVERROR(ENOMEM);
808     }
809     frame->enc_ctrl.Payload = av_mallocz(sizeof(mfxPayload*) * QSV_MAX_ENC_PAYLOAD);
810     if (!frame->enc_ctrl.Payload) {
811         av_freep(&frame);
812         return AVERROR(ENOMEM);
813     }
814     *last = frame;
815
816     *f = frame;
817
818     return 0;
819 }
820
821 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
822                         QSVFrame **new_frame)
823 {
824     QSVFrame *qf;
825     int ret;
826
827     ret = get_free_frame(q, &qf);
828     if (ret < 0)
829         return ret;
830
831     if (frame->format == AV_PIX_FMT_QSV) {
832         ret = av_frame_ref(qf->frame, frame);
833         if (ret < 0)
834             return ret;
835
836         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
837     } else {
838         /* make a copy if the input is not padded as libmfx requires */
839         if (     frame->height & (q->height_align - 1) ||
840             frame->linesize[0] & (q->width_align - 1)) {
841             qf->frame->height = FFALIGN(frame->height, q->height_align);
842             qf->frame->width  = FFALIGN(frame->width, q->width_align);
843
844             ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
845             if (ret < 0)
846                 return ret;
847
848             qf->frame->height = frame->height;
849             qf->frame->width  = frame->width;
850             ret = av_frame_copy(qf->frame, frame);
851             if (ret < 0) {
852                 av_frame_unref(qf->frame);
853                 return ret;
854             }
855         } else {
856             ret = av_frame_ref(qf->frame, frame);
857             if (ret < 0)
858                 return ret;
859         }
860
861         qf->surface_internal.Info = q->param.mfx.FrameInfo;
862
863         qf->surface_internal.Info.PicStruct =
864             !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
865             frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
866                                        MFX_PICSTRUCT_FIELD_BFF;
867         if (frame->repeat_pict == 1)
868             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
869         else if (frame->repeat_pict == 2)
870             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
871         else if (frame->repeat_pict == 4)
872             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
873
874         qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
875         qf->surface_internal.Data.Y         = qf->frame->data[0];
876         qf->surface_internal.Data.UV        = qf->frame->data[1];
877
878         qf->surface = &qf->surface_internal;
879     }
880
881     qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
882
883     *new_frame = qf;
884
885     return 0;
886 }
887
888 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
889 {
890     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
891         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
892             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
893             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
894             av_log(avctx, AV_LOG_WARNING,
895                    "Interlaced coding is supported"
896                    " at Main/High Profile Level 2.1-4.1\n");
897     }
898 }
899
900 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
901                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
902 {
903     AVPacket new_pkt = { 0 };
904     mfxBitstream *bs;
905
906     mfxFrameSurface1 *surf = NULL;
907     mfxSyncPoint sync      = NULL;
908     QSVFrame *qsv_frame = NULL;
909     mfxEncodeCtrl* enc_ctrl = NULL;
910     int ret;
911
912     if (frame) {
913         ret = submit_frame(q, frame, &qsv_frame);
914         if (ret < 0) {
915             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
916             return ret;
917         }
918     }
919     if (qsv_frame) {
920         surf = qsv_frame->surface;
921         enc_ctrl = &qsv_frame->enc_ctrl;
922     }
923
924     ret = av_new_packet(&new_pkt, q->packet_size);
925     if (ret < 0) {
926         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
927         return ret;
928     }
929
930     bs = av_mallocz(sizeof(*bs));
931     if (!bs) {
932         av_packet_unref(&new_pkt);
933         return AVERROR(ENOMEM);
934     }
935     bs->Data      = new_pkt.data;
936     bs->MaxLength = new_pkt.size;
937
938     if (q->set_encode_ctrl_cb) {
939         q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
940     }
941
942     do {
943         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, &sync);
944         if (ret == MFX_WRN_DEVICE_BUSY) {
945             av_usleep(500);
946             continue;
947         }
948         break;
949     } while ( 1 );
950
951     if (ret < 0) {
952         av_packet_unref(&new_pkt);
953         av_freep(&bs);
954         if (ret == MFX_ERR_MORE_DATA)
955             return 0;
956         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
957         return ff_qsv_error(ret);
958     }
959
960     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
961         if (frame->interlaced_frame)
962             print_interlace_msg(avctx, q);
963         else
964             av_log(avctx, AV_LOG_WARNING,
965                    "EncodeFrameAsync returned 'incompatible param' code\n");
966     }
967     if (sync) {
968         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
969         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
970         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
971     } else {
972         av_packet_unref(&new_pkt);
973         av_freep(&bs);
974     }
975
976     if (!av_fifo_space(q->async_fifo) ||
977         (!frame && av_fifo_size(q->async_fifo))) {
978         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
979         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
980         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
981
982         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
983
984         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
985         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
986         new_pkt.size = bs->DataLength;
987
988         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
989             bs->FrameType & MFX_FRAMETYPE_xIDR)
990             new_pkt.flags |= AV_PKT_FLAG_KEY;
991
992 #if FF_API_CODED_FRAME
993 FF_DISABLE_DEPRECATION_WARNINGS
994         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
995             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
996         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
997             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
998         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
999             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
1000 FF_ENABLE_DEPRECATION_WARNINGS
1001 #endif
1002
1003         av_freep(&bs);
1004
1005         if (pkt->data) {
1006             if (pkt->size < new_pkt.size) {
1007                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
1008                        pkt->size, new_pkt.size);
1009                 av_packet_unref(&new_pkt);
1010                 return AVERROR(EINVAL);
1011             }
1012
1013             memcpy(pkt->data, new_pkt.data, new_pkt.size);
1014             pkt->size = new_pkt.size;
1015
1016             ret = av_packet_copy_props(pkt, &new_pkt);
1017             av_packet_unref(&new_pkt);
1018             if (ret < 0)
1019                 return ret;
1020         } else
1021             *pkt = new_pkt;
1022
1023         *got_packet = 1;
1024     }
1025
1026     return 0;
1027 }
1028
1029 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
1030 {
1031     QSVFrame *cur;
1032
1033     if (q->session)
1034         MFXVideoENCODE_Close(q->session);
1035     q->session = NULL;
1036
1037     ff_qsv_close_internal_session(&q->internal_qs);
1038
1039     cur = q->work_frames;
1040     while (cur) {
1041         q->work_frames = cur->next;
1042         av_frame_free(&cur->frame);
1043         av_free(cur->enc_ctrl.Payload);
1044         av_freep(&cur);
1045         cur = q->work_frames;
1046     }
1047
1048     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
1049         AVPacket pkt;
1050         mfxSyncPoint sync;
1051         mfxBitstream *bs;
1052
1053         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
1054         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
1055         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
1056
1057         av_freep(&bs);
1058         av_packet_unref(&pkt);
1059     }
1060     av_fifo_free(q->async_fifo);
1061     q->async_fifo = NULL;
1062
1063     av_freep(&q->opaque_surfaces);
1064     av_buffer_unref(&q->opaque_alloc_buf);
1065
1066     av_freep(&q->extparam);
1067
1068     return 0;
1069 }