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.
Showing the changes to libavcodec (6 of 6 files). Show all
Unified · Split
| @@ -29,15 +29,11 @@ · 28 unmodified lines | |||
| 29 | #include "avcodec.h" | 29 | #include "avcodec.h" |
| 30 | #include "motion_est.h" | 30 | #include "motion_est.h" |
| 31 | #include "mpegpicture.h" | 31 | #include "mpegpicture.h" |
| 32 | #include "mpegvideo.h" | ||
| 33 | #include "refstruct.h" | 32 | #include "refstruct.h" |
| 34 | #include "threadframe.h" | 33 | #include "threadframe.h" |
| 35 | 34 | ||
| 36 | static void av_noinline free_picture_tables(Picture *pic) | 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 | av_buffer_unref(&pic->mbskip_table_buf); | 37 | av_buffer_unref(&pic->mbskip_table_buf); |
| 42 | av_buffer_unref(&pic->qscale_table_buf); | 38 | av_buffer_unref(&pic->qscale_table_buf); |
| 43 | av_buffer_unref(&pic->mb_type_buf); | 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 | av_buffer_unref(&pic->motion_val_buf[i]); | 42 | av_buffer_unref(&pic->motion_val_buf[i]); |
| 47 | av_buffer_unref(&pic->ref_index_buf[i]); | 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 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, | 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 | return 0; | 132 | return 0; |
| 171 | } | 133 | } |
| 172 | 134 | ||
| 173 | static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encoding, int out_format, | 135 | static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic, |
| 174 | int mb_stride, int mb_width, int mb_height, int b8_stride) | 136 | int mb_height) |
| 175 | { | 137 | { |
| 176 | const int big_mb_num = mb_stride * (mb_height + 1) + 1; | 138 | #define GET_BUFFER(name, idx_suffix) do { \ |
| 177 | const int mb_array_size = mb_stride * mb_height; | 139 | pic->name ## _buf idx_suffix = av_buffer_pool_get(pools->name ## _pool); \ |
| 178 | const int b8_array_size = b8_stride * mb_height * 2; | 140 | if (!pic->name ## _buf idx_suffix) \ |
| 179 | int i; | 141 | return AVERROR(ENOMEM); \ |
| 180 | 142 | } while (0) | |
| 181 | 143 | GET_BUFFER(mbskip_table,); | |
| 182 | pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); | 144 | GET_BUFFER(qscale_table,); |
| 183 | pic->qscale_table_buf = av_buffer_allocz(big_mb_num + mb_stride); | 145 | GET_BUFFER(mb_type,); |
| 184 | pic->mb_type_buf = av_buffer_allocz((big_mb_num + mb_stride) * | 146 | if (pools->motion_val_pool) { |
| 185 | sizeof(uint32_t)); | 147 | for (int i = 0; i < 2; i++) { |
| 186 | if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) | 148 | GET_BUFFER(motion_val, [i]); |
| 187 | return AVERROR(ENOMEM); | 149 | GET_BUFFER(ref_index, [i]); |
| 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); | ||
| 199 | } | 150 | } |
| 200 | } | 151 | } |
| 152 | #undef GET_BUFFER | ||
| 201 | 153 | ||
| 202 | pic->alloc_mb_width = mb_width; | 154 | pic->mb_width = pools->alloc_mb_width; |
| 203 | pic->alloc_mb_height = mb_height; | 155 | pic->mb_height = mb_height; |
| 204 | pic->alloc_mb_stride = mb_stride; | 156 | pic->mb_stride = pools->alloc_mb_stride; |
| 205 | 157 | ||
| 206 | return 0; | 158 | return 0; |
| 207 | } | 159 | } |
| @@ -211,17 +163,11 @@ static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encodin · 3 unmodified lines | |||
| 211 | * The pixels are allocated/set by calling get_buffer() if shared = 0 | 163 | * The pixels are allocated/set by calling get_buffer() if shared = 0 |
| 212 | */ | 164 | */ |
| 213 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, | 165 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, |
| 214 | ScratchpadContext *sc, int encoding, int out_format, | 166 | ScratchpadContext *sc, BufferPoolContext *pools, |
| 215 | int mb_stride, int mb_width, int mb_height, int b8_stride, | 167 | int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize) |
| 216 | ptrdiff_t *linesize, ptrdiff_t *uvlinesize) | ||
| 217 | { | 168 | { |
| 218 | int i, ret; | 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 | if (handle_pic_linesizes(avctx, pic, me, sc, | 171 | if (handle_pic_linesizes(avctx, pic, me, sc, |
| 226 | *linesize, *uvlinesize) < 0) | 172 | *linesize, *uvlinesize) < 0) |
| 227 | return -1; | 173 | return -1; |
| @@ -229,18 +175,14 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 1 unmodified line | |||
| 229 | *linesize = pic->f->linesize[0]; | 175 | *linesize = pic->f->linesize[0]; |
| 230 | *uvlinesize = pic->f->linesize[1]; | 176 | *uvlinesize = pic->f->linesize[1]; |
| 231 | 177 | ||
| 232 | if (!pic->qscale_table_buf) | 178 | ret = alloc_picture_tables(pools, pic, mb_height); |
| 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); | ||
| 237 | if (ret < 0) | 179 | if (ret < 0) |
| 238 | goto fail; | 180 | goto fail; |
| 239 | 181 | ||
| 240 | pic->mbskip_table = pic->mbskip_table_buf->data; | 182 | pic->mbskip_table = pic->mbskip_table_buf->data; |
| 241 | memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size); | 183 | memset(pic->mbskip_table, 0, pic->mbskip_table_buf->size); |
| 242 | pic->qscale_table = pic->qscale_table_buf->data + 2 * mb_stride + 1; | 184 | pic->qscale_table = pic->qscale_table_buf->data + 2 * pic->mb_stride + 1; |
| 243 | pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * mb_stride + 1; | 185 | pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * pic->mb_stride + 1; |
| 244 | 186 | ||
| 245 | if (pic->motion_val_buf[0]) { | 187 | if (pic->motion_val_buf[0]) { |
| 246 | for (i = 0; i < 2; i++) { | 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 | fail: | 199 | fail: |
| 258 | av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); | 200 | av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); |
| 259 | ff_mpeg_unref_picture(pic); | 201 | ff_mpeg_unref_picture(pic); |
| 260 | free_picture_tables(pic); | ||
| 261 | return AVERROR(ENOMEM); | 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 | ff_refstruct_unref(&pic->hwaccel_picture_private); | 214 | ff_refstruct_unref(&pic->hwaccel_picture_private); |
| 274 | 215 | ||
| 275 | if (pic->needs_realloc) | 216 | free_picture_tables(pic); |
| 276 | free_picture_tables(pic); | ||
| 277 | 217 | ||
| 278 | pic->dummy = 0; | 218 | pic->dummy = 0; |
| 279 | pic->field_picture = 0; | 219 | pic->field_picture = 0; |
| 280 | pic->b_frame_score = 0; | 220 | pic->b_frame_score = 0; |
| 281 | pic->needs_realloc = 0; | ||
| 282 | pic->reference = 0; | 221 | pic->reference = 0; |
| 283 | pic->shared = 0; | 222 | pic->shared = 0; |
| 284 | pic->display_picture_number = 0; | 223 | pic->display_picture_number = 0; |
| 285 | pic->coded_picture_number = 0; | 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 | int i, ret; | 229 | int i, ret; |
| 291 | 230 | ||
| @@ -310,9 +249,9 @@ int ff_update_picture_tables(Picture *dst, const Picture *src) · 18 unmodified lines | |||
| 310 | dst->ref_index[i] = src->ref_index[i]; | 249 | dst->ref_index[i] = src->ref_index[i]; |
| 311 | } | 250 | } |
| 312 | 251 | ||
| 313 | dst->alloc_mb_width = src->alloc_mb_width; | 252 | dst->mb_width = src->mb_width; |
| 314 | dst->alloc_mb_height = src->alloc_mb_height; | 253 | dst->mb_height = src->mb_height; |
| 315 | dst->alloc_mb_stride = src->alloc_mb_stride; | 254 | dst->mb_stride = src->mb_stride; |
| 316 | 255 | ||
| 317 | return 0; | 256 | return 0; |
| 318 | } | 257 | } |
| @@ -330,7 +269,7 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src) · 11 unmodified lines | |||
| 330 | if (ret < 0) | 269 | if (ret < 0) |
| 331 | goto fail; | 270 | goto fail; |
| 332 | 271 | ||
| 333 | ret = ff_update_picture_tables(dst, src); | 272 | ret = update_picture_tables(dst, src); |
| 334 | if (ret < 0) | 273 | if (ret < 0) |
| 335 | goto fail; | 274 | goto fail; |
| 336 | 275 | ||
| @@ -340,7 +279,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src) · 3 unmodified lines | |||
| 340 | dst->dummy = src->dummy; | 279 | dst->dummy = src->dummy; |
| 341 | dst->field_picture = src->field_picture; | 280 | dst->field_picture = src->field_picture; |
| 342 | dst->b_frame_score = src->b_frame_score; | 281 | dst->b_frame_score = src->b_frame_score; |
| 343 | dst->needs_realloc = src->needs_realloc; | ||
| 344 | dst->reference = src->reference; | 282 | dst->reference = src->reference; |
| 345 | dst->shared = src->shared; | 283 | dst->shared = src->shared; |
| 346 | dst->display_picture_number = src->display_picture_number; | 284 | dst->display_picture_number = src->display_picture_number; |
| @@ -352,30 +290,14 @@ fail: · 5 unmodified lines | |||
| 352 | return ret; | 290 | return ret; |
| 353 | } | 291 | } |
| 354 | 292 | ||
| 355 | static inline int pic_is_unused(Picture *pic) | 293 | int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) |
| 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) | ||
| 365 | { | 294 | { |
| 366 | int i; | 295 | int i; |
| 367 | 296 | ||
| 368 | if (shared) { | ||
| 369 | for (i = 0; i < MAX_PICTURE_COUNT; i++) { | 297 | for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
| 370 | if (!picture[i].f->buf[0]) | 298 | if (!picture[i].f->buf[0]) |
| 371 | return i; | 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 | av_log(avctx, AV_LOG_FATAL, | 302 | av_log(avctx, AV_LOG_FATAL, |
| 381 | "Internal error, picture buffer overflow\n"); | 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 | return -1; | 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 | void av_cold ff_mpv_picture_free(Picture *pic) | 319 | void av_cold ff_mpv_picture_free(Picture *pic) |
| 410 | { | 320 | { |
| 411 | free_picture_tables(pic); | ||
| 412 | ff_mpeg_unref_picture(pic); | 321 | ff_mpeg_unref_picture(pic); |
| 413 | av_frame_free(&pic->f); | 322 | av_frame_free(&pic->f); |
| 414 | } | 323 | } |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <stdint.h> | 24 | #include <stdint.h> |
| 25 | 25 | ||
| 26 | #include "libavutil/buffer.h" | ||
| 26 | #include "libavutil/frame.h" | 27 | #include "libavutil/frame.h" |
| 27 | 28 | ||
| 28 | #include "avcodec.h" | 29 | #include "avcodec.h" |
| @@ -41,6 +42,17 @@ typedef struct ScratchpadContext { · 12 unmodified lines | |||
| 41 | int linesize; ///< linesize that the buffers in this context have been allocated for | 42 | int linesize; ///< linesize that the buffers in this context have been allocated for |
| 42 | } ScratchpadContext; | 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 | * Picture. | 57 | * Picture. |
| 46 | */ | 58 | */ |
| @@ -63,18 +75,17 @@ typedef struct Picture { · 16 unmodified lines | |||
| 63 | AVBufferRef *ref_index_buf[2]; | 75 | AVBufferRef *ref_index_buf[2]; |
| 64 | int8_t *ref_index[2]; | 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 | /// RefStruct reference for hardware accelerator private data | 78 | /// RefStruct reference for hardware accelerator private data |
| 71 | void *hwaccel_picture_private; | 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 | int dummy; ///< Picture is a dummy and should not be output | 85 | int dummy; ///< Picture is a dummy and should not be output |
| 74 | int field_picture; ///< whether or not the picture was encoded in separate fields | 86 | int field_picture; ///< whether or not the picture was encoded in separate fields |
| 75 | 87 | ||
| 76 | int b_frame_score; | 88 | int b_frame_score; |
| 77 | int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change) | ||
| 78 | 89 | ||
| 79 | int reference; | 90 | int reference; |
| 80 | int shared; | 91 | int shared; |
| @@ -87,9 +98,8 @@ typedef struct Picture { · 6 unmodified lines | |||
| 87 | * Allocate a Picture's accessories, but not the AVFrame's buffer itself. | 98 | * Allocate a Picture's accessories, but not the AVFrame's buffer itself. |
| 88 | */ | 99 | */ |
| 89 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, | 100 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, |
| 90 | ScratchpadContext *sc, int encoding, int out_format, | 101 | ScratchpadContext *sc, BufferPoolContext *pools, |
| 91 | int mb_stride, int mb_width, int mb_height, int b8_stride, | 102 | int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize); |
| 92 | ptrdiff_t *linesize, ptrdiff_t *uvlinesize); | ||
| 93 | 103 | ||
| 94 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, | 104 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
| 95 | ScratchpadContext *sc, int linesize); | 105 | ScratchpadContext *sc, int linesize); |
| @@ -98,7 +108,6 @@ int ff_mpeg_ref_picture(Picture *dst, Picture *src); · 2 unmodified lines | |||
| 98 | void ff_mpeg_unref_picture(Picture *picture); | 108 | void ff_mpeg_unref_picture(Picture *picture); |
| 99 | 109 | ||
| 100 | void ff_mpv_picture_free(Picture *pic); | 110 | void ff_mpv_picture_free(Picture *pic); |
| 101 | int ff_update_picture_tables(Picture *dst, const Picture *src); | ||
| 102 | 111 | ||
| 103 | int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared); | 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 | s->slice_context_count = 1; | 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 | int ff_mpv_init_context_frame(MpegEncContext *s) | 547 | int ff_mpv_init_context_frame(MpegEncContext *s) |
| 538 | { | 548 | { |
| 549 | BufferPoolContext *const pools = &s->buffer_pools; | ||
| 539 | int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; | 550 | int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; |
| 540 | int mb_height; | 551 | int mb_height; |
| 541 | 552 | ||
| @@ -630,11 +641,36 @@ int ff_mpv_init_context_frame(MpegEncContext *s) · 88 unmodified lines | |||
| 630 | return AVERROR(ENOMEM); | 641 | return AVERROR(ENOMEM); |
| 631 | memset(s->mbintra_table, 1, mb_array_size); | 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 | return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s); | 668 | return !CONFIG_MPEGVIDEODEC || s->encoding ? 0 : ff_mpeg_er_init(s); |
| 634 | } | 669 | } |
| 635 | 670 | ||
| 636 | static void clear_context(MpegEncContext *s) | 671 | static void clear_context(MpegEncContext *s) |
| 637 | { | 672 | { |
| 673 | memset(&s->buffer_pools, 0, sizeof(s->buffer_pools)); | ||
| 638 | memset(&s->next_picture, 0, sizeof(s->next_picture)); | 674 | memset(&s->next_picture, 0, sizeof(s->next_picture)); |
| 639 | memset(&s->last_picture, 0, sizeof(s->last_picture)); | 675 | memset(&s->last_picture, 0, sizeof(s->last_picture)); |
| 640 | memset(&s->current_picture, 0, sizeof(s->current_picture)); | 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 | free_duplicate_contexts(s); | 799 | free_duplicate_contexts(s); |
| 764 | 800 | ||
| 801 | free_buffer_pools(&s->buffer_pools); | ||
| 765 | av_freep(&s->p_field_mv_table_base); | 802 | av_freep(&s->p_field_mv_table_base); |
| 766 | for (int i = 0; i < 2; i++) | 803 | for (int i = 0; i < 2; i++) |
| 767 | for (int j = 0; j < 2; j++) | 804 | for (int j = 0; j < 2; j++) |
| @@ -132,6 +132,8 @@ typedef struct MpegEncContext { · 131 unmodified lines | |||
| 132 | Picture **input_picture; ///< next pictures on display order for encoding | 132 | Picture **input_picture; ///< next pictures on display order for encoding |
| 133 | Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding | 133 | Picture **reordered_input_picture; ///< pointer to the next pictures in coded order for encoding |
| 134 | 134 | ||
| 135 | BufferPoolContext buffer_pools; | ||
| 136 | |||
| 135 | int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame() | 137 | int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_send_frame() |
| 136 | /** | 138 | /** |
| 137 | * pts difference between the first and second input frame, used for | 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 | #define UPDATE_PICTURE(pic)\ | 115 | #define UPDATE_PICTURE(pic)\ |
| 116 | do {\ | 116 | do {\ |
| 117 | ff_mpeg_unref_picture(&s->pic);\ | 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 | ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\ | 119 | ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\ |
| 120 | else\ | 120 | if (ret < 0)\ |
| 121 | ret = ff_update_picture_tables(&s->pic, &s1->pic);\ | 121 | return ret;\ |
| 122 | if (ret < 0)\ | 122 | }\ |
| 123 | return ret;\ | ||
| 124 | } while (0) | 123 | } while (0) |
| 125 | 124 | ||
| 126 | UPDATE_PICTURE(current_picture); | 125 | UPDATE_PICTURE(current_picture); |
| @@ -194,10 +193,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) · 67 unmodified lines | |||
| 194 | 193 | ||
| 195 | ff_mpv_free_context_frame(s); | 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 | s->last_picture_ptr = | 196 | s->last_picture_ptr = |
| 202 | s->next_picture_ptr = | 197 | s->next_picture_ptr = |
| 203 | s->current_picture_ptr = NULL; | 198 | s->current_picture_ptr = NULL; |
| @@ -268,9 +263,12 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference) · 64 unmodified lines | |||
| 268 | if (ret < 0) | 263 | if (ret < 0) |
| 269 | goto fail; | 264 | goto fail; |
| 270 | 265 | ||
| 271 | ret = ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 0, s->out_format, | 266 | av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); |
| 272 | s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, | 267 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height || |
| 273 | &s->linesize, &s->uvlinesize); | 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 | if (ret < 0) | 272 | if (ret < 0) |
| 275 | goto fail; | 273 | goto fail; |
| 276 | *picp = pic; | 274 | *picp = pic; |
| @@ -388,8 +386,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) · 111 unmodified lines | |||
| 388 | for (int i = 0; i < MAX_PICTURE_COUNT; i++) { | 386 | for (int i = 0; i < MAX_PICTURE_COUNT; i++) { |
| 389 | if (!s->picture[i].reference || | 387 | if (!s->picture[i].reference || |
| 390 | (&s->picture[i] != s->last_picture_ptr && | 388 | (&s->picture[i] != s->last_picture_ptr && |
| 391 | &s->picture[i] != s->next_picture_ptr && | 389 | &s->picture[i] != s->next_picture_ptr)) { |
| 392 | !s->picture[i].needs_realloc)) { | ||
| 393 | ff_mpeg_unref_picture(&s->picture[i]); | 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 | AVVideoEncParams *par; | 485 | AVVideoEncParams *par; |
| 489 | int mult = (qp_type == FF_MPV_QSCALE_TYPE_MPEG1) ? 2 : 1; | 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 | if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS)) | 489 | if (!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS)) |
| 493 | return 0; | 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 | if (!par) | 493 | if (!par) |
| 497 | return AVERROR(ENOMEM); | 494 | return AVERROR(ENOMEM); |
| 498 | 495 | ||
| 499 | for (unsigned y = 0; y < p->alloc_mb_height; y++) | 496 | for (unsigned y = 0; y < p->mb_height; y++) |
| 500 | for (unsigned x = 0; x < p->alloc_mb_width; x++) { | 497 | for (unsigned x = 0; x < p->mb_width; x++) { |
| 501 | const unsigned int block_idx = y * p->alloc_mb_width + x; | 498 | const unsigned int block_idx = y * p->mb_width + x; |
| 502 | const unsigned int mb_xy = y * p->alloc_mb_stride + x; | 499 | const unsigned int mb_xy = y * p->mb_stride + x; |
| 503 | AVVideoBlockParams *const b = av_video_enc_params_block(par, block_idx); | 500 | AVVideoBlockParams *const b = av_video_enc_params_block(par, block_idx); |
| 504 | 501 | ||
| 505 | b->src_x = x * 16; | 502 | b->src_x = x * 16; |
| @@ -1112,9 +1112,11 @@ static int alloc_picture(MpegEncContext *s, Picture *pic) · 1111 unmodified lines | |||
| 1112 | pic->f->width = avctx->width; | 1112 | pic->f->width = avctx->width; |
| 1113 | pic->f->height = avctx->height; | 1113 | pic->f->height = avctx->height; |
| 1114 | 1114 | ||
| 1115 | return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, 1, s->out_format, | 1115 | av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); |
| 1116 | s->mb_stride, s->mb_width, s->mb_height, s->b8_stride, | 1116 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height); |
| 1117 | &s->linesize, &s->uvlinesize); | 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 | static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) | 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 | s->next_picture_ptr && | 1482 | s->next_picture_ptr && |
| 1481 | skip_check(s, s->input_picture[0], s->next_picture_ptr)) { | 1483 | skip_check(s, s->input_picture[0], s->next_picture_ptr)) { |
| 1482 | // FIXME check that the gop check above is +-1 correct | 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 | ff_vbv_update(s, 0); | 1487 | ff_vbv_update(s, 0); |
| 1486 | 1488 | ||
| @@ -1627,8 +1629,7 @@ no_output_pic: · 140 unmodified lines | |||
| 1627 | pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number; | 1629 | pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number; |
| 1628 | 1630 | ||
| 1629 | /* mark us unused / free shared pic */ | 1631 | /* mark us unused / free shared pic */ |
| 1630 | av_frame_unref(s->reordered_input_picture[0]->f); | 1632 | ff_mpeg_unref_picture(s->reordered_input_picture[0]); |
| 1631 | s->reordered_input_picture[0]->shared = 0; | ||
| 1632 | 1633 | ||
| 1633 | s->current_picture_ptr = pic; | 1634 | s->current_picture_ptr = pic; |
| 1634 | } else { | 1635 | } else { |