[FFmpeg-devel] [PATCH 3/4] qsvenc: merge the output fifo elements into a structure

Steve Lhomme robux4 at gmail.com
Thu Sep 21 16:52:49 EEST 2017


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 772336b719..bbf72e54b0 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -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;
-- 
2.12.1



More information about the ffmpeg-devel mailing list