This is cleaner to read and less error prone. --- libavcodec/qsvenc.c | 117 +++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 61 deletions(-)
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 0c10fd45c9..0dd4b5288d 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -68,6 +68,13 @@ static const struct { #endif }; +struct QSVpacket +{ + AVPacket new_pkt; + mfxBitstream *bs; + mfxSyncPoint *syncp; +}; + static const char *print_profile(mfxU16 profile) { int i; @@ -813,8 +820,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); @@ -1063,14 +1069,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; mfxStatus ret; if (frame) { @@ -1081,29 +1092,29 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, } } - 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; - 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, NULL, 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(1); } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION); @@ -1112,9 +1123,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"); } @@ -1122,14 +1131,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; @@ -1146,57 +1151,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; } @@ -1227,17 +1228,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; -- 2.12.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel