int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, AVPacket *pkt, const AVFrame *frame, int *got_packet) { mfxBitstream bs = { { { 0 } } }; mfxFrameSurface1 *surf = NULL; mfxSyncPoint sync = NULL; int ret; if (frame) { ret = submit_frame(q, frame, &surf); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error submitting the frame for encoding.\n"); return ret; } } ret = ff_alloc_packet(pkt, q->packet_size); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n"); return ret; } bs.Data = pkt->data; bs.MaxLength = pkt->size; do { ret = MFXVideoENCODE_EncodeFrameAsync(q->session, NULL, surf, &bs, &sync); if (ret == MFX_WRN_DEVICE_BUSY) av_usleep(1); } while (ret > 0); if (ret < 0) return (ret == MFX_ERR_MORE_DATA) ? 0 : ff_qsv_error(ret); if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame) print_interlace_msg(avctx, q); if (sync) { MFXVideoCORE_SyncOperation(q->session, sync, 60000); if (bs.FrameType & MFX_FRAMETYPE_I || bs.FrameType & MFX_FRAMETYPE_xI) avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; else if (bs.FrameType & MFX_FRAMETYPE_P || bs.FrameType & MFX_FRAMETYPE_xP) avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; else if (bs.FrameType & MFX_FRAMETYPE_B || bs.FrameType & MFX_FRAMETYPE_xB) avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; pkt->dts = av_rescale_q(bs.DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base); pkt->pts = av_rescale_q(bs.TimeStamp, (AVRational){1, 90000}, avctx->time_base); pkt->size = bs.DataLength; if (bs.FrameType & MFX_FRAMETYPE_IDR || bs.FrameType & MFX_FRAMETYPE_xIDR) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; } return 0; }