[FFmpeg-devel] [PATCH 19/57] avcodec/mpegpicture: Use RefStruct-pool API
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Tue Apr 30 00:14:00 EEST 2024
It involves less allocations and therefore has less
potential errors to be checked. One consequence thereof
is that updating the picture tables can no longer fail.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
libavcodec/mpegpicture.c | 81 ++++++++++++++--------------------------
libavcodec/mpegpicture.h | 21 ++++-------
libavcodec/mpegvideo.c | 28 ++++++++------
3 files changed, 53 insertions(+), 77 deletions(-)
diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c
index b83fee67f8..ad6157f0c1 100644
--- a/libavcodec/mpegpicture.c
+++ b/libavcodec/mpegpicture.c
@@ -18,8 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdint.h>
-
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/mem.h"
@@ -34,13 +32,13 @@
static void av_noinline free_picture_tables(Picture *pic)
{
- av_buffer_unref(&pic->mbskip_table_buf);
- av_buffer_unref(&pic->qscale_table_buf);
- av_buffer_unref(&pic->mb_type_buf);
+ ff_refstruct_unref(&pic->mbskip_table);
+ ff_refstruct_unref(&pic->qscale_table_base);
+ ff_refstruct_unref(&pic->mb_type_base);
for (int i = 0; i < 2; i++) {
- av_buffer_unref(&pic->motion_val_buf[i]);
- av_buffer_unref(&pic->ref_index_buf[i]);
+ ff_refstruct_unref(&pic->motion_val_base[i]);
+ ff_refstruct_unref(&pic->ref_index[i]);
}
pic->mb_width =
@@ -135,18 +133,18 @@ static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic,
static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic,
int mb_height)
{
-#define GET_BUFFER(name, idx_suffix) do { \
- pic->name ## _buf idx_suffix = av_buffer_pool_get(pools->name ## _pool); \
- if (!pic->name ## _buf idx_suffix) \
+#define GET_BUFFER(name, buf_suffix, idx_suffix) do { \
+ pic->name ## buf_suffix idx_suffix = ff_refstruct_pool_get(pools->name ## _pool); \
+ if (!pic->name ## buf_suffix idx_suffix) \
return AVERROR(ENOMEM); \
} while (0)
- GET_BUFFER(mbskip_table,);
- GET_BUFFER(qscale_table,);
- GET_BUFFER(mb_type,);
+ GET_BUFFER(mbskip_table,,);
+ GET_BUFFER(qscale_table, _base,);
+ GET_BUFFER(mb_type, _base,);
if (pools->motion_val_pool) {
for (int i = 0; i < 2; i++) {
- GET_BUFFER(motion_val, [i]);
- GET_BUFFER(ref_index, [i]);
+ GET_BUFFER(ref_index,, [i]);
+ GET_BUFFER(motion_val, _base, [i]);
}
}
#undef GET_BUFFER
@@ -166,7 +164,7 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
ScratchpadContext *sc, BufferPoolContext *pools,
int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize)
{
- int i, ret;
+ int ret;
if (handle_pic_linesizes(avctx, pic, me, sc,
*linesize, *uvlinesize) < 0)
@@ -179,19 +177,12 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
if (ret < 0)
goto fail;
- pic->mbskip_table = pic->mbskip_table_buf->data;
- pic->qscale_table = pic->qscale_table_buf->data + 2 * pic->mb_stride + 1;
- pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * pic->mb_stride + 1;
-
- if (pic->motion_val_buf[0]) {
- for (i = 0; i < 2; i++) {
- pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
- pic->ref_index[i] = pic->ref_index_buf[i]->data;
- /* FIXME: The output of H.263 with OBMC depends upon
- * the earlier content of the buffer; therefore we
- * reset it here. */
- memset(pic->motion_val_buf[i]->data, 0, pic->motion_val_buf[i]->size);
- }
+ pic->qscale_table = pic->qscale_table_base + 2 * pic->mb_stride + 1;
+ pic->mb_type = pic->mb_type_base + 2 * pic->mb_stride + 1;
+
+ if (pic->motion_val_base[0]) {
+ for (int i = 0; i < 2; i++)
+ pic->motion_val[i] = pic->motion_val_base[i] + 4;
}
return 0;
@@ -223,36 +214,24 @@ void ff_mpeg_unref_picture(Picture *pic)
pic->coded_picture_number = 0;
}
-static int update_picture_tables(Picture *dst, const Picture *src)
+static void update_picture_tables(Picture *dst, const Picture *src)
{
- int i, ret;
-
- ret = av_buffer_replace(&dst->mbskip_table_buf, src->mbskip_table_buf);
- ret |= av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf);
- ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf);
- 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) {
- free_picture_tables(dst);
- return ret;
+ ff_refstruct_replace(&dst->mbskip_table, src->mbskip_table);
+ ff_refstruct_replace(&dst->qscale_table_base, src->qscale_table_base);
+ ff_refstruct_replace(&dst->mb_type_base, src->mb_type_base);
+ for (int i = 0; i < 2; i++) {
+ ff_refstruct_replace(&dst->motion_val_base[i], src->motion_val_base[i]);
+ ff_refstruct_replace(&dst->ref_index[i], src->ref_index[i]);
}
- dst->mbskip_table = src->mbskip_table;
dst->qscale_table = src->qscale_table;
dst->mb_type = src->mb_type;
- for (i = 0; i < 2; i++) {
+ for (int i = 0; i < 2; i++)
dst->motion_val[i] = src->motion_val[i];
- dst->ref_index[i] = src->ref_index[i];
- }
dst->mb_width = src->mb_width;
dst->mb_height = src->mb_height;
dst->mb_stride = src->mb_stride;
-
- return 0;
}
int ff_mpeg_ref_picture(Picture *dst, Picture *src)
@@ -268,9 +247,7 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src)
if (ret < 0)
goto fail;
- ret = update_picture_tables(dst, src);
- if (ret < 0)
- goto fail;
+ update_picture_tables(dst, src);
ff_refstruct_replace(&dst->hwaccel_picture_private,
src->hwaccel_picture_private);
diff --git a/libavcodec/mpegpicture.h b/libavcodec/mpegpicture.h
index a0bfd8250f..363732910a 100644
--- a/libavcodec/mpegpicture.h
+++ b/libavcodec/mpegpicture.h
@@ -23,9 +23,6 @@
#include <stdint.h>
-#include "libavutil/buffer.h"
-#include "libavutil/frame.h"
-
#include "avcodec.h"
#include "motion_est.h"
#include "threadframe.h"
@@ -43,11 +40,11 @@ typedef struct ScratchpadContext {
} ScratchpadContext;
typedef struct BufferPoolContext {
- AVBufferPool *mbskip_table_pool;
- AVBufferPool *qscale_table_pool;
- AVBufferPool *mb_type_pool;
- AVBufferPool *motion_val_pool;
- AVBufferPool *ref_index_pool;
+ struct FFRefStructPool *mbskip_table_pool;
+ struct FFRefStructPool *qscale_table_pool;
+ struct FFRefStructPool *mb_type_pool;
+ struct FFRefStructPool *motion_val_pool;
+ struct FFRefStructPool *ref_index_pool;
int alloc_mb_width; ///< mb_width used to allocate tables
int alloc_mb_height; ///< mb_height used to allocate tables
int alloc_mb_stride; ///< mb_stride used to allocate tables
@@ -60,19 +57,17 @@ typedef struct Picture {
struct AVFrame *f;
ThreadFrame tf;
- AVBufferRef *qscale_table_buf;
+ int8_t *qscale_table_base;
int8_t *qscale_table;
- AVBufferRef *motion_val_buf[2];
+ int16_t (*motion_val_base[2])[2];
int16_t (*motion_val[2])[2];
- AVBufferRef *mb_type_buf;
+ uint32_t *mb_type_base;
uint32_t *mb_type; ///< types and macros are defined in mpegutils.h
- AVBufferRef *mbskip_table_buf;
uint8_t *mbskip_table;
- AVBufferRef *ref_index_buf[2];
int8_t *ref_index[2];
/// RefStruct reference for hardware accelerator private data
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 5728f4cee3..487ffa41fd 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -41,6 +41,7 @@
#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpegvideodata.h"
+#include "refstruct.h"
static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
int16_t *block, int n, int qscale)
@@ -536,11 +537,11 @@ void ff_mpv_common_defaults(MpegEncContext *s)
static void free_buffer_pools(BufferPoolContext *pools)
{
- av_buffer_pool_uninit(&pools->mbskip_table_pool);
- av_buffer_pool_uninit(&pools->qscale_table_pool);
- av_buffer_pool_uninit(&pools->mb_type_pool);
- av_buffer_pool_uninit(&pools->motion_val_pool);
- av_buffer_pool_uninit(&pools->ref_index_pool);
+ ff_refstruct_pool_uninit(&pools->mbskip_table_pool);
+ ff_refstruct_pool_uninit(&pools->qscale_table_pool);
+ ff_refstruct_pool_uninit(&pools->mb_type_pool);
+ ff_refstruct_pool_uninit(&pools->motion_val_pool);
+ ff_refstruct_pool_uninit(&pools->ref_index_pool);
pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0;
}
@@ -641,15 +642,15 @@ int ff_mpv_init_context_frame(MpegEncContext *s)
return AVERROR(ENOMEM);
memset(s->mbintra_table, 1, mb_array_size);
-#define ALLOC_POOL(name, size) do { \
- pools->name ##_pool = av_buffer_pool_init((size), av_buffer_allocz); \
+#define ALLOC_POOL(name, size, flags) do { \
+ pools->name ##_pool = ff_refstruct_pool_alloc((size), (flags)); \
if (!pools->name ##_pool) \
return AVERROR(ENOMEM); \
} while (0)
- ALLOC_POOL(mbskip_table, mb_array_size + 2);
- ALLOC_POOL(qscale_table, mv_table_size);
- ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t));
+ ALLOC_POOL(mbskip_table, mb_array_size + 2, 0);
+ ALLOC_POOL(qscale_table, mv_table_size, 0);
+ ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t), 0);
if (s->out_format == FMT_H263 || s->encoding ||
(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) {
@@ -657,8 +658,11 @@ int ff_mpv_init_context_frame(MpegEncContext *s)
int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t);
int ref_index_size = 4 * mb_array_size;
- ALLOC_POOL(motion_val, mv_size);
- ALLOC_POOL(ref_index, ref_index_size);
+ /* FIXME: The output of H.263 with OBMC depends upon
+ * the earlier content of the buffer; therefore we set
+ * the flags to always reset returned buffers here. */
+ ALLOC_POOL(motion_val, mv_size, FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
+ ALLOC_POOL(ref_index, ref_index_size, 0);
}
#undef ALLOC_POOL
pools->alloc_mb_width = s->mb_width;
--
2.40.1
More information about the ffmpeg-devel
mailing list