qsvenc.c: use query to catch all kind of setting issues
[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[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[1] = (mfxExtBuffer *)&q->extco2;
179
180 #endif
181         q->param.ExtParam    = q->extparam;
182         q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam);
183     }
184
185     return 0;
186 }
187
188 static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
189 {
190     uint8_t sps_buf[128];
191     uint8_t pps_buf[128];
192
193     mfxExtCodingOptionSPSPPS extradata = {
194         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_SPSPPS,
195         .Header.BufferSz = sizeof(extradata),
196         .SPSBuffer = sps_buf, .SPSBufSize = sizeof(sps_buf),
197         .PPSBuffer = pps_buf, .PPSBufSize = sizeof(pps_buf)
198     };
199
200     mfxExtBuffer *ext_buffers[] = {
201         (mfxExtBuffer*)&extradata,
202     };
203
204     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
205     int ret;
206
207     q->param.ExtParam    = ext_buffers;
208     q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
209
210     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
211     if (ret < 0)
212         return ff_qsv_error(ret);
213
214     q->packet_size = q->param.mfx.BufferSizeInKB * 1000;
215
216     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)) {
217         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
218         return AVERROR_UNKNOWN;
219     }
220
221     avctx->extradata = av_malloc(extradata.SPSBufSize + need_pps * extradata.PPSBufSize +
222                                  AV_INPUT_BUFFER_PADDING_SIZE);
223     if (!avctx->extradata)
224         return AVERROR(ENOMEM);
225
226     memcpy(avctx->extradata,                        sps_buf, extradata.SPSBufSize);
227     if (need_pps)
228         memcpy(avctx->extradata + extradata.SPSBufSize, pps_buf, extradata.PPSBufSize);
229     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
230     memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
231
232     return 0;
233 }
234
235 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
236 {
237     int ret;
238
239     q->param.IOPattern  = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
240     q->param.AsyncDepth = q->async_depth;
241
242     q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
243                                   (sizeof(AVPacket) + sizeof(mfxSyncPoint) + sizeof(mfxBitstream*)));
244     if (!q->async_fifo)
245         return AVERROR(ENOMEM);
246
247     if (avctx->hwaccel_context) {
248         AVQSVContext *qsv = avctx->hwaccel_context;
249
250         q->session         = qsv->session;
251         q->param.IOPattern = qsv->iopattern;
252     }
253
254     if (!q->session) {
255         ret = ff_qsv_init_internal_session(avctx, &q->internal_qs,
256                                            q->load_plugins);
257         if (ret < 0)
258             return ret;
259
260         q->session = q->internal_qs.session;
261     }
262
263     ret = init_video_param(avctx, q);
264     if (ret < 0)
265         return ret;
266
267     ret = MFXVideoENCODE_Query(q->session, &q->param,&q->param);
268     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
269         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
270     } else if (ret < 0) {
271         av_log(avctx, AV_LOG_ERROR, "Error %d querying encoder params\n", ret);
272         return ff_qsv_error(ret);
273     }
274
275     ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
276     if (ret < 0) {
277         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
278         return ff_qsv_error(ret);
279     }
280
281     ret = MFXVideoENCODE_Init(q->session, &q->param);
282     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
283         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
284     } else if (ret < 0) {
285         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
286         return ff_qsv_error(ret);
287     }
288
289     ret = qsv_retrieve_enc_params(avctx, q);
290     if (ret < 0) {
291         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
292         return ret;
293     }
294
295     q->avctx = avctx;
296
297     return 0;
298 }
299
300 static void clear_unused_frames(QSVEncContext *q)
301 {
302     QSVFrame *cur = q->work_frames;
303     while (cur) {
304         if (cur->surface && !cur->surface->Data.Locked) {
305             cur->surface = NULL;
306             av_frame_unref(cur->frame);
307         }
308         cur = cur->next;
309     }
310 }
311
312 static int get_free_frame(QSVEncContext *q, QSVFrame **f)
313 {
314     QSVFrame *frame, **last;
315
316     clear_unused_frames(q);
317
318     frame = q->work_frames;
319     last  = &q->work_frames;
320     while (frame) {
321         if (!frame->surface) {
322             *f = frame;
323             return 0;
324         }
325
326         last  = &frame->next;
327         frame = frame->next;
328     }
329
330     frame = av_mallocz(sizeof(*frame));
331     if (!frame)
332         return AVERROR(ENOMEM);
333     frame->frame = av_frame_alloc();
334     if (!frame->frame) {
335         av_freep(&frame);
336         return AVERROR(ENOMEM);
337     }
338     *last = frame;
339
340     *f = frame;
341
342     return 0;
343 }
344
345 static int submit_frame(QSVEncContext *q, const AVFrame *frame,
346                         mfxFrameSurface1 **surface)
347 {
348     QSVFrame *qf;
349     int ret;
350
351     ret = get_free_frame(q, &qf);
352     if (ret < 0)
353         return ret;
354
355     if (frame->format == AV_PIX_FMT_QSV) {
356         ret = av_frame_ref(qf->frame, frame);
357         if (ret < 0)
358             return ret;
359
360         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
361         *surface = qf->surface;
362         return 0;
363     }
364
365     /* make a copy if the input is not padded as libmfx requires */
366     if (     frame->height & (q->height_align - 1) ||
367         frame->linesize[0] & (q->width_align - 1)) {
368         qf->frame->height = FFALIGN(frame->height, q->height_align);
369         qf->frame->width  = FFALIGN(frame->width, q->width_align);
370
371         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
372         if (ret < 0)
373             return ret;
374
375         qf->frame->height = frame->height;
376         qf->frame->width  = frame->width;
377         ret = av_frame_copy(qf->frame, frame);
378         if (ret < 0) {
379             av_frame_unref(qf->frame);
380             return ret;
381         }
382     } else {
383         ret = av_frame_ref(qf->frame, frame);
384         if (ret < 0)
385             return ret;
386     }
387
388     qf->surface_internal.Info = q->param.mfx.FrameInfo;
389
390     qf->surface_internal.Info.PicStruct =
391         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
392         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
393                                    MFX_PICSTRUCT_FIELD_BFF;
394     if (frame->repeat_pict == 1)
395         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
396     else if (frame->repeat_pict == 2)
397         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
398     else if (frame->repeat_pict == 4)
399         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
400
401     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
402     qf->surface_internal.Data.Y         = qf->frame->data[0];
403     qf->surface_internal.Data.UV        = qf->frame->data[1];
404     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
405
406     qf->surface = &qf->surface_internal;
407
408     *surface = qf->surface;
409
410     return 0;
411 }
412
413 static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
414 {
415     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
416         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
417             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
418             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
419             av_log(avctx, AV_LOG_WARNING,
420                    "Interlaced coding is supported"
421                    " at Main/High Profile Level 2.1-4.1\n");
422     }
423 }
424
425 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
426                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
427 {
428     AVPacket new_pkt = { 0 };
429     mfxBitstream *bs;
430
431     mfxFrameSurface1 *surf = NULL;
432     mfxSyncPoint sync      = NULL;
433     int ret;
434
435     if (frame) {
436         ret = submit_frame(q, frame, &surf);
437         if (ret < 0) {
438             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
439             return ret;
440         }
441     }
442
443     ret = av_new_packet(&new_pkt, q->packet_size);
444     if (ret < 0) {
445         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
446         return ret;
447     }
448
449     bs = av_mallocz(sizeof(*bs));
450     if (!bs) {
451         av_packet_unref(&new_pkt);
452         return AVERROR(ENOMEM);
453     }
454     bs->Data      = new_pkt.data;
455     bs->MaxLength = new_pkt.size;
456
457     do {
458         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
459         if (ret == MFX_WRN_DEVICE_BUSY) {
460             av_usleep(500);
461             continue;
462         }
463         break;
464     } while ( 1 );
465
466     if (ret < 0) {
467         av_packet_unref(&new_pkt);
468         av_freep(&bs);
469         if (ret == MFX_ERR_MORE_DATA)
470             return 0;
471         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
472         return ff_qsv_error(ret);
473     }
474
475     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
476         if (frame->interlaced_frame)
477             print_interlace_msg(avctx, q);
478         else
479             av_log(avctx, AV_LOG_WARNING,
480                    "EncodeFrameAsync returned 'incompatible param' code\n");
481     }
482     if (sync) {
483         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
484         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
485         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
486     } else {
487         av_packet_unref(&new_pkt);
488         av_freep(&bs);
489     }
490
491     if (!av_fifo_space(q->async_fifo) ||
492         (!frame && av_fifo_size(q->async_fifo))) {
493         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
494         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
495         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
496
497         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
498
499         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
500         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
501         new_pkt.size = bs->DataLength;
502
503         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
504             bs->FrameType & MFX_FRAMETYPE_xIDR)
505             new_pkt.flags |= AV_PKT_FLAG_KEY;
506
507 #if FF_API_CODED_FRAME
508 FF_DISABLE_DEPRECATION_WARNINGS
509         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
510             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
511         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
512             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
513         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
514             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
515 FF_ENABLE_DEPRECATION_WARNINGS
516 #endif
517
518         av_freep(&bs);
519
520         if (pkt->data) {
521             if (pkt->size < new_pkt.size) {
522                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
523                        pkt->size, new_pkt.size);
524                 av_packet_unref(&new_pkt);
525                 return AVERROR(EINVAL);
526             }
527
528             memcpy(pkt->data, new_pkt.data, new_pkt.size);
529             pkt->size = new_pkt.size;
530
531             ret = av_packet_copy_props(pkt, &new_pkt);
532             av_packet_unref(&new_pkt);
533             if (ret < 0)
534                 return ret;
535         } else
536             *pkt = new_pkt;
537
538         *got_packet = 1;
539     }
540
541     return 0;
542 }
543
544 int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
545 {
546     QSVFrame *cur;
547
548     if (q->session)
549         MFXVideoENCODE_Close(q->session);
550     q->session = NULL;
551
552     ff_qsv_close_internal_session(&q->internal_qs);
553
554     cur = q->work_frames;
555     while (cur) {
556         q->work_frames = cur->next;
557         av_frame_free(&cur->frame);
558         av_freep(&cur);
559         cur = q->work_frames;
560     }
561
562     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
563         AVPacket pkt;
564         mfxSyncPoint sync;
565         mfxBitstream *bs;
566
567         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
568         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
569         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
570
571         av_freep(&bs);
572         av_packet_unref(&pkt);
573     }
574     av_fifo_free(q->async_fifo);
575     q->async_fifo = NULL;
576
577     return 0;
578 }