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 435c0b87d28b48dc2e0360adc404a0e2d66d16a0, 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.
Unified · Split
| @@ -29,15 +29,11 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "avcodec.h" |
| 30 | 30 | #include "motion_est.h" |
| 31 | 31 | #include "mpegpicture.h" |
| 32 | −#include "mpegvideo.h" | |
| 33 | 32 | #include "refstruct.h" |
| 34 | 33 | #include "threadframe.h" |
| 35 | 34 | |
| 36 | 35 | static void av_noinline free_picture_tables(Picture *pic) |
| 37 | 36 | { |
| 38 | − pic->alloc_mb_width = | |
| 39 | − pic->alloc_mb_height = 0; | |
| 40 | − | |
| 41 | 37 | av_buffer_unref(&pic->mbskip_table_buf); |
| 42 | 38 | av_buffer_unref(&pic->qscale_table_buf); |
| 43 | 39 | av_buffer_unref(&pic->mb_type_buf); |
| @@ -46,43 +42,9 @@ static void av_noinline free_picture_tables(Picture *pic) · 2 unmodified lines | ||
| 46 | 42 | av_buffer_unref(&pic->motion_val_buf[i]); |
| 47 | 43 | av_buffer_unref(&pic->ref_index_buf[i]); |
| 48 | 44 | } |
| 49 | −} | |
| 50 | − | |
| 51 | −static int make_table_writable(AVBufferRef **ref) | |
| 52 | −{ | |
| 53 | − AVBufferRef *old = *ref, *new; | |
| 54 | − | |
| 55 | − if (av_buffer_is_writable(old)) | |
| 56 | − return 0; | |
| 57 | − new = av_buffer_allocz(old->size); | |
| 58 | − if (!new) | |
| 59 | − return AVERROR(ENOMEM); | |
| 60 | − av_buffer_unref(ref); | |
| 61 | − *ref = new; | |
| 62 | − return 0; | |
| 63 | −} | |
| 64 | − | |
| 65 | −static int make_tables_writable(Picture *pic) | |
| 66 | −{ | |
| 67 | −#define MAKE_WRITABLE(table) \ | |
| 68 | −do {\ | |
| 69 | − int ret = make_table_writable(&pic->table); \ | |
| 70 | − if (ret < 0) \ | |
| 71 | − return ret; \ | |
| 72 | −} while (0) | |
| 73 | − | |
| 74 | − MAKE_WRITABLE(mbskip_table_buf); | |
| 75 | − MAKE_WRITABLE(qscale_table_buf); | |
| 76 | − MAKE_WRITABLE(mb_type_buf); | |
| 77 | − | |
| 78 | − if (pic->motion_val_buf[0]) { | |
| 79 | − for (int i = 0; i < 2; i++) { | |
| 80 | − MAKE_WRITABLE(motion_val_buf[i]); | |
| 81 | − MAKE_WRITABLE(ref_index_buf[i]); | |
| 82 | − } | |
| 83 | − } | |
| 84 | 45 | |
| 85 | − return 0; | |
| 46 | + pic->mb_width = | |
| 47 | + pic->mb_height = 0; | |
| 86 | 48 | } |
| 87 | 49 | |
| 88 | 50 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
| @@ -170,38 +132,28 @@ static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic, · 81 unmodified lines | ||
| 170 | 132 | return 0; |
| 171 | 133 | } |
| 172 | 134 | |
| 173 | −static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encoding, int out_format, | |
| 174 | − int mb_stride, int mb_width, int mb_height, int b8_stride) | |
| 135 | +static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic, | |
| 136 | + int mb_height) | |
| 175 | 137 | { |
| 176 | − const int big_mb_num = mb_stride * (mb_height + 1) + 1; | |
| 177 | − const int mb_array_size = mb_stride * mb_height; | |
| 178 | − const int b8_array_size = b8_stride * mb_height * 2; | |
| 179 | − int i; | |
| 180 | − | |
| 181 | − | |
| 182 | − pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); | |
| 183 | − pic->qscale_table_buf = av_buffer_allocz(big_mb_num + mb_stride); | |
| 184 | − pic->mb_type_buf = av_buffer_allocz((big_mb_num + mb_stride) * | |
| 185 | − sizeof(uint32_t)); | |
| 186 | − if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) | |
| 187 | − return AVERROR(ENOMEM); | |
| 188 | − | |
| 189 | − if (out_format == FMT_H263 || encoding || | |
| 190 | − (avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) { | |
| 191 | − int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); | |
| 192 | − int ref_index_size = 4 * mb_array_size; | |
| 193 | − | |
| 194 | − for (i = 0; mv_size && i < 2; i++) { | |
| 195 | − pic->motion_val_buf[i] = av_buffer_allocz(mv_size); | |
| 196 | − pic->ref_index_buf[i] = av_buffer_allocz(ref_index_size); | |
| 197 | − if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) | |
| 198 | − return AVERROR(ENOMEM); | |
| 138 | +#define GET_BUFFER(name, idx_suffix) do { \ | |
| 139 | + pic->name ## _buf idx_suffix = av_buffer_pool_get(pools->name ## _pool); \ | |
| 140 | + if (!pic->name ## _buf idx_suffix) \ | |
| 141 | + return AVERROR(ENOMEM); \ | |
| 142 | +} while (0) | |
| 143 | + GET_BUFFER(mbskip_table,); | |
| 144 | + GET_BUFFER(qscale_table,); | |
| 145 | + GET_BUFFER(mb_type,); | |
| 146 | + if (pools->motion_val_pool) { | |
| 147 | + for (int i = 0; i < 2; i++) { | |
| 148 | + GET_BUFFER(motion_val, [i]); | |
| 149 | + GET_BUFFER(ref_index, [i]); | |
| 199 | 150 | } |
| 200 | 151 | } |
| 152 | +#undef GET_BUFFER | |
| 201 | 153 | |
| 202 | − pic->alloc_mb_width = mb_width; | |
| 203 | − pic->alloc_mb_height = mb_height; | |
| 204 | − pic->alloc_mb_stride = mb_stride; | |
| 154 | + pic->mb_width = pools->alloc_mb_width; | |
| 155 | + pic->mb_height = mb_height; | |
| 156 | + pic->mb_stride = pools->alloc_mb_stride; | |
| 205 | 157 | |
| 206 | 158 | return 0; |
| 207 | 159 | } |
| @@ -211,17 +163,11 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin · 3 unmodified lines | ||
| 211 | 163 | * The pixels are allocated/set by calling get_buffer() if shared = 0 |
| 212 | 164 | */ |
| 213 | 165 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, |
| 214 | − ScratchpadContext *sc, int encoding, int out_format, | |
| 215 | − int mb_stride, int mb_width, int mb_height, int b8_stride, | |
| 216 | − ptrdiff_t *linesize, ptrdiff_t *uvlinesize) | |
| 166 | + ScratchpadContext *sc, BufferPoolContext *pools, | |
| 167 | + int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize) | |
| 217 | 168 | { |
| 218 | 169 | int i, ret; |
| 219 | 170 | |
| 220 | − if (pic->qscale_table_buf) | |
| 221 | − if ( pic->alloc_mb_width != mb_width | |
| 222 | − || pic->alloc_mb_height != mb_height) | |
| 223 | − free_picture_tables(pic); | |
| 224 | − | |
| 225 | 171 | if (handle_pic_linesizes(avctx, pic, me, sc, |
| 226 | 172 | *linesize, *uvlinesize) < 0) |
| 227 | 173 | return -1; |
| @@ -229,18 +175,14 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 1 unmodified line | ||
| 229 | 175 | *linesize = pic->f->linesize[0]; |
| 230 | 176 | *uvlinesize = pic->f->linesize[1]; |
| 231 | 177 | |
| 232 | − if (!pic->qscale_table_buf) | |
| 233 | − ret = alloc_picture_tables(avctx, pic, encoding, out_format, | |
| 234 | − mb_stride, mb_width, mb_height, b8_stride); | |
| 235 | − else | |
| 236 | − ret = make_tables_writable(pic); | |
| 178 | + ret = alloc_picture_tables(pools, pic, mb_height); | |
| 237 | 179 | if (ret < 0) |
| 238 | 180 | goto fail; |
| 239 | 181 | |
| 240 | 182 | pic->mbskip_table = pic->mbskip_table_buf->data; |
| 241 | 183 | memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size); |
| 242 | − pic->qscale_table = pic->qscale_table_buf->data + 2 * mb_stride + 1; | |
| 243 | − pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * mb_stride + 1; | |
| 184 | + pic->qscale_table = pic->qscale_table_buf->data + 2 * pic->mb_stride + 1; | |
| 185 | + pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * pic->mb_stride + 1; | |
| 244 | 186 | |
| 245 | 187 | if (pic->motion_val_buf[0]) { |
| 246 | 188 | for (i = 0; i < 2; i++) { |
| @@ -257,7 +199,6 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 10 unmodified lines | ||
| 257 | 199 | fail: |
| 258 | 200 | av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); |
| 259 | 201 | ff_mpeg_unref_picture(pic); |
| 260 | − free_picture_tables(pic); | |
| 261 | 202 | return AVERROR(ENOMEM); |
| 262 | 203 | } |
| 263 | 204 | |
| @@ -272,20 +213,18 @@ void ff_mpeg_unref_picture(Picture *pic) · 8 unmodified lines | ||
| 272 | 213 | |
| 273 | 214 | ff_refstruct_unref(&pic->hwaccel_picture_private); |
| 274 | 215 | |
| 275 | − if (pic->needs_realloc) | |
| 276 | − free_picture_tables(pic); | |
| 216 | + free_picture_tables(pic); | |
| 277 | 217 | |
| 278 | 218 | pic->dummy = 0; |
| 279 | 219 | pic->field_picture = 0; |
| 280 | 220 | pic->b_frame_score = 0; |
| 281 | − pic->needs_realloc = 0; | |
| 282 | 221 | pic->reference = 0; |
| 283 | 222 | pic->shared = 0; |
| 284 | 223 | pic->display_picture_number = 0; |
| 285 | 224 | pic->coded_picture_number = 0; |
| 286 | 225 | } |
| 287 | 226 | |
| 288 | −int ff_update_picture_tables(Picture *dst, const Picture *src) | |
| 227 | +static int update_picture_tables(Picture *dst, const Picture *src) | |
| 289 | 228 | { |
| 290 | 229 | int i, ret; |
| 291 | 230 | |
| @@ -310,9 +249,9 @@ int ff_update_picture_tables(Picture *dst, const Picture *src) · 18 unmodified lines | ||
| 310 | 249 | dst->ref_index[i] = src->ref_index[i]; |
| 311 | 250 | } |
| 312 | 251 | |
| 313 | − dst->alloc_mb_width = src->alloc_mb_width; | |
| 314 | − dst->alloc_mb_height = src->alloc_mb_height; | |
| 315 | − dst->alloc_mb_stride = src->alloc_mb_stride; | |
| 252 | + dst->mb_width = src->mb_width; | |
| 253 | + dst->mb_height = src->mb_height; | |
| 254 | + dst->mb_stride = src->mb_stride; | |
| 316 | 255 | |
| 317 | 256 | return 0; |
| 318 | 257 | } |
| @@ -330,7 +269,7 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src) · 11 unmodified lines | ||
| 330 | 269 | if (ret < 0) |
| 331 | 270 | goto fail; |
| 332 | 271 | |
| 333 | − ret = ff_update_picture_tables(dst, src); | |
| 272 | + ret = update_picture_tables(dst, src); | |
| 334 | 273 | if (ret < 0) |
| 335 | 274 | goto fail; |
| 336 | 275 | |
| @@ -340,7 +279,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src) · 3 unmodified lines | ||
| 340 | 279 | dst->dummy = src->dummy; |
| 341 | 280 | dst->field_picture = src->field_picture; |
| 342 | 281 | dst->b_frame_score = src->b_frame_score; |
| 343 | − dst->needs_realloc = src->needs_realloc; | |
| 344 | 282 | dst->reference = src->reference; |
| 345 | 283 | dst->shared = src->shared; |
| 346 | 284 | dst->display_picture_number = src->display_picture_number; |
| @@ -352,30 +290,14 @@ fail: · 5 unmodified lines | ||
| 352 | 290 | return ret; |
| 353 | 291 | } |
| 354 | 292 | |
| 355 | −static inline int pic_is_unused(Picture *pic) | |
| 356 | −{ | |
| 357 | − if (!pic->f->buf[0]) | |
| 358 | − return 1; | |
| 359 | − if (pic->needs_realloc) | |
| 360 | − return 1; | |
| 361 | − return 0; | |
| 362 | −} | |
| 363 | − | |
| 364 | −static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) | |
| 293 | +int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) | |
| 365 | 294 | { |
| 366 | 295 | int i; |
| 367 | 296 | |
| 368 | − if (shared) { | |
| 369 | 297 | for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
| 370 | 298 | if (!picture[i].f->buf[0]) |
| 371 | 299 | return i; |
| 372 | 300 | } |
| 373 | − } else { | |
| 374 | − for (i = 0; i < MAX_PICTURE_COUNT; i++) { | |
| 375 | − if (pic_is_unused(&picture[i])) | |
| 376 | − return i; | |
| 377 | − } | |
| 378 | − } | |
| 379 | 301 | |
| 380 | 302 | av_log(avctx, AV_LOG_FATAL, |
| 381 | 303 | "Internal error, picture buffer overflow\n"); |
| @@ -394,21 +316,8 @@ static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shar · 12 unmodified lines | ||
| 394 | 316 | return -1; |
| 395 | 317 | } |
| 396 | 318 | |
| 397 | −int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) | |
| 398 | −{ | |
| 399 | − int ret = find_unused_picture(avctx, picture, shared); | |
| 400 | − | |
| 401 | − if (ret >= 0 && ret < MAX_PICTURE_COUNT) { | |
| 402 | − if (picture[ret].needs_realloc) { | |
| 403 | − ff_mpeg_unref_picture(&picture[ret]); | |
| 404 | − } | |
| 405 | − } | |
| 406 | − return ret; | |
| 407 | −} | |
| 408 | − | |
| 409 | 319 | void av_cold ff_mpv_picture_free(Picture *pic) |
| 410 | 320 | { |
| 411 | − free_picture_tables(pic); | |
| 412 | 321 | ff_mpeg_unref_picture(pic); |
| 413 | 322 | av_frame_free(&pic->f); |
| 414 | 323 | } |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <stdint.h> |
| 25 | 25 | |
| 26 | +#include "libavutil/buffer.h" | |
| 26 | 27 | #include "libavutil/frame.h" |
| 27 | 28 | |
| 28 | 29 | #include "avcodec.h" |
| @@ -41,6 +42,17 @@ typedef struct ScratchpadContext { · 12 unmodified lines | ||
| 41 | 42 | int linesize; ///< linesize that the buffers in this context have been allocated for |
| 42 | 43 | } ScratchpadContext; |
| 43 | 44 | |
| 45 | +typedef struct BufferPoolContext { | |
| 46 | + AVBufferPool *mbskip_table_pool; | |
| 47 | + AVBufferPool *qscale_table_pool; | |
| 48 | + AVBufferPool *mb_type_pool; | |
| 49 | + AVBufferPool *motion_val_pool; | |
| 50 | + AVBufferPool *ref_index_pool; | |
| 51 | + int alloc_mb_width; ///< mb_width used to allocate tables | |
| 52 | + int alloc_mb_height; ///< mb_height used to allocate tables | |
| 53 | + int alloc_mb_stride; ///< mb_stride used to allocate tables | |
| 54 | +} BufferPoolContext; | |
| 55 | + | |
| 44 | 56 | /** |
| 45 | 57 | * Picture. |
| 46 | 58 | */ |
| @@ -63,18 +75,17 @@ typedef struct Picture { · 16 unmodified lines | ||
| 63 | 75 | AVBufferRef *ref_index_buf[2]; |
| 64 | 76 | int8_t *ref_index[2]; |
| 65 | 77 | |
| 66 | − int alloc_mb_width; ///< mb_width used to allocate tables | |
| 67 | − int alloc_mb_height; ///< mb_height used to allocate tables | |
| 68 | − int alloc_mb_stride; ///< mb_stride used to allocate tables | |
| 69 | − | |
| 70 | 78 | /// RefStruct reference for hardware accelerator private data |
| 71 | 79 | void *hwaccel_picture_private; |
| 72 | 80 | |
| 81 | + int mb_width; ///< mb_width of the tables | |
| 82 | + int mb_height; ///< mb_height of the tables | |
| 83 | + int mb_stride; ///< mb_stride of the tables | |
| 84 | + | |
| 73 | 85 | int dummy; ///< Picture is a dummy and should not be output |
| 74 | 86 | int field_picture; ///< whether or not the picture was encoded in separate fields |
| 75 | 87 | |
| 76 | 88 | int b_frame_score; |
| 77 | − int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change) | |
| 78 | 89 | |
| 79 | 90 | int reference; |
| 80 | 91 | int shared; |
| @@ -87,9 +98,8 @@ typedef struct Picture { · 6 unmodified lines | ||
| 87 | 98 | * Allocate a Picture's accessories, but not the AVFrame's buffer itself. |
| 88 | 99 | */ |
| 89 | 100 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, |
| 90 | − ScratchpadContext *sc, int encoding, int out_format, | |
| 91 | − int mb_stride, int mb_width, int mb_height, int b8_stride, | |
| 92 | − ptrdiff_t *linesize, ptrdiff_t *uvlinesize); | |
| 101 | + ScratchpadContext *sc, BufferPoolContext *pools, | |
| 102 | + int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize); | |
| 93 | 103 | |
| 94 | 104 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
| 95 | 105 | ScratchpadContext *sc, int linesize); |
| @@ -98,7 +108,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src); · 2 unmodified lines | ||
| 98 | 108 | void ff_mpeg_unref_picture(Picture *picture); |
| 99 | 109 | |
| 100 | 110 | void ff_mpv_picture_free(Picture *pic); |
| 101 | −int ff_update_picture_tables(Picture *dst, const Picture *src); | |
| 102 | 111 | |
| 103 | 112 | int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared); |
| 104 | 113 | |
| @@ -534,8 +534,19 @@ void ff_mpv_common_defaults(MpegEncContext *s) · 533 unmodified lines | ||
| 534 | 534 | s->slice_context_count = 1; |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | +static void free_buffer_pools(BufferPoolContext *pools) | |
| 538 | +{ | |
| 539 | + av_buffer_pool_uninit(&pools->mbskip_table_pool); | |
| 540 | + av_buffer_pool_uninit(&pools->qscale_table_pool); | |
| 541 | + av_buffer_pool_uninit(&pools->mb_type_pool); | |
| 542 | + av_buffer_pool_uninit(&pools->motion_val_pool); | |
| 543 | + av_buffer_pool_uninit(&pools->ref_index_pool); | |
| 544 | + pools->alloc_mb_height = pools->alloc_mb_width = pools->alloc_mb_stride = 0; | |
| 545 | +} | |
| 546 | + | |
| 537 | 547 | int ff_mpv_init_context_frame(MpegEncContext *s) |
| 538 | 548 | { |
| 549 | + BufferPoolContext *const pools = &s->buffer_pools; | |
| 539 | 550 | int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; |
| 540 | 551 | int mb_height; |
| 541 | 552 | |
| @@ -630,11 +641,36 @@ int ff_mpv_init_context_frame(MpegEncContext *s) · 88 unmodified lines | ||
| 630 | 641 | return AVERROR(ENOMEM); |
| 631 | 642 | memset(s->mbintra_table, 1, mb_array_size); |
| 632 | 643 | |
| 644 | +#define ALLOC_POOL(name, size) do { \ | |
| 645 | + pools->name ##_pool = av_buffer_pool_init((size), av_buffer_allocz); \ | |
| 646 | + if (!pools->name ##_pool) \ | |
| 647 | + return AVERROR(ENOMEM); \ | |
| 648 | +} while (0) | |
| 649 | + | |
| 650 | + ALLOC_POOL(mbskip_table, mb_array_size + 2); | |
| 651 | + ALLOC_POOL(qscale_table, mv_table_size); | |
| 652 | + ALLOC_POOL(mb_type, mv_table_size * sizeof(uint32_t)); | |
| 653 | + | |
| 654 | + if (s->out_format == FMT_H263 || s->encoding || | |
| 655 | + (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) { | |
| 656 | + const int b8_array_size = s->b8_stride * mb_height * 2; | |
| 657 | + int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); | |
| 658 | + int ref_index_size = 4 * mb_array_size; | |
| 659 | + | |
| 660 | + ALLOC_POOL(motion_val, mv_size); | |
| 661 | + ALLOC_POOL(ref_index, ref_index_size); | |
| 662 | + } | |
| 663 | +#undef ALLOC_POOL | |
| 664 | + pools->alloc_mb_width = s->mb_width; | |
| 665 | + pools->alloc_mb_height = mb_height; | |
| 666 | + pools->alloc_mb_stride = s->mb_stride; | |
| 667 | + | |
| 633 | 668 | return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s); |
| 634 | 669 | } |
| 635 | 670 | |
| 636 | 671 | static void clear_context(MpegEncContext *s) |
| 637 | 672 | { |
| 673 | + memset(&s->buffer_pools, 0, sizeof(s->buffer_pools)); | |
| 638 | 674 | memset(&s->next_picture, 0, sizeof(s->next_picture)); |
| 639 | 675 | memset(&s->last_picture, 0, sizeof(s->last_picture)); |
| 640 | 676 | memset(&s->current_picture, 0, sizeof(s->current_picture)); |
| @@ -762,6 +798,7 @@ void ff_mpv_free_context_frame(MpegEncContext *s) · 121 unmodified lines | ||
| 762 | 798 | { |
| 763 | 799 | free_duplicate_contexts(s); |
| 764 | 800 | |
| 801 | + free_buffer_pools(&s->buffer_pools); | |
| 765 | 802 | av_freep(&s->p_field_mv_table_base); |
| 766 | 803 | for (int i = 0; i < 2; i++) |
| 767 | 804 | for (int j = 0; j < 2; j++) |
| @@ -132,6 +132,8 @@ typedef struct MpegEncContext { · 131 unmodified lines | ||
| 132 | 132 | Picture **input_picture; ///< next pictures on display order for encoding |
| 133 | 133 | Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding |
| 134 | 134 | |
| 135 | + BufferPoolContext buffer_pools; | |
| 136 | + | |
| 135 | 137 | int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame() |
| 136 | 138 | /** |
| 137 | 139 | * pts difference between the first and second input frame, used for |
| @@ -115,12 +115,11 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, · 114 unmodified lines | ||
| 115 | 115 | #define UPDATE_PICTURE(pic)\ |
| 116 | 116 | do {\ |
| 117 | 117 | ff_mpeg_unref_picture(&s->pic);\ |
| 118 | − if (s1->pic.f && s1->pic.f->buf[0])\ | |
| 118 | + if (s1->pic.f && s1->pic.f->buf[0]) {\ | |
| 119 | 119 | ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\ |
| 120 | − else\ | |
| 121 | − ret = ff_update_picture_tables(&s->pic, &s1->pic);\ | |
| 122 | − if (ret < 0)\ | |
| 123 | − return ret;\ | |
| 120 | + if (ret < 0)\ | |
| 121 | + return ret;\ | |
| 122 | + }\ | |
| 124 | 123 | } while (0) |
| 125 | 124 | |
| 126 | 125 | UPDATE_PICTURE(current_picture); |
| @@ -194,10 +193,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) · 67 unmodified lines | ||
| 194 | 193 | |
| 195 | 194 | ff_mpv_free_context_frame(s); |
| 196 | 195 | |
| 197 | − if (s->picture) | |
| 198 | − for (int i = 0; i < MAX_PICTURE_COUNT; i++) | |
| 199 | − s->picture[i].needs_realloc = 1; | |
| 200 | − | |
| 201 | 196 | s->last_picture_ptr = |
| 202 | 197 | s->next_picture_ptr = |
| 203 | 198 | s->current_picture_ptr = NULL; |
| @@ -268,9 +263,12 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference) · 64 unmodified lines | ||
| 268 | 263 | if (ret < 0) |
| 269 | 264 | goto fail; |
| 270 | 265 | |
| 271 | − ret = ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 0, s->out_format, | |
| 272 | − s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, | |
| 273 | − &s->linesize, &s->uvlinesize); | |
| 266 | + av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); | |
| 267 | + av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height || | |
| 268 | + FFALIGN(s->mb_height, 2) == s->buffer_pools.alloc_mb_height); | |
| 269 | + av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride); | |
| 270 | + ret = ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools, | |
| 271 | + s->mb_height, &s->linesize, &s->uvlinesize); | |
| 274 | 272 | if (ret < 0) |
| 275 | 273 | goto fail; |
| 276 | 274 | *picp = pic; |
| @@ -388,8 +386,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) · 111 unmodified lines | ||
| 388 | 386 | for (int i = 0; i < MAX_PICTURE_COUNT; i++) { |
| 389 | 387 | if (!s->picture[i].reference || |
| 390 | 388 | (&s->picture[i] != s->last_picture_ptr && |
| 391 | − &s->picture[i] != s->next_picture_ptr && | |
| 392 | − !s->picture[i].needs_realloc)) { | |
| 389 | + &s->picture[i] != s->next_picture_ptr)) { | |
| 393 | 390 | ff_mpeg_unref_picture(&s->picture[i]); |
| 394 | 391 | } |
| 395 | 392 | } |
| @@ -487,7 +484,7 @@ int ff_mpv_export_qp_table(const MpegEncContext *s, AVFrame *f, const Picture *p · 91 unmodified lines | ||
| 487 | 484 | { |
| 488 | 485 | AVVideoEncParams *par; |
| 489 | 486 | int mult = (qp_type == FF_MPV_QSCALE_TYPE_MPEG1) ? 2 : 1; |
| 490 | − unsigned int nb_mb = p->alloc_mb_height * p->alloc_mb_width; | |
| 487 | + unsigned int nb_mb = p->mb_height * p->mb_width; | |
| 491 | 488 | |
| 492 | 489 | if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS)) |
| 493 | 490 | return 0; |
| @@ -496,10 +493,10 @@ int ff_mpv_export_qp_table(const MpegEncContext *s, AVFrame *f, const Picture *p · 2 unmodified lines | ||
| 496 | 493 | if (!par) |
| 497 | 494 | return AVERROR(ENOMEM); |
| 498 | 495 | |
| 499 | − for (unsigned y = 0; y < p->alloc_mb_height; y++) | |
| 500 | − for (unsigned x = 0; x < p->alloc_mb_width; x++) { | |
| 501 | − const unsigned int block_idx = y * p->alloc_mb_width + x; | |
| 502 | − const unsigned int mb_xy = y * p->alloc_mb_stride + x; | |
| 496 | + for (unsigned y = 0; y < p->mb_height; y++) | |
| 497 | + for (unsigned x = 0; x < p->mb_width; x++) { | |
| 498 | + const unsigned int block_idx = y * p->mb_width + x; | |
| 499 | + const unsigned int mb_xy = y * p->mb_stride + x; | |
| 503 | 500 | AVVideoBlockParams *const b = av_video_enc_params_block(par, block_idx); |
| 504 | 501 | |
| 505 | 502 | b->src_x = x * 16; |
| @@ -1112,9 +1112,11 @@ static int alloc_picture(MpegEncContext *s, Picture *pic) · 1111 unmodified lines | ||
| 1112 | 1112 | pic->f->width = avctx->width; |
| 1113 | 1113 | pic->f->height = avctx->height; |
| 1114 | 1114 | |
| 1115 | − return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 1, s->out_format, | |
| 1116 | − s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, | |
| 1117 | − &s->linesize, &s->uvlinesize); | |
| 1115 | + av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); | |
| 1116 | + av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height); | |
| 1117 | + av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride); | |
| 1118 | + return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools, | |
| 1119 | + s->mb_height, &s->linesize, &s->uvlinesize); | |
| 1118 | 1120 | } |
| 1119 | 1121 | |
| 1120 | 1122 | static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) |
| @@ -1480,7 +1482,7 @@ static int select_input_picture(MpegEncContext *s) · 359 unmodified lines | ||
| 1480 | 1482 | s->next_picture_ptr && |
| 1481 | 1483 | skip_check(s, s->input_picture[0], s->next_picture_ptr)) { |
| 1482 | 1484 | // FIXME check that the gop check above is +-1 correct |
| 1483 | − av_frame_unref(s->input_picture[0]->f); | |
| 1485 | + ff_mpeg_unref_picture(s->input_picture[0]); | |
| 1484 | 1486 | |
| 1485 | 1487 | ff_vbv_update(s, 0); |
| 1486 | 1488 | |
| @@ -1627,8 +1629,7 @@ no_output_pic: · 140 unmodified lines | ||
| 1627 | 1629 | pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number; |
| 1628 | 1630 | |
| 1629 | 1631 | /* mark us unused / free shared pic */ |
| 1630 | − av_frame_unref(s->reordered_input_picture[0]->f); | |
| 1631 | − s->reordered_input_picture[0]->shared = 0; | |
| 1632 | + ff_mpeg_unref_picture(s->reordered_input_picture[0]); | |
| 1632 | 1633 | |
| 1633 | 1634 | s->current_picture_ptr = pic; |
| 1634 | 1635 | } else { |