1 |
|
|
/* |
2 |
|
|
* Mpeg video formats-related picture management functions |
3 |
|
|
* |
4 |
|
|
* This file is part of FFmpeg. |
5 |
|
|
* |
6 |
|
|
* FFmpeg is free software; you can redistribute it and/or |
7 |
|
|
* modify it under the terms of the GNU Lesser General Public |
8 |
|
|
* License as published by the Free Software Foundation; either |
9 |
|
|
* version 2.1 of the License, or (at your option) any later version. |
10 |
|
|
* |
11 |
|
|
* FFmpeg is distributed in the hope that it will be useful, |
12 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
|
|
* Lesser General Public License for more details. |
15 |
|
|
* |
16 |
|
|
* You should have received a copy of the GNU Lesser General Public |
17 |
|
|
* License along with FFmpeg; if not, write to the Free Software |
18 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 |
|
|
*/ |
20 |
|
|
|
21 |
|
|
#include <stdint.h> |
22 |
|
|
|
23 |
|
|
#include "libavutil/avassert.h" |
24 |
|
|
#include "libavutil/common.h" |
25 |
|
|
#include "libavutil/pixdesc.h" |
26 |
|
|
#include "libavutil/imgutils.h" |
27 |
|
|
|
28 |
|
|
#include "avcodec.h" |
29 |
|
|
#include "motion_est.h" |
30 |
|
|
#include "mpegpicture.h" |
31 |
|
|
#include "mpegutils.h" |
32 |
|
|
|
33 |
|
18457 |
static int make_tables_writable(Picture *pic) |
34 |
|
|
{ |
35 |
|
|
int ret, i; |
36 |
|
|
#define MAKE_WRITABLE(table) \ |
37 |
|
|
do {\ |
38 |
|
|
if (pic->table &&\ |
39 |
|
|
(ret = av_buffer_make_writable(&pic->table)) < 0)\ |
40 |
|
|
return ret;\ |
41 |
|
|
} while (0) |
42 |
|
|
|
43 |
✓✓✗✓
|
18457 |
MAKE_WRITABLE(mb_var_buf); |
44 |
✓✓✗✓
|
18457 |
MAKE_WRITABLE(mc_mb_var_buf); |
45 |
✓✓✗✓
|
18457 |
MAKE_WRITABLE(mb_mean_buf); |
46 |
✓✗✗✓
|
18457 |
MAKE_WRITABLE(mbskip_table_buf); |
47 |
✓✗✗✓
|
18457 |
MAKE_WRITABLE(qscale_table_buf); |
48 |
✓✗✗✓
|
18457 |
MAKE_WRITABLE(mb_type_buf); |
49 |
|
|
|
50 |
✓✓ |
55371 |
for (i = 0; i < 2; i++) { |
51 |
✓✓✗✓
|
36914 |
MAKE_WRITABLE(motion_val_buf[i]); |
52 |
✓✓✗✓
|
36914 |
MAKE_WRITABLE(ref_index_buf[i]); |
53 |
|
|
} |
54 |
|
|
|
55 |
|
18457 |
return 0; |
56 |
|
|
} |
57 |
|
|
|
58 |
|
436 |
int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, |
59 |
|
|
ScratchpadContext *sc, int linesize) |
60 |
|
|
{ |
61 |
|
|
# define EMU_EDGE_HEIGHT (4 * 70) |
62 |
|
436 |
int alloc_size = FFALIGN(FFABS(linesize) + 64, 32); |
63 |
|
|
|
64 |
✗✓ |
436 |
if (avctx->hwaccel) |
65 |
|
|
return 0; |
66 |
|
|
|
67 |
✗✓ |
436 |
if (linesize < 24) { |
68 |
|
|
av_log(avctx, AV_LOG_ERROR, "Image too small, temporary buffers cannot function\n"); |
69 |
|
|
return AVERROR_PATCHWELCOME; |
70 |
|
|
} |
71 |
|
|
|
72 |
✗✓ |
436 |
if (av_image_check_size2(alloc_size, EMU_EDGE_HEIGHT, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0) |
73 |
|
|
return AVERROR(ENOMEM); |
74 |
|
|
|
75 |
|
|
// edge emu needs blocksize + filter length - 1 |
76 |
|
|
// (= 17x17 for halfpel / 21x21 for H.264) |
77 |
|
|
// VC-1 computes luma and chroma simultaneously and needs 19X19 + 9x9 |
78 |
|
|
// at uvlinesize. It supports only YUV420 so 24x24 is enough |
79 |
|
|
// linesize * interlaced * MBsize |
80 |
|
|
// we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines |
81 |
✓✗ |
436 |
if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) || |
82 |
✗✓ |
436 |
!FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) |
83 |
|
|
return AVERROR(ENOMEM); |
84 |
|
436 |
me->temp = me->scratchpad; |
85 |
|
436 |
sc->rd_scratchpad = me->scratchpad; |
86 |
|
436 |
sc->b_scratchpad = me->scratchpad; |
87 |
|
436 |
sc->obmc_scratchpad = me->scratchpad + 16; |
88 |
|
|
|
89 |
|
436 |
return 0; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
|
/** |
93 |
|
|
* Allocate a frame buffer |
94 |
|
|
*/ |
95 |
|
19108 |
static int alloc_frame_buffer(AVCodecContext *avctx, Picture *pic, |
96 |
|
|
MotionEstContext *me, ScratchpadContext *sc, |
97 |
|
|
int chroma_x_shift, int chroma_y_shift, |
98 |
|
|
int linesize, int uvlinesize) |
99 |
|
|
{ |
100 |
|
19108 |
int edges_needed = av_codec_is_encoder(avctx->codec); |
101 |
|
|
int r, ret; |
102 |
|
|
|
103 |
|
19108 |
pic->tf.f = pic->f; |
104 |
✓✗ |
19108 |
if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE && |
105 |
✓✗ |
19108 |
avctx->codec_id != AV_CODEC_ID_VC1IMAGE && |
106 |
✓✓ |
19108 |
avctx->codec_id != AV_CODEC_ID_MSS2) { |
107 |
✓✓ |
19029 |
if (edges_needed) { |
108 |
|
8358 |
pic->f->width = avctx->width + 2 * EDGE_WIDTH; |
109 |
|
8358 |
pic->f->height = avctx->height + 2 * EDGE_WIDTH; |
110 |
|
|
} |
111 |
|
|
|
112 |
|
19029 |
r = ff_thread_get_buffer(avctx, &pic->tf, |
113 |
|
19029 |
pic->reference ? AV_GET_BUFFER_FLAG_REF : 0); |
114 |
|
|
} else { |
115 |
|
79 |
pic->f->width = avctx->width; |
116 |
|
79 |
pic->f->height = avctx->height; |
117 |
|
79 |
pic->f->format = avctx->pix_fmt; |
118 |
|
79 |
r = avcodec_default_get_buffer2(avctx, pic->f, 0); |
119 |
|
|
} |
120 |
|
|
|
121 |
✓✗✗✓
|
19108 |
if (r < 0 || !pic->f->buf[0]) { |
122 |
|
|
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n", |
123 |
|
|
r, pic->f->data[0]); |
124 |
|
|
return -1; |
125 |
|
|
} |
126 |
|
|
|
127 |
✓✓ |
19108 |
if (edges_needed) { |
128 |
|
|
int i; |
129 |
✓✓ |
33432 |
for (i = 0; pic->f->data[i]; i++) { |
130 |
✓✓ |
25074 |
int offset = (EDGE_WIDTH >> (i ? chroma_y_shift : 0)) * |
131 |
|
25074 |
pic->f->linesize[i] + |
132 |
✓✓ |
25074 |
(EDGE_WIDTH >> (i ? chroma_x_shift : 0)); |
133 |
|
25074 |
pic->f->data[i] += offset; |
134 |
|
|
} |
135 |
|
8358 |
pic->f->width = avctx->width; |
136 |
|
8358 |
pic->f->height = avctx->height; |
137 |
|
|
} |
138 |
|
|
|
139 |
✗✓ |
19108 |
if (avctx->hwaccel) { |
140 |
|
|
assert(!pic->hwaccel_picture_private); |
141 |
|
|
if (avctx->hwaccel->frame_priv_data_size) { |
142 |
|
|
pic->hwaccel_priv_buf = av_buffer_allocz(avctx->hwaccel->frame_priv_data_size); |
143 |
|
|
if (!pic->hwaccel_priv_buf) { |
144 |
|
|
av_log(avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n"); |
145 |
|
|
return -1; |
146 |
|
|
} |
147 |
|
|
pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data; |
148 |
|
|
} |
149 |
|
|
} |
150 |
|
|
|
151 |
✓✓✓✗ ✓✓ |
19108 |
if ((linesize && linesize != pic->f->linesize[0]) || |
152 |
✗✓ |
18708 |
(uvlinesize && uvlinesize != pic->f->linesize[1])) { |
153 |
|
|
av_log(avctx, AV_LOG_ERROR, |
154 |
|
|
"get_buffer() failed (stride changed: linesize=%d/%d uvlinesize=%d/%d)\n", |
155 |
|
|
linesize, pic->f->linesize[0], |
156 |
|
|
uvlinesize, pic->f->linesize[1]); |
157 |
|
|
ff_mpeg_unref_picture(avctx, pic); |
158 |
|
|
return -1; |
159 |
|
|
} |
160 |
|
|
|
161 |
✓✗ |
19108 |
if (av_pix_fmt_count_planes(pic->f->format) > 2 && |
162 |
✗✓ |
19108 |
pic->f->linesize[1] != pic->f->linesize[2]) { |
163 |
|
|
av_log(avctx, AV_LOG_ERROR, |
164 |
|
|
"get_buffer() failed (uv stride mismatch)\n"); |
165 |
|
|
ff_mpeg_unref_picture(avctx, pic); |
166 |
|
|
return -1; |
167 |
|
|
} |
168 |
|
|
|
169 |
✓✓✗✓
|
19508 |
if (!sc->edge_emu_buffer && |
170 |
|
400 |
(ret = ff_mpeg_framesize_alloc(avctx, me, sc, |
171 |
|
400 |
pic->f->linesize[0])) < 0) { |
172 |
|
|
av_log(avctx, AV_LOG_ERROR, |
173 |
|
|
"get_buffer() failed to allocate context scratch buffers.\n"); |
174 |
|
|
ff_mpeg_unref_picture(avctx, pic); |
175 |
|
|
return ret; |
176 |
|
|
} |
177 |
|
|
|
178 |
|
19108 |
return 0; |
179 |
|
|
} |
180 |
|
|
|
181 |
|
1300 |
static int alloc_picture_tables(AVCodecContext *avctx, Picture *pic, int encoding, int out_format, |
182 |
|
|
int mb_stride, int mb_width, int mb_height, int b8_stride) |
183 |
|
|
{ |
184 |
|
1300 |
const int big_mb_num = mb_stride * (mb_height + 1) + 1; |
185 |
|
1300 |
const int mb_array_size = mb_stride * mb_height; |
186 |
|
1300 |
const int b8_array_size = b8_stride * mb_height * 2; |
187 |
|
|
int i; |
188 |
|
|
|
189 |
|
|
|
190 |
|
1300 |
pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2); |
191 |
|
1300 |
pic->qscale_table_buf = av_buffer_allocz(big_mb_num + mb_stride); |
192 |
|
1300 |
pic->mb_type_buf = av_buffer_allocz((big_mb_num + mb_stride) * |
193 |
|
|
sizeof(uint32_t)); |
194 |
✓✗✓✗ ✗✓ |
1300 |
if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf) |
195 |
|
|
return AVERROR(ENOMEM); |
196 |
|
|
|
197 |
✓✓ |
1300 |
if (encoding) { |
198 |
|
687 |
pic->mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); |
199 |
|
687 |
pic->mc_mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t)); |
200 |
|
687 |
pic->mb_mean_buf = av_buffer_allocz(mb_array_size); |
201 |
✓✗✓✗ ✗✓ |
687 |
if (!pic->mb_var_buf || !pic->mc_mb_var_buf || !pic->mb_mean_buf) |
202 |
|
|
return AVERROR(ENOMEM); |
203 |
|
|
} |
204 |
|
|
|
205 |
✓✓✓✓
|
1300 |
if (out_format == FMT_H263 || encoding || |
206 |
|
|
#if FF_API_DEBUG_MV |
207 |
|
|
avctx->debug_mv || |
208 |
|
|
#endif |
209 |
✗✓ |
184 |
(avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS)) { |
210 |
|
1116 |
int mv_size = 2 * (b8_array_size + 4) * sizeof(int16_t); |
211 |
|
1116 |
int ref_index_size = 4 * mb_array_size; |
212 |
|
|
|
213 |
✓✗✓✓
|
3348 |
for (i = 0; mv_size && i < 2; i++) { |
214 |
|
2232 |
pic->motion_val_buf[i] = av_buffer_allocz(mv_size); |
215 |
|
2232 |
pic->ref_index_buf[i] = av_buffer_allocz(ref_index_size); |
216 |
✓✗✗✓
|
2232 |
if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) |
217 |
|
|
return AVERROR(ENOMEM); |
218 |
|
|
} |
219 |
|
|
} |
220 |
|
|
|
221 |
|
1300 |
pic->alloc_mb_width = mb_width; |
222 |
|
1300 |
pic->alloc_mb_height = mb_height; |
223 |
|
1300 |
pic->alloc_mb_stride = mb_stride; |
224 |
|
|
|
225 |
|
1300 |
return 0; |
226 |
|
|
} |
227 |
|
|
|
228 |
|
|
/** |
229 |
|
|
* Allocate a Picture. |
230 |
|
|
* The pixels are allocated/set by calling get_buffer() if shared = 0 |
231 |
|
|
*/ |
232 |
|
19757 |
int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me, |
233 |
|
|
ScratchpadContext *sc, int shared, int encoding, |
234 |
|
|
int chroma_x_shift, int chroma_y_shift, int out_format, |
235 |
|
|
int mb_stride, int mb_width, int mb_height, int b8_stride, |
236 |
|
|
ptrdiff_t *linesize, ptrdiff_t *uvlinesize) |
237 |
|
|
{ |
238 |
|
|
int i, ret; |
239 |
|
|
|
240 |
✓✓ |
19757 |
if (pic->qscale_table_buf) |
241 |
✓✗ |
18457 |
if ( pic->alloc_mb_width != mb_width |
242 |
✗✓ |
18457 |
|| pic->alloc_mb_height != mb_height) |
243 |
|
|
ff_free_picture_tables(pic); |
244 |
|
|
|
245 |
✓✓ |
19757 |
if (shared) { |
246 |
✗✓ |
649 |
av_assert0(pic->f->data[0]); |
247 |
|
649 |
pic->shared = 1; |
248 |
|
|
} else { |
249 |
✗✓ |
19108 |
av_assert0(!pic->f->buf[0]); |
250 |
✗✓ |
19108 |
if (alloc_frame_buffer(avctx, pic, me, sc, |
251 |
|
|
chroma_x_shift, chroma_y_shift, |
252 |
|
19108 |
*linesize, *uvlinesize) < 0) |
253 |
|
|
return -1; |
254 |
|
|
|
255 |
|
19108 |
*linesize = pic->f->linesize[0]; |
256 |
|
19108 |
*uvlinesize = pic->f->linesize[1]; |
257 |
|
|
} |
258 |
|
|
|
259 |
✓✓ |
19757 |
if (!pic->qscale_table_buf) |
260 |
|
1300 |
ret = alloc_picture_tables(avctx, pic, encoding, out_format, |
261 |
|
|
mb_stride, mb_width, mb_height, b8_stride); |
262 |
|
|
else |
263 |
|
18457 |
ret = make_tables_writable(pic); |
264 |
✗✓ |
19757 |
if (ret < 0) |
265 |
|
|
goto fail; |
266 |
|
|
|
267 |
✓✓ |
19757 |
if (encoding) { |
268 |
|
9007 |
pic->mb_var = (uint16_t*)pic->mb_var_buf->data; |
269 |
|
9007 |
pic->mc_mb_var = (uint16_t*)pic->mc_mb_var_buf->data; |
270 |
|
9007 |
pic->mb_mean = pic->mb_mean_buf->data; |
271 |
|
|
} |
272 |
|
|
|
273 |
|
19757 |
pic->mbskip_table = pic->mbskip_table_buf->data; |
274 |
|
19757 |
pic->qscale_table = pic->qscale_table_buf->data + 2 * mb_stride + 1; |
275 |
|
19757 |
pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * mb_stride + 1; |
276 |
|
|
|
277 |
✓✓ |
19757 |
if (pic->motion_val_buf[0]) { |
278 |
✓✓ |
47892 |
for (i = 0; i < 2; i++) { |
279 |
|
31928 |
pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; |
280 |
|
31928 |
pic->ref_index[i] = pic->ref_index_buf[i]->data; |
281 |
|
|
} |
282 |
|
|
} |
283 |
|
|
|
284 |
|
19757 |
return 0; |
285 |
|
|
fail: |
286 |
|
|
av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n"); |
287 |
|
|
ff_mpeg_unref_picture(avctx, pic); |
288 |
|
|
ff_free_picture_tables(pic); |
289 |
|
|
return AVERROR(ENOMEM); |
290 |
|
|
} |
291 |
|
|
|
292 |
|
|
/** |
293 |
|
|
* Deallocate a picture. |
294 |
|
|
*/ |
295 |
|
780781 |
void ff_mpeg_unref_picture(AVCodecContext *avctx, Picture *pic) |
296 |
|
|
{ |
297 |
|
780781 |
int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean); |
298 |
|
|
|
299 |
|
780781 |
pic->tf.f = pic->f; |
300 |
|
|
/* WM Image / Screen codecs allocate internal buffers with different |
301 |
|
|
* dimensions / colorspaces; ignore user-defined callbacks for these. */ |
302 |
✓✗ |
780781 |
if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE && |
303 |
✓✗ |
780781 |
avctx->codec_id != AV_CODEC_ID_VC1IMAGE && |
304 |
✓✓ |
780781 |
avctx->codec_id != AV_CODEC_ID_MSS2) |
305 |
|
774219 |
ff_thread_release_buffer(avctx, &pic->tf); |
306 |
✓✗ |
6562 |
else if (pic->f) |
307 |
|
6562 |
av_frame_unref(pic->f); |
308 |
|
|
|
309 |
|
780781 |
av_buffer_unref(&pic->hwaccel_priv_buf); |
310 |
|
|
|
311 |
✓✓ |
780781 |
if (pic->needs_realloc) |
312 |
|
1348 |
ff_free_picture_tables(pic); |
313 |
|
|
|
314 |
|
780781 |
memset((uint8_t*)pic + off, 0, sizeof(*pic) - off); |
315 |
|
780781 |
} |
316 |
|
|
|
317 |
|
73425 |
int ff_update_picture_tables(Picture *dst, Picture *src) |
318 |
|
|
{ |
319 |
|
|
int i, ret; |
320 |
|
|
|
321 |
|
73425 |
ret = av_buffer_replace(&dst->mb_var_buf, src->mb_var_buf); |
322 |
|
73425 |
ret |= av_buffer_replace(&dst->mc_mb_var_buf, src->mc_mb_var_buf); |
323 |
|
73425 |
ret |= av_buffer_replace(&dst->mb_mean_buf, src->mb_mean_buf); |
324 |
|
73425 |
ret |= av_buffer_replace(&dst->mbskip_table_buf, src->mbskip_table_buf); |
325 |
|
73425 |
ret |= av_buffer_replace(&dst->qscale_table_buf, src->qscale_table_buf); |
326 |
|
73425 |
ret |= av_buffer_replace(&dst->mb_type_buf, src->mb_type_buf); |
327 |
✓✓ |
220275 |
for (i = 0; i < 2; i++) { |
328 |
|
146850 |
ret |= av_buffer_replace(&dst->motion_val_buf[i], src->motion_val_buf[i]); |
329 |
|
146850 |
ret |= av_buffer_replace(&dst->ref_index_buf[i], src->ref_index_buf[i]); |
330 |
|
|
} |
331 |
|
|
|
332 |
✗✓ |
73425 |
if (ret < 0) { |
333 |
|
|
ff_free_picture_tables(dst); |
334 |
|
|
return ret; |
335 |
|
|
} |
336 |
|
|
|
337 |
|
73425 |
dst->mb_var = src->mb_var; |
338 |
|
73425 |
dst->mc_mb_var = src->mc_mb_var; |
339 |
|
73425 |
dst->mb_mean = src->mb_mean; |
340 |
|
73425 |
dst->mbskip_table = src->mbskip_table; |
341 |
|
73425 |
dst->qscale_table = src->qscale_table; |
342 |
|
73425 |
dst->mb_type = src->mb_type; |
343 |
✓✓ |
220275 |
for (i = 0; i < 2; i++) { |
344 |
|
146850 |
dst->motion_val[i] = src->motion_val[i]; |
345 |
|
146850 |
dst->ref_index[i] = src->ref_index[i]; |
346 |
|
|
} |
347 |
|
|
|
348 |
|
73425 |
dst->alloc_mb_width = src->alloc_mb_width; |
349 |
|
73425 |
dst->alloc_mb_height = src->alloc_mb_height; |
350 |
|
73425 |
dst->alloc_mb_stride = src->alloc_mb_stride; |
351 |
|
|
|
352 |
|
73425 |
return 0; |
353 |
|
|
} |
354 |
|
|
|
355 |
|
73425 |
int ff_mpeg_ref_picture(AVCodecContext *avctx, Picture *dst, Picture *src) |
356 |
|
|
{ |
357 |
|
|
int ret; |
358 |
|
|
|
359 |
✗✓ |
73425 |
av_assert0(!dst->f->buf[0]); |
360 |
✗✓ |
73425 |
av_assert0(src->f->buf[0]); |
361 |
|
|
|
362 |
|
73425 |
src->tf.f = src->f; |
363 |
|
73425 |
dst->tf.f = dst->f; |
364 |
|
73425 |
ret = ff_thread_ref_frame(&dst->tf, &src->tf); |
365 |
✗✓ |
73425 |
if (ret < 0) |
366 |
|
|
goto fail; |
367 |
|
|
|
368 |
|
73425 |
ret = ff_update_picture_tables(dst, src); |
369 |
✗✓ |
73425 |
if (ret < 0) |
370 |
|
|
goto fail; |
371 |
|
|
|
372 |
✗✓ |
73425 |
if (src->hwaccel_picture_private) { |
373 |
|
|
dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf); |
374 |
|
|
if (!dst->hwaccel_priv_buf) { |
375 |
|
|
ret = AVERROR(ENOMEM); |
376 |
|
|
goto fail; |
377 |
|
|
} |
378 |
|
|
dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data; |
379 |
|
|
} |
380 |
|
|
|
381 |
|
73425 |
dst->field_picture = src->field_picture; |
382 |
|
73425 |
dst->mb_var_sum = src->mb_var_sum; |
383 |
|
73425 |
dst->mc_mb_var_sum = src->mc_mb_var_sum; |
384 |
|
73425 |
dst->b_frame_score = src->b_frame_score; |
385 |
|
73425 |
dst->needs_realloc = src->needs_realloc; |
386 |
|
73425 |
dst->reference = src->reference; |
387 |
|
73425 |
dst->shared = src->shared; |
388 |
|
|
|
389 |
|
73425 |
memcpy(dst->encoding_error, src->encoding_error, |
390 |
|
|
sizeof(dst->encoding_error)); |
391 |
|
|
|
392 |
|
73425 |
return 0; |
393 |
|
|
fail: |
394 |
|
|
ff_mpeg_unref_picture(avctx, dst); |
395 |
|
|
return ret; |
396 |
|
|
} |
397 |
|
|
|
398 |
|
40912 |
static inline int pic_is_unused(Picture *pic) |
399 |
|
|
{ |
400 |
✓✓ |
40912 |
if (!pic->f->buf[0]) |
401 |
|
18740 |
return 1; |
402 |
✓✓✓✗
|
22172 |
if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) |
403 |
|
20 |
return 1; |
404 |
|
22152 |
return 0; |
405 |
|
|
} |
406 |
|
|
|
407 |
|
19409 |
static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) |
408 |
|
|
{ |
409 |
|
|
int i; |
410 |
|
|
|
411 |
✓✓ |
19409 |
if (shared) { |
412 |
✓✗ |
852 |
for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
413 |
✓✓ |
852 |
if (!picture[i].f->buf[0]) |
414 |
|
649 |
return i; |
415 |
|
|
} |
416 |
|
|
} else { |
417 |
✓✗ |
40912 |
for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
418 |
✓✓ |
40912 |
if (pic_is_unused(&picture[i])) |
419 |
|
18760 |
return i; |
420 |
|
|
} |
421 |
|
|
} |
422 |
|
|
|
423 |
|
|
av_log(avctx, AV_LOG_FATAL, |
424 |
|
|
"Internal error, picture buffer overflow\n"); |
425 |
|
|
/* We could return -1, but the codec would crash trying to draw into a |
426 |
|
|
* non-existing frame anyway. This is safer than waiting for a random crash. |
427 |
|
|
* Also the return of this is never useful, an encoder must only allocate |
428 |
|
|
* as much as allowed in the specification. This has no relationship to how |
429 |
|
|
* much libavcodec could allocate (and MAX_PICTURE_COUNT is always large |
430 |
|
|
* enough for such valid streams). |
431 |
|
|
* Plus, a decoder has to check stream validity and remove frames if too |
432 |
|
|
* many reference frames are around. Waiting for "OOM" is not correct at |
433 |
|
|
* all. Similarly, missing reference frames have to be replaced by |
434 |
|
|
* interpolated/MC frames, anything else is a bug in the codec ... |
435 |
|
|
*/ |
436 |
|
|
abort(); |
437 |
|
|
return -1; |
438 |
|
|
} |
439 |
|
|
|
440 |
|
19409 |
int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) |
441 |
|
|
{ |
442 |
|
19409 |
int ret = find_unused_picture(avctx, picture, shared); |
443 |
|
|
|
444 |
✓✗✓✗
|
19409 |
if (ret >= 0 && ret < MAX_PICTURE_COUNT) { |
445 |
✓✓ |
19409 |
if (picture[ret].needs_realloc) { |
446 |
|
20 |
picture[ret].needs_realloc = 0; |
447 |
|
20 |
ff_free_picture_tables(&picture[ret]); |
448 |
|
20 |
ff_mpeg_unref_picture(avctx, &picture[ret]); |
449 |
|
|
} |
450 |
|
|
} |
451 |
|
19409 |
return ret; |
452 |
|
|
} |
453 |
|
|
|
454 |
|
31690 |
void ff_free_picture_tables(Picture *pic) |
455 |
|
|
{ |
456 |
|
|
int i; |
457 |
|
|
|
458 |
|
31690 |
pic->alloc_mb_width = |
459 |
|
31690 |
pic->alloc_mb_height = 0; |
460 |
|
|
|
461 |
|
31690 |
av_buffer_unref(&pic->mb_var_buf); |
462 |
|
31690 |
av_buffer_unref(&pic->mc_mb_var_buf); |
463 |
|
31690 |
av_buffer_unref(&pic->mb_mean_buf); |
464 |
|
31690 |
av_buffer_unref(&pic->mbskip_table_buf); |
465 |
|
31690 |
av_buffer_unref(&pic->qscale_table_buf); |
466 |
|
31690 |
av_buffer_unref(&pic->mb_type_buf); |
467 |
|
|
|
468 |
✓✓ |
95070 |
for (i = 0; i < 2; i++) { |
469 |
|
63380 |
av_buffer_unref(&pic->motion_val_buf[i]); |
470 |
|
63380 |
av_buffer_unref(&pic->ref_index_buf[i]); |
471 |
|
|
} |
472 |
|
31690 |
} |