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