History

avcodec/mpegpicture: Split ff_alloc_picture() into check and alloc part

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.

Andreas Rheinhardt committed 3 years ago

Commit 89ca63c1 parent 042117d4 files · +69 −81Browse files

Unified · Split

4 files
  1. libavcodec/mpegpicture.c +25 −45
  2. libavcodec/mpegpicture.h +12 −3
  3. libavcodec/mpegvideo_dec.c +6 −2
  4. libavcodec/mpegvideo_enc.c +26 −31
libavcodec/mpegpicture.c+25−45
@@ -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/**94int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f,
95 * Check the pic's linesize and allocate linesize dependent scratch buffers95 ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep)
96 */
97static 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/**146int 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 = 0148 BufferPoolContext *pools, int mb_height)
162 */
163int 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;
194fail:175fail:
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/**
libavcodec/mpegpicture.h+12−3
@@ -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 */
99int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,99int 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 */
109int ff_mpv_pic_check_linesize(void *logctx, const struct AVFrame *f,
110 ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep);
102 111
103int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,112int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
104 ScratchpadContext *sc, int linesize);113 ScratchpadContext *sc, int linesize);
libavcodec/mpegvideo_dec.c+6−2
@@ -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;
libavcodec/mpegvideo_enc.c+26−31
@@ -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
1122static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)1122static 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;
1261fail:
1262 ff_mpeg_unref_picture(pic);
1263 return ret;
1261}1264}
1262 1265
1263static int skip_check(MpegEncContext *s, const Picture *p, const Picture *ref)1266static 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 new1607 // input is a shared pix, so we can't modify it -> allocate a new
1609 // one & ensure that the shared one is reuseable1608 // 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_pix1618 // 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 }

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