mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/mpegpicture: Use RefStruct-pool API
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@outlook.com>
This commit is contained in:
parent
6450cfcd10
commit
bed17eba47
|
@ -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,20 +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;
|
||||
memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size);
|
||||
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;
|
||||
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_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);
|
||||
}
|
||||
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;
|
||||
|
@ -224,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]);
|
||||
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]);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
free_picture_tables(dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -269,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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue