[FFmpeg-cvslog] avcodec/h264_picture: add ff_h264_replace_picture()

James Almer git at videolan.org
Tue Aug 10 21:18:38 EEST 2021


ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sun Aug  8 18:19:00 2021 -0300| [a2a5a579bc408cf6fae5751e6a6f2a3c820c3c30] | committer: James Almer

avcodec/h264_picture: add ff_h264_replace_picture()

Will remove unnecessary allocations when both src and dst picture contain
references to the same buffers.

Signed-off-by: James Almer <jamrial at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a2a5a579bc408cf6fae5751e6a6f2a3c820c3c30
---

 libavcodec/h264_picture.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/h264dec.h      |  1 +
 2 files changed, 45 insertions(+)

diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
index f61bdc0cbe..ff30166b4d 100644
--- a/libavcodec/h264_picture.c
+++ b/libavcodec/h264_picture.c
@@ -142,6 +142,50 @@ fail:
     return ret;
 }
 
+int ff_h264_replace_picture(H264Context *h, H264Picture *dst, const H264Picture *src)
+{
+    int ret, i;
+
+    if (!src->f || !src->f->buf[0]) {
+        ff_h264_unref_picture(h, dst);
+        return 0;
+    }
+
+    av_assert0(src->tf.f == src->f);
+
+    dst->tf.f = dst->f;
+    ff_thread_release_buffer(h->avctx, &dst->tf);
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+    ret  = av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf);
+    ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf);
+    ret |= av_buffer_replace(&dst->pps_buf, src->pps_buf);
+    if (ret < 0)
+        goto fail;
+
+    for (i = 0; i < 2; i++) {
+        ret  = av_buffer_replace(&dst->motion_val_buf[i], src->motion_val_buf[i]);
+        ret |= av_buffer_replace(&dst->ref_index_buf[i], src->ref_index_buf[i]);
+        if (ret < 0)
+            goto fail;
+    }
+
+    ret = av_buffer_replace(&dst->hwaccel_priv_buf, src->hwaccel_priv_buf);
+    if (ret < 0)
+        goto fail;
+
+    dst->hwaccel_picture_private = src->hwaccel_picture_private;
+
+    h264_copy_picture_params(dst, src);
+
+    return 0;
+fail:
+    ff_h264_unref_picture(h, dst);
+    return ret;
+}
+
 void ff_h264_set_erpic(ERPicture *dst, H264Picture *src)
 {
 #if CONFIG_ERROR_RESILIENCE
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index 8954b74795..125966aa04 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -833,6 +833,7 @@ static inline int find_start_code(const uint8_t *buf, int buf_size,
 int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup);
 
 int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src);
+int ff_h264_replace_picture(H264Context *h, H264Picture *dst, const H264Picture *src);
 void ff_h264_unref_picture(H264Context *h, H264Picture *pic);
 
 int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl);



More information about the ffmpeg-cvslog mailing list