Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6147 | serge | 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 |
||
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 h264) |
||
75 | // VC1 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 * 68, |
||
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 | return 0; |
||
391 | fail: |
||
392 | ff_mpeg_unref_picture(avctx, dst); |
||
393 | return ret; |
||
394 | } |
||
395 | |||
396 | static inline int pic_is_unused(Picture *pic) |
||
397 | { |
||
398 | if (!pic->f->buf[0]) |
||
399 | return 1; |
||
400 | if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF)) |
||
401 | return 1; |
||
402 | return 0; |
||
403 | } |
||
404 | |||
405 | static int find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) |
||
406 | { |
||
407 | int i; |
||
408 | |||
409 | if (shared) { |
||
410 | for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
||
411 | if (!picture[i].f->buf[0]) |
||
412 | return i; |
||
413 | } |
||
414 | } else { |
||
415 | for (i = 0; i < MAX_PICTURE_COUNT; i++) { |
||
416 | if (pic_is_unused(&picture[i])) |
||
417 | return i; |
||
418 | } |
||
419 | } |
||
420 | |||
421 | av_log(avctx, AV_LOG_FATAL, |
||
422 | "Internal error, picture buffer overflow\n"); |
||
423 | /* We could return -1, but the codec would crash trying to draw into a |
||
424 | * non-existing frame anyway. This is safer than waiting for a random crash. |
||
425 | * Also the return of this is never useful, an encoder must only allocate |
||
426 | * as much as allowed in the specification. This has no relationship to how |
||
427 | * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large |
||
428 | * enough for such valid streams). |
||
429 | * Plus, a decoder has to check stream validity and remove frames if too |
||
430 | * many reference frames are around. Waiting for "OOM" is not correct at |
||
431 | * all. Similarly, missing reference frames have to be replaced by |
||
432 | * interpolated/MC frames, anything else is a bug in the codec ... |
||
433 | */ |
||
434 | abort(); |
||
435 | return -1; |
||
436 | } |
||
437 | |||
438 | int ff_find_unused_picture(AVCodecContext *avctx, Picture *picture, int shared) |
||
439 | { |
||
440 | int ret = find_unused_picture(avctx, picture, shared); |
||
441 | |||
442 | if (ret >= 0 && ret < MAX_PICTURE_COUNT) { |
||
443 | if (picture[ret].needs_realloc) { |
||
444 | picture[ret].needs_realloc = 0; |
||
445 | ff_free_picture_tables(&picture[ret]); |
||
446 | ff_mpeg_unref_picture(avctx, &picture[ret]); |
||
447 | } |
||
448 | } |
||
449 | return ret; |
||
450 | } |
||
451 | |||
452 | void ff_free_picture_tables(Picture *pic) |
||
453 | { |
||
454 | int i; |
||
455 | |||
456 | pic->alloc_mb_width = |
||
457 | pic->alloc_mb_height = 0; |
||
458 | |||
459 | av_buffer_unref(&pic->mb_var_buf); |
||
460 | av_buffer_unref(&pic->mc_mb_var_buf); |
||
461 | av_buffer_unref(&pic->mb_mean_buf); |
||
462 | av_buffer_unref(&pic->mbskip_table_buf); |
||
463 | av_buffer_unref(&pic->qscale_table_buf); |
||
464 | av_buffer_unref(&pic->mb_type_buf); |
||
465 | |||
466 | for (i = 0; i < 2; i++) { |
||
467 | av_buffer_unref(&pic->motion_val_buf[i]); |
||
468 | av_buffer_unref(&pic->ref_index_buf[i]); |
||
469 | } |
||
470 | }>>>>>>>>>>>>>>>>> |