Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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_QueryIOSurf(q->session, &q->param, &q->req);
  268.     if (ret < 0) {
  269.         av_log(avctx, AV_LOG_ERROR, "Error querying the encoding parameters\n");
  270.         return ff_qsv_error(ret);
  271.     }
  272.  
  273.     ret = MFXVideoENCODE_Init(q->session, &q->param);
  274.     if (MFX_WRN_PARTIAL_ACCELERATION==ret) {
  275.         av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
  276.     } else if (ret < 0) {
  277.         av_log(avctx, AV_LOG_ERROR, "Error initializing the encoder\n");
  278.         return ff_qsv_error(ret);
  279.     }
  280.  
  281.     ret = qsv_retrieve_enc_params(avctx, q);
  282.     if (ret < 0) {
  283.         av_log(avctx, AV_LOG_ERROR, "Error retrieving encoding parameters.\n");
  284.         return ret;
  285.     }
  286.  
  287.     q->avctx = avctx;
  288.  
  289.     return 0;
  290. }
  291.  
  292. static void clear_unused_frames(QSVEncContext *q)
  293. {
  294.     QSVFrame *cur = q->work_frames;
  295.     while (cur) {
  296.         if (cur->surface && !cur->surface->Data.Locked) {
  297.             cur->surface = NULL;
  298.             av_frame_unref(cur->frame);
  299.         }
  300.         cur = cur->next;
  301.     }
  302. }
  303.  
  304. static int get_free_frame(QSVEncContext *q, QSVFrame **f)
  305. {
  306.     QSVFrame *frame, **last;
  307.  
  308.     clear_unused_frames(q);
  309.  
  310.     frame = q->work_frames;
  311.     last  = &q->work_frames;
  312.     while (frame) {
  313.         if (!frame->surface) {
  314.             *f = frame;
  315.             return 0;
  316.         }
  317.  
  318.         last  = &frame->next;
  319.         frame = frame->next;
  320.     }
  321.  
  322.     frame = av_mallocz(sizeof(*frame));
  323.     if (!frame)
  324.         return AVERROR(ENOMEM);
  325.     frame->frame = av_frame_alloc();
  326.     if (!frame->frame) {
  327.         av_freep(&frame);
  328.         return AVERROR(ENOMEM);
  329.     }
  330.     *last = frame;
  331.  
  332.     *f = frame;
  333.  
  334.     return 0;
  335. }
  336.  
  337. static int submit_frame(QSVEncContext *q, const AVFrame *frame,
  338.                         mfxFrameSurface1 **surface)
  339. {
  340.     QSVFrame *qf;
  341.     int ret;
  342.  
  343.     ret = get_free_frame(q, &qf);
  344.     if (ret < 0)
  345.         return ret;
  346.  
  347.     if (frame->format == AV_PIX_FMT_QSV) {
  348.         ret = av_frame_ref(qf->frame, frame);
  349.         if (ret < 0)
  350.             return ret;
  351.  
  352.         qf->surface = (mfxFrameSurface1*)qf->frame->data[3];
  353.         *surface = qf->surface;
  354.         return 0;
  355.     }
  356.  
  357.     /* make a copy if the input is not padded as libmfx requires */
  358.     if (     frame->height & (q->height_align - 1) ||
  359.         frame->linesize[0] & (q->width_align - 1)) {
  360.         qf->frame->height = FFALIGN(frame->height, q->height_align);
  361.         qf->frame->width  = FFALIGN(frame->width, q->width_align);
  362.  
  363.         ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);
  364.         if (ret < 0)
  365.             return ret;
  366.  
  367.         qf->frame->height = frame->height;
  368.         qf->frame->width  = frame->width;
  369.         ret = av_frame_copy(qf->frame, frame);
  370.         if (ret < 0) {
  371.             av_frame_unref(qf->frame);
  372.             return ret;
  373.         }
  374.     } else {
  375.         ret = av_frame_ref(qf->frame, frame);
  376.         if (ret < 0)
  377.             return ret;
  378.     }
  379.  
  380.     qf->surface_internal.Info = q->param.mfx.FrameInfo;
  381.  
  382.     qf->surface_internal.Info.PicStruct =
  383.         !frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE :
  384.         frame->top_field_first   ? MFX_PICSTRUCT_FIELD_TFF :
  385.                                    MFX_PICSTRUCT_FIELD_BFF;
  386.     if (frame->repeat_pict == 1)
  387.         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED;
  388.     else if (frame->repeat_pict == 2)
  389.         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
  390.     else if (frame->repeat_pict == 4)
  391.         qf->surface_internal.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
  392.  
  393.     qf->surface_internal.Data.PitchLow  = qf->frame->linesize[0];
  394.     qf->surface_internal.Data.Y         = qf->frame->data[0];
  395.     qf->surface_internal.Data.UV        = qf->frame->data[1];
  396.     qf->surface_internal.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, (AVRational){1, 90000});
  397.  
  398.     qf->surface = &qf->surface_internal;
  399.  
  400.     *surface = qf->surface;
  401.  
  402.     return 0;
  403. }
  404.  
  405. static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
  406. {
  407.     if (q->param.mfx.CodecId == MFX_CODEC_AVC) {
  408.         if (q->param.mfx.CodecProfile == MFX_PROFILE_AVC_BASELINE ||
  409.             q->param.mfx.CodecLevel < MFX_LEVEL_AVC_21 ||
  410.             q->param.mfx.CodecLevel > MFX_LEVEL_AVC_41)
  411.             av_log(avctx, AV_LOG_WARNING,
  412.                    "Interlaced coding is supported"
  413.                    " at Main/High Profile Level 2.1-4.1\n");
  414.     }
  415. }
  416.  
  417. int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
  418.                   AVPacket *pkt, const AVFrame *frame, int *got_packet)
  419. {
  420.     AVPacket new_pkt = { 0 };
  421.     mfxBitstream *bs;
  422.  
  423.     mfxFrameSurface1 *surf = NULL;
  424.     mfxSyncPoint sync      = NULL;
  425.     int ret;
  426.  
  427.     if (frame) {
  428.         ret = submit_frame(q, frame, &surf);
  429.         if (ret < 0) {
  430.             av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n");
  431.             return ret;
  432.         }
  433.     }
  434.  
  435.     ret = av_new_packet(&new_pkt, q->packet_size);
  436.     if (ret < 0) {
  437.         av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
  438.         return ret;
  439.     }
  440.  
  441.     bs = av_mallocz(sizeof(*bs));
  442.     if (!bs) {
  443.         av_packet_unref(&new_pkt);
  444.         return AVERROR(ENOMEM);
  445.     }
  446.     bs->Data      = new_pkt.data;
  447.     bs->MaxLength = new_pkt.size;
  448.  
  449.     do {
  450.         ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, bs, &sync);
  451.         if (ret == MFX_WRN_DEVICE_BUSY) {
  452.             av_usleep(500);
  453.             continue;
  454.         }
  455.         break;
  456.     } while ( 1 );
  457.  
  458.     if (ret < 0) {
  459.         av_packet_unref(&new_pkt);
  460.         av_freep(&bs);
  461.         if (ret == MFX_ERR_MORE_DATA)
  462.             return 0;
  463.         av_log(avctx, AV_LOG_ERROR, "EncodeFrameAsync returned %d\n", ret);
  464.         return ff_qsv_error(ret);
  465.     }
  466.  
  467.     if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) {
  468.         if (frame->interlaced_frame)
  469.             print_interlace_msg(avctx, q);
  470.         else
  471.             av_log(avctx, AV_LOG_WARNING,
  472.                    "EncodeFrameAsync returned 'incompatible param' code\n");
  473.     }
  474.     if (sync) {
  475.         av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
  476.         av_fifo_generic_write(q->async_fifo, &sync,    sizeof(sync),    NULL);
  477.         av_fifo_generic_write(q->async_fifo, &bs,      sizeof(bs),    NULL);
  478.     } else {
  479.         av_packet_unref(&new_pkt);
  480.         av_freep(&bs);
  481.     }
  482.  
  483.     if (!av_fifo_space(q->async_fifo) ||
  484.         (!frame && av_fifo_size(q->async_fifo))) {
  485.         av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
  486.         av_fifo_generic_read(q->async_fifo, &sync,    sizeof(sync),    NULL);
  487.         av_fifo_generic_read(q->async_fifo, &bs,      sizeof(bs),      NULL);
  488.  
  489.         MFXVideoCORE_SyncOperation(q->session, sync, 60000);
  490.  
  491.         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
  492.         new_pkt.pts  = av_rescale_q(bs->TimeStamp,       (AVRational){1, 90000}, avctx->time_base);
  493.         new_pkt.size = bs->DataLength;
  494.  
  495.         if (bs->FrameType & MFX_FRAMETYPE_IDR ||
  496.             bs->FrameType & MFX_FRAMETYPE_xIDR)
  497.             new_pkt.flags |= AV_PKT_FLAG_KEY;
  498.  
  499. #if FF_API_CODED_FRAME
  500. FF_DISABLE_DEPRECATION_WARNINGS
  501.         if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
  502.             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
  503.         else if (bs->FrameType & MFX_FRAMETYPE_P || bs->FrameType & MFX_FRAMETYPE_xP)
  504.             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
  505.         else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & MFX_FRAMETYPE_xB)
  506.             avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
  507. FF_ENABLE_DEPRECATION_WARNINGS
  508. #endif
  509.  
  510.         av_freep(&bs);
  511.  
  512.         if (pkt->data) {
  513.             if (pkt->size < new_pkt.size) {
  514.                 av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
  515.                        pkt->size, new_pkt.size);
  516.                 av_packet_unref(&new_pkt);
  517.                 return AVERROR(EINVAL);
  518.             }
  519.  
  520.             memcpy(pkt->data, new_pkt.data, new_pkt.size);
  521.             pkt->size = new_pkt.size;
  522.  
  523.             ret = av_packet_copy_props(pkt, &new_pkt);
  524.             av_packet_unref(&new_pkt);
  525.             if (ret < 0)
  526.                 return ret;
  527.         } else
  528.             *pkt = new_pkt;
  529.  
  530.         *got_packet = 1;
  531.     }
  532.  
  533.     return 0;
  534. }
  535.  
  536. int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
  537. {
  538.     QSVFrame *cur;
  539.  
  540.     MFXVideoENCODE_Close(q->session);
  541.     q->session = NULL;
  542.  
  543.     ff_qsv_close_internal_session(&q->internal_qs);
  544.  
  545.     cur = q->work_frames;
  546.     while (cur) {
  547.         q->work_frames = cur->next;
  548.         av_frame_free(&cur->frame);
  549.         av_freep(&cur);
  550.         cur = q->work_frames;
  551.     }
  552.  
  553.     while (q->async_fifo && av_fifo_size(q->async_fifo)) {
  554.         AVPacket pkt;
  555.         mfxSyncPoint sync;
  556.         mfxBitstream *bs;
  557.  
  558.         av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);
  559.         av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
  560.         av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);
  561.  
  562.         av_freep(&bs);
  563.         av_packet_unref(&pkt);
  564.     }
  565.     av_fifo_free(q->async_fifo);
  566.     q->async_fifo = NULL;
  567.  
  568.     return 0;
  569. }
  570.