History

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.

Andreas Rheinhardt committed 4 years ago

Commit bed17eb1 parent 6450cfc3 files · +53 −78Browse files

Showing the changes to libavcodec (3 of 3 files). Show all

Unified · Split

3 files
  1. libavcodec/mpegpicture.c +29 −53
  2. libavcodec/mpegpicture.h +8 −13
  3. libavcodec/mpegvideo.c +16 −12
libavcodec/mpegpicture.c+29−53
@@ -18,8 +18,6 @@ · 17 unmodified lines
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */19 */
20 20
21#include <stdint.h>
22
23#include "libavutil/avassert.h"21#include "libavutil/avassert.h"
24#include "libavutil/common.h"22#include "libavutil/common.h"
25#include "libavutil/mem.h"23#include "libavutil/mem.h"
@@ -34,13 +32,13 @@ · 8 unmodified lines
34 32
35static void av_noinline free_picture_tables(Picture *pic)33static void av_noinline free_picture_tables(Picture *pic)
36{34{
37 av_buffer_unref(&pic->mbskip_table_buf);35 ff_refstruct_unref(&pic->mbskip_table);
38 av_buffer_unref(&pic->qscale_table_buf);36 ff_refstruct_unref(&pic->qscale_table_base);
39 av_buffer_unref(&pic->mb_type_buf);37 ff_refstruct_unref(&pic->mb_type_base);
40 38
41 for (int i = 0; i < 2; i++) {39 for (int i = 0; i < 2; i++) {
42 av_buffer_unref(&pic->motion_val_buf[i]);40 ff_refstruct_unref(&pic->motion_val_base[i]);
43 av_buffer_unref(&pic->ref_index_buf[i]);41 ff_refstruct_unref(&pic->ref_index[i]);
44 }42 }
45 43
46 pic->mb_width =44 pic->mb_width =
@@ -135,18 +133,18 @@ static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic, · 88 unmodified lines
135static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic,133static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic,
136 int mb_height)134 int mb_height)
137{135{
138#define GET_BUFFER(name, idx_suffix) do { \136#define GET_BUFFER(name, buf_suffix, idx_suffix) do { \
139 pic->name ## _buf idx_suffix = av_buffer_pool_get(pools->name ## _pool); \137 pic->name ## buf_suffix idx_suffix = ff_refstruct_pool_get(pools->name ## _pool); \
140 if (!pic->name ## _buf idx_suffix) \138 if (!pic->name ## buf_suffix idx_suffix) \
141 return AVERROR(ENOMEM); \139 return AVERROR(ENOMEM); \
142} while (0)140} while (0)
143 GET_BUFFER(mbskip_table,);141 GET_BUFFER(mbskip_table,,);
144 GET_BUFFER(qscale_table,);142 GET_BUFFER(qscale_table, _base,);
145 GET_BUFFER(mb_type,);143 GET_BUFFER(mb_type, _base,);
146 if (pools->motion_val_pool) {144 if (pools->motion_val_pool) {
147 for (int i = 0; i < 2; i++) {145 for (int i = 0; i < 2; i++) {
148 GET_BUFFER(motion_val, [i]);146 GET_BUFFER(ref_index,, [i]);
149 GET_BUFFER(ref_index, [i]);147 GET_BUFFER(motion_val, _base, [i]);
150 }148 }
151 }149 }
152#undef GET_BUFFER150#undef GET_BUFFER
@@ -166,7 +164,7 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 13 unmodified lines
166 ScratchpadContext *sc, BufferPoolContext *pools,164 ScratchpadContext *sc, BufferPoolContext *pools,
167 int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize)165 int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize)
168{166{
169 int i, ret;167 int ret;
170 168
171 if (handle_pic_linesizes(avctx, pic, me, sc,169 if (handle_pic_linesizes(avctx, pic, me, sc,
172 *linesize, *uvlinesize) < 0)170 *linesize, *uvlinesize) < 0)
@@ -179,20 +177,12 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 6 unmodified lines
179 if (ret < 0)177 if (ret < 0)
180 goto fail;178 goto fail;
181 179
182 pic->mbskip_table = pic->mbskip_table_buf->data;180 pic->qscale_table = pic->qscale_table_base + 2 * pic->mb_stride + 1;
183 memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size);181 pic->mb_type = pic->mb_type_base + 2 * pic->mb_stride + 1;
184 pic->qscale_table = pic->qscale_table_buf->data + 2 * pic->mb_stride + 1;182
185 pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * pic->mb_stride + 1;183 if (pic->motion_val_base[0]) {
186 184 for (int i = 0; i < 2; i++)
187 if (pic->motion_val_buf[0]) {185 pic->motion_val[i] = pic->motion_val_base[i] + 4;
188 for (i = 0; i < 2; i++) {
189 pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
190 pic->ref_index[i] = pic->ref_index_buf[i]->data;
191 /* FIXME: The output of H.263 with OBMC depends upon
192 * the earlier content of the buffer; therefore we
193 * reset it here. */
194 memset(pic->motion_val_buf[i]->data, 0, pic->motion_val_buf[i]->size);
195 }
196 }186 }
197 187
198 return 0;188 return 0;
@@ -224,36 +214,24 @@ void ff_mpeg_unref_picture(Picture *pic) · 25 unmodified lines
224 pic->coded_picture_number = 0;214 pic->coded_picture_number = 0;
225}215}
226 216
227static int update_picture_tables(Picture *dst, const Picture *src)217static void update_picture_tables(Picture *dst, const Picture *src)
228{218{
229 int i, ret;219 ff_refstruct_replace(&dst->mbskip_table, src->mbskip_table);
230 220 ff_refstruct_replace(&dst->qscale_table_base, src->qscale_table_base);
231 ret = av_buffer_replace(&dst->mbskip_table_buf, src->mbskip_table_buf);221 ff_refstruct_replace(&dst->mb_type_base, src->mb_type_base);
232 ret |= av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf);222 for (int i = 0; i < 2; i++) {
233 ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf);223 ff_refstruct_replace(&dst->motion_val_base[i], src->motion_val_base[i]);
234 for (i = 0; i < 2; i++) {224 ff_refstruct_replace(&dst->ref_index[i], src->ref_index[i]);
235 ret |= av_buffer_replace(&dst->motion_val_buf[i], src->motion_val_buf[i]);
236 ret |= av_buffer_replace(&dst->ref_index_buf[i], src->ref_index_buf[i]);
237 }
238
239 if (ret < 0) {
240 free_picture_tables(dst);
241 return ret;
242 }225 }
243 226
244 dst->mbskip_table = src->mbskip_table;
245 dst->qscale_table = src->qscale_table;227 dst->qscale_table = src->qscale_table;
246 dst->mb_type = src->mb_type;228 dst->mb_type = src->mb_type;
247 for (i = 0; i < 2; i++) {229 for (int i = 0; i < 2; i++)
248 dst->motion_val[i] = src->motion_val[i];230 dst->motion_val[i] = src->motion_val[i];
249 dst->ref_index[i] = src->ref_index[i];
250 }
251 231
252 dst->mb_width = src->mb_width;232 dst->mb_width = src->mb_width;
253 dst->mb_height = src->mb_height;233 dst->mb_height = src->mb_height;
254 dst->mb_stride = src->mb_stride;234 dst->mb_stride = src->mb_stride;
255
256 return 0;
257}235}
258 236
259int ff_mpeg_ref_picture(Picture *dst, Picture *src)237int ff_mpeg_ref_picture(Picture *dst, Picture *src)
@@ -269,9 +247,7 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src) · 9 unmodified lines
269 if (ret < 0)247 if (ret < 0)
270 goto fail;248 goto fail;
271 249
272 ret = update_picture_tables(dst, src);250 update_picture_tables(dst, src);
273 if (ret < 0)
274 goto fail;
275 251
276 ff_refstruct_replace(&dst->hwaccel_picture_private,252 ff_refstruct_replace(&dst->hwaccel_picture_private,
277 src->hwaccel_picture_private);253 src->hwaccel_picture_private);
libavcodec/mpegpicture.h+8−13
@@ -23,9 +23,6 @@ · 22 unmodified lines
23 23
24#include <stdint.h>24#include <stdint.h>
25 25
26#include "libavutil/buffer.h"
27#include "libavutil/frame.h"
28
29#include "avcodec.h"26#include "avcodec.h"
30#include "motion_est.h"27#include "motion_est.h"
31#include "threadframe.h"28#include "threadframe.h"
@@ -43,11 +40,11 @@ typedef struct ScratchpadContext { · 11 unmodified lines
43} ScratchpadContext;40} ScratchpadContext;
44 41
45typedef struct BufferPoolContext {42typedef struct BufferPoolContext {
46 AVBufferPool *mbskip_table_pool;43 struct FFRefStructPool *mbskip_table_pool;
47 AVBufferPool *qscale_table_pool;44 struct FFRefStructPool *qscale_table_pool;
48 AVBufferPool *mb_type_pool;45 struct FFRefStructPool *mb_type_pool;
49 AVBufferPool *motion_val_pool;46 struct FFRefStructPool *motion_val_pool;
50 AVBufferPool *ref_index_pool;47 struct FFRefStructPool *ref_index_pool;
51 int alloc_mb_width; ///< mb_width used to allocate tables48 int alloc_mb_width; ///< mb_width used to allocate tables
52 int alloc_mb_height; ///< mb_height used to allocate tables49 int alloc_mb_height; ///< mb_height used to allocate tables
53 int alloc_mb_stride; ///< mb_stride used to allocate tables50 int alloc_mb_stride; ///< mb_stride used to allocate tables
@@ -60,19 +57,17 @@ typedef struct Picture { · 6 unmodified lines
60 struct AVFrame *f;57 struct AVFrame *f;
61 ThreadFrame tf;58 ThreadFrame tf;
62 59
63 AVBufferRef *qscale_table_buf;60 int8_t *qscale_table_base;
64 int8_t *qscale_table;61 int8_t *qscale_table;
65 62
66 AVBufferRef *motion_val_buf[2];63 int16_t (*motion_val_base[2])[2];
67 int16_t (*motion_val[2])[2];64 int16_t (*motion_val[2])[2];
68 65
69 AVBufferRef *mb_type_buf;66 uint32_t *mb_type_base;
70 uint32_t *mb_type; ///< types and macros are defined in mpegutils.h67 uint32_t *mb_type; ///< types and macros are defined in mpegutils.h
71 68
72 AVBufferRef *mbskip_table_buf;
73 uint8_t *mbskip_table;69 uint8_t *mbskip_table;
74 70
75 AVBufferRef *ref_index_buf[2];
76 int8_t *ref_index[2];71 int8_t *ref_index[2];
77 72
78 /// RefStruct reference for hardware accelerator private data73 /// RefStruct reference for hardware accelerator private data
libavcodec/mpegvideo.c+16−12
@@ -41,6 +41,7 @@ · 40 unmodified lines
41#include "mpegutils.h"41#include "mpegutils.h"
42#include "mpegvideo.h"42#include "mpegvideo.h"
43#include "mpegvideodata.h"43#include "mpegvideodata.h"
44#include "refstruct.h"
44 45
45static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,46static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
46 int16_t *block, int n, int qscale)47 int16_t *block, int n, int qscale)
@@ -536,11 +537,11 @@ void ff_mpv_common_defaults(MpegEncContext *s) · 489 unmodified lines
536 537
537static void free_buffer_pools(BufferPoolContext *pools)538static void free_buffer_pools(BufferPoolContext *pools)
538{539{
539 av_buffer_pool_uninit(&pools->mbskip_table_pool);540 ff_refstruct_pool_uninit(&pools->mbskip_table_pool);
540 av_buffer_pool_uninit(&pools->qscale_table_pool);541 ff_refstruct_pool_uninit(&pools->qscale_table_pool);
541 av_buffer_pool_uninit(&pools->mb_type_pool);542 ff_refstruct_pool_uninit(&pools->mb_type_pool);
542 av_buffer_pool_uninit(&pools->motion_val_pool);543 ff_refstruct_pool_uninit(&pools->motion_val_pool);
543 av_buffer_pool_uninit(&pools->ref_index_pool);544 ff_refstruct_pool_uninit(&pools->ref_index_pool);
544 pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0;545 pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0;
545}546}
546 547
@@ -641,15 +642,15 @@ int ff_mpv_init_context_frame(MpegEncContext *s) · 94 unmodified lines
641 return AVERROR(ENOMEM);642 return AVERROR(ENOMEM);
642 memset(s->mbintra_table, 1, mb_array_size);643 memset(s->mbintra_table, 1, mb_array_size);
643 644
644#define ALLOC_POOL(name, size) do { \645#define ALLOC_POOL(name, size, flags) do { \
645 pools->name ##_pool = av_buffer_pool_init((size), av_buffer_allocz); \646 pools->name ##_pool = ff_refstruct_pool_alloc((size), (flags)); \
646 if (!pools->name ##_pool) \647 if (!pools->name ##_pool) \
647 return AVERROR(ENOMEM); \648 return AVERROR(ENOMEM); \
648} while (0)649} while (0)
649 650
650 ALLOC_POOL(mbskip_table, mb_array_size + 2);651 ALLOC_POOL(mbskip_table, mb_array_size + 2, FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
651 ALLOC_POOL(qscale_table, mv_table_size);652 ALLOC_POOL(qscale_table, mv_table_size, 0);
652 ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t));653 ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t), 0);
653 654
654 if (s->out_format == FMT_H263 || s->encoding ||655 if (s->out_format == FMT_H263 || s->encoding ||
655 (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) {656 (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) {
@@ -657,8 +658,11 @@ int ff_mpv_init_context_frame(MpegEncContext *s) · 1 unmodified line
657 int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t);658 int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t);
658 int ref_index_size = 4 * mb_array_size;659 int ref_index_size = 4 * mb_array_size;
659 660
660 ALLOC_POOL(motion_val, mv_size);661 /* FIXME: The output of H.263 with OBMC depends upon
661 ALLOC_POOL(ref_index, ref_index_size);662 * the earlier content of the buffer; therefore we set
663 * the flags to always reset returned buffers here. */
664 ALLOC_POOL(motion_val, mv_size, FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
665 ALLOC_POOL(ref_index, ref_index_size, 0);
662 }666 }
663#undef ALLOC_POOL667#undef ALLOC_POOL
664 pools->alloc_mb_width = s->mb_width;668 pools->alloc_mb_width = s->mb_width;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t