@@ -69,6 +69,13 @@ static const struct {
#endif
};
+struct QSVpacket
+{
+ AVPacket new_pkt;
+ mfxBitstream *bs;
+ mfxSyncPoint *syncp;
+};
+
static const char *print_profile(mfxU16 profile)
{
int i;
@@ -727,8 +734,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
q->param.AsyncDepth = q->async_depth;
- q->async_fifo = av_fifo_alloc((1 + q->async_depth) *
- (sizeof(AVPacket) + sizeof(mfxSyncPoint*) + sizeof(mfxBitstream*)));
+ q->async_fifo = av_fifo_alloc((1 + q->async_depth) * sizeof(struct QSVpacket));
if (!q->async_fifo)
return AVERROR(ENOMEM);
@@ -979,14 +985,19 @@ static void print_interlace_msg(AVCodecContext *avctx, QSVEncContext *q)
}
}
+static void qsv_packet_release(struct QSVpacket *qsv_pkt)
+{
+ av_packet_unref(&qsv_pkt->new_pkt);
+ av_freep(qsv_pkt->bs);
+ av_freep(qsv_pkt->syncp);
+}
+
static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
const AVFrame *frame)
{
- AVPacket new_pkt = { 0 };
- mfxBitstream *bs;
+ struct QSVpacket qsv_pkt = { 0 };
mfxFrameSurface1 *surf = NULL;
- mfxSyncPoint *sync = NULL;
QSVFrame *qsv_frame = NULL;
mfxEncodeCtrl* enc_ctrl = NULL;
mfxStatus ret;
@@ -1003,33 +1014,33 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
enc_ctrl = &qsv_frame->enc_ctrl;
}
- ret = av_new_packet(&new_pkt, q->packet_size);
+ ret = av_new_packet(&qsv_pkt.new_pkt, q->packet_size);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error allocating the output packet\n");
return ret;
}
- bs = av_mallocz(sizeof(*bs));
- if (!bs) {
- av_packet_unref(&new_pkt);
+ qsv_pkt.bs = av_mallocz(sizeof(*qsv_pkt.bs));
+ if (!qsv_pkt.bs) {
+ av_packet_unref(&qsv_pkt.new_pkt);
return AVERROR(ENOMEM);
}
- bs->Data = new_pkt.data;
- bs->MaxLength = new_pkt.size;
+ qsv_pkt.bs->Data = qsv_pkt.new_pkt.data;
+ qsv_pkt.bs->MaxLength = qsv_pkt.new_pkt.size;
if (q->set_encode_ctrl_cb) {
q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
}
- sync = av_mallocz(sizeof(*sync));
- if (!sync) {
- av_freep(&bs);
- av_packet_unref(&new_pkt);
+ qsv_pkt.syncp = av_mallocz(sizeof(*qsv_pkt.syncp));
+ if (!qsv_pkt.syncp) {
+ av_freep(&qsv_pkt.bs);
+ av_packet_unref(&qsv_pkt.new_pkt);
return AVERROR(ENOMEM);
}
do {
- ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, sync);
+ ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, qsv_pkt.bs, qsv_pkt.syncp);
if (ret == MFX_WRN_DEVICE_BUSY)
av_usleep(500);
} while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION);
@@ -1038,9 +1049,7 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
ff_qsv_print_warning(avctx, ret, "Warning during encoding");
if (ret < 0) {
- av_packet_unref(&new_pkt);
- av_freep(&bs);
- av_freep(&sync);
+ qsv_packet_release(&qsv_pkt);
return (ret == MFX_ERR_MORE_DATA) ?
0 : ff_qsv_print_error(avctx, ret, "Error during encoding");
}
@@ -1048,14 +1057,10 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
if (ret == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM && frame->interlaced_frame)
print_interlace_msg(avctx, q);
- if (*sync) {
- av_fifo_generic_write(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
- av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL);
- av_fifo_generic_write(q->async_fifo, &bs, sizeof(bs), NULL);
+ if (*qsv_pkt.syncp) {
+ av_fifo_generic_write(q->async_fifo, &qsv_pkt, sizeof(qsv_pkt), NULL);
} else {
- av_freep(&sync);
- av_packet_unref(&new_pkt);
- av_freep(&bs);
+ qsv_packet_release(&qsv_pkt);
}
return 0;
@@ -1072,57 +1077,53 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
if (!av_fifo_space(q->async_fifo) ||
(!frame && av_fifo_size(q->async_fifo))) {
- AVPacket new_pkt;
- mfxBitstream *bs;
- mfxSyncPoint *sync;
+ struct QSVpacket qsv_pkt;
- av_fifo_generic_read(q->async_fifo, &new_pkt, sizeof(new_pkt), NULL);
- av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
- av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
+ av_fifo_generic_read(q->async_fifo, &qsv_pkt, sizeof(qsv_pkt), NULL);
do {
- ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
+ ret = MFXVideoCORE_SyncOperation(q->session, *qsv_pkt.syncp, 1000);
} while (ret == MFX_WRN_IN_EXECUTION);
- new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
- new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
- new_pkt.size = bs->DataLength;
+ qsv_pkt.new_pkt.dts = av_rescale_q(qsv_pkt.bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
+ qsv_pkt.new_pkt.pts = av_rescale_q(qsv_pkt.bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base);
+ qsv_pkt.new_pkt.size = qsv_pkt.bs->DataLength;
- if (bs->FrameType & MFX_FRAMETYPE_IDR ||
- bs->FrameType & MFX_FRAMETYPE_xIDR)
- new_pkt.flags |= AV_PKT_FLAG_KEY;
+ if (qsv_pkt.bs->FrameType & MFX_FRAMETYPE_IDR ||
+ qsv_pkt.bs->FrameType & MFX_FRAMETYPE_xIDR)
+ qsv_pkt.new_pkt.flags |= AV_PKT_FLAG_KEY;
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
- if (bs->FrameType & MFX_FRAMETYPE_I || bs->FrameType & MFX_FRAMETYPE_xI)
+ if (qsv_pkt.bs->FrameType & MFX_FRAMETYPE_I || qsv_pkt.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)
+ else if (qsv_pkt.bs->FrameType & MFX_FRAMETYPE_P || qsv_pkt.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)
+ else if (qsv_pkt.bs->FrameType & MFX_FRAMETYPE_B || qsv_pkt.bs->FrameType & MFX_FRAMETYPE_xB)
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- av_freep(&bs);
- av_freep(&sync);
+ av_freep(&qsv_pkt.bs);
+ av_freep(&qsv_pkt.syncp);
if (pkt->data) {
- if (pkt->size < new_pkt.size) {
+ if (pkt->size < qsv_pkt.new_pkt.size) {
av_log(avctx, AV_LOG_ERROR, "Submitted buffer not large enough: %d < %d\n",
- pkt->size, new_pkt.size);
- av_packet_unref(&new_pkt);
+ pkt->size, qsv_pkt.new_pkt.size);
+ av_packet_unref(&qsv_pkt.new_pkt);
return AVERROR(EINVAL);
}
- memcpy(pkt->data, new_pkt.data, new_pkt.size);
- pkt->size = new_pkt.size;
+ memcpy(pkt->data, qsv_pkt.new_pkt.data, qsv_pkt.new_pkt.size);
+ pkt->size = qsv_pkt.new_pkt.size;
- ret = av_packet_copy_props(pkt, &new_pkt);
- av_packet_unref(&new_pkt);
+ ret = av_packet_copy_props(pkt, &qsv_pkt.new_pkt);
+ av_packet_unref(&qsv_pkt.new_pkt);
if (ret < 0)
return ret;
} else
- *pkt = new_pkt;
+ *pkt = qsv_pkt.new_pkt;
*got_packet = 1;
}
@@ -1154,17 +1155,11 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
}
while (q->async_fifo && av_fifo_size(q->async_fifo)) {
- AVPacket pkt;
- mfxSyncPoint *sync;
- mfxBitstream *bs;
+ struct QSVpacket qsv_pkt;
- av_fifo_generic_read(q->async_fifo, &pkt, sizeof(pkt), NULL);
- av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);
- av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL);
+ av_fifo_generic_read(q->async_fifo, &qsv_pkt, sizeof(qsv_pkt), NULL);
- av_freep(&sync);
- av_freep(&bs);
- av_packet_unref(&pkt);
+ qsv_packet_release(&qsv_pkt);
}
av_fifo_free(q->async_fifo);
q->async_fifo = NULL;