Subversion Repositories Kolibri OS

Rev

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
}