avcodec/mpegvideo, mpegpicture: Add buffer pool

This avoids constant allocations+frees and will also allow
to simply switch to the RefStruct API, thereby avoiding
the overhead of the AVBuffer API.
It also simplifies the code, because it removes the "needs_realloc"
field: It was added in 435c0b87d2,
before the introduction of the AVBuffer API: given that these buffers
may be used by different threads, they were not freed immediately
and instead were marked as being freed later by setting needs_realloc.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
release/7.1
Andreas Rheinhardt 3 years ago
parent a95591dbfd
commit 788892d647
  1. 155
      libavcodec/mpegpicture.c
  2. 27
      libavcodec/mpegpicture.h
  3. 37
      libavcodec/mpegvideo.c
  4. 2
      libavcodec/mpegvideo.h
  5. 35
      libavcodec/mpegvideo_dec.c
  6. 13
      libavcodec/mpegvideo_enc.c

@ -29,15 +29,11 @@
#include "avcodec.h" #include "avcodec.h"
#include "motion_est.h" #include "motion_est.h"
#include "mpegpicture.h" #include "mpegpicture.h"
#include "mpegvideo.h"
#include "refstruct.h" #include "refstruct.h"
#include "threadframe.h" #include "threadframe.h"
static void av_noinline free_picture_tables(Picture *pic) static void av_noinline free_picture_tables(Picture *pic)
{ {
pic->alloc_mb_width =
pic->alloc_mb_height = 0;
av_buffer_unref(&pic->mbskip_table_buf); av_buffer_unref(&pic->mbskip_table_buf);
av_buffer_unref(&pic->qscale_table_buf); av_buffer_unref(&pic->qscale_table_buf);
av_buffer_unref(&pic->mb_type_buf); av_buffer_unref(&pic->mb_type_buf);
@ -46,43 +42,9 @@ static void av_noinline free_picture_tables(Picture *pic)
av_buffer_unref(&pic->motion_val_buf[i]); av_buffer_unref(&pic->motion_val_buf[i]);
av_buffer_unref(&pic->ref_index_buf[i]); av_buffer_unref(&pic->ref_index_buf[i]);
} }
}
static int make_table_writable(AVBufferRef **ref)
{
AVBufferRef *old = *ref, *new;
if (av_buffer_is_writable(old))
return 0;
new = av_buffer_allocz(old->size);
if (!new)
return AVERROR(ENOMEM);
av_buffer_unref(ref);
*ref = new;
return 0;
}
static int make_tables_writable(Picture *pic)
{
#define MAKE_WRITABLE(table) \
do {\
int ret = make_table_writable(&pic->table); \
if (ret < 0) \
return ret; \
} while (0)
MAKE_WRITABLE(mbskip_table_buf);
MAKE_WRITABLE(qscale_table_buf);
MAKE_WRITABLE(mb_type_buf);
if (pic->motion_val_buf[0]) {
for (int i = 0; i < 2; i++) {
MAKE_WRITABLE(motion_val_buf[i]);
MAKE_WRITABLE(ref_index_buf[i]);
}
}
return 0; pic->mb_width =
pic->mb_height = 0;
} }
int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
@ -170,38 +132,28 @@ static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic,
return 0; return 0;
} }
static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encoding, int out_format, static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic,
int mb_stride, int mb_width, int mb_height, int b8_stride) int mb_height)
{ {
const int big_mb_num = mb_stride * (mb_height + 1) + 1; #define GET_BUFFER(name, idx_suffix) do { \
const int mb_array_size = mb_stride * mb_height; pic->name ## _buf idx_suffix = av_buffer_pool_get(pools->name ## _pool); \
const int b8_array_size = b8_stride * mb_height * 2; if (!pic->name ## _buf idx_suffix) \
int i; return AVERROR(ENOMEM); \
} while (0)
GET_BUFFER(mbskip_table,);
pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); GET_BUFFER(qscale_table,);
pic->qscale_table_buf = av_buffer_allocz(big_mb_num + mb_stride); GET_BUFFER(mb_type,);
pic->mb_type_buf = av_buffer_allocz((big_mb_num + mb_stride) * if (pools->motion_val_pool) {
sizeof(uint32_t)); for (int i = 0; i < 2; i++) {
if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) GET_BUFFER(motion_val, [i]);
return AVERROR(ENOMEM); GET_BUFFER(ref_index, [i]);
if (out_format == FMT_H263 || encoding ||
(avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) {
int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t);
int ref_index_size = 4 * mb_array_size;
for (i = 0; mv_size && i < 2; i++) {
pic->motion_val_buf[i] = av_buffer_allocz(mv_size);
pic->ref_index_buf[i] = av_buffer_allocz(ref_index_size);
if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
return AVERROR(ENOMEM);
} }
} }
#undef GET_BUFFER
pic->alloc_mb_width = mb_width; pic->mb_width = pools->alloc_mb_width;
pic->alloc_mb_height = mb_height; pic->mb_height = mb_height;
pic->alloc_mb_stride = mb_stride; pic->mb_stride = pools->alloc_mb_stride;
return 0; return 0;
} }
@ -211,17 +163,11 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin
* The pixels are allocated/set by calling get_buffer() if shared = 0 * The pixels are allocated/set by calling get_buffer() if shared = 0
*/ */
int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
ScratchpadContext *sc, int encoding, int out_format, ScratchpadContext *sc, BufferPoolContext *pools,
int mb_stride, int mb_width, int mb_height, int b8_stride, int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize)
ptrdiff_t *linesize, ptrdiff_t *uvlinesize)
{ {
int i, ret; int i, ret;
if (pic->qscale_table_buf)
if ( pic->alloc_mb_width != mb_width
|| pic->alloc_mb_height != mb_height)
free_picture_tables(pic);
if (handle_pic_linesizes(avctx, pic, me, sc, if (handle_pic_linesizes(avctx, pic, me, sc,
*linesize, *uvlinesize) < 0) *linesize, *uvlinesize) < 0)
return -1; return -1;
@ -229,18 +175,14 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
*linesize = pic->f->linesize[0]; *linesize = pic->f->linesize[0];
*uvlinesize = pic->f->linesize[1]; *uvlinesize = pic->f->linesize[1];
if (!pic->qscale_table_buf) ret = alloc_picture_tables(pools, pic, mb_height);
ret = alloc_picture_tables(avctx, pic, encoding, out_format,
mb_stride, mb_width, mb_height, b8_stride);
else
ret = make_tables_writable(pic);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
pic->mbskip_table = pic->mbskip_table_buf->data; pic->mbskip_table = pic->mbskip_table_buf->data;
memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size); memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size);
pic->qscale_table = pic->qscale_table_buf->data + 2 * mb_stride + 1; pic->qscale_table = pic->qscale_table_buf->data + 2 * pic->mb_stride + 1;
pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * mb_stride + 1; pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * pic->mb_stride + 1;
if (pic->motion_val_buf[0]) { if (pic->motion_val_buf[0]) {
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
@ -257,7 +199,6 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
fail: fail:
av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n");
ff_mpeg_unref_picture(pic); ff_mpeg_unref_picture(pic);
free_picture_tables(pic);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
@ -272,20 +213,18 @@ void ff_mpeg_unref_picture(Picture *pic)
ff_refstruct_unref(&pic->hwaccel_picture_private); ff_refstruct_unref(&pic->hwaccel_picture_private);
if (pic->needs_realloc) free_picture_tables(pic);
free_picture_tables(pic);
pic->dummy = 0; pic->dummy = 0;
pic->field_picture = 0; pic->field_picture = 0;
pic->b_frame_score = 0; pic->b_frame_score = 0;
pic->needs_realloc = 0;
pic->reference = 0; pic->reference = 0;
pic->shared = 0; pic->shared = 0;
pic->display_picture_number = 0; pic->display_picture_number = 0;
pic->coded_picture_number = 0; pic->coded_picture_number = 0;
} }
int ff_update_picture_tables(Picture *dst, const Picture *src) static int update_picture_tables(Picture *dst, const Picture *src)
{ {
int i, ret; int i, ret;
@ -310,9 +249,9 @@ int ff_update_picture_tables(Picture *dst, const Picture *src)
dst->ref_index[i] = src->ref_index[i]; dst->ref_index[i] = src->ref_index[i];
} }
dst->alloc_mb_width = src->alloc_mb_width; dst->mb_width = src->mb_width;
dst->alloc_mb_height = src->alloc_mb_height; dst->mb_height = src->mb_height;
dst->alloc_mb_stride = src->alloc_mb_stride; dst->mb_stride = src->mb_stride;
return 0; return 0;
} }
@ -330,7 +269,7 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src)
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ret = ff_update_picture_tables(dst, src); ret = update_picture_tables(dst, src);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
@ -340,7 +279,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src)
dst->dummy = src->dummy; dst->dummy = src->dummy;
dst->field_picture = src->field_picture; dst->field_picture = src->field_picture;
dst->b_frame_score = src->b_frame_score; dst->b_frame_score = src->b_frame_score;
dst->needs_realloc = src->needs_realloc;
dst->reference = src->reference; dst->reference = src->reference;
dst->shared = src->shared; dst->shared = src->shared;
dst->display_picture_number = src->display_picture_number; dst->display_picture_number = src->display_picture_number;
@ -352,30 +290,14 @@ fail:
return ret; return ret;
} }
static inline int pic_is_unused(Picture *pic) int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared)
{
if (!pic->f->buf[0])
return 1;
if (pic->needs_realloc)
return 1;
return 0;
}
static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared)
{ {
int i; int i;
if (shared) {
for (i = 0; i < MAX_PICTURE_COUNT; i++) { for (i = 0; i < MAX_PICTURE_COUNT; i++) {
if (!picture[i].f->buf[0]) if (!picture[i].f->buf[0])
return i; return i;
} }
} else {
for (i = 0; i < MAX_PICTURE_COUNT; i++) {
if (pic_is_unused(&picture[i]))
return i;
}
}
av_log(avctx, AV_LOG_FATAL, av_log(avctx, AV_LOG_FATAL,
"Internal error, picture buffer overflow\n"); "Internal error, picture buffer overflow\n");
@ -394,21 +316,8 @@ static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shar
return -1; return -1;
} }
int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared)
{
int ret = find_unused_picture(avctx, picture, shared);
if (ret >= 0 && ret < MAX_PICTURE_COUNT) {
if (picture[ret].needs_realloc) {
ff_mpeg_unref_picture(&picture[ret]);
}
}
return ret;
}
void av_cold ff_mpv_picture_free(Picture *pic) void av_cold ff_mpv_picture_free(Picture *pic)
{ {
free_picture_tables(pic);
ff_mpeg_unref_picture(pic); ff_mpeg_unref_picture(pic);
av_frame_free(&pic->f); av_frame_free(&pic->f);
} }

@ -23,6 +23,7 @@
#include <stdint.h> #include <stdint.h>
#include "libavutil/buffer.h"
#include "libavutil/frame.h" #include "libavutil/frame.h"
#include "avcodec.h" #include "avcodec.h"
@ -41,6 +42,17 @@ typedef struct ScratchpadContext {
int linesize; ///< linesize that the buffers in this context have been allocated for int linesize; ///< linesize that the buffers in this context have been allocated for
} 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;
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
} BufferPoolContext;
/** /**
* Picture. * Picture.
*/ */
@ -63,18 +75,17 @@ typedef struct Picture {
AVBufferRef *ref_index_buf[2]; AVBufferRef *ref_index_buf[2];
int8_t *ref_index[2]; int8_t *ref_index[2];
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
/// RefStruct reference for hardware accelerator private data /// RefStruct reference for hardware accelerator private data
void *hwaccel_picture_private; void *hwaccel_picture_private;
int mb_width; ///< mb_width of the tables
int mb_height; ///< mb_height of the tables
int mb_stride; ///< mb_stride of the tables
int dummy; ///< Picture is a dummy and should not be output int dummy; ///< Picture is a dummy and should not be output
int field_picture; ///< whether or not the picture was encoded in separate fields int field_picture; ///< whether or not the picture was encoded in separate fields
int b_frame_score; int b_frame_score;
int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change)
int reference; int reference;
int shared; int shared;
@ -87,9 +98,8 @@ typedef struct Picture {
* Allocate a Picture's accessories, but not the AVFrame's buffer itself. * Allocate a Picture's accessories, but not the AVFrame's buffer itself.
*/ */
int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
ScratchpadContext *sc, int encoding, int out_format, ScratchpadContext *sc, BufferPoolContext *pools,
int mb_stride, int mb_width, int mb_height, int b8_stride, int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize);
ptrdiff_t *linesize, ptrdiff_t *uvlinesize);
int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
ScratchpadContext *sc, int linesize); ScratchpadContext *sc, int linesize);
@ -98,7 +108,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src);
void ff_mpeg_unref_picture(Picture *picture); void ff_mpeg_unref_picture(Picture *picture);
void ff_mpv_picture_free(Picture *pic); void ff_mpv_picture_free(Picture *pic);
int ff_update_picture_tables(Picture *dst, const Picture *src);
int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared); int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared);

@ -534,8 +534,19 @@ void ff_mpv_common_defaults(MpegEncContext *s)
s->slice_context_count = 1; s->slice_context_count = 1;
} }
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);
pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0;
}
int ff_mpv_init_context_frame(MpegEncContext *s) int ff_mpv_init_context_frame(MpegEncContext *s)
{ {
BufferPoolContext *const pools = &s->buffer_pools;
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
int mb_height; int mb_height;
@ -630,11 +641,36 @@ int ff_mpv_init_context_frame(MpegEncContext *s)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
memset(s->mbintra_table, 1, mb_array_size); 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); \
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));
if (s->out_format == FMT_H263 || s->encoding ||
(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) {
const int b8_array_size = s->b8_stride * mb_height * 2;
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);
}
#undef ALLOC_POOL
pools->alloc_mb_width = s->mb_width;
pools->alloc_mb_height = mb_height;
pools->alloc_mb_stride = s->mb_stride;
return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s); return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s);
} }
static void clear_context(MpegEncContext *s) static void clear_context(MpegEncContext *s)
{ {
memset(&s->buffer_pools, 0, sizeof(s->buffer_pools));
memset(&s->next_picture, 0, sizeof(s->next_picture)); memset(&s->next_picture, 0, sizeof(s->next_picture));
memset(&s->last_picture, 0, sizeof(s->last_picture)); memset(&s->last_picture, 0, sizeof(s->last_picture));
memset(&s->current_picture, 0, sizeof(s->current_picture)); memset(&s->current_picture, 0, sizeof(s->current_picture));
@ -762,6 +798,7 @@ void ff_mpv_free_context_frame(MpegEncContext *s)
{ {
free_duplicate_contexts(s); free_duplicate_contexts(s);
free_buffer_pools(&s->buffer_pools);
av_freep(&s->p_field_mv_table_base); av_freep(&s->p_field_mv_table_base);
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)

@ -132,6 +132,8 @@ typedef struct MpegEncContext {
Picture **input_picture; ///< next pictures on display order for encoding Picture **input_picture; ///< next pictures on display order for encoding
Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding
BufferPoolContext buffer_pools;
int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame() int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame()
/** /**
* pts difference between the first and second input frame, used for * pts difference between the first and second input frame, used for

@ -115,12 +115,11 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
#define UPDATE_PICTURE(pic)\ #define UPDATE_PICTURE(pic)\
do {\ do {\
ff_mpeg_unref_picture(&s->pic);\ ff_mpeg_unref_picture(&s->pic);\
if (s1->pic.f && s1->pic.f->buf[0])\ if (s1->pic.f && s1->pic.f->buf[0]) {\
ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\ ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\
else\ if (ret < 0)\
ret = ff_update_picture_tables(&s->pic, &s1->pic);\ return ret;\
if (ret < 0)\ }\
return ret;\
} while (0) } while (0)
UPDATE_PICTURE(current_picture); UPDATE_PICTURE(current_picture);
@ -194,10 +193,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
ff_mpv_free_context_frame(s); ff_mpv_free_context_frame(s);
if (s->picture)
for (int i = 0; i < MAX_PICTURE_COUNT; i++)
s->picture[i].needs_realloc = 1;
s->last_picture_ptr = s->last_picture_ptr =
s->next_picture_ptr = s->next_picture_ptr =
s->current_picture_ptr = NULL; s->current_picture_ptr = NULL;
@ -268,9 +263,12 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference)
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ret = ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 0, s->out_format, av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width);
s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height ||
&s->linesize, &s->uvlinesize); FFALIGN(s->mb_height, 2) == s->buffer_pools.alloc_mb_height);
av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
ret = ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools,
s->mb_height, &s->linesize, &s->uvlinesize);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
*picp = pic; *picp = pic;
@ -388,8 +386,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
for (int i = 0; i < MAX_PICTURE_COUNT; i++) { for (int i = 0; i < MAX_PICTURE_COUNT; i++) {
if (!s->picture[i].reference || if (!s->picture[i].reference ||
(&s->picture[i] != s->last_picture_ptr && (&s->picture[i] != s->last_picture_ptr &&
&s->picture[i] != s->next_picture_ptr && &s->picture[i] != s->next_picture_ptr)) {
!s->picture[i].needs_realloc)) {
ff_mpeg_unref_picture(&s->picture[i]); ff_mpeg_unref_picture(&s->picture[i]);
} }
} }
@ -487,7 +484,7 @@ int ff_mpv_export_qp_table(const MpegEncContext *s, AVFrame *f, const Picture *p
{ {
AVVideoEncParams *par; AVVideoEncParams *par;
int mult = (qp_type == FF_MPV_QSCALE_TYPE_MPEG1) ? 2 : 1; int mult = (qp_type == FF_MPV_QSCALE_TYPE_MPEG1) ? 2 : 1;
unsigned int nb_mb = p->alloc_mb_height * p->alloc_mb_width; unsigned int nb_mb = p->mb_height * p->mb_width;
if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS)) if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS))
return 0; return 0;
@ -496,10 +493,10 @@ int ff_mpv_export_qp_table(const MpegEncContext *s, AVFrame *f, const Picture *p
if (!par) if (!par)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
for (unsigned y = 0; y < p->alloc_mb_height; y++) for (unsigned y = 0; y < p->mb_height; y++)
for (unsigned x = 0; x < p->alloc_mb_width; x++) { for (unsigned x = 0; x < p->mb_width; x++) {
const unsigned int block_idx = y * p->alloc_mb_width + x; const unsigned int block_idx = y * p->mb_width + x;
const unsigned int mb_xy = y * p->alloc_mb_stride + x; const unsigned int mb_xy = y * p->mb_stride + x;
AVVideoBlockParams *const b = av_video_enc_params_block(par, block_idx); AVVideoBlockParams *const b = av_video_enc_params_block(par, block_idx);
b->src_x = x * 16; b->src_x = x * 16;

@ -1112,9 +1112,11 @@ static int alloc_picture(MpegEncContext *s, Picture *pic)
pic->f->width = avctx->width; pic->f->width = avctx->width;
pic->f->height = avctx->height; pic->f->height = avctx->height;
return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 1, s->out_format, av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width);
s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height);
&s->linesize, &s->uvlinesize); av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools,
s->mb_height, &s->linesize, &s->uvlinesize);
} }
static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
@ -1480,7 +1482,7 @@ static int select_input_picture(MpegEncContext *s)
s->next_picture_ptr && s->next_picture_ptr &&
skip_check(s, s->input_picture[0], s->next_picture_ptr)) { skip_check(s, s->input_picture[0], s->next_picture_ptr)) {
// FIXME check that the gop check above is +-1 correct // FIXME check that the gop check above is +-1 correct
av_frame_unref(s->input_picture[0]->f); ff_mpeg_unref_picture(s->input_picture[0]);
ff_vbv_update(s, 0); ff_vbv_update(s, 0);
@ -1627,8 +1629,7 @@ no_output_pic:
pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number; pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number;
/* mark us unused / free shared pic */ /* mark us unused / free shared pic */
av_frame_unref(s->reordered_input_picture[0]->f); ff_mpeg_unref_picture(s->reordered_input_picture[0]);
s->reordered_input_picture[0]->shared = 0;
s->current_picture_ptr = pic; s->current_picture_ptr = pic;
} else { } else {

Loading…
Cancel
Save