Merge commit '2ec96b6bd5bf7b22978711bcf2cee702bee89c6f'
[ffmpeg.git] / 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
34 #include "avcodec.h"
35 #include "internal.h"
36 #include "qsv.h"
37 #include "qsv_internal.h"
38 #include "qsvenc.h"
39
40 static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
41 {
42     const char *ratecontrol_desc;
43
44     float quant;
45     int ret;
46
47     ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);
48     if (ret < 0)
49         return AVERROR_BUG;
50     q->param.mfx.CodecId = ret;
51
52     q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
53
54     if (avctx->level > 0)
55         q->param.mfx.CodecLevel = avctx->level;
56
57     q->param.mfx.CodecProfile       = q->profile;
58     q->param.mfx.TargetUsage        = q->preset;
59     q->param.mfx.GopPicSize         = FFMAX(0, avctx->gop_size);
60     q->param.mfx.GopRefDist         = FFMAX(-1, avctx->max_b_frames) + 1;
61     q->param.mfx.GopOptFlag         = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
62                                       MFX_GOP_CLOSED : 0;
63     q->param.mfx.IdrInterval        = q->idr_interval;
64     q->param.mfx.NumSlice           = avctx->slices;
65     q->param.mfx.NumRefFrame        = FFMAX(0, avctx->refs);
66     q->param.mfx.EncodedOrder       = 0;
67     q->param.mfx.BufferSizeInKB     = 0;
68
69     q->param.mfx.FrameInfo.FourCC         = MFX_FOURCC_NV12;
70     q->param.mfx.FrameInfo.CropX          = 0;
71     q->param.mfx.FrameInfo.CropY          = 0;
72     q->param.mfx.FrameInfo.CropW          = avctx->width;
73     q->param.mfx.FrameInfo.CropH          = avctx->height;
74     q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
75     q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
76     q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
77     q->param.mfx.FrameInfo.BitDepthLuma   = 8;
78     q->param.mfx.FrameInfo.BitDepthChroma = 8;
79     q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, q->width_align);
80
81     if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
82        /* A true field layout (TFF or BFF) is not important here,
83           it will specified later during frame encoding. But it is important
84           to specify is frame progressive or not because allowed heigh alignment
85           does depend by this.
86         */
87         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
88         q->height_align = 32;
89     } else {
90         q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
91         q->height_align = 16;
92     }
93    q->param.mfx.FrameInfo.Height    = FFALIGN(avctx->height, q->height_align);
94
95     if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
96         q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
97         q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
98     } else {
99         q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
100         q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
101     }
102
103     if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
104         q->param.mfx.RateControlMethod = MFX_RATECONTROL_CQP;
105         ratecontrol_desc = "constant quantization parameter (CQP)";
106     } else if (avctx->rc_max_rate == avctx->bit_rate) {
107         q->param.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
108         ratecontrol_desc = "constant bitrate (CBR)";
109     } else if (!avctx->rc_max_rate) {
110 #if QSV_VERSION_ATLEAST(1,7)
111         if (q->look_ahead) {
112             q->param.mfx.RateControlMethod = MFX_RATECONTROL_LA;
113             ratecontrol_desc = "lookahead (LA)";
114         } else
115 #endif
116         {
117             q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR;
118             ratecontrol_desc = "average variable bitrate (AVBR)";
119         }
120     } else {
121         q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
122         ratecontrol_desc = "variable bitrate (VBR)";
123     }
124
125     av_log(avctx, AV_LOG_VERBOSE, "Using the %s ratecontrol method\n", ratecontrol_desc);
126
127     switch (q->param.mfx.RateControlMethod) {
128     case MFX_RATECONTROL_CBR:
129     case MFX_RATECONTROL_VBR:
130         q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000;
131         q->param.mfx.TargetKbps       = avctx->bit_rate / 1000;
132         q->param.mfx.MaxKbps          = avctx->rc_max_rate / 1000;
133         break;
134     case MFX_RATECONTROL_CQP:
135         quant = avctx->global_quality / FF_QP2LAMBDA;
136
137         q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51);
138         q->param.mfx.QPP = av_clip(quant, 0, 51);
139         q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51);
140
141         break;
142     case MFX_RATECONTROL_AVBR:
143 #if QSV_VERSION_ATLEAST(1,7)
144     case MFX_RATECONTROL_LA:
145 #endif
146         q->param.mfx.TargetKbps  = avctx->bit_rate / 1000;
147         q->param.mfx.Convergence = q->avbr_convergence;
148         q->param.mfx.Accuracy    = q->avbr_accuracy;
149         break;
150     }
151
152     // the HEVC encoder plugin currently fails if coding options
153     // are provided
154     if (avctx->codec_id != AV_CODEC_ID_HEVC) {
155         q->extco.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION;
156         q->extco.Header.BufferSz      = sizeof(q->extco);
157         q->extco.CAVLC                = avctx->coder_type == FF_CODER_TYPE_VLC ?
158                                         MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
159
160         q->extco.PicTimingSEI         = q->pic_timing_sei ?
161                                         MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
162
163         q->extparam_internal[0] = (mfxExtBuffer *)&q->extco;
164
165 #if QSV_VERSION_ATLEAST(1,6)
166         q->extco2.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION2;
167         q->extco2.Header.BufferSz      = sizeof(q->extco2);
168
169 #if QSV_VERSION_ATLEAST(1,7)
170         // valid value range is from 10 to 100 inclusive
171         // to instruct the encoder to use the default value this should be set to zero
172         q->extco2.LookAheadDepth        = q->look_ahead_depth != 0 ? FFMAX(10, q->look_ahead_depth) : 0;
173 #endif
174 #if QSV_VERSION_ATLEAST(1,8)
175         q->extco2.LookAheadDS           = q->look_ahead_downsampling;
176 #endif
177
178         q->extparam_internal[1] = (mfxExtBuffer *)&q->extco2;
179
180 #endif
181     }
182
183     return 0;
184 }
185
186 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
187 {
188     uint8_t sps_buf[128];
189     uint8_t pps_buf[128];
190
191     mfxExtCodingOptionSPSPPS extradata = {
192         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
193         .Header.BufferSz = sizeof(extradata),
194         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
195         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
196     };
197
198     mfxExtBuffer *ext_buffers[] = {
199         (mfxExtBuffer*)&extradata,
200     };
201
202     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
203     int ret;
204
205     q->param.ExtParam    = ext_buffers;
206     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
207
208     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
209     if (ret < 0)
210         return ff_qsv_error(ret);
211
212     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
213
214     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
215         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
216         return AVERROR_UNKNOWN;
217     }
218
219     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
220                                  AV_INPUT_BUFFER_PADDING_SIZE);
221     if (!avctx->extradata)
222         return AVERROR(ENOMEM);
223
224     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
225     if (need_pps)
226         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
227     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
228     memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
229
230     return 0;
231 }
232
233 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
234 {
235     int ret;
236
237     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
238     q->param.AsyncDepth = q->async_depth;
239
240     q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
241                                   (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
242     if (!q->async_fifo)
243         return AVERROR(ENOMEM);
244
245     if (avctx->hwaccel_context) {
246         AVQSVContext *qsv = avctx->hwaccel_context;
247
248         q->session         = qsv->session;
249         q->param.IOPattern = qsv->iopattern;
250     }
251
252     if (!q->session) {
253         ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
254                                            q->load_plugins);
255         if (ret < 0)
256             return ret;
257
258         q->session = q->internal_qs.session;
259     }
260
261     ret = init_video_param(avctx, q);
262     if (ret < 0)
263         return ret;
264
265     ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
266     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
267         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
268     } else if (ret < 0) {
269         av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
270         return ff_qsv_error(ret);
271     }
272
273     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
274     if (ret < 0) {
275         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
276         return ff_qsv_error(ret);
277     }
278
279     if (avctx->hwaccel_context) {
280         AVQSVContext *qsv = avctx->hwaccel_context;
281         int i, j;
282
283         q->extparam = av_mallocz_array(qsv->nb_ext_buffers + FF_ARRAY_ELEMS(q->extparam_internal),
284                                        sizeof(*q->extparam));
285         if (!q->extparam)
286             return AVERROR(ENOMEM);
287
288         q->param.ExtParam = q->extparam;
289         for (i = 0; i < qsv->nb_ext_buffers; i++)
290             q->param.ExtParam[i] = qsv->ext_buffers[i];
291         q->param.NumExtParam = qsv->nb_ext_buffers;
292
293         for (i = 0; i < FF_ARRAY_ELEMS(q->extparam_internal); i++) {
294             for (j = 0; j < qsv->nb_ext_buffers; j++) {
295                 if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId)
296                     break;
297             }
298             if (j < qsv->nb_ext_buffers)
299                 continue;
300
301             q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i];
302         }
303     } else {
304         q->param.ExtParam    = q->extparam_internal;
305         q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam_internal);
306     }
307
308     ret = MFXVideoENCODE_Init(q->session, &q->param);
309     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
310         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
311     } else if (ret < 0) {
312         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
313         return ff_qsv_error(ret);
314     }
315
316     ret = qsv_retrieve_enc_params(avctx, q);
317     if (ret < 0) {
318         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
319         return ret;
320     }
321
322     q->avctx = avctx;
323
324     return 0;
325 }
326
327 static void clear_unused_frames(QSVEncContext *q)
328 {
329     QSVFrame *cur = q->work_frames;
330     while (cur) {
331         if (cur->surface && !cur->surface->Data.Locked) {
332             cur->surface = NULL;
333             av_frame_unref(cur->frame);
334         }
335         cur = cur->next;
336     }
337 }
338
339 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
340 {
341     QSVFrame *frame, **last;
342
343     clear_unused_frames(q);
344
345     frame = q->work_frames;
346     last  = &q->work_frames;
347     while (frame) {
348         if (!frame->surface) {
349             *f = frame;
350             return 0;
351         }
352
353         last  = &frame->next;
354         frame = frame->next;
355     }
356
357     frame = av_mallocz(sizeof(*frame));
358     if (!frame)
359         return AVERROR(ENOMEM);
360     frame->frame = av_frame_alloc();
361     if (!frame->frame) {
362         av_freep(&frame);
363         return AVERROR(ENOMEM);
364     }
365     *last = frame;
366
367     *f = frame;
368
369     return 0;
370 }
371
372 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
373                         mfxFrameSurface1 **surface)
374 {
375     QSVFrame *qf;
376     int ret;
377
378     ret = get_free_frame(q, &qf);
379     if (ret < 0)
380         return ret;
381
382     if (frame->format == AV_PIX_FMT_QSV) {
383         ret = av_frame_ref(qf->frame, frame);
384         if (ret < 0)
385             return ret;
386
387         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
388     } else {
389         /* make a copy if the input is not padded as libmfx requires */
390         if (     frame->height & (q->height_align - 1) ||
391             frame->linesize[0] & (q->width_align - 1)) {
392             qf->frame->height = FFALIGN(frame->height, q->height_align);
393             qf->frame->width  = FFALIGN(frame->width, q->width_align);
394
395             ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
396             if (ret < 0)
397                 return ret;
398
399             qf->frame->height = frame->height;
400             qf->frame->width  = frame->width;
401             ret = av_frame_copy(qf->frame, frame);
402             if (ret < 0) {
403                 av_frame_unref(qf->frame);
404                 return ret;
405             }
406         } else {
407             ret = av_frame_ref(qf->frame, frame);
408             if (ret < 0)
409                 return ret;
410         }
411
412         qf->surface_internal.Info = q->param.mfx.FrameInfo;
413
414         qf->surface_internal.Info.PicStruct =
415             !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
416             frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
417                                        MFX_PICSTRUCT_FIELD_BFF;
418         if (frame->repeat_pict == 1)
419             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
420         else if (frame->repeat_pict == 2)
421             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
422         else if (frame->repeat_pict == 4)
423             qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
424
425         qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
426         qf->surface_internal.Data.Y         = qf->frame->data[0];
427         qf->surface_internal.Data.UV        = qf->frame->data[1];
428
429         qf->surface = &qf->surface_internal;
430     }
431
432     qf->surface->Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
433
434     *surface = qf->surface;
435
436     return 0;
437 }
438
439 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
440 {
441     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
442         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
443             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
444             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
445             av_log(avctx, AV_LOG_WARNING,
446                    "Interlaced coding is supported"
447                    " at Main/High Profile Level 2.1-4.1\n");
448     }
449 }
450
451 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
452                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
453 {
454     AVPacket new_pkt = { 0 };
455     mfxBitstream *bs;
456
457     mfxFrameSurface1 *surf = NULL;
458     mfxSyncPoint sync      = NULL;
459     int ret;
460
461     if (frame) {
462         ret = submit_frame(q, frame, &surf);
463         if (ret < 0) {
464             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
465             return ret;
466         }
467     }
468
469     ret = av_new_packet(&new_pkt, q->packet_size);
470     if (ret < 0) {
471         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
472         return ret;
473     }
474
475     bs = av_mallocz(sizeof(*bs));
476     if (!bs) {
477         av_packet_unref(&new_pkt);
478         return AVERROR(ENOMEM);
479     }
480     bs->Data      = new_pkt.data;
481     bs->MaxLength = new_pkt.size;
482
483     do {
484         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
485         if (ret == MFX_WRN_DEVICE_BUSY) {
486             av_usleep(500);
487             continue;
488         }
489         break;
490     } while ( 1 );
491
492     if (ret < 0) {
493         av_packet_unref(&new_pkt);
494         av_freep(&bs);
495         if (ret == MFX_ERR_MORE_DATA)
496             return 0;
497         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
498         return ff_qsv_error(ret);
499     }
500
501     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
502         if (frame->interlaced_frame)
503             print_interlace_msg(avctx, q);
504         else
505             av_log(avctx, AV_LOG_WARNING,
506                    "EncodeFrameAsync returned 'incompatible param' code\n");
507     }
508     if (sync) {
509         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
510         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
511         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
512     } else {
513         av_packet_unref(&new_pkt);
514         av_freep(&bs);
515     }
516
517     if (!av_fifo_space(q->async_fifo) ||
518         (!frame && av_fifo_size(q->async_fifo))) {
519         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
520         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
521         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
522
523         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
524
525         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
526         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
527         new_pkt.size = bs->DataLength;
528
529         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
530             bs->FrameType & MFX_FRAMETYPE_xIDR)
531             new_pkt.flags |= AV_PKT_FLAG_KEY;
532
533 #if FF_API_CODED_FRAME
534 FF_DISABLE_DEPRECATION_WARNINGS
535         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
536             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
537         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
538             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
539         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
540             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
541 FF_ENABLE_DEPRECATION_WARNINGS
542 #endif
543
544         av_freep(&bs);
545
546         if (pkt->data) {
547             if (pkt->size < new_pkt.size) {
548                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
549                        pkt->size, new_pkt.size);
550                 av_packet_unref(&new_pkt);
551                 return AVERROR(EINVAL);
552             }
553
554             memcpy(pkt->data, new_pkt.data, new_pkt.size);
555             pkt->size = new_pkt.size;
556
557             ret = av_packet_copy_props(pkt, &new_pkt);
558             av_packet_unref(&new_pkt);
559             if (ret < 0)
560                 return ret;
561         } else
562             *pkt = new_pkt;
563
564         *got_packet = 1;
565     }
566
567     return 0;
568 }
569
570 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
571 {
572     QSVFrame *cur;
573
574     if (q->session)
575         MFXVideoENCODE_Close(q->session);
576     q->session = NULL;
577
578     ff_qsv_close_internal_session(&q->internal_qs);
579
580     cur = q->work_frames;
581     while (cur) {
582         q->work_frames = cur->next;
583         av_frame_free(&cur->frame);
584         av_freep(&cur);
585         cur = q->work_frames;
586     }
587
588     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
589         AVPacket pkt;
590         mfxSyncPoint sync;
591         mfxBitstream *bs;
592
593         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
594         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
595         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
596
597         av_freep(&bs);
598         av_packet_unref(&pkt);
599     }
600     av_fifo_free(q->async_fifo);
601     q->async_fifo = NULL;
602
603     av_freep(&q->extparam);
604
605     return 0;
606 }