~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/roqvideo.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (C) 2003 the ffmpeg project
3
3
 *
4
 
 * This library is free software; you can redistribute it and/or
 
4
 * This file is part of FFmpeg.
 
5
 *
 
6
 * FFmpeg is free software; you can redistribute it and/or
5
7
 * modify it under the terms of the GNU Lesser General Public
6
8
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
 
9
 * version 2.1 of the License, or (at your option) any later version.
8
10
 *
9
 
 * This library is distributed in the hope that it will be useful,
 
11
 * FFmpeg is distributed in the hope that it will be useful,
10
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
14
 * Lesser General Public License for more details.
13
15
 *
14
16
 * You should have received a copy of the GNU Lesser General Public
15
 
 * License along with this library; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
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
17
19
 *
18
20
 */
19
21
 
41
43
  int idx[4];
42
44
} roq_qcell;
43
45
 
 
46
static int uiclip[1024], *uiclp;  /* clipping table */
 
47
#define avg2(a,b) uiclp[(((int)(a)+(int)(b)+1)>>1)]
 
48
#define avg4(a,b,c,d) uiclp[(((int)(a)+(int)(b)+(int)(c)+(int)(d)+2)>>2)]
44
49
 
45
50
typedef struct RoqContext {
46
51
 
47
52
    AVCodecContext *avctx;
48
53
    DSPContext dsp;
49
 
    AVFrame last_frame;
50
 
    AVFrame current_frame;
 
54
    AVFrame frames[2];
 
55
    AVFrame *last_frame;
 
56
    AVFrame *current_frame;
51
57
    int first_frame;
52
58
    int y_stride;
53
59
    int c_stride;
82
88
{
83
89
    unsigned char *yptr;
84
90
 
85
 
    yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x;
 
91
    yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
86
92
    *yptr++ = cell->y0;
87
93
    *yptr++ = cell->y1;
88
94
    yptr += (ri->y_stride - 2);
89
95
    *yptr++ = cell->y2;
90
96
    *yptr++ = cell->y3;
91
 
    ri->current_frame.data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
92
 
    ri->current_frame.data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
 
97
    ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
 
98
    ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
93
99
}
94
100
 
95
101
static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
98
104
    register unsigned char y0, y1, u, v;
99
105
    unsigned char *yptr, *uptr, *vptr;
100
106
 
101
 
    yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x;
102
 
    uptr = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
103
 
    vptr = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
 
107
    yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
 
108
    uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2;
 
109
    vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2;
104
110
 
105
111
    row_inc = ri->y_stride - 4;
106
112
    c_row_inc = (ri->c_stride) - 2;
132
138
}
133
139
 
134
140
static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv,
135
 
    char mean_x, char mean_y)
 
141
    signed char mean_x, signed char mean_y)
136
142
{
137
 
    int i, mx, my;
 
143
    int i, hw, mx, my;
138
144
    unsigned char *pa, *pb;
139
145
 
140
146
    mx = x + 8 - (mv >> 4) - mean_x;
141
147
    my = y + 8 - (mv & 0xf) - mean_y;
142
148
 
143
 
    pa = ri->current_frame.data[0] + (y * ri->y_stride) + x;
144
 
    pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx;
 
149
    /* check MV against frame boundaries */
 
150
    if ((mx < 0) || (mx > ri->avctx->width - 4) ||
 
151
        (my < 0) || (my > ri->avctx->height - 4)) {
 
152
        av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
 
153
            mx, my, ri->avctx->width, ri->avctx->height);
 
154
        return;
 
155
    }
 
156
 
 
157
    pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
 
158
    pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
145
159
    for(i = 0; i < 4; i++) {
146
160
        pa[0] = pb[0];
147
161
        pa[1] = pb[1];
151
165
        pb += ri->y_stride;
152
166
    }
153
167
 
154
 
    pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
155
 
    pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2;
156
 
    for(i = 0; i < 2; i++) {
157
 
        pa[0] = pb[0];
158
 
        pa[1] = pb[1];
159
 
        pa += ri->c_stride;
160
 
        pb += ri->c_stride;
161
 
    }
162
 
 
163
 
    pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
164
 
    pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2;
165
 
    for(i = 0; i < 2; i++) {
166
 
        pa[0] = pb[0];
167
 
        pa[1] = pb[1];
168
 
        pa += ri->c_stride;
169
 
        pb += ri->c_stride;
 
168
    hw = ri->y_stride/2;
 
169
    pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
 
170
    pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
 
171
 
 
172
    for(i = 0; i < 2; i++) {
 
173
        switch(((my & 0x01) << 1) | (mx & 0x01)) {
 
174
 
 
175
        case 0:
 
176
            pa[0] = pb[0];
 
177
            pa[1] = pb[1];
 
178
            pa[hw] = pb[hw];
 
179
            pa[hw+1] = pb[hw+1];
 
180
            break;
 
181
 
 
182
        case 1:
 
183
            pa[0] = avg2(pb[0], pb[1]);
 
184
            pa[1] = avg2(pb[1], pb[2]);
 
185
            pa[hw] = avg2(pb[hw], pb[hw+1]);
 
186
            pa[hw+1] = avg2(pb[hw+1], pb[hw+2]);
 
187
            break;
 
188
 
 
189
        case 2:
 
190
            pa[0] = avg2(pb[0], pb[hw]);
 
191
            pa[1] = avg2(pb[1], pb[hw+1]);
 
192
            pa[hw] = avg2(pb[hw], pb[hw*2]);
 
193
            pa[hw+1] = avg2(pb[hw+1], pb[(hw*2)+1]);
 
194
            break;
 
195
 
 
196
        case 3:
 
197
            pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]);
 
198
            pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]);
 
199
            pa[hw] = avg4(pb[hw], pb[hw+1], pb[hw*2], pb[(hw*2)+1]);
 
200
            pa[hw+1] = avg4(pb[hw+1], pb[hw+2], pb[(hw*2)+1], pb[(hw*2)+1]);
 
201
            break;
 
202
        }
 
203
 
 
204
        pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
 
205
        pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
170
206
    }
171
207
}
172
208
 
173
209
static void apply_motion_8x8(RoqContext *ri, int x, int y,
174
 
    unsigned char mv, char mean_x, char mean_y)
 
210
    unsigned char mv, signed char mean_x, signed char mean_y)
175
211
{
176
 
    int mx, my, i;
 
212
    int mx, my, i, j, hw;
177
213
    unsigned char *pa, *pb;
178
214
 
179
215
    mx = x + 8 - (mv >> 4) - mean_x;
180
216
    my = y + 8 - (mv & 0xf) - mean_y;
181
217
 
182
 
    pa = ri->current_frame.data[0] + (y * ri->y_stride) + x;
183
 
    pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx;
 
218
    /* check MV against frame boundaries */
 
219
    if ((mx < 0) || (mx > ri->avctx->width - 8) ||
 
220
        (my < 0) || (my > ri->avctx->height - 8)) {
 
221
        av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
 
222
            mx, my, ri->avctx->width, ri->avctx->height);
 
223
        return;
 
224
    }
 
225
 
 
226
    pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
 
227
    pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
184
228
    for(i = 0; i < 8; i++) {
185
229
        pa[0] = pb[0];
186
230
        pa[1] = pb[1];
194
238
        pb += ri->y_stride;
195
239
    }
196
240
 
197
 
    pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
198
 
    pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2;
199
 
    for(i = 0; i < 4; i++) {
200
 
        pa[0] = pb[0];
201
 
        pa[1] = pb[1];
202
 
        pa[2] = pb[2];
203
 
        pa[3] = pb[3];
204
 
        pa += ri->c_stride;
205
 
        pb += ri->c_stride;
206
 
    }
207
 
 
208
 
    pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
209
 
    pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2;
210
 
    for(i = 0; i < 4; i++) {
211
 
        pa[0] = pb[0];
212
 
        pa[1] = pb[1];
213
 
        pa[2] = pb[2];
214
 
        pa[3] = pb[3];
215
 
        pa += ri->c_stride;
216
 
        pb += ri->c_stride;
 
241
    hw = ri->c_stride;
 
242
    pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
 
243
    pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
 
244
    for(j = 0; j < 2; j++) {
 
245
        for(i = 0; i < 4; i++) {
 
246
            switch(((my & 0x01) << 1) | (mx & 0x01)) {
 
247
 
 
248
            case 0:
 
249
                pa[0] = pb[0];
 
250
                pa[1] = pb[1];
 
251
                pa[2] = pb[2];
 
252
                pa[3] = pb[3];
 
253
                break;
 
254
 
 
255
            case 1:
 
256
                pa[0] = avg2(pb[0], pb[1]);
 
257
                pa[1] = avg2(pb[1], pb[2]);
 
258
                pa[2] = avg2(pb[2], pb[3]);
 
259
                pa[3] = avg2(pb[3], pb[4]);
 
260
                break;
 
261
 
 
262
            case 2:
 
263
                pa[0] = avg2(pb[0], pb[hw]);
 
264
                pa[1] = avg2(pb[1], pb[hw+1]);
 
265
                pa[2] = avg2(pb[2], pb[hw+2]);
 
266
                pa[3] = avg2(pb[3], pb[hw+3]);
 
267
                break;
 
268
 
 
269
            case 3:
 
270
                pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]);
 
271
                pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]);
 
272
                pa[2] = avg4(pb[2], pb[3], pb[hw+2], pb[hw+3]);
 
273
                pa[3] = avg4(pb[3], pb[4], pb[hw+3], pb[hw+4]);
 
274
                break;
 
275
            }
 
276
            pa += ri->c_stride;
 
277
            pb += ri->c_stride;
 
278
        }
 
279
 
 
280
        pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
 
281
        pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
217
282
    }
218
283
}
219
284
 
300
365
                            apply_motion_4x4(ri, x, y, 0, 8, 8);
301
366
                            break;
302
367
                        case RoQ_ID_FCC:
303
 
                            apply_motion_4x4(ri, x, y, buf[bpos++], 
 
368
                            apply_motion_4x4(ri, x, y, buf[bpos++],
304
369
                                chunk_arg >> 8, chunk_arg & 0xff);
305
370
                            break;
306
371
                        case RoQ_ID_SLD:
321
386
                    }
322
387
                    break;
323
388
                default:
324
 
                    printf("Unknown vq code: %d\n", vqid);
 
389
                    av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid);
325
390
            }
326
391
        }
327
392
 
339
404
static int roq_decode_init(AVCodecContext *avctx)
340
405
{
341
406
    RoqContext *s = avctx->priv_data;
 
407
    int i;
342
408
 
343
409
    s->avctx = avctx;
344
410
    s->first_frame = 1;
 
411
    s->last_frame    = &s->frames[0];
 
412
    s->current_frame = &s->frames[1];
345
413
    avctx->pix_fmt = PIX_FMT_YUV420P;
346
414
    avctx->has_b_frames = 0;
347
415
    dsputil_init(&s->dsp, avctx);
348
416
 
 
417
    uiclp = uiclip+512;
 
418
    for(i = -512; i < 512; i++)
 
419
        uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i));
 
420
 
349
421
    return 0;
350
422
}
351
423
 
355
427
{
356
428
    RoqContext *s = avctx->priv_data;
357
429
 
358
 
    *data_size = 0;
359
 
 
360
 
    if (avctx->get_buffer(avctx, &s->current_frame)) {
361
 
        printf ("  RoQ: get_buffer() failed\n");
 
430
    if (avctx->get_buffer(avctx, s->current_frame)) {
 
431
        av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
362
432
        return -1;
363
433
    }
364
 
    s->y_stride = s->current_frame.linesize[0];
365
 
    s->c_stride = s->current_frame.linesize[1];
 
434
    s->y_stride = s->current_frame->linesize[0];
 
435
    s->c_stride = s->current_frame->linesize[1];
366
436
 
367
437
    s->buf = buf;
368
438
    s->size = buf_size;
372
442
    if (s->first_frame)
373
443
        s->first_frame = 0;
374
444
    else
375
 
        avctx->release_buffer(avctx, &s->last_frame);
 
445
        avctx->release_buffer(avctx, s->last_frame);
 
446
 
 
447
    *data_size = sizeof(AVFrame);
 
448
    *(AVFrame*)data = *s->current_frame;
376
449
 
377
450
    /* shuffle frames */
378
 
    s->last_frame = s->current_frame;
379
 
 
380
 
    *data_size = sizeof(AVFrame);
381
 
    *(AVFrame*)data = s->current_frame;
 
451
    FFSWAP(AVFrame *, s->current_frame, s->last_frame);
382
452
 
383
453
    return buf_size;
384
454
}
388
458
    RoqContext *s = avctx->priv_data;
389
459
 
390
460
    /* release the last frame */
391
 
    avctx->release_buffer(avctx, &s->last_frame);
 
461
    if (s->last_frame->data[0])
 
462
        avctx->release_buffer(avctx, s->last_frame);
392
463
 
393
464
    return 0;
394
465
}