ff_alloc_picture() currently does two things: It checks the consistency of the linesize (which should not be necessary, but is) and it allocates certain buffers. (It does not actually allocate the picture buffers, so its name is misleading.) This commit splits it into two separate functions. The rationale for this is that for the encoders, every picture needs its linesizes checked, but not every picture needs these extra buffers.
Unified · Split
| @@ -91,40 +91,27 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, · 90 unmodified lines | |||
| 91 | return 0; | 91 | return 0; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /** | 94 | int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f, |
| 95 | * Check the pic's linesize and allocate linesize dependent scratch buffers | 95 | ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep) |
| 96 | */ | ||
| 97 | static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic, | ||
| 98 | MotionEstContext *me, ScratchpadContext *sc, | ||
| 99 | int linesize, int uvlinesize) | ||
| 100 | { | 96 | { |
| 101 | int ret; | 97 | ptrdiff_t linesize = *linesizep, uvlinesize = *uvlinesizep; |
| 102 | 98 | ||
| 103 | if ((linesize && linesize != pic->f->linesize[0]) || | 99 | if ((linesize && linesize != f->linesize[0]) || |
| 104 | (uvlinesize && uvlinesize != pic->f->linesize[1])) { | 100 | (uvlinesize && uvlinesize != f->linesize[1])) { |
| 105 | av_log(avctx, AV_LOG_ERROR, "Stride change unsupported: " | 101 | av_log(logctx, AV_LOG_ERROR, "Stride change unsupported: " |
| 106 | "linesize=%d/%d uvlinesize=%d/%d)\n", | 102 | "linesize=%"PTRDIFF_SPECIFIER"/%d uvlinesize=%"PTRDIFF_SPECIFIER"/%d)\n", |
| 107 | linesize, pic->f->linesize[0], | 103 | linesize, f->linesize[0], |
| 108 | uvlinesize, pic->f->linesize[1]); | 104 | uvlinesize, f->linesize[1]); |
| 109 | ff_mpeg_unref_picture(pic); | ||
| 110 | return AVERROR_PATCHWELCOME; | 105 | return AVERROR_PATCHWELCOME; |
| 111 | } | 106 | } |
| 112 | 107 | ||
| 113 | if (av_pix_fmt_count_planes(pic->f->format) > 2 && | 108 | if (av_pix_fmt_count_planes(f->format) > 2 && |
| 114 | pic->f->linesize[1] != pic->f->linesize[2]) { | 109 | f->linesize[1] != f->linesize[2]) { |
| 115 | av_log(avctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n"); | 110 | av_log(logctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n"); |
| 116 | ff_mpeg_unref_picture(pic); | ||
| 117 | return AVERROR_PATCHWELCOME; | 111 | return AVERROR_PATCHWELCOME; |
| 118 | } | 112 | } |
| 119 | 113 | *linesizep = f->linesize[0]; | |
| 120 | ret = ff_mpeg_framesize_alloc(avctx, me, sc, | 114 | *uvlinesizep = f->linesize[1]; |
| 121 | pic->f->linesize[0]); | ||
| 122 | if (ret < 0) { | ||
| 123 | av_log(avctx, AV_LOG_ERROR, | ||
| 124 | "get_buffer() failed to allocate context scratch buffers.\n"); | ||
| 125 | ff_mpeg_unref_picture(pic); | ||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | 115 | ||
| 129 | return 0; | 116 | return 0; |
| 130 | } | 117 | } |
| @@ -156,28 +143,22 @@ static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic, · 25 unmodified lines | |||
| 156 | return 0; | 143 | return 0; |
| 157 | } | 144 | } |
| 158 | 145 | ||
| 159 | /** | 146 | int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, Picture *pic, |
| 160 | * Allocate a Picture. | 147 | MotionEstContext *me, ScratchpadContext *sc, |
| 161 | * The pixels are allocated/set by calling get_buffer() if shared = 0 | 148 | BufferPoolContext *pools, int mb_height) |
| 162 | */ | ||
| 163 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, | ||
| 164 | ScratchpadContext *sc, BufferPoolContext *pools, | ||
| 165 | int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize) | ||
| 166 | { | 149 | { |
| 167 | int ret; | 150 | int ret; |
| 168 | 151 | ||
| 169 | if (handle_pic_linesizes(avctx, pic, me, sc, | ||
| 170 | *linesize, *uvlinesize) < 0) | ||
| 171 | return -1; | ||
| 172 | |||
| 173 | *linesize = pic->f->linesize[0]; | ||
| 174 | *uvlinesize = pic->f->linesize[1]; | ||
| 175 | |||
| 176 | for (int i = 0; i < MPV_MAX_PLANES; i++) { | 152 | for (int i = 0; i < MPV_MAX_PLANES; i++) { |
| 177 | pic->data[i] = pic->f->data[i]; | 153 | pic->data[i] = pic->f->data[i]; |
| 178 | pic->linesize[i] = pic->f->linesize[i]; | 154 | pic->linesize[i] = pic->f->linesize[i]; |
| 179 | } | 155 | } |
| 180 | 156 | ||
| 157 | ret = ff_mpeg_framesize_alloc(avctx, me, sc, | ||
| 158 | pic->f->linesize[0]); | ||
| 159 | if (ret < 0) | ||
| 160 | goto fail; | ||
| 161 | |||
| 181 | ret = alloc_picture_tables(pools, pic, mb_height); | 162 | ret = alloc_picture_tables(pools, pic, mb_height); |
| 182 | if (ret < 0) | 163 | if (ret < 0) |
| 183 | goto fail; | 164 | goto fail; |
| @@ -192,9 +173,8 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, · 8 unmodified lines | |||
| 192 | 173 | ||
| 193 | return 0; | 174 | return 0; |
| 194 | fail: | 175 | fail: |
| 195 | av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); | 176 | av_log(avctx, AV_LOG_ERROR, "Error allocating picture accessories.\n"); |
| 196 | ff_mpeg_unref_picture(pic); | 177 | return ret; |
| 197 | return AVERROR(ENOMEM); | ||
| 198 | } | 178 | } |
| 199 | 179 | ||
| 200 | /** | 180 | /** |
| @@ -96,9 +96,18 @@ typedef struct Picture { · 95 unmodified lines | |||
| 96 | /** | 96 | /** |
| 97 | * Allocate a Picture's accessories, but not the AVFrame's buffer itself. | 97 | * Allocate a Picture's accessories, but not the AVFrame's buffer itself. |
| 98 | */ | 98 | */ |
| 99 | int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, | 99 | int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, Picture *pic, |
| 100 | ScratchpadContext *sc, BufferPoolContext *pools, | 100 | MotionEstContext *me, ScratchpadContext *sc, |
| 101 | int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize); | 101 | BufferPoolContext *pools, int mb_height); |
| 102 | |||
| 103 | /** | ||
| 104 | * Check that the linesizes of an AVFrame are consistent with the requirements | ||
| 105 | * of mpegvideo. | ||
| 106 | * FIXME: There should be no need for this function. mpegvideo should be made | ||
| 107 | * to work with changing linesizes. | ||
| 108 | */ | ||
| 109 | int ff_mpv_pic_check_linesize(void *logctx, const struct AVFrame *f, | ||
| 110 | ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep); | ||
| 102 | 111 | ||
| 103 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, | 112 | int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
| 104 | ScratchpadContext *sc, int linesize); | 113 | ScratchpadContext *sc, int linesize); |
| @@ -259,6 +259,10 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference) · 258 unmodified lines | |||
| 259 | if (ret < 0) | 259 | if (ret < 0) |
| 260 | goto fail; | 260 | goto fail; |
| 261 | 261 | ||
| 262 | ret = ff_mpv_pic_check_linesize(avctx, pic->f, &s->linesize, &s->uvlinesize); | ||
| 263 | if (ret < 0) | ||
| 264 | goto fail; | ||
| 265 | |||
| 262 | ret = ff_hwaccel_frame_priv_alloc(avctx, &pic->hwaccel_picture_private); | 266 | ret = ff_hwaccel_frame_priv_alloc(avctx, &pic->hwaccel_picture_private); |
| 263 | if (ret < 0) | 267 | if (ret < 0) |
| 264 | goto fail; | 268 | goto fail; |
| @@ -267,8 +271,8 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference) · 2 unmodified lines | |||
| 267 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height || | 271 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height || |
| 268 | FFALIGN(s->mb_height, 2) == s->buffer_pools.alloc_mb_height); | 272 | FFALIGN(s->mb_height, 2) == s->buffer_pools.alloc_mb_height); |
| 269 | av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride); | 273 | 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, | 274 | ret = ff_mpv_alloc_pic_accessories(s->avctx, pic, &s->me, &s->sc, |
| 271 | s->mb_height, &s->linesize, &s->uvlinesize); | 275 | &s->buffer_pools, s->mb_height); |
| 272 | if (ret < 0) | 276 | if (ret < 0) |
| 273 | goto fail; | 277 | goto fail; |
| 274 | *picp = pic; | 278 | *picp = pic; |
| @@ -1103,6 +1103,10 @@ static int alloc_picture(MpegEncContext *s, Picture *pic) · 1102 unmodified lines | |||
| 1103 | if (ret < 0) | 1103 | if (ret < 0) |
| 1104 | return ret; | 1104 | return ret; |
| 1105 | 1105 | ||
| 1106 | ret = ff_mpv_pic_check_linesize(avctx, pic->f, &s->linesize, &s->uvlinesize); | ||
| 1107 | if (ret < 0) | ||
| 1108 | return ret; | ||
| 1109 | |||
| 1106 | for (int i = 0; pic->f->data[i]; i++) { | 1110 | for (int i = 0; pic->f->data[i]; i++) { |
| 1107 | int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) * | 1111 | int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) * |
| 1108 | pic->f->linesize[i] + | 1112 | pic->f->linesize[i] + |
| @@ -1112,11 +1116,7 @@ static int alloc_picture(MpegEncContext *s, Picture *pic) · 3 unmodified lines | |||
| 1112 | pic->f->width = avctx->width; | 1116 | pic->f->width = avctx->width; |
| 1113 | pic->f->height = avctx->height; | 1117 | pic->f->height = avctx->height; |
| 1114 | 1118 | ||
| 1115 | av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); | 1119 | return 0; |
| 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); | ||
| 1120 | } | 1120 | } |
| 1121 | 1121 | ||
| 1122 | static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) | 1122 | static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) |
| @@ -1188,7 +1188,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 65 unmodified lines | |||
| 1188 | } else { | 1188 | } else { |
| 1189 | ret = alloc_picture(s, pic); | 1189 | ret = alloc_picture(s, pic); |
| 1190 | if (ret < 0) | 1190 | if (ret < 0) |
| 1191 | return ret; | 1191 | goto fail; |
| 1192 | ret = av_frame_copy_props(pic->f, pic_arg); | 1192 | ret = av_frame_copy_props(pic->f, pic_arg); |
| 1193 | if (ret < 0) { | 1193 | if (ret < 0) { |
| 1194 | ff_mpeg_unref_picture(pic); | 1194 | ff_mpeg_unref_picture(pic); |
| @@ -1258,6 +1258,9 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) · 63 unmodified lines | |||
| 1258 | s->input_picture[encoding_delay] = pic; | 1258 | s->input_picture[encoding_delay] = pic; |
| 1259 | 1259 | ||
| 1260 | return 0; | 1260 | return 0; |
| 1261 | fail: | ||
| 1262 | ff_mpeg_unref_picture(pic); | ||
| 1263 | return ret; | ||
| 1261 | } | 1264 | } |
| 1262 | 1265 | ||
| 1263 | static int skip_check(MpegEncContext *s, const Picture *p, const Picture *ref) | 1266 | static int skip_check(MpegEncContext *s, const Picture *p, const Picture *ref) |
| @@ -1600,45 +1603,37 @@ no_output_pic: · 336 unmodified lines | |||
| 1600 | s->reordered_input_picture[0]->f->pict_type != | 1603 | s->reordered_input_picture[0]->f->pict_type != |
| 1601 | AV_PICTURE_TYPE_B ? 3 : 0; | 1604 | AV_PICTURE_TYPE_B ? 3 : 0; |
| 1602 | 1605 | ||
| 1603 | if ((ret = av_frame_ref(s->new_pic, | ||
| 1604 | s->reordered_input_picture[0]->f))) | ||
| 1605 | goto fail; | ||
| 1606 | |||
| 1607 | if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) { | 1606 | if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) { |
| 1608 | // input is a shared pix, so we can't modify it -> allocate a new | 1607 | // input is a shared pix, so we can't modify it -> allocate a new |
| 1609 | // one & ensure that the shared one is reuseable | 1608 | // one & ensure that the shared one is reuseable |
| 1610 | 1609 | av_frame_move_ref(s->new_pic, s->reordered_input_picture[0]->f); | |
| 1611 | Picture *pic; | 1610 | ret = alloc_picture(s, s->reordered_input_picture[0]); |
| 1612 | int i = ff_find_unused_picture(s->avctx, s->picture, 0); | ||
| 1613 | if (i < 0) | ||
| 1614 | return i; | ||
| 1615 | pic = &s->picture[i]; | ||
| 1616 | |||
| 1617 | pic->reference = s->reordered_input_picture[0]->reference; | ||
| 1618 | ret = alloc_picture(s, pic); | ||
| 1619 | if (ret < 0) | 1611 | if (ret < 0) |
| 1620 | goto fail; | 1612 | goto fail; |
| 1621 | 1613 | ||
| 1622 | ret = av_frame_copy_props(pic->f, s->reordered_input_picture[0]->f); | 1614 | ret = av_frame_copy_props(s->reordered_input_picture[0]->f, s->new_pic); |
| 1623 | if (ret < 0) { | 1615 | if (ret < 0) |
| 1624 | ff_mpeg_unref_picture(pic); | ||
| 1625 | goto fail; | 1616 | goto fail; |
| 1626 | } | ||
| 1627 | pic->coded_picture_number = s->reordered_input_picture[0]->coded_picture_number; | ||
| 1628 | pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number; | ||
| 1629 | |||
| 1630 | /* mark us unused / free shared pic */ | ||
| 1631 | ff_mpeg_unref_picture(s->reordered_input_picture[0]); | ||
| 1632 | |||
| 1633 | s->cur_pic_ptr = pic; | ||
| 1634 | } else { | 1617 | } else { |
| 1635 | // input is not a shared pix -> reuse buffer for current_pix | 1618 | // input is not a shared pix -> reuse buffer for current_pix |
| 1636 | s->cur_pic_ptr = s->reordered_input_picture[0]; | 1619 | ret = av_frame_ref(s->new_pic, s->reordered_input_picture[0]->f); |
| 1620 | if (ret < 0) | ||
| 1621 | goto fail; | ||
| 1637 | for (int i = 0; i < MPV_MAX_PLANES; i++) { | 1622 | for (int i = 0; i < MPV_MAX_PLANES; i++) { |
| 1638 | if (s->new_pic->data[i]) | 1623 | if (s->new_pic->data[i]) |
| 1639 | s->new_pic->data[i] += INPLACE_OFFSET; | 1624 | s->new_pic->data[i] += INPLACE_OFFSET; |
| 1640 | } | 1625 | } |
| 1641 | } | 1626 | } |
| 1627 | s->cur_pic_ptr = s->reordered_input_picture[0]; | ||
| 1628 | av_assert1(s->mb_width == s->buffer_pools.alloc_mb_width); | ||
| 1629 | av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height); | ||
| 1630 | av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride); | ||
| 1631 | ret = ff_mpv_alloc_pic_accessories(s->avctx, s->cur_pic_ptr, &s->me, | ||
| 1632 | &s->sc, &s->buffer_pools, s->mb_height); | ||
| 1633 | if (ret < 0) { | ||
| 1634 | ff_mpeg_unref_picture(s->cur_pic_ptr); | ||
| 1635 | return ret; | ||
| 1636 | } | ||
| 1642 | s->picture_number = s->cur_pic_ptr->display_picture_number; | 1637 | s->picture_number = s->cur_pic_ptr->display_picture_number; |
| 1643 | 1638 | ||
| 1644 | } | 1639 | } |