[FFmpeg-devel] [PATCH 4/6] avcodec/qsvenc: Combine multiple allocations

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Sun Sep 26 09:40:25 EEST 2021


It makes the cleanup code smaller (and reduces the amount of
allocations).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
Better naming suggestions for the structures welcome.

One could also stop using an av_fifo altogether and use an ordinary
array (that is only allocated once) with FIFO semantics.
Or one could combine the AVPacket and the pointer to the new structure
to one structure, so that one can read and write it from/to the FIFO
in one call.

 libavcodec/qsvenc.c | 111 ++++++++++++++++++--------------------------
 1 file changed, 46 insertions(+), 65 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 26a94cd419..1650d89a17 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -111,6 +111,19 @@ static const struct {
 #endif
 };
 
+typedef struct QSVTmp {
+    mfxBitstream bs;
+    mfxSyncPoint sync;
+} QSVTmp;
+
+#if QSV_VERSION_ATLEAST(1, 26)
+typedef struct QSVH264Tmp {
+    QSVTmp common;
+    mfxExtAVCEncodedFrameInfo enc_info;
+    mfxExtBuffer *enc_buf;
+} QSVH264Tmp;
+#endif
+
 static const char *print_ratecontrol(mfxU16 rc_mode)
 {
     int i;
@@ -1110,7 +1123,7 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
 
 static inline unsigned int qsv_fifo_item_size(void)
 {
-    return sizeof(AVPacket) + sizeof(mfxSyncPoint*) + sizeof(mfxBitstream*);
+    return sizeof(AVPacket) + sizeof(QSVTmp*);
 }
 
 static inline unsigned int qsv_fifo_size(const AVFifoBuffer* fifo)
@@ -1414,16 +1427,12 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
                         const AVFrame *frame)
 {
     AVPacket new_pkt = { 0 };
-    mfxBitstream *bs = NULL;
-#if QSV_VERSION_ATLEAST(1, 26)
-    mfxExtAVCEncodedFrameInfo *enc_info = NULL;
-    mfxExtBuffer **enc_buf = NULL;
-#endif
+    QSVTmp *tmp_struct;
 
     mfxFrameSurface1 *surf = NULL;
-    mfxSyncPoint *sync     = NULL;
     QSVFrame *qsv_frame = NULL;
     mfxEncodeCtrl* enc_ctrl = NULL;
+    size_t alloc_size;
     int ret;
 
     if (frame) {
@@ -1443,34 +1452,36 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
                 enc_ctrl->FrameType |= MFX_FRAMETYPE_IDR;
         }
     }
-
     ret = av_new_packet(&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)
-        goto nomem;
-    bs->Data      = new_pkt.data;
-    bs->MaxLength = new_pkt.size;
+    alloc_size = sizeof(QSVTmp);
+#if QSV_VERSION_ATLEAST(1, 26)
+    if (avctx->codec_id == AV_CODEC_ID_H264)
+        alloc_size = sizeof(QSVH264Tmp);
+#endif
+    tmp_struct = av_mallocz(alloc_size);
+    if (!tmp_struct) {
+        ret = AVERROR(ENOMEM);
+        goto free;
+    }
+    tmp_struct->bs.Data      = new_pkt.data;
+    tmp_struct->bs.MaxLength = new_pkt.size;
 
 #if QSV_VERSION_ATLEAST(1, 26)
     if (avctx->codec_id == AV_CODEC_ID_H264) {
-        enc_info = av_mallocz(sizeof(*enc_info));
-        if (!enc_info)
-            goto nomem;
+        QSVH264Tmp *const h264_tmp_struct = (QSVH264Tmp*)tmp_struct;
+        mfxExtAVCEncodedFrameInfo *const enc_info = &h264_tmp_struct->enc_info;
+        mfxExtBuffer **const enc_buf = &h264_tmp_struct->enc_buf;
 
         enc_info->Header.BufferId = MFX_EXTBUFF_ENCODED_FRAME_INFO;
         enc_info->Header.BufferSz = sizeof (*enc_info);
-        bs->NumExtParam = 1;
-        enc_buf = av_mallocz(sizeof(mfxExtBuffer *));
-        if (!enc_buf)
-            goto nomem;
+        tmp_struct->bs.NumExtParam = 1;
         enc_buf[0] = (mfxExtBuffer *)enc_info;
 
-        bs->ExtParam = enc_buf;
+        tmp_struct->bs.ExtParam = enc_buf;
     }
 #endif
 
@@ -1478,12 +1489,9 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
         q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
     }
 
-    sync = av_mallocz(sizeof(*sync));
-    if (!sync)
-        goto nomem;
-
     do {
-        ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, sync);
+        ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf,
+                                              &tmp_struct->bs, &tmp_struct->sync);
         if (ret == MFX_WRN_DEVICE_BUSY)
             av_usleep(500);
     } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION);
@@ -1502,27 +1510,16 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
 
     ret = 0;
 
-    if (*sync) {
+    if (tmp_struct->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);
+        av_fifo_generic_write(q->async_fifo, &tmp_struct, sizeof(tmp_struct), NULL);
     } else {
 free:
-        av_freep(&sync);
+        av_freep(&tmp_struct);
         av_packet_unref(&new_pkt);
-        av_freep(&bs);
-#if QSV_VERSION_ATLEAST(1, 26)
-        if (avctx->codec_id == AV_CODEC_ID_H264) {
-            av_freep(&enc_info);
-            av_freep(&enc_buf);
-        }
-#endif
     }
 
     return ret;
-nomem:
-    ret = AVERROR(ENOMEM);
-    goto free;
 }
 
 int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
@@ -1537,20 +1534,19 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
     if ((qsv_fifo_size(q->async_fifo) >= q->async_depth) ||
         (!frame && av_fifo_size(q->async_fifo))) {
         AVPacket new_pkt;
+        QSVTmp *tmp_struct;
         mfxBitstream *bs;
-        mfxSyncPoint *sync;
 #if QSV_VERSION_ATLEAST(1, 26)
         mfxExtAVCEncodedFrameInfo *enc_info;
-        mfxExtBuffer **enc_buf;
 #endif
         enum AVPictureType pict_type;
 
         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, &tmp_struct, sizeof(tmp_struct), NULL);
+        bs = &tmp_struct->bs;
 
         do {
-            ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);
+            ret = MFXVideoCORE_SyncOperation(q->session, tmp_struct->sync, 1000);
         } while (ret == MFX_WRN_IN_EXECUTION);
 
         new_pkt.dts  = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base);
@@ -1576,16 +1572,12 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 
 #if QSV_VERSION_ATLEAST(1, 26)
         if (avctx->codec_id == AV_CODEC_ID_H264) {
-            enc_buf = bs->ExtParam;
             enc_info = (mfxExtAVCEncodedFrameInfo *)(*bs->ExtParam);
             ff_side_data_set_encoder_stats(&new_pkt,
                 enc_info->QP * FF_QP2LAMBDA, NULL, 0, pict_type);
-            av_freep(&enc_info);
-            av_freep(&enc_buf);
         }
 #endif
-        av_freep(&bs);
-        av_freep(&sync);
+        av_freep(&tmp_struct);
 
         av_packet_move_ref(pkt, &new_pkt);
 
@@ -1619,23 +1611,12 @@ 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;
+        QSVTmp *tmp_struct;
 
         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, &tmp_struct, sizeof(tmp_struct), NULL);
 
-#if QSV_VERSION_ATLEAST(1, 26)
-        if (avctx->codec_id == AV_CODEC_ID_H264) {
-            mfxExtBuffer **enc_buf = bs->ExtParam;
-            mfxExtAVCEncodedFrameInfo *enc_info = (mfxExtAVCEncodedFrameInfo *)(*bs->ExtParam);
-            av_freep(&enc_info);
-            av_freep(&enc_buf);
-        }
-#endif
-        av_freep(&sync);
-        av_freep(&bs);
+        av_freep(&tmp_struct);
         av_packet_unref(&pkt);
     }
     av_fifo_free(q->async_fifo);
-- 
2.30.2



More information about the ffmpeg-devel mailing list